Version 2.19.0-255.1.beta

Merge 2.19.0-255.1.beta into beta
diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml
index 49965ae..713fbdb 100644
--- a/.github/workflows/scorecards-analysis.yml
+++ b/.github/workflows/scorecards-analysis.yml
@@ -26,7 +26,7 @@
           persist-credentials: false
 
       - name: "Run analysis"
-        uses: ossf/scorecard-action@ce330fde6b1a5c9c75b417e7efc510b822a35564
+        uses: ossf/scorecard-action@865b4092859256271290c77adbd10a43f4779972
         with:
           results_file: results.sarif
           results_format: sarif
@@ -49,6 +49,6 @@
 
       # Upload the results to GitHub's code scanning dashboard.
       - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@f5d217be74900c6ac8fbbe53f3c10376ba4e64da
+        uses: github/codeql-action/upload-sarif@904260d7d935dff982205cbdb42025ce30b7a34f
         with:
           sarif_file: results.sarif
diff --git a/AUTHORS b/AUTHORS
index 8c4e5d7..6a6a41e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -5,6 +5,7 @@
 
 Google Inc.
 The V8 project authors
+The Go Authors
 Arm Ltd. <*@arm.com>
 
 Ola Martin Bini <ola.bini@gmail.com>
diff --git a/BUILD.gn b/BUILD.gn
index 40bd306..1773913 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -109,6 +109,7 @@
     "utils/dart2wasm:compile_dart2wasm_platform",
     "utils/dart2wasm:dart2wasm_asserts_snapshot",
     "utils/dart2wasm:dart2wasm_snapshot",
+    "utils/dart2wasm:test_wasm_modules",
   ]
 }
 
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ced4ef6..4d831d3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,7 +24,35 @@
   Previously, these behaviors only took effect if `e` was a reference to a local
   variable.
 
+  Additionally, a type test of the form `v is Never` (where `v` is a local
+  variable) no longer promotes `v` to type `Never`.
+
+- **Breaking change** [#49878][]: Calling `ResourceHandle.toFile()`,
+  `ResourceHandle.toSocket()`, `ResourceHandle.toRawSocket()` or
+  `ResourceHandle.toRawDatagramSocket()`, more than once now throws a
+  `StateError`.
+
+  The previous behavior would allow multiple Dart objects to refer to the same
+  file descriptor, which would produce errors when one object was closed or
+  garbage collected.
+
 [#49635]: https://github.com/dart-lang/sdk/issues/49635
+[#49878]: https://github.com/dart-lang/sdk/issues/49878
+
+- **Breaking Change** [#49687][]: Don't delegate inaccessible private names to
+  `noSuchMethod`. If a concrete class implements an interface containing a
+  member with a name that's private to different library, and does not inherit
+  an implementation of that interface member, a invocation of that member will
+  result in an exception getting thrown.  Previously, such attempts would result
+  in the call being diverted to the `noSuchMethod` method.
+
+  This change closes a loophole in Dart's privacy system, where another library
+  can provide a different implementation of a supposedly private member using
+  `noSuchMethod`, and paves the way for a future implementation of promotion for
+  private final fields (see [#2020][]).
+
+[#49687]: https://github.com/dart-lang/sdk/issues/49687
+[#2020]: https://github.com/dart-lang/language/issues/2020
 
 ### Libraries
 
@@ -36,15 +64,6 @@
 [#34233]: https://github.com/dart-lang/sdk/issues/34233
 [`DEFAULT_BUFFER_SIZE`]: https://api.dart.dev/stable/2.17.6/dart-convert/JsonUtf8Encoder/DEFAULT_BUFFER_SIZE-constant.html
 
-#### `dart:core`
-
-- The `Uri` class will parse a backslash in the path or the authority separator
-  of a URI as a forward slash. This affects the `Uri` constructor's `path`
-  parameter, and the `Uri.parse` method.
-  This change was made to not diverge as much from the browser `URL` behavior.
-  The Dart `Uri` class is still not an implementation of the same standard
-  as the browser's `URL` implementation.
-
 #### `dart:developer`
 
 - **Breaking change** [#34233][]: The previously deprecated APIs
@@ -52,11 +71,32 @@
   `kExtensionErrorMin` in [`ServiceExtensionResponse`][] have been removed. They
   have been replaced by `invalidParams`, `extensionError`, `extensionErrorMax`,
   and `extensionErrorMin`.
+- Deprecated `UserTag.MAX_USER_TAGS` in favor of `UserTag.maxUserTags`.
 
 [#34233]: https://github.com/dart-lang/sdk/issues/34233
 [`ServiceExtensionResponse`]: https://api.dart.dev/stable/2.17.6/dart-developer/ServiceExtensionResponse-class.html#constants
 
-- Deprecated `UserTag.MAX_USER_TAGS` in favor of `UserTag.maxUserTags`.
+
+#### `dart:html`
+
+- Add constructor and `slice` to `SharedArrayBuffer`.
+- Deprecated `registerElement` and `registerElement2` in `Document` and
+  `HtmlDocument`. These APIs were based on the deprecated Web Components v0.5
+  specification and are not supported by browsers today. These APIs are expected
+  to be deleted in a future release. See the related breaking change
+  request [#49536](https://github.com/dart-lang/sdk/issues/49536).
+
+#### `dart:io`
+
+- **Breaking change** [#49305](https://github.com/dart-lang/sdk/issues/49305):
+  Disallow negative or hexadecimal content-length headers.
+- **Breaking change** [#49647](https://github.com/dart-lang/sdk/issues/49647):
+  `File.create` now takes new optional `exclusive` `bool` parameter, and
+  when it is `true` the operation will fail if target file already exists.
+
+#### `dart:isolate`
+
+- Add `Isolate.run` to run a function in a new isolate.
 
 #### `dart:mirrors`
 
@@ -68,29 +108,27 @@
 [`MirrorsUsed`]: https://api.dart.dev/stable/dart-mirrors/MirrorsUsed-class.html
 [`Comment`]: https://api.dart.dev/stable/dart-mirrors/Comment-class.html
 
-#### `dart:html`
-
-- Deprecated `registerElement` and `registerElement2` in `Document` and
-  `HtmlDocument`. These APIs were based on the deprecated Web Components v0.5
-  specification and are not supported by browsers today. These APIs are expected
-  to be deleted in a future release. See the related breaking change
-  request [#49536](https://github.com/dart-lang/sdk/issues/49536).
-
-### `dart:io`
- - **Breaking change** [#49647][]: `File.create` now takes new optional
-   `exclusive` `bool` parameter, and when it is `true` the operation
-   will fail if target file already exists.
-
-#### `dart:isolate`
-
-- Add `Isolate.run` to run a function in a new isolate.
-
 ### Tools
 
+#### Analyzer
+
+- added static enforcement of new `mustBeOverridden` annotation
+- added quick fixes for diagnostics:
+  `abstract_field_initializer`,
+  `ambiguous_extension_member_access`,
+  `assert_in_redirecting_constructor`,
+  `default_value_on_required_parameter`,
+  `initializing_formal_for_non_existent_field`,
+  `super_formal_parameter_without_associated_named`,
+- added new Hint: `cast_from_null_always_fails`
+
 #### Linter
 
-Updated the Linter to `1.27.0`, which includes changes that
+Updated the Linter to `1.28.0`, which includes changes that
 
+- update `avoid_redundant_argument_values` to work with enum declarations.
+- improve performance for `prefer_contains`.
+- add new lint: `unreachable_from_main`.
 - fix `avoid_redundant_argument_values` when referencing required
   parameters in legacy libraries.
 - improve performance for `use_late_for_private_fields_and_variables`.
@@ -127,18 +165,35 @@
 - **Breaking change** [49473](https://github.com/dart-lang/sdk/issues/49473):
   dart2js no longer supports HTTP URIs as inputs.
 
-### Core libraries
+## 2.18.2 - 2022-09-28
 
-#### `dart:io`
+This is a patch release that:
 
-- **Breaking Change** [#49305](https://github.com/dart-lang/sdk/issues/49305):
-  Disallow negative or hexadecimal content-length headers.
+- fixes incorrect behavior in `Uri.parse`.
+- fixes a compiler crash (issue [#50052][]).
 
-#### `dart:html`
+### Libraries
 
-- Add constructor and `slice` to `SharedArrayBuffer`.
+#### `dart:core`
 
-## 2.18.0
+- The `Uri` class will parse a backslash in the path or the authority separator
+  of a URI as a forward slash. This affects the `Uri` constructor's `path`
+  parameter, and the `Uri.parse` method.
+  This change was made to not diverge as much from the browser `URL` behavior.
+  The Dart `Uri` class is still not an implementation of the same standard
+  as the browser's `URL` implementation.
+
+[#50052]: https://github.com/dart-lang/sdk/issues/50052
+
+## 2.18.1 - 2022-09-14
+
+This is a patch release that fixes a crash caused by incorrect type inference
+(issues [flutter/flutter#110715][] and [flutter/flutter#111088][]).
+
+[flutter/flutter#110715]: https://github.com/flutter/flutter/issues/110715
+[flutter/flutter#111088]: https://github.com/flutter/flutter/issues/111088
+
+## 2.18.0 - 2022-08-30
 
 ### Language
 
@@ -209,10 +264,15 @@
 
 - The `Stream.fromIterable` stream can now be listened to more than once.
 
-### `dart:collection`
+#### `dart:collection`
 
 - Deprecates `BidirectionalIterator`.
 
+#### `dart:core`
+
+- Allow omitting the `unencodedPath` positional argument to `Uri.http` and
+  `Uri.https` to default to an empty path.
+
 #### `dart:html`
 
 - Add `connectionState` attribute and `connectionstatechange` listener to
@@ -223,7 +283,6 @@
 - **Breaking Change** [#49045](https://github.com/dart-lang/sdk/issues/49045):
   The `uri` property of `RedirectException` in `dart:io` has been changed to
   be nullable. Programs must be updated to handle the `null` case.
-
 - **Breaking Change** [#34218](https://github.com/dart-lang/sdk/issues/34218):
   Constants in `dart:io`'s networking APIs following the `SCREAMING_CAPS`
   convention have been removed (they were previously deprecated). Please use
@@ -277,11 +336,6 @@
 
 - Added `dartify` and a number of minor helper functions.
 
-#### `dart:core`
-
-- Allow omitting the `unencodedPath` positional argument to `Uri.http` and
-  `Uri.https` to default to an empty path.
-
 ### Dart VM
 
 Implementation of `async`/`async*`/`sync*` is revamped in Dart VM,
@@ -344,6 +398,20 @@
   The standalone `dartanalyzer` tool has been removed as previously
   announced. `dartanalyzer` is replaced by the `dart analyze` command.
 
+#### Analyzer
+
+- added quick fixes for diagnostics: `abstract_field_constructor_initializer`,
+  `abstract_class_member`,
+  [`always_put_control_body_on_new_line`](https://dart-lang.github.io/linter/lints/always_put_control_body_on_new_line.html),
+  [`avoid_print`](https://dart-lang.github.io/linter/lints/avoid_print.html),
+  [`avoid_renaming_method_parameters`](https://dart-lang.github.io/linter/lints/avoid_renaming_method_parameters.html),
+  [`discarded_futures`](https://dart-lang.github.io/linter/lints/discarded_futures.html),
+  `enum_with_abstract_member`, `non_bool_condition`,
+  `super_formal_parameter_without_associated_named`,
+  [`unawaited_futures`](https://dart-lang.github.io/linter/lints/unawaited_futures.html),
+  `unnecessary_final` `unused_element_parameter`,
+- added new Hint: `deprecated_export_use`
+
 #### Linter
 
 Updated the Linter to `1.25.0`, which includes changes that
@@ -618,7 +686,6 @@
   is unchanged for now, but users who intend to use the native
   `Element.scrollIntoViewIfNeeded` should use the new `scrollIntoViewIfNeeded`
   definition instead.
-
 - Change `Performance.mark` and `Performance.measure` to accept their different
   overloads. `mark` can now accept a `markOptions` map, and `measure` can now
   accept a `startMark` and `endMark`, or a `measureOptions` map. Both methods
@@ -659,16 +726,13 @@
   Constants in `dart:io` following the `SCREAMING_CAPS` convention have been
   removed (they were previously deprecated).  Please use the corresponding
   `lowerCamelCase` constants instead.
-
-- Add a optional `keyLog` parameter to `SecureSocket.connect` and
-  `SecureSocket.startConnect`.
-
-- Deprecate `SecureSocket.renegotiate` and `RawSecureSocket.renegotiate`,
-  which were no-ops.
-
 - **Breaking Change** [#48513](https://github.com/dart-lang/sdk/issues/48513):
   Add a new `allowLegacyUnsafeRenegotiation` poperty to `SecurityContext`,
   which allows TLS renegotiation for client secure sockets.
+- Add a optional `keyLog` parameter to `SecureSocket.connect` and
+  `SecureSocket.startConnect`.
+- Deprecate `SecureSocket.renegotiate` and `RawSecureSocket.renegotiate`,
+  which were no-ops.
 
 ### Tools
 
@@ -704,6 +768,31 @@
           [web]                  A web app that uses only core Dart libraries.
 ```
 
+#### Analyzer
+
+- added quick fixes for diagnostics:
+  [`always_use_package_imports`](https://dart-lang.github.io/linter/lints/always_use_package_imports.html),
+  [`avoid_void_async`](https://dart-lang.github.io/linter/lints/avoid_void_async.html),
+  [`cascade_invocations`](https://dart-lang.github.io/linter/lints/cascade_invocations.html),
+  `default_list_constructor`,
+  [`must_call_super`](https://dart.dev/tools/diagnostic-messages#must_call_super),
+  [`no_leading_underscores_for_local_identifiers`](https://dart-lang.github.io/linter/lints/no_leading_underscores_for_local_identifiers.html),
+  [`null_check_on_nullable_type_parameter`](https://dart-lang.github.io/linter/lints/null_check_on_nullable_type_parameter.html),
+  [`prefer_function_declarations_over_variables`](https://dart-lang.github.io/linter/lints/prefer_function_declarations_over_variables.html),
+  [`sort_constructors_first`](https://dart-lang.github.io/linter/lints/sort_constructors_first.html),
+  [`sort_unnamed_constructors_first`](https://dart-lang.github.io/linter/lints/sort_unnamed_constructors_first.html),
+  `undefined_enum_constant`,
+  [`unnecessary_late`](https://dart-lang.github.io/linter/lints/unnecessary_late.html),
+  `unnecessary_null_aware_assignments`,
+  [`use_enums`](https://dart-lang.github.io/linter/lints/use_enums.html),
+  [`use_raw_strings`](https://dart-lang.github.io/linter/lints/use_raw_strings.html),
+  [`use_super_parameters`](https://dart-lang.github.io/linter/lints/use_super_parameters.html),
+  `var_return_type`
+- added many errors for invalid enhanced enums
+- added new Hint: [`unnecessary_final`](https://dart.dev/tools/diagnostic-messages#unnecessary_final)
+- added new FFI error: `compound_implements_finalizable`
+- improved errors for invalid Unicode escapes in source code
+
 #### Linter
 
 Updated the Linter to `1.22.0`, which includes changes that
@@ -7191,9 +7280,9 @@
   - `import` and `Isolate.spawnUri` now supports the
     [Data URI scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) on the VM.
 
-## Tool Changes
+### Tool Changes
 
-### pub
+#### pub
 
 - Running `pub run foo` within a package now runs the `foo` executable defined
   by the `foo` package. The previous behavior ran `bin/foo`. This makes it easy
diff --git a/DEPS b/DEPS
index 8736824..d6be5ed 100644
--- a/DEPS
+++ b/DEPS
@@ -39,11 +39,11 @@
 
   # 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.18.0-271.7.beta",
+  "sdk_tag": "version:2.18.0",
 
   # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
   # hashes.
-  "co19_rev": "b572e42fbbfe89644236601f93cb982f23f4d7f1",
+  "co19_rev": "5f1506d4bc923342791d7e7b747a9b9c598fefe1",
   # This line prevents conflicts when both packages are rolled simultaneously.
   "co19_2_rev": "b2034a17609472e374623f3dbe0efd9f5cb258af",
 
@@ -58,7 +58,7 @@
   # Checkout extra javascript engines for testing or benchmarking.
   # d8, the V8 shell, is always checked out.
   "checkout_javascript_engines": False,
-  "d8_tag": "version:10.6.182",
+  "d8_tag": "version:10.7.157",
   "jsshell_tag": "version:95.0",
 
   # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
@@ -69,6 +69,9 @@
   "clang_revision": "c2592c374e469f343ecea82d6728609650924259",
   "gn_revision": "d7c2209cebcfe37f46dba7be4e1a7000ffc342fb",
 
+  # Ninja, runs the build based on files generated by GN.
+  "ninja_tag": "version:2@1.11.1.chromium.4",
+
   # Scripts that make 'git cl format' work.
   "clang_format_scripts_rev": "bb994c6f067340c1135eb43eed84f4b33cfa7397",
 
@@ -90,7 +93,7 @@
   "characters_rev": "559755d67af2c78b9beaaeb7ca57d7c4ae0b836d",
   "chrome_rev": "19997",
   "cli_util_rev": "b0adbba89442b2ea6fef39c7a82fe79cb31e1168",
-  "clock_rev": "2507a228773c5e877fc9e3330080b234aad965c0",
+  "clock_rev": "97026d1657566bb0c9f5a33642712ec350e45084",
   "collection_rev": "414ffa1bc8ba18bd608bbf916d95715311d89ac1",
   "convert_rev": "7145da14f9cd730e80fb4c6a10108fcfd205e8e7",
   "crypto_rev": "7cf89d35b3d90786d9f7f75211b3b3cd7e4d173f",
@@ -108,8 +111,8 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164.
   "dart_style_rev": "49bc3ff32b5578b6e19f8fd376d668130941ee29", # manually rev'd
 
-  "dartdoc_rev": "63e2f2bd0816223cf886609bbeef5f49d2a16a1f",
-  "devtools_rev": "d131d19091f6b89ac89486bd92440a25a523e8b0",
+  "dartdoc_rev": "691fa9640aaeda2044627ae8d7e072572344e499",
+  "devtools_rev": "40aae5e5ea2118e2b6dee8a8a20f166f7cec4270",
   "ffi_rev": "fb5f2667826c0900e551d19101052f84e35f41bf",
   "file_rev": "b2e31cb6ef40b223701dbfa0b907fe58468484d7",
   "fixnum_rev": "e0b17cc1f639c55a9c24947392c64b5a68992535",
@@ -117,52 +120,52 @@
   "html_rev": "8243e967caad9932c13971af3b2a7c8f028383d5",
   "http_multi_server_rev": "20bf079c8955d1250a45afb9cb096472a724a551",
   "http_parser_rev": "b968f7ddde0588273a6cbd1d2eb6569f418606ac",
-  "http_rev": "c7ee0ef0a8bd3488ce88698148df8a8778d78529",
+  "http_rev": "738a55b20e391c5a526b86bf4b02af6b7745b494",
   "icu_rev": "81d656878ec611cb0b42d52c82e9dae93920d9ba",
-  "intl_rev": "7e3a1bbdeff241323f56295d8991c004bef815e6",
+  "intl_rev": "5464b3b95635e97f67e29d71bdbe85a5d4126971",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "805e6536dd961d66f6b8cd46d8f3e61774f957c9",
-  "linter_rev": "304042aaa933a02d2581ab9598dd2ddaebdbc803", # dev
+  "linter_rev": "f2c55484e8ebda0aec8c2fea637b3bd5b17258ca", # 1.28.0
   "lints_rev": "8294e5648ab49474541527e2911e72e4c5aefe55",
-  "logging_rev": "d10e24844c2e01d3f6d2b5a1a2bb8717359c6a87",
-  "markdown_rev": "e3f4bd28c9e61b522f75f291d4d6cfcfeccd83ee", # b/236358256
+  "logging_rev": "f5d64426af1b48966a4b33e97927c9fc456960b6",
+  "markdown_rev": "87e4c689342d5bbaa84ba2999abf0bff503979be",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
-  "matcher_rev": "cba63ebf8ed1daeffd5f3c55fd30085152c4512d",
+  "matcher_rev": "6a9b83bbd73e50df2058b3e8e4aa301df49569c6",
   "mime_rev": "0a75a41445eb642674a0a271eecde78cb025ee60",
-  "mockito_rev": "2acf22f4d400c6e1eee0f6ca595092220fba8b34",
+  "mockito_rev": "02ad6c793d9ea970b5cc892f45a55d12d8ebf4e8",
   "oauth2_rev": "199ebf15cbd5b07958438184f32e41c4447a57bf",
   "package_config_rev": "cff98c90acc457a3b0750f0a7da0e351a35e5d0c",
   "path_rev": "9955b27b9bb98d87591208e19eb01c51d29fd467",
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_rev": "fa84ddd0e39f45bf3f09dcc5d6b9fbdda7820fef",
-  "protobuf_rev": "19c4eb63e05e7a87c61a98ecca868fff904b589c",
+  "protobuf_rev": "1d175bef6043bc4bdef5970f6dbd6d3001124373",
   "pub_rev": "ec35d46261b610e558dfd0d8525ca3fc8387b4b7", # manually rev'd
   "pub_semver_rev": "9fd28757ba45961ac5449e0f2b0020670e921475",
   "root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
-  "shelf_rev": "0965d864d0e6c66d5bb6daece400e80484640bd5",
+  "shelf_rev": "39d820d4e32fc99c65f562786097487d597dcee1",
   "source_map_stack_trace_rev": "72dbf21a33293b2b8434d0a9751e36f9463981ac",
   "source_maps_rev": "e93565b43a7b6b367789de8ffba969c4ebeeb317",
   "source_span_rev": "ff03af16474ce91c89eb3bc28182866f4cb6dfb0",
   "sse_rev": "00084c43684ddaf7e09c19c5364c4a27eb04efda",
   "stack_trace_rev": "17f09c2c6845bb31c7c385acecce5befb8527a13",
-  "stream_channel_rev": "8e0d7ef1f4a3fb97fbd82e11cd539093f58511f3",
+  "stream_channel_rev": "a5129ca44322a7024074ca38fb98e343dcb638c7",
   "string_scanner_rev": "2d84b16d8ae03c3a8c2417b71abe0fe6de7d8bf6",
-  "sync_http_rev": "39509d69fd5a9c3da46eab48fcafdf62e6ad4580",
+  "sync_http_rev": "f5c1f18f579752112870fa2f1860470d28c6f605",
   "term_glyph_rev": "ec7cf7bb51ebb7d55760a1359f6697690dbc06ba",
   "test_descriptor_rev": "f392f85a9804349976be041616ef66925cee8a91",
   "test_process_rev": "3e695bcfeab551473ddc288970f345f30e5e1375",
-  "test_reflective_loader_rev": "8d0de01bbe852fea1f8e33aba907abcba50a8a1e",
-  "test_rev": "5f52c524cd10ba3dd9aa5614955c338d50b29d21",
+  "test_reflective_loader_rev": "ef934b7a894d78601ba67d8f6207bd4505690456",
+  "test_rev": "58beb14cf1562429d411efa8926d7c61d0d0b133",
   "typed_data_rev": "6369490ede1c87a4a5758304a606a6e4eee364b9",
   "usage_rev": "e287a72228974886d8a3b40ddcdf12f69d7c6a22",
-  "vector_math_rev": "feb2a188b1ecd863fd92500453b26a90048e71ad",
+  "vector_math_rev": "1eee95b15e5d35cf519514cc253037b19705fb7a",
   "watcher_rev": "e00c0ea769e32821d91c0880da8eb736839a6e6d",
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
   "web_socket_channel_rev": "4b46c0c4196a5e76c2b0e2589ed37de247d35938",
   "WebCore_rev": "bcb10901266c884e7b3740abc597ab95373ab55c",
-  "webdev_rev": "605b981abe95221d2bd10c069669e4f751e55c5d",
+  "webdev_rev": "741695691a7a8d357e404888ebe8d3e614a84e71",
   "webdriver_rev": "e1a9ad671ee82e05eee463f922a34585ed2d2f15",
-  "webkit_inspection_protocol_rev": "57ebca4b97310a10774c59c0fb056d8f23bd5cee",
+  "webkit_inspection_protocol_rev": "4e5eb8d4a48fb97603d90f2b5aac5483ebbdeb1d",
   "yaml_edit_rev": "01589b3ce447b03aed991db49f1ec6445ad5476d",
   "yaml_rev": "fda5b15692ccfa0feb7793a27fe3829b3d0f77fa",
   "zlib_rev": "27c2f474b71d0d20764f86f60ef8b00da1a16cda",
@@ -178,6 +181,11 @@
   "chrome_tag": "101.0.4951.41",
   "download_firefox": False,
   "firefox_tag": "98.0.2",
+
+  # Emscripten is used in dart2wasm tests.
+  "download_emscripten": False,
+  "emsdk_rev": "d0291b3216fbc9765d9cfc1a2103316b32a555c6",
+  "emsdk_ver": "3.1.3",
 }
 
 gclient_gn_args_file = Var("dart_root") + '/build/config/gclient_args.gni'
@@ -270,6 +278,10 @@
       Var("dart_git") + "root_certificates.git" +
       "@" + Var("root_certificates_rev"),
 
+  Var("dart_root") + "/third_party/emsdk":
+      Var("dart_git") + "external/github.com/emscripten-core/emsdk.git" +
+      "@" + Var("emsdk_rev"),
+
   Var("dart_root") + "/third_party/jinja2":
       Var("chromium_git") + "/chromium/src/third_party/jinja2.git" +
       "@" + Var("jinja2_rev"),
@@ -500,6 +512,14 @@
       "dep_type": "cipd",
   },
 
+  Var("dart_root") + "/buildtools/ninja": {
+      "packages": [{
+          "package": "infra/3pp/tools/ninja/${{platform}}",
+          "version": Var("ninja_tag"),
+      }],
+      "dep_type": "cipd",
+  },
+
   Var("dart_root") + "/third_party/android_tools/ndk": {
       "packages": [
           {
@@ -708,4 +728,19 @@
     'action': ['python3', 'sdk/build/vs_toolchain.py', 'update'],
     'condition': 'checkout_win'
   },
+  # Install and activate the empscripten SDK.
+  {
+    'name': 'install_emscripten',
+    'pattern': '.',
+    'action': ['python3', 'sdk/third_party/emsdk/emsdk.py', 'install',
+        Var('emsdk_ver')],
+    'condition': 'download_emscripten'
+  },
+  {
+    'name': 'activate_emscripten',
+    'pattern': '.',
+    'action': ['python3', 'sdk/third_party/emsdk/emsdk.py', 'activate',
+        Var('emsdk_ver')],
+    'condition': 'download_emscripten'
+  },
 ]
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 6a47593..5a4fd72 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -125,6 +125,10 @@
         print('WARNING: dart not found: %s' % (dart))
         return []
 
+    dartFixes = [
+        '--fix-named-default-separator',
+    ]
+
     def HasFormatErrors(filename: str = None, contents: str = None):
         # Don't look for formatting errors in multitests. Since those are very
         # sensitive to whitespace, many cannot be reformatted without breaking
@@ -138,6 +142,7 @@
         args = [
             dart,
             'format',
+        ] + dartFixes + [
             '--set-exit-if-changed',
             '--output=none',
             '--summary=none',
@@ -181,8 +186,8 @@
             output_api.PresubmitError(
                 'File output does not match dart format.\n'
                 'Fix these issues with:\n'
-                '%s format %s%s' %
-                (dart, lineSep, lineSep.join(unformatted_files)))
+                '%s format %s%s%s' % (dart, ' '.join(dartFixes), lineSep,
+                                      lineSep.join(unformatted_files)))
         ]
 
     return []
diff --git a/benchmarks/IntegerSetLookup/dart/IntegerSetLookup.dart b/benchmarks/IntegerSetLookup/dart/IntegerSetLookup.dart
new file mode 100644
index 0000000..7be4deb
--- /dev/null
+++ b/benchmarks/IntegerSetLookup/dart/IntegerSetLookup.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2022, 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.
+
+// Benchmark for https://github.com/dart-lang/sdk/issues/48641.
+//
+// Measures the average time needed for a lookup in Sets of integers.
+
+import 'dart:math';
+import 'dart:collection';
+import 'package:benchmark_harness/benchmark_harness.dart';
+
+class SetBenchmark extends BenchmarkBase {
+  SetBenchmark(String name, this.mySet) : super(name);
+
+  final Set<int> mySet;
+
+  @override
+  void run() {
+    mySet.contains(123456789);
+  }
+}
+
+void main() {
+  final list = [
+    for (int i = 0; i < 14790; i++) (i + 1) * 0x10000000 + 123456789
+  ];
+
+  final r = Random();
+  final randomList = List<int>.generate(14790, (_) => r.nextInt(1 << 31));
+
+  final benchmarks = [
+    () => SetBenchmark("IntegerSetLookup.DefaultHashSet", {...list}),
+    () =>
+        SetBenchmark("IntegerSetLookup.HashSet", HashSet<int>()..addAll(list)),
+    () =>
+        SetBenchmark("IntegerSetLookup.DefaultHashSet_Random", {...randomList}),
+    () => SetBenchmark(
+        "IntegerSetLookup.HashSet_Random", HashSet<int>()..addAll(randomList)),
+  ];
+  for (final benchmark in benchmarks) {
+    benchmark().report();
+  }
+}
diff --git a/benchmarks/IntegerSetLookup/dart2/IntegerSetLookup.dart b/benchmarks/IntegerSetLookup/dart2/IntegerSetLookup.dart
new file mode 100644
index 0000000..3a29792
--- /dev/null
+++ b/benchmarks/IntegerSetLookup/dart2/IntegerSetLookup.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2022, 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.
+
+// Benchmark for https://github.com/dart-lang/sdk/issues/48641.
+//
+// Measures the average time needed for a lookup in Sets of integers.
+
+// @dart=2.9
+
+import 'dart:math';
+import 'dart:collection';
+import 'package:benchmark_harness/benchmark_harness.dart';
+
+class SetBenchmark extends BenchmarkBase {
+  SetBenchmark(String name, this.mySet) : super(name);
+
+  final Set<int> mySet;
+
+  @override
+  void run() {
+    mySet.contains(123456789);
+  }
+}
+
+void main() {
+  final list = [
+    for (int i = 0; i < 14790; i++) (i + 1) * 0x10000000 + 123456789
+  ];
+
+  final r = Random();
+  final randomList = List<int>.generate(14790, (_) => r.nextInt(1 << 31));
+
+  final benchmarks = [
+    () => SetBenchmark("IntegerSetLookup.DefaultHashSet", {...list}),
+    () =>
+        SetBenchmark("IntegerSetLookup.HashSet", HashSet<int>()..addAll(list)),
+    () =>
+        SetBenchmark("IntegerSetLookup.DefaultHashSet_Random", {...randomList}),
+    () => SetBenchmark(
+        "IntegerSetLookup.HashSet_Random", HashSet<int>()..addAll(randomList)),
+  ];
+  for (final benchmark in benchmarks) {
+    benchmark().report();
+  }
+}
diff --git a/benchmarks/SoundSplayTreeSieve/dart/sound_splay_tree.dart b/benchmarks/SoundSplayTreeSieve/dart/sound_splay_tree.dart
index dd952f3..d2126f8 100644
--- a/benchmarks/SoundSplayTreeSieve/dart/sound_splay_tree.dart
+++ b/benchmarks/SoundSplayTreeSieve/dart/sound_splay_tree.dart
@@ -549,7 +549,7 @@
       : _tree = tree,
         _modificationCount = tree._modificationCount,
         _splayCount = tree._splayCount {
-    _findLeftMostDescendent(tree._root);
+    _findLeftMostDescendant(tree._root);
   }
 
   _SoundSplayTreeIterator.startAt(_SoundSplayTree<K, _SoundSplayTreeNode<K>> tree, K startKey)
@@ -560,7 +560,7 @@
     _splayCount = tree._splayCount;
     if (compare < 0) {
       // Don't include the root, start at the next element after the root.
-      _findLeftMostDescendent(tree._root.right);
+      _findLeftMostDescendant(tree._root.right);
     } else {
       _workList.add(tree._root);
     }
@@ -571,7 +571,7 @@
     return _getValue(_currentNode);
   }
 
-  void _findLeftMostDescendent(_SoundSplayTreeNode<K> node) {
+  void _findLeftMostDescendant(_SoundSplayTreeNode<K> node) {
     while (node != null) {
       _workList.add(node);
       node = node.left;
@@ -588,10 +588,10 @@
     assert(_workList.isNotEmpty);
     _workList.clear();
     if (currentNode == null) {
-      _findLeftMostDescendent(_tree._root);
+      _findLeftMostDescendant(_tree._root);
     } else {
       _tree._splay(currentNode.key);
-      _findLeftMostDescendent(_tree._root.right);
+      _findLeftMostDescendant(_tree._root.right);
       assert(_workList.isNotEmpty);
     }
   }
@@ -613,7 +613,7 @@
       _rebuildWorkList(_currentNode);
     }
     _currentNode = _workList.removeLast();
-    _findLeftMostDescendent(_currentNode.right);
+    _findLeftMostDescendant(_currentNode.right);
     return true;
   }
 
diff --git a/benchmarks/SoundSplayTreeSieve/dart2/sound_splay_tree.dart b/benchmarks/SoundSplayTreeSieve/dart2/sound_splay_tree.dart
index 6494a14..768582c 100644
--- a/benchmarks/SoundSplayTreeSieve/dart2/sound_splay_tree.dart
+++ b/benchmarks/SoundSplayTreeSieve/dart2/sound_splay_tree.dart
@@ -551,7 +551,7 @@
       : _tree = tree,
         _modificationCount = tree._modificationCount,
         _splayCount = tree._splayCount {
-    _findLeftMostDescendent(tree._root);
+    _findLeftMostDescendant(tree._root);
   }
 
   _SoundSplayTreeIterator.startAt(_SoundSplayTree<K, _SoundSplayTreeNode<K>> tree, K startKey)
@@ -562,7 +562,7 @@
     _splayCount = tree._splayCount;
     if (compare < 0) {
       // Don't include the root, start at the next element after the root.
-      _findLeftMostDescendent(tree._root.right);
+      _findLeftMostDescendant(tree._root.right);
     } else {
       _workList.add(tree._root);
     }
@@ -573,7 +573,7 @@
     return _getValue(_currentNode);
   }
 
-  void _findLeftMostDescendent(_SoundSplayTreeNode<K> node) {
+  void _findLeftMostDescendant(_SoundSplayTreeNode<K> node) {
     while (node != null) {
       _workList.add(node);
       node = node.left;
@@ -590,10 +590,10 @@
     assert(_workList.isNotEmpty);
     _workList.clear();
     if (currentNode == null) {
-      _findLeftMostDescendent(_tree._root);
+      _findLeftMostDescendant(_tree._root);
     } else {
       _tree._splay(currentNode.key);
-      _findLeftMostDescendent(_tree._root.right);
+      _findLeftMostDescendant(_tree._root.right);
       assert(_workList.isNotEmpty);
     }
   }
@@ -615,7 +615,7 @@
       _rebuildWorkList(_currentNode);
     }
     _currentNode = _workList.removeLast();
-    _findLeftMostDescendent(_currentNode.right);
+    _findLeftMostDescendant(_currentNode.right);
     return true;
   }
 
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn
index bc54953..5bce92e 100644
--- a/build/toolchain/win/BUILD.gn
+++ b/build/toolchain/win/BUILD.gn
@@ -22,6 +22,8 @@
 # This tool will is used as a wrapper for various commands below.
 tool_wrapper_path = rebase_path("tool_wrapper.py", root_build_dir)
 
+ninja_path = rebase_path("//buildtools/ninja/ninja")
+
 if (use_goma) {
   goma_prefix = "$goma_dir/gomacc.exe "
 } else {
@@ -72,7 +74,7 @@
       # TODO(brettw) enable this when GN support in the binary has been rolled.
       #precompiled_header_type = "msvc"
       pdbname = "{{target_out_dir}}/{{target_output_name}}_c.pdb"
-      command = "ninja -t msvc -e $env -- $cl /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd$pdbname"
+      command = "$ninja_path -t msvc -e $env -- $cl /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd$pdbname"
       depsformat = "msvc"
       description = "CC {{output}}"
       outputs = [
@@ -93,7 +95,7 @@
       if (is_clang && invoker.current_cpu == "x86") {
         flags = "-m32"
       }
-      command = "ninja -t msvc -e $env -- $cl $flags /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd$pdbname"
+      command = "$ninja_path -t msvc -e $env -- $cl $flags /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd$pdbname"
       depsformat = "msvc"
       description = "CXX {{output}}"
       outputs = [
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index 830a379..efc9e71 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -104,12 +104,10 @@
     Expression extends Object, Variable extends Object, Type extends Object> {
   factory FlowAnalysis(Operations<Variable, Type> operations,
       AssignedVariables<Node, Variable> assignedVariables,
-      {required bool respectImplicitlyTypedVarInitializers,
-      Set<Object?> promotableFields = const {}}) {
+      {required bool respectImplicitlyTypedVarInitializers}) {
     return new _FlowAnalysisImpl(operations, assignedVariables,
         respectImplicitlyTypedVarInitializers:
-            respectImplicitlyTypedVarInitializers,
-        promotableFields: promotableFields);
+            respectImplicitlyTypedVarInitializers);
   }
 
   factory FlowAnalysis.legacy(Operations<Variable, Type> operations,
@@ -379,11 +377,18 @@
   /// Call this method after visiting the condition part of an if statement.
   /// [condition] should be the if statement's condition.  [ifNode] should be
   /// the entire `if` statement (or the collection literal entry).
-  void ifStatement_thenBegin(Expression condition, Node ifNode);
+  ///
+  /// For an if-case statement, [condition] should be `null`.
+  void ifStatement_thenBegin(Expression? condition, Node ifNode);
 
-  /// Call this method after visiting the initializer of a variable declaration.
+  /// Call this method after visiting the initializer of a variable declaration,
+  /// or a variable pattern that is being matched (and hence being initialized
+  /// with an implicit value).
+  ///
+  /// If the initialized value is not known (i.e. because this is a variable
+  /// pattern that's being matched), pass `null` for [initializerExpression].
   void initialize(
-      Variable variable, Type initializerType, Expression initializerExpression,
+      Variable variable, Type matchedType, Expression? initializerExpression,
       {required bool isFinal,
       required bool isLate,
       required bool isImplicitlyTyped});
@@ -485,10 +490,10 @@
   /// expression.
   ///
   /// [propertyMember] should be whatever data structure the client uses to keep
-  /// track of the field or property being accessed.  This will be matched
-  /// against set set of promotable fields passed to the [FlowAnalysis]
-  /// constructor.  [staticType] should be the static type of the value returned
-  /// by the property get.
+  /// track of the field or property being accessed.  If not `null`,
+  /// [Operations.isPropertyPromotable] will be consulted to find out whether
+  /// the property is promotable.  [staticType] should be the static type of the
+  /// value returned by the property get.
   ///
   /// Note: although only fields can be promoted, this method uses the
   /// nomenclature "property" rather than "field", to highlight the fact that
@@ -508,15 +513,23 @@
   /// the identifier to the right hand side of the `.`.  [staticType] should be
   /// the static type of the value returned by the property get.
   ///
+  /// [wholeExpression] is used by flow analysis to detect the case where the
+  /// property get is used as a subexpression of a larger expression that
+  /// participates in promotion (e.g. promotion of a property of a property).
+  /// If there is no expression corresponding to the property get (e.g. because
+  /// the property is being invoked like a method, or the property get is part
+  /// of a compound assignment), [wholeExpression] may be `null`.
+  ///
   /// [propertyMember] should be whatever data structure the client uses to keep
-  /// track of the field or property being accessed.  This will be matched
-  /// against the set of promotable fields passed to the [FlowAnalysis]
-  /// constructor.  In the event of non-promotion of a property get, this value
-  /// can be retrieved from [PropertyNotPromoted.propertyMember].
+  /// track of the field or property being accessed.  If not `null`,
+  /// [Operations.isPropertyPromotable] will be consulted to find out whether
+  /// the property is promotable.  In the event of non-promotion of a property
+  /// get, this value can be retrieved from
+  /// [PropertyNotPromoted.propertyMember].
   ///
   /// If the property's type is currently promoted, the promoted type is
   /// returned.  Otherwise `null` is returned.
-  Type? propertyGet(Expression wholeExpression, Expression target,
+  Type? propertyGet(Expression? wholeExpression, Expression target,
       String propertyName, Object? propertyMember, Type staticType);
 
   /// Retrieves the SSA node associated with [variable], or `null` if [variable]
@@ -525,14 +538,20 @@
   @visibleForTesting
   SsaNode<Type>? ssaNodeForTesting(Variable variable);
 
+  /// Call this method just after visiting a guard part of a case clause.  See
+  /// [switchStatement_expressionEnd] for details.
+  ///
+  /// [when] should be the expression following the `when` keyword.
+  void switchStatement_afterGuard(Expression when);
+
+  /// Call this method just before visiting a sequence of two or more `case` or
+  /// `default` clauses that share a body.  See [switchStatement_expressionEnd]
+  /// for details.`
+  void switchStatement_beginAlternatives();
+
   /// Call this method just before visiting one of the cases in the body of a
   /// switch statement.  See [switchStatement_expressionEnd] for details.
-  ///
-  /// [hasLabel] indicates whether the case has any labels.
-  ///
-  /// [node] should be the same node that was passed to
-  /// [AssignedVariables.endNode] for the switch statement.
-  void switchStatement_beginCase(bool hasLabel, Node node);
+  void switchStatement_beginCase();
 
   /// Call this method just after visiting the body of a switch statement.  See
   /// [switchStatement_expressionEnd] for details.
@@ -542,17 +561,44 @@
   /// were listed in cases.
   void switchStatement_end(bool isExhaustive);
 
+  /// Call this method just after visiting a `case` or `default` clause, if it
+  /// shares a body with at least one other `case` or `default` clause.  See
+  /// [switchStatement_expressionEnd] for details.`
+  void switchStatement_endAlternative();
+
+  /// Call this method just after visiting a sequence of two or more `case` or
+  /// `default` clauses that share a body.  See [switchStatement_expressionEnd]
+  /// for details.`
+  ///
+  /// [node] should be the same node that was passed to
+  /// [AssignedVariables.endNode] for the switch statement.
+  ///
+  /// [hasLabels] indicates whether the case has any labels.
+  void switchStatement_endAlternatives(Statement node,
+      {required bool hasLabels});
+
   /// Call this method just after visiting the expression part of a switch
-  /// statement.
+  /// statement or expression.  [switchStatement] should be the switch statement
+  /// itself (or `null` if this is a switch expression).
   ///
   /// The order of visiting a switch statement should be:
   /// - Visit the switch expression.
   /// - Call [switchStatement_expressionEnd].
-  /// - For each switch case (including the default case, if any):
+  /// - For each case body:
   ///   - Call [switchStatement_beginCase].
-  ///   - Visit the case.
+  ///   - If there is more than one `case` or `default` clause associated with
+  ///     this case body, call [switchStatement_beginAlternatives].  (Also safe
+  ///     to call if there is just one `case` or `default` clause).
+  ///   - For each `case` or `default` clause associated with this case body:
+  ///     - If a `when` clause is present, visit it and then call
+  ///       [switchStatement_afterGuard].
+  ///     - If [switchStatement_beginAlternatives] was called, call
+  ///       [switchStatement_endAlternative].
+  ///   - If [switchStatement_beginAlternatives] was called, call
+  ///     [switchStatement_endAlternatives].
+  ///   - Visit the case body.
   /// - Call [switchStatement_end].
-  void switchStatement_expressionEnd(Statement switchStatement);
+  void switchStatement_expressionEnd(Statement? switchStatement);
 
   /// Call this method just after visiting the expression `this` (or the
   /// pseudo-expression `super`, in the case of the analyzer, which represents
@@ -570,10 +616,11 @@
   /// returned by the property get.
   ///
   /// [propertyMember] should be whatever data structure the client uses to keep
-  /// track of the field or property being accessed.  This will be matched
-  /// against the set of promotable fields passed to the [FlowAnalysis]
-  /// constructor.  In the event of non-promotion of a property get, this value
-  /// can be retrieved from [PropertyNotPromoted.propertyMember].
+  /// track of the field or property being accessed.  If not `null`,
+  /// [Operations.isPropertyPromotable] will be consulted to find out whether
+  /// the property is promotable.  In the event of non-promotion of a property
+  /// get, this value can be retrieved from
+  /// [PropertyNotPromoted.propertyMember].
   ///
   /// If the property's type is currently promoted, the promoted type is
   /// returned.  Otherwise `null` is returned.
@@ -768,14 +815,12 @@
 
   factory FlowAnalysisDebug(Operations<Variable, Type> operations,
       AssignedVariables<Node, Variable> assignedVariables,
-      {required bool respectImplicitlyTypedVarInitializers,
-      Set<Object?> promotableFields = const {}}) {
+      {required bool respectImplicitlyTypedVarInitializers}) {
     print('FlowAnalysisDebug()');
     return new FlowAnalysisDebug._(new _FlowAnalysisImpl(
         operations, assignedVariables,
         respectImplicitlyTypedVarInitializers:
-            respectImplicitlyTypedVarInitializers,
-        promotableFields: promotableFields));
+            respectImplicitlyTypedVarInitializers));
   }
 
   factory FlowAnalysisDebug.legacy(Operations<Variable, Type> operations,
@@ -1002,23 +1047,22 @@
   }
 
   @override
-  void ifStatement_thenBegin(Expression condition, Node ifNode) {
+  void ifStatement_thenBegin(Expression? condition, Node ifNode) {
     _wrap('ifStatement_thenBegin($condition, $ifNode)',
         () => _wrapped.ifStatement_thenBegin(condition, ifNode));
   }
 
   @override
   void initialize(
-      Variable variable, Type initializerType, Expression initializerExpression,
+      Variable variable, Type matchedType, Expression? initializerExpression,
       {required bool isFinal,
       required bool isLate,
       required bool isImplicitlyTyped}) {
     _wrap(
-        'initialize($variable, $initializerType, $initializerExpression, '
+        'initialize($variable, $matchedType, $initializerExpression, '
         'isFinal: $isFinal, isLate: $isLate, '
         'isImplicitlyTyped: $isImplicitlyTyped)',
-        () => _wrapped.initialize(
-            variable, initializerType, initializerExpression,
+        () => _wrapped.initialize(variable, matchedType, initializerExpression,
             isFinal: isFinal,
             isLate: isLate,
             isImplicitlyTyped: isImplicitlyTyped));
@@ -1149,7 +1193,7 @@
   }
 
   @override
-  Type? propertyGet(Expression wholeExpression, Expression target,
+  Type? propertyGet(Expression? wholeExpression, Expression target,
       String propertyName, Object? propertyMember, Type staticType) {
     return _wrap(
         'propertyGet($wholeExpression, $target, $propertyName, '
@@ -1168,9 +1212,21 @@
   }
 
   @override
-  void switchStatement_beginCase(bool hasLabel, Node node) {
-    _wrap('switchStatement_beginCase($hasLabel, $node)',
-        () => _wrapped.switchStatement_beginCase(hasLabel, node));
+  void switchStatement_afterGuard(Expression when) {
+    _wrap('switchStatement_afterGuard($when)',
+        () => _wrapped.switchStatement_afterGuard(when));
+  }
+
+  @override
+  void switchStatement_beginAlternatives() {
+    _wrap('switchStatement_beginAlternatives()',
+        () => _wrapped.switchStatement_beginAlternatives());
+  }
+
+  @override
+  void switchStatement_beginCase() {
+    _wrap('switchStatement_beginCase()',
+        () => _wrapped.switchStatement_beginCase());
   }
 
   @override
@@ -1180,7 +1236,22 @@
   }
 
   @override
-  void switchStatement_expressionEnd(Statement switchStatement) {
+  void switchStatement_endAlternative() {
+    _wrap('switchStatement_endAlternative()',
+        () => _wrapped.switchStatement_endAlternative());
+  }
+
+  @override
+  void switchStatement_endAlternatives(Statement node,
+      {required bool hasLabels}) {
+    _wrap(
+        'switchStatement_endAlternatives($node, hasLabels: $hasLabels)',
+        () => _wrapped.switchStatement_endAlternatives(node,
+            hasLabels: hasLabels));
+  }
+
+  @override
+  void switchStatement_expressionEnd(Statement? switchStatement) {
     _wrap('switchStatement_expressionEnd($switchStatement)',
         () => _wrapped.switchStatement_expressionEnd(switchStatement));
   }
@@ -2178,7 +2249,13 @@
 
 /// Operations on types and variables, abstracted from concrete type interfaces.
 abstract class Operations<Variable extends Object, Type extends Object>
-    implements TypeOperations<Type>, VariableOperations<Variable, Type> {}
+    implements TypeOperations<Type>, VariableOperations<Variable, Type> {
+  /// Determines whether the given property can be promoted.  [propertyMember]
+  /// will correspond to a `propertyMember` value passed to
+  /// [FlowAnalysis.promotedPropertyType], [FlowAnalysis.propertyGet], or
+  /// [FlowAnalysis.thisOrSuperPropertyGet].
+  bool isPropertyPromotable(Object property);
+}
 
 /// Non-promotion reason describing the situation where an expression was not
 /// promoted due to the fact that it's a property get.
@@ -3095,16 +3172,9 @@
   @override
   final PromotionKeyStore<Variable> promotionKeyStore;
 
-  /// The set of fields that can be promoted.  The type of the set element is
-  /// `Object?` to match the type of the `propertyMember` argument of
-  /// [promotedFieldType], [propertyGet], and [thisOrSuperPropertyGet].
-  final Set<Object?> _promotableFields;
-
   _FlowAnalysisImpl(this.operations, this._assignedVariables,
-      {required this.respectImplicitlyTypedVarInitializers,
-      Set<Object?> promotableFields = const {}})
-      : promotionKeyStore = _assignedVariables.promotionKeyStore,
-        _promotableFields = promotableFields {
+      {required this.respectImplicitlyTypedVarInitializers})
+      : promotionKeyStore = _assignedVariables.promotionKeyStore {
     if (!_assignedVariables.isFinished) {
       _assignedVariables.finish();
     }
@@ -3466,7 +3536,7 @@
   }
 
   @override
-  void ifStatement_thenBegin(Expression condition, Node ifNode) {
+  void ifStatement_thenBegin(Expression? condition, Node ifNode) {
     ExpressionInfo<Type> conditionInfo = _expressionEnd(condition);
     _stack.add(new _IfContext(conditionInfo));
     _current = conditionInfo.ifTrue;
@@ -3474,7 +3544,7 @@
 
   @override
   void initialize(
-      Variable variable, Type initializerType, Expression initializerExpression,
+      Variable variable, Type matchedType, Expression? initializerExpression,
       {required bool isFinal,
       required bool isLate,
       required bool isImplicitlyTyped}) {
@@ -3488,18 +3558,18 @@
       // initializer expressions for implicitly typed variables, in order to
       // preserve the buggy behavior of
       // https://github.com/dart-lang/language/issues/1785.
-    } else {
+    } else if (initializerExpression != null) {
       expressionInfo = _getExpressionInfo(initializerExpression);
     }
     SsaNode<Type> newSsaNode = new SsaNode<Type>(
         expressionInfo is _TrivialExpressionInfo ? null : expressionInfo);
-    _current = _current.write(this, null, variable, variableKey,
-        initializerType, newSsaNode, operations,
+    _current = _current.write(
+        this, null, variable, variableKey, matchedType, newSsaNode, operations,
         promoteToTypeOfInterest: !isImplicitlyTyped && !isFinal);
-    if (isImplicitlyTyped && operations.isTypeParameterType(initializerType)) {
+    if (isImplicitlyTyped && operations.isTypeParameterType(matchedType)) {
       _current = _current
           .tryPromoteForTypeCheck(
-              this, _variableReference(variable, variableKey), initializerType)
+              this, _variableReference(variable, variableKey), matchedType)
           .ifTrue;
     }
   }
@@ -3670,7 +3740,7 @@
   }
 
   @override
-  Type? propertyGet(Expression wholeExpression, Expression target,
+  Type? propertyGet(Expression? wholeExpression, Expression target,
       String propertyName, Object? propertyMember, Type staticType) {
     return _handleProperty(
         wholeExpression, target, propertyName, propertyMember, staticType);
@@ -3681,16 +3751,26 @@
       .variableInfo[promotionKeyStore.keyForVariable(variable)]?.ssaNode;
 
   @override
-  void switchStatement_beginCase(bool hasLabel, Node node) {
-    AssignedVariablesNodeInfo info = _assignedVariables.getInfoForNode(node);
+  void switchStatement_afterGuard(Expression when) {
+    ExpressionInfo<Type>? expressionInfo = _getExpressionInfo(when);
+    if (expressionInfo != null) {
+      _current = expressionInfo.ifTrue;
+    }
+  }
+
+  @override
+  void switchStatement_beginAlternatives() {
+    _current = _current.split();
+    _SwitchAlternativesContext<Type> context =
+        new _SwitchAlternativesContext<Type>(_current);
+    _stack.add(context);
+  }
+
+  @override
+  void switchStatement_beginCase() {
     _SimpleStatementContext<Type> context =
         _stack.last as _SimpleStatementContext<Type>;
-    if (hasLabel) {
-      _current =
-          context._previous.conservativeJoin(this, info.written, info.captured);
-    } else {
-      _current = context._previous;
-    }
+    _current = context._previous;
   }
 
   @override
@@ -3710,12 +3790,40 @@
   }
 
   @override
-  void switchStatement_expressionEnd(Statement switchStatement) {
+  void switchStatement_endAlternative() {
+    _SwitchAlternativesContext<Type> context =
+        _stack.last as _SwitchAlternativesContext<Type>;
+    context._combinedModel = _join(context._combinedModel, _current);
+    _current = context._previous;
+  }
+
+  @override
+  void switchStatement_endAlternatives(Statement? node,
+      {required bool hasLabels}) {
+    _SwitchAlternativesContext<Type> alternativesContext =
+        _stack.removeLast() as _SwitchAlternativesContext<Type>;
+    _SimpleStatementContext<Type> switchContext =
+        _stack.last as _SimpleStatementContext<Type>;
+    if (hasLabels) {
+      AssignedVariablesNodeInfo info = _assignedVariables.getInfoForNode(node!);
+      _current = switchContext._previous
+          .conservativeJoin(this, info.written, info.captured);
+    } else {
+      _current =
+          (alternativesContext._combinedModel ?? alternativesContext._previous)
+              .unsplit();
+    }
+  }
+
+  @override
+  void switchStatement_expressionEnd(Statement? switchStatement) {
     _current = _current.split();
     _SimpleStatementContext<Type> context =
         new _SimpleStatementContext<Type>(_current.reachable.parent!, _current);
     _stack.add(context);
-    _statementToContext[switchStatement] = context;
+    if (switchStatement != null) {
+      _statementToContext[switchStatement] = context;
+    }
   }
 
   @override
@@ -3908,14 +4016,14 @@
   /// be the last expression that was traversed).  If there is no
   /// [ExpressionInfo] associated with the [expression], then a fresh
   /// [ExpressionInfo] is created recording the current flow analysis state.
-  ExpressionInfo<Type> _expressionEnd(Expression expression) =>
+  ExpressionInfo<Type> _expressionEnd(Expression? expression) =>
       _getExpressionInfo(expression) ?? new _TrivialExpressionInfo(_current);
 
   /// Gets the [ExpressionInfo] associated with the [expression] (which should
   /// be the last expression that was traversed).  If there is no
   /// [ExpressionInfo] associated with the [expression], then `null` is
   /// returned.
-  ExpressionInfo<Type>? _getExpressionInfo(Expression expression) {
+  ExpressionInfo<Type>? _getExpressionInfo(Expression? expression) {
     if (identical(expression, _expressionWithInfo)) {
       ExpressionInfo<Type>? expressionInfo = _expressionInfo;
       _expressionInfo = null;
@@ -3992,7 +4100,8 @@
   Type? _handleProperty(Expression? wholeExpression, Expression? target,
       String propertyName, Object? propertyMember, Type staticType) {
     int targetKey;
-    bool isPromotable = _promotableFields.contains(propertyMember);
+    bool isPromotable = propertyMember != null &&
+        operations.isPropertyPromotable(propertyMember);
     if (target == null) {
       targetKey = promotionKeyStore.thisPromotionKey;
     } else {
@@ -4319,13 +4428,13 @@
   }
 
   @override
-  void ifStatement_thenBegin(Expression condition, Node ifNode) {
+  void ifStatement_thenBegin(Expression? condition, Node ifNode) {
     _conditionalOrIf_thenBegin(condition, ifNode);
   }
 
   @override
   void initialize(
-      Variable variable, Type initializerType, Expression initializerExpression,
+      Variable variable, Type matchedType, Expression? initializerExpression,
       {required bool isFinal,
       required bool isLate,
       required bool isImplicitlyTyped}) {}
@@ -4498,7 +4607,7 @@
   }
 
   @override
-  Type? propertyGet(Expression wholeExpression, Expression target,
+  Type? propertyGet(Expression? wholeExpression, Expression target,
           String propertyName, Object? propertyMember, Type staticType) =>
       null;
 
@@ -4508,13 +4617,26 @@
   }
 
   @override
-  void switchStatement_beginCase(bool hasLabel, Node node) {}
+  void switchStatement_afterGuard(Expression when) {}
+
+  @override
+  void switchStatement_beginAlternatives() {}
+
+  @override
+  void switchStatement_beginCase() {}
 
   @override
   void switchStatement_end(bool isExhaustive) {}
 
   @override
-  void switchStatement_expressionEnd(Statement switchStatement) {}
+  void switchStatement_endAlternative() {}
+
+  @override
+  void switchStatement_endAlternatives(Statement node,
+      {required bool hasLabels}) {}
+
+  @override
+  void switchStatement_expressionEnd(Statement? switchStatement) {}
 
   @override
   void thisOrSuper(Expression expression, Type staticType) {}
@@ -4585,7 +4707,7 @@
     _writeStackForAnd.last.add(variableKey);
   }
 
-  void _conditionalOrIf_thenBegin(Expression condition, Node node) {
+  void _conditionalOrIf_thenBegin(Expression? condition, Node node) {
     _contextStack.add(new _LegacyContext<Type>(_knownTypes));
     AssignedVariablesNodeInfo info = _assignedVariables.getInfoForNode(node);
     Map<int, Type>? newKnownTypes;
@@ -4633,7 +4755,7 @@
 
   /// Gets the [_LegacyExpressionInfo] associated with [expression], if any;
   /// otherwise returns `null`.
-  _LegacyExpressionInfo<Type>? _getExpressionInfo(Expression expression) {
+  _LegacyExpressionInfo<Type>? _getExpressionInfo(Expression? expression) {
     if (identical(expression, _expressionWithInfo)) {
       _LegacyExpressionInfo<Type>? expressionInfo = _expressionInfo;
       _expressionInfo = null;
@@ -4760,6 +4882,14 @@
       'checkpoint: $_checkpoint)';
 }
 
+class _SwitchAlternativesContext<Type extends Object> extends _FlowContext {
+  final FlowModel<Type> _previous;
+
+  FlowModel<Type>? _combinedModel;
+
+  _SwitchAlternativesContext(this._previous);
+}
+
 /// Specialization of [ExpressionInfo] for the case where the information we
 /// have about the expression is trivial (meaning we know by construction that
 /// the expression's [after], [ifTrue], and [ifFalse] models are all the same).
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 8ed8068..ca3aca0 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -1074,7 +1074,7 @@
 const MessageCode messageCompilingWithSoundNullSafety = const MessageCode(
     "CompilingWithSoundNullSafety",
     severity: Severity.info,
-    problemMessage: r"""Compiling with sound null safety""");
+    problemMessage: r"""Compiling with sound null safety.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeCompilingWithoutSoundNullSafety =
@@ -1084,7 +1084,8 @@
 const MessageCode messageCompilingWithoutSoundNullSafety = const MessageCode(
     "CompilingWithoutSoundNullSafety",
     severity: Severity.info,
-    problemMessage: r"""Compiling without sound null safety""");
+    problemMessage: r"""Compiling without sound null safety!
+Dart 3 will only support sound null safety, see https://dart.dev/null-safety""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
@@ -2882,25 +2883,14 @@
     correctionMessage: r"""Try adding an optional parameter to the list.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeEmptyRecordTypeFieldsList =
-    messageEmptyRecordTypeFieldsList;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageEmptyRecordTypeFieldsList = const MessageCode(
-    "EmptyRecordTypeFieldsList",
-    analyzerCodes: <String>["MISSING_IDENTIFIER"],
-    problemMessage: r"""Record type fields list cannot be empty.""",
-    correctionMessage: r"""Try adding a record type field to the list.""");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeEmptyRecordTypeNamedFieldsList =
     messageEmptyRecordTypeNamedFieldsList;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageEmptyRecordTypeNamedFieldsList = const MessageCode(
     "EmptyRecordTypeNamedFieldsList",
-    analyzerCodes: <String>["MISSING_IDENTIFIER"],
-    problemMessage: r"""Record type named fields list cannot be empty.""",
+    index: 129,
+    problemMessage: r"""Record type named fields list can't be empty.""",
     correctionMessage:
         r"""Try adding a record type named field to the list.""");
 
@@ -7132,6 +7122,76 @@
     correctionMessage: r"""Try replacing this with a normal method.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name, String string)>
+    templateJsInteropStaticInteropMockExternalExtensionMemberConflict =
+    const Template<Message Function(String name, String string)>(
+        problemMessageTemplate:
+            r"""External extension member with name '#name' is defined in the following extensions and none are more specific: #string.""",
+        correctionMessageTemplate:
+            r"""Try using the `@JS` annotation to rename conflicting members.""",
+        withArguments:
+            _withArgumentsJsInteropStaticInteropMockExternalExtensionMemberConflict);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String string)>
+    codeJsInteropStaticInteropMockExternalExtensionMemberConflict =
+    const Code<Message Function(String name, String string)>(
+  "JsInteropStaticInteropMockExternalExtensionMemberConflict",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsJsInteropStaticInteropMockExternalExtensionMemberConflict(
+    String name, String string) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (string.isEmpty) throw 'No string provided';
+  return new Message(
+      codeJsInteropStaticInteropMockExternalExtensionMemberConflict,
+      problemMessage:
+          """External extension member with name '${name}' is defined in the following extensions and none are more specific: ${string}.""",
+      correctionMessage: """Try using the `@JS` annotation to rename conflicting members.""",
+      arguments: {'name': name, 'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String name,
+        String name2,
+        String
+            name3)> templateJsInteropStaticInteropMockMissingOverride = const Template<
+        Message Function(
+            String name, String name2, String name3)>(
+    problemMessageTemplate:
+        r"""`@staticInterop` class '#name' has external extension member '#name2', but Dart class '#name3' does not have an overriding instance member.""",
+    correctionMessageTemplate:
+        r"""Add a Dart instance member in '#name3' that overrides '#name.#name2'.""",
+    withArguments: _withArgumentsJsInteropStaticInteropMockMissingOverride);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String name2, String name3)>
+    codeJsInteropStaticInteropMockMissingOverride =
+    const Code<Message Function(String name, String name2, String name3)>(
+  "JsInteropStaticInteropMockMissingOverride",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsJsInteropStaticInteropMockMissingOverride(
+    String name, String name2, String name3) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (name2.isEmpty) throw 'No name provided';
+  name2 = demangleMixinApplicationName(name2);
+  if (name3.isEmpty) throw 'No name provided';
+  name3 = demangleMixinApplicationName(name3);
+  return new Message(codeJsInteropStaticInteropMockMissingOverride,
+      problemMessage:
+          """`@staticInterop` class '${name}' has external extension member '${name2}', but Dart class '${name3}' does not have an overriding instance member.""",
+      correctionMessage: """Add a Dart instance member in '${name3}' that overrides '${name}.${name2}'.""",
+      arguments: {'name': name, 'name2': name2, 'name3': name3});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)>
     templateJsInteropStaticInteropTrustTypesUsageNotAllowed =
     const Template<Message Function(String name)>(
@@ -9125,19 +9185,6 @@
     problemMessage: r"""The class 'Object' can't use mixins.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeOnlyOneRecordTypeFieldsList =
-    messageOnlyOneRecordTypeFieldsList;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageOnlyOneRecordTypeFieldsList = const MessageCode(
-    "OnlyOneRecordTypeFieldsList",
-    analyzerCodes: <String>["MISSING_IDENTIFIER"],
-    problemMessage:
-        r"""Record type fields list cannot contain only one element without a named field.""",
-    correctionMessage:
-        r"""Try adding another record type field to the list or add a named field.""");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeOnlyTry = messageOnlyTry;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -9915,6 +9962,41 @@
     problemMessage: r"""An optional named parameter can't start with '_'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeRecordLiteralEmpty = messageRecordLiteralEmpty;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageRecordLiteralEmpty = const MessageCode(
+    "RecordLiteralEmpty",
+    index: 128,
+    problemMessage: r"""Record literal can't be empty.""",
+    correctionMessage:
+        r"""Try adding elements or use 'Record.empty()' instead.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeRecordLiteralOnePositionalFieldNoTrailingComma =
+    messageRecordLiteralOnePositionalFieldNoTrailingComma;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageRecordLiteralOnePositionalFieldNoTrailingComma =
+    const MessageCode("RecordLiteralOnePositionalFieldNoTrailingComma",
+        index: 127,
+        problemMessage:
+            r"""Record literal with one field requires a trailing comma.""",
+        correctionMessage: r"""Try adding a trailing comma.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeRecordTypeOnePositionalFieldNoTrailingComma =
+    messageRecordTypeOnePositionalFieldNoTrailingComma;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageRecordTypeOnePositionalFieldNoTrailingComma =
+    const MessageCode("RecordTypeOnePositionalFieldNoTrailingComma",
+        index: 130,
+        problemMessage:
+            r"""Record type with one entry requires a trailing comma.""",
+        correctionMessage: r"""Try adding a trailing comma.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeRedirectingConstructorWithAnotherInitializer =
     messageRedirectingConstructorWithAnotherInitializer;
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/class_member_parser.dart b/pkg/_fe_analyzer_shared/lib/src/parser/class_member_parser.dart
index f53db77..773275a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/class_member_parser.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/class_member_parser.dart
@@ -45,7 +45,8 @@
   // This method is overridden for two reasons:
   // 1. Avoid generating events for arguments.
   // 2. Avoid calling skip expression for each argument (which doesn't work).
-  Token parseArgumentsOpt(Token token) => skipArgumentsOpt(token);
+  Token parseArgumentsOpt(Token token, {bool forPattern = false}) =>
+      skipArgumentsOpt(token);
 
   Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
     return skipFunctionBody(token, isExpression, allowAbstract);
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 77e46b2..28d96f2 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -36,6 +36,11 @@
   }
 
   @override
+  void beginBinaryPattern(Token token) {
+    listener?.beginBinaryPattern(token);
+  }
+
+  @override
   void beginBlock(Token token, BlockKind blockKind) {
     listener?.beginBlock(token, blockKind);
   }
@@ -523,6 +528,12 @@
   }
 
   @override
+  void handleExtractorPatternFields(
+      int count, Token beginToken, Token endToken) {
+    listener?.handleExtractorPatternFields(count, beginToken, endToken);
+  }
+
+  @override
   void endAssert(Token assertKeyword, Assert kind, Token leftParenthesis,
       Token? commaToken, Token semicolonToken) {
     listener?.endAssert(
@@ -540,6 +551,11 @@
   }
 
   @override
+  void endBinaryPattern(Token token) {
+    listener?.endBinaryPattern(token);
+  }
+
+  @override
   void handleEndingBinaryExpression(Token token) {
     listener?.handleEndingBinaryExpression(token);
   }
@@ -973,8 +989,8 @@
   }
 
   @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
-    listener?.endLibraryName(libraryKeyword, semicolon);
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
+    listener?.endLibraryName(libraryKeyword, semicolon, hasName);
   }
 
   @override
@@ -1255,6 +1271,11 @@
   }
 
   @override
+  void handleCastPattern(Token operator) {
+    listener?.handleCastPattern(operator);
+  }
+
+  @override
   void handleAssignmentExpression(Token token) {
     listener?.handleAssignmentExpression(token);
   }
@@ -1562,11 +1583,21 @@
   }
 
   @override
+  void handleListPattern(int count, Token beginToken, Token endToken) {
+    listener?.handleListPattern(count, beginToken, endToken);
+  }
+
+  @override
   void handleLiteralMapEntry(Token colon, Token endToken) {
     listener?.handleLiteralMapEntry(colon, endToken);
   }
 
   @override
+  void handleMapPatternEntry(Token colon, Token endToken) {
+    listener?.handleMapPatternEntry(colon, endToken);
+  }
+
+  @override
   void handleLiteralNull(Token token) {
     listener?.handleLiteralNull(token);
   }
@@ -1586,6 +1617,11 @@
   }
 
   @override
+  void handleMapPattern(int count, Token leftBrace, Token rightBrace) {
+    listener?.handleMapPattern(count, leftBrace, rightBrace);
+  }
+
+  @override
   void handleMixinHeader(Token mixinKeyword) {
     listener?.handleMixinHeader(mixinKeyword);
   }
@@ -1601,6 +1637,11 @@
   }
 
   @override
+  void handlePatternField(Token? colon) {
+    listener?.handlePatternField(colon);
+  }
+
+  @override
   void handleNamedRecordField(Token colon) {
     listener?.handleNamedRecordField(colon);
   }
@@ -1681,6 +1722,21 @@
   }
 
   @override
+  void handleNullAssertPattern(Token bang) {
+    listener?.handleNullAssertPattern(bang);
+  }
+
+  @override
+  void handleNullCheckPattern(Token question) {
+    listener?.handleNullCheckPattern(question);
+  }
+
+  @override
+  void handleVariablePattern(Token? keyword, Token variable) {
+    listener?.handleVariablePattern(keyword, variable);
+  }
+
+  @override
   void handleNoType(Token lastConsumed) {
     listener?.handleNoType(lastConsumed);
   }
@@ -1716,8 +1772,8 @@
   }
 
   @override
-  void handleParenthesizedCondition(Token token) {
-    listener?.handleParenthesizedCondition(token);
+  void handleParenthesizedCondition(Token token, Token? case_) {
+    listener?.handleParenthesizedCondition(token, case_);
   }
 
   @override
@@ -1726,8 +1782,13 @@
   }
 
   @override
-  void endRecordLiteral(Token token, int count) {
-    listener?.endRecordLiteral(token, count);
+  void endRecordLiteral(Token token, int count, Token? constKeyword) {
+    listener?.endRecordLiteral(token, count, constKeyword);
+  }
+
+  @override
+  void handleRecordPattern(Token token, int count) {
+    listener?.handleRecordPattern(token, count);
   }
 
   @override
@@ -1736,6 +1797,22 @@
   }
 
   @override
+  void handleParenthesizedPattern(Token token) {
+    listener?.handleParenthesizedPattern(token);
+  }
+
+  @override
+  void handleConstantPattern(Token? constKeyword) {
+    listener?.handleConstantPattern(constKeyword);
+  }
+
+  @override
+  void handleExtractorPattern(
+      Token firstIdentifier, Token? dot, Token? secondIdentifier) {
+    listener?.handleExtractorPattern(firstIdentifier, dot, secondIdentifier);
+  }
+
+  @override
   void handleQualified(Token period) {
     listener?.handleQualified(period);
   }
@@ -1840,6 +1917,11 @@
   }
 
   @override
+  void handleRelationalPattern(Token token) {
+    listener?.handleRelationalPattern(token);
+  }
+
+  @override
   void handleUnescapeError(
       Message message, Token location, int offset, int length) {
     listener?.handleUnescapeError(message, location, offset, length);
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index 78f0c81..90d8adc 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -52,6 +52,13 @@
     logEvent("Arguments");
   }
 
+  /// Called after the parser has consumed a sequence of patternFields that
+  /// forms the arguments to an extractorPattern
+  void handleExtractorPatternFields(
+      int count, Token beginToken, Token endToken) {
+    logEvent("ExtractorPatternFields");
+  }
+
   /// Handle async modifiers `async`, `async*`, `sync`.
   void handleAsyncModifier(Token? asyncToken, Token? starToken) {
     logEvent("AsyncModifier");
@@ -968,7 +975,7 @@
   /// Handle the end of a library directive.  Substructures:
   /// - Metadata
   /// - Library name (a qualified identifier)
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
     logEvent("LibraryName");
   }
 
@@ -976,6 +983,12 @@
     logEvent("LiteralMapEntry");
   }
 
+  /// Called after the parser has consumed a mapPatternEntry, consisting of an
+  /// expression, a colon, and a pattern.
+  void handleMapPatternEntry(Token colon, Token endToken) {
+    logEvent("MapPatternEntry");
+  }
+
   void beginLiteralString(Token token) {}
 
   void handleInterpolationExpression(Token leftBracket, Token? rightBracket) {}
@@ -1371,6 +1384,25 @@
     logEvent("NonNullAssertExpression");
   }
 
+  /// Called after the parser has consumed a null-assert pattern, consisting of
+  /// a pattern followed by a `!` operator.
+  void handleNullAssertPattern(Token bang) {
+    logEvent("NullAssertPattern");
+  }
+
+  /// Called after the parser has consumed a null-check pattern, consisting of a
+  /// pattern followed by a `?` operator.
+  void handleNullCheckPattern(Token question) {
+    logEvent('NullCheckPattern');
+  }
+
+  /// Called after the parser has consumed a variable pattern, consisting of an
+  /// optional `var` or `final` keyword, an optional type annotation, and a
+  /// variable name identifier.
+  void handleVariablePattern(Token? keyword, Token variable) {
+    logEvent('VariablePattern');
+  }
+
   void handleNoName(Token token) {
     logEvent("NoName");
   }
@@ -1518,6 +1550,12 @@
     logEvent("AsOperator");
   }
 
+  /// Called after the parser has consumed a cast pattern, consisting of a
+  /// pattern, `as` operator, and type annotation.
+  void handleCastPattern(Token operator) {
+    logEvent('CastPattern');
+  }
+
   void handleAssignmentExpression(Token token) {
     logEvent("AssignmentExpression");
   }
@@ -1532,6 +1570,15 @@
     logEvent("BinaryExpression");
   }
 
+  /// Called when the parser has consumed the operator of a binary pattern.
+  void beginBinaryPattern(Token token) {}
+
+  /// Called when the parser has consumed a binary pattern, consisting of a LHS
+  /// pattern, `&` or `|` operator, and a RHS pattern.
+  void endBinaryPattern(Token token) {
+    logEvent("BinaryPattern");
+  }
+
   /// Called for `.`, `?.` and `..`.
   void handleEndingBinaryExpression(Token token) {
     // TODO(jensj): push implementation into subclasses
@@ -1706,6 +1753,12 @@
     logEvent("LiteralList");
   }
 
+  /// Called after the parser has consumed a list pattern, consisting of a `[`,
+  /// a comma-separated sequence of patterns, and a `]`.
+  void handleListPattern(int count, Token leftBracket, Token rightBracket) {
+    logEvent("ListPattern");
+  }
+
   void handleLiteralSetOrMap(
     int count,
     Token leftBrace,
@@ -1718,6 +1771,12 @@
     logEvent('LiteralSetOrMap');
   }
 
+  /// Called after the parser has consumed a map pattern, consisting of a `{`,
+  /// a comma-separated sequence of mapPatternEntry, and a `}`.
+  void handleMapPattern(int count, Token leftBrace, Token rightBrace) {
+    logEvent('MapPattern');
+  }
+
   void handleLiteralNull(Token token) {
     logEvent("LiteralNull");
   }
@@ -1730,6 +1789,12 @@
     logEvent("NamedArgument");
   }
 
+  /// Called after the parser has consumed a patternField, consisting of an
+  /// optional identifier, optional `:`, and a pattern.
+  void handlePatternField(Token? colon) {
+    logEvent("PatternField");
+  }
+
   void handleNamedRecordField(Token colon) {
     logEvent("NamedRecordField");
   }
@@ -1784,7 +1849,7 @@
   /// - do while loop
   /// - switch statement
   /// - while loop
-  void handleParenthesizedCondition(Token token) {
+  void handleParenthesizedCondition(Token token, Token? case_) {
     logEvent("ParenthesizedCondition");
   }
 
@@ -1793,10 +1858,16 @@
   void beginParenthesizedExpressionOrRecordLiteral(Token token) {}
 
   /// Ends a record literal with [count] entries.
-  void endRecordLiteral(Token token, int count) {
+  void endRecordLiteral(Token token, int count, Token? constKeyword) {
     logEvent("RecordLiteral");
   }
 
+  /// Called after the parser has consumed a record pattern, consisting of a
+  /// `(`, a comma-separated sequence of patternFields, and a `)`.
+  void handleRecordPattern(Token token, int count) {
+    logEvent("RecordPattern");
+  }
+
   /// End a parenthesized expression.
   /// These may be within the condition expression of a control structure
   /// but will not be the condition of a control structure.
@@ -1804,6 +1875,27 @@
     logEvent("ParenthesizedExpression");
   }
 
+  /// Called after the parser has consumed a parenthesized pattern, consisting
+  /// of a `(`, a pattern, and a `)`.
+  void handleParenthesizedPattern(Token token) {
+    logEvent("ParenthesizedPattern");
+  }
+
+  /// Called after the parser has consumed a constant pattern, consisting of an
+  /// optional `const` and an expression.
+  void handleConstantPattern(Token? constKeyword) {
+    logEvent("ConstantPattern");
+  }
+
+  /// Called after the parser has consumed an extractor pattern, consisting of
+  /// an identifier, optional dot and second identifier, optional type
+  /// arguments, and a parenthesized list of extractor pattern fields (see
+  /// [handleExtractorPatternFields]).
+  void handleExtractorPattern(
+      Token firstIdentifier, Token? dot, Token? secondIdentifier) {
+    logEvent("ExtractorPattern");
+  }
+
   /// Handle a construct of the form "identifier.identifier" occurring in a part
   /// of the grammar where expressions in general are not allowed.
   /// Substructures:
@@ -1851,6 +1943,12 @@
     logEvent("UnaryPrefixExpression");
   }
 
+  /// Called after the parser has consumed a relational pattern, consisting of
+  /// an equality operator or relational operator, followed by an expression.
+  void handleRelationalPattern(Token token) {
+    logEvent("RelationalPattern");
+  }
+
   void handleUnaryPrefixAssignmentExpression(Token token) {
     logEvent("UnaryPrefixAssignmentExpression");
   }
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/literal_entry_info_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/literal_entry_info_impl.dart
index 697726f..bb0c2ec 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/literal_entry_info_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/literal_entry_info_impl.dart
@@ -144,7 +144,8 @@
     final Token ifToken = token.next!;
     assert(optional('if', ifToken));
     parser.listener.beginIfControlFlow(ifToken);
-    Token result = parser.ensureParenthesizedCondition(ifToken);
+    Token result = parser.ensureParenthesizedCondition(ifToken,
+        allowCase: parser.allowPatterns);
     parser.listener.handleThenControlFlow(result);
     return result;
   }
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 cf71d42..98b7595 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -15,11 +15,13 @@
         ASSIGNMENT_PRECEDENCE,
         BeginToken,
         CASCADE_PRECEDENCE,
+        CAST_PATTERN_PRECEDENCE,
         EQUALITY_PRECEDENCE,
         Keyword,
         POSTFIX_PRECEDENCE,
         RELATIONAL_PRECEDENCE,
         SELECTOR_PRECEDENCE,
+        SHIFT_PRECEDENCE,
         StringToken,
         SyntheticBeginToken,
         SyntheticKeywordToken,
@@ -110,6 +112,7 @@
         computeMethodTypeArguments,
         computeType,
         computeTypeParamOrArg,
+        computeVariablePatternType,
         isValidNonRecordTypeReference,
         noType,
         noTypeParamOrArg;
@@ -317,7 +320,17 @@
   // implicit create expression without the special casing.
   final bool useImplicitCreationExpression;
 
-  Parser(this.listener, {this.useImplicitCreationExpression = true})
+  /// Indicates whether pattern parsing is enabled.
+  ///
+  /// This ensures that we don't regress non-pattern functionality while pattern
+  /// parsing logic is being developed.  Eventually we will want to turn this
+  /// functionality on permanently, and leave it to the client to report an
+  /// appropriate error if a pattern is used while patterns are not enabled.
+  /// TODO(paulberry): remove this flag when appropriate.
+  final bool allowPatterns;
+
+  Parser(this.listener,
+      {this.useImplicitCreationExpression = true, this.allowPatterns = false})
       : assert(listener != null); // ignore:unnecessary_null_comparison
 
   bool get inGenerator {
@@ -577,8 +590,23 @@
       // and can be used in a top level declaration
       // as an identifier such as "abstract<T>() => 0;"
       // or as a prefix such as "abstract.A b() => 0;".
+      // This also means that `typedef ({int? j}) => 0;` is a method, but with
+      // records something like `typedef ({int? j}) X();` is a typedef.
       String? nextValue = keyword.next!.stringValue;
-      if (identical(nextValue, '(') || identical(nextValue, '.')) {
+      bool typedefWithRecord = false;
+      if (identical(value, 'typedef') && identical(nextValue, '(')) {
+        Token? endParen = keyword.next!.endGroup;
+        if (endParen != null && endParen.next!.isIdentifier) {
+          // Looks like a typedef with a record.
+          TypeInfo typeInfo = computeType(keyword, /* required = */ false);
+          if (typeInfo is ComplexTypeInfo && typeInfo.recordType) {
+            typedefWithRecord = true;
+          }
+        }
+      }
+
+      if ((identical(nextValue, '(') || identical(nextValue, '.')) &&
+          !typedefWithRecord) {
         directiveState?.checkDeclaration();
         return parseTopLevelMemberImpl(start);
       } else if (identical(nextValue, '<')) {
@@ -654,17 +682,23 @@
 
   /// ```
   /// libraryDirective:
-  ///   'library' qualified ';'
+  ///   'library' qualified? ';'
   /// ;
   /// ```
   Token parseLibraryName(Token libraryKeyword) {
     assert(optional('library', libraryKeyword));
     listener.beginUncategorizedTopLevelDeclaration(libraryKeyword);
     listener.beginLibraryName(libraryKeyword);
-    Token token = parseQualified(libraryKeyword, IdentifierContext.libraryName,
-        IdentifierContext.libraryNameContinuation);
-    token = ensureSemicolon(token);
-    listener.endLibraryName(libraryKeyword, token);
+    Token token = libraryKeyword.next!;
+    bool hasName = !optional(';', token);
+    if (hasName) {
+      token = parseQualified(libraryKeyword, IdentifierContext.libraryName,
+          IdentifierContext.libraryNameContinuation);
+      token = ensureSemicolon(token);
+    } else {
+      token = ensureSemicolon(libraryKeyword);
+    }
+    listener.endLibraryName(libraryKeyword, token, hasName);
     return token;
   }
 
@@ -1394,6 +1428,7 @@
     /// parameterCount counting the presence of named fields as 1.
     int parameterCount = 0;
     bool hasNamedFields = false;
+    bool sawComma = false;
     while (true) {
       Token next = token.next!;
       if (optional(')', next)) {
@@ -1436,15 +1471,17 @@
           }
         }
         break;
+      } else {
+        sawComma = true;
       }
       token = next;
     }
     assert(optional(')', token));
 
-    if (parameterCount == 0) {
-      reportRecoverableError(token, codes.messageEmptyRecordTypeFieldsList);
-    } else if (parameterCount == 1 && !hasNamedFields) {
-      reportRecoverableError(token, codes.messageOnlyOneRecordTypeFieldsList);
+    if (parameterCount == 1 && !hasNamedFields && !sawComma) {
+      // Single non-named element without trailing comma.
+      reportRecoverableError(
+          token, codes.messageRecordTypeOnePositionalFieldNoTrailingComma);
     }
 
     Token? questionMark = token.next!;
@@ -5320,6 +5357,7 @@
   }
 
   int expressionDepth = 0;
+
   Token parseExpression(Token token) {
     if (expressionDepth++ > 500) {
       // This happens in degenerate programs, for example, with a lot of nested
@@ -5433,7 +5471,7 @@
       TypeParamOrArgInfo typeArg, Token token) {
     Token next = token.next!;
     TokenType type = next.type;
-    int tokenLevel = _computePrecedence(next);
+    int tokenLevel = _computePrecedence(next, forPattern: false);
     bool enteredLoop = false;
     for (int level = tokenLevel; level >= precedence; --level) {
       int lastBinaryExpressionLevel = -1;
@@ -5572,7 +5610,7 @@
         }
         next = token.next!;
         type = next.type;
-        tokenLevel = _computePrecedence(next);
+        tokenLevel = _computePrecedence(next, forPattern: false);
       }
       if (_recoverAtPrecedenceLevel && !_currentlyRecovering) {
         // Attempt recovery
@@ -5582,7 +5620,7 @@
           level++;
           next = token.next!;
           type = next.type;
-          tokenLevel = _computePrecedence(next);
+          tokenLevel = _computePrecedence(next, forPattern: false);
         }
       }
     }
@@ -5695,7 +5733,9 @@
     ],
   };
 
-  int _computePrecedence(Token token) {
+  /// Computes the precedence of [token].  [forPattern] indicates whether a
+  /// pattern is being parsed (this changes the precedence of a few operators).
+  int _computePrecedence(Token token, {required bool forPattern}) {
     TokenType type = token.type;
     if (identical(type, TokenType.BANG)) {
       // The '!' has prefix precedence but here it's being used as a
@@ -5717,13 +5757,19 @@
           token.charEnd == token.next!.offset) {
         return TokenType.GT_GT_GT_EQ.precedence;
       }
-    } else if (identical(type, TokenType.QUESTION) &&
-        optional('[', token.next!)) {
-      // "?[" can be a null-aware bracket or a conditional. If it's a
-      // null-aware bracket it has selector precedence.
-      bool isConditional = canParseAsConditional(token);
-      if (!isConditional) {
+    } else if (identical(type, TokenType.QUESTION)) {
+      if (forPattern) {
+        // The '?' has conditional precedence but here it's being used as a
+        // postfix operator as part of a pattern, so it should have selector
+        // precedence.
         return SELECTOR_PRECEDENCE;
+      } else if (optional('[', token.next!)) {
+        // "?[" can be a null-aware bracket or a conditional. If it's a
+        // null-aware bracket it has selector precedence.
+        bool isConditional = canParseAsConditional(token);
+        if (!isConditional) {
+          return SELECTOR_PRECEDENCE;
+        }
       }
     } else if (identical(type, TokenType.IDENTIFIER)) {
       // An identifier at this point is not right. So some recovery is going to
@@ -5732,6 +5778,9 @@
           _tokenRecoveryReplacements.containsKey(token.lexeme)) {
         _recoverAtPrecedenceLevel = true;
       }
+    } else if (forPattern && identical(type, TokenType.AS)) {
+      // Casts bind tighter in patterns.
+      return CAST_PATTERN_PRECEDENCE;
     }
 
     return type.precedence;
@@ -6054,12 +6103,19 @@
     }
     bool old = mayParseFunctionExpressions;
     mayParseFunctionExpressions = true;
-    token = parseParenthesizedExpressionOrRecordLiteral(token);
+    token = parseParenthesizedExpressionOrRecordLiteral(token, null);
     mayParseFunctionExpressions = old;
     return token;
   }
 
-  Token ensureParenthesizedCondition(Token token) {
+  /// Parses an expression inside parentheses that represents the condition part
+  /// of an if-statement, if-element, do-while statement, or while statement, or
+  /// the scrutinee part of a switch statement.  [token] is the token before
+  /// where the `(` is expected.
+  ///
+  /// [allowCase] indicates whether the condition may optionally be followed
+  /// by a caseHead.
+  Token ensureParenthesizedCondition(Token token, {required bool allowCase}) {
     Token openParen = token.next!;
     if (!optional('(', openParen)) {
       // Recover
@@ -6067,12 +6123,15 @@
           openParen, codes.templateExpectedToken.withArguments('('));
       openParen = rewriter.insertParens(token, /* includeIdentifier = */ false);
     }
-    token = parseExpressionInParenthesisRest(openParen);
-    listener.handleParenthesizedCondition(openParen);
+    token = parseExpressionInParenthesisRest(openParen, allowCase: allowCase);
     return token;
   }
 
-  Token parseParenthesizedExpressionOrRecordLiteral(Token token) {
+  /// Parse either a parenthesized expression or a record literal.
+  /// If [constKeywordForRecord] is non-null it is forced to be a record
+  /// literal and an error will be issued if there is no trailing comma.
+  Token parseParenthesizedExpressionOrRecordLiteral(
+      Token token, Token? constKeywordForRecord) {
     Token begin = token.next!;
     assert(optional('(', begin));
     listener.beginParenthesizedExpressionOrRecordLiteral(begin);
@@ -6082,12 +6141,11 @@
 
     token = begin;
     int count = 0;
-    bool wasRecord = false;
+    bool wasRecord = constKeywordForRecord != null;
+    bool wasValidRecord = false;
     while (true) {
       Token next = token.next!;
-      if (count > 0 && optional(')', next)) {
-        // TODO(jensj): Possibly bail out even if count is 0 and give some
-        // specific error.
+      if ((count > 0 || wasRecord) && optional(')', next)) {
         break;
       }
       Token? colon = null;
@@ -6099,6 +6157,7 @@
           IdentifierContext.namedRecordFieldReference,
         ).next!;
         colon = token;
+        wasValidRecord = true;
       }
       token = parseExpression(token);
       next = token.next!;
@@ -6110,6 +6169,7 @@
       } else {
         // It is a comma, i.e. it's a record.
         wasRecord = true;
+        wasValidRecord = true;
       }
       token = next;
     }
@@ -6119,7 +6179,13 @@
     assert(wasRecord || count <= 1);
 
     if (wasRecord) {
-      listener.endRecordLiteral(begin, count);
+      if (count == 0) {
+        reportRecoverableError(token, codes.messageRecordLiteralEmpty);
+      } else if (count == 1 && !wasValidRecord) {
+        reportRecoverableError(
+            token, codes.messageRecordLiteralOnePositionalFieldNoTrailingComma);
+      }
+      listener.endRecordLiteral(begin, count, constKeywordForRecord);
     } else {
       listener.endParenthesizedExpression(begin);
     }
@@ -6127,11 +6193,27 @@
     return token;
   }
 
-  Token parseExpressionInParenthesisRest(Token token) {
+  /// Parses an expression inside parentheses that represents the condition part
+  /// of an if-statement, if-element, do-while statement, or while statement, or
+  /// the scrutinee part of a switch statement.  [token] is the `(` token.
+  ///
+  /// [allowCase] indicates whether the condition may optionally be followed by
+  /// a caseHead.
+  Token parseExpressionInParenthesisRest(Token token,
+      {required bool allowCase}) {
     assert(optional('(', token));
     BeginToken begin = token as BeginToken;
     token = parseExpression(token);
-    token = ensureCloseParen(token, begin);
+    Token next = token.next!;
+    if (allowPatterns && optional('case', next)) {
+      Token case_ = token = next;
+      token = parsePattern(token);
+      token = ensureCloseParen(token, begin);
+      listener.handleParenthesizedCondition(begin, case_);
+    } else {
+      token = ensureCloseParen(token, begin);
+      listener.handleParenthesizedCondition(begin, null);
+    }
     assert(optional(')', token));
     return token;
   }
@@ -6266,6 +6348,8 @@
 
   /// This method parses the portion of a set or map literal that starts with
   /// the left curly brace when there are no leading type arguments.
+  ///
+  /// [forPattern] indicates whether an expression or pattern should be parsed.
   Token parseLiteralSetOrMapSuffix(Token token, Token? constKeyword) {
     Token leftBrace = token = token.next!;
     assert(optional('{', leftBrace));
@@ -6608,6 +6692,13 @@
       listener.endConstLiteral(token.next!);
       return token;
     }
+    if (identical(value, '(')) {
+      // Const record literal.
+      listener.beginConstLiteral(next);
+      token = parseParenthesizedExpressionOrRecordLiteral(token, constKeyword);
+      listener.endConstLiteral(token.next!);
+      return token;
+    }
     if (identical(value, '{')) {
       listener.beginConstLiteral(next);
       listener.handleNoTypeArguments(next);
@@ -6953,6 +7044,7 @@
     return parseArgumentsRest(token.next!);
   }
 
+  /// Parses the rest of an arguments list, where [token] is the `(`.
   Token parseArgumentsRest(Token token) {
     Token begin = token;
     assert(optional('(', begin));
@@ -7028,8 +7120,21 @@
     if (typeInfo.isNullable) {
       Token skipToken = typeInfo.skipType(token);
       Token next = skipToken.next!;
-      if (isOneOfOrEof(next,
-          const [')', '}', ']', '?', '??', ',', ';', ':', 'is', 'as', '..'])) {
+      if (isOneOfOrEof(next, const [
+        ')',
+        '}',
+        ']',
+        '?',
+        '??',
+        ',',
+        ';',
+        ':',
+        'is',
+        'as',
+        '..',
+        '|',
+        '&'
+      ])) {
         // TODO(danrubel): investigate other situations
         // where `?` should be considered part of the type info
         // rather than the start of a conditional expression.
@@ -7423,7 +7528,7 @@
     Token ifToken = token.next!;
     assert(optional('if', ifToken));
     listener.beginIfStatement(ifToken);
-    token = ensureParenthesizedCondition(ifToken);
+    token = ensureParenthesizedCondition(ifToken, allowCase: allowPatterns);
     listener.beginThenStatement(token.next!);
     token = parseStatement(token);
     listener.endThenStatement(token);
@@ -7677,7 +7782,7 @@
     Token whileToken = token.next!;
     assert(optional('while', whileToken));
     listener.beginWhileStatement(whileToken);
-    token = ensureParenthesizedCondition(whileToken);
+    token = ensureParenthesizedCondition(whileToken, allowCase: false);
     listener.beginWhileStatementBody(token.next!);
     LoopState savedLoopState = loopState;
     loopState = LoopState.InsideLoop;
@@ -7709,7 +7814,7 @@
           whileToken, codes.templateExpectedButGot.withArguments('while'));
       whileToken = rewriter.insertSyntheticKeyword(token, Keyword.WHILE);
     }
-    token = ensureParenthesizedCondition(whileToken);
+    token = ensureParenthesizedCondition(whileToken, allowCase: false);
     token = ensureSemicolon(token);
     listener.endDoWhileStatement(doToken, whileToken, token);
     return token;
@@ -7932,13 +8037,7 @@
         // 'on' type catchPart?
         onKeyword = token;
         TypeInfo typeInfo = computeType(token, /* required = */ true);
-        // TODO(jensj): Record types wreak havoc here so waiting for input from
-        // language team. For now pretend like we don't know record types.
-        // https://github.com/dart-lang/language/issues/2406
-        if (catchCount > 0 &&
-            (typeInfo == noType ||
-                typeInfo.recovered ||
-                (typeInfo is ComplexTypeInfo && typeInfo.recordType))) {
+        if (catchCount > 0 && (typeInfo == noType || typeInfo.recovered)) {
           // Not a valid on-clause and we have enough catch counts to be a valid
           // try block already.
           // This could for instance be code like `on([...])` or `on = 42` after
@@ -8068,7 +8167,7 @@
     Token switchKeyword = token.next!;
     assert(optional('switch', switchKeyword));
     listener.beginSwitchStatement(switchKeyword);
-    token = ensureParenthesizedCondition(switchKeyword);
+    token = ensureParenthesizedCondition(switchKeyword, allowCase: false);
     LoopState savedLoopState = loopState;
     if (loopState == LoopState.OutsideLoop) {
       loopState = LoopState.InsideSwitch;
@@ -8123,7 +8222,11 @@
                 caseKeyword, codes.messageSwitchHasCaseAfterDefault);
           }
           listener.beginCaseExpression(caseKeyword);
-          token = parseExpression(caseKeyword);
+          if (allowPatterns) {
+            token = parsePattern(caseKeyword);
+          } else {
+            token = parseExpression(caseKeyword);
+          }
           token = ensureColon(token);
           listener.endCaseExpression(token);
           listener.handleCaseMatch(caseKeyword, token);
@@ -8958,6 +9061,493 @@
     }
     return ch == 0x5B;
   }
+
+  /// pattern               ::= logicalOrPattern
+  /// logicalOrPattern      ::= logicalOrPattern ( '|' logicalAndPattern )?
+  /// logicalAndPattern     ::= logicalAndPattern ( '&' relationalPattern )?
+  /// relationalPattern     ::= ( equalityOperator | relationalOperator)
+  ///                               relationalExpression
+  ///                         | unaryPattern
+  /// unaryPattern          ::= castPattern
+  ///                         | nullCheckPattern
+  ///                         | nullAssertPattern
+  ///                         | primaryPattern
+  /// castPattern ::= primaryPattern 'as' type
+  /// nullAssertPattern ::= primaryPattern '!'
+  /// nullCheckPattern ::= primaryPattern '?'
+  Token parsePattern(Token token, {int precedence = 1}) {
+    assert(precedence >= 1);
+    assert(precedence <= SELECTOR_PRECEDENCE);
+    token = parsePrimaryPattern(token);
+    while (true) {
+      Token next = token.next!;
+      int tokenLevel = _computePrecedence(next, forPattern: true);
+      if (tokenLevel < precedence) return token;
+      switch (next.lexeme) {
+        // castPattern ::= primaryPattern 'as' type
+        case 'as':
+          Token operator = token = next;
+          listener.beginAsOperatorType(token);
+          TypeInfo typeInfo = computeTypeAfterIsOrAs(token);
+          token = typeInfo.ensureTypeNotVoid(token, this);
+          listener.endAsOperatorType(operator);
+          listener.handleCastPattern(operator);
+          // TODO(paulberry): report error if cast is followed by something the
+          // grammar doesn't permit
+          break;
+        case '!':
+          // nullAssertPattern ::= primaryPattern '!'
+          listener.handleNullAssertPattern(next);
+          token = next;
+          break;
+        case '?':
+          // nullCheckPattern ::= primaryPattern '?'
+          listener.handleNullCheckPattern(next);
+          token = next;
+          break;
+        case '&':
+        case '|':
+          listener.beginBinaryPattern(next);
+          // Left associative so we parse the RHS one precedence level higher
+          token = parsePattern(next, precedence: tokenLevel + 1);
+          listener.endBinaryPattern(next);
+          break;
+        default:
+          throw new UnimplementedError('TODO(paulberry): ${next.lexeme}');
+      }
+    }
+  }
+
+  /// primaryPattern        ::= constantPattern
+  ///                         | variablePattern
+  ///                         | parenthesizedPattern
+  ///                         | listPattern
+  ///                         | mapPattern
+  ///                         | recordPattern
+  ///                         | extractorPattern
+  /// listPattern ::= typeArguments? '[' patterns? ']'
+  /// mapPattern        ::= typeArguments? '{' mapPatternEntries? '}'
+  /// mapPatternEntries ::= mapPatternEntry ( ',' mapPatternEntry )* ','?
+  /// mapPatternEntry   ::= expression ':' pattern
+  /// variablePattern ::= ( 'var' | 'final' | 'final'? type )? identifier
+  /// parenthesizedPattern  ::= '(' pattern ')'
+  /// recordPattern         ::= '(' patternFields? ')'
+  /// patternFields         ::= patternField ( ',' patternField )* ','?
+  /// patternField          ::= ( identifier? ':' )? pattern
+  /// constantPattern ::= booleanLiteral
+  ///                   | nullLiteral
+  ///                   | numericLiteral
+  ///                   | stringLiteral
+  ///                   | identifier
+  ///                   | qualifiedName
+  ///                   | constObjectExpression
+  ///                   | 'const' typeArguments? '[' elements? ']'
+  ///                   | 'const' typeArguments? '{' elements? '}'
+  ///                   | 'const' '(' expression ')'
+  /// extractorPattern ::= extractorName typeArguments?
+  ///                          '(' patternFields? ')'
+  /// extractorName    ::= typeIdentifier | qualifiedName
+  Token parsePrimaryPattern(Token token) {
+    TypeParamOrArgInfo typeArg =
+        computeTypeParamOrArg(token, /* inDeclaration = */ true);
+    Token next = typeArg.skip(token).next!;
+    switch (next.lexeme) {
+      case '[]':
+      case '[':
+        // listPattern ::= typeArguments? '[' patterns? ']'
+        token = typeArg.parseArguments(token, this);
+        return parseListPatternSuffix(token);
+      case '{':
+        // mapPattern        ::= typeArguments? '{' mapPatternEntries? '}'
+        // mapPatternEntries ::= mapPatternEntry ( ',' mapPatternEntry )* ','?
+        // mapPatternEntry   ::= expression ':' pattern
+        token = typeArg.parseArguments(token, this);
+        return parseMapPatternSuffix(token);
+    }
+    // Whatever was after the optional type arguments didn't parse as a pattern
+    // that can start with type arguments, so back up and reparse assuming that
+    // we weren't looking at type arguments after all.
+    next = token.next!;
+    switch (next.lexeme) {
+      case 'var':
+      case 'final':
+        // variablePattern ::= ( 'var' | 'final' | 'final'? type )? identifier
+        return parseVariablePattern(token);
+      case '(':
+        // parenthesizedPattern  ::= '(' pattern ')'
+        // recordPattern         ::= '(' patternFields? ')'
+        // patternFields         ::= patternField ( ',' patternField )* ','?
+        // patternField          ::= ( identifier? ':' )? pattern
+        Token nextNext = next.next!;
+        if (optional(')', nextNext)) {
+          listener.handleRecordPattern(next, /* count = */ 0);
+          return nextNext;
+        } else {
+          return parseParenthesizedPatternOrRecordPattern(token);
+        }
+      case 'const':
+        // constantPattern ::= booleanLiteral
+        //                   | nullLiteral
+        //                   | numericLiteral
+        //                   | stringLiteral
+        //                   | identifier
+        //                   | qualifiedName
+        //                   | constObjectExpression
+        //                   | 'const' typeArguments? '[' elements? ']'
+        //                   | 'const' typeArguments? '{' elements? '}'
+        //                   | 'const' '(' expression ')'
+        throw new UnimplementedError('TODO(paulberry)');
+    }
+    TokenType type = next.type;
+    if (type.isRelationalOperator || type.isEqualityOperator) {
+      // TODO(paulberry): maybe handle other operators for error recovery?
+      Token operator = next;
+      // Note: the spec says we should use RELATIONAL_PRECEDENCE here, but
+      // that leads to parsing ambiguities.  So we use SHIFT_PRECEDENCE, as
+      // suggested in https://github.com/dart-lang/language/issues/2501.
+      // TODO(paulberry): update this code if necessary when that issue is
+      // resolved.
+      token = parsePrecedenceExpression(
+          next, SHIFT_PRECEDENCE, /* allowCascades = */ false);
+      listener.handleRelationalPattern(operator);
+      return token;
+    }
+    TypeInfo typeInfo = computeVariablePatternType(token);
+    if (typeInfo != noType) {
+      return parseVariablePattern(token, typeInfo: typeInfo);
+    }
+    // extractorPattern ::= extractorName typeArguments?
+    //                          '(' patternFields? ')'
+    // extractorName    ::= typeIdentifier | qualifiedName
+    // TODO(paulberry): Make sure OTHER_IDENTIFIER is handled
+    // TODO(paulberry): Technically `dynamic` is valid for
+    // `typeIdentifier`--file an issue
+    if (isValidNonRecordTypeReference(next)) {
+      Token beforeFirstIdentifier = token;
+      Token firstIdentifier = token = next;
+      next = token.next!;
+      Token? dot;
+      Token? secondIdentifier;
+      if (optional('.', next)) {
+        dot = token = next;
+        next = token.next!;
+        if (isValidNonRecordTypeReference(next)) {
+          secondIdentifier = token = next;
+          // TODO(paulberry): grammar specifies
+          // `typeIdentifier | qualifiedName`, but that permits `a.b.c`,
+          // which doesn't make sense.
+        } else {
+          throw new UnimplementedError('TODO(paulberry)');
+        }
+      }
+      TypeParamOrArgInfo potentialTypeArg = computeTypeParamOrArg(token);
+      Token afterToken = potentialTypeArg.skip(token).next!;
+      if (optional('(', afterToken) && !potentialTypeArg.recovered) {
+        TypeParamOrArgInfo typeArg = potentialTypeArg;
+        token = typeArg.parseArguments(token, this);
+        token = parseExtractorPatternRest(token);
+        listener.handleExtractorPattern(firstIdentifier, dot, secondIdentifier);
+        return token;
+      }
+      // It's not an extractor pattern so parse it as an expression.
+      token = beforeFirstIdentifier;
+    }
+    // TODO(paulberry): report error if this constant is not permitted by the
+    // grammar
+    token = parseUnaryExpression(token, /* allowCascades = */ false);
+    listener.handleConstantPattern(null);
+    return token;
+  }
+
+  /// Parses variable pattern starting after [token].  [typeInfo] is information
+  /// about the type appearing after [token], if any.
+  ///
+  /// variablePattern ::= ( 'var' | 'final' | 'final'? type )? identifier
+  Token parseVariablePattern(Token token, {TypeInfo typeInfo = noType}) {
+    Token? keyword;
+    if (typeInfo != noType) {
+      token = typeInfo.parseType(token, this);
+    } else {
+      Token next = token.next!;
+      assert(optional('var', next) || optional('final', next));
+      token = keyword = next;
+      // TODO(paulberry): this accepts `var <type> name` as a variable pattern.
+      // We want to accept that for error recovery, but don't forget to report
+      // the appropriate error.
+      typeInfo = computeVariablePatternType(token);
+      token = typeInfo.parseType(token, this);
+    }
+    Token next = token.next!;
+    if (next.isIdentifier) {
+      token = next;
+    } else {
+      // Recovery
+      token = insertSyntheticIdentifier(
+          token, IdentifierContext.localVariableDeclaration);
+    }
+    listener.handleVariablePattern(keyword, token);
+    return token;
+  }
+
+  /// This method parses the portion of a list pattern starting with the left
+  /// bracket.
+  ///
+  /// listPattern ::= typeArguments? '[' patterns? ']'
+  Token parseListPatternSuffix(Token token) {
+    Token beforeToken = token;
+    Token beginToken = token = token.next!;
+    assert(optional('[', token) || optional('[]', token));
+    int count = 0;
+    if (optional('[]', token)) {
+      token = rewriteSquareBrackets(beforeToken).next!;
+      listener.handleListPattern(
+        /* count = */ 0,
+        token,
+        token.next!,
+      );
+      return token.next!;
+    }
+    while (true) {
+      Token next = token.next!;
+      if (optional(']', next)) {
+        token = next;
+        break;
+      }
+      token = parsePattern(token);
+      next = token.next!;
+      ++count;
+      if (!optional(',', next)) {
+        if (optional(']', next)) {
+          token = next;
+          break;
+        }
+
+        // TODO(paulberry): test this error recovery logic
+        // Recovery
+        if (!looksLikeLiteralEntry(next)) {
+          if (beginToken.endGroup!.isSynthetic) {
+            // The scanner has already reported an error,
+            // but inserted `]` in the wrong place.
+            token = rewriter.moveSynthetic(token, beginToken.endGroup!);
+          } else {
+            // Report an error and jump to the end of the list.
+            reportRecoverableError(
+                next, codes.templateExpectedButGot.withArguments(']'));
+            token = beginToken.endGroup!;
+          }
+          break;
+        }
+        // This looks like the start of an expression.
+        // Report an error, insert the comma, and continue parsing.
+        SyntheticToken comma = new SyntheticToken(TokenType.COMMA, next.offset);
+        codes.Message message = codes.templateExpectedButGot.withArguments(',');
+        next = rewriteAndRecover(token, message, comma);
+      }
+      token = next;
+    }
+    listener.handleListPattern(count, beginToken, token);
+    return token;
+  }
+
+  /// This method parses the portion of a map pattern starting with the left
+  /// curly brace.
+  ///
+  /// mapPattern        ::= typeArguments? '{' mapPatternEntries? '}'
+  /// mapPatternEntries ::= mapPatternEntry ( ',' mapPatternEntry )* ','?
+  /// mapPatternEntry   ::= expression ':' pattern
+  Token parseMapPatternSuffix(Token token) {
+    Token leftBrace = token = token.next!;
+    assert(optional('{', leftBrace));
+    Token next = token.next!;
+    if (optional('}', next)) {
+      listener.handleMapPattern(/* count = */ 0, leftBrace, next);
+      return next;
+    }
+
+    int count = 0;
+    while (true) {
+      token = parseExpression(token);
+      Token colon = token.next!;
+      if (!optional(':', colon)) {
+        // TODO(paulberry): test this error recovery logic
+        // Recover from a missing colon by inserting one.
+        colon = rewriteAndRecover(
+            token,
+            codes.templateExpectedButGot.withArguments(':'),
+            new SyntheticToken(TokenType.PERIOD, next.charOffset));
+      }
+      token = parsePattern(colon);
+      listener.handleMapPatternEntry(colon, token.next!);
+      ++count;
+      next = token.next!;
+
+      Token? comma;
+      if (optional(',', next)) {
+        comma = token = next;
+        next = token.next!;
+      }
+      if (optional('}', next)) {
+        listener.handleMapPattern(count, leftBrace, next);
+        return next;
+      }
+
+      if (comma == null) {
+        // TODO(paulberry): test this error recovery logic
+        // Recovery
+        if (looksLikeLiteralEntry(next)) {
+          // If this looks like the start of an expression,
+          // then report an error, insert the comma, and continue parsing.
+          SyntheticToken comma =
+              new SyntheticToken(TokenType.COMMA, next.offset);
+          codes.Message message =
+              codes.templateExpectedButGot.withArguments(',');
+          token = rewriteAndRecover(token, message, comma);
+        } else {
+          reportRecoverableError(
+              next, codes.templateExpectedButGot.withArguments('}'));
+          // Scanner guarantees a closing curly bracket
+          next = leftBrace.endGroup!;
+          listener.handleMapPattern(count, leftBrace, next);
+          return next;
+        }
+      }
+    }
+  }
+
+  /// Parses either a parenthesizedPattern or a recordPattern.
+  ///
+  /// parenthesizedPattern  ::= '(' pattern ')'
+  /// recordPattern         ::= '(' patternFields? ')'
+  /// patternFields         ::= patternField ( ',' patternField )* ','?
+  /// patternField          ::= ( identifier? ':' )? pattern
+  Token parseParenthesizedPatternOrRecordPattern(Token token) {
+    Token begin = token.next!;
+    assert(optional('(', begin));
+
+    token = begin;
+    int count = 0;
+    bool wasRecord = false;
+    bool wasValidRecord = false;
+    while (true) {
+      Token next = token.next!;
+      if ((count > 0 || wasRecord) && optional(')', next)) {
+        break;
+      }
+      Token? colon = null;
+      // TODO(paulberry): test error recovery
+      if (optional(':', next)) {
+        wasRecord = true;
+        wasValidRecord = true;
+        listener.handleNoName(token);
+        colon = token = next;
+      } else if (optional(':', next.next!) || /* recovery */
+          optional(':', next)) {
+        // Record with named expression.
+        wasRecord = true;
+        token = ensureIdentifier(
+          token,
+          IdentifierContext.namedRecordFieldReference,
+        ).next!;
+        colon = token;
+        wasValidRecord = true;
+      }
+      token = parsePattern(token);
+      next = token.next!;
+      if (wasRecord || colon != null) {
+        listener.handlePatternField(colon);
+      }
+      ++count;
+      if (!optional(',', next)) {
+        // TODO(paulberry): make sure to test the error case where there's a
+        // colon but it's not a record.
+        break;
+      } else {
+        // It is a comma, i.e. it's a record.
+        if (!wasRecord && colon == null) {
+          listener.handlePatternField(colon);
+        }
+        wasRecord = true;
+        wasValidRecord = true;
+      }
+      token = next;
+    }
+    token = ensureCloseParen(token, begin);
+    assert(optional(')', token));
+
+    assert(wasRecord || count <= 1);
+
+    if (wasRecord) {
+      if (count == 0) {
+        reportRecoverableError(token, codes.messageRecordLiteralEmpty);
+      } else if (count == 1 && !wasValidRecord) {
+        reportRecoverableError(
+            token, codes.messageRecordLiteralOnePositionalFieldNoTrailingComma);
+      }
+      listener.handleRecordPattern(begin, count);
+    } else {
+      listener.handleParenthesizedPattern(begin);
+    }
+
+    return token;
+  }
+
+  /// Parses the rest of an extractorPattern, where [token] is the token before
+  /// the `(`.
+  ///
+  /// extractorPattern ::= extractorName typeArguments?
+  ///                          '(' patternFields? ')'
+  Token parseExtractorPatternRest(Token token) {
+    Token begin = token = token.next!;
+    assert(optional('(', begin));
+    int argumentCount = 0;
+    bool old = mayParseFunctionExpressions;
+    mayParseFunctionExpressions = true;
+    while (true) {
+      Token next = token.next!;
+      if (optional(')', next)) {
+        token = next;
+        break;
+      }
+      Token? colon = null;
+      if (optional(':', next)) {
+        listener.handleNoName(token);
+        colon = token = next;
+      } else if (optional(':', next.next!)) {
+        token =
+            ensureIdentifier(token, IdentifierContext.namedArgumentReference)
+                .next!;
+        colon = token;
+      }
+      token = parsePattern(token);
+      next = token.next!;
+      listener.handlePatternField(colon);
+      ++argumentCount;
+      if (!optional(',', next)) {
+        if (optional(')', next)) {
+          token = next;
+          break;
+        }
+        // TODO(paulberry): test error recovery
+        // Recovery
+        if (looksLikeExpressionStart(next)) {
+          // If this looks like the start of an expression,
+          // then report an error, insert the comma, and continue parsing.
+          next = rewriteAndRecover(
+              token,
+              codes.templateExpectedButGot.withArguments(','),
+              new SyntheticToken(TokenType.COMMA, next.offset));
+        } else {
+          token = ensureCloseParen(token, begin);
+          break;
+        }
+      }
+      token = next;
+    }
+    assert(optional(')', token));
+    mayParseFunctionExpressions = old;
+    listener.handleExtractorPatternFields(argumentCount, begin, token);
+    return token;
+  }
 }
 
 // TODO(ahe): Remove when analyzer supports generalized function syntax.
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 36da5a1..a7cd257 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
@@ -427,12 +427,12 @@
   }
 
   @override
-  void handleParenthesizedCondition(Token token) {
+  void handleParenthesizedCondition(Token token, Token? case_) {
     debugEvent("handleParenthesizedCondition");
   }
 
   @override
-  void endRecordLiteral(Token token, int count) {
+  void endRecordLiteral(Token token, int count, Token? constKeyword) {
     debugEvent("RecordLiteral");
   }
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart b/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart
index e399e0f..7dee64b 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart
@@ -14,7 +14,7 @@
 
 import 'type_info_impl.dart';
 
-import 'util.dart' show isOneOf, optional;
+import 'util.dart' show isOneOf, isOneOfOrEof, optional;
 
 /// [TypeInfo] provides information collected by [computeType]
 /// about a particular type reference.
@@ -348,6 +348,34 @@
   return noType;
 }
 
+/// Computes the [TypeInfo] for a variable pattern.
+///
+/// This is similar to [computeType], but has special logic to account for an
+/// ambiguity that arises in patterns due to the fact that `as` can either be
+/// an identifier or the operator in a castPattern.
+TypeInfo computeVariablePatternType(Token token) {
+  TypeInfo typeInfo = computeType(token, /* required = */ false);
+  Token afterType = typeInfo.skipType(token);
+  if (!identical(afterType, token)) {
+    Token next = afterType.next!;
+    if (next.isIdentifier) {
+      if (optional('as', next)) {
+        // We've seen `TYPE as`.  `as` is a built-in identifier, so this
+        // *could* be a variable pattern.  Or it could be that TYPE should
+        // have been parsed as a pattern.  It's probably not a variable
+        // pattern (since `as` is an unusual variable name), so we'll only
+        // treat it as a variable pattern if the token following `as` is
+        // something that could legitimately follow a variable pattern (and
+        // hence couldn't introduce a type).
+        if (!mayFollowVariablePattern(next.next!)) {
+          return noType;
+        }
+      }
+    }
+  }
+  return typeInfo;
+}
+
 /// Called by the parser to obtain information about a possible group of type
 /// parameters or type arguments that follow [token].
 /// This does not modify the token stream.
@@ -407,6 +435,23 @@
       : noTypeParamOrArg;
 }
 
+/// Determines whether [token] can validly follow a variable pattern.
+bool mayFollowVariablePattern(Token token) =>
+    isOneOfOrEof(token, _allowedTokensAfterVariablePattern);
+
+const Set<String> _allowedTokensAfterVariablePattern = {
+  ',',
+  ':',
+  '|',
+  '&',
+  ')',
+  '}',
+  ']',
+  'as',
+  '?',
+  '!'
+};
+
 /// Indicates whether the given [token] is allowed to follow a list of type
 /// arguments used as a selector after an expression.
 ///
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart
index 2cf0b4a..d660680 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart
@@ -739,7 +739,8 @@
         }
       } else {
         // Is it e.g. List<(int, int)> or Map<(int, int), (String, String)>?
-        if (!isOneOfOrEof(next, const [",", ">"])) {
+        // or List<List<(int, int)>> or List<List<List<(int, int)>>>.
+        if (!isOneOfOrEof(next, const [",", ">", ">>", ">>>"])) {
           return noType;
         }
       }
@@ -769,6 +770,7 @@
       Token token, final Token endGroup) {
     int parameterCount = 0;
     bool hasNamedFields = false;
+    bool hasComma = false;
     while (true) {
       Token next = token.next!;
       if (optional(')', next)) {
@@ -815,13 +817,14 @@
           return;
         }
         break;
+      } else {
+        hasComma = true;
       }
       token = next;
     }
 
     if (!recovered &&
-        (parameterCount == 0 ||
-            (parameterCount == 1 && !hasNamedFields) ||
+        ((parameterCount == 1 && !hasNamedFields && !hasComma) ||
             token != endGroup)) {
       recovered = true;
       return;
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
index bc3fe89..d9d21af 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
@@ -24,12 +24,13 @@
 const int BITWISE_OR_PRECEDENCE = 9;
 const int BITWISE_XOR_PRECEDENCE = 10;
 const int BITWISE_AND_PRECEDENCE = 11;
-const int SHIFT_PRECEDENCE = 12;
-const int ADDITIVE_PRECEDENCE = 13;
-const int MULTIPLICATIVE_PRECEDENCE = 14;
-const int PREFIX_PRECEDENCE = 15;
-const int POSTFIX_PRECEDENCE = 16;
-const int SELECTOR_PRECEDENCE = 17;
+const int CAST_PATTERN_PRECEDENCE = 12;
+const int SHIFT_PRECEDENCE = 13;
+const int ADDITIVE_PRECEDENCE = 14;
+const int MULTIPLICATIVE_PRECEDENCE = 15;
+const int PREFIX_PRECEDENCE = 16;
+const int POSTFIX_PRECEDENCE = 17;
+const int SELECTOR_PRECEDENCE = 18;
 
 /**
  * The opening half of a grouping pair of tokens. This is used for curly
@@ -516,7 +517,7 @@
    * token.
    */
   @override
-  int get offset => _typeAndOffset >> 8;
+  int get offset => (_typeAndOffset >> 8) - 1;
 
   /**
    * Set the offset from the beginning of the file to the first character in
@@ -525,7 +526,9 @@
   @override
   void set offset(int value) {
     assert(_tokenTypesByIndex.length < 256);
-    _typeAndOffset = (value << 8) | (_typeAndOffset & 0xff);
+    // See https://github.com/dart-lang/sdk/issues/50048 for details.
+    assert(value >= -1);
+    _typeAndOffset = ((value + 1) << 8) | (_typeAndOffset & 0xff);
   }
 
   /**
@@ -551,7 +554,10 @@
    * Initialize a newly created token to have the given [type] and [offset].
    */
   SimpleToken(TokenType type, int offset, [this._precedingComment])
-      : _typeAndOffset = ((offset << 8) | type.index) {
+      : _typeAndOffset = (((offset + 1) << 8) | type.index) {
+    // See https://github.com/dart-lang/sdk/issues/50048 for details.
+    assert(offset >= -1);
+
     // Assert the encoding of the [type] is fully reversible.
     assert(type.index < 256 && _tokenTypesByIndex.length < 256);
     assert(identical(offset, this.offset));
diff --git a/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analysis_result.dart b/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analysis_result.dart
index 116c859..e6c03d3 100644
--- a/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analysis_result.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analysis_result.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 'type_analyzer.dart';
+
 /// Container for the result of running type analysis on an expression.
 ///
 /// This class keeps track of a provisional type of the expression (prior to
@@ -21,6 +23,9 @@
   /// of analyzing `(... as int?)?.isEven`, then calling [resolveShorting] will
   /// cause the `?.` to be desugared (if code generation is occurring) and will
   /// return the type `bool?`.
+  ///
+  /// TODO(paulberry): document what calls back to the client might be made by
+  /// invoking this method.
   Type resolveShorting();
 }
 
@@ -33,6 +38,74 @@
   IntTypeAnalysisResult({required super.type, required this.convertedToDouble});
 }
 
+/// Information about the code context surrounding a pattern match.
+class MatchContext<Node extends Object, Expression extends Node> {
+  /// Simple case where the match context is non-final and there's nothing else
+  /// special going on.
+  static const MatchContext<Never, Never> simpleNonFinal =
+      const MatchContext(isFinal: false, topPattern: null);
+
+  /// If non-`null`, the match is being done in an irrefutable context, and this
+  /// is the surrounding AST node that establishes the irrefutable context.
+  final Node? irrefutableContext;
+
+  /// Indicates whether variables declared in the pattern should be `final`.
+  final bool isFinal;
+
+  /// Indicates whether variables declared in the pattern should be `late`.
+  final bool isLate;
+
+  /// The top level pattern in this pattern match.
+  final Node? topPattern;
+
+  /// The initializer being assigned to this pattern via a variable declaration
+  /// statement, or `null` if this pattern does not occur in a variable
+  /// declaration statement.
+  final Expression? _initializer;
+
+  /// The switch scrutinee, or `null` if this pattern does not occur in a switch
+  /// statement or switch expression.
+  final Expression? _switchScrutinee;
+
+  const MatchContext(
+      {Expression? initializer,
+      this.irrefutableContext,
+      required this.isFinal,
+      this.isLate = false,
+      Expression? switchScrutinee,
+      required this.topPattern})
+      : _initializer = initializer,
+        _switchScrutinee = switchScrutinee;
+
+  /// If the pattern [pattern] is the [topPattern] and there is a corresponding
+  /// initializer expression, returns it.  Otherwise returns `null`.
+  ///
+  /// Note: the type of [pattern] is `Object` to avoid a runtime covariance
+  /// check (which would fail if this method is called on [simpleNonFinal]).
+  Expression? getInitializer(Object pattern) =>
+      identical(pattern, topPattern) ? _initializer : null;
+
+  /// If the pattern [pattern] is the [topPattern] and there is a corresponding
+  /// switch scrutinee expression, returns it.  Otherwise returns `null`.
+  ///
+  /// Note: the type of [pattern] is `Object` to avoid a runtime covariance
+  /// check (which would fail if this method is called on [simpleNonFinal]).
+  Expression? getSwitchScrutinee(Object pattern) =>
+      identical(pattern, topPattern) ? _switchScrutinee : null;
+
+  /// Returns a modified version of `this`, with [irrefutableContext] set to
+  /// `null`.  This is used to suppress cascading errors after reporting
+  /// [TypeAnalyzerErrors.refutablePatternInIrrefutableContext].
+  MatchContext<Node, Expression> makeRefutable() => irrefutableContext == null
+      ? this
+      : new MatchContext(
+          initializer: _initializer,
+          isFinal: isFinal,
+          isLate: isLate,
+          switchScrutinee: _switchScrutinee,
+          topPattern: topPattern);
+}
+
 /// Container for the result of running type analysis on an expression that does
 /// not contain any null shorting.
 class SimpleTypeAnalysisResult<Type extends Object>
@@ -48,3 +121,29 @@
   @override
   Type resolveShorting() => type;
 }
+
+/// Container for the result of running type analysis on an integer literal.
+class SwitchStatementTypeAnalysisResult<Type> {
+  /// Whether the switch statement had a `default` clause.
+  final bool hasDefault;
+
+  /// Whether the switch statement was exhaustive.
+  final bool isExhaustive;
+
+  /// Whether the last case body in the switch statement terminated.
+  final bool lastCaseTerminates;
+
+  /// The number of case bodies in the switch statement (after merging cases
+  /// that share a body).
+  final int numExecutionPaths;
+
+  /// The static type of the scrutinee expression.
+  final Type scrutineeType;
+
+  SwitchStatementTypeAnalysisResult(
+      {required this.hasDefault,
+      required this.isExhaustive,
+      required this.lastCaseTerminates,
+      required this.numExecutionPaths,
+      required this.scrutineeType});
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer.dart b/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer.dart
index 2447096..4ca5963 100644
--- a/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer.dart
@@ -6,6 +6,60 @@
 import 'type_analysis_result.dart';
 import 'type_operations.dart';
 
+/// Information supplied by the client to [TypeAnalyzer.analyzeSwitchExpression]
+/// or [TypeAnalyzer.analyzeSwitchStatement] about a single case head or
+/// `default` clause.
+///
+/// The client is free to `implement` or `extend` this class.
+class CaseHeadOrDefaultInfo<Node extends Object, Expression extends Node> {
+  /// For a `case` clause, the case pattern.  For a `default` clause, `null`.
+  final Node? pattern;
+
+  /// For a `case` clause that has a guard clause, the expression following
+  /// `when`.  Otherwise `null`.
+  final Expression? guard;
+
+  CaseHeadOrDefaultInfo({required this.pattern, this.guard});
+}
+
+/// Information supplied by the client to [TypeAnalyzer.analyzeSwitchExpression]
+/// about an individual `case` or `default` clause.
+///
+/// The client is free to `implement` or `extend` this class.
+class SwitchExpressionMemberInfo<Node extends Object, Expression extends Node> {
+  /// The [CaseOrDefaultHead] associated with this clause.
+  final CaseHeadOrDefaultInfo<Node, Expression> head;
+
+  /// The body of the `case` or `default` clause.
+  final Expression expression;
+
+  SwitchExpressionMemberInfo({required this.head, required this.expression});
+}
+
+/// Information supplied by the client to [TypeAnalyzer.analyzeSwitchStatement]
+/// about an individual `case` or `default` clause.
+///
+/// The client is free to `implement` or `extend` this class.
+class SwitchStatementMemberInfo<Node extends Object, Statement extends Node,
+    Expression extends Node> {
+  /// The list of case heads for this case.
+  ///
+  /// The reason this is a list rather than a single head is because the front
+  /// end merges together cases that share a body at parse time.
+  final List<CaseHeadOrDefaultInfo<Node, Expression>> heads;
+
+  /// The labels preceding this `case` or `default` clause, if any.
+  final List<Node> labels;
+
+  /// The statements following this `case` or `default` clause.  If this list is
+  /// empty, and this is not the last `case` or `default` clause, this clause
+  /// will be considered to share a body with the `case` or `default` clause
+  /// that follows.
+  final List<Statement> body;
+
+  SwitchStatementMemberInfo(this.heads, this.body, {this.labels = const []});
+}
+
 /// Type analysis logic to be shared between the analyzer and front end.  The
 /// intention is that the client's main type inference visitor class can include
 /// this mix-in and call shared analysis logic as needed.
@@ -23,14 +77,69 @@
 /// query the client-specific information (e.g. to obtain the client's
 /// representation of core types), and to trigger recursive analysis of child
 /// AST nodes.
+///
+/// Note that calling an `analyzeX` method is guaranteed to call `dispatch` on
+/// all its subexpressions.  However, we don't specify the precise order in
+/// which this will happen, nor do we always specify which callbacks will be
+/// invoked during analysis, because these details are considered part of the
+/// implementation of type analysis, not its API.  Instead, we specify the
+/// effect that each method has on a conceptual "stack" of entities.
+///
+/// In documentation, the entities in the stack are listed in low-to-high order.
+/// So, for example, if the documentation says the stack contains "(K, L)", then
+/// an entity of kind L is on the top of the stack, with an entity of kind K
+/// under it.  This low-to-high order is used when describing pushes and pops
+/// too, so, for example a method documented with "pushes (K, L)" pushes K
+/// first, then L, whereas a method documented with "pops (K, L)" pops L first,
+/// then K.
+///
+/// In the paragraph above, "K" and "L" are just variables for illustrating the
+/// conventions.  The actual kinds used by the analyzer are concepts from the
+/// language itself such as "Statement", "Expression", "Pattern", etc.  See the
+/// `Kind` enum in `test/mini_ir.dart` for a discussion of all possible kinds of
+/// stack entries.
+///
+/// If multiple stack entries share a kind, we will sometimes add a name to
+/// clarify which stack entry is which, e.g. analyzeIfStatement pushes
+/// "(Expression condition, Statement ifTrue, Statement ifFalse)".
+///
+/// We'll also use the convention that "n * K" represents n consecutive entities
+/// in the stack, each with kind K.
+///
+/// The kind associated with all pushes and pops is statically known (and
+/// documented, and unit tested), and entities never change from one kind to
+/// another.  This fact gives the client considerable freedom in how to actually
+/// represent the stack in practice; for example, they might choose to ignore
+/// some kinds entirely, or represent certain kinds with a block of multiple
+/// stack entries instead of just one.  Or they might choose to multiple stacks,
+/// one for each kind.  It's also possible that some clients won't need to keep
+/// a stack at all.
+///
+/// Reasons a client might want to actually have a stack include:
+/// - Constructing a lowered intermediate representation of the code as a side
+///   effect of analysis,
+/// - Building up a symbolic representation of the program's runtime behavior,
+/// - Or keeping track of AST nodes that need to be replaced (e.g. replacing an
+///   `integer literal` node with a `double literal` node when int->double
+///   conversion happens).
+///
+/// The unit tests in the `_fe_analyzer_shared` package associate a simple
+/// intermediate representation with each stack entry, and also record the kind
+/// of each entry in order to verify that when an entity is popped, it has the
+/// expected kind.
 mixin TypeAnalyzer<Node extends Object, Statement extends Node,
     Expression extends Node, Variable extends Object, Type extends Object> {
+  /// Returns the type `bool`.
+  Type get boolType;
+
   /// Returns the type `double`.
   Type get doubleType;
 
   /// Returns the type `dynamic`.
   Type get dynamicType;
 
+  TypeAnalyzerErrors<Node, Statement, Expression, Variable, Type>? get errors;
+
   /// Returns the client's [FlowAnalysis] object.
   ///
   /// May be `null`, because the analyzer doesn't have a flow analysis object
@@ -41,13 +150,210 @@
   /// Returns the type `int`.
   Type get intType;
 
+  /// Returns the type `Object?`.
+  Type get objectQuestionType;
+
+  /// Options affecting the behavior of [TypeAnalyzer].
+  TypeAnalyzerOptions get options;
+
   /// Returns the client's implementation of the [TypeOperations] class.
-  TypeOperations<Type> get typeOperations;
+  TypeOperations2<Type> get typeOperations;
 
   /// Returns the unknown type context (`?`) used in type inference.
   Type get unknownType;
 
+  /// Analyzes a cast pattern.  [innerPattern] is the sub-pattern] and [type] is
+  /// the type to cast to.
+  ///
+  /// See [dispatchPattern] for the meanings of [matchedType], [typeInfos], and
+  /// [context].
+  ///
+  /// Stack effect: pushes (Pattern innerPattern).
+  void analyzeCastPattern(
+      Type matchedType,
+      Map<Variable, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context,
+      Node innerPattern,
+      Type type) {
+    dispatchPattern(type, typeInfos, context, innerPattern);
+    // Stack: (Pattern)
+  }
+
+  /// Computes the type schema for a cast pattern.
+  ///
+  /// Stack effect: none.
+  Type analyzeCastPatternSchema() => objectQuestionType;
+
+  /// Analyzes a constant pattern.  [node] is the pattern itself, and
+  /// [expression] is the constant expression.  Depending on the client's
+  /// representation, [node] and [expression] might or might not be identical.
+  ///
+  /// See [dispatchPattern] for the meanings of [matchedType], [typeInfos], and
+  /// [context].
+  ///
+  /// Stack effect: pushes (Expression).
+  void analyzeConstantPattern(
+      Type matchedType,
+      Map<Variable, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context,
+      Node node,
+      Expression expression) {
+    // Stack: ()
+    TypeAnalyzerErrors<Node, Node, Expression, Variable, Type>? errors =
+        this.errors;
+    Node? irrefutableContext = context.irrefutableContext;
+    if (irrefutableContext != null) {
+      errors?.refutablePatternInIrrefutableContext(node, irrefutableContext);
+    }
+    Type staticType = analyzeExpression(expression, matchedType);
+    // Stack: (Expression)
+    if (errors != null && !options.patternsEnabled) {
+      Expression? switchScrutinee = context.getSwitchScrutinee(node);
+      if (switchScrutinee != null) {
+        bool nullSafetyEnabled = options.nullSafetyEnabled;
+        bool matches = nullSafetyEnabled
+            ? typeOperations.isSubtypeOf(staticType, matchedType)
+            : typeOperations.isAssignableTo(staticType, matchedType);
+        if (!matches) {
+          errors.caseExpressionTypeMismatch(
+              caseExpression: expression,
+              scrutinee: switchScrutinee,
+              caseExpressionType: staticType,
+              scrutineeType: matchedType,
+              nullSafetyEnabled: nullSafetyEnabled);
+        }
+      }
+    }
+  }
+
+  /// Computes the type schema for a constant pattern.
+  ///
+  /// Stack effect: none.
+  Type analyzeConstantPatternSchema() {
+    // Constant patterns are only allowed in refutable contexts, and refutable
+    // contexts don't propagate a type schema into the scrutinee.  So this
+    // code path is only reachable if the user's code contains errors.
+    errors?.assertInErrorRecovery();
+    return unknownType;
+  }
+
+  /// Analyzes an expression.  [node] is the expression to analyze, and
+  /// [context] is the type schema which should be used for type inference.
+  ///
+  /// Stack effect: pushes (Expression).
+  Type analyzeExpression(Expression node, Type? context) {
+    // Stack: ()
+    if (context == null || typeOperations.isDynamic(context)) {
+      context = unknownType;
+    }
+    ExpressionTypeAnalysisResult<Type> result =
+        dispatchExpression(node, context);
+    // Stack: (Expression)
+    if (typeOperations.isNever(result.provisionalType)) {
+      flow?.handleExit();
+    }
+    return result.resolveShorting();
+  }
+
+  /// Analyzes a statement of the form `if (expression case pattern) ifTrue` or
+  /// `if (expression case pattern) ifTrue else ifFalse`.
+  ///
+  /// [node] should be the AST node for the entire statement, [expression] for
+  /// the expression, [pattern] for the pattern to match, [ifTrue] for the
+  /// "then" branch, and [ifFalse] for the "else" branch (if present).
+  ///
+  /// Stack effect: pushes (Expression scrutinee, Pattern, Expression guard,
+  /// Statement ifTrue, Statement ifFalse).  If there is no `else` clause, the
+  /// representation for `ifFalse` will be pushed by [handleNoStatement].  If
+  /// there is no guard, the representation for `guard` will be pushed by
+  /// [handleNoGuard].
+  void analyzeIfCaseStatement(Statement node, Expression expression,
+      Node pattern, Expression? guard, Statement ifTrue, Statement? ifFalse) {
+    // Stack: ()
+    flow?.ifStatement_conditionBegin();
+    Type initializerType = analyzeExpression(expression, unknownType);
+    // Stack: (Expression)
+    Map<Variable, VariableTypeInfo<Node, Type>> typeInfos = {};
+    // TODO(paulberry): rework handling of isFinal
+    dispatchPattern(initializerType, typeInfos,
+        new MatchContext(isFinal: false, topPattern: pattern), pattern);
+    // Stack: (Expression, Pattern)
+    if (guard != null) {
+      _checkGuardType(guard, analyzeExpression(guard, boolType));
+    } else {
+      handleNoGuard(node, 0);
+    }
+    // Stack: (Expression, Pattern, Guard)
+    flow?.ifStatement_thenBegin(null, node);
+    _analyzeIfCommon(node, ifTrue, ifFalse);
+  }
+
+  /// Analyzes a statement of the form `if (condition) ifTrue` or
+  /// `if (condition) ifTrue else ifFalse`.
+  ///
+  /// [node] should be the AST node for the entire statement, [condition] for
+  /// the condition expression, [ifTrue] for the "then" branch, and [ifFalse]
+  /// for the "else" branch (if present).
+  ///
+  /// Stack effect: pushes (Expression condition, Statement ifTrue, Statement
+  /// ifFalse).  Note that if there is no `else` clause, the representation for
+  /// `ifFalse` will be pushed by [handleNoStatement].
+  void analyzeIfStatement(Statement node, Expression condition,
+      Statement ifTrue, Statement? ifFalse) {
+    // Stack: ()
+    flow?.ifStatement_conditionBegin();
+    analyzeExpression(condition, boolType);
+    // Stack: (Expression condition)
+    flow?.ifStatement_thenBegin(condition, node);
+    _analyzeIfCommon(node, ifTrue, ifFalse);
+  }
+
+  /// Analyzes a variable declaration statement of the form
+  /// `pattern = initializer;`.
+  ///
+  /// [node] should be the AST node for the entire declaration, [pattern] for
+  /// the pattern, and [initializer] for the initializer.  [isFinal] and
+  /// [isLate] indicate whether this is a final declaration and/or a late
+  /// declaration, respectively.
+  ///
+  /// Note that the only kind of pattern allowed in a late declaration is a
+  /// variable pattern; [TypeAnalyzerErrors.patternDoesNotAllowLate] will be
+  /// reported if any other kind of pattern is used.
+  ///
+  /// Stack effect: pushes (Expression, Pattern).
+  void analyzeInitializedVariableDeclaration(
+      Node node, Node pattern, Expression initializer,
+      {required bool isFinal, required bool isLate}) {
+    // Stack: ()
+    if (isLate && !isVariablePattern(pattern)) {
+      errors?.patternDoesNotAllowLate(pattern);
+    }
+    if (isLate) {
+      flow?.lateInitializer_begin(node);
+    }
+    Type initializerType =
+        analyzeExpression(initializer, dispatchPatternSchema(pattern));
+    // Stack: (Expression)
+    if (isLate) {
+      flow?.lateInitializer_end();
+    }
+    Map<Variable, VariableTypeInfo<Node, Type>> typeInfos = {};
+    dispatchPattern(
+        initializerType,
+        typeInfos,
+        new MatchContext(
+            isFinal: isFinal,
+            isLate: isLate,
+            initializer: initializer,
+            irrefutableContext: node,
+            topPattern: pattern),
+        pattern);
+    // Stack: (Expression, Pattern)
+  }
+
   /// Analyzes an integer literal, given the type context [context].
+  ///
+  /// Stack effect: none.
   IntTypeAnalysisResult<Type> analyzeIntLiteral(Type context) {
     bool convertToDouble = !typeOperations.isSubtypeOf(intType, context) &&
         typeOperations.isSubtypeOf(doubleType, context);
@@ -56,17 +362,776 @@
         type: type, convertedToDouble: convertToDouble);
   }
 
+  /// Analyzes a list pattern.  [node] is the pattern itself, [elementType] is
+  /// the list element type (if explicitly supplied), and [elements] is the
+  /// list of subpatterns.
+  ///
+  /// See [dispatchPattern] for the meanings of [matchedType], [typeInfos], and
+  /// [context].
+  ///
+  /// Stack effect: pushes (n * Pattern) where n = elements.length.
+  Type analyzeListPattern(
+      Type matchedType,
+      Map<Variable, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context,
+      Node node,
+      {Type? elementType,
+      required List<Node> elements}) {
+    // Stack: ()
+    Type? matchedElementType = typeOperations.matchListType(matchedType);
+    if (matchedElementType == null) {
+      if (typeOperations.isDynamic(matchedType)) {
+        matchedElementType = dynamicType;
+      } else {
+        matchedElementType = objectQuestionType;
+      }
+    }
+    for (Node element in elements) {
+      dispatchPattern(matchedElementType, typeInfos, context, element);
+    }
+    // Stack: (n * Pattern) where n = elements.length
+    Type requiredType = listType(elementType ?? matchedElementType);
+    Node? irrefutableContext = context.irrefutableContext;
+    if (irrefutableContext != null &&
+        !typeOperations.isAssignableTo(matchedType, requiredType)) {
+      errors?.patternTypeMismatchInIrrefutableContext(
+          pattern: node,
+          context: irrefutableContext,
+          matchedType: matchedType,
+          requiredType: requiredType);
+    }
+    return requiredType;
+  }
+
+  /// Computes the type schema for a list pattern.  [elementType] is the list
+  /// element type (if explicitly supplied), and [elements] is the list of
+  /// subpatterns.
+  ///
+  /// Stack effect: none.
+  Type analyzeListPatternSchema(
+      {Type? elementType, required List<Node> elements}) {
+    if (elementType == null) {
+      if (elements.isEmpty) {
+        return objectQuestionType;
+      }
+      elementType = dispatchPatternSchema(elements[0]);
+      for (int i = 1; i < elements.length; i++) {
+        elementType = typeOperations.glb(
+            elementType!, dispatchPatternSchema(elements[i]));
+      }
+    }
+    return listType(elementType!);
+  }
+
+  /// Analyzes a logical-or or logical-and pattern.  [node] is the pattern
+  /// itself, and [lhs] and [rhs] are the left and right sides of the `|` or `&`
+  /// operator.  [isAnd] indicates whether [node] is a logical-or or a
+  /// logical-and.
+  ///
+  /// See [dispatchPattern] for the meanings of [matchedType], [typeInfos], and
+  /// [context].
+  ///
+  /// Stack effect: pushes (Pattern left, Pattern right)
+  void analyzeLogicalPattern(
+      Type matchedType,
+      Map<Variable, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context,
+      Node node,
+      Node lhs,
+      Node rhs,
+      {required bool isAnd}) {
+    // Stack: ()
+    if (!isAnd) {
+      Node? irrefutableContext = context.irrefutableContext;
+      if (irrefutableContext != null) {
+        errors?.refutablePatternInIrrefutableContext(node, irrefutableContext);
+        // Avoid cascading errors
+        context = context.makeRefutable();
+      }
+    }
+    dispatchPattern(matchedType, typeInfos, context, lhs);
+    // Stack: (Pattern left)
+    dispatchPattern(matchedType, typeInfos, context, rhs);
+    // Stack: (Pattern left, Pattern right)
+  }
+
+  /// Computes the type schema for a logical-or or logical-and pattern.  [lhs]
+  /// and [rhs] are the left and right sides of the `|` or `&` operator.
+  /// [isAnd] indicates whether [node] is a logical-or or a logical-and.
+  ///
+  /// Stack effect: none.
+  Type analyzeLogicalPatternSchema(Node lhs, Node rhs, {required bool isAnd}) {
+    if (isAnd) {
+      return typeOperations.glb(
+          dispatchPatternSchema(lhs), dispatchPatternSchema(rhs));
+    } else {
+      // Logical-or patterns are only allowed in refutable contexts, and
+      // refutable contexts don't propagate a type schema into the scrutinee.
+      // So this code path is only reachable if the user's code contains errors.
+      errors?.assertInErrorRecovery();
+      return unknownType;
+    }
+  }
+
+  /// Analyzes a null-check or null-assert pattern.  [node] is the pattern
+  /// itself, [innerPattern] is the sub-pattern, and [isAssert] indicates
+  /// whether this is a null-check or a null-assert pattern.
+  ///
+  /// See [dispatchPattern] for the meanings of [matchedType], [typeInfos], and
+  /// [context].
+  ///
+  /// Stack effect: pushes (Pattern innerPattern).
+  void analyzeNullCheckOrAssertPattern(
+      Type matchedType,
+      Map<Variable, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context,
+      Node node,
+      Node innerPattern,
+      {required bool isAssert}) {
+    // Stack: ()
+    Type innerMatchedType = typeOperations.promoteToNonNull(matchedType);
+    Node? irrefutableContext = context.irrefutableContext;
+    if (irrefutableContext != null && !isAssert) {
+      errors?.refutablePatternInIrrefutableContext(node, irrefutableContext);
+      // Avoid cascading errors
+      context = context.makeRefutable();
+    }
+    dispatchPattern(innerMatchedType, typeInfos, context, innerPattern);
+    // Stack: (Pattern)
+  }
+
+  /// Computes the type schema for a null-check or null-assert pattern.
+  /// [innerPattern] is the sub-pattern and [isAssert] indicates whether this is
+  /// a null-check or a null-assert pattern.
+  ///
+  /// Stack effect: none.
+  Type analyzeNullCheckOrAssertPatternSchema(Node innerPattern,
+      {required bool isAssert}) {
+    if (isAssert) {
+      return typeOperations.makeNullable(dispatchPatternSchema(innerPattern));
+    } else {
+      // Null-check patterns are only allowed in refutable contexts, and
+      // refutable contexts don't propagate a type schema into the scrutinee.
+      // So this code path is only reachable if the user's code contains errors.
+      errors?.assertInErrorRecovery();
+      return unknownType;
+    }
+  }
+
+  /// Analyzes an expression of the form `switch (expression) { cases }`.
+  ///
+  /// Stack effect: pushes (Expression, n * ExpressionCase), where n is the
+  /// number of cases.
+  SimpleTypeAnalysisResult<Type> analyzeSwitchExpression(
+      Expression node, Expression scrutinee, int numCases, Type context) {
+    // Stack: ()
+    Type expressionType = analyzeExpression(scrutinee, unknownType);
+    // Stack: (Expression)
+    handleSwitchScrutinee(expressionType);
+    flow?.switchStatement_expressionEnd(null);
+    Type? lubType;
+    for (int i = 0; i < numCases; i++) {
+      // Stack: (Expression, i * ExpressionCase)
+      SwitchExpressionMemberInfo<Node, Expression> memberInfo =
+          getSwitchExpressionMemberInfo(node, i);
+      flow?.switchStatement_beginCase();
+      Map<Variable, VariableTypeInfo<Node, Type>> typeInfos = {};
+      Node? pattern = memberInfo.head.pattern;
+      if (pattern != null) {
+        dispatchPattern(
+            expressionType,
+            typeInfos,
+            new MatchContext<Node, Expression>(
+                isFinal: false,
+                switchScrutinee: scrutinee,
+                topPattern: pattern),
+            pattern);
+        // Stack: (Expression, i * ExpressionCase, Pattern)
+        Expression? guard = memberInfo.head.guard;
+        bool hasGuard = guard != null;
+        if (hasGuard) {
+          _checkGuardType(guard, analyzeExpression(guard, boolType));
+          // Stack: (Expression, i * ExpressionCase, Pattern, Expression)
+          flow?.switchStatement_afterGuard(guard);
+        } else {
+          handleNoGuard(node, i);
+          // Stack: (Expression, i * ExpressionCase, Pattern, Expression)
+        }
+        handleCaseHead(node, caseIndex: i, subIndex: 0);
+      } else {
+        handleDefault(node, i);
+      }
+      // Stack: (Expression, i * ExpressionCase, CaseHead)
+      Type type = analyzeExpression(memberInfo.expression, context);
+      // Stack: (Expression, i * ExpressionCase, CaseHead, Expression)
+      if (lubType == null) {
+        lubType = type;
+      } else {
+        lubType = typeOperations.lub(lubType, type);
+      }
+      finishExpressionCase(node, i);
+      // Stack: (Expression, (i + 1) * ExpressionCase)
+    }
+    // Stack: (Expression, numCases * ExpressionCase)
+    flow?.switchStatement_end(true);
+    return new SimpleTypeAnalysisResult<Type>(type: lubType!);
+  }
+
+  /// Analyzes a statement of the form `switch (expression) { cases }`.
+  ///
+  /// Stack effect: pushes (Expression, n * StatementCase), where n is the
+  /// number of cases after merging together cases that share a body.
+  SwitchStatementTypeAnalysisResult<Type> analyzeSwitchStatement(
+      Statement node, Expression scrutinee, int numCases) {
+    // Stack: ()
+    Type scrutineeType = analyzeExpression(scrutinee, unknownType);
+    // Stack: (Expression)
+    handleSwitchScrutinee(scrutineeType);
+    flow?.switchStatement_expressionEnd(node);
+    int numExecutionPaths = 0;
+    int i = 0;
+    bool hasDefault = false;
+    bool lastCaseTerminates = true;
+    while (i < numCases) {
+      // Stack: (Expression, numExecutionPaths * StatementCase)
+      int firstCaseInThisExecutionPath = i;
+      int numHeads = 0;
+      Map<Variable, VariableTypeInfo<Node, Type>> typeInfos = {};
+      flow?.switchStatement_beginCase();
+      flow?.switchStatement_beginAlternatives();
+      bool hasLabels = false;
+      List<Statement> body = const [];
+      while (i < numCases) {
+        // Stack: (Expression, numExecutionPaths * StatementCase,
+        //         numHeads * CaseHead)
+        SwitchStatementMemberInfo<Node, Statement, Expression> memberInfo =
+            getSwitchStatementMemberInfo(node, i);
+        if (memberInfo.labels.isNotEmpty) {
+          hasLabels = true;
+        }
+        List<CaseHeadOrDefaultInfo<Node, Expression>> heads = memberInfo.heads;
+        for (int j = 0; j < heads.length; j++) {
+          CaseHeadOrDefaultInfo<Node, Expression> head = heads[j];
+          Node? pattern = head.pattern;
+          if (pattern != null) {
+            dispatchPattern(
+                scrutineeType,
+                typeInfos,
+                new MatchContext<Node, Expression>(
+                    isFinal: false,
+                    switchScrutinee: scrutinee,
+                    topPattern: pattern),
+                pattern);
+            // Stack: (Expression, numExecutionPaths * StatementCase,
+            //         numHeads * CaseHead, Pattern),
+            Expression? guard = head.guard;
+            bool hasGuard = guard != null;
+            if (hasGuard) {
+              _checkGuardType(guard, analyzeExpression(guard, boolType));
+              // Stack: (Expression, numExecutionPaths * StatementCase,
+              //         numHeads * CaseHead, Pattern, Expression),
+              flow?.switchStatement_afterGuard(guard);
+            } else {
+              handleNoGuard(node, i);
+            }
+            handleCaseHead(node, caseIndex: i, subIndex: j);
+          } else {
+            hasDefault = true;
+            handleDefault(node, i);
+          }
+          numHeads++;
+          // Stack: (Expression, numExecutionPaths * StatementCase,
+          //         numHeads * CaseHead),
+          flow?.switchStatement_endAlternative();
+          body = memberInfo.body;
+        }
+        i++;
+        if (body.isNotEmpty) break;
+      }
+      // Stack: (Expression, numExecutionPaths * StatementCase,
+      //         numHeads * CaseHead)
+      flow?.switchStatement_endAlternatives(node, hasLabels: hasLabels);
+      handleCase_afterCaseHeads(node, firstCaseInThisExecutionPath, numHeads);
+      // Stack: (Expression, numExecutionPaths * StatementCase, CaseHeads)
+      for (Statement statement in body) {
+        dispatchStatement(statement);
+      }
+      // Stack: (Expression, numExecutionPaths * StatementCase, CaseHeads,
+      //         n * Statement), where n = body.length
+      lastCaseTerminates = flow == null || !flow!.isReachable;
+      if (i < numCases &&
+          options.nullSafetyEnabled &&
+          !options.patternsEnabled &&
+          !lastCaseTerminates) {
+        errors?.switchCaseCompletesNormally(node, firstCaseInThisExecutionPath,
+            i - firstCaseInThisExecutionPath);
+      }
+      handleMergedStatementCase(node,
+          caseIndex: i - 1,
+          executionPathIndex: numExecutionPaths,
+          numStatements: body.length);
+      // Stack: (Expression, (numExecutionPaths + 1) * StatementCase)
+      hasLabels = false;
+      numExecutionPaths++;
+    }
+    // Stack: (Expression, numExecutionPaths * StatementCase)
+    bool isExhaustive = hasDefault || isSwitchExhaustive(node, scrutineeType);
+    flow?.switchStatement_end(isExhaustive);
+    return new SwitchStatementTypeAnalysisResult<Type>(
+        hasDefault: hasDefault,
+        isExhaustive: isExhaustive,
+        lastCaseTerminates: lastCaseTerminates,
+        numExecutionPaths: numExecutionPaths,
+        scrutineeType: scrutineeType);
+  }
+
+  /// Analyzes a variable declaration of the form `type variable;` or
+  /// `var variable;`.
+  ///
+  /// [node] should be the AST node for the entire declaration, [variable] for
+  /// the variable, and [declaredType] for the type (if present).  [isFinal] and
+  /// [isLate] indicate whether this is a final declaration and/or a late
+  /// declaration, respectively.
+  ///
+  /// Stack effect: none.
+  ///
+  /// Returns the inferred type of the variable.
+  Type analyzeUninitializedVariableDeclaration(
+      Node node, Variable variable, Type? declaredType,
+      {required bool isFinal, required bool isLate}) {
+    Type inferredType = declaredType ?? dynamicType;
+    flow?.declare(variable, false);
+    setVariableType(variable, inferredType);
+    return inferredType;
+  }
+
+  /// Analyzes a variable pattern.  [node] is the pattern itself, [variable] is
+  /// the variable, [declaredType] is the explicitly declared type (if present),
+  /// and [isFinal] indicates whether the variable is final.
+  ///
+  /// See [dispatchPattern] for the meanings of [matchedType], [typeInfos], and
+  /// [context].
+  ///
+  /// If this is a wildcard pattern (it doesn't bind any variable), [variable]
+  /// should be `null`.
+  ///
+  /// Stack effect: none.
+  Type analyzeVariablePattern(
+      Type matchedType,
+      Map<Variable, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context,
+      Node node,
+      Variable? variable,
+      Type? declaredType,
+      {required bool isFinal}) {
+    Type staticType =
+        declaredType ?? variableTypeFromInitializerType(matchedType);
+    Node? irrefutableContext = context.irrefutableContext;
+    if (irrefutableContext != null &&
+        !typeOperations.isAssignableTo(matchedType, staticType)) {
+      errors?.patternTypeMismatchInIrrefutableContext(
+          pattern: node,
+          context: irrefutableContext,
+          matchedType: matchedType,
+          requiredType: staticType);
+    }
+    bool isImplicitlyTyped = declaredType == null;
+    if (variable != null) {
+      bool isFirstMatch = _recordTypeInfo(typeInfos,
+          pattern: node,
+          variable: variable,
+          staticType: staticType,
+          isImplicitlyTyped: isImplicitlyTyped);
+      if (isFirstMatch) {
+        flow?.declare(variable, false);
+        setVariableType(variable, staticType);
+        // TODO(paulberry): are we handling _isFinal correctly?
+        // TODO(paulberry): do we need to verify that all instances of a
+        // variable are final or all are not final?
+        flow?.initialize(variable, matchedType, context.getInitializer(node),
+            isFinal: context.isFinal || isFinal,
+            isLate: context.isLate,
+            isImplicitlyTyped: isImplicitlyTyped);
+      }
+    }
+    return staticType;
+  }
+
+  /// Computes the type schema for a variable pattern.  [declaredType] is the
+  /// explicitly declared type (if present).
+  ///
+  /// Stack effect: none.
+  Type analyzeVariablePatternSchema(Type? declaredType) =>
+      declaredType ?? unknownType;
+
   /// Calls the appropriate `analyze` method according to the form of
-  /// [expression].
+  /// [expression], and then adjusts the stack as needed to combine any
+  /// sub-structures into a single expression.
   ///
   /// For example, if [node] is a binary expression (`a + b`), calls
   /// [analyzeBinaryExpression].
+  ///
+  /// Stack effect: pushes (Expression).
   ExpressionTypeAnalysisResult<Type> dispatchExpression(
-      Expression expression, Type context);
+      Expression node, Type context);
+
+  /// Calls the appropriate `analyze` method according to the form of [pattern].
+  ///
+  /// [matchedType] is the type of the thing being matched (for a variable
+  /// declaration, this is the type of the initializer or substructure thereof;
+  /// for a switch statement this is the type of the scrutinee or substructure
+  /// thereof).
+  ///
+  /// [typeInfos] is a data structure keeping track of the variable patterns
+  /// seen so far and their type information.
+  ///
+  /// [context] keeps track of other contextual information pertinent to the
+  /// match, such as whether it is late and/or final, whether there is an
+  /// initializer expression (and if so, what it is), and whether the match is
+  /// happening in an irrefutable context (and if so, what surrounding construct
+  /// causes it to be irrefutable).
+  ///
+  /// Stack effect: pushes (Pattern).
+  void dispatchPattern(
+      Type matchedType,
+      Map<Variable, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context,
+      Node node);
+
+  /// Calls the appropriate `analyze...Schema` method according to the form of
+  /// [pattern].
+  ///
+  /// Stack effect: none.
+  Type dispatchPatternSchema(Node pattern);
 
   /// Calls the appropriate `analyze` method according to the form of
-  /// [statement].
+  /// [statement], and then adjusts the stack as needed to combine any
+  /// sub-structures into a single statement.
   ///
   /// For example, if [statement] is a `while` loop, calls [analyzeWhileLoop].
+  ///
+  /// Stack effect: pushes (Statement).
   void dispatchStatement(Statement statement);
+
+  /// Called after visiting an expression case.
+  ///
+  /// [node] is the enclosing switch expression, and [caseIndex] is the index of
+  /// this code path within the switch expression's cases.
+  ///
+  /// Stack effect: pops (CaseHead, Expression) and pushes (ExpressionCase).
+  void finishExpressionCase(Expression node, int caseIndex);
+
+  /// Returns an [ExpressionCaseInfo] object describing the [index]th `case` or
+  /// `default` clause in the switch expression [node].
+  ///
+  /// Note: it is allowed for the client's AST nodes for `case` and `default`
+  /// clauses to implement [ExpressionCaseInfo], in which case this method can
+  /// simply return the [index]th `case` or `default` clause.
+  ///
+  /// See [analyzeSwitchExpression].
+  SwitchExpressionMemberInfo<Node, Expression> getSwitchExpressionMemberInfo(
+      Expression node, int index);
+
+  /// Returns a [StatementCaseInfo] object describing the [index]th `case` or
+  /// `default` clause in the switch statement [node].
+  ///
+  /// Note: it is allowed for the client's AST nodes for `case` and `default`
+  /// clauses to implement [StatementCaseInfo], in which case this method can
+  /// simply return the [index]th `case` or `default` clause.
+  ///
+  /// See [analyzeSwitchStatement].
+  SwitchStatementMemberInfo<Node, Statement, Expression>
+      getSwitchStatementMemberInfo(Statement node, int caseIndex);
+
+  /// Called after visiting a merged set of `case` / `default` clauses.
+  ///
+  /// [node] is the enclosing switch statement, [caseIndex] is the index of the
+  /// first `case` / `default` clause to be merged, and [numHeads] is the number
+  /// of `case` / `default` clauses to be merged.
+  ///
+  /// Stack effect: pops (numHeads * CaseHead) and pushes (CaseHeads).
+  void handleCase_afterCaseHeads(Statement node, int caseIndex, int numHeads);
+
+  /// Called after visiting a single `case` clause, consisting of a pattern and
+  /// an optional guard.
+  ///
+  /// [node] is the enclosing switch statement or switch expression and
+  /// [caseIndex] is the index of the `case` clause.
+  ///
+  /// Stack effect: pops (Pattern, Expression) and pushes (CaseHead).
+  void handleCaseHead(Node node,
+      {required int caseIndex, required int subIndex});
+
+  /// Called after visiting a `default` clause.
+  ///
+  /// [node] is the enclosing switch statement or switch expression and
+  /// [caseIndex] is the index of the `default` clause.
+  ///
+  /// Stack effect: pushes (CaseHead).
+  void handleDefault(Node node, int caseIndex);
+
+  /// Called after visiting a merged statement case.
+  ///
+  /// [node] is enclosing switch statement, [caseIndex] is the index of the last
+  /// `case` or `default` clause in the merged statement case, and
+  /// [numStatements] is the number of statements in the case body.
+  ///
+  /// Stack effect: pops (CaseHeads, numStatements * Statement) and pushes
+  /// (StatementCase).
+  void handleMergedStatementCase(Statement node,
+      {required int caseIndex,
+      required int executionPathIndex,
+      required int numStatements});
+
+  /// Called when visiting a `case` that lacks a guard clause.  Since the lack
+  /// of a guard clause is semantically equivalent to `when true`, this method
+  /// should behave similarly to visiting the boolean literal `true`.
+  ///
+  /// [node] is the enclosing switch statement, switch expression, or `if`, and
+  /// [caseIndex] is the index of the `case` within [node].
+  ///
+  /// Stack effect: pushes (Expression).
+  void handleNoGuard(Node node, int caseIndex);
+
+  /// Called when visiting a syntactic construct where there is an implicit
+  /// no-op statement.  For example, this is called in place of the missing
+  /// `else` part of an `if` statement that lacks an `else` clause.
+  ///
+  /// Stack effect: pushes (Statement).
+  void handleNoStatement(Statement node);
+
+  /// Called after visiting the scrutinee part of a switch statement or switch
+  /// expression.  This is a hook to allow the client to start exhaustiveness
+  /// analysis.
+  ///
+  /// [type] is the static type of the scrutinee expression.
+  ///
+  /// TODO(paulberry): move exhaustiveness analysis into the shared code and
+  /// eliminate this method.
+  ///
+  /// Stack effect: none.
+  void handleSwitchScrutinee(Type type);
+
+  /// Queries whether the switch statement or expression represented by [node]
+  /// was exhaustive.  [expressionType] is the static type of the scrutinee.
+  ///
+  /// Will only be called if the switch statement or expression lacks a
+  /// `default` clause.
+  bool isSwitchExhaustive(Node node, Type expressionType);
+
+  /// Queries whether [pattern] is a variable pattern.
+  bool isVariablePattern(Node pattern);
+
+  /// Returns the type `List`, with type parameter [elementType].
+  Type listType(Type elementType);
+
+  /// Records that type inference has assigned a [type] to a [variable].  This
+  /// is called once per variable, regardless of whether the variable's type is
+  /// explicit or inferred.
+  void setVariableType(Variable variable, Type type);
+
+  /// Computes the type that should be inferred for an implicitly typed variable
+  /// whose initializer expression has static type [type].
+  Type variableTypeFromInitializerType(Type type);
+
+  /// Common functionality shared by [analyzeIfStatement] and
+  /// [analyzeIfCaseStatement].
+  ///
+  /// Stack effect: pushes (Statement ifTrue, Statement ifFalse).
+  void _analyzeIfCommon(Statement node, Statement ifTrue, Statement? ifFalse) {
+    // Stack: ()
+    dispatchStatement(ifTrue);
+    // Stack: (Statement ifTrue)
+    if (ifFalse == null) {
+      handleNoStatement(node);
+      flow?.ifStatement_end(false);
+    } else {
+      flow?.ifStatement_elseBegin();
+      dispatchStatement(ifFalse);
+      flow?.ifStatement_end(true);
+    }
+    // Stack: (Statement ifTrue, Statement ifFalse)
+  }
+
+  void _checkGuardType(Expression expression, Type type) {
+    // TODO(paulberry): harmonize this with analyzer's checkForNonBoolExpression
+    // TODO(paulberry): spec says the type must be `bool` or `dynamic`.  This
+    // logic permits `T extends bool`, `T promoted to bool`, or `Never`.  What
+    // do we want?
+    if (!typeOperations.isAssignableTo(type, boolType)) {
+      errors?.nonBooleanCondition(expression);
+    }
+  }
+
+  /// Records in [typeInfos] that a [pattern] binds a [variable] with a given
+  /// [staticType], and reports any errors caused by type inconsistency.
+  /// [isImplicitlyTyped] indicates whether the variable is implicitly typed in
+  /// this pattern.
+  bool _recordTypeInfo(Map<Variable, VariableTypeInfo<Node, Type>> typeInfos,
+      {required Node pattern,
+      required Variable variable,
+      required Type staticType,
+      required bool isImplicitlyTyped}) {
+    VariableTypeInfo<Node, Type>? typeInfo = typeInfos[variable];
+    if (typeInfo == null) {
+      typeInfos[variable] =
+          new VariableTypeInfo(pattern, staticType, isImplicitlyTyped);
+      return true;
+    } else {
+      TypeAnalyzerErrors<Node, Statement, Expression, Variable, Type>? errors =
+          this.errors;
+      if (errors != null) {
+        if (!typeOperations.isSameType(
+            typeInfo._latestStaticType, staticType)) {
+          errors.inconsistentMatchVar(
+              pattern: pattern,
+              type: staticType,
+              previousPattern: typeInfo._latestPattern,
+              previousType: typeInfo._latestStaticType);
+        } else if (typeInfo._isImplicitlyTyped != isImplicitlyTyped) {
+          errors.inconsistentMatchVarExplicitness(
+              pattern: pattern, previousPattern: typeInfo._latestPattern);
+        }
+      }
+      typeInfo._latestStaticType = staticType;
+      typeInfo._latestPattern = pattern;
+      typeInfo._isImplicitlyTyped = isImplicitlyTyped;
+      return false;
+    }
+  }
+}
+
+/// Interface used by the shared [TypeAnalyzer] logic to report error conditions
+/// up to the client during the "visit" phase of type analysis.
+abstract class TypeAnalyzerErrors<
+    Node extends Object,
+    Statement extends Node,
+    Expression extends Node,
+    Variable extends Object,
+    Type extends Object> implements TypeAnalyzerErrorsBase {
+  /// Called if pattern support is disabled and a case constant's static type
+  /// doesn't properly match the scrutinee's static type.
+  void caseExpressionTypeMismatch(
+      {required Expression scrutinee,
+      required Expression caseExpression,
+      required scrutineeType,
+      required caseExpressionType,
+      required bool nullSafetyEnabled});
+
+  /// Called if a single variable is bound using two different types within the
+  /// same pattern, or between two patterns in a set of case clauses that share
+  /// a body.
+  ///
+  /// [pattern] is the variable pattern that was being processed at the time the
+  /// inconsistency was discovered, and [type] is its type (which might have
+  /// been inferred).  [previousPattern] is the previous variable pattern that
+  /// was binding the same variable, and [previousType] is its type.
+  void inconsistentMatchVar(
+      {required Node pattern,
+      required Type type,
+      required Node previousPattern,
+      required Type previousType});
+
+  /// Called if a single variable is bound both with an explicit type and with
+  /// an implicit type within the same pattern, or between two patterns in a set
+  /// of case clauses that share a body.
+  ///
+  /// [pattern] is the variable pattern that was being processed at the time the
+  /// inconsistency was discovered.  [previousPattern] is the previous variable
+  /// pattern that was binding the same variable.
+  ///
+  /// TODO(paulberry): the spec might be changed so that this is not an error
+  /// condition.  See https://github.com/dart-lang/language/issues/2424.
+  void inconsistentMatchVarExplicitness(
+      {required Node pattern, required Node previousPattern});
+
+  /// Called if the static type of a condition is not assignable to `bool`.
+  void nonBooleanCondition(Expression node);
+
+  /// Called if a pattern is illegally used in a variable declaration statement
+  /// that is marked `late`, and that pattern is not allowed in such a
+  /// declaration.  The only kind of pattern that may be used in a late variable
+  /// declaration is a variable pattern.
+  ///
+  /// [pattern] is the AST node of the illegal pattern.
+  void patternDoesNotAllowLate(Node pattern);
+
+  /// Called if, for a pattern in an irrefutable context, the matched type of
+  /// the pattern is not assignable to the required type.
+  ///
+  /// [pattern] is the AST node of the pattern with the type error, [context] is
+  /// the containing AST node that established an irrefutable context,
+  /// [matchedType] is the matched type, and [requiredType] is the required
+  /// type.
+  void patternTypeMismatchInIrrefutableContext(
+      {required Node pattern,
+      required Node context,
+      required Type matchedType,
+      required Type requiredType});
+
+  /// Called if a refutable pattern is illegally used in an irrefutable context.
+  ///
+  /// [pattern] is the AST node of the refutable pattern, and [context] is the
+  /// containing AST node that established an irrefutable context.
+  ///
+  /// TODO(paulberry): move this error reporting to the parser.
+  void refutablePatternInIrrefutableContext(Node pattern, Node context);
+
+  /// Called if one of the case bodies of a switch statement completes normally
+  /// (other than the last case body), and the "patterns" feature is not
+  /// enabled.
+  ///
+  /// [node] is the AST node of the switch statement.  [caseIndex] is the index
+  /// of the first case sharing the erroneous case body.  [numMergedCases] is
+  /// the number of case heads sharing the erroneous case body.
+  void switchCaseCompletesNormally(
+      Statement node, int caseIndex, int numMergedCases);
+}
+
+/// Base class for error reporting callbacks that might be reported either in
+/// the "pre-visit" or the "visit" phase of type analysis.
+abstract class TypeAnalyzerErrorsBase {
+  /// Called when the [TypeAnalyzer] encounters a condition which should be
+  /// impossible if the user's code is free from static errors, but which might
+  /// arise as a result of error recovery.  To verify this invariant, the client
+  /// should double check (preferably using an assertion) that at least one
+  /// error is reported.
+  ///
+  /// Note that the error might be reported after this method is called.
+  void assertInErrorRecovery();
+}
+
+/// Options affecting the behavior of [TypeAnalyzer].
+///
+/// The client is free to `implement` or `extend` this class.
+class TypeAnalyzerOptions {
+  final bool nullSafetyEnabled;
+
+  final bool patternsEnabled;
+
+  TypeAnalyzerOptions(
+      {required this.nullSafetyEnabled, required this.patternsEnabled});
+}
+
+/// Data structure tracking information about the type of a variable bound by
+/// one or more patterns.
+class VariableTypeInfo<Node extends Object, Type extends Object> {
+  Node _latestPattern;
+
+  /// The static type of [_latestPattern].  This is used to detect
+  /// [TypeAnalyzerErrors.inconsistentMatchVar].
+  Type _latestStaticType;
+
+  /// Indicates whether [_latestPattern] used an implicit type.  This is used to
+  /// detect [TypeAnalyzerErrors.inconsistentMatchVarExplicitness].
+  bool _isImplicitlyTyped;
+
+  VariableTypeInfo(
+      this._latestPattern, this._latestStaticType, this._isImplicitlyTyped);
+
+  /// Indicates whether this variable was implicitly typed.
+  bool get isImplicitlyTyped => _isImplicitlyTyped;
+
+  /// The static type of this variable.
+  Type get staticType => _latestStaticType;
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/type_inference/type_operations.dart b/pkg/_fe_analyzer_shared/lib/src/type_inference/type_operations.dart
index 852daa4..c12d64c 100644
--- a/pkg/_fe_analyzer_shared/lib/src/type_inference/type_operations.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/type_inference/type_operations.dart
@@ -75,3 +75,32 @@
   /// promoted type if it succeeds, otherwise null.
   Type? tryPromoteToType(Type to, Type from);
 }
+
+/// Interface used by [TypeAnalyzer] as a replacement for [TypeOperations].
+///
+/// This interface includes additional methods that are not needed by flow
+/// analysis.
+///
+/// TODO(paulberry): once the analyzer and front end both use [TypeAnalyzer],
+/// combine this mixin with [TypeOperations].
+mixin TypeOperations2<Type extends Object> implements TypeOperations<Type> {
+  /// Computes the greatest lower bound of [type1] and [type2].
+  Type glb(Type type1, Type type2);
+
+  /// Returns `true` if [fromType] is assignable to [toType].
+  bool isAssignableTo(Type fromType, Type toType);
+
+  /// Returns `true` if [type] is the type `dynamic`.
+  bool isDynamic(Type type);
+
+  /// Computes the least upper bound of [type1] and [type2].
+  Type lub(Type type1, Type type2);
+
+  /// Computes the nullable form of [type], in other words the least upper bound
+  /// of [type] and `Null`.
+  Type makeNullable(Type type);
+
+  /// If [type] is a subtype of the type `List<T>` for some `T`, returns the
+  /// type `T`.  Otherwise returns `null`.
+  Type? matchListType(Type type);
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/type_inference/variable_bindings.dart b/pkg/_fe_analyzer_shared/lib/src/type_inference/variable_bindings.dart
new file mode 100644
index 0000000..dc5231d
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/type_inference/variable_bindings.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2022, 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 'type_analyzer.dart';
+
+/// Data structure for tracking all the variable bindings used by a pattern or
+/// a collection of patterns.
+class VariableBinder<Node extends Object, Variable extends Object,
+    Type extends Object> {
+  final VariableBindingCallbacks<Node, Variable, Type> _callbacks;
+
+  final Map<Variable, VariableBinding<Node>> _bindings = {};
+
+  /// Stack reflecting the nesting of alternatives under consideration.
+  ///
+  /// Each entry in the outer list represents a nesting level of alternatives,
+  /// corresponding to a call to [startAlternatives] that has not yet been
+  /// matched by a call to [finishAlternatives].  Each inner list contains the
+  /// list of alternatives that have been passed to [startAlternative] so far
+  /// at the corresponding nesting level.
+  List<List<Node>> _alternativesStack = [];
+
+  /// The innermost alternative for which variable bindings are currently being
+  /// accumulated.
+  Node? _currentAlternative;
+
+  VariableBinder(this._callbacks);
+
+  /// Updates the set of bindings to account for the presence of a variable
+  /// pattern.  [pattern] is the variable pattern, [variable] is the variable it
+  /// refers to, [staticType] is the static type of the variable (inferred or
+  /// declared), and [isImplicitlyTyped] indicates whether the variable pattern
+  /// had an explicit type.
+  bool add(Node pattern, Variable variable) {
+    VariableBinding<Node>? binding = _bindings[variable];
+    VariableBinderErrors<Node, Variable>? errors = _callbacks.errors;
+    if (binding == null) {
+      if (errors != null) {
+        for (List<Node> alternatives in _alternativesStack) {
+          for (int i = 0; i < alternatives.length - 1; i++) {
+            errors.missingMatchVar(alternatives[i], variable);
+          }
+        }
+      }
+      _bindings[variable] = new VariableBinding._(pattern,
+          currentAlternative: _currentAlternative);
+      return true;
+    } else {
+      if (identical(_currentAlternative, binding._latestAlternative)) {
+        errors?.matchVarOverlap(
+            pattern: pattern, previousPattern: binding._latestPattern);
+      }
+      binding._latestPattern = pattern;
+      binding._latestAlternative = _currentAlternative;
+      return false;
+    }
+  }
+
+  /// Performs a debug check that start/finish calls were properly nested.
+  /// Should be called after all the alternatives have been visited.
+  void finish() {
+    assert(_alternativesStack.isEmpty);
+  }
+
+  /// Called at the end of processing an alternative (either the left or right
+  /// hand side of a logical-or pattern, or one of the cases in a set of cases
+  /// that share a body).
+  void finishAlternative() {
+    if (_alternativesStack.last.length > 1) {
+      Node previousAlternative =
+          _alternativesStack.last[_alternativesStack.last.length - 2];
+      for (MapEntry<Variable, VariableBinding<Node>> entry
+          in _bindings.entries) {
+        VariableBinding<Node> variable = entry.value;
+        if (identical(variable._latestAlternative, previousAlternative)) {
+          // For error recovery, pretend it wasn't missing.
+          _callbacks.errors?.missingMatchVar(_currentAlternative!, entry.key);
+          variable._latestAlternative = _currentAlternative;
+        }
+      }
+    }
+  }
+
+  /// Called at the end of processing a set of alternatives (either a logical-or
+  /// pattern, or all of the cases in a set of cases that share a body).
+  void finishAlternatives() {
+    List<Node> alternatives = _alternativesStack.removeLast();
+    if (alternatives.isEmpty) {
+      _callbacks.errors?.assertInErrorRecovery();
+      // Do nothing; it will be as if `startAlternatives` was never called.
+    } else {
+      Node lastAlternative = alternatives.last;
+      _currentAlternative =
+          _alternativesStack.isEmpty ? null : _alternativesStack.last.last;
+      for (VariableBinding<Node> binding in _bindings.values) {
+        if (identical(binding._latestAlternative, lastAlternative)) {
+          binding._latestAlternative = _currentAlternative;
+        }
+      }
+    }
+  }
+
+  /// Called at the start of processing an alternative (either the left or right
+  /// hand side of a logical-or pattern, or one of the cases in a set of cases
+  /// that share a body).
+  void startAlternative(Node alternative) {
+    _currentAlternative = alternative;
+    _alternativesStack.last.add(alternative);
+  }
+
+  /// Called at the end of processing a set of alternatives (either a logical-or
+  /// pattern, or all of the cases in a set of cases that share a body).
+  void startAlternatives() {
+    _alternativesStack.add([]);
+  }
+}
+
+/// Interface used by the [VariableBinder] logic to report error conditions
+/// up to the client during the "pre-visit" phase of type analysis.
+abstract class VariableBinderErrors<Node extends Object,
+    Variable extends Object> extends TypeAnalyzerErrorsBase {
+  /// Called if two subpatterns of a pattern attempt to declare the same
+  /// variable (with the exception of `_` and logical-or patterns).
+  ///
+  /// [pattern] is the variable pattern that was being processed at the time the
+  /// overlap was discovered.  [previousPattern] is the previous variable
+  /// pattern that overlaps with it.
+  void matchVarOverlap({required Node pattern, required Node previousPattern});
+
+  /// Called if a variable is bound by one of the alternatives of a logical-or
+  /// pattern but not the other, or if it is bound by one of the cases in a set
+  /// of case clauses that share a body, but not all of them.
+  ///
+  /// [alternative] is the AST node which fails to bind the variable.  This will
+  /// either be one of the immediate sub-patterns of a logical-or pattern, or a
+  /// value of [StatementCaseInfo.node].
+  ///
+  /// [variable] is the variable that is not bound within [alternative].
+  void missingMatchVar(Node alternative, Variable variable);
+}
+
+/// Information about how a single variable is bound within a pattern (or in the
+/// case of several case clauses that share a body, a collection of patterns).
+class VariableBinding<Node extends Object> {
+  /// The most recently seen variable pattern that binds [variable].
+  Node _latestPattern;
+
+  /// The alternative enclosing [_latestPattern].  This is used to detect
+  /// [TypeAnalyzerErrors.matchVarOverlap].
+  Node? _latestAlternative;
+
+  VariableBinding._(this._latestPattern, {required Node? currentAlternative})
+      : _latestAlternative = currentAlternative;
+}
+
+/// Callbacks used by [VariableBindings] to access members of [TypeAnalyzer].
+abstract class VariableBindingCallbacks<Node extends Object,
+    Variable extends Object, Type extends Object> {
+  /// Returns the interface for reporting error conditions up to the client.
+  VariableBinderErrors<Node, Variable>? get errors;
+}
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index eccba85..2b27bc4 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
 name: _fe_analyzer_shared
-version: 46.0.0
+version: 49.0.0
 description: Logic that is shared between the front_end and analyzer packages.
 repository: https://github.com/dart-lang/sdk/tree/main/pkg/_fe_analyzer_shared
 
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
index 66cd877..9f0f424 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
@@ -3,23 +3,24 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
-import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/promotion_key_store.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/type_operations.dart';
 
 import '../mini_ast.dart';
+import '../mini_ir.dart';
 import '../mini_types.dart';
 
 /// Creates a [Statement] that, when analyzed, will cause [callback] to be
 /// passed an [SsaNodeHarness] allowing the test to examine the values of
 /// variables' SSA nodes.
 Statement getSsaNodes(void Function(SsaNodeHarness) callback) =>
-    new _GetSsaNodes(callback);
+    new _GetSsaNodes(callback, location: computeLocation());
 
 Statement implicitThis_whyNotPromoted(String staticType,
         void Function(Map<Type, NonPromotionReason>) callback) =>
-    new _WhyNotPromoted_ImplicitThis(Type(staticType), callback);
+    new _WhyNotPromoted_ImplicitThis(Type(staticType), callback,
+        location: computeLocation());
 
 /// Test harness for creating flow analysis tests.  This class implements all
 /// the [Operations] needed by flow analysis, as well as other methods needed
@@ -48,16 +49,17 @@
 
   final void Function(ExpressionInfo<Type>?) callback;
 
-  _GetExpressionInfo(this.target, this.callback);
+  _GetExpressionInfo(this.target, this.callback, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    target.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    target.preVisit(visitor);
   }
 
   @override
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
-    var type = h.typeAnalyzer.analyzeExpression(target);
+    var type =
+        h.typeAnalyzer.analyzeExpression(target, h.typeAnalyzer.unknownType);
     h.flow.forwardExpression(this, target);
     callback(h.flow.expressionInfoForTesting(this));
     return new SimpleTypeAnalysisResult<Type>(type: type);
@@ -67,15 +69,15 @@
 class _GetSsaNodes extends Statement {
   final void Function(SsaNodeHarness) callback;
 
-  _GetSsaNodes(this.callback);
+  _GetSsaNodes(this.callback, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   void visit(Harness h) {
     callback(SsaNodeHarness(h.flow));
-    h.irBuilder.atom('null');
+    h.irBuilder.atom('null', Kind.statement, location: location);
   }
 }
 
@@ -84,11 +86,11 @@
 
   final void Function(Map<Type, NonPromotionReason>) callback;
 
-  _WhyNotPromoted(this.target, this.callback);
+  _WhyNotPromoted(this.target, this.callback, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    target.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    target.preVisit(visitor);
   }
 
   @override
@@ -96,7 +98,8 @@
 
   @override
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
-    var type = h.typeAnalyzer.analyzeExpression(target);
+    var type =
+        h.typeAnalyzer.analyzeExpression(target, h.typeAnalyzer.unknownType);
     h.flow.forwardExpression(this, target);
     Type.withComparisonsAllowed(() {
       callback(h.flow.whyNotPromoted(this)());
@@ -110,10 +113,11 @@
 
   final void Function(Map<Type, NonPromotionReason>) callback;
 
-  _WhyNotPromoted_ImplicitThis(this.staticType, this.callback);
+  _WhyNotPromoted_ImplicitThis(this.staticType, this.callback,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() => 'implicit this (whyNotPromoted)';
@@ -123,7 +127,7 @@
     Type.withComparisonsAllowed(() {
       callback(h.flow.whyNotPromotedImplicitThis(staticType)());
     });
-    h.irBuilder.atom('noop');
+    h.irBuilder.atom('noop', Kind.statement, location: location);
   }
 }
 
@@ -134,7 +138,7 @@
   /// analysis information associated with it, `null` will be passed to
   /// [callback].
   Expression getExpressionInfo(void Function(ExpressionInfo<Type>?) callback) =>
-      new _GetExpressionInfo(this, callback);
+      new _GetExpressionInfo(this, callback, location: computeLocation());
 
   /// Creates an [Expression] that, when analyzed, will behave the same as
   /// `this`, but after visiting it, will cause [callback] to be passed the
@@ -142,5 +146,5 @@
   /// non-promotion info, an empty map will be passed to [callback].
   Expression whyNotPromoted(
           void Function(Map<Type, NonPromotionReason>) callback) =>
-      new _WhyNotPromoted(this, callback);
+      new _WhyNotPromoted(this, callback, location: computeLocation());
 }
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index 14c510f..e6b1c35 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -1333,6 +1333,7 @@
         'parameter types', () {
       test('when not final', () {
         var x = Var('x');
+        h.addSubtype('T&int', 'T', true);
         h.run([
           declare(x, type: 'T', initializer: expr('T&int')),
           checkNotPromoted(x),
@@ -1341,6 +1342,7 @@
 
       test('when final', () {
         var x = Var('x');
+        h.addSubtype('T&int', 'T', true);
         h.run([
           declare(x, isFinal: true, type: 'T', initializer: expr('T&int')),
           checkNotPromoted(x),
@@ -1628,10 +1630,11 @@
 
     test('labeledBlock without break', () {
       var x = Var('x');
+      var l = Label('l');
       h.run([
         declare(x, type: 'int?', initializer: expr('int?')),
         if_(x.expr.isNot('int'), [
-          labeled((_) => return_()),
+          l.thenStmt(return_()),
         ]),
         checkPromoted(x, 'int'),
       ]);
@@ -1639,15 +1642,16 @@
 
     test('labeledBlock with break joins', () {
       var x = Var('x');
+      var l = Label('l');
       h.run([
         declare(x, type: 'int?', initializer: expr('int?')),
         if_(x.expr.isNot('int'), [
-          labeled((t) => block([
-                if_(expr('bool'), [
-                  break_(t),
-                ]),
-                return_(),
-              ])),
+          l.thenStmt(block([
+            if_(expr('bool'), [
+              break_(l),
+            ]),
+            return_(),
+          ])),
         ]),
         checkNotPromoted(x),
       ]);
@@ -1861,6 +1865,38 @@
       ]);
     });
 
+    test('ifCase splits control flow', () {
+      var x = Var('x');
+      var y = Var('y');
+      var z = Var('z');
+      var w = Var('w');
+      h.run([
+        declare(x, type: 'int'),
+        declare(y, type: 'int'),
+        declare(z, type: 'int'),
+        ifCase(expr('num'), w.pattern(type: 'int'), [
+          x.write(expr('int')).stmt,
+          y.write(expr('int')).stmt,
+        ], else_: [
+          y.write(expr('int')).stmt,
+          z.write(expr('int')).stmt,
+        ]),
+        checkAssigned(x, false),
+        checkAssigned(y, true),
+        checkAssigned(z, false),
+      ]);
+    });
+
+    test('ifCase does not promote when expression true', () {
+      var x = Var('x');
+      h.run([
+        declare(x, type: 'int?', initializer: expr('int?')),
+        ifCase(x.expr.notEq(nullLiteral), intLiteral(0).pattern, [
+          checkNotPromoted(x),
+        ]),
+      ]);
+    });
+
     test('promote promotes to a subtype and sets type of interest', () {
       var x = Var('x');
       h.run([
@@ -1910,20 +1946,120 @@
       ]);
     });
 
+    test('switchExpression throw in scrutinee makes all cases unreachable', () {
+      h.run([
+        switchExpr(throw_(expr('C')), [
+          intLiteral(0)
+              .pattern
+              .thenExpr(checkReachable(false).thenExpr(intLiteral(1))),
+          default_.thenExpr(checkReachable(false).thenExpr(intLiteral(2))),
+        ]).stmt,
+        checkReachable(false),
+      ]);
+    });
+
+    test('switchExpression throw in case body has isolated effect', () {
+      h.run([
+        switchExpr(expr('int'), [
+          intLiteral(0).pattern.thenExpr(throw_(expr('C'))),
+          default_.thenExpr(checkReachable(true).thenExpr(intLiteral(2))),
+        ]).stmt,
+        checkReachable(true),
+      ]);
+    });
+
+    test('switchExpression throw in all case bodies affects flow after', () {
+      h.run([
+        switchExpr(expr('int'), [
+          intLiteral(0).pattern.thenExpr(throw_(expr('C'))),
+          default_.thenExpr(throw_(expr('C'))),
+        ]).stmt,
+        checkReachable(false),
+      ]);
+    });
+
+    test('switchExpression var promotes', () {
+      var x = Var('x');
+      h.run([
+        switchExpr(expr('int'), [
+          x
+              .pattern(type: 'int?')
+              .thenExpr(checkPromoted(x, 'int').thenExpr(nullLiteral)),
+        ]).stmt,
+      ]);
+    });
+
+    test('switchStatement throw in scrutinee makes all cases unreachable', () {
+      h.run([
+        switch_(
+            throw_(expr('C')),
+            [
+              intLiteral(0).pattern.then([
+                checkReachable(false),
+              ]),
+              intLiteral(1).pattern.then([
+                checkReachable(false),
+              ]),
+            ],
+            isExhaustive: false),
+        checkReachable(false),
+      ]);
+    });
+
+    test('switchStatement var promotes', () {
+      var x = Var('x');
+      h.run([
+        switch_(
+            expr('int'),
+            [
+              x.pattern(type: 'int?').then([
+                checkPromoted(x, 'int'),
+              ]),
+            ],
+            isExhaustive: true),
+      ]);
+    });
+
+    test('switchStatement_afterWhen() promotes', () {
+      var x = Var('x');
+      h.run([
+        switch_(
+            expr('num'),
+            [
+              x.pattern().when(x.expr.is_('int')).then([
+                checkPromoted(x, 'int'),
+              ]),
+            ],
+            isExhaustive: true),
+      ]);
+    });
+
+    test('switchStatement_afterWhen() called for switch expressions', () {
+      var x = Var('x');
+      h.run([
+        switchExpr(expr('num'), [
+          x
+              .pattern()
+              .when(x.expr.is_('int'))
+              .thenExpr(checkPromoted(x, 'int').thenExpr(expr('String'))),
+        ]).stmt,
+      ]);
+    });
+
     test('switchStatement_beginCase(false) restores previous promotions', () {
       var x = Var('x');
       h.run([
         declare(x, type: 'int?', initializer: expr('int?')),
         x.expr.as_('int').stmt,
         switch_(
-            expr('Null'),
+            expr('int'),
             [
-              case_([
+              intLiteral(0).pattern.then([
                 checkPromoted(x, 'int'),
                 x.write(expr('int?')).stmt,
                 checkNotPromoted(x),
               ]),
-              case_([
+              intLiteral(1).pattern.then([
                 checkPromoted(x, 'int'),
                 x.write(expr('int?')).stmt,
                 checkNotPromoted(x),
@@ -1939,9 +2075,9 @@
         declare(x, type: 'int?', initializer: expr('int?')),
         x.expr.as_('int').stmt,
         switch_(
-            expr('Null'),
+            expr('int'),
             [
-              case_([
+              intLiteral(0).pattern.then([
                 checkPromoted(x, 'int'),
                 x.write(expr('int?')).stmt,
                 checkNotPromoted(x),
@@ -1958,9 +2094,9 @@
         declare(x, type: 'int?', initializer: expr('int?')),
         x.expr.as_('int').stmt,
         switch_(
-            expr('Null'),
+            expr('int'),
             [
-              case_([
+              intLiteral(0).pattern.then([
                 checkPromoted(x, 'int'),
                 localFunction([
                   x.write(expr('int?')).stmt,
@@ -1974,23 +2110,24 @@
 
     test('switchStatement_beginCase(true) un-promotes', () {
       var x = Var('x');
+      var l = Label('l');
       late SsaNode<Type> ssaBeforeSwitch;
       h.run([
         declare(x, type: 'int?', initializer: expr('int?')),
         x.expr.as_('int').stmt,
         switch_(
-            expr('Null').thenStmt(block([
+            expr('int').thenStmt(block([
               checkPromoted(x, 'int'),
               getSsaNodes((nodes) => ssaBeforeSwitch = nodes[x]!),
             ])),
             [
-              case_([
+              l.then(intLiteral(0).pattern).then([
                 checkNotPromoted(x),
                 getSsaNodes(
                     (nodes) => expect(nodes[x], isNot(ssaBeforeSwitch))),
                 x.write(expr('int?')).stmt,
                 checkNotPromoted(x),
-              ], hasLabel: true),
+              ]),
             ],
             isExhaustive: false),
       ]);
@@ -1998,20 +2135,21 @@
 
     test('switchStatement_beginCase(true) handles write captures in cases', () {
       var x = Var('x');
+      var l = Label('l');
       h.run([
         declare(x, type: 'int?', initializer: expr('int?')),
         x.expr.as_('int').stmt,
         switch_(
-            expr('Null'),
+            expr('int'),
             [
-              case_([
+              l.then(intLiteral(0).pattern).then([
                 x.expr.as_('int').stmt,
                 checkNotPromoted(x),
                 localFunction([
                   x.write(expr('int?')).stmt,
                 ]),
                 checkNotPromoted(x),
-              ], hasLabel: true),
+              ]),
             ],
             isExhaustive: false),
       ]);
@@ -2028,9 +2166,9 @@
         y.expr.as_('int').stmt,
         z.expr.as_('int').stmt,
         switch_(
-            expr('Null'),
+            expr('int'),
             [
-              case_([
+              intLiteral(0).pattern.then([
                 x.expr.as_('int').stmt,
                 y.write(expr('int?')).stmt,
                 break_(),
@@ -2057,15 +2195,15 @@
         y.expr.as_('int').stmt,
         z.expr.as_('int').stmt,
         switch_(
-            expr('Null'),
+            expr('int'),
             [
-              case_([
+              intLiteral(0).pattern.then([
                 w.expr.as_('int').stmt,
                 y.expr.as_('int').stmt,
                 x.write(expr('int?')).stmt,
                 break_(),
               ]),
-              case_([
+              default_.then([
                 w.expr.as_('int').stmt,
                 x.expr.as_('int').stmt,
                 y.write(expr('int?')).stmt,
@@ -2085,19 +2223,43 @@
       h.run([
         declare(x, type: 'int?', initializer: expr('int?')),
         switch_(
-            expr('Null'),
+            expr('int'),
             [
-              case_([
+              intLiteral(0).pattern.then([
                 x.expr.as_('int').stmt,
                 break_(),
               ]),
-              case_([]),
+              default_.then([]),
             ],
             isExhaustive: true),
         checkNotPromoted(x),
       ]);
     });
 
+    test('switchStatement_endAlternative() joins branches', () {
+      var x = Var('x');
+      var y = Var('y');
+      var z = Var('z');
+      h.run([
+        declare(y, type: 'num'),
+        declare(z, type: 'num'),
+        switch_(
+            expr('num'),
+            [
+              x
+                  .pattern()
+                  .when(x.expr.is_('int').and(y.expr.is_('int')))
+                  .then([]),
+              x.pattern().when(y.expr.is_('int').and(z.expr.is_('int'))).then([
+                checkNotPromoted(x),
+                checkPromoted(y, 'int'),
+                checkNotPromoted(z),
+              ]),
+            ],
+            isExhaustive: true),
+      ]);
+    });
+
     test('tryCatchStatement_bodyEnd() restores pre-try state', () {
       var x = Var('x');
       var y = Var('y');
diff --git a/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart b/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart
index 8e32c36..7e37e62 100644
--- a/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart
@@ -109,7 +109,8 @@
 
 void checkParameterDeclaration(
     ParameterData expected, ParameterDeclaration declaration, String context) {
-  expect(expected.name, declaration.identifier.name, '$context.identifer.name');
+  expect(
+      expected.name, declaration.identifier.name, '$context.identifier.name');
   expect(expected.isNamed, declaration.isNamed, '$context.isNamed');
   expect(expected.isRequired, declaration.isRequired, '$context.isRequired');
   checkTypeAnnotation(expected.type, declaration.type, '$context.type');
diff --git a/pkg/_fe_analyzer_shared/test/macros/util.dart b/pkg/_fe_analyzer_shared/test/macros/util.dart
index 3e68eb6..69f04c8 100644
--- a/pkg/_fe_analyzer_shared/test/macros/util.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/util.dart
@@ -146,7 +146,7 @@
   }
 }
 
-/// Checks if two [Code] objectss are of the same type and all their fields are
+/// Checks if two [Code] objects are of the same type and all their fields are
 /// equal.
 Matcher deepEqualsCode(Code other) => _DeepEqualityMatcher(other);
 
diff --git a/pkg/_fe_analyzer_shared/test/mini_ast.dart b/pkg/_fe_analyzer_shared/test/mini_ast.dart
index 2455fe9..60004b9 100644
--- a/pkg/_fe_analyzer_shared/test/mini_ast.dart
+++ b/pkg/_fe_analyzer_shared/test/mini_ast.dart
@@ -12,82 +12,124 @@
 import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/type_operations.dart';
+import 'package:_fe_analyzer_shared/src/type_inference/variable_bindings.dart';
 import 'package:test/test.dart';
 
 import 'mini_ir.dart';
 import 'mini_types.dart';
 
-Expression get nullLiteral => new _NullLiteral();
+final RegExp _locationRegExp =
+    RegExp('(file:)?[a-zA-Z0-9_./]+.dart:[0-9]+:[0-9]+');
 
-Expression get this_ => new _This();
+CaseHead get default_ => _Default(location: computeLocation());
+
+Expression get nullLiteral => new _NullLiteral(location: computeLocation());
+
+Expression get this_ => new _This(location: computeLocation());
 
 Statement assert_(Expression condition, [Expression? message]) =>
-    new _Assert(condition, message);
+    new _Assert(condition, message, location: computeLocation());
 
-Statement block(List<Statement> statements) => new _Block(statements);
+Statement block(List<Statement> statements) =>
+    new _Block(statements, location: computeLocation());
 
-Expression booleanLiteral(bool value) => _BooleanLiteral(value);
+Expression booleanLiteral(bool value) =>
+    _BooleanLiteral(value, location: computeLocation());
 
-Statement break_([LabeledStatement? target]) => new _Break(target);
-
-SwitchCase case_(List<Statement> body, {bool hasLabel = false}) =>
-    SwitchCase._(hasLabel, new _Block(body));
+Statement break_([Label? target]) =>
+    new _Break(target, location: computeLocation());
 
 /// Creates a pseudo-statement whose function is to verify that flow analysis
 /// considers [variable]'s assigned state to be [expectedAssignedState].
 Statement checkAssigned(Var variable, bool expectedAssignedState) =>
-    new _CheckAssigned(variable, expectedAssignedState);
+    new _CheckAssigned(variable, expectedAssignedState,
+        location: computeLocation());
 
 /// Creates a pseudo-statement whose function is to verify that flow analysis
 /// considers [promotable] to be un-promoted.
 Statement checkNotPromoted(Promotable promotable) =>
-    new _CheckPromoted(promotable, null);
+    new _CheckPromoted(promotable, null, location: computeLocation());
 
 /// Creates a pseudo-statement whose function is to verify that flow analysis
 /// considers [promotable]'s assigned state to be promoted to [expectedTypeStr].
 Statement checkPromoted(Promotable promotable, String? expectedTypeStr) =>
-    new _CheckPromoted(promotable, expectedTypeStr);
+    new _CheckPromoted(promotable, expectedTypeStr,
+        location: computeLocation());
 
 /// Creates a pseudo-statement whose function is to verify that flow analysis
 /// considers the current location's reachability state to be
 /// [expectedReachable].
 Statement checkReachable(bool expectedReachable) =>
-    new _CheckReachable(expectedReachable);
+    new _CheckReachable(expectedReachable, location: computeLocation());
 
 /// Creates a pseudo-statement whose function is to verify that flow analysis
 /// considers [variable]'s unassigned state to be [expectedUnassignedState].
 Statement checkUnassigned(Var variable, bool expectedUnassignedState) =>
-    new _CheckUnassigned(variable, expectedUnassignedState);
+    new _CheckUnassigned(variable, expectedUnassignedState,
+        location: computeLocation());
 
-Statement continue_() => new _Continue();
+/// Computes a "location" string using `StackTrace.current` to find the source
+/// location of the caller's caller.
+///
+/// Note: this is highly dependent on the behavior of VM stack traces.  This
+/// won't work in code compiled with dart2js for example.  That's fine, though,
+/// since we only run these tests under the VM.
+String computeLocation() {
+  var callStack = StackTrace.current.toString().split('\n');
+  assert(callStack[0].contains('mini_ast.dart'));
+  assert(callStack[1].contains('mini_ast.dart'));
+  assert(
+      callStack[2].contains('type_inference_test.dart') ||
+          callStack[2].contains('flow_analysis_test.dart'),
+      'Unexpected file: ${callStack[2]}');
+  var match = _locationRegExp.firstMatch(callStack[2]);
+  if (match == null) {
+    throw AssertionError(
+        '_locationRegExp failed to match ${callStack[2]} in $callStack');
+  }
+  return match.group(0)!;
+}
+
+Statement continue_() => new _Continue(location: computeLocation());
 
 Statement declare(Var variable,
-        {bool isLate = false,
-        bool isFinal = false,
-        String? type,
-        Expression? initializer,
-        String? expectInferredType}) =>
-    new _Declare(variable, initializer,
-        isLate: isLate,
-        isFinal: isFinal,
-        declaredType: type == null ? null : Type(type),
-        expectInferredType: expectInferredType);
+    {bool isLate = false,
+    bool isFinal = false,
+    String? type,
+    Expression? initializer,
+    String? expectInferredType}) {
+  var location = computeLocation();
+  return new _Declare(
+      new _VariablePattern(
+          type == null ? null : Type(type), variable, expectInferredType,
+          location: location),
+      initializer,
+      isLate: isLate,
+      isFinal: isFinal,
+      location: location);
+}
 
-Statement do_(List<Statement> body, Expression condition) =>
-    _Do(block(body), condition);
+Statement do_(List<Statement> body, Expression condition) {
+  var location = computeLocation();
+  return _Do(_Block(body, location: location), condition, location: location);
+}
 
 /// Creates a pseudo-expression having type [typeStr] that otherwise has no
 /// effect on flow analysis.
 Expression expr(String typeStr) =>
-    new _PlaceholderExpression(new Type(typeStr));
+    new _PlaceholderExpression(new Type(typeStr), location: computeLocation());
 
 /// Creates a conventional `for` statement.  Optional boolean [forCollection]
 /// indicates that this `for` statement is actually a collection element, so
 /// `null` should be passed to [for_bodyBegin].
 Statement for_(Statement? initializer, Expression? condition,
-        Expression? updater, List<Statement> body,
-        {bool forCollection = false}) =>
-    new _For(initializer, condition, updater, block(body), forCollection);
+    Expression? updater, List<Statement> body,
+    {bool forCollection = false}) {
+  var location = computeLocation();
+  return new _For(initializer, condition, updater,
+      _Block(body, location: location), forCollection,
+      location: location);
+}
 
 /// Creates a "for each" statement where the identifier being assigned to by the
 /// iteration is not a local variable.
@@ -97,8 +139,11 @@
 ///     f(Iterable iterable) {
 ///       for (x in iterable) { ... }
 ///     }
-Statement forEachWithNonVariable(Expression iterable, List<Statement> body) =>
-    new _ForEach(null, iterable, block(body), false);
+Statement forEachWithNonVariable(Expression iterable, List<Statement> body) {
+  var location = computeLocation();
+  return new _ForEach(null, iterable, _Block(body, location: location), false,
+      location: location);
+}
 
 /// Creates a "for each" statement where the identifier being assigned to by the
 /// iteration is a variable that is being declared by the "for each" statement.
@@ -111,7 +156,8 @@
     Var variable, Expression iterable, List<Statement> body) {
   // ignore: unnecessary_null_comparison
   assert(variable != null);
-  return new _ForEach(variable, iterable, block(body), true);
+  return new _ForEach(variable, iterable, block(body), true,
+      location: computeLocation());
 }
 
 /// Creates a "for each" statement where the identifier being assigned to by the
@@ -126,108 +172,210 @@
     Var variable, Expression iterable, List<Statement> body) {
   // ignore: unnecessary_null_comparison
   assert(variable != null);
-  return new _ForEach(variable, iterable, block(body), false);
+  var location = computeLocation();
+  return new _ForEach(
+      variable, iterable, _Block(body, location: location), false,
+      location: location);
 }
 
 Statement if_(Expression condition, List<Statement> ifTrue,
-        [List<Statement>? ifFalse]) =>
-    new _If(condition, block(ifTrue), ifFalse == null ? null : block(ifFalse));
-
-Expression intLiteral(int value, {bool? expectConversionToDouble}) =>
-    new _IntLiteral(value, expectConversionToDouble: expectConversionToDouble);
-
-Statement labeled(Statement Function(LabeledStatement) callback) {
-  var labeledStatement = LabeledStatement._();
-  labeledStatement._body = callback(labeledStatement);
-  return labeledStatement;
+    [List<Statement>? ifFalse]) {
+  var location = computeLocation();
+  return new _If(condition, _Block(ifTrue, location: location),
+      ifFalse == null ? null : _Block(ifFalse, location: location),
+      location: location);
 }
 
-Statement localFunction(List<Statement> body) => _LocalFunction(block(body));
+Statement ifCase(
+    Expression expression, CaseHead caseHead, List<Statement> ifTrue,
+    {List<Statement>? else_}) {
+  var location = computeLocation();
+  return new _IfCase(
+      expression,
+      caseHead._pattern!,
+      caseHead._guard,
+      _Block(ifTrue, location: location),
+      else_ == null ? null : _Block(else_, location: location),
+      location: location);
+}
 
-Statement return_() => new _Return();
+Expression intLiteral(int value, {bool? expectConversionToDouble}) =>
+    new _IntLiteral(value,
+        expectConversionToDouble: expectConversionToDouble,
+        location: computeLocation());
 
-Statement switch_(Expression expression, List<SwitchCase> cases,
-        {required bool isExhaustive}) =>
-    new _Switch(expression, cases, isExhaustive);
+Pattern listPattern(List<Pattern> elements, {String? elementType}) =>
+    _ListPattern(elementType == null ? null : Type(elementType), elements,
+        location: computeLocation());
+
+Statement localFunction(List<Statement> body) {
+  var location = computeLocation();
+  return _LocalFunction(_Block(body, location: location), location: location);
+}
+
+Statement match(Pattern pattern, Expression initializer,
+        {bool isLate = false, bool isFinal = false}) =>
+    new _Declare(pattern, initializer,
+        isLate: isLate, isFinal: isFinal, location: computeLocation());
+
+CaseHeads mergedCase(List<CaseHead> cases) => _CaseHeads(cases, const []);
+
+Statement return_() => new _Return(location: computeLocation());
+
+Statement switch_(Expression expression, List<StatementCase> cases,
+        {required bool isExhaustive,
+        bool? expectHasDefault,
+        bool? expectIsExhaustive,
+        bool? expectLastCaseTerminates,
+        String? expectScrutineeType}) =>
+    new _SwitchStatement(expression, cases, isExhaustive,
+        location: computeLocation(),
+        expectHasDefault: expectHasDefault,
+        expectIsExhaustive: expectIsExhaustive,
+        expectLastCaseTerminates: expectLastCaseTerminates,
+        expectScrutineeType: expectScrutineeType);
+
+Expression switchExpr(Expression expression, List<ExpressionCase> cases) =>
+    new _SwitchExpression(expression, cases, location: computeLocation());
 
 PromotableLValue thisOrSuperProperty(String name) =>
-    new _ThisOrSuperProperty(name);
+    new _ThisOrSuperProperty(name, location: computeLocation());
 
-Expression throw_(Expression operand) => new _Throw(operand);
+Expression throw_(Expression operand) =>
+    new _Throw(operand, location: computeLocation());
 
-TryBuilder try_(List<Statement> body) =>
-    new _TryStatement(block(body), [], null);
+TryBuilder try_(List<Statement> body) {
+  var location = computeLocation();
+  return new _TryStatement(_Block(body, location: location), [], null,
+      location: location);
+}
 
-Statement while_(Expression condition, List<Statement> body) =>
-    new _While(condition, block(body));
+Statement while_(Expression condition, List<Statement> body) {
+  var location = computeLocation();
+  return new _While(condition, _Block(body, location: location),
+      location: location);
+}
+
+Pattern wildcard(
+        {String? type, String? expectInferredType, bool isFinal = false}) =>
+    _VariablePattern(type == null ? null : Type(type), null, expectInferredType,
+        isFinal: isFinal, location: computeLocation());
+
+mixin CaseHead implements CaseHeads, Node {
+  @override
+  List<CaseHead> get _caseHeads => [this];
+
+  Expression? get _guard;
+
+  @override
+  List<Label> get _labels => const [];
+
+  Pattern? get _pattern;
+
+  ExpressionCase thenExpr(Expression body) =>
+      ExpressionCase._(_pattern, _guard, body, location: computeLocation());
+
+  void _preVisit(
+      PreVisitor visitor, VariableBinder<Node, Var, Type> variableBinder) {
+    variableBinder.startAlternative(this);
+    _pattern?.preVisit(visitor, variableBinder);
+    variableBinder.finishAlternative();
+    _guard?.preVisit(visitor);
+  }
+}
+
+mixin CaseHeads {
+  List<CaseHead> get _caseHeads;
+
+  List<Label> get _labels;
+
+  StatementCase then(List<Statement> body) {
+    var location = computeLocation();
+    return StatementCase._(this, _Block(body, location: location),
+        location: location);
+  }
+}
 
 /// Representation of an expression in the pseudo-Dart language used for flow
 /// analysis testing.  Methods in this class may be used to create more complex
 /// expressions based on this one.
 abstract class Expression extends Node {
-  Expression() : super._();
+  Expression({required super.location}) : super._();
 
   /// If `this` is an expression `x`, creates the expression `x!`.
-  Expression get nonNullAssert => new _NonNullAssert(this);
+  Expression get nonNullAssert =>
+      new _NonNullAssert(this, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `!x`.
-  Expression get not => new _Not(this);
+  Expression get not => new _Not(this, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `(x)`.
-  Expression get parenthesized => new _ParenthesizedExpression(this);
+  Expression get parenthesized =>
+      new _ParenthesizedExpression(this, location: computeLocation());
+
+  Pattern get pattern => _ConstantPattern(this, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the statement `x;`.
-  Statement get stmt => new _ExpressionStatement(this);
+  Statement get stmt =>
+      new _ExpressionStatement(this, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `x && other`.
-  Expression and(Expression other) => new _Logical(this, other, isAnd: true);
+  Expression and(Expression other) =>
+      new _Logical(this, other, isAnd: true, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `x as typeStr`.
-  Expression as_(String typeStr) => new _As(this, Type(typeStr));
+  Expression as_(String typeStr) =>
+      new _As(this, Type(typeStr), location: computeLocation());
 
   /// Wraps `this` in such a way that, when the test is run, it will verify that
   /// the context provided when analyzing the expression matches
   /// [expectedContext].
   Expression checkContext(String expectedContext) =>
-      _CheckExpressionContext(this, expectedContext);
+      _CheckExpressionContext(this, expectedContext,
+          location: computeLocation());
 
   /// Wraps `this` in such a way that, when the test is run, it will verify that
   /// the IR produced matches [expectedIr].
-  Expression checkIr(String expectedIr) => _CheckExpressionIr(this, expectedIr);
+  Expression checkIr(String expectedIr) =>
+      _CheckExpressionIr(this, expectedIr, location: computeLocation());
 
   /// Creates an [Expression] that, when analyzed, will behave the same as
   /// `this`, but after visiting it, will verify that the type of the expression
   /// was [expectedType].
   Expression checkType(String expectedType) =>
-      new _CheckExpressionType(this, expectedType);
+      new _CheckExpressionType(this, expectedType, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression
   /// `x ? ifTrue : ifFalse`.
   Expression conditional(Expression ifTrue, Expression ifFalse) =>
-      new _Conditional(this, ifTrue, ifFalse);
+      new _Conditional(this, ifTrue, ifFalse, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `x == other`.
-  Expression eq(Expression other) => new _Equal(this, other, false);
+  Expression eq(Expression other) =>
+      new _Equal(this, other, false, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `x ?? other`.
-  Expression ifNull(Expression other) => new _IfNull(this, other);
+  Expression ifNull(Expression other) =>
+      new _IfNull(this, other, location: computeLocation());
 
   /// Creates a [Statement] that, when analyzed, will analyze `this`, supplying
   /// a context type of [context].
   Statement inContext(String context) =>
-      _ExpressionInContext(this, Type(context));
+      _ExpressionInContext(this, Type(context), location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `x is typeStr`.
   ///
   /// With [isInverted] set to `true`, creates the expression `x is! typeStr`.
   Expression is_(String typeStr, {bool isInverted = false}) =>
-      new _Is(this, Type(typeStr), isInverted);
+      new _Is(this, Type(typeStr), isInverted, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `x is! typeStr`.
-  Expression isNot(String typeStr) => _Is(this, Type(typeStr), true);
+  Expression isNot(String typeStr) =>
+      _Is(this, Type(typeStr), true, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `x != other`.
-  Expression notEq(Expression other) => _Equal(this, other, true);
+  Expression notEq(Expression other) =>
+      _Equal(this, other, true, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `x?.other`.
   ///
@@ -235,43 +383,91 @@
   /// strictly speaking an expression.  However for flow analysis it suffices to
   /// model it as an expression.
   Expression nullAwareAccess(Expression other, {bool isCascaded = false}) =>
-      _NullAwareAccess(this, other, isCascaded);
+      _NullAwareAccess(this, other, isCascaded, location: computeLocation());
 
   /// If `this` is an expression `x`, creates the expression `x || other`.
-  Expression or(Expression other) => new _Logical(this, other, isAnd: false);
+  Expression or(Expression other) =>
+      new _Logical(this, other, isAnd: false, location: computeLocation());
 
-  void preVisit(AssignedVariables<Node, Var> assignedVariables);
+  void preVisit(PreVisitor visitor);
 
   /// If `this` is an expression `x`, creates the L-value `x.name`.
-  PromotableLValue property(String name) => new _Property(this, name);
+  PromotableLValue property(String name) =>
+      new _Property(this, name, location: computeLocation());
 
   /// If `this` is an expression `x`, creates a pseudo-expression that models
   /// evaluation of `x` followed by execution of [stmt].  This can be used to
   /// test that flow analysis is in the correct state after an expression is
   /// visited.
   Expression thenStmt(Statement stmt) =>
-      new _WrappedExpression(null, this, stmt);
+      new _WrappedExpression(null, this, stmt, location: computeLocation());
 
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context);
 }
 
-class Harness with TypeOperations<Type> implements Operations<Var, Type> {
+/// Representation of a single case clause in a switch expression.  Use
+/// [caseExpr] to create instances of this class.
+class ExpressionCase extends Node
+    implements
+        SwitchExpressionMemberInfo<Node, Expression>,
+        CaseHeadOrDefaultInfo<Node, Expression> {
+  @override
+  final Pattern? pattern;
+
+  @override
+  final Expression? guard;
+
+  @override
+  final Expression expression;
+
+  ExpressionCase._(this.pattern, this.guard, this.expression,
+      {required super.location})
+      : super._();
+
+  @override
+  CaseHeadOrDefaultInfo<Node, Expression> get head => this;
+
+  String toString() => [
+        pattern == null ? 'default' : 'case $pattern',
+        if (guard != null) ' when $guard',
+        ': $expression'
+      ].join('');
+
+  void _preVisit(PreVisitor visitor) {
+    var variableBinder = VariableBinder<Node, Var, Type>(visitor);
+    pattern?.preVisit(visitor, variableBinder);
+    variableBinder.finish();
+    expression.preVisit(visitor);
+  }
+}
+
+class Harness
+    with TypeOperations<Type>, TypeOperations2<Type>
+    implements Operations<Var, Type> {
   static const Map<String, bool> _coreSubtypes = const {
     'bool <: int': false,
     'bool <: Object': true,
+    'double <: bool': false,
     'double <: double?': true,
     'double <: Object': true,
     'double <: Object?': true,
+    'double <: Never': false,
     'double <: num': true,
     'double <: num?': true,
     'double <: int': false,
     'double <: int?': false,
     'double <: String': false,
+    'dynamic <: int': false,
+    'dynamic <: Null': false,
+    'dynamic <: Object': false,
+    'int <: bool': false,
     'int <: double': false,
     'int <: double?': false,
+    'int <: dynamic': true,
     'int <: int?': true,
     'int <: Iterable': false,
     'int <: List': false,
+    'int <: Never': false,
     'int <: Null': false,
     'int <: num': true,
     'int <: num?': true,
@@ -287,10 +483,14 @@
     'int? <: num?': true,
     'int? <: Object': false,
     'int? <: Object?': true,
+    'List<int> <: Object': true,
     'Never <: Object?': true,
+    'Null <: double?': true,
     'Null <: int': false,
     'Null <: Object': false,
     'Null <: Object?': true,
+    'Null <: dynamic': true,
+    'num <: double': false,
     'num <: int': false,
     'num <: Iterable': false,
     'num <: List': false,
@@ -314,6 +514,7 @@
     'List <: int': false,
     'List <: Iterable': true,
     'List <: Object': true,
+    'List<int> <: List<num>': true,
     'Never <: int': true,
     'Never <: int?': true,
     'Never <: Null': true,
@@ -325,6 +526,7 @@
     'Object <: int': false,
     'Object <: int?': false,
     'Object <: List': false,
+    'Object <: List<Object?>': false,
     'Object <: Null': false,
     'Object <: num': false,
     'Object <: num?': false,
@@ -336,6 +538,8 @@
     'Object? <: Null': false,
     'String <: int': false,
     'String <: int?': false,
+    'String <: List<num>': false,
+    'String <: num': false,
     'String <: num?': false,
     'String <: Object': true,
     'String <: Object?': true,
@@ -381,11 +585,30 @@
     'num* - Object': Type('Never'),
   };
 
+  static final Map<String, Type> _coreGlbs = {
+    'double, int': Type('Never'),
+    'double?, int?': Type('Null'),
+    'int?, num': Type('int'),
+  };
+
+  static final Map<String, Type> _coreLubs = {
+    'double, int': Type('num'),
+    'double?, int?': Type('num?'),
+    'int, num': Type('num'),
+    'Never, int': Type('int'),
+    'Null, int': Type('int?'),
+    '?, int': Type('int'),
+    '?, List<?>': Type('List<?>'),
+    '?, Null': Type('Null'),
+  };
+
   bool _started = false;
 
   late final FlowAnalysis<Node, Statement, Expression, Var, Type> flow;
 
-  bool _legacy = false;
+  bool? _legacy;
+
+  bool? _patternsEnabled;
 
   Type? _thisType;
 
@@ -393,11 +616,18 @@
 
   final Map<String, Type> _factorResults = Map.of(_coreFactors);
 
+  final Map<String, Type> _glbs = Map.of(_coreGlbs);
+
+  final Map<String, Type> _lubs = Map.of(_coreLubs);
+
   final Map<String, _PropertyElement> _members = {};
 
   Map<String, Map<String, String>> _promotionExceptions = {};
 
-  late final typeAnalyzer = _MiniAstTypeAnalyzer(this);
+  late final typeAnalyzer = _MiniAstTypeAnalyzer(
+      this,
+      TypeAnalyzerOptions(
+          nullSafetyEnabled: !legacy, patternsEnabled: patternsEnabled));
 
   /// Indicates whether initializers of implicitly typed variables should be
   /// accounted for by SSA analysis.  (In an ideal world, they always would be,
@@ -410,11 +640,20 @@
 
   MiniIrBuilder get irBuilder => typeAnalyzer._irBuilder;
 
+  bool get legacy => _legacy ?? false;
+
   set legacy(bool value) {
     assert(!_started);
     _legacy = value;
   }
 
+  bool get patternsEnabled => _patternsEnabled ?? !legacy;
+
+  set patternsEnabled(bool value) {
+    assert(!_started);
+    _patternsEnabled = value;
+  }
+
   set respectImplicitlyTypedVarInitializers(bool value) {
     assert(!_started);
     _respectImplicitlyTypedVarInitializers = value;
@@ -481,11 +720,35 @@
   }
 
   @override
+  Type glb(Type type1, Type type2) {
+    if (type1.type == type2.type) return type1;
+    var typeNames = [type1.type, type2.type];
+    typeNames.sort();
+    var query = typeNames.join(', ');
+    return _glbs[query] ?? fail('Unknown glb query: $query');
+  }
+
+  @override
+  bool isAssignableTo(Type fromType, Type toType) {
+    if (legacy && isSubtypeOf(toType, fromType)) return true;
+    if (fromType.type == 'dynamic') return true;
+    return isSubtypeOf(fromType, toType);
+  }
+
+  @override
+  bool isDynamic(Type type) =>
+      type is NonFunctionType && type.name == 'dynamic' && type.args.isEmpty;
+
+  @override
   bool isNever(Type type) {
     return type.type == 'Never';
   }
 
   @override
+  bool isPropertyPromotable(Object property) =>
+      promotableFields.contains(property);
+
+  @override
   bool isSameType(Type type1, Type type2) {
     return type1.type == type2.type;
   }
@@ -501,6 +764,28 @@
   bool isTypeParameterType(Type type) => type is PromotedTypeVariableType;
 
   @override
+  Type lub(Type type1, Type type2) {
+    if (type1.type == type2.type) return type1;
+    var typeNames = [type1.type, type2.type];
+    typeNames.sort();
+    var query = typeNames.join(', ');
+    return _lubs[query] ?? fail('Unknown lub query: $query');
+  }
+
+  @override
+  Type makeNullable(Type type) => lub(type, Type('Null'));
+
+  @override
+  Type? matchListType(Type type) {
+    if (type is NonFunctionType) {
+      if (type.args.length == 1) {
+        return type.args[0];
+      }
+    }
+    return null;
+  }
+
+  @override
   Type promoteToNonNull(Type type) {
     if (type.type.endsWith('?')) {
       return Type(type.type.substring(0, type.type.length - 1));
@@ -513,21 +798,31 @@
 
   /// Runs the given [statements] through flow analysis, checking any assertions
   /// they contain.
-  void run(List<Statement> statements) {
+  void run(List<Statement> statements,
+      {bool errorRecoveryOk = false, Set<String> expectedErrors = const {}}) {
     _started = true;
-    var assignedVariables = AssignedVariables<Node, Var>();
-    var b = block(statements);
-    b.preVisit(assignedVariables);
-    flow = _legacy
+    if (legacy && patternsEnabled) {
+      fail('Patterns cannot be enabled in legacy mode');
+    }
+    var visitor = PreVisitor(typeAnalyzer.errors);
+    var b = _Block(statements, location: computeLocation());
+    b.preVisit(visitor);
+    flow = legacy
         ? FlowAnalysis<Node, Statement, Expression, Var, Type>.legacy(
-            this, assignedVariables)
+            this, visitor._assignedVariables)
         : FlowAnalysis<Node, Statement, Expression, Var, Type>(
-            this, assignedVariables,
+            this, visitor._assignedVariables,
             respectImplicitlyTypedVarInitializers:
-                _respectImplicitlyTypedVarInitializers,
-            promotableFields: promotableFields);
+                _respectImplicitlyTypedVarInitializers);
     typeAnalyzer.dispatchStatement(b);
     typeAnalyzer.finish();
+    expect(typeAnalyzer.errors._accumulatedErrors, expectedErrors);
+    var assertInErrorRecoveryStack =
+        typeAnalyzer.errors._assertInErrorRecoveryStack;
+    if (!errorRecoveryOk && assertInErrorRecoveryStack != null) {
+      fail('assertInErrorRecovery called but no errors reported: '
+          '$assertInErrorRecoveryStack');
+    }
   }
 
   @override
@@ -583,37 +878,41 @@
   }
 }
 
-class LabeledStatement extends Statement {
-  late final Statement _body;
+class Label extends Node {
+  final String _name;
 
-  LabeledStatement._();
+  late final Node _binding;
 
-  @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    _body.preVisit(assignedVariables);
+  Label(this._name) : super._(location: computeLocation());
+
+  CaseHeads then(CaseHeads caseHeads) =>
+      _CaseHeads(caseHeads._caseHeads, [this, ...caseHeads._labels]);
+
+  Statement thenStmt(Statement statement) {
+    if (statement is! _LabeledStatement) {
+      statement = _LabeledStatement(statement, location: computeLocation());
+    }
+    statement._labels.insert(0, this);
+    _binding = statement;
+    return statement;
   }
 
   @override
-  String toString() => 'labeled: $_body';
-
-  @override
-  void visit(Harness h) {
-    h.typeAnalyzer.analyzeLabeledStatement(this, _body);
-  }
+  String toString() => _name;
 }
 
 /// Representation of an expression that can appear on the left hand side of an
 /// assignment (or as the target of `++` or `--`).  Methods in this class may be
 /// used to create more complex expressions based on this one.
 abstract class LValue extends Expression {
-  LValue._();
+  LValue._({required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables,
-      {_LValueDisposition disposition});
+  void preVisit(PreVisitor visitor, {_LValueDisposition disposition});
 
   /// Creates an expression representing a write to this L-value.
-  Expression write(Expression? value) => new _Write(this, value);
+  Expression write(Expression? value) =>
+      new _Write(this, value, location: computeLocation());
 
   void _visitWrite(Harness h, Expression assignmentExpression, Type writtenType,
       Expression? rhs);
@@ -626,17 +925,90 @@
 
   final int id;
 
-  Node._() : id = _nextId++;
+  final String location;
+
+  String? _errorId;
+
+  Node._({required this.location}) : id = _nextId++;
+
+  String get errorId {
+    String? errorId = _errorId;
+    if (errorId == null) {
+      fail('No error ID assigned for $runtimeType $this at $location');
+    } else {
+      return errorId;
+    }
+  }
+
+  set errorId(String value) {
+    _errorId = value;
+  }
 
   String toString() => 'Node#$id';
 }
 
+abstract class Pattern extends Node with CaseHead, CaseHeads {
+  Pattern._({required super.location}) : super._();
+
+  Pattern get nullAssert =>
+      _NullCheckOrAssertPattern(this, true, location: computeLocation());
+
+  Pattern get nullCheck =>
+      _NullCheckOrAssertPattern(this, false, location: computeLocation());
+
+  @override
+  Expression? get _guard => null;
+
+  @override
+  Pattern? get _pattern => this;
+
+  Pattern and(Pattern other) =>
+      _LogicalPattern(this, other, isAnd: true, location: computeLocation());
+
+  Pattern as_(String type) =>
+      new _CastPattern(this, Type(type), location: computeLocation());
+
+  Type computeSchema(Harness h);
+
+  Pattern or(Pattern other) =>
+      _LogicalPattern(this, other, isAnd: false, location: computeLocation());
+
+  void preVisit(
+      PreVisitor visitor, VariableBinder<Node, Var, Type> variableBinder);
+
+  @override
+  String toString() => _debugString(needsKeywordOrType: true);
+
+  void visit(
+      Harness h,
+      Type matchedType,
+      Map<Var, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context);
+
+  CaseHead when(Expression guard) =>
+      _GuardedCaseHead(this, guard, location: location);
+
+  String _debugString({required bool needsKeywordOrType});
+}
+
+/// Data structure holding information needed during the "pre-visit" phase of
+/// type analysis.
+class PreVisitor implements VariableBindingCallbacks<Node, Var, Type> {
+  final AssignedVariables<Node, Var> _assignedVariables =
+      AssignedVariables<Node, Var>();
+
+  @override
+  final VariableBinderErrors<Node, Var>? errors;
+
+  PreVisitor(this.errors);
+}
+
 /// Base class for language constructs that, at a given point in flow analysis,
 /// might or might not be promoted.
 abstract class Promotable {
-  /// Makes the appropriate calls to [assignedVariables] for this syntactic
-  /// construct.
-  void preVisit(AssignedVariables<Node, Var> assignedVariables);
+  /// Makes the appropriate calls to [AssignedVariables] and [VariableBinder]
+  /// for this syntactic construct.
+  void preVisit(PreVisitor visitor);
 
   /// Queries the current promotion status of `this`.  Return value is either a
   /// type (if `this` is promoted), or `null` (if it isn't).
@@ -646,46 +1018,40 @@
 /// Base class for l-values that, at a given point in flow analysis, might or
 /// might not be promoted.
 abstract class PromotableLValue extends LValue implements Promotable {
-  PromotableLValue._() : super._();
+  PromotableLValue._({required super.location}) : super._();
 }
 
 /// Representation of a statement in the pseudo-Dart language used for flow
 /// analysis testing.
 abstract class Statement extends Node {
-  Statement() : super._();
+  Statement({required super.location}) : super._();
 
   /// Wraps `this` in such a way that, when the test is run, it will verify that
   /// the IR produced matches [expectedIr].
-  Statement checkIr(String expectedIr) => _CheckStatementIr(this, expectedIr);
+  Statement checkIr(String expectedIr) =>
+      _CheckStatementIr(this, expectedIr, location: computeLocation());
 
-  void preVisit(AssignedVariables<Node, Var> assignedVariables);
+  void preVisit(PreVisitor visitor);
 
   /// If `this` is a statement `x`, creates a pseudo-expression that models
   /// execution of `x` followed by evaluation of [expr].  This can be used to
   /// test that flow analysis is in the correct state before an expression is
   /// visited.
-  Expression thenExpr(Expression expr) => _WrappedExpression(this, expr, null);
+  Expression thenExpr(Expression expr) =>
+      _WrappedExpression(this, expr, null, location: computeLocation());
 
   void visit(Harness h);
 }
 
 /// Representation of a single case clause in a switch statement.  Use [case_]
 /// to create instances of this class.
-class SwitchCase {
-  final bool _hasLabel;
+class StatementCase extends Node {
+  final CaseHeads _caseHeads;
+
   final _Block _body;
 
-  SwitchCase._(this._hasLabel, this._body);
-
-  String toString() => [
-        if (_hasLabel) '<label>:',
-        'case <value>:',
-        ..._body.statements
-      ].join(' ');
-
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    _body.preVisit(assignedVariables);
-  }
+  StatementCase._(this._caseHeads, this._body, {required super.location})
+      : super._();
 }
 
 abstract class TryBuilder {
@@ -696,21 +1062,22 @@
 }
 
 abstract class TryStatement extends Statement implements TryBuilder {
-  TryStatement._();
+  TryStatement._({required super.location});
 }
 
 /// Representation of a local variable in the pseudo-Dart language used for flow
 /// analysis testing.
-class Var implements Promotable {
+class Var extends Node implements Promotable {
   final String name;
 
   /// The type of the variable, or `null` if it is not yet known.
   Type? _type;
 
-  Var(this.name);
+  Var(this.name) : super._(location: computeLocation());
 
   /// Creates an L-value representing a reference to this variable.
-  LValue get expr => new _VariableReference(this, null);
+  LValue get expr =>
+      new _VariableReference(this, null, location: computeLocation());
 
   /// Gets the type if known; otherwise throws an exception.
   Type get type {
@@ -728,23 +1095,34 @@
     _type = value;
   }
 
+  Pattern pattern(
+          {String? type, String? expectInferredType, bool isFinal = false}) =>
+      new _VariablePattern(
+          type == null ? null : Type(type), this, expectInferredType,
+          isFinal: isFinal, location: computeLocation());
+
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   /// Creates an expression representing a read of this variable, which as a
   /// side effect will call the given callback with the returned promoted type.
   Expression readAndCheckPromotedType(void Function(Type?) callback) =>
-      new _VariableReference(this, callback);
+      new _VariableReference(this, callback, location: computeLocation());
 
   @override
   String toString() => 'var $name';
 
   /// Creates an expression representing a write to this variable.
-  Expression write(Expression? value) => expr.write(value);
+  Expression write(Expression? value) {
+    var location = computeLocation();
+    return new _Write(
+        new _VariableReference(this, null, location: location), value,
+        location: location);
+  }
 
   @override
   Type? _getPromotedType(Harness h) {
-    h.irBuilder.atom(name);
+    h.irBuilder.atom(name, Kind.expression, location: location);
     return h.flow.promotedType(this);
   }
 }
@@ -753,11 +1131,11 @@
   final Expression target;
   final Type type;
 
-  _As(this.target, this.type);
+  _As(this.target, this.type, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    target.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    target.preVisit(visitor);
   }
 
   @override
@@ -773,12 +1151,12 @@
   final Expression condition;
   final Expression? message;
 
-  _Assert(this.condition, this.message);
+  _Assert(this.condition, this.message, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    condition.preVisit(assignedVariables);
-    message?.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    condition.preVisit(visitor);
+    message?.preVisit(visitor);
   }
 
   @override
@@ -787,20 +1165,22 @@
 
   @override
   void visit(Harness h) {
-    h.typeAnalyzer.analyzeAssertStatement(condition, message);
-    h.irBuilder.apply('assert', 2);
+    h.typeAnalyzer.analyzeAssertStatement(this, condition, message);
+    h.irBuilder.apply(
+        'assert', [Kind.expression, Kind.expression], Kind.statement,
+        location: location);
   }
 }
 
 class _Block extends Statement {
   final List<Statement> statements;
 
-  _Block(this.statements);
+  _Block(this.statements, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
+  void preVisit(PreVisitor visitor) {
     for (var statement in statements) {
-      statement.preVisit(assignedVariables);
+      statement.preVisit(visitor);
     }
   }
 
@@ -811,17 +1191,19 @@
   @override
   void visit(Harness h) {
     h.typeAnalyzer.analyzeBlock(statements);
-    h.irBuilder.apply('block', statements.length);
+    h.irBuilder.apply(
+        'block', List.filled(statements.length, Kind.statement), Kind.statement,
+        location: location);
   }
 }
 
 class _BooleanLiteral extends Expression {
   final bool value;
 
-  _BooleanLiteral(this.value);
+  _BooleanLiteral(this.value, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() => '$value';
@@ -829,29 +1211,75 @@
   @override
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
     var type = h.typeAnalyzer.analyzeBoolLiteral(this, value);
-    h.irBuilder.atom('$value');
+    h.irBuilder.atom('$value', Kind.expression, location: location);
     return new SimpleTypeAnalysisResult<Type>(type: type);
   }
 }
 
 class _Break extends Statement {
-  final LabeledStatement? target;
+  final Label? target;
 
-  _Break(this.target);
+  _Break(this.target, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() => 'break;';
 
   @override
   void visit(Harness h) {
-    h.typeAnalyzer.analyzeBreakStatement(target);
-    h.irBuilder.apply('break', 0);
+    h.typeAnalyzer.analyzeBreakStatement(target?._binding as Statement?);
+    h.irBuilder.apply('break', [], Kind.statement, location: location);
   }
 }
 
+class _CaseHeads with CaseHeads {
+  @override
+  final List<CaseHead> _caseHeads;
+
+  @override
+  final List<Label> _labels;
+
+  _CaseHeads(this._caseHeads, this._labels);
+}
+
+class _CastPattern extends Pattern {
+  final Pattern _inner;
+
+  final Type _type;
+
+  _CastPattern(this._inner, this._type, {required super.location}) : super._();
+
+  Type computeSchema(Harness h) => h.typeAnalyzer.analyzeCastPatternSchema();
+
+  @override
+  void preVisit(
+      PreVisitor visitor, VariableBinder<Node, Var, Type> variableBinder) {
+    _inner.preVisit(visitor, variableBinder);
+  }
+
+  @override
+  void visit(
+      Harness h,
+      Type matchedType,
+      Map<Var, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context) {
+    h.typeAnalyzer
+        .analyzeCastPattern(matchedType, typeInfos, context, _inner, _type);
+    h.irBuilder.atom(_type.type, Kind.type, location: location);
+    h.irBuilder.atom(matchedType.type, Kind.type, location: location);
+    h.irBuilder.apply(
+        'castPattern', [Kind.pattern, Kind.type, Kind.type], Kind.pattern,
+        names: ['matchedType'], location: location);
+  }
+
+  @override
+  String _debugString({required bool needsKeywordOrType}) =>
+      '${_inner._debugString(needsKeywordOrType: needsKeywordOrType)} as '
+      '${_type.type}';
+}
+
 /// Representation of a single catch clause in a try/catch statement.  Use
 /// [catch_] to create instances of this class.
 class _CatchClause {
@@ -873,8 +1301,8 @@
     return '$initialPart $_body';
   }
 
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    _body.preVisit(assignedVariables);
+  void _preVisit(PreVisitor visitor) {
+    _body.preVisit(visitor);
   }
 }
 
@@ -882,10 +1310,11 @@
   final Var variable;
   final bool expectedAssignedState;
 
-  _CheckAssigned(this.variable, this.expectedAssignedState);
+  _CheckAssigned(this.variable, this.expectedAssignedState,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() {
@@ -896,7 +1325,7 @@
   @override
   void visit(Harness h) {
     expect(h.flow.isAssigned(variable), expectedAssignedState);
-    h.irBuilder.atom('null');
+    h.irBuilder.atom('null', Kind.statement, location: location);
   }
 }
 
@@ -905,11 +1334,12 @@
 
   final String expectedContext;
 
-  _CheckExpressionContext(this.inner, this.expectedContext);
+  _CheckExpressionContext(this.inner, this.expectedContext,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    inner.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    inner.preVisit(visitor);
   }
 
   @override
@@ -929,11 +1359,11 @@
 
   final String expectedIr;
 
-  _CheckExpressionIr(this.inner, this.expectedIr);
+  _CheckExpressionIr(this.inner, this.expectedIr, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    inner.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    inner.preVisit(visitor);
   }
 
   @override
@@ -943,7 +1373,7 @@
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
     var result =
         h.typeAnalyzer.analyzeParenthesizedExpression(this, inner, context);
-    h.irBuilder.check(expectedIr);
+    h.irBuilder.check(expectedIr, Kind.expression, location: location);
     return result;
   }
 }
@@ -951,13 +1381,13 @@
 class _CheckExpressionType extends Expression {
   final Expression target;
   final String expectedType;
-  final StackTrace _creationTrace = StackTrace.current;
 
-  _CheckExpressionType(this.target, this.expectedType);
+  _CheckExpressionType(this.target, this.expectedType,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    target.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    target.preVisit(visitor);
   }
 
   @override
@@ -967,7 +1397,7 @@
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
     var result =
         h.typeAnalyzer.analyzeParenthesizedExpression(this, target, context);
-    expect(result.type.type, expectedType, reason: '$_creationTrace');
+    expect(result.type.type, expectedType, reason: 'at $location');
     return result;
   }
 }
@@ -975,13 +1405,13 @@
 class _CheckPromoted extends Statement {
   final Promotable promotable;
   final String? expectedTypeStr;
-  final StackTrace _creationTrace = StackTrace.current;
 
-  _CheckPromoted(this.promotable, this.expectedTypeStr);
+  _CheckPromoted(this.promotable, this.expectedTypeStr,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    promotable.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    promotable.preVisit(visitor);
   }
 
   @override
@@ -995,26 +1425,27 @@
   @override
   void visit(Harness h) {
     var promotedType = promotable._getPromotedType(h);
-    expect(promotedType?.type, expectedTypeStr, reason: '$_creationTrace');
+    expect(promotedType?.type, expectedTypeStr, reason: 'at $location');
+    h.irBuilder
+        .apply('stmt', [Kind.expression], Kind.statement, location: location);
   }
 }
 
 class _CheckReachable extends Statement {
   final bool expectedReachable;
-  final StackTrace _creationTrace = StackTrace.current;
 
-  _CheckReachable(this.expectedReachable);
+  _CheckReachable(this.expectedReachable, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() => 'check reachable;';
 
   @override
   void visit(Harness h) {
-    expect(h.flow.isReachable, expectedReachable, reason: '$_creationTrace');
-    h.irBuilder.atom('null');
+    expect(h.flow.isReachable, expectedReachable, reason: 'at $location');
+    h.irBuilder.atom('null', Kind.statement, location: location);
   }
 }
 
@@ -1023,11 +1454,11 @@
 
   final String expectedIr;
 
-  _CheckStatementIr(this.inner, this.expectedIr);
+  _CheckStatementIr(this.inner, this.expectedIr, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    inner.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    inner.preVisit(visitor);
   }
 
   @override
@@ -1036,19 +1467,19 @@
   @override
   void visit(Harness h) {
     h.typeAnalyzer.dispatchStatement(inner);
-    h.irBuilder.check(expectedIr);
+    h.irBuilder.check(expectedIr, Kind.statement, location: location);
   }
 }
 
 class _CheckUnassigned extends Statement {
   final Var variable;
   final bool expectedUnassignedState;
-  final StackTrace _creationTrace = StackTrace.current;
 
-  _CheckUnassigned(this.variable, this.expectedUnassignedState);
+  _CheckUnassigned(this.variable, this.expectedUnassignedState,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() {
@@ -1059,8 +1490,8 @@
   @override
   void visit(Harness h) {
     expect(h.flow.isUnassigned(variable), expectedUnassignedState,
-        reason: '$_creationTrace');
-    h.irBuilder.atom('null');
+        reason: 'at $location');
+    h.irBuilder.atom('null', Kind.statement, location: location);
   }
 }
 
@@ -1069,15 +1500,16 @@
   final Expression ifTrue;
   final Expression ifFalse;
 
-  _Conditional(this.condition, this.ifTrue, this.ifFalse);
+  _Conditional(this.condition, this.ifTrue, this.ifFalse,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    condition.preVisit(assignedVariables);
-    assignedVariables.beginNode();
-    ifTrue.preVisit(assignedVariables);
-    assignedVariables.endNode(this);
-    ifFalse.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    condition.preVisit(visitor);
+    visitor._assignedVariables.beginNode();
+    ifTrue.preVisit(visitor);
+    visitor._assignedVariables.endNode(this);
+    ifFalse.preVisit(visitor);
   }
 
   @override
@@ -1087,14 +1519,48 @@
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
     var result = h.typeAnalyzer
         .analyzeConditionalExpression(this, condition, ifTrue, ifFalse);
-    h.irBuilder.apply('if', 3);
+    h.irBuilder.apply('if', [Kind.expression, Kind.expression, Kind.expression],
+        Kind.expression,
+        location: location);
     return result;
   }
 }
 
-class _Continue extends Statement {
+class _ConstantPattern extends Pattern {
+  final Expression constant;
+
+  _ConstantPattern(this.constant, {required super.location}) : super._();
+
+  Type computeSchema(Harness h) =>
+      h.typeAnalyzer.analyzeConstantPatternSchema();
+
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(
+      PreVisitor visitor, VariableBinder<Node, Var, Type> variableBinder) {
+    constant.preVisit(visitor);
+  }
+
+  void visit(
+      Harness h,
+      Type matchedType,
+      Map<Var, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context) {
+    h.typeAnalyzer.analyzeConstantPattern(
+        matchedType, typeInfos, context, this, constant);
+    h.irBuilder.atom(matchedType.type, Kind.type, location: location);
+    h.irBuilder.apply('const', [Kind.expression, Kind.type], Kind.pattern,
+        names: ['matchedType'], location: location);
+  }
+
+  @override
+  _debugString({required bool needsKeywordOrType}) => constant.toString();
+}
+
+class _Continue extends Statement {
+  _Continue({required super.location});
+
+  @override
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() => 'continue;';
@@ -1102,28 +1568,31 @@
   @override
   void visit(Harness h) {
     h.typeAnalyzer.analyzeContinueStatement();
-    h.irBuilder.apply('continue', 0);
+    h.irBuilder.apply('continue', [], Kind.statement, location: location);
   }
 }
 
 class _Declare extends Statement {
   final bool isLate;
   final bool isFinal;
-  final Type? declaredType;
-  final Var variable;
+  final Pattern pattern;
   final Expression? initializer;
-  final String? expectInferredType;
 
-  _Declare(this.variable, this.initializer,
-      {required this.isLate,
-      required this.isFinal,
-      required this.declaredType,
-      this.expectInferredType});
+  _Declare(this.pattern, this.initializer,
+      {required this.isLate, required this.isFinal, required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    assignedVariables.declare(variable);
-    initializer?.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    var variableBinder = VariableBinder<Node, Var, Type>(visitor);
+    pattern.preVisit(visitor, variableBinder);
+    variableBinder.finish();
+    if (isLate) {
+      visitor._assignedVariables.beginNode();
+    }
+    initializer?.preVisit(visitor);
+    if (isLate) {
+      visitor._assignedVariables.endNode(this);
+    }
   }
 
   @override
@@ -1131,8 +1600,7 @@
     var parts = <String>[
       if (isLate) 'late',
       if (isFinal) 'final',
-      if (declaredType != null) declaredType!.type else if (!isFinal) 'var',
-      variable.name,
+      pattern._debugString(needsKeywordOrType: !isFinal),
       if (initializer != null) '= $initializer'
     ];
     return '${parts.join(' ')};';
@@ -1140,31 +1608,55 @@
 
   @override
   void visit(Harness h) {
-    h.irBuilder.atom(variable.name);
-    h.typeAnalyzer.analyzeVariableDeclaration(
-        this, declaredType, variable, initializer,
-        isFinal: isFinal, isLate: isLate);
-    var expectInferredType = this.expectInferredType;
-    if (expectInferredType != null) {
-      expect(variable.type.type, expectInferredType);
+    String irName;
+    List<Kind> argKinds;
+    var initializer = this.initializer;
+    if (initializer == null) {
+      var pattern = this.pattern as _VariablePattern;
+      var staticType = h.typeAnalyzer.analyzeUninitializedVariableDeclaration(
+          this, pattern.variable!, pattern.declaredType,
+          isFinal: isFinal, isLate: isLate);
+      h.typeAnalyzer.handleVariablePattern(pattern,
+          matchedType: staticType, staticType: staticType);
+      irName = 'declare';
+      argKinds = [Kind.pattern];
+    } else {
+      h.typeAnalyzer.analyzeInitializedVariableDeclaration(
+          this, pattern, initializer,
+          isFinal: isFinal, isLate: isLate);
+      irName = 'match';
+      argKinds = [Kind.expression, Kind.pattern];
     }
     h.irBuilder.apply(
-        ['declare', if (isLate) 'late', if (isFinal) 'final'].join('_'), 2);
+        [irName, if (isLate) 'late', if (isFinal) 'final'].join('_'),
+        argKinds,
+        Kind.statement,
+        location: location);
   }
 }
 
+class _Default extends Node with CaseHead, CaseHeads {
+  _Default({required super.location}) : super._();
+
+  @override
+  Expression? get _guard => null;
+
+  @override
+  Pattern? get _pattern => null;
+}
+
 class _Do extends Statement {
   final Statement body;
   final Expression condition;
 
-  _Do(this.body, this.condition);
+  _Do(this.body, this.condition, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    assignedVariables.beginNode();
-    body.preVisit(assignedVariables);
-    condition.preVisit(assignedVariables);
-    assignedVariables.endNode(this);
+  void preVisit(PreVisitor visitor) {
+    visitor._assignedVariables.beginNode();
+    body.preVisit(visitor);
+    condition.preVisit(visitor);
+    visitor._assignedVariables.endNode(this);
   }
 
   @override
@@ -1173,7 +1665,8 @@
   @override
   void visit(Harness h) {
     h.typeAnalyzer.analyzeDoLoop(this, body, condition);
-    h.irBuilder.apply('do', 2);
+    h.irBuilder.apply('do', [Kind.statement, Kind.expression], Kind.statement,
+        location: location);
   }
 }
 
@@ -1182,12 +1675,12 @@
   final Expression rhs;
   final bool isInverted;
 
-  _Equal(this.lhs, this.rhs, this.isInverted);
+  _Equal(this.lhs, this.rhs, this.isInverted, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    lhs.preVisit(assignedVariables);
-    rhs.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    lhs.preVisit(visitor);
+    rhs.preVisit(visitor);
   }
 
   @override
@@ -1198,7 +1691,9 @@
     var operatorName = isInverted ? '!=' : '==';
     var result =
         h.typeAnalyzer.analyzeBinaryExpression(this, lhs, operatorName, rhs);
-    h.irBuilder.apply(operatorName, 2);
+    h.irBuilder.apply(
+        operatorName, [Kind.expression, Kind.expression], Kind.expression,
+        location: location);
     return result;
   }
 }
@@ -1208,11 +1703,11 @@
 
   final Type context;
 
-  _ExpressionInContext(this.expr, this.context);
+  _ExpressionInContext(this.expr, this.context, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    expr.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    expr.preVisit(visitor);
   }
 
   @override
@@ -1221,17 +1716,19 @@
   @override
   void visit(Harness h) {
     h.typeAnalyzer.analyzeExpression(expr, context);
+    h.irBuilder
+        .apply('stmt', [Kind.expression], Kind.statement, location: location);
   }
 }
 
 class _ExpressionStatement extends Statement {
   final Expression expr;
 
-  _ExpressionStatement(this.expr);
+  _ExpressionStatement(this.expr, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    expr.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    expr.preVisit(visitor);
   }
 
   @override
@@ -1240,6 +1737,8 @@
   @override
   void visit(Harness h) {
     h.typeAnalyzer.analyzeExpressionStatement(expr);
+    h.irBuilder
+        .apply('stmt', [Kind.expression], Kind.statement, location: location);
   }
 }
 
@@ -1251,16 +1750,17 @@
   final bool forCollection;
 
   _For(this.initializer, this.condition, this.updater, this.body,
-      this.forCollection);
+      this.forCollection,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    initializer?.preVisit(assignedVariables);
-    assignedVariables.beginNode();
-    condition?.preVisit(assignedVariables);
-    body.preVisit(assignedVariables);
-    updater?.preVisit(assignedVariables);
-    assignedVariables.endNode(this);
+  void preVisit(PreVisitor visitor) {
+    initializer?.preVisit(visitor);
+    visitor._assignedVariables.beginNode();
+    condition?.preVisit(visitor);
+    body.preVisit(visitor);
+    updater?.preVisit(visitor);
+    visitor._assignedVariables.endNode(this);
   }
 
   @override
@@ -1288,24 +1788,28 @@
     if (initializer != null) {
       h.typeAnalyzer.dispatchStatement(initializer!);
     } else {
-      h.typeAnalyzer.handleNoInitializer();
+      h.typeAnalyzer.handleNoInitializer(this);
     }
     h.flow.for_conditionBegin(this);
     if (condition != null) {
-      h.typeAnalyzer.analyzeExpression(condition!);
+      h.typeAnalyzer.analyzeExpression(condition!, h.typeAnalyzer.unknownType);
     } else {
-      h.typeAnalyzer.handleNoCondition();
+      h.typeAnalyzer.handleNoCondition(this);
     }
     h.flow.for_bodyBegin(forCollection ? null : this, condition);
     h.typeAnalyzer._visitLoopBody(this, body);
     h.flow.for_updaterBegin();
     if (updater != null) {
-      h.typeAnalyzer.analyzeExpression(updater!);
+      h.typeAnalyzer.analyzeExpression(updater!, h.typeAnalyzer.unknownType);
     } else {
-      h.typeAnalyzer.handleNoStatement();
+      h.typeAnalyzer.handleNoCondition(this);
     }
     h.flow.for_end();
-    h.irBuilder.apply('for', 4);
+    h.irBuilder.apply(
+        'for',
+        [Kind.statement, Kind.expression, Kind.statement, Kind.expression],
+        Kind.statement,
+        location: location);
   }
 }
 
@@ -1315,21 +1819,22 @@
   final Statement body;
   final bool declaresVariable;
 
-  _ForEach(this.variable, this.iterable, this.body, this.declaresVariable);
+  _ForEach(this.variable, this.iterable, this.body, this.declaresVariable,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    iterable.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    iterable.preVisit(visitor);
     if (variable != null) {
       if (declaresVariable) {
-        assignedVariables.declare(variable!);
+        visitor._assignedVariables.declare(variable!);
       } else {
-        assignedVariables.write(variable!);
+        visitor._assignedVariables.write(variable!);
       }
     }
-    assignedVariables.beginNode();
-    body.preVisit(assignedVariables);
-    assignedVariables.endNode(this);
+    visitor._assignedVariables.beginNode();
+    body.preVisit(visitor);
+    visitor._assignedVariables.endNode(this);
   }
 
   @override
@@ -1347,8 +1852,8 @@
 
   @override
   void visit(Harness h) {
-    var iteratedType =
-        h._getIteratedType(h.typeAnalyzer.analyzeExpression(iterable));
+    var iteratedType = h._getIteratedType(
+        h.typeAnalyzer.analyzeExpression(iterable, h.typeAnalyzer.unknownType));
     h.flow.forEach_bodyBegin(this);
     var variable = this.variable;
     if (variable != null && !declaresVariable) {
@@ -1356,34 +1861,105 @@
     }
     h.typeAnalyzer._visitLoopBody(this, body);
     h.flow.forEach_end();
-    h.irBuilder.apply('forEach', 2);
+    h.irBuilder.apply(
+        'forEach', [Kind.expression, Kind.statement], Kind.statement,
+        location: location);
   }
 }
 
-class _If extends Statement {
+class _GuardedCaseHead extends Node with CaseHead, CaseHeads {
+  @override
+  final Pattern _pattern;
+
+  @override
+  final Expression _guard;
+
+  _GuardedCaseHead(this._pattern, this._guard, {required super.location})
+      : super._();
+}
+
+class _If extends _IfBase {
   final Expression condition;
-  final Statement ifTrue;
-  final Statement? ifFalse;
 
-  _If(this.condition, this.ifTrue, this.ifFalse);
+  _If(this.condition, super.ifTrue, super.ifFalse, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    condition.preVisit(assignedVariables);
-    assignedVariables.beginNode();
-    ifTrue.preVisit(assignedVariables);
-    assignedVariables.endNode(this);
-    ifFalse?.preVisit(assignedVariables);
+  String get _conditionPartString => condition.toString();
+
+  @override
+  void preVisit(PreVisitor visitor) {
+    condition.preVisit(visitor);
+    super.preVisit(visitor);
   }
 
   @override
-  String toString() =>
-      'if ($condition) $ifTrue' + (ifFalse == null ? '' : 'else $ifFalse');
-
-  @override
   void visit(Harness h) {
     h.typeAnalyzer.analyzeIfStatement(this, condition, ifTrue, ifFalse);
-    h.irBuilder.apply('if', 3);
+    h.irBuilder.apply(
+        'if', [Kind.expression, Kind.statement, Kind.statement], Kind.statement,
+        location: location);
+  }
+}
+
+abstract class _IfBase extends Statement {
+  final Statement ifTrue;
+  final Statement? ifFalse;
+
+  _IfBase(this.ifTrue, this.ifFalse, {required super.location});
+
+  String get _conditionPartString;
+
+  @override
+  void preVisit(PreVisitor visitor) {
+    visitor._assignedVariables.beginNode();
+    ifTrue.preVisit(visitor);
+    visitor._assignedVariables.endNode(this);
+    ifFalse?.preVisit(visitor);
+  }
+
+  @override
+  String toString() =>
+      'if ($_conditionPartString) $ifTrue' +
+      (ifFalse == null ? '' : 'else $ifFalse');
+}
+
+class _IfCase extends _IfBase {
+  final Expression _expression;
+  final Pattern _pattern;
+  final Expression? _guard;
+
+  _IfCase(
+      this._expression, this._pattern, this._guard, super.ifTrue, super.ifFalse,
+      {required super.location});
+
+  @override
+  String get _conditionPartString => '$_expression case $_pattern';
+
+  @override
+  void preVisit(PreVisitor visitor) {
+    _expression.preVisit(visitor);
+    var variableBinder = VariableBinder<Node, Var, Type>(visitor);
+    _pattern.preVisit(visitor, variableBinder);
+    variableBinder.finish();
+    _guard?.preVisit(visitor);
+    super.preVisit(visitor);
+  }
+
+  @override
+  void visit(Harness h) {
+    h.typeAnalyzer.analyzeIfCaseStatement(
+        this, _expression, _pattern, _guard, ifTrue, ifFalse);
+    h.irBuilder.apply(
+        'ifCase',
+        [
+          Kind.expression,
+          Kind.pattern,
+          Kind.expression,
+          Kind.statement,
+          Kind.statement
+        ],
+        Kind.statement,
+        location: location);
   }
 }
 
@@ -1391,12 +1967,12 @@
   final Expression lhs;
   final Expression rhs;
 
-  _IfNull(this.lhs, this.rhs);
+  _IfNull(this.lhs, this.rhs, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    lhs.preVisit(assignedVariables);
-    rhs.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    lhs.preVisit(visitor);
+    rhs.preVisit(visitor);
   }
 
   @override
@@ -1405,7 +1981,9 @@
   @override
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
     var result = h.typeAnalyzer.analyzeIfNullExpression(this, lhs, rhs);
-    h.irBuilder.apply('ifNull', 2);
+    h.irBuilder.apply(
+        'ifNull', [Kind.expression, Kind.expression], Kind.expression,
+        location: location);
     return result;
   }
 }
@@ -1417,10 +1995,11 @@
   /// does, or does not, happen.  `null` if no assertion should be done.
   final bool? expectConversionToDouble;
 
-  _IntLiteral(this.value, {this.expectConversionToDouble});
+  _IntLiteral(this.value,
+      {this.expectConversionToDouble, required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() => '$value';
@@ -1431,8 +2010,10 @@
     if (expectConversionToDouble != null) {
       expect(result.convertedToDouble, expectConversionToDouble);
     }
-    h.irBuilder
-        .atom(result.convertedToDouble ? '${value.toDouble()}f' : '$value');
+    h.irBuilder.atom(
+        result.convertedToDouble ? '${value.toDouble()}f' : '$value',
+        Kind.expression,
+        location: location);
     return result;
   }
 }
@@ -1442,11 +2023,11 @@
   final Type type;
   final bool isInverted;
 
-  _Is(this.target, this.type, this.isInverted);
+  _Is(this.target, this.type, this.isInverted, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    target.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    target.preVisit(visitor);
   }
 
   @override
@@ -1459,16 +2040,85 @@
   }
 }
 
+class _LabeledStatement extends Statement {
+  final List<Label> _labels = [];
+
+  final Statement _body;
+
+  _LabeledStatement(this._body, {required super.location});
+
+  @override
+  void preVisit(PreVisitor visitor) {
+    _body.preVisit(visitor);
+  }
+
+  @override
+  String toString() => [..._labels, _body].join(': ');
+
+  @override
+  void visit(Harness h) {
+    h.typeAnalyzer.analyzeLabeledStatement(this, _body);
+  }
+}
+
+class _ListPattern extends Pattern {
+  final Type? _elementType;
+
+  final List<Pattern> _elements;
+
+  _ListPattern(this._elementType, this._elements, {required super.location})
+      : super._();
+
+  Type computeSchema(Harness h) => h.typeAnalyzer
+      .analyzeListPatternSchema(elementType: _elementType, elements: _elements);
+
+  @override
+  void preVisit(
+      PreVisitor visitor, VariableBinder<Node, Var, Type> variableBinder) {
+    for (var element in _elements) {
+      element.preVisit(visitor, variableBinder);
+    }
+  }
+
+  void visit(
+      Harness h,
+      Type matchedType,
+      Map<Var, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context) {
+    var requiredType = h.typeAnalyzer.analyzeListPattern(
+        matchedType, typeInfos, context, this,
+        elementType: _elementType, elements: _elements);
+    h.irBuilder.atom(matchedType.type, Kind.type, location: location);
+    h.irBuilder.atom(requiredType.type, Kind.type, location: location);
+    h.irBuilder.apply(
+        'listPattern',
+        [...List.filled(_elements.length, Kind.pattern), Kind.type, Kind.type],
+        Kind.pattern,
+        names: ['matchedType', 'requiredType'],
+        location: location);
+  }
+
+  @override
+  String _debugString({required bool needsKeywordOrType}) {
+    var elements = [
+      for (var element in _elements)
+        element._debugString(needsKeywordOrType: needsKeywordOrType)
+    ];
+    return '[${elements.join(', ')}]';
+  }
+}
+
 class _LocalFunction extends Statement {
   final Statement body;
 
-  _LocalFunction(this.body);
+  _LocalFunction(this.body, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    assignedVariables.beginNode();
-    body.preVisit(assignedVariables);
-    assignedVariables.endNode(this, isClosureOrLateVariableInitializer: true);
+  void preVisit(PreVisitor visitor) {
+    visitor._assignedVariables.beginNode();
+    body.preVisit(visitor);
+    visitor._assignedVariables
+        .endNode(this, isClosureOrLateVariableInitializer: true);
   }
 
   @override
@@ -1487,14 +2137,14 @@
   final Expression rhs;
   final bool isAnd;
 
-  _Logical(this.lhs, this.rhs, {required this.isAnd});
+  _Logical(this.lhs, this.rhs, {required this.isAnd, required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    lhs.preVisit(assignedVariables);
-    assignedVariables.beginNode();
-    rhs.preVisit(assignedVariables);
-    assignedVariables.endNode(this);
+  void preVisit(PreVisitor visitor) {
+    lhs.preVisit(visitor);
+    visitor._assignedVariables.beginNode();
+    rhs.preVisit(visitor);
+    visitor._assignedVariables.endNode(this);
   }
 
   @override
@@ -1505,11 +2155,68 @@
     var operatorName = isAnd ? '&&' : '||';
     var result =
         h.typeAnalyzer.analyzeBinaryExpression(this, lhs, operatorName, rhs);
-    h.irBuilder.apply(operatorName, 2);
+    h.irBuilder.apply(
+        operatorName, [Kind.expression, Kind.expression], Kind.expression,
+        location: location);
     return result;
   }
 }
 
+class _LogicalPattern extends Pattern {
+  final Pattern _lhs;
+
+  final Pattern _rhs;
+
+  final bool isAnd;
+
+  _LogicalPattern(this._lhs, this._rhs,
+      {required this.isAnd, required super.location})
+      : super._();
+
+  Type computeSchema(Harness h) =>
+      h.typeAnalyzer.analyzeLogicalPatternSchema(_lhs, _rhs, isAnd: isAnd);
+
+  @override
+  void preVisit(
+      PreVisitor visitor, VariableBinder<Node, Var, Type> variableBinder) {
+    if (!isAnd) {
+      variableBinder.startAlternatives();
+      variableBinder.startAlternative(_lhs);
+    }
+    _lhs.preVisit(visitor, variableBinder);
+    if (!isAnd) {
+      variableBinder.finishAlternative();
+      variableBinder.startAlternative(_rhs);
+    }
+    _rhs.preVisit(visitor, variableBinder);
+    if (!isAnd) {
+      variableBinder.finishAlternative();
+      variableBinder.finishAlternatives();
+    }
+  }
+
+  void visit(
+      Harness h,
+      Type matchedType,
+      Map<Var, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context) {
+    h.typeAnalyzer.analyzeLogicalPattern(
+        matchedType, typeInfos, context, this, _lhs, _rhs,
+        isAnd: isAnd);
+    h.irBuilder.atom(matchedType.type, Kind.type, location: location);
+    h.irBuilder.apply(isAnd ? 'logicalAndPattern' : 'logicalOrPattern',
+        [Kind.pattern, Kind.pattern, Kind.type], Kind.pattern,
+        names: ['matchedType'], location: location);
+  }
+
+  @override
+  _debugString({required bool needsKeywordOrType}) => [
+        _lhs._debugString(needsKeywordOrType: false),
+        isAnd ? '&' : '|',
+        _rhs._debugString(needsKeywordOrType: false)
+      ].join(' ');
+}
+
 /// Enum representing the different ways an [LValue] might be used.
 enum _LValueDisposition {
   /// The [LValue] is being read from only, not written to.  This happens if it
@@ -1526,16 +2233,127 @@
   readWrite,
 }
 
+class _MiniAstErrors
+    implements
+        TypeAnalyzerErrors<Node, Statement, Expression, Var, Type>,
+        VariableBinderErrors<Node, Var> {
+  final Set<String> _accumulatedErrors = {};
+
+  /// If [assertInErrorRecovery] is called prior to any errors being reported,
+  /// the stack trace is captured and stored in this variable, so that if no
+  /// errors are reported by the end of running the test, we can use it to
+  /// highlight the point of failure.
+  StackTrace? _assertInErrorRecoveryStack;
+
+  @override
+  void assertInErrorRecovery() {
+    if (_accumulatedErrors.isEmpty) {
+      _assertInErrorRecoveryStack ??= StackTrace.current;
+    }
+  }
+
+  @override
+  void caseExpressionTypeMismatch(
+      {required Expression scrutinee,
+      required Expression caseExpression,
+      required scrutineeType,
+      required caseExpressionType,
+      required bool nullSafetyEnabled}) {
+    _recordError('caseExpressionTypeMismatch(scrutinee: ${scrutinee.errorId}, '
+        'caseExpression: ${caseExpression.errorId}, '
+        'scrutineeType: ${scrutineeType.type}, '
+        'caseExpressionType: ${caseExpressionType.type}, '
+        'nullSafetyEnabled: $nullSafetyEnabled)');
+  }
+
+  @override
+  void inconsistentMatchVar(
+      {required Node pattern,
+      required Type type,
+      required Node previousPattern,
+      required Type previousType}) {
+    _recordError(
+        'inconsistentMatchVar(pattern: ${pattern.errorId}, type: ${type.type}, '
+        'previousPattern: ${previousPattern.errorId}, '
+        'previousType: ${previousType.type})');
+  }
+
+  @override
+  void inconsistentMatchVarExplicitness(
+      {required Node pattern, required Node previousPattern}) {
+    _recordError(
+        'inconsistentMatchVarExplicitness(pattern: ${pattern.errorId}, '
+        'previousPattern: ${previousPattern.errorId})');
+  }
+
+  @override
+  void matchVarOverlap({required Node pattern, required Node previousPattern}) {
+    _recordError('matchVarOverlap(pattern: ${pattern.errorId}, '
+        'previousPattern: ${previousPattern.errorId})');
+  }
+
+  @override
+  void missingMatchVar(Node alternative, Var variable) {
+    _recordError('missingMatchVar(${alternative.errorId}, ${variable.name})');
+  }
+
+  @override
+  void nonBooleanCondition(Expression node) {
+    _recordError('nonBooleanCondition(${node.errorId})');
+  }
+
+  @override
+  void patternDoesNotAllowLate(Node pattern) {
+    _recordError('patternDoesNotAllowLate(${pattern.errorId})');
+  }
+
+  @override
+  void patternTypeMismatchInIrrefutableContext(
+      {required Node pattern,
+      required Node context,
+      required Type matchedType,
+      required Type requiredType}) {
+    _recordError(
+        'patternTypeMismatchInIrrefutableContext(pattern: ${pattern.errorId}, '
+        'context: ${context.errorId}, matchedType: ${matchedType.type}, '
+        'requiredType: ${requiredType.type})');
+  }
+
+  @override
+  void refutablePatternInIrrefutableContext(Node pattern, Node context) {
+    _recordError('refutablePatternInIrrefutableContext(${pattern.errorId}, '
+        '${context.errorId})');
+  }
+
+  @override
+  void switchCaseCompletesNormally(
+      covariant _SwitchStatement node, int caseIndex, int numHeads) {
+    _recordError(
+        'switchCaseCompletesNormally(${node.errorId}, $caseIndex, $numHeads)');
+  }
+
+  void _recordError(String errorText) {
+    _assertInErrorRecoveryStack = null;
+    if (!_accumulatedErrors.add(errorText)) {
+      fail('Same error reported twice: $errorText');
+    }
+  }
+}
+
 class _MiniAstTypeAnalyzer
     with TypeAnalyzer<Node, Statement, Expression, Var, Type> {
   final Harness _harness;
 
+  @override
+  final _MiniAstErrors errors = _MiniAstErrors();
+
   Statement? _currentBreakTarget;
 
   Statement? _currentContinueTarget;
 
   final _irBuilder = MiniIrBuilder();
 
+  @override
   late final Type boolType = Type('bool');
 
   @override
@@ -1552,9 +2370,15 @@
   late final Type nullType = Type('Null');
 
   @override
+  late final Type objectQuestionType = Type('Object?');
+
+  @override
   late final Type unknownType = Type('?');
 
-  _MiniAstTypeAnalyzer(this._harness);
+  @override
+  final TypeAnalyzerOptions options;
+
+  _MiniAstTypeAnalyzer(this._harness, this.options);
 
   @override
   FlowAnalysis<Node, Statement, Expression, Var, Type> get flow =>
@@ -1563,16 +2387,17 @@
   Type get thisType => _harness._thisType!;
 
   @override
-  TypeOperations<Type> get typeOperations => _harness;
+  TypeOperations2<Type> get typeOperations => _harness;
 
-  void analyzeAssertStatement(Expression condition, Expression? message) {
+  void analyzeAssertStatement(
+      Statement node, Expression condition, Expression? message) {
     flow.assert_begin();
-    analyzeExpression(condition);
+    analyzeExpression(condition, unknownType);
     flow.assert_afterCondition(condition);
     if (message != null) {
-      analyzeExpression(message);
+      analyzeExpression(message, unknownType);
     } else {
-      handleNoMessage();
+      handleNoMessage(node);
     }
     flow.assert_end();
   }
@@ -1610,14 +2435,14 @@
     if (isLogical) {
       flow.logicalBinaryOp_begin();
     }
-    var leftType = analyzeExpression(lhs);
+    var leftType = analyzeExpression(lhs, unknownType);
     EqualityInfo<Type>? leftInfo;
     if (isEquals) {
       leftInfo = flow.equalityOperand_end(lhs, leftType);
     } else if (isLogical) {
       flow.logicalBinaryOp_rightBegin(lhs, node, isAnd: isAnd);
     }
-    var rightType = analyzeExpression(rhs);
+    var rightType = analyzeExpression(rhs, unknownType);
     if (isEquals) {
       flow.equalityOperation_end(
           node, leftInfo, flow.equalityOperand_end(rhs, rightType),
@@ -1646,11 +2471,11 @@
   SimpleTypeAnalysisResult<Type> analyzeConditionalExpression(Expression node,
       Expression condition, Expression ifTrue, Expression ifFalse) {
     flow.conditional_conditionBegin();
-    analyzeExpression(condition);
+    analyzeExpression(condition, unknownType);
     flow.conditional_thenBegin(condition, node);
-    var ifTrueType = analyzeExpression(ifTrue);
+    var ifTrueType = analyzeExpression(ifTrue, unknownType);
     flow.conditional_elseBegin(ifTrue);
-    var ifFalseType = analyzeExpression(ifFalse);
+    var ifFalseType = analyzeExpression(ifFalse, unknownType);
     flow.conditional_end(node, ifFalse);
     return new SimpleTypeAnalysisResult<Type>(
         type: leastUpperBound(ifTrueType, ifFalseType));
@@ -1664,51 +2489,25 @@
     flow.doStatement_bodyBegin(node);
     _visitLoopBody(node, body);
     flow.doStatement_conditionBegin();
-    analyzeExpression(condition);
+    analyzeExpression(condition, unknownType);
     flow.doStatement_end(condition);
   }
 
-  Type analyzeExpression(Expression expression, [Type? context]) {
-    // TODO(paulberry): make the [context] argument required.
-    context ??= unknownType;
-    var result = dispatchExpression(expression, context);
-    if (flow.operations.isNever(result.provisionalType)) {
-      flow.handleExit();
-    }
-    return result.resolveShorting();
-  }
-
   void analyzeExpressionStatement(Expression expression) {
-    analyzeExpression(expression);
+    analyzeExpression(expression, unknownType);
   }
 
   SimpleTypeAnalysisResult<Type> analyzeIfNullExpression(
       Expression node, Expression lhs, Expression rhs) {
-    var leftType = analyzeExpression(lhs);
+    var leftType = analyzeExpression(lhs, unknownType);
     flow.ifNullExpression_rightBegin(lhs, leftType);
-    var rightType = analyzeExpression(rhs);
+    var rightType = analyzeExpression(rhs, unknownType);
     flow.ifNullExpression_end();
     return new SimpleTypeAnalysisResult<Type>(
         type: leastUpperBound(
             flow.operations.promoteToNonNull(leftType), rightType));
   }
 
-  void analyzeIfStatement(Statement node, Expression condition,
-      Statement ifTrue, Statement? ifFalse) {
-    flow.ifStatement_conditionBegin();
-    analyzeExpression(condition);
-    flow.ifStatement_thenBegin(condition, node);
-    dispatchStatement(ifTrue);
-    if (ifFalse == null) {
-      handleNoStatement();
-      flow.ifStatement_end(false);
-    } else {
-      flow.ifStatement_elseBegin();
-      dispatchStatement(ifFalse);
-      flow.ifStatement_end(true);
-    }
-  }
-
   void analyzeLabeledStatement(Statement node, Statement body) {
     flow.labeledStatement_begin(node);
     dispatchStatement(body);
@@ -1717,14 +2516,14 @@
 
   SimpleTypeAnalysisResult<Type> analyzeLogicalNot(
       Expression node, Expression expression) {
-    analyzeExpression(expression);
+    analyzeExpression(expression, unknownType);
     flow.logicalNot_end(node, expression);
     return new SimpleTypeAnalysisResult<Type>(type: boolType);
   }
 
   SimpleTypeAnalysisResult<Type> analyzeNonNullAssert(
       Expression node, Expression expression) {
-    var type = analyzeExpression(expression);
+    var type = analyzeExpression(expression, unknownType);
     flow.nonNullAssert_end(expression);
     return new SimpleTypeAnalysisResult<Type>(
         type: flow.operations.promoteToNonNull(type));
@@ -1744,7 +2543,7 @@
 
   ExpressionTypeAnalysisResult<Type> analyzePropertyGet(
       Expression node, Expression receiver, String propertyName) {
-    var receiverType = analyzeExpression(receiver);
+    var receiverType = analyzeExpression(receiver, unknownType);
     var member = _lookupMember(node, receiverType, propertyName);
     var promotedType =
         flow.propertyGet(node, receiver, propertyName, member, member._type);
@@ -1757,20 +2556,6 @@
     flow.handleExit();
   }
 
-  void analyzeSwitchStatement(
-      _Switch node, Expression expression, List<SwitchCase> cases) {
-    analyzeExpression(expression);
-    flow.switchStatement_expressionEnd(node);
-    var previousBreakTarget = _currentBreakTarget;
-    _currentBreakTarget = node;
-    for (var case_ in cases) {
-      flow.switchStatement_beginCase(case_._hasLabel, node);
-      dispatchStatement(case_._body);
-    }
-    _currentBreakTarget = previousBreakTarget;
-    flow.switchStatement_end(isSwitchExhaustive(node));
-  }
-
   SimpleTypeAnalysisResult<Type> analyzeThis(Expression node) {
     var thisType = this.thisType;
     flow.thisOrSuper(node, thisType);
@@ -1788,7 +2573,7 @@
 
   SimpleTypeAnalysisResult<Type> analyzeThrow(
       Expression node, Expression expression) {
-    analyzeExpression(expression);
+    analyzeExpression(expression, unknownType);
     flow.handleExit();
     return new SimpleTypeAnalysisResult<Type>(type: neverType);
   }
@@ -1818,13 +2603,13 @@
       dispatchStatement(finallyBlock);
       flow.tryFinallyStatement_end();
     } else {
-      handleNoStatement();
+      handleNoStatement(node);
     }
   }
 
   SimpleTypeAnalysisResult<Type> analyzeTypeCast(
       Expression node, Expression expression, Type type) {
-    analyzeExpression(expression);
+    analyzeExpression(expression, unknownType);
     flow.asExpression_end(expression, type);
     return new SimpleTypeAnalysisResult<Type>(type: type);
   }
@@ -1832,30 +2617,11 @@
   SimpleTypeAnalysisResult<Type> analyzeTypeTest(
       Expression node, Expression expression, Type type,
       {bool isInverted = false}) {
-    analyzeExpression(expression);
+    analyzeExpression(expression, unknownType);
     flow.isExpression_end(node, expression, isInverted, type);
     return new SimpleTypeAnalysisResult<Type>(type: boolType);
   }
 
-  void analyzeVariableDeclaration(
-      Statement node, Type? declaredType, Var variable, Expression? initializer,
-      {required bool isFinal, required bool isLate}) {
-    if (initializer == null) {
-      handleNoInitializer();
-      flow.declare(variable, false);
-      variable.type = declaredType ?? dynamicType;
-    } else {
-      var initializerType = analyzeExpression(initializer);
-      flow.declare(variable, true);
-      variable.type =
-          declaredType ?? variableTypeFromInitializerType(initializerType);
-      flow.initialize(variable, initializerType, initializer,
-          isFinal: isFinal,
-          isLate: isLate,
-          isImplicitlyTyped: declaredType == null);
-    }
-  }
-
   SimpleTypeAnalysisResult<Type> analyzeVariableGet(
       Expression node, Var variable, void Function(Type?)? callback) {
     var promotedType = flow.variableRead(node, variable);
@@ -1866,7 +2632,7 @@
 
   void analyzeWhileLoop(Statement node, Expression condition, Statement body) {
     flow.whileStatement_conditionBegin(node);
-    analyzeExpression(condition);
+    analyzeExpression(condition, unknownType);
     flow.whileStatement_bodyBegin(node, condition);
     _visitLoopBody(node, body);
     flow.whileStatement_end();
@@ -1878,6 +2644,20 @@
       _irBuilder.guard(expression, () => expression.visit(_harness, context));
 
   @override
+  void dispatchPattern(
+      Type matchedType,
+      Map<Var, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context,
+      covariant Pattern node) {
+    return node.visit(_harness, matchedType, typeInfos, context);
+  }
+
+  @override
+  Type dispatchPatternSchema(covariant Pattern node) {
+    return node.computeSchema(_harness);
+  }
+
+  @override
   void dispatchStatement(Statement statement) =>
       _irBuilder.guard(statement, () => statement.visit(_harness));
 
@@ -1885,38 +2665,136 @@
     flow.finish();
   }
 
-  void handleNoCondition() {
-    _irBuilder.atom('true');
+  @override
+  void finishExpressionCase(Expression node, int caseIndex) {
+    _irBuilder.apply(
+        'case', [Kind.caseHead, Kind.expression], Kind.expressionCase,
+        location: node.location);
   }
 
-  void handleNoInitializer() {
-    _irBuilder.atom('uninitialized');
+  @override
+  SwitchExpressionMemberInfo<Node, Expression> getSwitchExpressionMemberInfo(
+          covariant _SwitchExpression node, int index) =>
+      node.cases[index];
+
+  @override
+  SwitchStatementMemberInfo<Node, Statement, Expression>
+      getSwitchStatementMemberInfo(
+          covariant _SwitchStatement node, int caseIndex) {
+    StatementCase case_ = node.cases[caseIndex];
+    return SwitchStatementMemberInfo([
+      for (var caseHead in case_._caseHeads._caseHeads)
+        CaseHeadOrDefaultInfo(
+            pattern: caseHead._pattern, guard: caseHead._guard)
+    ], case_._body.statements, labels: case_._caseHeads._labels);
   }
 
-  void handleNoMessage() {
-    _irBuilder.atom('failure');
+  @override
+  void handleCase_afterCaseHeads(
+      covariant _SwitchStatement node, int caseIndex, int numHeads) {
+    var labels = node.cases[caseIndex]._caseHeads._labels;
+    for (var label in labels) {
+      _irBuilder.atom(label._name, Kind.caseHead, location: node.location);
+    }
+    _irBuilder.apply('heads',
+        List.filled(numHeads + labels.length, Kind.caseHead), Kind.caseHeads,
+        location: node.location);
   }
 
-  void handleNoStatement() {
-    _irBuilder.atom('noop');
+  @override
+  void handleCaseHead(Node node,
+      {required int caseIndex, required int subIndex}) {
+    _irBuilder.apply('head', [Kind.pattern, Kind.expression], Kind.caseHead,
+        location: node.location);
   }
 
-  bool isSwitchExhaustive(_Switch node) {
+  @override
+  void handleDefault(Node node, int caseIndex) {
+    _irBuilder.atom('default', Kind.caseHead, location: node.location);
+  }
+
+  @override
+  void handleMergedStatementCase(Statement node,
+      {required int caseIndex,
+      required int executionPathIndex,
+      required int numStatements}) {
+    _irBuilder.apply(
+        'block', List.filled(numStatements, Kind.statement), Kind.statement,
+        location: node.location);
+    _irBuilder.apply(
+        'case', [Kind.caseHeads, Kind.statement], Kind.statementCase,
+        location: node.location);
+  }
+
+  void handleNoCondition(Node node) {
+    _irBuilder.atom('true', Kind.expression, location: node.location);
+  }
+
+  @override
+  void handleNoGuard(Node node, int caseIndex) {
+    _irBuilder.atom('true', Kind.expression, location: node.location);
+  }
+
+  void handleNoInitializer(Node node) {
+    _irBuilder.atom('uninitialized', Kind.statement, location: node.location);
+  }
+
+  void handleNoMessage(Node node) {
+    _irBuilder.atom('failure', Kind.expression, location: node.location);
+  }
+
+  @override
+  void handleNoStatement(Node node) {
+    _irBuilder.atom('noop', Kind.statement, location: node.location);
+  }
+
+  @override
+  void handleSwitchScrutinee(Type type) {}
+
+  void handleVariablePattern(covariant _VariablePattern node,
+      {required Type matchedType, required Type staticType}) {
+    _irBuilder.atom(node.variable?.name ?? '_', Kind.variable,
+        location: node.location);
+    _irBuilder.atom(matchedType.type, Kind.type, location: node.location);
+    _irBuilder.atom(staticType.type, Kind.type, location: node.location);
+    _irBuilder.apply(
+        'varPattern', [Kind.variable, Kind.type, Kind.type], Kind.pattern,
+        names: ['matchedType', 'staticType'], location: node.location);
+    var expectInferredType = node.expectInferredType;
+    if (expectInferredType != null) {
+      expect(staticType.type, expectInferredType);
+    }
+  }
+
+  @override
+  bool isSwitchExhaustive(
+      covariant _SwitchStatement node, Type expressionType) {
     return node.isExhaustive;
   }
 
+  @override
+  bool isVariablePattern(Node pattern) => pattern is _VariablePattern;
+
   Type leastUpperBound(Type t1, Type t2) => _harness._lub(t1, t2);
 
+  @override
+  Type listType(Type elementType) =>
+      NonFunctionType('List', args: [elementType]);
+
   _PropertyElement lookupInterfaceMember(
       Node node, Type receiverType, String memberName) {
     return _harness.getMember(receiverType, memberName);
   }
 
   @override
+  void setVariableType(Var variable, Type type) {
+    variable.type = type;
+  }
+
+  @override
   String toString() => _irBuilder.toString();
 
-  /// Computes the type that should be inferred for an implicitly typed variable
-  /// whose initializer expression has static type [type].
+  @override
   Type variableTypeFromInitializerType(Type type) {
     // Variables whose initializer has type `Null` receive the inferred type
     // `dynamic`.
@@ -1950,11 +2828,11 @@
 class _NonNullAssert extends Expression {
   final Expression operand;
 
-  _NonNullAssert(this.operand);
+  _NonNullAssert(this.operand, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    operand.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    operand.preVisit(visitor);
   }
 
   @override
@@ -1969,11 +2847,11 @@
 class _Not extends Expression {
   final Expression operand;
 
-  _Not(this.operand);
+  _Not(this.operand, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    operand.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    operand.preVisit(visitor);
   }
 
   @override
@@ -1992,12 +2870,13 @@
   final Expression rhs;
   final bool isCascaded;
 
-  _NullAwareAccess(this.lhs, this.rhs, this.isCascaded);
+  _NullAwareAccess(this.lhs, this.rhs, this.isCascaded,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    lhs.preVisit(assignedVariables);
-    rhs.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    lhs.preVisit(visitor);
+    rhs.preVisit(visitor);
   }
 
   @override
@@ -2005,21 +2884,62 @@
 
   @override
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
-    var lhsType = h.typeAnalyzer.analyzeExpression(lhs);
+    var lhsType =
+        h.typeAnalyzer.analyzeExpression(lhs, h.typeAnalyzer.unknownType);
     h.flow.nullAwareAccess_rightBegin(isCascaded ? null : lhs, lhsType);
-    var rhsType = h.typeAnalyzer.analyzeExpression(rhs);
+    var rhsType =
+        h.typeAnalyzer.analyzeExpression(rhs, h.typeAnalyzer.unknownType);
     h.flow.nullAwareAccess_end();
     var type = h._lub(rhsType, Type('Null'));
-    h.irBuilder.apply(_fakeMethodName, 2);
+    h.irBuilder.apply(
+        _fakeMethodName, [Kind.expression, Kind.expression], Kind.expression,
+        location: location);
     return new SimpleTypeAnalysisResult<Type>(type: type);
   }
 }
 
-class _NullLiteral extends Expression {
-  _NullLiteral();
+class _NullCheckOrAssertPattern extends Pattern {
+  final Pattern _inner;
+
+  final bool _isAssert;
+
+  _NullCheckOrAssertPattern(this._inner, this._isAssert,
+      {required super.location})
+      : super._();
+
+  Type computeSchema(Harness h) => h.typeAnalyzer
+      .analyzeNullCheckOrAssertPatternSchema(_inner, isAssert: _isAssert);
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(
+      PreVisitor visitor, VariableBinder<Node, Var, Type> variableBinder) {
+    _inner.preVisit(visitor, variableBinder);
+  }
+
+  void visit(
+      Harness h,
+      Type matchedType,
+      Map<Var, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context) {
+    h.typeAnalyzer.analyzeNullCheckOrAssertPattern(
+        matchedType, typeInfos, context, this, _inner,
+        isAssert: _isAssert);
+    h.irBuilder.atom(matchedType.type, Kind.type, location: location);
+    h.irBuilder.apply(_isAssert ? 'nullAssertPattern' : 'nullCheckPattern',
+        [Kind.pattern, Kind.type], Kind.pattern,
+        names: ['matchedType'], location: location);
+  }
+
+  @override
+  String _debugString({required bool needsKeywordOrType}) =>
+      '${_inner._debugString(needsKeywordOrType: needsKeywordOrType)}?';
+}
+
+class _NullLiteral extends Expression {
+  _NullLiteral({required super.location});
+
+  @override
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() => 'null';
@@ -2027,7 +2947,7 @@
   @override
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
     var result = h.typeAnalyzer.analyzeNullLiteral(this);
-    h.irBuilder.atom('null');
+    h.irBuilder.atom('null', Kind.expression, location: location);
     return result;
   }
 }
@@ -2035,11 +2955,11 @@
 class _ParenthesizedExpression extends Expression {
   final Expression expr;
 
-  _ParenthesizedExpression(this.expr);
+  _ParenthesizedExpression(this.expr, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    expr.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    expr.preVisit(visitor);
   }
 
   @override
@@ -2054,18 +2974,18 @@
 class _PlaceholderExpression extends Expression {
   final Type type;
 
-  _PlaceholderExpression(this.type);
+  _PlaceholderExpression(this.type, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() => '(expr with type $type)';
 
   @override
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
-    h.irBuilder.atom(type.type);
-    h.irBuilder.apply('expr', 1);
+    h.irBuilder.atom(type.type, Kind.type, location: location);
+    h.irBuilder.apply('expr', [Kind.type], Kind.expression, location: location);
     return new SimpleTypeAnalysisResult<Type>(type: type);
   }
 }
@@ -2075,12 +2995,13 @@
 
   final String propertyName;
 
-  _Property(this.target, this.propertyName) : super._();
+  _Property(this.target, this.propertyName, {required super.location})
+      : super._();
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables,
+  void preVisit(PreVisitor visitor,
       {_LValueDisposition disposition = _LValueDisposition.read}) {
-    target.preVisit(assignedVariables);
+    target.preVisit(visitor);
   }
 
   @override
@@ -2090,7 +3011,8 @@
 
   @override
   Type? _getPromotedType(Harness h) {
-    var receiverType = h.typeAnalyzer.analyzeExpression(target);
+    var receiverType =
+        h.typeAnalyzer.analyzeExpression(target, h.typeAnalyzer.unknownType);
     var member = h.typeAnalyzer._lookupMember(this, receiverType, propertyName);
     return h.flow
         .promotedPropertyType(target, propertyName, member, member._type);
@@ -2113,8 +3035,10 @@
 }
 
 class _Return extends Statement {
+  _Return({required super.location});
+
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() => 'return;';
@@ -2122,25 +3046,99 @@
   @override
   void visit(Harness h) {
     h.typeAnalyzer.analyzeReturnStatement();
-    h.irBuilder.apply('return', 0);
+    h.irBuilder.apply('return', [], Kind.statement, location: location);
   }
 }
 
-class _Switch extends Statement {
-  final Expression expression;
-  final List<SwitchCase> cases;
-  final bool isExhaustive;
+class _SwitchExpression extends Expression {
+  final Expression scrutinee;
 
-  _Switch(this.expression, this.cases, this.isExhaustive);
+  final List<ExpressionCase> cases;
+
+  _SwitchExpression(this.scrutinee, this.cases, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    expression.preVisit(assignedVariables);
-    assignedVariables.beginNode();
+  void preVisit(PreVisitor visitor) {
+    scrutinee.preVisit(visitor);
     for (var case_ in cases) {
-      case_._preVisit(assignedVariables);
+      case_._preVisit(visitor);
     }
-    assignedVariables.endNode(this);
+  }
+
+  @override
+  String toString() {
+    String body;
+    if (cases.isEmpty) {
+      body = '{}';
+    } else {
+      var contents = cases.join(' ');
+      body = '{ $contents }';
+    }
+    return 'switch ($scrutinee) $body';
+  }
+
+  @override
+  ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
+    var result = h.typeAnalyzer
+        .analyzeSwitchExpression(this, scrutinee, cases.length, context);
+    h.irBuilder.apply(
+        'switchExpr',
+        [Kind.expression, ...List.filled(cases.length, Kind.expressionCase)],
+        Kind.expression,
+        location: location);
+    return result;
+  }
+}
+
+class _SwitchStatement extends Statement {
+  final Expression scrutinee;
+
+  final List<StatementCase> cases;
+
+  final bool isExhaustive;
+
+  final bool? expectHasDefault;
+
+  final bool? expectIsExhaustive;
+
+  final bool? expectLastCaseTerminates;
+
+  final String? expectScrutineeType;
+
+  _SwitchStatement(this.scrutinee, this.cases, this.isExhaustive,
+      {required super.location,
+      required this.expectHasDefault,
+      required this.expectIsExhaustive,
+      required this.expectLastCaseTerminates,
+      required this.expectScrutineeType});
+
+  @override
+  void preVisit(PreVisitor visitor) {
+    scrutinee.preVisit(visitor);
+    visitor._assignedVariables.beginNode();
+    VariableBinder<Node, Var, Type>? variableBinder;
+    for (var case_ in cases) {
+      variableBinder ??= VariableBinder<Node, Var, Type>(visitor)
+        ..startAlternatives();
+      for (var label in case_._caseHeads._labels) {
+        variableBinder.startAlternative(label);
+        variableBinder.finishAlternative();
+      }
+      for (var caseHead in case_._caseHeads._caseHeads) {
+        caseHead._preVisit(visitor, variableBinder);
+      }
+      if (case_._body.statements.isNotEmpty) {
+        variableBinder.finishAlternatives();
+        variableBinder.finish();
+        variableBinder = null;
+      }
+      case_._body.preVisit(visitor);
+    }
+    if (variableBinder != null) {
+      variableBinder.finishAlternatives();
+      variableBinder.finish();
+    }
+    visitor._assignedVariables.endNode(this);
   }
 
   @override
@@ -2153,19 +3151,41 @@
       var contents = cases.join(' ');
       body = '{ $contents }';
     }
-    return 'switch<$exhaustiveness> ($expression) $body';
+    return 'switch<$exhaustiveness> ($scrutinee) $body';
   }
 
   @override
   void visit(Harness h) {
-    h.typeAnalyzer.analyzeSwitchStatement(this, expression, cases);
-    h.irBuilder.apply('switch', cases.length + 1);
+    var previousBreakTarget = h.typeAnalyzer._currentBreakTarget;
+    h.typeAnalyzer._currentBreakTarget = this;
+    var previousContinueTarget = h.typeAnalyzer._currentContinueTarget;
+    h.typeAnalyzer._currentContinueTarget = this;
+    var analysisResult =
+        h.typeAnalyzer.analyzeSwitchStatement(this, scrutinee, cases.length);
+    expect(analysisResult.hasDefault, expectHasDefault ?? anything);
+    expect(analysisResult.isExhaustive, expectIsExhaustive ?? anything);
+    expect(analysisResult.lastCaseTerminates,
+        expectLastCaseTerminates ?? anything);
+    expect(analysisResult.scrutineeType.type, expectScrutineeType ?? anything);
+    var numExecutionPaths = analysisResult.numExecutionPaths;
+    h.irBuilder.apply(
+        'switch',
+        [
+          Kind.expression,
+          ...List.filled(numExecutionPaths, Kind.statementCase)
+        ],
+        Kind.statement,
+        location: location);
+    h.typeAnalyzer._currentBreakTarget = previousBreakTarget;
+    h.typeAnalyzer._currentContinueTarget = previousContinueTarget;
   }
 }
 
 class _This extends Expression {
+  _This({required super.location});
+
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+  void preVisit(PreVisitor visitor) {}
 
   @override
   String toString() => 'this';
@@ -2173,7 +3193,7 @@
   @override
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
     var result = h.typeAnalyzer.analyzeThis(this);
-    h.irBuilder.atom('this');
+    h.irBuilder.atom('this', Kind.expression, location: location);
     return result;
   }
 }
@@ -2181,22 +3201,23 @@
 class _ThisOrSuperProperty extends PromotableLValue {
   final String propertyName;
 
-  _ThisOrSuperProperty(this.propertyName) : super._();
+  _ThisOrSuperProperty(this.propertyName, {required super.location})
+      : super._();
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables,
+  void preVisit(PreVisitor visitor,
       {_LValueDisposition disposition = _LValueDisposition.read}) {}
 
   @override
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
     var result = h.typeAnalyzer.analyzeThisPropertyGet(this, propertyName);
-    h.irBuilder.atom('this.$propertyName');
+    h.irBuilder.atom('this.$propertyName', Kind.expression, location: location);
     return result;
   }
 
   @override
   Type? _getPromotedType(Harness h) {
-    h.irBuilder.atom('this.$propertyName');
+    h.irBuilder.atom('this.$propertyName', Kind.expression, location: location);
     var member = h.typeAnalyzer._lookupMember(this, h._thisType!, propertyName);
     return h.flow
         .promotedPropertyType(null, propertyName, member, member._type);
@@ -2212,11 +3233,11 @@
 class _Throw extends Expression {
   final Expression operand;
 
-  _Throw(this.operand);
+  _Throw(this.operand, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    operand.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    operand.preVisit(visitor);
   }
 
   @override
@@ -2233,65 +3254,133 @@
   final List<_CatchClause> _catches;
   final Statement? _finally;
 
-  _TryStatement(this._body, this._catches, this._finally) : super._();
+  _TryStatement(this._body, this._catches, this._finally,
+      {required super.location})
+      : super._();
 
   @override
   TryStatement catch_(
       {Var? exception, Var? stackTrace, required List<Statement> body}) {
     assert(_finally == null, 'catch after finally');
-    return _TryStatement(_body,
-        [..._catches, _CatchClause(block(body), exception, stackTrace)], null);
+    return _TryStatement(
+        _body,
+        [
+          ..._catches,
+          _CatchClause(
+              _Block(body, location: computeLocation()), exception, stackTrace)
+        ],
+        null,
+        location: location);
   }
 
   @override
   Statement finally_(List<Statement> statements) {
     assert(_finally == null, 'multiple finally clauses');
-    return _TryStatement(_body, _catches, block(statements));
+    return _TryStatement(
+        _body, _catches, _Block(statements, location: computeLocation()),
+        location: location);
   }
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
+  void preVisit(PreVisitor visitor) {
     if (_finally != null) {
-      assignedVariables.beginNode();
+      visitor._assignedVariables.beginNode();
     }
     if (_catches.isNotEmpty) {
-      assignedVariables.beginNode();
+      visitor._assignedVariables.beginNode();
     }
-    _body.preVisit(assignedVariables);
-    assignedVariables.endNode(_body);
+    _body.preVisit(visitor);
+    visitor._assignedVariables.endNode(_body);
     for (var catch_ in _catches) {
-      catch_._preVisit(assignedVariables);
+      catch_._preVisit(visitor);
     }
     if (_finally != null) {
       if (_catches.isNotEmpty) {
-        assignedVariables.endNode(this);
+        visitor._assignedVariables.endNode(this);
       }
-      _finally!.preVisit(assignedVariables);
+      _finally!.preVisit(visitor);
     }
   }
 
   @override
   void visit(Harness h) {
     h.typeAnalyzer.analyzeTryStatement(this, _body, _catches, _finally);
-    h.irBuilder.apply('try', 2 + _catches.length);
+    h.irBuilder.apply(
+        'try',
+        [
+          Kind.statement,
+          ...List.filled(_catches.length, Kind.statement),
+          Kind.statement
+        ],
+        Kind.statement,
+        location: location);
   }
 }
 
+class _VariablePattern extends Pattern {
+  final Type? declaredType;
+
+  final Var? variable;
+
+  final String? expectInferredType;
+
+  final bool isFinal;
+
+  _VariablePattern(this.declaredType, this.variable, this.expectInferredType,
+      {this.isFinal = false, required super.location})
+      : super._();
+
+  Type computeSchema(Harness h) =>
+      h.typeAnalyzer.analyzeVariablePatternSchema(declaredType);
+
+  @override
+  void preVisit(
+      PreVisitor visitor, VariableBinder<Node, Var, Type> variableBinder) {
+    var variable = this.variable;
+    if (variable != null && variableBinder.add(this, variable)) {
+      visitor._assignedVariables.declare(variable);
+    }
+  }
+
+  void visit(
+      Harness h,
+      Type matchedType,
+      Map<Var, VariableTypeInfo<Node, Type>> typeInfos,
+      MatchContext<Node, Expression> context) {
+    var staticType = h.typeAnalyzer.analyzeVariablePattern(
+        matchedType, typeInfos, context, this, variable, declaredType,
+        isFinal: isFinal);
+    h.typeAnalyzer.handleVariablePattern(this,
+        matchedType: matchedType, staticType: staticType);
+  }
+
+  @override
+  _debugString({required bool needsKeywordOrType}) => [
+        if (declaredType != null)
+          declaredType!.type
+        else if (needsKeywordOrType)
+          'var',
+        variable?.name ?? '_',
+        if (expectInferredType != null) '(expected type $expectInferredType)'
+      ].join(' ');
+}
+
 class _VariableReference extends LValue {
   final Var variable;
 
   final void Function(Type?)? callback;
 
-  _VariableReference(this.variable, this.callback) : super._();
+  _VariableReference(this.variable, this.callback, {required super.location})
+      : super._();
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables,
+  void preVisit(PreVisitor visitor,
       {_LValueDisposition disposition = _LValueDisposition.read}) {
     if (disposition != _LValueDisposition.write) {
-      assignedVariables.read(variable);
+      visitor._assignedVariables.read(variable);
     }
     if (disposition != _LValueDisposition.read) {
-      assignedVariables.write(variable);
+      visitor._assignedVariables.write(variable);
     }
   }
 
@@ -2301,7 +3390,7 @@
   @override
   ExpressionTypeAnalysisResult<Type> visit(Harness h, Type context) {
     var result = h.typeAnalyzer.analyzeVariableGet(this, variable, callback);
-    h.irBuilder.atom(variable.name);
+    h.irBuilder.atom(variable.name, Kind.expression, location: location);
     return result;
   }
 
@@ -2316,14 +3405,14 @@
   final Expression condition;
   final Statement body;
 
-  _While(this.condition, this.body);
+  _While(this.condition, this.body, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    assignedVariables.beginNode();
-    condition.preVisit(assignedVariables);
-    body.preVisit(assignedVariables);
-    assignedVariables.endNode(this);
+  void preVisit(PreVisitor visitor) {
+    visitor._assignedVariables.beginNode();
+    condition.preVisit(visitor);
+    body.preVisit(visitor);
+    visitor._assignedVariables.endNode(this);
   }
 
   @override
@@ -2332,7 +3421,9 @@
   @override
   void visit(Harness h) {
     h.typeAnalyzer.analyzeWhileLoop(this, condition, body);
-    h.irBuilder.apply('while', 2);
+    h.irBuilder.apply(
+        'while', [Kind.expression, Kind.statement], Kind.statement,
+        location: location);
   }
 }
 
@@ -2341,13 +3432,14 @@
   final Expression expr;
   final Statement? after;
 
-  _WrappedExpression(this.before, this.expr, this.after);
+  _WrappedExpression(this.before, this.expr, this.after,
+      {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    before?.preVisit(assignedVariables);
-    expr.preVisit(assignedVariables);
-    after?.preVisit(assignedVariables);
+  void preVisit(PreVisitor visitor) {
+    before?.preVisit(visitor);
+    expr.preVisit(visitor);
+    after?.preVisit(visitor);
   }
 
   @override
@@ -2369,20 +3461,25 @@
     late MiniIrTmp beforeTmp;
     if (before != null) {
       h.typeAnalyzer.dispatchStatement(before!);
+      h.irBuilder
+          .apply('expr', [Kind.statement], Kind.expression, location: location);
       beforeTmp = h.irBuilder.allocateTmp();
     }
-    var type = h.typeAnalyzer.analyzeExpression(expr);
+    var type =
+        h.typeAnalyzer.analyzeExpression(expr, h.typeAnalyzer.unknownType);
     if (after != null) {
       var exprTmp = h.irBuilder.allocateTmp();
       h.typeAnalyzer.dispatchStatement(after!);
+      h.irBuilder
+          .apply('expr', [Kind.statement], Kind.expression, location: location);
       var afterTmp = h.irBuilder.allocateTmp();
-      h.irBuilder.readTmp(exprTmp);
-      h.irBuilder.let(afterTmp);
-      h.irBuilder.let(exprTmp);
+      h.irBuilder.readTmp(exprTmp, location: location);
+      h.irBuilder.let(afterTmp, location: location);
+      h.irBuilder.let(exprTmp, location: location);
     }
     h.flow.forwardExpression(this, expr);
     if (before != null) {
-      h.irBuilder.let(beforeTmp);
+      h.irBuilder.let(beforeTmp, location: location);
     }
     return new SimpleTypeAnalysisResult<Type>(type: type);
   }
@@ -2392,15 +3489,15 @@
   final LValue lhs;
   final Expression? rhs;
 
-  _Write(this.lhs, this.rhs);
+  _Write(this.lhs, this.rhs, {required super.location});
 
   @override
-  void preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    lhs.preVisit(assignedVariables,
+  void preVisit(PreVisitor visitor) {
+    lhs.preVisit(visitor,
         disposition: rhs == null
             ? _LValueDisposition.readWrite
             : _LValueDisposition.write);
-    rhs?.preVisit(assignedVariables);
+    rhs?.preVisit(visitor);
   }
 
   @override
@@ -2413,9 +3510,9 @@
     if (rhs == null) {
       // We are simulating an increment/decrement operation.
       // TODO(paulberry): Make a separate node type for this.
-      type = h.typeAnalyzer.analyzeExpression(lhs);
+      type = h.typeAnalyzer.analyzeExpression(lhs, h.typeAnalyzer.unknownType);
     } else {
-      type = h.typeAnalyzer.analyzeExpression(rhs);
+      type = h.typeAnalyzer.analyzeExpression(rhs, h.typeAnalyzer.unknownType);
     }
     lhs._visitWrite(h, this, type, rhs);
     // TODO(paulberry): null shorting
diff --git a/pkg/_fe_analyzer_shared/test/mini_ir.dart b/pkg/_fe_analyzer_shared/test/mini_ir.dart
index b3f0dfa..07f390d 100644
--- a/pkg/_fe_analyzer_shared/test/mini_ir.dart
+++ b/pkg/_fe_analyzer_shared/test/mini_ir.dart
@@ -9,6 +9,61 @@
 
 import 'mini_ast.dart';
 
+/// A single stack entry representing an intermediate representation of some
+/// Dart code produced using the facilities of `mini_ast.dart`.
+class IrNode {
+  /// The intermediate representation itself, expressed as a string.
+  final String ir;
+
+  /// The location of the Dart code that led to this [IrNode].
+  final String location;
+
+  /// The kind of entity represented by this [IrNode].
+  final Kind kind;
+
+  IrNode({required this.ir, required this.location, required this.kind});
+
+  @override
+  String toString() => '$kind $ir ($location)';
+}
+
+/// Kinds of entities that can be represented by an [IrNode].
+enum Kind {
+  /// A single `case` or `default` clause in a switch statement or switch
+  /// expression.
+  caseHead,
+
+  /// A set of `case` or `default` clauses in a switch statement, which all
+  /// share the same body.
+  caseHeads,
+
+  /// An expression.
+  expression,
+
+  /// A single case from a switch expression, consisting of a [caseHead] and a
+  /// body [expression].
+  expressionCase,
+
+  /// A label for `break` or `continue` to branch to.
+  label,
+
+  /// A pattern.
+  pattern,
+
+  /// A statement.
+  statement,
+
+  /// A single case from a switch statement, consisting of [caseHeads] and body
+  /// [statement]s.
+  statementCase,
+
+  /// A type in the type system.
+  type,
+
+  /// A local variable.
+  variable,
+}
+
 /// Stack-based builder class allowing construction of a miniature string-based
 /// internal representation ("IR") of Dart code suitable for use in unit
 /// testing.
@@ -29,7 +84,7 @@
   int _popLimit = 0;
 
   /// Stack of partially built IR nodes.
-  final _stack = <String>[];
+  final _stack = <IrNode>[];
 
   /// Number of temporaries allocated so far.
   int _tmpCounter = 0;
@@ -46,22 +101,39 @@
   ///
   /// See [let].
   MiniIrTmp allocateTmp() {
-    return MiniIrTmp._('t${_tmpCounter++}', _pop());
+    return MiniIrTmp._('t${_tmpCounter++}', _pop(Kind.expression).ir);
   }
 
   /// Pops the top [numArgs] nodes from the stack and pushes a node that
   /// combines them using [name].  For example, if the stack contains `1, 2, 3`,
   /// calling `apply('f', 2)` results in a stack of `1, f(2, 3)`.
-  void apply(String name, int numArgs) =>
-      _push('$name(${_popList(numArgs).join(', ')})');
+  ///
+  /// Optional argument [names] allows applying names to the last n arguments.
+  /// For example, if the stack contains `1, 2, 3`, calling
+  /// `apply('f', 3, names: ['a', 'b'])` results in a stack of
+  /// `f(1, a: 2, b: 3)`.
+  void apply(String name, List<Kind> inputKinds, Kind outputKind,
+      {required String location, List<String> names = const []}) {
+    var args = [
+      for (var irNode in _popList(inputKinds.length, inputKinds)) irNode.ir
+    ];
+    for (int i = 1; i <= names.length; i++) {
+      args[args.length - i] =
+          '${names[names.length - i]}: ${args[args.length - i]}';
+    }
+    _push(IrNode(
+        ir: '$name(${args.join(', ')})', kind: outputKind, location: location));
+  }
 
   /// Pushes a node on the stack representing a single atomic expression (for
   /// example a literal value or a variable reference).
-  void atom(String name) => _push(name);
+  void atom(String name, Kind kind, {required String location}) =>
+      _push(IrNode(ir: name, kind: kind, location: location));
 
   /// Verifies that the top node on the stack matches [expectedIr] exactly.
-  void check(String expectedIr) {
-    expect(_stack.last.toString(), expectedIr);
+  void check(String expectedIr, Kind expectedKind, {required String location}) {
+    expect(_stack.last, _nodeWithKind(expectedKind), reason: 'at $location');
+    expect(_stack.last.ir, expectedIr, reason: 'at $location');
   }
 
   /// Pushes a node representing a `for-in` loop onto the stack, using a loop
@@ -69,12 +141,16 @@
   ///
   /// If [tmp] is non-null, it is used as the loop variable instead of obtaining
   /// it from the stack.
-  void forIn(MiniIrTmp? tmp, {required bool isAsynchronous}) {
+  void forIn(MiniIrTmp? tmp,
+      {required String location, required bool isAsynchronous}) {
     var name = isAsynchronous ? 'forIn_async' : 'forIn';
-    var body = _pop();
-    var iterable = _pop();
-    var variable = tmp == null ? _pop() : tmp._name;
-    _push('$name($variable, $iterable, $body)');
+    var body = _pop(Kind.statement);
+    var iterable = _pop(Kind.expression);
+    var variable = tmp == null ? _pop(Kind.variable) : tmp._name;
+    _push(IrNode(
+        ir: '$name($variable, $iterable, $body)',
+        kind: Kind.statement,
+        location: location));
   }
 
   /// Executes [callback], checking that it leaves all nodes presently on the
@@ -106,9 +182,12 @@
   ///
   /// This is intended to be used as a building block for null shorting
   /// operations.
-  void ifNotNull(MiniIrTmp tmp) {
-    _push('if(==(${tmp._name}, null), null, ${_pop()})');
-    let(tmp);
+  void ifNotNull(MiniIrTmp tmp, {required String location}) {
+    _push(IrNode(
+        ir: 'if(==(${tmp._name}, null), null, ${_pop(Kind.expression)})',
+        kind: Kind.expression,
+        location: location));
+    let(tmp, location: location);
   }
 
   /// Pushes a node representing an "if null" check onto the stack, using [tmp]
@@ -117,27 +196,37 @@
   ///
   /// This is intended to be used as a building block for null `??` and `??=`
   /// operations.
-  void ifNull(MiniIrTmp tmp) {
-    var ifNull = _pop();
-    var ifNotNull = _pop();
-    _push('if(==(${tmp._name}, null), $ifNull, $ifNotNull)');
-    let(tmp);
+  void ifNull(MiniIrTmp tmp, {required String location}) {
+    var ifNull = _pop(Kind.expression);
+    var ifNotNull = _pop(Kind.expression);
+    _push(IrNode(
+        ir: 'if(==(${tmp._name}, null), $ifNull, $ifNotNull)',
+        kind: Kind.expression,
+        location: location));
+    let(tmp, location: location);
   }
 
   /// Pushes a node representing a call to `operator[]` onto the stack, using
   /// a receiver and an index obtained from the stack.
-  void indexGet() => apply('[]', 2);
+  void indexGet({required String location}) =>
+      apply('[]', [Kind.expression, Kind.expression], Kind.expression,
+          location: location);
 
   /// Pushes a node representing a call to `operator[]=` onto the stack, using
   /// a receiver, index, and value obtained from the stack.
   ///
   /// If [receiverTmp] and/or [indexTmp] is non-null, they are used instead of
   /// obtaining values from the stack.
-  void indexSet(MiniIrTmp? receiverTmp, MiniIrTmp? indexTmp) {
-    var value = _pop();
-    var index = indexTmp == null ? _pop() : indexTmp._name;
-    var receiver = receiverTmp == null ? _pop() : receiverTmp._name;
-    _push('[]=($receiver, $index, $value)');
+  void indexSet(MiniIrTmp? receiverTmp, MiniIrTmp? indexTmp,
+      {required String location}) {
+    var value = _pop(Kind.expression);
+    var index = indexTmp == null ? _pop(Kind.expression) : indexTmp._name;
+    var receiver =
+        receiverTmp == null ? _pop(Kind.expression) : receiverTmp._name;
+    _push(IrNode(
+        ir: '[]=($receiver, $index, $value)',
+        kind: Kind.expression,
+        location: location));
   }
 
   /// Pushes a node representing a labeled statement onto the stack, using an
@@ -149,10 +238,13 @@
   /// - build `stmt` on the stack, using [referToLabel] to refer to label as
   ///   needed.
   /// - Call [labeled] to build the final `labeled` statement.
-  void labeled(MiniIrLabel label) {
+  void labeled(MiniIrLabel label, {required String location}) {
     var name = label._name;
     if (name != null) {
-      _push('labeled($name, ${_pop()})');
+      _push(IrNode(
+          ir: 'labeled($name, ${_pop(Kind.statement)})',
+          kind: Kind.statement,
+          location: location));
     }
   }
 
@@ -169,60 +261,86 @@
   /// - Build `expr` on the stack, using [readTmp] to refer to the temporary
   ///   variable as needed.
   /// - Call [let] to build the final `let` expression.
-  void let(MiniIrTmp tmp) {
-    _push('let(${tmp._name}, ${tmp._value}, ${_pop()})');
+  void let(MiniIrTmp tmp, {required String location}) {
+    _push(IrNode(
+        ir: 'let(${tmp._name}, ${tmp._value}, ${_pop(Kind.expression)})',
+        kind: Kind.expression,
+        location: location));
   }
 
   /// Pushes a node representing a property get onto the stack, using a receiver
   /// obtained from the stack.
-  void propertyGet(String propertyName) => apply('get_$propertyName', 1);
+  void propertyGet(String propertyName, {required String location}) =>
+      apply('get_$propertyName', [Kind.expression], Kind.expression,
+          location: location);
 
   /// Pushes a node representing a property set onto the stack, using a receiver
   /// and value obtained from the stack.
   ///
   /// If [receiverTmp] is non-null, it is used as the receiver rather than
   /// obtaining it from the stack.
-  void propertySet(MiniIrTmp? receiverTmp, String propertyName) {
-    var value = _pop();
-    var receiver = receiverTmp == null ? _pop() : receiverTmp._name;
-    _push('set_$propertyName($receiver, $value)');
+  void propertySet(MiniIrTmp? receiverTmp, String propertyName,
+      {required String location}) {
+    var value = _pop(Kind.expression);
+    var receiver =
+        receiverTmp == null ? _pop(Kind.expression) : receiverTmp._name;
+    _push(IrNode(
+        ir: 'set_$propertyName($receiver, $value)',
+        kind: Kind.expression,
+        location: location));
   }
 
   /// Pushes a node representing a read of [tmp] onto the stack.
-  void readTmp(MiniIrTmp tmp) => _push(tmp._name);
+  void readTmp(MiniIrTmp tmp, {required String location}) =>
+      _push(IrNode(ir: tmp._name, kind: Kind.expression, location: location));
 
   /// Pushes a node representing a reference to [label] onto the stack.
-  void referToLabel(MiniIrLabel label) {
-    _push(label._name ??= 'L${_labelCounter++}');
+  void referToLabel(MiniIrLabel label, {required String location}) {
+    _push(IrNode(
+        ir: label._name ??= 'L${_labelCounter++}',
+        kind: Kind.label,
+        location: location));
   }
 
   @override
-  String toString() => _stack.join(', ');
+  String toString() => [for (var irNode in _stack) irNode.ir].join(', ');
 
   /// Pushes a node representing a read of a local variable onto the stack.
-  void variableGet(Var v) => atom(v.name);
+  void variableGet(Var v, {required String location}) =>
+      atom(v.name, Kind.expression, location: location);
 
   /// Pushes a node representing a set of a local variable onto the stack, using
   /// a value obtained from the stack.
-  void variableSet(Var v) => apply('${v.name}=', 1);
+  void variableSet(Var v, {required String location}) =>
+      apply('${v.name}=', [Kind.expression], Kind.expression,
+          location: location);
+
+  TypeMatcher<IrNode> _nodeWithKind(Kind expectedKind) =>
+      TypeMatcher<IrNode>().having((node) => node.kind, 'kind', expectedKind);
 
   /// Pops a single node off the stack.
-  String _pop() {
+  IrNode _pop(Kind expectedKind) {
     expect(_stack.length, greaterThan(_popLimit));
-    return _stack.removeLast();
+    var irNode = _stack.removeLast();
+    expect(irNode, _nodeWithKind(expectedKind));
+    return irNode;
   }
 
   /// Pops a list of nodes off the stack.
-  List<String> _popList(int count) {
+  List<IrNode> _popList(int count, List<Kind> expectedKinds) {
     var newLength = _stack.length - count;
     expect(newLength, greaterThanOrEqualTo(_popLimit));
     var result = _stack.sublist(newLength);
     _stack.length = newLength;
+    expect(result,
+        [for (var expectedKind in expectedKinds) _nodeWithKind(expectedKind)]);
     return result;
   }
 
   /// Pushes a node onto the stack.
-  void _push(String node) => _stack.add(node);
+  void _push(IrNode node) {
+    _stack.add(node);
+  }
 }
 
 /// Representation of a branch target label used by [MiniIrBuilder] when
diff --git a/pkg/_fe_analyzer_shared/test/type_inference/type_inference_test.dart b/pkg/_fe_analyzer_shared/test/type_inference/type_inference_test.dart
index ee058e6..348b69d 100644
--- a/pkg/_fe_analyzer_shared/test/type_inference/type_inference_test.dart
+++ b/pkg/_fe_analyzer_shared/test/type_inference/type_inference_test.dart
@@ -85,5 +85,1798 @@
         ]);
       });
     });
+
+    group('Switch:', () {
+      test('IR', () {
+        h.run([
+          switchExpr(expr('int'), [
+            default_.thenExpr(intLiteral(0)),
+          ]).checkIr('switchExpr(expr(int), case(default, 0))').stmt,
+        ]);
+      });
+
+      test('scrutinee expression context', () {
+        h.run([
+          switchExpr(expr('int').checkContext('?'), [
+            default_.thenExpr(intLiteral(0)),
+          ]).inContext('num'),
+        ]);
+      });
+
+      test('body expression context', () {
+        h.run([
+          switchExpr(expr('int'), [
+            default_.thenExpr(nullLiteral.checkContext('C?')),
+          ]).inContext('C?'),
+        ]);
+      });
+
+      test('least upper bound behavior', () {
+        h.run([
+          switchExpr(expr('int'), [
+            intLiteral(0).pattern.thenExpr(expr('int')),
+            default_.thenExpr(expr('double')),
+          ]).checkType('num').stmt
+        ]);
+      });
+
+      test('guard', () {
+        var i = Var('i');
+        h.run([
+          switchExpr(expr('int'), [
+            i
+                .pattern()
+                .when(i.expr
+                    .checkType('int')
+                    .eq(expr('num'))
+                    .checkContext('bool'))
+                .thenExpr(expr('String')),
+          ])
+              .checkIr('switchExpr(expr(int), '
+                  'case(head(varPattern(i, matchedType: int, '
+                  'staticType: int), ==(i, expr(num))), expr(String)))')
+              .stmt,
+        ]);
+      });
+
+      group('Guard not assignable to bool', () {
+        test('int', () {
+          var x = Var('x');
+          h.run([
+            switchExpr(expr('int'), [
+              x
+                  .pattern()
+                  .when(expr('int')..errorId = 'GUARD')
+                  .thenExpr(expr('int')),
+            ]).stmt,
+          ], expectedErrors: {
+            'nonBooleanCondition(GUARD)'
+          });
+        });
+
+        test('bool', () {
+          var x = Var('x');
+          h.run([
+            switchExpr(expr('int'), [
+              x.pattern().when(expr('bool')).thenExpr(expr('int')),
+            ]).stmt,
+          ], expectedErrors: {});
+        });
+
+        test('dynamic', () {
+          var x = Var('x');
+          h.run([
+            switchExpr(expr('int'), [
+              x.pattern().when(expr('dynamic')).thenExpr(expr('int')),
+            ]).stmt,
+          ], expectedErrors: {});
+        });
+      });
+    });
+  });
+
+  group('Statements:', () {
+    group('If:', () {
+      test('Condition context', () {
+        h.run([
+          if_(expr('dynamic').checkContext('bool'), [
+            expr('Object').stmt,
+          ]).checkIr('if(expr(dynamic), block(stmt(expr(Object))), noop)'),
+        ]);
+      });
+
+      test('With else', () {
+        h.run([
+          if_(expr('bool'), [
+            expr('Object').stmt,
+          ], [
+            expr('String').stmt,
+          ]).checkIr('if(expr(bool), block(stmt(expr(Object))), '
+              'block(stmt(expr(String))))'),
+        ]);
+      });
+    });
+
+    group('If-case:', () {
+      test('Type schema', () {
+        var x = Var('x');
+        h.run([
+          ifCase(expr('int').checkContext('?'), x.pattern(type: 'num'), [
+            expr('Object').stmt,
+          ]).checkIr('ifCase(expr(int), '
+              'varPattern(x, matchedType: int, staticType: num), true, '
+              'block(stmt(expr(Object))), noop)'),
+        ]);
+      });
+
+      test('With else', () {
+        var x = Var('x');
+        h.run([
+          ifCase(expr('num'), x.pattern(type: 'int'), [
+            expr('Object').stmt,
+          ], else_: [
+            expr('String').stmt,
+          ]).checkIr('ifCase(expr(num), '
+              'varPattern(x, matchedType: num, staticType: int), true, '
+              'block(stmt(expr(Object))), block(stmt(expr(String))))'),
+        ]);
+      });
+
+      test('With guard', () {
+        var x = Var('x');
+        h.run([
+          ifCase(expr('num'),
+              x.pattern(type: 'int').when(x.expr.eq(intLiteral(0))), [
+            expr('Object').stmt,
+          ]).checkIr('ifCase(expr(num), '
+              'varPattern(x, matchedType: num, staticType: int), ==(x, 0), '
+              'block(stmt(expr(Object))), noop)'),
+        ]);
+      });
+
+      test('Allows refutable patterns', () {
+        var x = Var('x');
+        h.run([
+          ifCase(expr('num').checkContext('?'), x.pattern(type: 'int'), [
+            expr('Object').stmt,
+          ]).checkIr('ifCase(expr(num), '
+              'varPattern(x, matchedType: num, staticType: int), true, '
+              'block(stmt(expr(Object))), noop)'),
+        ]);
+      });
+
+      group('Guard not assignable to bool', () {
+        test('int', () {
+          var x = Var('x');
+          h.run([
+            ifCase(expr('int'),
+                x.pattern().when(expr('int')..errorId = 'GUARD'), []),
+          ], expectedErrors: {
+            'nonBooleanCondition(GUARD)'
+          });
+        });
+
+        test('bool', () {
+          var x = Var('x');
+          h.run([
+            ifCase(expr('int'), x.pattern().when(expr('bool')), []),
+          ], expectedErrors: {});
+        });
+
+        test('dynamic', () {
+          var x = Var('x');
+          h.run([
+            ifCase(expr('int'), x.pattern().when(expr('dynamic')), []),
+          ], expectedErrors: {});
+        });
+      });
+    });
+
+    group('Switch:', () {
+      test('Empty', () {
+        h.run([
+          switch_(expr('int'), [],
+              isExhaustive: false, expectLastCaseTerminates: true),
+        ]);
+      });
+
+      test('Exhaustive', () {
+        h.run([
+          switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: true,
+              expectIsExhaustive: true),
+        ]);
+      });
+
+      test('No default', () {
+        h.run([
+          switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: false,
+              expectHasDefault: false,
+              expectIsExhaustive: false),
+        ]);
+      });
+
+      test('Has default', () {
+        h.run([
+          switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([
+                  break_(),
+                ]),
+                default_.then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: false,
+              expectHasDefault: true,
+              expectIsExhaustive: true),
+        ]);
+      });
+
+      test('Last case terminates', () {
+        h.run([
+          switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([
+                  expr('int').stmt,
+                ]),
+                intLiteral(1).pattern.then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: false,
+              expectLastCaseTerminates: true),
+        ]);
+      });
+
+      test("Last case doesn't terminate", () {
+        h.run([
+          switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([
+                  break_(),
+                ]),
+                intLiteral(1).pattern.then([
+                  expr('int').stmt,
+                ]),
+              ],
+              isExhaustive: false,
+              expectLastCaseTerminates: false),
+        ]);
+      });
+
+      test('Scrutinee type', () {
+        h.run([
+          switch_(expr('int'), [],
+              isExhaustive: false, expectScrutineeType: 'int'),
+        ]);
+      });
+
+      test('const pattern', () {
+        h.run([
+          switch_(
+                  expr('int').checkContext('?'),
+                  [
+                    intLiteral(0).pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false)
+              .checkIr('switch(expr(int), '
+                  'case(heads(head(const(0, matchedType: int), true)), '
+                  'block(break())))'),
+        ]);
+      });
+
+      group('var pattern:', () {
+        test('untyped', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                    expr('int').checkContext('?'),
+                    [
+                      x.pattern().then([
+                        break_(),
+                      ]),
+                    ],
+                    isExhaustive: false)
+                .checkIr('switch(expr(int), '
+                    'case(heads(head(varPattern(x, matchedType: int, '
+                    'staticType: int), true)), block(break())))'),
+          ]);
+        });
+
+        test('typed', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                    expr('int').checkContext('?'),
+                    [
+                      x.pattern(type: 'num').then([
+                        break_(),
+                      ]),
+                    ],
+                    isExhaustive: false)
+                .checkIr('switch(expr(int), '
+                    'case(heads(head(varPattern(x, matchedType: int, '
+                    'staticType: num), true)), block(break())))'),
+          ]);
+        });
+      });
+
+      test('scrutinee expression context', () {
+        h.run([
+          switch_(
+              expr('int').checkContext('?'),
+              [
+                intLiteral(0).pattern.then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: false),
+        ]);
+      });
+
+      test('merge cases', () {
+        h.run([
+          switch_(
+                  expr('int'),
+                  [
+                    intLiteral(0).pattern.then([]),
+                    intLiteral(1).pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false)
+              .checkIr('switch(expr(int), '
+                  'case(heads(head(const(0, matchedType: int), true), '
+                  'head(const(1, matchedType: int), true)), block(break())))'),
+        ]);
+      });
+
+      test('merge labels', () {
+        var x = Var('x');
+        var l = Label('l');
+        h.run([
+          declare(x, type: 'int?', initializer: expr('int?')),
+          x.expr.as_('int').stmt,
+          switch_(
+                  expr('int'),
+                  [
+                    l.then(intLiteral(0).pattern).then([]),
+                    intLiteral(1).pattern.then([
+                      x.expr.checkType('int?').stmt,
+                      break_(),
+                    ]),
+                    intLiteral(2).pattern.then([
+                      x.expr.checkType('int').stmt,
+                      x.write(nullLiteral).stmt,
+                      continue_(),
+                    ])
+                  ],
+                  isExhaustive: false)
+              .checkIr('switch(expr(int), '
+                  'case(heads(head(const(0, matchedType: int), true), '
+                  'head(const(1, matchedType: int), true), l), '
+                  'block(stmt(x), break())), '
+                  'case(heads(head(const(2, matchedType: int), true)), '
+                  'block(stmt(x), stmt(null), continue())))'),
+        ]);
+      });
+
+      test('empty final case', () {
+        h.run([
+          switch_(
+                  expr('int'),
+                  [
+                    intLiteral(0).pattern.then([
+                      break_(),
+                    ]),
+                    intLiteral(1).pattern.then([]),
+                  ],
+                  isExhaustive: false)
+              .checkIr('switch(expr(int), '
+                  'case(heads(head(const(0, matchedType: int), true)), '
+                  'block(break())), '
+                  'case(heads(head(const(1, matchedType: int), true)), '
+                  'block()))'),
+        ]);
+      });
+
+      test('guard', () {
+        var i = Var('i');
+        h.run([
+          switch_(
+                  expr('int'),
+                  [
+                    i
+                        .pattern()
+                        .when(i.expr
+                            .checkType('int')
+                            .eq(expr('num'))
+                            .checkContext('bool'))
+                        .then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: true)
+              .checkIr('switch(expr(int), '
+                  'case(heads(head(varPattern(i, matchedType: int, '
+                  'staticType: int), ==(i, expr(num)))), block(break())))'),
+        ]);
+      });
+
+      group('missing var:', () {
+        test('default', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                expr('int'),
+                [
+                  x.pattern().then([]),
+                  (default_..errorId = 'DEFAULT').then([]),
+                ],
+                isExhaustive: true),
+          ], expectedErrors: {
+            'missingMatchVar(DEFAULT, x)'
+          });
+        });
+
+        test('case', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                expr('int'),
+                [
+                  (intLiteral(0).pattern..errorId = 'CASE(0)').then([]),
+                  x.pattern().then([]),
+                ],
+                isExhaustive: true),
+          ], expectedErrors: {
+            'missingMatchVar(CASE(0), x)'
+          });
+        });
+
+        test('label', () {
+          var x = Var('x');
+          var l = Label('l')..errorId = 'LABEL';
+          h.run([
+            switch_(
+                expr('int'),
+                [
+                  l.then(x.pattern()).then([]),
+                ],
+                isExhaustive: true),
+          ], expectedErrors: {
+            'missingMatchVar(LABEL, x)'
+          });
+        });
+      });
+
+      group('conflicting var:', () {
+        test('explicit/explicit type', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                expr('num'),
+                [
+                  (x.pattern(type: 'int')..errorId = 'PATTERN(int x)').then([]),
+                  (x.pattern(type: 'num')..errorId = 'PATTERN(num x)').then([]),
+                ],
+                isExhaustive: true),
+          ], expectedErrors: {
+            'inconsistentMatchVar(pattern: PATTERN(num x), type: num, '
+                'previousPattern: PATTERN(int x), previousType: int)'
+          });
+        });
+
+        test('explicit/implicit type', () {
+          // TODO(paulberry): not sure whether this should be treated as a
+          // conflict.  See https://github.com/dart-lang/language/issues/2424.
+          var x = Var('x');
+          h.run([
+            switch_(
+                expr('int'),
+                [
+                  (x.pattern()..errorId = 'PATTERN(x)').then([]),
+                  (x.pattern(type: 'int')..errorId = 'PATTERN(int x)').then([]),
+                ],
+                isExhaustive: true),
+          ], expectedErrors: {
+            'inconsistentMatchVarExplicitness(pattern: PATTERN(int x), '
+                'previousPattern: PATTERN(x))'
+          });
+        });
+
+        test('implicit/implicit type', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                expr('List<int>'),
+                [
+                  (x.pattern()..errorId = 'PATTERN(List<int> x)').then([]),
+                  listPattern([x.pattern()..errorId = 'PATTERN(int x)'])
+                      .then([]),
+                ],
+                isExhaustive: true),
+          ], expectedErrors: {
+            'inconsistentMatchVar(pattern: PATTERN(int x), type: int, '
+                'previousPattern: PATTERN(List<int> x), '
+                'previousType: List<int>)'
+          });
+        });
+      });
+
+      group('Case completes normally:', () {
+        test('Reported when patterns disabled', () {
+          h.patternsEnabled = false;
+          h.run([
+            (switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([
+                  expr('int').stmt,
+                ]),
+                default_.then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: true,
+            )..errorId = 'SWITCH'),
+          ], expectedErrors: {
+            'switchCaseCompletesNormally(SWITCH, 0, 1)'
+          });
+        });
+
+        test('Handles cases that share a body', () {
+          h.patternsEnabled = false;
+          h.run([
+            (switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([]),
+                intLiteral(1).pattern.then([]),
+                intLiteral(2).pattern.then([
+                  expr('int').stmt,
+                ]),
+                default_.then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: true,
+            )..errorId = 'SWITCH'),
+          ], expectedErrors: {
+            'switchCaseCompletesNormally(SWITCH, 0, 3)'
+          });
+        });
+
+        test('Not reported when unreachable', () {
+          h.patternsEnabled = false;
+          h.run([
+            switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([
+                  break_(),
+                ]),
+                default_.then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: true,
+            ),
+          ], expectedErrors: {});
+        });
+
+        test('Not reported for final case', () {
+          h.patternsEnabled = false;
+          h.run([
+            switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([
+                  expr('int').stmt,
+                ]),
+              ],
+              isExhaustive: false,
+            ),
+          ], expectedErrors: {});
+        });
+
+        test('Not reported in legacy mode', () {
+          // In legacy mode, the criteria for reporting a switch case that
+          // "falls through" are less accurate (since flow analysis isn't
+          // available in legacy mode).  This logic is not currently implemented
+          // in the shared analyzer.
+          h.legacy = true;
+          h.run([
+            switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([
+                  expr('int').stmt,
+                ]),
+                default_.then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: false,
+            ),
+          ], expectedErrors: {});
+        });
+
+        test('Not reported when patterns enabled', () {
+          // When patterns are enabled, there is an implicit `break` at the end
+          // of every switch body.
+          h.patternsEnabled = true;
+          h.run([
+            switch_(
+              expr('int'),
+              [
+                intLiteral(0).pattern.then([
+                  expr('int').stmt,
+                ]),
+                default_.then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: false,
+            ),
+          ], expectedErrors: {});
+        });
+      });
+
+      group('Case expression type mismatch:', () {
+        group('Pre-null safety:', () {
+          test('subtype', () {
+            h.legacy = true;
+            h.run([
+              switch_(
+                  expr('num'),
+                  [
+                    expr('int').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+
+          test('supertype', () {
+            h.legacy = true;
+            h.run([
+              switch_(
+                  expr('int'),
+                  [
+                    expr('num').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+
+          test('unrelated types', () {
+            h.legacy = true;
+            h.run([
+              switch_(
+                  expr('int')..errorId = 'SCRUTINEE',
+                  [
+                    (expr('String')..errorId = 'EXPRESSION').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false)
+            ], expectedErrors: {
+              'caseExpressionTypeMismatch(scrutinee: SCRUTINEE, '
+                  'caseExpression: EXPRESSION, scrutineeType: int, '
+                  'caseExpressionType: String, nullSafetyEnabled: false)'
+            });
+          });
+
+          test('dynamic scrutinee', () {
+            h.legacy = true;
+            h.run([
+              switch_(
+                  expr('dynamic'),
+                  [
+                    expr('int').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+
+          test('dynamic case', () {
+            h.legacy = true;
+            h.run([
+              switch_(
+                  expr('int'),
+                  [
+                    expr('dynamic').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+        });
+
+        group('Null safe, patterns disabled:', () {
+          test('subtype', () {
+            h.patternsEnabled = false;
+            h.run([
+              switch_(
+                  expr('num'),
+                  [
+                    expr('int').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+
+          test('supertype', () {
+            h.patternsEnabled = false;
+            h.run([
+              switch_(
+                  expr('int')..errorId = 'SCRUTINEE',
+                  [
+                    (expr('num')..errorId = 'EXPRESSION').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false)
+            ], expectedErrors: {
+              'caseExpressionTypeMismatch(scrutinee: SCRUTINEE, '
+                  'caseExpression: EXPRESSION, scrutineeType: int, '
+                  'caseExpressionType: num, nullSafetyEnabled: true)'
+            });
+          });
+
+          test('unrelated types', () {
+            h.patternsEnabled = false;
+            h.run([
+              switch_(
+                  expr('int')..errorId = 'SCRUTINEE',
+                  [
+                    (expr('String')..errorId = 'EXPRESSION').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false)
+            ], expectedErrors: {
+              'caseExpressionTypeMismatch(scrutinee: SCRUTINEE, '
+                  'caseExpression: EXPRESSION, scrutineeType: int, '
+                  'caseExpressionType: String, nullSafetyEnabled: true)'
+            });
+          });
+
+          test('dynamic scrutinee', () {
+            h.patternsEnabled = false;
+            h.run([
+              switch_(
+                  expr('dynamic'),
+                  [
+                    expr('int').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+
+          test('dynamic case', () {
+            h.patternsEnabled = false;
+            h.run([
+              switch_(
+                  expr('int')..errorId = 'SCRUTINEE',
+                  [
+                    (expr('dynamic')..errorId = 'EXPRESSION').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false)
+            ], expectedErrors: {
+              'caseExpressionTypeMismatch(scrutinee: SCRUTINEE, '
+                  'caseExpression: EXPRESSION, scrutineeType: int, '
+                  'caseExpressionType: dynamic, nullSafetyEnabled: true)'
+            });
+          });
+        });
+
+        group('Patterns enabled:', () {
+          test('subtype', () {
+            h.run([
+              switch_(
+                  expr('num'),
+                  [
+                    expr('int').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+
+          test('supertype', () {
+            h.run([
+              switch_(
+                  expr('int'),
+                  [
+                    expr('num').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+
+          test('unrelated types', () {
+            h.run([
+              switch_(
+                  expr('int'),
+                  [
+                    expr('String').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+
+          test('dynamic scrutinee', () {
+            h.run([
+              switch_(
+                  expr('dynamic'),
+                  [
+                    expr('int').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+
+          test('dynamic case', () {
+            h.run([
+              switch_(
+                  expr('int'),
+                  [
+                    expr('dynamic').pattern.then([
+                      break_(),
+                    ]),
+                  ],
+                  isExhaustive: false),
+            ]);
+          });
+        });
+      });
+
+      group('Pre-merged', () {
+        // The CFE merges cases that share a body at parse time, so make sure we
+        // we can handle merged cases
+        test('Empty', () {
+          // During CFE error recovery, there can be an empty case.
+          h.run([
+            switch_(
+              expr('int'),
+              [
+                mergedCase([]).then([
+                  break_(),
+                ]),
+              ],
+              isExhaustive: false,
+            ).checkIr('switch(expr(int), case(heads(), block()))'),
+          ], errorRecoveryOk: true);
+        });
+
+        test('Multiple', () {
+          h.run([
+            switch_(
+                    expr('int'),
+                    [
+                      mergedCase([intLiteral(0).pattern, intLiteral(1).pattern])
+                          .then([
+                        break_(),
+                      ]),
+                    ],
+                    isExhaustive: false)
+                .checkIr('switch(expr(int), '
+                    'case(heads(head(const(0, matchedType: int), true), '
+                    'head(const(1, matchedType: int), true)), '
+                    'block(break())))'),
+          ]);
+        });
+      });
+
+      group('Guard not assignable to bool', () {
+        test('int', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                expr('int'),
+                [
+                  x.pattern().when(expr('int')..errorId = 'GUARD').then([
+                    break_(),
+                  ]),
+                ],
+                isExhaustive: false),
+          ], expectedErrors: {
+            'nonBooleanCondition(GUARD)'
+          });
+        });
+
+        test('bool', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                expr('int'),
+                [
+                  x.pattern().when(expr('bool')).then([
+                    break_(),
+                  ]),
+                ],
+                isExhaustive: false),
+          ], expectedErrors: {});
+        });
+
+        test('dynamic', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                expr('int'),
+                [
+                  x.pattern().when(expr('dynamic')).then([
+                    break_(),
+                  ]),
+                ],
+                isExhaustive: false),
+          ], expectedErrors: {});
+        });
+      });
+    });
+
+    group('Variable declaration:', () {
+      test('initialized, typed', () {
+        var x = Var('x');
+        h.run([
+          declare(x, type: 'num', initializer: expr('int').checkContext('num'))
+              .checkIr('match(expr(int), '
+                  'varPattern(x, matchedType: int, staticType: num))'),
+        ]);
+      });
+
+      test('initialized, untyped', () {
+        var x = Var('x');
+        h.run([
+          declare(x, initializer: expr('int').checkContext('?'))
+              .checkIr('match(expr(int), '
+                  'varPattern(x, matchedType: int, staticType: int))'),
+        ]);
+      });
+
+      test('uninitialized, typed', () {
+        var x = Var('x');
+        h.run([
+          declare(x, type: 'int').checkIr(
+              'declare(varPattern(x, matchedType: int, staticType: int))'),
+        ]);
+      });
+
+      test('uninitialized, untyped', () {
+        var x = Var('x');
+        h.run([
+          declare(x).checkIr('declare(varPattern(x, matchedType: dynamic, '
+              'staticType: dynamic))'),
+        ]);
+      });
+
+      test('promoted initializer', () {
+        h.addSubtype('T&int', 'T', true);
+        h.addSubtype('T&int', 'Object', true);
+        h.addFactor('T', 'T&int', 'T');
+        var x = Var('x');
+        h.run([
+          declare(x, initializer: expr('T&int')).checkIr('match(expr(T&int), '
+              'varPattern(x, matchedType: T&int, staticType: T))'),
+        ]);
+      });
+
+      test('legal late pattern', () {
+        var x = Var('x');
+        h.run([
+          match(x.pattern(), intLiteral(0), isLate: true)
+              .checkIr('match_late(0, varPattern(x, matchedType: int, '
+                  'staticType: int))'),
+        ]);
+      });
+
+      test('illegal late pattern', () {
+        h.run([
+          (match(
+              listPattern([wildcard()])..errorId = 'PATTERN', expr('List<int>'),
+              isLate: true)
+            ..errorId = 'CONTEXT'),
+        ], expectedErrors: {
+          'patternDoesNotAllowLate(PATTERN)'
+        });
+      });
+
+      test('illegal refutable pattern', () {
+        h.run([
+          (match(intLiteral(1).pattern..errorId = 'PATTERN', intLiteral(0))
+            ..errorId = 'CONTEXT'),
+        ], expectedErrors: {
+          'refutablePatternInIrrefutableContext(PATTERN, CONTEXT)'
+        });
+      });
+    });
+  });
+
+  group('Patterns:', () {
+    group('Cast:', () {
+      test('Type schema', () {
+        var x = Var('x');
+        h.run([
+          switch_(
+                  expr('num'),
+                  [
+                    x.pattern().as_('int').then([]),
+                  ],
+                  isExhaustive: true)
+              .checkIr('switch(expr(num), '
+                  'case(heads(head(castPattern(varPattern(x, matchedType: int, '
+                  'staticType: int), int, matchedType: num), true)), '
+                  'block()))'),
+        ]);
+      });
+
+      group('Missing var:', () {
+        test('default', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                expr('int'),
+                [
+                  x.pattern().as_('int').then([]),
+                  (default_..errorId = 'DEFAULT').then([]),
+                ],
+                isExhaustive: true),
+          ], expectedErrors: {
+            'missingMatchVar(DEFAULT, x)'
+          });
+        });
+
+        test('case', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                expr('int'),
+                [
+                  (intLiteral(0).pattern..errorId = 'CASE_0').then([]),
+                  x.pattern().as_('int').then([]),
+                ],
+                isExhaustive: true),
+          ], expectedErrors: {
+            'missingMatchVar(CASE_0, x)'
+          });
+        });
+
+        test('label', () {
+          var x = Var('x');
+          var l = Label('l')..errorId = 'LABEL';
+          h.run([
+            switch_(
+                expr('int'),
+                [
+                  l.then(x.pattern().as_('int')).then([]),
+                ],
+                isExhaustive: true),
+          ], expectedErrors: {
+            'missingMatchVar(LABEL, x)'
+          });
+        });
+      });
+
+      test('conflicting var:', () {
+        var x = Var('x');
+        h.run([
+          switch_(
+              expr('num'),
+              [
+                (x.pattern()..errorId = 'INT_PATTERN').as_('int').then([]),
+                (x.pattern()..errorId = 'NUM_PATTERN').as_('num').then([]),
+              ],
+              isExhaustive: true),
+        ], expectedErrors: {
+          'inconsistentMatchVar(pattern: NUM_PATTERN, type: num, '
+              'previousPattern: INT_PATTERN, previousType: int)'
+        });
+      });
+
+      group('Refutability:', () {
+        test('When matched type is a subtype of variable type', () {
+          var x = Var('x');
+          h.run([
+            match(x.pattern().as_('num'), expr('int'))
+                .checkIr('match(expr(int), '
+                    'castPattern(varPattern(x, matchedType: num, '
+                    'staticType: num), num, matchedType: int))'),
+          ]);
+        });
+
+        test('When matched type is dynamic', () {
+          var x = Var('x');
+          h.run([
+            match(x.pattern().as_('num'), expr('dynamic'))
+                .checkIr('match(expr(dynamic), '
+                    'castPattern(varPattern(x, matchedType: num, '
+                    'staticType: num), num, matchedType: dynamic))'),
+          ]);
+        });
+
+        test('When matched type is not a subtype of variable type', () {
+          var x = Var('x');
+          h.run([
+            match(x.pattern().as_('num'), expr('String'))
+                .checkIr('match(expr(String), '
+                    'castPattern(varPattern(x, matchedType: num, '
+                    'staticType: num), num, matchedType: String))'),
+          ]);
+        });
+      });
+    });
+
+    group('Const or literal:', () {
+      test('Refutability', () {
+        h.run([
+          (match(intLiteral(1).pattern..errorId = 'PATTERN', intLiteral(0))
+            ..errorId = 'CONTEXT'),
+        ], expectedErrors: {
+          'refutablePatternInIrrefutableContext(PATTERN, CONTEXT)'
+        });
+      });
+    });
+
+    group('List:', () {
+      group('Type schema:', () {
+        test('Explicit element type', () {
+          var x = Var('x');
+          h.run([
+            match(listPattern([x.pattern()], elementType: 'int'),
+                expr('dynamic').checkContext('List<int>')),
+          ]);
+        });
+
+        group('Implicit element type:', () {
+          test('Empty', () {
+            h.run([
+              match(listPattern([]), expr('dynamic').checkContext('Object?')),
+            ]);
+          });
+
+          test('Non-empty', () {
+            var x = Var('x');
+            var y = Var('y');
+            h.run([
+              match(
+                  listPattern(
+                      [x.pattern(type: 'int?'), y.pattern(type: 'num')]),
+                  expr('dynamic').checkContext('List<int>')),
+            ]);
+          });
+        });
+      });
+
+      group('Static type:', () {
+        test('Explicit type', () {
+          var x = Var('x');
+          h.run([
+            match(listPattern([x.pattern(type: 'num')], elementType: 'int'),
+                    expr('dynamic'))
+                .checkIr('match(expr(dynamic), '
+                    'listPattern(varPattern(x, matchedType: dynamic, '
+                    'staticType: num), '
+                    'matchedType: dynamic, requiredType: List<int>))'),
+          ]);
+        });
+
+        test('Matched type is a list', () {
+          var x = Var('x');
+          h.run([
+            match(listPattern([x.pattern(expectInferredType: 'int')]),
+                    expr('List<int>'))
+                .checkIr('match(expr(List<int>), '
+                    'listPattern(varPattern(x, matchedType: int, '
+                    'staticType: int), matchedType: List<int>, '
+                    'requiredType: List<int>))'),
+          ]);
+        });
+
+        test('Matched type is dynamic', () {
+          var x = Var('x');
+          h.run([
+            match(listPattern([x.pattern(expectInferredType: 'dynamic')]),
+                    expr('dynamic'))
+                .checkIr('match(expr(dynamic), '
+                    'listPattern(varPattern(x, matchedType: dynamic, '
+                    'staticType: dynamic), matchedType: dynamic, '
+                    'requiredType: List<dynamic>))'),
+          ]);
+        });
+
+        test('Matched type is other', () {
+          var x = Var('x');
+          h.run([
+            switch_(
+                    expr('Object'),
+                    [
+                      listPattern([x.pattern(expectInferredType: 'Object?')])
+                          .then([]),
+                    ],
+                    isExhaustive: false)
+                .checkIr('switch(expr(Object), '
+                    'case(heads(head(listPattern(varPattern(x, '
+                    'matchedType: Object?, staticType: Object?), '
+                    'matchedType: Object, requiredType: List<Object?>), '
+                    'true)), block()))'),
+          ]);
+        });
+      });
+
+      group('Refutability:', () {
+        test('When matched type is a subtype of pattern type', () {
+          h.run([
+            match(
+              listPattern([wildcard()], elementType: 'num'),
+              expr('List<int>'),
+            ).checkIr('match(expr(List<int>), '
+                'listPattern(varPattern(_, matchedType: int, staticType: int), '
+                'matchedType: List<int>, requiredType: List<num>))'),
+          ]);
+        });
+
+        test('When matched type is dynamic', () {
+          h.run([
+            match(listPattern([wildcard()], elementType: 'num'),
+                    expr('dynamic'))
+                .checkIr('match(expr(dynamic), '
+                    'listPattern(varPattern(_, matchedType: dynamic, '
+                    'staticType: dynamic), matchedType: dynamic, '
+                    'requiredType: List<num>))'),
+          ]);
+        });
+
+        test('When matched type is not a subtype of variable type', () {
+          h.run([
+            (match(
+                listPattern([wildcard()], elementType: 'num')
+                  ..errorId = 'PATTERN',
+                expr('String'))
+              ..errorId = 'CONTEXT'),
+          ], expectedErrors: {
+            'patternTypeMismatchInIrrefutableContext(pattern: PATTERN, '
+                'context: CONTEXT, matchedType: String, '
+                'requiredType: List<num>)'
+          });
+        });
+
+        test('Sub-refutability', () {
+          h.run([
+            (match(
+                listPattern([
+                  wildcard(type: 'int')..errorId = 'INT',
+                  wildcard(type: 'double')..errorId = 'DOUBLE'
+                ], elementType: 'num'),
+                expr('List<num>'))
+              ..errorId = 'CONTEXT'),
+          ], expectedErrors: {
+            'patternTypeMismatchInIrrefutableContext(pattern: INT, '
+                'context: CONTEXT, matchedType: num, requiredType: int)',
+            'patternTypeMismatchInIrrefutableContext(pattern: DOUBLE, '
+                'context: CONTEXT, matchedType: num, requiredType: double)'
+          });
+        });
+      });
+
+      test('Match var overlap', () {
+        var x = Var('x');
+        h.run([
+          match(
+              listPattern(
+                  [x.pattern()..errorId = 'LHS', x.pattern()..errorId = 'RHS']),
+              expr('List<int>')),
+        ], expectedErrors: {
+          'matchVarOverlap(pattern: RHS, previousPattern: LHS)'
+        });
+      });
+    });
+
+    group('Logical-and:', () {
+      test('Type schema', () {
+        h.run([
+          match(wildcard(type: 'int?').and(wildcard(type: 'double?')),
+                  nullLiteral.checkContext('Null'))
+              .checkIr('match(null, '
+                  'logicalAndPattern(varPattern(_, matchedType: Null, '
+                  'staticType: int?), '
+                  'varPattern(_, matchedType: Null, staticType: double?), '
+                  'matchedType: Null))'),
+        ]);
+      });
+
+      test('Refutability', () {
+        h.run([
+          (match(
+              (wildcard(type: 'int')..errorId = 'LHS')
+                  .and(wildcard(type: 'double')..errorId = 'RHS'),
+              expr('num'))
+            ..errorId = 'CONTEXT'),
+        ], expectedErrors: {
+          'patternTypeMismatchInIrrefutableContext(pattern: LHS, '
+              'context: CONTEXT, matchedType: num, requiredType: int)',
+          'patternTypeMismatchInIrrefutableContext(pattern: RHS, '
+              'context: CONTEXT, matchedType: num, requiredType: double)'
+        });
+      });
+
+      test('Match var overlap', () {
+        var x = Var('x');
+        h.run([
+          match(
+              (x.pattern()..errorId = 'LHS').and(x.pattern()..errorId = 'RHS'),
+              expr('int')),
+        ], expectedErrors: {
+          'matchVarOverlap(pattern: RHS, previousPattern: LHS)'
+        });
+      });
+    });
+
+    group('Logical-or:', () {
+      test('Type schema', () {
+        h.run([
+          (match(
+            wildcard(type: 'int?').or(wildcard(type: 'double?'))
+              ..errorId = 'PATTERN',
+            nullLiteral.checkContext('?'),
+          )..errorId = 'CONTEXT'),
+        ], expectedErrors: {
+          'refutablePatternInIrrefutableContext(PATTERN, CONTEXT)'
+        });
+      });
+
+      test('Refutability', () {
+        // Note: even though the logical-or contains refutable sub-patterns, we
+        // don't issue errors for them because they would overlap with the error
+        // we're issuing for the logical-or pattern as a whole.
+        h.run([
+          (match(
+              wildcard(type: 'int').or(wildcard(type: 'double'))
+                ..errorId = 'PATTERN',
+              expr('num'))
+            ..errorId = 'CONTEXT'),
+        ], expectedErrors: {
+          'refutablePatternInIrrefutableContext(PATTERN, CONTEXT)'
+        });
+      });
+
+      test('Missing var', () {
+        var x = Var('x');
+        h.run([
+          ifCase(expr('int'), x.pattern().or(wildcard()..errorId = 'WILDCARD'),
+              []),
+        ], expectedErrors: {
+          'missingMatchVar(WILDCARD, x)'
+        });
+      });
+
+      group('Conflicting var:', () {
+        test('explicit/explicit type', () {
+          var x = Var('x');
+          h.run([
+            ifCase(
+                expr('int'),
+                (x.pattern(type: 'int')..errorId = 'PATTERN(int x)')
+                    .or(x.pattern(type: 'num')..errorId = 'PATTERN(num x)'),
+                []),
+          ], expectedErrors: {
+            'inconsistentMatchVar(pattern: PATTERN(num x), type: num, '
+                'previousPattern: PATTERN(int x), previousType: int)'
+          });
+        });
+
+        test('explicit/implicit type', () {
+          // TODO(paulberry): not sure whether this should be treated as a
+          // conflict.  See https://github.com/dart-lang/language/issues/2424.
+          var x = Var('x');
+          h.run([
+            ifCase(
+              expr('int'),
+              (x.pattern()..errorId = 'PATTERN(x)')
+                  .or(x.pattern(type: 'int')..errorId = 'PATTERN(int x)'),
+              [],
+            ),
+          ], expectedErrors: {
+            'inconsistentMatchVarExplicitness(pattern: PATTERN(int x), '
+                'previousPattern: PATTERN(x))'
+          });
+        });
+
+        test('implicit/implicit type', () {
+          var x = Var('x');
+          h.run([
+            ifCase(
+              expr('List<int>'),
+              (x.pattern()..errorId = 'PATTERN(List<int> x)')
+                  .or(listPattern([x.pattern()..errorId = 'PATTERN(int x)'])),
+              [],
+            ),
+          ], expectedErrors: {
+            'inconsistentMatchVar(pattern: PATTERN(int x), type: int, '
+                'previousPattern: PATTERN(List<int> x), '
+                'previousType: List<int>)'
+          });
+        });
+
+        group('Error recovery:', () {
+          test('Each type compared to previous', () {
+            var x = Var('x');
+            h.run([
+              ifCase(
+                  expr('int'),
+                  (x.pattern(type: 'int')..errorId = 'PATTERN1')
+                      .or(x.pattern(type: 'num')..errorId = 'PATTERN2')
+                      .or(x.pattern(type: 'num')..errorId = 'PATTERN3')
+                      .or(x.pattern(type: 'int')..errorId = 'PATTERN4'),
+                  []),
+            ], expectedErrors: {
+              'inconsistentMatchVar(pattern: PATTERN2, type: num, '
+                  'previousPattern: PATTERN1, previousType: int)',
+              'inconsistentMatchVar(pattern: PATTERN4, type: int, '
+                  'previousPattern: PATTERN3, previousType: num)'
+            });
+          });
+
+          test('Each type explicitness compared to previous', () {
+            var x = Var('x');
+            h.run([
+              ifCase(
+                  expr('int'),
+                  (x.pattern(type: 'int')..errorId = 'PATTERN1')
+                      .or(x.pattern()..errorId = 'PATTERN2')
+                      .or(x.pattern()..errorId = 'PATTERN3')
+                      .or(x.pattern(type: 'int')..errorId = 'PATTERN4'),
+                  []),
+            ], expectedErrors: {
+              'inconsistentMatchVarExplicitness(pattern: PATTERN2, '
+                  'previousPattern: PATTERN1)',
+              'inconsistentMatchVarExplicitness(pattern: PATTERN4, '
+                  'previousPattern: PATTERN3)'
+            });
+          });
+        });
+      });
+    });
+
+    group('Null-assert:', () {
+      test('Type schema', () {
+        var x = Var('x');
+        h.run([
+          match(x.pattern(type: 'int').nullAssert,
+                  expr('int').checkContext('int?'))
+              .checkIr('match(expr(int), '
+                  'nullAssertPattern(varPattern(x, matchedType: int, '
+                  'staticType: int), matchedType: int))'),
+        ]);
+      });
+
+      group('Refutability:', () {
+        test('When matched type is nullable', () {
+          h.run([
+            match(wildcard().nullAssert, expr('int?'))
+                .checkIr('match(expr(int?), '
+                    'nullAssertPattern(varPattern(_, matchedType: int, '
+                    'staticType: int), matchedType: int?))'),
+          ]);
+        });
+
+        test('When matched type is non-nullable', () {
+          h.run([
+            match(wildcard().nullAssert, expr('int'))
+                .checkIr('match(expr(int), '
+                    'nullAssertPattern(varPattern(_, matchedType: int, '
+                    'staticType: int), matchedType: int))'),
+          ]);
+        });
+
+        test('When matched type is dynamic', () {
+          h.run([
+            match(wildcard().nullAssert, expr('dynamic'))
+                .checkIr('match(expr(dynamic), '
+                    'nullAssertPattern(varPattern(_, matchedType: dynamic, '
+                    'staticType: dynamic), matchedType: dynamic))'),
+          ]);
+        });
+
+        test('Sub-refutability', () {
+          h.run([
+            (match((wildcard(type: 'int')..errorId = 'INT').nullAssert,
+                expr('num'))
+              ..errorId = 'CONTEXT'),
+          ], expectedErrors: {
+            'patternTypeMismatchInIrrefutableContext(pattern: INT, '
+                'context: CONTEXT, matchedType: num, requiredType: int)'
+          });
+        });
+      });
+    });
+
+    group('Null-check:', () {
+      test('Type schema', () {
+        var x = Var('x');
+        h.run([
+          (match(x.pattern(type: 'int').nullCheck..errorId = 'PATTERN',
+              expr('int').checkContext('?'))
+            ..errorId = 'CONTEXT'),
+        ], expectedErrors: {
+          'refutablePatternInIrrefutableContext(PATTERN, CONTEXT)'
+        });
+      });
+
+      group('Refutability:', () {
+        test('When matched type is nullable', () {
+          h.run([
+            (match(wildcard().nullCheck..errorId = 'PATTERN', expr('int?'))
+              ..errorId = 'CONTEXT'),
+          ], expectedErrors: {
+            'refutablePatternInIrrefutableContext(PATTERN, CONTEXT)'
+          });
+        });
+
+        test('When matched type is non-nullable', () {
+          h.run([
+            (match(wildcard().nullCheck..errorId = 'PATTERN', expr('int'))
+              ..errorId = 'CONTEXT'),
+          ], expectedErrors: {
+            'refutablePatternInIrrefutableContext(PATTERN, CONTEXT)'
+          });
+        });
+
+        test('When matched type is dynamic', () {
+          h.run([
+            (match(wildcard().nullCheck..errorId = 'PATTERN', expr('dynamic'))
+              ..errorId = 'CONTEXT'),
+          ], expectedErrors: {
+            'refutablePatternInIrrefutableContext(PATTERN, CONTEXT)'
+          });
+        });
+
+        test('Sub-refutability', () {
+          h.run([
+            (match(wildcard(type: 'int').nullCheck..errorId = 'PATTERN',
+                expr('num'))
+              ..errorId = 'CONTEXT'),
+          ], expectedErrors: {
+            'refutablePatternInIrrefutableContext(PATTERN, CONTEXT)'
+          });
+        });
+      });
+    });
+
+    group('Variable:', () {
+      group('Refutability:', () {
+        test('When matched type is a subtype of variable type', () {
+          var x = Var('x');
+          h.run([
+            match(x.pattern(type: 'num'), expr('int'))
+                .checkIr('match(expr(int), '
+                    'varPattern(x, matchedType: int, staticType: num))'),
+          ]);
+        });
+
+        test('When matched type is dynamic', () {
+          var x = Var('x');
+          h.run([
+            match(x.pattern(type: 'num'), expr('dynamic'))
+                .checkIr('match(expr(dynamic), '
+                    'varPattern(x, matchedType: dynamic, staticType: num))'),
+          ]);
+        });
+
+        test('When matched type is not a subtype of variable type', () {
+          var x = Var('x');
+          h.run([
+            (match(x.pattern(type: 'num')..errorId = 'PATTERN', expr('String'))
+              ..errorId = 'CONTEXT'),
+          ], expectedErrors: {
+            'patternTypeMismatchInIrrefutableContext(pattern: PATTERN, '
+                'context: CONTEXT, matchedType: String, requiredType: num)'
+          });
+        });
+      });
+    });
+
+    group('Wildcard:', () {
+      test('Untyped', () {
+        h.run([
+          switch_(
+                  expr('int'),
+                  [
+                    wildcard().then([]),
+                  ],
+                  isExhaustive: true)
+              .checkIr('switch(expr(int), '
+                  'case(heads(head(varPattern(_, matchedType: int, '
+                  'staticType: int), true)), block()))'),
+        ]);
+      });
+
+      test('Typed', () {
+        h.run([
+          switch_(
+                  expr('num'),
+                  [
+                    wildcard(type: 'int').then([]),
+                  ],
+                  isExhaustive: true)
+              .checkIr('switch(expr(num), '
+                  'case(heads(head(varPattern(_, matchedType: num, '
+                  'staticType: int), true)), block()))'),
+        ]);
+      });
+
+      group('Exempt from errors:', () {
+        group('Missing var:', () {
+          test('default', () {
+            h.run([
+              switch_(
+                      expr('int'),
+                      [
+                        wildcard().then([]),
+                        default_.then([]),
+                      ],
+                      isExhaustive: true)
+                  .checkIr('switch(expr(int), '
+                      'case(heads(head(varPattern(_, matchedType: int, '
+                      'staticType: int), true), default), '
+                      'block()))'),
+            ]);
+          });
+
+          test('case', () {
+            h.run([
+              switch_(
+                      expr('int'),
+                      [
+                        intLiteral(0).pattern.then([]),
+                        wildcard().then([]),
+                      ],
+                      isExhaustive: true)
+                  .checkIr('switch(expr(int), '
+                      'case(heads(head(const(0, matchedType: int), true), '
+                      'head(varPattern(_, matchedType: int, '
+                      'staticType: int), true)), block()))'),
+            ]);
+          });
+
+          test('label', () {
+            var l = Label('l');
+            h.run([
+              switch_(
+                      expr('int'),
+                      [
+                        l.then(wildcard()).then([]),
+                      ],
+                      isExhaustive: true)
+                  .checkIr('switch(expr(int), '
+                      'case(heads(head(varPattern(_, matchedType: int, '
+                      'staticType: int), true), l), '
+                      'block()))'),
+            ]);
+          });
+        });
+
+        group('conflicting var:', () {
+          test('explicit/explicit type', () {
+            h.run([
+              switch_(
+                      expr('num'),
+                      [
+                        wildcard(type: 'int').then([]),
+                        wildcard(type: 'num').then([]),
+                      ],
+                      isExhaustive: true)
+                  .checkIr('switch(expr(num), '
+                      'case(heads(head(varPattern(_, matchedType: num, '
+                      'staticType: int), true), '
+                      'head(varPattern(_, matchedType: num, '
+                      'staticType: num), true)), block()))'),
+            ]);
+          });
+
+          test('explicit/implicit type', () {
+            h.run([
+              switch_(
+                      expr('int'),
+                      [
+                        wildcard().then([]),
+                        wildcard(type: 'int').then([]),
+                      ],
+                      isExhaustive: true)
+                  .checkIr('switch(expr(int), '
+                      'case(heads(head(varPattern(_, matchedType: int, '
+                      'staticType: int), true), '
+                      'head(varPattern(_, matchedType: int, '
+                      'staticType: int), true)), block()))'),
+            ]);
+          });
+
+          test('implicit/implicit type', () {
+            h.run([
+              switch_(
+                      expr('List<int>'),
+                      [
+                        wildcard().then([]),
+                        listPattern([wildcard()]).then([]),
+                      ],
+                      isExhaustive: true)
+                  .checkIr('switch(expr(List<int>), '
+                      'case(heads(head(varPattern(_, matchedType: List<int>, '
+                      'staticType: List<int>), true), '
+                      'head(listPattern(varPattern(_, matchedType: int, '
+                      'staticType: int), matchedType: List<int>, '
+                      'requiredType: List<int>), true)), block()))'),
+            ]);
+          });
+        });
+      });
+
+      group('Refutability:', () {
+        test('When matched type is a subtype of variable type', () {
+          h.run([
+            match(wildcard(type: 'num'), expr('int'))
+                .checkIr('match(expr(int), '
+                    'varPattern(_, matchedType: int, staticType: num))'),
+          ]);
+        });
+
+        test('When matched type is dynamic', () {
+          h.run([
+            match(wildcard(type: 'num'), expr('dynamic'))
+                .checkIr('match(expr(dynamic), '
+                    'varPattern(_, matchedType: dynamic, staticType: num))'),
+          ]);
+        });
+
+        test('When matched type is not a subtype of variable type', () {
+          h.run([
+            (match(wildcard(type: 'num')..errorId = 'PATTERN', expr('String'))
+              ..errorId = 'CONTEXT'),
+          ], expectedErrors: {
+            'patternTypeMismatchInIrrefutableContext(pattern: PATTERN, '
+                'context: CONTEXT, matchedType: String, requiredType: num)'
+          });
+        });
+      });
+    });
   });
 }
diff --git a/pkg/_fe_analyzer_shared/test/type_inference/variable_bindings_test.dart b/pkg/_fe_analyzer_shared/test/type_inference/variable_bindings_test.dart
new file mode 100644
index 0000000..3838ac0
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/type_inference/variable_bindings_test.dart
@@ -0,0 +1,205 @@
+// Copyright (c) 2022, 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/type_inference/variable_bindings.dart';
+import 'package:test/test.dart';
+
+main() {
+  late _Harness h;
+
+  setUp(() {
+    h = _Harness();
+  });
+
+  test('Variable overlap', () {
+    h.run(_And([_VarPattern('x')..id = 1, _VarPattern('x')..id = 2]),
+        expectErrors: [
+          'matchVarOverlap(pattern: 2: x, previousPattern: 1: x)'
+        ]);
+  });
+
+  group('Alternative:', () {
+    test('Consistent', () {
+      h.run(_Or([
+        _VarPattern('x', expectNew: true),
+        _VarPattern('x', expectNew: false)
+      ]));
+    });
+
+    test('Does not bind unmentioned variables', () {
+      // Even though the variable 'y' has already been seen at the time the
+      // nested `_Or` is visited, it's important that the nested `_Or` not be
+      // construed to bind the variable 'y'.  Otherwise the variable pattern for
+      // `y` that follows would be incorrectly considered an error.
+      h.run(_Or([
+        _And([_VarPattern('x'), _VarPattern('y')]),
+        _And([
+          _Or([_VarPattern('x'), _VarPattern('x')]),
+          _VarPattern('y')
+        ])
+      ]));
+    });
+
+    group('Missing var:', () {
+      test('On left', () {
+        h.run(_Or([_Empty(), _VarPattern('x')]),
+            expectErrors: ['missingMatchVar((), x)']);
+      });
+
+      test('On right', () {
+        h.run(_Or([_VarPattern('x'), _Empty()]),
+            expectErrors: ['missingMatchVar((), x)']);
+      });
+
+      test('Middle of three', () {
+        h.run(_Or([_VarPattern('x'), _Empty(), _VarPattern('x')]),
+            expectErrors: ['missingMatchVar((), x)']);
+      });
+    });
+  });
+
+  group('Recovery:', () {
+    test('Overlap after missing', () {
+      h.run(
+          _And([
+            _Or([_VarPattern('x')..id = 1, _Empty()]),
+            _VarPattern('x')..id = 2
+          ]),
+          expectErrors: [
+            'missingMatchVar((), x)',
+            'matchVarOverlap(pattern: 2: x, previousPattern: 1: x)'
+          ]);
+    });
+
+    test('Missing after overlap after missing', () {
+      h.run(
+          _Or([
+            _And([
+              _Or([_VarPattern('x')..id = 1, _Empty()..id = 2]),
+              _VarPattern('x')..id = 3
+            ]),
+            _Empty()..id = 4
+          ]),
+          expectErrors: [
+            'missingMatchVar(2: (), x)',
+            'matchVarOverlap(pattern: 3: x, previousPattern: 1: x)',
+            'missingMatchVar(4: (), x)'
+          ]);
+    });
+  });
+}
+
+class _And extends _Node {
+  final List<_Node> _nodes;
+
+  _And(this._nodes);
+
+  @override
+  String _toDebugString() => '(${_nodes.join(' & ')})';
+
+  @override
+  void _visit(_Harness h) {
+    for (var node in _nodes) {
+      node._visit(h);
+    }
+  }
+}
+
+class _Empty extends _Node {
+  @override
+  String _toDebugString() => '()';
+
+  @override
+  void _visit(_Harness h) {}
+}
+
+class _Errors implements VariableBinderErrors<_Node, Never> {
+  final List<String> _errors = [];
+
+  @override
+  void matchVarOverlap(
+      {required _Node pattern, required _Node previousPattern}) {
+    _errors.add('matchVarOverlap(pattern: $pattern, '
+        'previousPattern: $previousPattern)');
+  }
+
+  @override
+  void missingMatchVar(_Node alternative, String variable) {
+    _errors.add('missingMatchVar($alternative, $variable)');
+  }
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) {
+    throw 'Unexpected error ${invocation.memberName}';
+  }
+}
+
+class _Harness implements VariableBindingCallbacks<_Node, String, String> {
+  late final _binder = VariableBinder<_Node, String, String>(this);
+
+  @override
+  final _Errors errors = _Errors();
+
+  void run(_Node node, {List<String> expectErrors = const []}) {
+    node._visit(this);
+    expect(errors._errors, expectErrors);
+  }
+}
+
+abstract class _Node {
+  int? id;
+
+  @override
+  String toString() {
+    var debugString = _toDebugString();
+    if (id != null) {
+      return '$id: $debugString';
+    } else {
+      return debugString;
+    }
+  }
+
+  String _toDebugString();
+
+  void _visit(_Harness h);
+}
+
+class _Or extends _Node {
+  final List<_Node> _alternatives;
+
+  _Or(this._alternatives);
+
+  @override
+  String _toDebugString() => '(${_alternatives.join(' | ')})';
+
+  @override
+  void _visit(_Harness h) {
+    h._binder.startAlternatives();
+    for (var node in _alternatives) {
+      h._binder.startAlternative(node);
+      node._visit(h);
+      h._binder.finishAlternative();
+    }
+    h._binder.finishAlternatives();
+  }
+}
+
+class _VarPattern extends _Node {
+  final String variable;
+  final bool? expectNew;
+
+  _VarPattern(this.variable, {this.expectNew});
+
+  @override
+  String _toDebugString() =>
+      [variable, if (expectNew != null) '(expectNew: $expectNew)'].join(' ');
+
+  @override
+  void _visit(_Harness h) {
+    var isNew = h._binder.add(this, variable);
+    if (expectNew != null) {
+      expect(isNew, expectNew);
+    }
+  }
+}
diff --git a/pkg/_js_interop_checks/lib/js_interop_checks.dart b/pkg/_js_interop_checks/lib/js_interop_checks.dart
index b9a73eb..1205cfb 100644
--- a/pkg/_js_interop_checks/lib/js_interop_checks.dart
+++ b/pkg/_js_interop_checks/lib/js_interop_checks.dart
@@ -448,7 +448,7 @@
     return _checkExtensionMember(member, _nativeClasses.containsValue);
   }
 
-  /// Returns whether given extension [member] is on a class that passses the
+  /// Returns whether given extension [member] is on a class that passes the
   /// given [validateExtensionClass].
   bool _checkExtensionMember(Member member, Function validateExtensionClass) {
     assert(member.isExtensionMember);
diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart
index 07fa54f..b7287a5 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_wasm_optimizer.dart
@@ -51,13 +51,15 @@
   final Procedure _newObjectTarget;
   final Procedure _wrapDartFunctionTarget;
   final Procedure _allowInteropTarget;
-  final Class _wasmAnyRefClass;
+  final Procedure _numToInt;
+  final Class _wasmExternRefClass;
   final Class _objectClass;
   final Class _pragmaClass;
   final Field _pragmaName;
   final Field _pragmaOptions;
   final Member _globalThisMember;
   int _functionTrampolineN = 1;
+  late Library _library;
 
   final CoreTypes _coreTypes;
   final StatefulStaticTypeContext _staticTypeContext;
@@ -83,7 +85,12 @@
             _coreTypes.index.getTopLevelProcedure('dart:js_util', 'newObject'),
         _allowInteropTarget =
             _coreTypes.index.getTopLevelProcedure('dart:js', 'allowInterop'),
-        _wasmAnyRefClass = _coreTypes.index.getClass('dart:wasm', 'WasmAnyRef'),
+        _wasmExternRefClass =
+            _coreTypes.index.getClass('dart:wasm', 'WasmExternRef'),
+        _numToInt = _coreTypes.index
+            .getClass('dart:core', 'num')
+            .procedures
+            .firstWhere((p) => p.name.text == 'toInt'),
         _objectClass = _coreTypes.objectClass,
         _pragmaClass = _coreTypes.pragmaClass,
         _pragmaName = _coreTypes.pragmaName,
@@ -93,6 +100,7 @@
 
   @override
   Library visitLibrary(Library lib) {
+    _library = lib;
     _staticTypeContext.enterLibrary(lib);
     lib.transformChildren(this);
     _staticTypeContext.leaveLibrary(lib);
@@ -131,10 +139,9 @@
           if (hasAnonymousAnnotation(cls)) {
             transformedBody = _getExternalAnonymousConstructorBody(node);
           } else {
-            String jsName = getJSName(cls);
-            String constructorName = jsName == '' ? cls.name : jsName;
-            transformedBody =
-                _getExternalCallConstructorBody(node, constructorName);
+            _JSMemberSelector selector = _processJSName(cls, cls.name, node);
+            transformedBody = _getExternalCallConstructorBody(
+                node, selector.target, selector.member);
           }
         }
       } else if (node.isExtensionMember) {
@@ -153,23 +160,9 @@
           }
         }
       } else if (hasJSInteropAnnotation(node)) {
-        String selectorString = getJSName(node);
-        late Expression target;
-        late String name;
-        if (selectorString.isEmpty) {
-          target = _globalThis;
-          name = node.name.text;
-        } else {
-          List<String> selectors = selectorString.split('.');
-          if (selectors.length == 1) {
-            target = _globalThis;
-            name = selectors.single;
-          } else {
-            target = getObjectOffGlobalThis(
-                node, selectors.sublist(0, selectors.length - 1));
-            name = selectors.last;
-          }
-        }
+        _JSMemberSelector selector = _processJSName(node, node.name.text, node);
+        Expression target = selector.target;
+        String name = selector.member;
         if (node.isGetter) {
           transformedBody = _getExternalGetterBody(node, target, name);
         } else if (node.isSetter) {
@@ -192,6 +185,28 @@
     return node;
   }
 
+  _JSMemberSelector _processJSName(
+      Annotatable a, String nameOnEmpty, Procedure node) {
+    String selectorString = getJSName(a);
+    Expression target;
+    String name;
+    if (selectorString.isEmpty) {
+      target = _globalThis;
+      name = nameOnEmpty;
+    } else {
+      List<String> selectors = selectorString.split('.');
+      if (selectors.length == 1) {
+        target = _globalThis;
+        name = selectors.single;
+      } else {
+        target = getObjectOffGlobalThis(
+            node, selectors.sublist(0, selectors.length - 1));
+        name = selectors.last;
+      }
+    }
+    return _JSMemberSelector(target, name);
+  }
+
   /// Returns and initializes `_extensionMemberIndex` to an index of the member
   /// reference to the member `ExtensionMemberDescriptor`, for all extension
   /// members in the given [library] of classes annotated with
@@ -225,9 +240,9 @@
   /// [String] function name representing the name of the wrapping function.
   /// TODO(joshualitt): Share callback trampolines if the [FunctionType]
   /// matches.
-  String _createFunctionTrampoline(Procedure node, FunctionType function) {
+  String _createFunctionTrampoline(
+      Procedure node, FunctionType function, Expression argument) {
     int fileOffset = node.fileOffset;
-    Library library = node.enclosingLibrary;
 
     // Create arguments for each positional parameter in the function. These
     // arguments will be converted in JS to Dart objects. The generated wrapper
@@ -243,24 +258,67 @@
     List<Expression> callbackArguments = [];
     DartType nullableObjectType =
         _objectClass.getThisType(_coreTypes, Nullability.nullable);
-    for (DartType type in function.positionalParameters) {
+    for (int i = 0; i < function.positionalParameters.length; i++) {
+      DartType type = function.positionalParameters[i];
+      Expression? defaultExpression;
+      bool hasDefault = i >= function.requiredParameterCount;
+      if (hasDefault) {
+        // We can only generate default values if we have a statically typed
+        // function argument.
+        Expression? initializer;
+        if (argument is ConstantExpression) {
+          Procedure callbackTarget = (argument.constant as TearOffConstant)
+              .targetReference
+              .asProcedure;
+          initializer =
+              callbackTarget.function.positionalParameters[i].initializer;
+        } else if (argument is FunctionExpression) {
+          initializer = argument.function.positionalParameters[i].initializer;
+        } else if (argument is InstanceTearOff) {
+          initializer = argument.interfaceTargetReference.asProcedure.function
+              .positionalParameters[i].initializer;
+        } else {
+          throw 'Cannot pass default arguments.';
+        }
+
+        // The initializer for a default argument must be a
+        // [ConstantExpression].
+        ConstantExpression init = initializer as ConstantExpression;
+        defaultExpression = ConstantExpression(init.constant, init.type);
+      }
       VariableDeclaration variable =
           VariableDeclaration('x${parameterId++}', type: nullableObjectType);
       positionalParameters.add(variable);
-      callbackArguments.add(AsExpression(VariableGet(variable), type));
+      Expression body;
+      if (hasDefault) {
+        body = ConditionalExpression(
+            StaticInvocation(
+                _coreTypes.identicalProcedure,
+                Arguments([
+                  VariableGet(variable),
+                  ConstantExpression(NullConstant())
+                ])),
+            defaultExpression ?? ConstantExpression(NullConstant()),
+            VariableGet(variable),
+            nullableObjectType);
+      } else {
+        body = VariableGet(variable);
+      }
+      callbackArguments.add(AsExpression(body, type));
     }
 
     // Create a new procedure for the callback trampoline. This procedure will
     // be exported from Wasm to JS so it can be called from JS. The argument
     // returned from the supplied callback will be converted with `jsifyRaw` to
     // a native JS value before being returned to JS.
-    DartType nullableWasmAnyRefType =
-        _wasmAnyRefClass.getThisType(_coreTypes, Nullability.nullable);
+    DartType nullableWasmExternRefType =
+        _wasmExternRefClass.getThisType(_coreTypes, Nullability.nullable);
+    final String libraryName = _library.name ?? 'Unnamed';
     final functionTrampolineName =
-        '|_functionTrampoline${_functionTrampolineN++}';
+        '|_functionTrampoline${_functionTrampolineN++}For$libraryName';
     final functionTrampolineImportName = '\$$functionTrampolineName';
     final functionTrampoline = Procedure(
-        Name(functionTrampolineName, library),
+        Name(functionTrampolineName, _library),
         ProcedureKind.Method,
         FunctionNode(
             ReturnStatement(StaticInvocation(
@@ -273,7 +331,7 @@
                       functionType: function),
                 ]))),
             positionalParameters: positionalParameters,
-            returnType: nullableWasmAnyRefType)
+            returnType: nullableWasmExternRefType)
           ..fileOffset = fileOffset,
         isStatic: true,
         fileUri: node.fileUri)
@@ -285,7 +343,7 @@
       _pragmaOptions.fieldReference:
           StringConstant(functionTrampolineImportName)
     })));
-    library.addProcedure(functionTrampoline);
+    _library.addProcedure(functionTrampoline);
     return functionTrampolineImportName;
   }
 
@@ -293,11 +351,17 @@
   /// [_createFunctionTrampoline] followed by `_wrapDartFunction`.
   StaticInvocation _allowInterop(
       Procedure node, FunctionType type, Expression argument) {
-    String functionTrampolineName = _createFunctionTrampoline(node, type);
+    String functionTrampolineName =
+        _createFunctionTrampoline(node, type, argument);
     return StaticInvocation(
         _wrapDartFunctionTarget,
-        Arguments([argument, StringLiteral(functionTrampolineName)],
-            types: [type]));
+        Arguments([
+          argument,
+          StringLiteral(functionTrampolineName),
+          ConstantExpression(IntConstant(type.positionalParameters.length))
+        ], types: [
+          type
+        ]));
   }
 
   StaticGet get _globalThis => StaticGet(_globalThisMember);
@@ -340,12 +404,12 @@
   /// The new function body will call `js_util.callConstructor`
   /// for the given external method.
   ReturnStatement _getExternalCallConstructorBody(
-      Procedure node, String constructorName) {
+      Procedure node, Expression target, String constructorName) {
     var function = node.function;
     var callConstructorInvocation = StaticInvocation(
         _callConstructorTarget,
         Arguments([
-          _getProperty(node, _globalThis, constructorName),
+          _getProperty(node, target, constructorName),
           ListLiteral(
               function.positionalParameters
                   .map<Expression>((value) => VariableGet(value))
@@ -358,17 +422,59 @@
     return ReturnStatement(callConstructorInvocation);
   }
 
+  // Handles any necessary return type conversions. Today this is just for
+  // handling the case where a user wants us to coerce a JS number to an int
+  // instead of a double.
+  Expression _convertReturnType(DartType type, Expression expression) {
+    if (type == _coreTypes.intNullableRawType ||
+        type == _coreTypes.intNonNullableRawType) {
+      VariableDeclaration v =
+          VariableDeclaration('#var', initializer: expression);
+      return Let(
+          v,
+          ConditionalExpression(
+              StaticInvocation(
+                  _coreTypes.identicalProcedure,
+                  Arguments(
+                      [VariableGet(v), ConstantExpression(NullConstant())])),
+              ConstantExpression(NullConstant()),
+              InstanceInvocation(InstanceAccessKind.Instance, VariableGet(v),
+                  _numToInt.name, Arguments([]),
+                  interfaceTarget: _numToInt,
+                  functionType: _numToInt.function
+                      .computeFunctionType(Nullability.nonNullable)),
+              type));
+    } else {
+      return expression;
+    }
+  }
+
+  Expression _callAndConvertReturn(
+      DartType returnType, Expression generateCall(DartType type)) {
+    // Because we simply don't have enough information, we leave all JS numbers
+    // as doubles. However, in cases where we know the user expects an `int` we
+    // insert a cast.
+    DartType typeArgumentOverride = returnType == _coreTypes.intNullableRawType
+        ? _coreTypes.doubleNullableRawType
+        : returnType == _coreTypes.intNonNullableRawType
+            ? _coreTypes.doubleNonNullableRawType
+            : returnType;
+    return _convertReturnType(returnType, generateCall(typeArgumentOverride));
+  }
+
   /// Returns a new [Expression] for the given [node] external getter.
   ///
   /// The new [Expression] is equivalent to:
   /// `js_util.getProperty([object], [getterName])`.
   Expression _getProperty(Procedure node, Expression object, String getterName,
           {DartType? typeArgument}) =>
-      StaticInvocation(
-          _getPropertyTarget,
-          Arguments([object, StringLiteral(getterName)],
-              types: [typeArgument ?? node.function.returnType]))
-        ..fileOffset = node.fileOffset;
+      _callAndConvertReturn(
+          typeArgument ?? node.function.returnType,
+          (DartType typeArgumentOverride) => StaticInvocation(
+              _getPropertyTarget,
+              Arguments([object, StringLiteral(getterName)],
+                  types: [typeArgumentOverride]))
+            ..fileOffset = node.fileOffset);
 
   /// Returns a new function body for the given [node] external getter.
   ReturnStatement _getExternalGetterBody(
@@ -410,21 +516,23 @@
   /// The new function body is equivalent to:
   /// `js_util.callMethod([object], [methodName], [values])`.
   ReturnStatement _getExternalMethodBody(Procedure node, Expression object,
-      String methodName, List<VariableDeclaration> values) {
-    final callMethodInvocation = StaticInvocation(
-        _callMethodTarget,
-        Arguments([
-          object,
-          StringLiteral(methodName),
-          ListLiteral(
-              values.map<Expression>((value) => VariableGet(value)).toList(),
-              typeArgument: _nullableObjectType)
-        ], types: [
-          node.function.returnType
-        ]))
-      ..fileOffset = node.fileOffset;
-    return ReturnStatement(callMethodInvocation);
-  }
+          String methodName, List<VariableDeclaration> values) =>
+      ReturnStatement(_callAndConvertReturn(
+          node.function.returnType,
+          (DartType typeArgumentOverride) => StaticInvocation(
+              _callMethodTarget,
+              Arguments([
+                object,
+                StringLiteral(methodName),
+                ListLiteral(
+                    values
+                        .map<Expression>((value) => VariableGet(value))
+                        .toList(),
+                    typeArgument: _nullableObjectType)
+              ], types: [
+                typeArgumentOverride,
+              ]))
+            ..fileOffset = node.fileOffset));
 
   ReturnStatement _getExternalExtensionMethodBody(Procedure node) {
     final parameters = node.function.positionalParameters;
@@ -446,3 +554,10 @@
     return _extensionMemberIndex![node.reference]!.name.text;
   }
 }
+
+class _JSMemberSelector {
+  final Expression target;
+  final String member;
+
+  _JSMemberSelector(this.target, this.member);
+}
diff --git a/pkg/_js_interop_checks/lib/src/transformations/static_interop_mock_creator.dart b/pkg/_js_interop_checks/lib/src/transformations/static_interop_mock_creator.dart
new file mode 100644
index 0000000..d88e799
--- /dev/null
+++ b/pkg/_js_interop_checks/lib/src/transformations/static_interop_mock_creator.dart
@@ -0,0 +1,677 @@
+// Copyright (c) 2022, 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:front_end/src/fasta/fasta_codes.dart'
+    show
+        templateJsInteropStaticInteropMockMemberNotSubtype,
+        templateJsInteropStaticInteropMockNotDartInterfaceType,
+        templateJsInteropStaticInteropMockNotStaticInteropType;
+import 'package:kernel/ast.dart';
+import 'package:kernel/target/targets.dart';
+import 'package:kernel/type_environment.dart';
+import 'package:_fe_analyzer_shared/src/messages/codes.dart'
+    show
+        Message,
+        LocatedMessage,
+        templateJsInteropStaticInteropMockMissingOverride,
+        templateJsInteropStaticInteropMockExternalExtensionMemberConflict;
+import 'package:_js_interop_checks/src/js_interop.dart' as js_interop;
+
+class _ExtensionVisitor extends RecursiveVisitor {
+  final Map<Reference, Extension> staticInteropClassesWithExtensions;
+
+  _ExtensionVisitor(this.staticInteropClassesWithExtensions);
+
+  @override
+  void visitExtension(Extension extension) {
+    // TODO(srujzs): This code was written with the assumption there would be
+    // one single extension per `@staticInterop` class. This is no longer true
+    // and this code needs to be refactored to handle multiple extensions.
+    var onType = extension.onType;
+    if (onType is InterfaceType &&
+        js_interop.hasStaticInteropAnnotation(onType.classNode)) {
+      if (!staticInteropClassesWithExtensions.containsKey(onType.className)) {
+        staticInteropClassesWithExtensions[onType.className] = extension;
+      }
+    }
+    super.visitExtension(extension);
+  }
+}
+
+class StaticInteropMockCreator extends Transformer {
+  final Procedure _allowInterop;
+  final Procedure _callMethod;
+  final Procedure _createStaticInteropMock;
+  final DiagnosticReporter<Message, LocatedMessage> _diagnosticReporter;
+  late final _ExtensionVisitor _extensionVisitor;
+  final InterfaceType _functionType;
+  final Procedure _getProperty;
+  final Procedure _globalThis;
+  final InterfaceType _objectType;
+  final Procedure _setProperty;
+  final Map<Reference, Extension> _staticInteropClassesWithExtensions = {};
+  final TypeEnvironment _typeEnvironment;
+
+  StaticInteropMockCreator(this._typeEnvironment, this._diagnosticReporter)
+      : _allowInterop = _typeEnvironment.coreTypes.index
+            .getTopLevelProcedure('dart:js', 'allowInterop'),
+        _callMethod = _typeEnvironment.coreTypes.index
+            .getTopLevelProcedure('dart:js_util', 'callMethod'),
+        _createStaticInteropMock = _typeEnvironment.coreTypes.index
+            .getTopLevelProcedure('dart:js_util', 'createStaticInteropMock'),
+        _functionType = _typeEnvironment.coreTypes.functionNonNullableRawType,
+        _getProperty = _typeEnvironment.coreTypes.index
+            .getTopLevelProcedure('dart:js_util', 'getProperty'),
+        _globalThis = _typeEnvironment.coreTypes.index
+            .getTopLevelProcedure('dart:js_util', 'get:globalThis'),
+        _objectType = _typeEnvironment.coreTypes.objectNonNullableRawType,
+        _setProperty = _typeEnvironment.coreTypes.index
+            .getTopLevelProcedure('dart:js_util', 'setProperty') {
+    _extensionVisitor = _ExtensionVisitor(_staticInteropClassesWithExtensions);
+  }
+
+  void processExtensions(Library library) =>
+      _extensionVisitor.visitLibrary(library);
+
+  @override
+  TreeNode visitStaticInvocation(StaticInvocation node) {
+    if (node.target != _createStaticInteropMock) return node;
+    var typeArguments = node.arguments.types;
+    assert(typeArguments.length == 2);
+    var staticInteropType = typeArguments[0];
+    var dartType = typeArguments[1];
+    var typeArgumentsError = false;
+    if (staticInteropType is! InterfaceType ||
+        staticInteropType.declaredNullability != Nullability.nonNullable ||
+        !js_interop.hasStaticInteropAnnotation(staticInteropType.classNode)) {
+      _diagnosticReporter.report(
+          templateJsInteropStaticInteropMockNotStaticInteropType.withArguments(
+              staticInteropType, true),
+          node.fileOffset,
+          node.name.text.length,
+          node.location?.file);
+      typeArgumentsError = true;
+    }
+    if (dartType is! InterfaceType ||
+        dartType.declaredNullability != Nullability.nonNullable ||
+        js_interop.hasJSInteropAnnotation(dartType.classNode) ||
+        js_interop.hasStaticInteropAnnotation(dartType.classNode) ||
+        js_interop.hasAnonymousAnnotation(dartType.classNode)) {
+      _diagnosticReporter.report(
+          templateJsInteropStaticInteropMockNotDartInterfaceType.withArguments(
+              dartType, true),
+          node.fileOffset,
+          node.name.text.length,
+          node.location?.file);
+      typeArgumentsError = true;
+    }
+    // Can't proceed with these errors.
+    if (typeArgumentsError) return node;
+
+    var staticInteropClass = (staticInteropType as InterfaceType).classNode;
+    var dartClass = (dartType as InterfaceType).classNode;
+
+    var dartMemberMap = <String, Member>{};
+    for (var procedure in dartClass.allInstanceProcedures) {
+      // We only care about concrete instance getters, setters, and methods.
+      if (procedure.isAbstract ||
+          procedure.isStatic ||
+          procedure.isExtensionMember ||
+          procedure.isFactory) {
+        continue;
+      }
+      var name = procedure.name.text;
+      // Add a suffix to differentiate getters and setters.
+      if (procedure.isSetter) name += '=';
+      dartMemberMap[name] = procedure;
+    }
+    for (var field in dartClass.allInstanceFields) {
+      // We only care about concrete instance fields.
+      if (field.isAbstract || field.isStatic) continue;
+      var name = field.name.text;
+      dartMemberMap[name] = field;
+      if (!field.isFinal) {
+        // Add the setter.
+        name += '=';
+        dartMemberMap[name] = field;
+      }
+    }
+
+    var conformanceError = false;
+    var nameToDescriptors = <String, List<ExtensionMemberDescriptor>>{};
+    var descriptorToClass = <ExtensionMemberDescriptor, Class>{};
+    staticInteropClass.computeAllNonStaticExternalExtensionMembers(
+        nameToDescriptors,
+        descriptorToClass,
+        _staticInteropClassesWithExtensions,
+        _typeEnvironment);
+    for (var descriptorName in nameToDescriptors.keys) {
+      var descriptors = nameToDescriptors[descriptorName]!;
+      // In the case of a getter/setter, we may have 2 descriptors per extension
+      // with the same name, and therefore per class. So, only get one
+      // descriptor per class to determine if there are conflicts.
+      var visitedClasses = <Class>{};
+      var descriptorConflicts = <ExtensionMemberDescriptor>{};
+      for (var descriptor in descriptors) {
+        if (visitedClasses.add(descriptorToClass[descriptor]!)) {
+          descriptorConflicts.add(descriptor);
+        }
+      }
+      if (descriptorConflicts.length > 1) {
+        // Conflict, report an error.
+        var violations = <String>[];
+        for (var descriptor in descriptorConflicts) {
+          var cls = descriptorToClass[descriptor]!;
+          var extension = _staticInteropClassesWithExtensions[cls.reference]!;
+          var extensionName =
+              extension.isUnnamedExtension ? 'unnamed' : extension.name;
+          violations.add("'${cls.name}.$extensionName'");
+        }
+        // Sort violations so error expectations can be deterministic.
+        violations.sort();
+        _diagnosticReporter.report(
+            templateJsInteropStaticInteropMockExternalExtensionMemberConflict
+                .withArguments(descriptorName, violations.join(', ')),
+            node.fileOffset,
+            node.name.text.length,
+            node.location?.file);
+        conformanceError = true;
+        continue;
+      }
+      // With no conflicts, there should be either just 1 entry or 2 entries
+      // where one is a getter and the other is a setter in the same extension
+      // (and therefore the same @staticInterop class).
+      assert(descriptors.length == 1 || descriptors.length == 2);
+      if (descriptors.length == 2) {
+        var first = descriptors[0];
+        var second = descriptors[1];
+        assert(descriptorToClass[first]! == descriptorToClass[second]!);
+        assert((first.isGetter && second.isSetter) ||
+            (first.isSetter && second.isGetter));
+      }
+      for (var interopDescriptor in descriptors) {
+        var dartMemberName = descriptorName;
+        // Distinguish getters and setters for overriding conformance.
+        if (interopDescriptor.isSetter) dartMemberName += '=';
+
+        // Determine whether the Dart instance member with the same name as the
+        // `@staticInterop` procedure is the right type of member such that it
+        // can be considered an override.
+        bool validOverridingMemberType() {
+          var dartMember = dartMemberMap[dartMemberName]!;
+          if (interopDescriptor.isGetter &&
+              dartMember is! Field &&
+              !(dartMember as Procedure).isGetter) {
+            return false;
+          } else if (interopDescriptor.isSetter &&
+              dartMember is! Field &&
+              !(dartMember as Procedure).isSetter) {
+            return false;
+          } else if (interopDescriptor.isMethod && dartMember is! Procedure) {
+            return false;
+          }
+          return true;
+        }
+
+        if (!dartMemberMap.containsKey(dartMemberName) ||
+            !validOverridingMemberType()) {
+          _diagnosticReporter.report(
+              templateJsInteropStaticInteropMockMissingOverride.withArguments(
+                  staticInteropClass.name, dartMemberName, dartClass.name),
+              node.fileOffset,
+              node.name.text.length,
+              node.location?.file);
+          conformanceError = true;
+          continue;
+        }
+        var dartMember = dartMemberMap[dartMemberName]!;
+
+        // Determine if the given type of the Dart member is a valid subtype of
+        // the given type of the `@staticInterop` member. If not, report an
+        // error to the user.
+        bool overrideIsSubtype(DartType? dartType, DartType? interopType) {
+          if (dartType == null ||
+              interopType == null ||
+              !_typeEnvironment.isSubtypeOf(
+                  dartType, interopType, SubtypeCheckMode.withNullabilities)) {
+            _diagnosticReporter.report(
+                templateJsInteropStaticInteropMockMemberNotSubtype
+                    .withArguments(
+                        dartClass.name,
+                        dartMemberName,
+                        dartType ?? NullType(),
+                        staticInteropClass.name,
+                        dartMemberName,
+                        interopType ?? NullType(),
+                        true),
+                node.fileOffset,
+                node.name.text.length,
+                node.location?.file);
+            return false;
+          }
+          return true;
+        }
+
+        // CFE creates static procedures for each extension member.
+        var interopMember = interopDescriptor.member.asProcedure;
+        DartType getGetterFunctionType(DartType getterType) {
+          return FunctionType([], getterType, Nullability.nonNullable);
+        }
+
+        DartType getSetterFunctionType(DartType setterType) {
+          return FunctionType(
+              [setterType], VoidType(), Nullability.nonNullable);
+        }
+
+        if (interopDescriptor.isGetter &&
+            !overrideIsSubtype(getGetterFunctionType(dartMember.getterType),
+                getGetterFunctionType(interopMember.function.returnType))) {
+          conformanceError = true;
+          continue;
+        } else if (interopDescriptor.isSetter &&
+            !overrideIsSubtype(
+                getSetterFunctionType(dartMember.setterType),
+                // Ignore the first argument `this` in the generated procedure.
+                getSetterFunctionType(
+                    interopMember.function.positionalParameters[1].type))) {
+          conformanceError = true;
+          continue;
+        } else if (interopDescriptor.isMethod) {
+          var interopMemberType = interopMember.function
+              .computeFunctionType(Nullability.nonNullable);
+          // Ignore the first argument `this` in the generated procedure.
+          interopMemberType = FunctionType(
+              interopMemberType.positionalParameters.skip(1).toList(),
+              interopMemberType.returnType,
+              interopMemberType.declaredNullability,
+              namedParameters: interopMemberType.namedParameters,
+              typeParameters: interopMemberType.typeParameters,
+              requiredParameterCount:
+                  interopMemberType.requiredParameterCount - 1);
+          if (!overrideIsSubtype(
+              (dartMember as Procedure)
+                  .function
+                  .computeFunctionType(Nullability.nonNullable),
+              interopMemberType)) {
+            conformanceError = true;
+            continue;
+          }
+        }
+      }
+    }
+    // The interfaces do not conform and therefore we can't create a mock.
+    if (conformanceError) return node;
+    // Everything conforms, we can safely create a mock and replace this
+    // invocation with it.
+    return _createMock(
+        node, nameToDescriptors, descriptorToClass, dartMemberMap);
+  }
+
+  TreeNode _createMock(
+      StaticInvocation node,
+      Map<String, List<ExtensionMemberDescriptor>> nameToDescriptors,
+      Map<ExtensionMemberDescriptor, Class> descriptorToClass,
+      Map<String, Member> dartMemberMap) {
+    var block = <Statement>[];
+    var argsLength = node.arguments.positional.length;
+    assert(argsLength == 1 || argsLength == 2);
+    var interopType = node.arguments.types[0];
+    var dartType = node.arguments.types[1];
+
+    var dartMock = VariableDeclaration('#dartMock',
+        initializer: node.arguments.positional[0], type: dartType)
+      ..fileOffset = node.fileOffset
+      ..parent = node.parent;
+    block.add(dartMock);
+
+    // Get the global 'Object' property.
+    StaticInvocation getObjectProperty() => StaticInvocation(
+        _getProperty,
+        Arguments([StaticGet(_globalThis), StringLiteral('Object')],
+            types: [_objectType]));
+
+    // Get a fresh object literal, using the proto to create it if one was
+    // given.
+    StaticInvocation getLiteral([Expression? proto]) {
+      return StaticInvocation(
+          _callMethod,
+          Arguments([
+            getObjectProperty(),
+            StringLiteral('create'),
+            ListLiteral([proto ?? NullLiteral()]),
+          ], types: [
+            _objectType
+          ]));
+    }
+
+    var jsMock = VariableDeclaration('#jsMock',
+        initializer: AsExpression(
+            getLiteral(argsLength == 2 ? node.arguments.positional[1] : null),
+            interopType),
+        type: interopType)
+      ..fileOffset = node.fileOffset
+      ..parent = node.parent;
+    block.add(jsMock);
+
+    // Keep a map of all the mappings we use for `Object.defineProperty`. It's
+    // possible that different descriptors might have the same rename, and it's
+    // invalid to redefine a property. This is used in `createAndOrAddToMapping`
+    // below.
+    var jsNameToGetSetMap = <String, VariableDeclaration>{};
+    for (var descriptorName in nameToDescriptors.keys) {
+      var descriptors = nameToDescriptors[descriptorName]!;
+      var descriptor = descriptors[0];
+      // Do any necessary renaming from the `@JS()` annotation.
+      String getJSName(ExtensionMemberDescriptor desc) {
+        var name = js_interop.getJSName(desc.member.asProcedure);
+        return name.isEmpty ? descriptorName : name;
+      }
+
+      ExpressionStatement setProperty(VariableGet jsObject, String propertyName,
+          StaticInvocation wrappedValue) {
+        // `setProperty(jsObject, propertyName, wrappedValue)`
+        return ExpressionStatement(StaticInvocation(
+            _setProperty,
+            Arguments([jsObject, StringLiteral(propertyName), wrappedValue],
+                types: [_objectType])))
+          ..fileOffset = node.fileOffset
+          ..parent = node.parent;
+      }
+
+      var jsName = getJSName(descriptor);
+      if (descriptor.isMethod) {
+        var target = dartMemberMap[descriptorName]! as Procedure;
+        // `setProperty(jsMock, jsName, allowInterop(dartMock.tearoffMethod))`
+        block.add(setProperty(
+            VariableGet(jsMock),
+            jsName,
+            StaticInvocation(
+                _allowInterop,
+                Arguments([
+                  InstanceTearOff(InstanceAccessKind.Instance,
+                      VariableGet(dartMock), target.name,
+                      interfaceTarget: target, resultType: target.getterType)
+                ], types: [
+                  _functionType
+                ]))));
+      } else {
+        // Create the mapping from `get` and `set` to their `dartMock` calls to
+        // be used in `Object.defineProperty`.
+
+        // Add the given descriptor to the mapping that corresponds to the given
+        // JS name that is used by `Object.defineProperty`. In order to conform
+        // to that API, this function defines 'get' or 'set' properties on a
+        // given object literal.
+        // The AST code looks like:
+        //
+        // ```
+        // setProperty(getSetMap, 'get', allowInterop(() {
+        //   return dartMock.getter;
+        // }));
+        // ```
+        //
+        // in the case of a getter and:
+        //
+        // ```
+        // setProperty(getSetMap, 'set', allowInterop((val) {
+        //  dartMock.setter = val;
+        // }));
+        // ```
+        //
+        // in the case of a setter.
+        //
+        // In the case where a mapping does not exist yet for the JS name, a new
+        // VariableDeclaration is created and added to the block of statements.
+        ExpressionStatement createAndOrAddToMapping(
+            ExtensionMemberDescriptor desc,
+            String jsName,
+            List<Statement> block) {
+          if (!jsNameToGetSetMap.containsKey(jsName)) {
+            jsNameToGetSetMap[jsName] = VariableDeclaration('#${jsName}Mapping',
+                initializer: getLiteral(), type: _objectType)
+              ..fileOffset = node.fileOffset
+              ..parent = node.parent;
+            block.add(jsNameToGetSetMap[jsName]!);
+          }
+          var getSetMap = jsNameToGetSetMap[jsName]!;
+          var dartTarget = desc.isGetter
+              ? dartMemberMap[descriptorName]!
+              : dartMemberMap[descriptorName + '=']!;
+          // Parameter needed in case the descriptor is a setter.
+          var setterParameter =
+              VariableDeclaration('#val', type: dartTarget.setterType)
+                ..fileOffset = node.fileOffset
+                ..parent = node.parent;
+          return setProperty(
+              VariableGet(getSetMap),
+              desc.isGetter ? 'get' : 'set',
+              desc.isGetter
+                  ? StaticInvocation(
+                      _allowInterop,
+                      Arguments([
+                        FunctionExpression(FunctionNode(ReturnStatement(
+                            InstanceGet(InstanceAccessKind.Instance,
+                                VariableGet(dartMock), dartTarget.name,
+                                interfaceTarget: dartTarget,
+                                resultType: dartTarget.getterType))))
+                      ], types: [
+                        _functionType
+                      ]))
+                  : StaticInvocation(
+                      _allowInterop,
+                      Arguments([
+                        FunctionExpression(FunctionNode(
+                            ExpressionStatement(InstanceSet(
+                                InstanceAccessKind.Instance,
+                                VariableGet(dartMock),
+                                dartTarget.name,
+                                VariableGet(setterParameter),
+                                interfaceTarget: dartTarget)),
+                            positionalParameters: [setterParameter]))
+                      ], types: [
+                        _functionType
+                      ])));
+        }
+
+        var jsName = getJSName(descriptor);
+        block.add(createAndOrAddToMapping(descriptor, jsName, block));
+        if (descriptors.length == 2) {
+          var secondDescriptor = descriptors[1];
+          var secondJsName = getJSName(secondDescriptor);
+          block.add(
+              createAndOrAddToMapping(secondDescriptor, secondJsName, block));
+          if (secondJsName != jsName) {
+            // Getter and setter's JS names don't match, we will use the new
+            // mapping. This is likely a bug, so print a warning but proceed
+            // anyways.
+            var classRef =
+                descriptorToClass[nameToDescriptors[descriptorName]![0]]!;
+            print('WARNING: ${classRef.name} has getter and setter named '
+                '$descriptorName, but do not share the same JS name: $jsName '
+                'and $secondJsName. Proceeding anyways...');
+          }
+        }
+      }
+    }
+    // Call `Object.defineProperty` to define the descriptor name with the 'get'
+    // and/or 'set' mapping. This allows us to treat get/set semantics as
+    // methods.
+    for (var jsName in jsNameToGetSetMap.keys) {
+      block.add(ExpressionStatement(StaticInvocation(
+          _callMethod,
+          Arguments([
+            getObjectProperty(),
+            StringLiteral('defineProperty'),
+            ListLiteral([
+              VariableGet(jsMock),
+              StringLiteral(jsName),
+              VariableGet(jsNameToGetSetMap[jsName]!)
+            ])
+          ], types: [
+            VoidType()
+          ])))
+        ..fileOffset = node.fileOffset
+        ..parent = node.parent);
+    }
+
+    block.add(ReturnStatement(VariableGet(jsMock)));
+    // Return a call to evaluate the entire block of code and return the JS mock
+    // that was created.
+    return FunctionInvocation(
+        FunctionAccessKind.Function,
+        FunctionExpression(FunctionNode(Block(block), returnType: interopType)),
+        Arguments([]),
+        functionType: FunctionType([], interopType, Nullability.nonNullable))
+      ..fileOffset = node.fileOffset
+      ..parent = node.parent;
+  }
+}
+
+extension _DartClassExtension on Class {
+  List<Procedure> get allInstanceProcedures {
+    var allProcs = <Procedure>[];
+    Class? cls = this;
+    // We only care about instance procedures that have a body.
+    bool isInstanceProcedure(Procedure proc) =>
+        !proc.isAbstract &&
+        !proc.isStatic &&
+        !proc.isExtensionMember &&
+        !proc.isFactory;
+    while (cls != null) {
+      allProcs.addAll(cls.procedures.where(isInstanceProcedure));
+      // Mixin members override the given superclass' members, but are
+      // overridden by the class' instance members, so they are inserted next.
+      if (cls.isMixinApplication) {
+        allProcs.addAll(cls.mixin.procedures.where(isInstanceProcedure));
+      }
+      cls = cls.superclass;
+    }
+    // We inserted procedures from subtype to supertypes, so reverse them so
+    // that overridden members come first, with their overrides last.
+    return allProcs.reversed.toList();
+  }
+
+  List<Field> get allInstanceFields {
+    var allFields = <Field>[];
+    Class? cls = this;
+    bool isInstanceField(Field field) => !field.isAbstract && !field.isStatic;
+    while (cls != null) {
+      allFields.addAll(cls.fields.where(isInstanceField));
+      if (cls.isMixinApplication) {
+        allFields.addAll(cls.mixin.fields.where(isInstanceField));
+      }
+      cls = cls.superclass;
+    }
+    return allFields.reversed.toList();
+  }
+}
+
+extension _StaticInteropClassExtension on Class {
+  /// Sets [nameToDescriptors] to be a map between all the available external
+  /// extension member names and the descriptors that have that name, and also
+  /// sets [descriptorToClass] to be a mapping between every external extension
+  /// member and its on-type.
+  ///
+  /// [staticInteropClassesWithExtensions] is a map between all the
+  /// `@staticInterop` classes and their singular extension. [typeEnvironment]
+  /// is the current component's `TypeEnvironment`.
+  ///
+  /// Note: The algorithm to determine the most-specific extension member in the
+  /// event of name collisions does not conform to the specificity rules
+  /// described here:
+  /// https://github.com/dart-lang/language/blob/master/accepted/2.7/static-extension-methods/feature-specification.md#specificity.
+  /// Instead, it only uses subtype checking of the on-types to find the most
+  /// specific member. This is mostly benign as:
+  /// 1. There's a single extension per @staticInterop class, so conflicts occur
+  /// between classes and not within them.
+  /// 2. Generics in the context of interop are by design supposed to be more
+  /// rare, and external extension members are already disallowed from using
+  /// type parameters. This lowers the importance of checking for instantiation
+  /// to bounds.
+  void computeAllNonStaticExternalExtensionMembers(
+      Map<String, List<ExtensionMemberDescriptor>> nameToDescriptors,
+      Map<ExtensionMemberDescriptor, Class> descriptorToClass,
+      Map<Reference, Extension> staticInteropClassesWithExtensions,
+      TypeEnvironment typeEnvironment) {
+    assert(js_interop.hasStaticInteropAnnotation(this));
+    var classes = <Class>{};
+    // Compute a map of all the possible descriptors available in this type and
+    // the supertypes.
+    void getAllDescriptors(Class cls) {
+      if (classes.add(cls)) {
+        if (staticInteropClassesWithExtensions.containsKey(cls.reference)) {
+          for (var descriptor
+              in staticInteropClassesWithExtensions[cls.reference]!.members) {
+            if (!descriptor.isExternal || descriptor.isStatic) continue;
+            // No need to handle external fields - they are transformed to
+            // external getters/setters by the CFE.
+            if (!descriptor.isGetter &&
+                !descriptor.isSetter &&
+                !descriptor.isMethod) {
+              continue;
+            }
+            descriptorToClass[descriptor] = cls;
+            nameToDescriptors
+                .putIfAbsent(descriptor.name.text, () => [])
+                .add(descriptor);
+          }
+        }
+        cls.supers.forEach((Supertype supertype) {
+          getAllDescriptors(supertype.classNode);
+        });
+      }
+    }
+
+    getAllDescriptors(this);
+
+    InterfaceType getOnType(ExtensionMemberDescriptor desc) =>
+        InterfaceType(descriptorToClass[desc]!, Nullability.nonNullable);
+
+    bool isStrictSubtypeOf(InterfaceType s, InterfaceType t) {
+      if (s.className == t.className) return false;
+      return typeEnvironment.isSubtypeOf(
+          s, t, SubtypeCheckMode.withNullabilities);
+    }
+
+    // Try and find the most specific member amongst duplicate names using
+    // subtype checks.
+    for (var name in nameToDescriptors.keys) {
+      // The set of potential targets whose on-types are not strict subtypes of
+      // any other target's on-type. As we iterate through the descriptors, this
+      // invariant will hold true.
+      var targets = <ExtensionMemberDescriptor>[];
+      for (var descriptor in nameToDescriptors[name]!) {
+        if (targets.isEmpty) {
+          targets.add(descriptor);
+        } else {
+          var newOnType = getOnType(descriptor);
+          // For each existing target, if the new descriptor's on-type is a
+          // strict subtype of the target's on-type, then the new descriptor is
+          // more specific. If any of the existing targets' on-types are a
+          // strict subtype of the new descriptor's on-type, then the new
+          // descriptor is never more specific, and therefore can be ignored.
+          if (!targets.any(
+              (target) => isStrictSubtypeOf(getOnType(target), newOnType))) {
+            targets = [
+              descriptor,
+              // Not a supertype or a subtype, potential conflict or simply a
+              // setter and getter.
+              ...targets.where(
+                  (target) => !isStrictSubtypeOf(newOnType, getOnType(target))),
+            ];
+          }
+        }
+      }
+      nameToDescriptors[name] = targets;
+    }
+  }
+}
+
+extension ExtensionMemberDescriptorExtension on ExtensionMemberDescriptor {
+  bool get isGetter => this.kind == ExtensionMemberKind.Getter;
+  bool get isSetter => this.kind == ExtensionMemberKind.Setter;
+  bool get isMethod => this.kind == ExtensionMemberKind.Method;
+
+  bool get isExternal => (this.member.asProcedure).isExternal;
+}
diff --git a/pkg/_js_interop_checks/pubspec.yaml b/pkg/_js_interop_checks/pubspec.yaml
index 786fd8d..fcb1de5 100644
--- a/pkg/_js_interop_checks/pubspec.yaml
+++ b/pkg/_js_interop_checks/pubspec.yaml
@@ -8,6 +8,7 @@
 # Use 'any' constraints here; we get our versions from the DEPS file.
 dependencies:
   _fe_analyzer_shared: any
+  front_end: any
   kernel: any
 
 # Use 'any' constraints here; we get our versions from the DEPS file.
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index a3e89ce..ac30ecc 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -1754,7 +1754,7 @@
         <p>
           A list of objects each containing a path and the additional libraries from which
           the client is interested in receiving completion suggestions.
-          If one configured path is beneath another, the descendent
+          If one configured path is beneath another, the descendant
           will override the ancestors' configured libraries of interest.
         </p>
       </dd></dl></dd><dt class="request"><a name="request_completion.getSuggestionDetails">completion.getSuggestionDetails</a></dt><dd><div class="box"><pre>request: {
diff --git a/pkg/analysis_server/doc/implementation/navigation.md b/pkg/analysis_server/doc/implementation/navigation.md
new file mode 100644
index 0000000..d18f005
--- /dev/null
+++ b/pkg/analysis_server/doc/implementation/navigation.md
@@ -0,0 +1,39 @@
+# Adding Navigation
+
+This document describes what navigation is and how to enhance it.
+
+## Overview
+
+Navigation is the ability to move from one piece of text to a related location.
+This includes such things as jumping to the declaration of an identifier or
+opening a file based on a URI or file path.
+
+## Enhancing navigation
+
+If we have decided to provide navigation from a given kind of text that was
+previously not supported, you can add that support by extending the class
+`_DartNavigationComputerVisitor`. That class is a `RecursiveAstVisitor`, so the
+first task is to figure out which kind of node contains the text at the origin.
+You can then either add a new `visit` method for the node or edit an existing
+method.
+
+If you're adding a new `visit` method, you'll need to invoke the overridden
+method to ensure that children are still visited.
+
+Within the `visit` method, compute the region from which the user can navigate
+and the location to which they should be navigated. There are some utility
+methods in `_DartNavigationCollector`, to make common cases easier, or you can
+use `computer.collector.addRegion` to add an arbitrary region.
+
+## Testing the navigation
+
+The tests for navigation are in the class `AnalysisNotificationNavigationTest`.
+
+The tests generally follow the following pattern:
+
+1. Use `addTestFile` to add a file containing both the origin and target of the
+   navigation.
+2. Use `await prepareNavigation();` to compute and cache navigation results.
+3. Use `assertHasRegion` to test that the offset of the string in the test file
+   is a navigation origin, and `assertHasTarget` to ensure the target to which
+   the user will be navigated.
diff --git a/pkg/analysis_server/doc/implementation/overview.md b/pkg/analysis_server/doc/implementation/overview.md
index 47e3ccb..f3a9dd5 100644
--- a/pkg/analysis_server/doc/implementation/overview.md
+++ b/pkg/analysis_server/doc/implementation/overview.md
@@ -13,7 +13,7 @@
 - Flutter Outline
 - Hovers
 - Implemented Markers
-- Navigation
+- [Navigation](navigation.md)
 - Occurrences
 - Organize Imports
 - Outline
diff --git a/pkg/analysis_server/doc/process/overview.md b/pkg/analysis_server/doc/process/overview.md
index 87fc4ac..b5847a1 100644
--- a/pkg/analysis_server/doc/process/overview.md
+++ b/pkg/analysis_server/doc/process/overview.md
@@ -8,4 +8,5 @@
 
 The documentation covers the following topics:
 
-- [Implementing a new language feature](new_language_feature.md)
\ No newline at end of file
+- [Implementing a new language feature](new_language_feature.md)
+- [Running/Debugging analysis_server from source in VS Code](running_in_vs_code.md)
diff --git a/pkg/analysis_server/doc/process/running_in_vs_code.md b/pkg/analysis_server/doc/process/running_in_vs_code.md
new file mode 100644
index 0000000..2eca862
--- /dev/null
+++ b/pkg/analysis_server/doc/process/running_in_vs_code.md
@@ -0,0 +1,166 @@
+# Running/Debugging the Analysis Server from Source in VS Code
+
+When working in the `analysis_server` package it's often useful to have VS Code
+run the server from your source instead of using a compiled snapshot from the
+SDK (which would require a potentially lengthy SDK build).
+
+Server startup will be slower when running from source so it's recommended to
+enable this just for specific projects while testing and not generally run the
+server from source.
+
+## VS Code Configuration
+
+- Press `F1` to open the VS Code command palette
+- Run the **Preferences: Open Workspace Settings (JSON)** command
+- Add a `dart.analyzerPath` setting, pointing to the analysis servers's entry
+  script:
+  ```
+  "dart.analyzerPath": "/Users/developer/dart-sdk/sdk/pkg/analysis_server/bin/server.dart"
+  ```
+- Add `dart.sdkPath` pointing to an SDK that is compatible with the version of
+  the source code being run (such as a recent [bleeding edge build][1]):
+  ```
+  "dart.sdkPath": "/Users/developer/Dart SDKs/bleeding_edge"
+  ```
+- Press **Save**
+
+Modifying the `dart.analyzerPath` or `dart.sdkPath` settings will automatically
+restart the analysis server. The server may take a little longer than usual to
+start up when running from source, but all interactions with the server will now
+be your local version.
+
+## Capturing Protocol Traffic
+
+There are a number of ways you can capture the traffic between VS Code and the
+Dart analysis server. The simplest way if you just need to capture some ad-hoc
+traffic is with the **Dart: Capture Analysis Server Logs** command.
+
+- Press `F1` to open the VS Code command palette
+- Run the **Dart: Capture Analysis Server Logs** command
+- While the logging notification is visible, use the editor to trigger
+  communication with the server.
+- If you accidentally hide the logging notification with `<escape>` you can get
+  it back by clicking the bell icon in the status bar.
+- To stop logging and open the log file, click the **Cancel** button on the
+  logging notification.
+
+If you want to have traffic always written to files, you can use some workspace
+settings:
+
+- Press `F1` to open the VS Code command palette
+- Run the **Preferences: Open Workspace Settings (JSON)** command
+- Add a `dart.analyzerLogFile` and/or `dart.analyzerInstrumentationLogFile`
+  setting with an absolute or relative path for a log file:
+  ```
+  "dart.analyzerLogFile": "logs/analyzer.txt",
+  "dart.analyzerInstrumentationLogFile": "logs/analyzer.instrum.txt",
+  ```
+- Press **Save**
+
+The `analyzerLogFile` is captured by the VS Code extension (client-side). This
+records all traffic between VS Code and the server as well as some header and
+startup information (such as how the server is being spawned) and any output to
+stderr. Lines in this log are truncated by default based on the
+`dart.maxLogLineLength` setting (you may wish to increase this if
+troubleshooting large requests).
+
+The `analyzerInstrumentationLogFile` is written by the server. It also includes
+all protocol traffic but also some additional info (such as file watcher events)
+that the client does not have visibility of.
+
+Which log file is most useful may depend on your needs.
+
+At the time of writing, modifying the `dart.analyzerInstrumentationLogFile`
+setting will automatically restart the analysis server but
+`dart.analyzerLogFile` will not. You can force the server to restart using the
+**Dart: Restart Analysis Server** command in the VS Code command palette (`F1`)
+or restart the whole extension host with the **Developer: Reload Window**
+command.
+
+## Attaching a Debugger
+
+If the protocol traffic is not enough, you can attach a debugger to a running
+analysis server as long as its VM Service is enabled.
+
+- Open two VS Code windows, one with the `analysis_server` code open and the
+  other with a test project that will be running the server from source
+- In the test project, follow the instructions above in
+  [VS Code Configuration][2] but additionally set the
+  `dart.analyzerVmServicePort` setting to an available port number.
+  > **NOTE:** This setting will enable the VM Service with authentication codes
+  > disabled. Be sure to unset this setting once you are done debugging.
+  ```
+  "dart.analyzerVmServicePort": 8222
+  ```
+- Click **Save** (the analysis server will be automatically restarted when
+  `dart.analyzerVmServicePort` is modified)
+- Switch to the other VS Code instance that has the `analysis_server` source
+  loaded
+- Press `F1` to open the VS Code command palette
+- Run the **Debug: Attach to Dart Process** command
+- Type the port number used in the `dart.analyzerVmServicePort` setting above
+  and press `<enter>`
+
+This should connect the debugger to the server running in the other VS Code
+window. If everything has worked you can add breakpoints in the server code and
+trigger them by interacting with the server in the test project. To test this is
+working, add a breakpoint to the top of `TextDocumentChangeHandler._changeFile`
+in `lib/src/lsp/handlers/handler_text_document_changes.dart` and modify a file
+in the test project to ensure the breakpoint is hit and you can evaluate
+values using the Debug Console, watch window or hovering over a variable.
+
+## Other Useful Notes
+
+### Multi-Root Workspaces
+
+If you need to work on multiple projects (such as `analysis_server`, `analyzer`,
+`analyzer_plugin`) you can open this without everything else in the `pkg` folder
+by ctrl+clicking folders in the Open dialog, or by using **File -> Add Folder to
+Workspace** to add additional folders.
+
+You can then save this workspace with **File -> Save Workspace** which creates
+a `.code-workspace` file that can be re-opened for the same folders later.
+
+When using a `.code-workspace` like this, workspace-level settings (found via
+**Preferences: Open Workspace Settings (JSON)** command) will be stored in this
+file (since there isn't a single `.vscode/settings.json` file to store them in
+for a multi-root workspace). Similarly, launch configurations can be added to
+this file that apply to the whole workspace.
+
+### Sorting and Organizing On-Save
+
+In the `analysis_server` package, files should have directives and members
+sorted. You can configure this to happen on-save by adding the following to the
+workspace settings for the analyzer project:
+
+```js
+"editor.codeActionsOnSave": {
+	"source.organizeImports": true,
+	"source.sortMembers": true
+},
+```
+
+### Rulers
+
+Code and comments are usually wrapped at 80 characters. You can enable a ruler
+at this point in Dart files with the following setting (either at workspace or
+user level):
+
+```js
+"[dart]": {
+  "editor.rulers": [80],
+}
+```
+
+See [here][3] for some other useful/recommended settings.
+
+### Analyzer Diagnostics Pages
+
+Running the **Dart: Open Analyzer Diagnostics** command will start and open a
+small web app that provides some additional insight into the running server,
+including some timings and exceptions.
+
+
+[1]: https://gsdview.appspot.com/dart-archive/channels/be/raw/latest/sdk/
+[2]: #vs-code-configuration
+[3]: https://dartcode.org/docs/recommended-settings/
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
index 4e1308d..bdc2346 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
@@ -16,9 +16,10 @@
 
 const jsonEncoder = JsonEncoder.withIndent('    ');
 
-typedef DocumentUri = String;
+typedef DocumentUri = Uri;
 typedef LSPAny = Object?;
 typedef LSPObject = Object;
+typedef LSPUri = Uri;
 typedef TextDocumentEditEdits
     = List<Either3<AnnotatedTextEdit, SnippetTextEdit, TextEdit>>;
 
@@ -142,61 +143,46 @@
 /// returned by the server. The values of the parameters should appear in the
 /// `args` field of the `Command` sent to the server in the same order as the
 /// corresponding parameters.
-class CommandParameter implements ToJsonable {
+abstract class CommandParameter implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CommandParameter.canParse,
     CommandParameter.fromJson,
   );
 
   CommandParameter({
-    required this.defaultValue,
-    required this.label,
-    required this.type,
+    required this.parameterLabel,
   });
   static CommandParameter fromJson(Map<String, Object?> json) {
-    final defaultValueJson = json['defaultValue'];
-    final defaultValue = defaultValueJson as String;
-    final labelJson = json['label'];
-    final label = labelJson as String;
-    final typeJson = json['type'];
-    final type = CommandParameterType.fromJson(typeJson as String);
-    return CommandParameter(
-      defaultValue: defaultValue,
-      label: label,
-      type: type,
-    );
+    if (SaveUriCommandParameter.canParse(json, nullLspJsonReporter)) {
+      return SaveUriCommandParameter.fromJson(json);
+    }
+    throw ArgumentError(
+        'Supplied map is not valid for any subclass of CommandParameter');
   }
 
-  /// The default value for the parameter.
-  final String defaultValue;
+  /// An optional default value for the parameter. The type of this value may
+  /// vary between parameter kinds but must always be something that can be
+  /// converted directly to/from JSON.
+  Object? get defaultValue;
+
+  /// The kind of this parameter. The client may use different UIs based on this
+  /// value.
+  String get kind;
 
   /// A human-readable label to be displayed in the UI affordance used to prompt
   /// the user for the value of the parameter.
-  final String label;
-
-  /// The type of the value of the parameter.
-  final CommandParameterType type;
+  final String parameterLabel;
 
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['defaultValue'] = defaultValue;
-    result['label'] = label;
-    result['type'] = type.toJson();
+    result['parameterLabel'] = parameterLabel;
     return result;
   }
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      if (!_canParseString(obj, reporter, 'defaultValue',
-          allowsUndefined: false, allowsNull: false)) {
-        return false;
-      }
-      if (!_canParseString(obj, reporter, 'label',
-          allowsUndefined: false, allowsNull: false)) {
-        return false;
-      }
-      return _canParseCommandParameterType(obj, reporter, 'type',
+      return _canParseString(obj, reporter, 'parameterLabel',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type CommandParameter');
@@ -208,58 +194,16 @@
   bool operator ==(Object other) {
     return other is CommandParameter &&
         other.runtimeType == CommandParameter &&
-        defaultValue == other.defaultValue &&
-        label == other.label &&
-        type == other.type;
+        parameterLabel == other.parameterLabel;
   }
 
   @override
-  int get hashCode => Object.hash(
-        defaultValue,
-        label,
-        type,
-      );
+  int get hashCode => parameterLabel.hashCode;
 
   @override
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// The type of the value associated with a CommandParameter. All values are
-/// encoded as strings, but the type indicates how the string will be decoded by
-/// the server.
-class CommandParameterType implements ToJsonable {
-  const CommandParameterType(this._value);
-  const CommandParameterType.fromJson(this._value);
-
-  final String _value;
-
-  static bool canParse(Object? obj, LspJsonReporter reporter) => obj is String;
-
-  /// The type associated with a bool value.
-  ///
-  /// The value must either be `'true'` or `'false'`.
-  static const boolean = CommandParameterType('boolean');
-
-  /// The type associated with a value representing a path to a file.
-  static const filePath = CommandParameterType('filePath');
-
-  /// The type associated with a string value.
-  static const string = CommandParameterType('string');
-
-  @override
-  Object toJson() => _value;
-
-  @override
-  String toString() => _value.toString();
-
-  @override
-  int get hashCode => _value.hashCode;
-
-  @override
-  bool operator ==(Object other) =>
-      other is CommandParameterType && other._value == _value;
-}
-
 class CompletionItemResolutionInfo implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     CompletionItemResolutionInfo.canParse,
@@ -1217,7 +1161,7 @@
         .map((item) => ClosingLabel.fromJson(item as Map<String, Object?>))
         .toList();
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return PublishClosingLabelsParams(
       labels: labels,
       uri: uri,
@@ -1225,13 +1169,13 @@
   }
 
   final List<ClosingLabel> labels;
-  final String uri;
+  final Uri uri;
 
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
     result['labels'] = labels.map((item) => item.toJson()).toList();
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -1241,7 +1185,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type PublishClosingLabelsParams');
@@ -1283,7 +1227,7 @@
     final outline =
         FlutterOutline.fromJson(outlineJson as Map<String, Object?>);
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return PublishFlutterOutlineParams(
       outline: outline,
       uri: uri,
@@ -1291,13 +1235,13 @@
   }
 
   final FlutterOutline outline;
-  final String uri;
+  final Uri uri;
 
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
     result['outline'] = outline.toJson();
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -1307,7 +1251,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type PublishFlutterOutlineParams');
@@ -1347,7 +1291,7 @@
     final outlineJson = json['outline'];
     final outline = Outline.fromJson(outlineJson as Map<String, Object?>);
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return PublishOutlineParams(
       outline: outline,
       uri: uri,
@@ -1355,13 +1299,13 @@
   }
 
   final Outline outline;
-  final String uri;
+  final Uri uri;
 
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
     result['outline'] = outline.toJson();
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -1371,7 +1315,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type PublishOutlineParams');
@@ -1689,6 +1633,147 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
+/// Information about a Save URI argument needed by the command.
+class SaveUriCommandParameter implements CommandParameter, ToJsonable {
+  static const jsonHandler = LspJsonHandler(
+    SaveUriCommandParameter.canParse,
+    SaveUriCommandParameter.fromJson,
+  );
+
+  SaveUriCommandParameter({
+    required this.actionLabel,
+    this.defaultValue,
+    this.filters,
+    this.kind = 'saveUri',
+    required this.parameterLabel,
+    required this.parameterTitle,
+  }) {
+    if (kind != 'saveUri') {
+      throw 'kind may only be the literal \'saveUri\'';
+    }
+  }
+  static SaveUriCommandParameter fromJson(Map<String, Object?> json) {
+    final actionLabelJson = json['actionLabel'];
+    final actionLabel = actionLabelJson as String;
+    final defaultValueJson = json['defaultValue'];
+    final defaultValue = defaultValueJson as String?;
+    final filtersJson = json['filters'];
+    final filters = (filtersJson as Map<Object, Object?>?)?.map((key, value) =>
+        MapEntry(key as String,
+            (value as List<Object?>).map((item) => item as String).toList()));
+    final kindJson = json['kind'];
+    final kind = kindJson as String;
+    final parameterLabelJson = json['parameterLabel'];
+    final parameterLabel = parameterLabelJson as String;
+    final parameterTitleJson = json['parameterTitle'];
+    final parameterTitle = parameterTitleJson as String;
+    return SaveUriCommandParameter(
+      actionLabel: actionLabel,
+      defaultValue: defaultValue,
+      filters: filters,
+      kind: kind,
+      parameterLabel: parameterLabel,
+      parameterTitle: parameterTitle,
+    );
+  }
+
+  /// A label for the file dialogs action button.
+  final String actionLabel;
+
+  /// An optional default URI for the parameter.
+  @override
+  final String? defaultValue;
+
+  /// A set of file filters for a file dialog. Keys of the map are textual names
+  /// ("Dart") and the value is a list of file extensions (["dart"]).
+  final Map<String, List<String>>? filters;
+  @override
+  final String kind;
+
+  /// A human-readable label to be displayed in the UI affordance used to prompt
+  /// the user for the value of the parameter.
+  @override
+  final String parameterLabel;
+
+  /// A title that may be displayed on a file dialog.
+  final String parameterTitle;
+
+  @override
+  Map<String, Object?> toJson() {
+    var result = <String, Object?>{};
+    result['actionLabel'] = actionLabel;
+    if (defaultValue != null) {
+      result['defaultValue'] = defaultValue;
+    }
+    if (filters != null) {
+      result['filters'] = filters;
+    }
+    result['kind'] = kind;
+    result['parameterLabel'] = parameterLabel;
+    result['parameterTitle'] = parameterTitle;
+    return result;
+  }
+
+  static bool canParse(Object? obj, LspJsonReporter reporter) {
+    if (obj is Map<String, Object?>) {
+      if (!_canParseString(obj, reporter, 'actionLabel',
+          allowsUndefined: false, allowsNull: false)) {
+        return false;
+      }
+      if (!_canParseString(obj, reporter, 'defaultValue',
+          allowsUndefined: true, allowsNull: true)) {
+        return false;
+      }
+      if (!_canParseMapStringListString(obj, reporter, 'filters',
+          allowsUndefined: true, allowsNull: true)) {
+        return false;
+      }
+      if (!_canParseLiteral(obj, reporter, 'kind',
+          allowsUndefined: false, allowsNull: false, literal: 'saveUri')) {
+        return false;
+      }
+      if (!_canParseString(obj, reporter, 'parameterLabel',
+          allowsUndefined: false, allowsNull: false)) {
+        return false;
+      }
+      return _canParseString(obj, reporter, 'parameterTitle',
+          allowsUndefined: false, allowsNull: false);
+    } else {
+      reporter.reportError('must be of type SaveUriCommandParameter');
+      return false;
+    }
+  }
+
+  @override
+  bool operator ==(Object other) {
+    return other is SaveUriCommandParameter &&
+        other.runtimeType == SaveUriCommandParameter &&
+        actionLabel == other.actionLabel &&
+        defaultValue == other.defaultValue &&
+        mapEqual(
+            filters,
+            other.filters,
+            (List<String> a, List<String> b) =>
+                listEqual(a, b, (String a, String b) => a == b)) &&
+        kind == other.kind &&
+        parameterLabel == other.parameterLabel &&
+        parameterTitle == other.parameterTitle;
+  }
+
+  @override
+  int get hashCode => Object.hash(
+        actionLabel,
+        defaultValue,
+        lspHashCode(filters),
+        kind,
+        parameterLabel,
+        parameterTitle,
+      );
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
+
 class SnippetTextEdit implements TextEdit, ToJsonable {
   static const jsonHandler = LspJsonHandler(
     SnippetTextEdit.canParse,
@@ -1864,32 +1949,6 @@
   return true;
 }
 
-bool _canParseCommandParameterType(
-    Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
-    {required bool allowsUndefined, required bool allowsNull}) {
-  reporter.push(fieldName);
-  try {
-    if (!allowsUndefined && !map.containsKey(fieldName)) {
-      reporter.reportError('must not be undefined');
-      return false;
-    }
-    final value = map[fieldName];
-    final nullCheck = allowsNull || allowsUndefined;
-    if (!nullCheck && value == null) {
-      reporter.reportError('must not be null');
-      return false;
-    }
-    if ((!nullCheck || value != null) &&
-        !CommandParameterType.canParse(value, reporter)) {
-      reporter.reportError('must be of type CommandParameterType');
-      return false;
-    }
-  } finally {
-    reporter.pop();
-  }
-  return true;
-}
-
 bool _canParseElement(
     Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
     {required bool allowsUndefined, required bool allowsNull}) {
@@ -2152,6 +2211,64 @@
   return true;
 }
 
+bool _canParseLiteral(
+    Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
+    {required bool allowsUndefined,
+    required bool allowsNull,
+    required String literal}) {
+  reporter.push(fieldName);
+  try {
+    if (!allowsUndefined && !map.containsKey(fieldName)) {
+      reporter.reportError('must not be undefined');
+      return false;
+    }
+    final value = map[fieldName];
+    final nullCheck = allowsNull || allowsUndefined;
+    if (!nullCheck && value == null) {
+      reporter.reportError('must not be null');
+      return false;
+    }
+    if ((!nullCheck || value != null) && value != literal) {
+      reporter.reportError("must be the literal '$literal'");
+      return false;
+    }
+  } finally {
+    reporter.pop();
+  }
+  return true;
+}
+
+bool _canParseMapStringListString(
+    Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
+    {required bool allowsUndefined, required bool allowsNull}) {
+  reporter.push(fieldName);
+  try {
+    if (!allowsUndefined && !map.containsKey(fieldName)) {
+      reporter.reportError('must not be undefined');
+      return false;
+    }
+    final value = map[fieldName];
+    final nullCheck = allowsNull || allowsUndefined;
+    if (!nullCheck && value == null) {
+      reporter.reportError('must not be null');
+      return false;
+    }
+    if ((!nullCheck || value != null) &&
+        (value is! Map ||
+            (value.keys.any((item) =>
+                item is! String ||
+                value.values.any((item) =>
+                    item is! List<Object?> ||
+                    item.any((item) => item is! String)))))) {
+      reporter.reportError('must be of type Map<String, List<String>>');
+      return false;
+    }
+  } finally {
+    reporter.pop();
+  }
+  return true;
+}
+
 bool _canParseMethod(
     Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
     {required bool allowsUndefined, required bool allowsNull}) {
@@ -2278,6 +2395,32 @@
   return true;
 }
 
+bool _canParseUri(
+    Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
+    {required bool allowsUndefined, required bool allowsNull}) {
+  reporter.push(fieldName);
+  try {
+    if (!allowsUndefined && !map.containsKey(fieldName)) {
+      reporter.reportError('must not be undefined');
+      return false;
+    }
+    final value = map[fieldName];
+    final nullCheck = allowsNull || allowsUndefined;
+    if (!nullCheck && value == null) {
+      reporter.reportError('must not be null');
+      return false;
+    }
+    if ((!nullCheck || value != null) &&
+        (value is! String || Uri.tryParse(value) == null)) {
+      reporter.reportError('must be of type Uri');
+      return false;
+    }
+  } finally {
+    reporter.pop();
+  }
+  return true;
+}
+
 Either2<int, String> _eitherIntString(Object? value) {
   return value is int
       ? Either2.t1(value)
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index 00f7c4c..6879e1b 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -115,11 +115,6 @@
 /// @since 3.17.0
 typedef LspPattern = String;
 
-/// A tagging type for string properties that are actually URIs
-///
-/// @since 3.16.0
-typedef LspUri = String;
-
 /// A notebook document filter denotes a notebook document by different
 /// properties. The properties will be match against the notebook's URI (same as
 /// with documents)
@@ -1009,7 +1004,7 @@
         ?.map((item) => SymbolTag.fromJson(item as int))
         .toList();
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return CallHierarchyItem(
       data: data,
       detail: detail,
@@ -1065,7 +1060,7 @@
     if (tags != null) {
       result['tags'] = tags?.map((item) => item.toJson()).toList();
     }
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -1095,7 +1090,7 @@
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type CallHierarchyItem');
@@ -3045,25 +3040,25 @@
   });
   static CodeDescription fromJson(Map<String, Object?> json) {
     final hrefJson = json['href'];
-    final href = hrefJson as String;
+    final href = Uri.parse(hrefJson as String);
     return CodeDescription(
       href: href,
     );
   }
 
   /// An URI to open with more information about the diagnostic error.
-  final LspUri href;
+  final LSPUri href;
 
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['href'] = href;
+    result['href'] = href.toString();
     return result;
   }
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      return _canParseString(obj, reporter, 'href',
+      return _canParseUri(obj, reporter, 'href',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type CodeDescription');
@@ -6403,7 +6398,7 @@
         ? CreateFileOptions.fromJson(optionsJson as Map<String, Object?>)
         : null;
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return CreateFile(
       annotationId: annotationId,
       kind: kind,
@@ -6438,7 +6433,7 @@
     if (options != null) {
       result['options'] = options?.toJson();
     }
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -6456,7 +6451,7 @@
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type CreateFile');
@@ -7311,7 +7306,7 @@
         ? DeleteFileOptions.fromJson(optionsJson as Map<String, Object?>)
         : null;
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return DeleteFile(
       annotationId: annotationId,
       kind: kind,
@@ -7346,7 +7341,7 @@
     if (options != null) {
       result['options'] = options?.toJson();
     }
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -7364,7 +7359,7 @@
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type DeleteFile');
@@ -9699,7 +9694,7 @@
     final relatedDocumentsJson = json['relatedDocuments'];
     final relatedDocuments = (relatedDocumentsJson as Map<Object, Object?>).map(
         (key, value) => MapEntry(
-            key as String,
+            Uri.parse(key as String),
             _eitherFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
                 value)));
     return DocumentDiagnosticReportPartialResult(
@@ -9715,13 +9710,14 @@
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['relatedDocuments'] = relatedDocuments;
+    result['relatedDocuments'] =
+        relatedDocuments.map((key, value) => MapEntry(key.toString(), value));
     return result;
   }
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      return _canParseMapStringFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
+      return _canParseMapUriFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
           obj, reporter, 'relatedDocuments',
           allowsUndefined: false, allowsNull: false);
     } else {
@@ -12912,7 +12908,7 @@
     final typeJson = json['type'];
     final type = FileChangeType.fromJson(typeJson as int);
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return FileEvent(
       type: type,
       uri: uri,
@@ -12929,7 +12925,7 @@
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
     result['type'] = type.toJson();
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -12939,7 +12935,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type FileEvent');
@@ -15637,7 +15633,8 @@
     final rootPathJson = json['rootPath'];
     final rootPath = rootPathJson as String?;
     final rootUriJson = json['rootUri'];
-    final rootUri = rootUriJson as String?;
+    final rootUri =
+        rootUriJson != null ? Uri.parse(rootUriJson as String) : null;
     final traceJson = json['trace'];
     final trace = const {null, 'off', 'messages', 'compact', 'verbose'}
             .contains(traceJson)
@@ -15734,7 +15731,7 @@
     if (rootPath != null) {
       result['rootPath'] = rootPath;
     }
-    result['rootUri'] = rootUri;
+    result['rootUri'] = rootUri?.toString();
     if (trace != null) {
       result['trace'] = trace;
     }
@@ -15770,7 +15767,7 @@
           allowsUndefined: true, allowsNull: true)) {
         return false;
       }
-      if (!_canParseString(obj, reporter, 'rootUri',
+      if (!_canParseUri(obj, reporter, 'rootUri',
           allowsUndefined: false, allowsNull: true)) {
         return false;
       }
@@ -18163,7 +18160,7 @@
     final rangeJson = json['range'];
     final range = Range.fromJson(rangeJson as Map<String, Object?>);
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return Location(
       range: range,
       uri: uri,
@@ -18177,7 +18174,7 @@
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
     result['range'] = range.toJson();
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -18187,7 +18184,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type Location');
@@ -18239,7 +18236,7 @@
     final targetSelectionRange =
         Range.fromJson(targetSelectionRangeJson as Map<String, Object?>);
     final targetUriJson = json['targetUri'];
-    final targetUri = targetUriJson as String;
+    final targetUri = Uri.parse(targetUriJson as String);
     return LocationLink(
       originSelectionRange: originSelectionRange,
       targetRange: targetRange,
@@ -18276,7 +18273,7 @@
     }
     result['targetRange'] = targetRange.toJson();
     result['targetSelectionRange'] = targetSelectionRange.toJson();
-    result['targetUri'] = targetUri;
+    result['targetUri'] = targetUri.toString();
     return result;
   }
 
@@ -18294,7 +18291,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'targetUri',
+      return _canParseUri(obj, reporter, 'targetUri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type LocationLink');
@@ -19558,7 +19555,7 @@
   });
   static NotebookCell fromJson(Map<String, Object?> json) {
     final documentJson = json['document'];
-    final document = documentJson as String;
+    final document = Uri.parse(documentJson as String);
     final executionSummaryJson = json['executionSummary'];
     final executionSummary = executionSummaryJson != null
         ? ExecutionSummary.fromJson(
@@ -19593,7 +19590,7 @@
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['document'] = document;
+    result['document'] = document.toString();
     if (executionSummary != null) {
       result['executionSummary'] = executionSummary?.toJson();
     }
@@ -19606,7 +19603,7 @@
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      if (!_canParseString(obj, reporter, 'document',
+      if (!_canParseUri(obj, reporter, 'document',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -19875,7 +19872,7 @@
     final notebookTypeJson = json['notebookType'];
     final notebookType = notebookTypeJson as String;
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     final versionJson = json['version'];
     final version = versionJson as int;
     return NotebookDocument(
@@ -19899,7 +19896,7 @@
   final String notebookType;
 
   /// The notebook document's uri.
-  final LspUri uri;
+  final LSPUri uri;
 
   /// The version number of this document (it will increase after each change,
   /// including undo/redo).
@@ -19913,7 +19910,7 @@
       result['metadata'] = metadata;
     }
     result['notebookType'] = notebookType;
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     result['version'] = version;
     return result;
   }
@@ -19932,7 +19929,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      if (!_canParseString(obj, reporter, 'uri',
+      if (!_canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -20654,25 +20651,25 @@
   });
   static NotebookDocumentIdentifier fromJson(Map<String, Object?> json) {
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return NotebookDocumentIdentifier(
       uri: uri,
     );
   }
 
   /// The notebook document's uri.
-  final LspUri uri;
+  final LSPUri uri;
 
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type NotebookDocumentIdentifier');
@@ -21280,7 +21277,7 @@
   static OptionalVersionedTextDocumentIdentifier fromJson(
       Map<String, Object?> json) {
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     final versionJson = json['version'];
     final version = versionJson as int?;
     return OptionalVersionedTextDocumentIdentifier(
@@ -21304,14 +21301,14 @@
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     result['version'] = version;
     return result;
   }
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      if (!_canParseString(obj, reporter, 'uri',
+      if (!_canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -21946,7 +21943,7 @@
   });
   static PreviousResultId fromJson(Map<String, Object?> json) {
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     final valueJson = json['value'];
     final value = valueJson as String;
     return PreviousResultId(
@@ -21964,14 +21961,14 @@
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     result['value'] = value;
     return result;
   }
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      if (!_canParseString(obj, reporter, 'uri',
+      if (!_canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -22276,7 +22273,7 @@
         .map((item) => Diagnostic.fromJson(item as Map<String, Object?>))
         .toList();
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     final versionJson = json['version'];
     final version = versionJson as int?;
     return PublishDiagnosticsParams(
@@ -22302,7 +22299,7 @@
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
     result['diagnostics'] = diagnostics.map((item) => item.toJson()).toList();
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     if (version != null) {
       result['version'] = version;
     }
@@ -22315,7 +22312,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      if (!_canParseString(obj, reporter, 'uri',
+      if (!_canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -23040,7 +23037,7 @@
     final relatedDocumentsJson = json['relatedDocuments'];
     final relatedDocuments = (relatedDocumentsJson as Map<Object, Object?>?)
         ?.map((key, value) => MapEntry(
-            key as String,
+            Uri.parse(key as String),
             _eitherFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
                 value)));
     final resultIdJson = json['resultId'];
@@ -23084,7 +23081,8 @@
     result['items'] = items.map((item) => item.toJson()).toList();
     result['kind'] = kind;
     if (relatedDocuments != null) {
-      result['relatedDocuments'] = relatedDocuments;
+      result['relatedDocuments'] = relatedDocuments
+          ?.map((key, value) => MapEntry(key.toString(), value));
     }
     if (resultId != null) {
       result['resultId'] = resultId;
@@ -23102,7 +23100,7 @@
           allowsUndefined: false, allowsNull: false, literal: 'full')) {
         return false;
       }
-      if (!_canParseMapStringFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
+      if (!_canParseMapUriFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
           obj, reporter, 'relatedDocuments',
           allowsUndefined: true, allowsNull: false)) {
         return false;
@@ -23173,7 +23171,7 @@
     final relatedDocumentsJson = json['relatedDocuments'];
     final relatedDocuments = (relatedDocumentsJson as Map<Object, Object?>?)
         ?.map((key, value) => MapEntry(
-            key as String,
+            Uri.parse(key as String),
             _eitherFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
                 value)));
     final resultIdJson = json['resultId'];
@@ -23212,7 +23210,8 @@
     var result = <String, Object?>{};
     result['kind'] = kind;
     if (relatedDocuments != null) {
-      result['relatedDocuments'] = relatedDocuments;
+      result['relatedDocuments'] = relatedDocuments
+          ?.map((key, value) => MapEntry(key.toString(), value));
     }
     result['resultId'] = resultId;
     return result;
@@ -23224,7 +23223,7 @@
           allowsUndefined: false, allowsNull: false, literal: 'unchanged')) {
         return false;
       }
-      if (!_canParseMapStringFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
+      if (!_canParseMapUriFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
           obj, reporter, 'relatedDocuments',
           allowsUndefined: true, allowsNull: false)) {
         return false;
@@ -23284,7 +23283,7 @@
   });
   static RelativePattern fromJson(Map<String, Object?> json) {
     final baseUriJson = json['baseUri'];
-    final baseUri = _eitherStringWorkspaceFolder(baseUriJson);
+    final baseUri = _eitherUriWorkspaceFolder(baseUriJson);
     final patternJson = json['pattern'];
     final pattern = patternJson as String;
     return RelativePattern(
@@ -23295,7 +23294,7 @@
 
   /// A workspace folder or a base URI to which this pattern will be matched
   /// against relatively.
-  final Either2<LspUri, WorkspaceFolder> baseUri;
+  final Either2<LSPUri, WorkspaceFolder> baseUri;
 
   /// The actual glob pattern;
   final LspPattern pattern;
@@ -23310,7 +23309,7 @@
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      if (!_canParseStringWorkspaceFolder(obj, reporter, 'baseUri',
+      if (!_canParseUriWorkspaceFolder(obj, reporter, 'baseUri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -23486,9 +23485,9 @@
     final kindJson = json['kind'];
     final kind = kindJson as String;
     final newUriJson = json['newUri'];
-    final newUri = newUriJson as String;
+    final newUri = Uri.parse(newUriJson as String);
     final oldUriJson = json['oldUri'];
-    final oldUri = oldUriJson as String;
+    final oldUri = Uri.parse(oldUriJson as String);
     final optionsJson = json['options'];
     final options = optionsJson != null
         ? RenameFileOptions.fromJson(optionsJson as Map<String, Object?>)
@@ -23528,8 +23527,8 @@
       result['annotationId'] = annotationId;
     }
     result['kind'] = kind;
-    result['newUri'] = newUri;
-    result['oldUri'] = oldUri;
+    result['newUri'] = newUri.toString();
+    result['oldUri'] = oldUri.toString();
     if (options != null) {
       result['options'] = options?.toJson();
     }
@@ -23546,11 +23545,11 @@
           allowsUndefined: false, allowsNull: false, literal: 'rename')) {
         return false;
       }
-      if (!_canParseString(obj, reporter, 'newUri',
+      if (!_canParseUri(obj, reporter, 'newUri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      if (!_canParseString(obj, reporter, 'oldUri',
+      if (!_canParseUri(obj, reporter, 'oldUri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -27158,7 +27157,7 @@
     final takeFocusJson = json['takeFocus'];
     final takeFocus = takeFocusJson as bool?;
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return ShowDocumentParams(
       external: external,
       selection: selection,
@@ -27183,7 +27182,7 @@
   final bool? takeFocus;
 
   /// The document uri to show.
-  final LspUri uri;
+  final LSPUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -27197,7 +27196,7 @@
     if (takeFocus != null) {
       result['takeFocus'] = takeFocus;
     }
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -27215,7 +27214,7 @@
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type ShowDocumentParams');
@@ -30105,7 +30104,7 @@
       return OptionalVersionedTextDocumentIdentifier.fromJson(json);
     }
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return TextDocumentIdentifier(
       uri: uri,
     );
@@ -30117,13 +30116,13 @@
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type TextDocumentIdentifier');
@@ -30164,7 +30163,7 @@
     final textJson = json['text'];
     final text = textJson as String;
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     final versionJson = json['version'];
     final version = versionJson as int;
     return TextDocumentItem(
@@ -30193,7 +30192,7 @@
     var result = <String, Object?>{};
     result['languageId'] = languageId;
     result['text'] = text;
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     result['version'] = version;
     return result;
   }
@@ -30208,7 +30207,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      if (!_canParseString(obj, reporter, 'uri',
+      if (!_canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -31466,7 +31465,7 @@
         ?.map((item) => SymbolTag.fromJson(item as int))
         .toList();
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return TypeHierarchyItem(
       data: data,
       detail: detail,
@@ -31524,7 +31523,7 @@
     if (tags != null) {
       result['tags'] = tags?.map((item) => item.toJson()).toList();
     }
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -31554,7 +31553,7 @@
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type TypeHierarchyItem');
@@ -32299,7 +32298,7 @@
   static VersionedNotebookDocumentIdentifier fromJson(
       Map<String, Object?> json) {
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     final versionJson = json['version'];
     final version = versionJson as int;
     return VersionedNotebookDocumentIdentifier(
@@ -32309,7 +32308,7 @@
   }
 
   /// The notebook document's uri.
-  final LspUri uri;
+  final LSPUri uri;
 
   /// The version number of this notebook document.
   final int version;
@@ -32317,14 +32316,14 @@
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     result['version'] = version;
     return result;
   }
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      if (!_canParseString(obj, reporter, 'uri',
+      if (!_canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -32369,7 +32368,7 @@
   });
   static VersionedTextDocumentIdentifier fromJson(Map<String, Object?> json) {
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     final versionJson = json['version'];
     final version = versionJson as int;
     return VersionedTextDocumentIdentifier(
@@ -32388,14 +32387,14 @@
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     result['version'] = version;
     return result;
   }
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      if (!_canParseString(obj, reporter, 'uri',
+      if (!_canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -33970,7 +33969,7 @@
     final changesJson = json['changes'];
     final changes = (changesJson as Map<Object, Object?>?)?.map((key, value) =>
         MapEntry(
-            key as String,
+            Uri.parse(key as String),
             (value as List<Object?>)
                 .map((item) => TextEdit.fromJson(item as Map<String, Object?>))
                 .toList()));
@@ -34021,7 +34020,8 @@
       result['changeAnnotations'] = changeAnnotations;
     }
     if (changes != null) {
-      result['changes'] = changes;
+      result['changes'] = changes?.map((key, value) => MapEntry(
+          key.toString(), value.map((item) => item.toJson()).toList()));
     }
     if (documentChanges != null) {
       result['documentChanges'] = documentChanges;
@@ -34036,7 +34036,7 @@
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
-      if (!_canParseMapStringListTextEdit(obj, reporter, 'changes',
+      if (!_canParseMapUriListTextEdit(obj, reporter, 'changes',
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
@@ -34299,7 +34299,7 @@
     final nameJson = json['name'];
     final name = nameJson as String;
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return WorkspaceFolder(
       name: name,
       uri: uri,
@@ -34311,13 +34311,13 @@
   final String name;
 
   /// The associated URI for this workspace folder.
-  final LspUri uri;
+  final LSPUri uri;
 
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
     result['name'] = name;
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
@@ -34327,7 +34327,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type WorkspaceFolder');
@@ -34539,7 +34539,7 @@
     final resultIdJson = json['resultId'];
     final resultId = resultIdJson as String?;
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     final versionJson = json['version'];
     final version = versionJson as int?;
     return WorkspaceFullDocumentDiagnosticReport(
@@ -34579,7 +34579,7 @@
     if (resultId != null) {
       result['resultId'] = resultId;
     }
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     result['version'] = version;
     return result;
   }
@@ -34598,7 +34598,7 @@
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
-      if (!_canParseString(obj, reporter, 'uri',
+      if (!_canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -35090,7 +35090,7 @@
   });
   static WorkspaceSymbolLocation fromJson(Map<String, Object?> json) {
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     return WorkspaceSymbolLocation(
       uri: uri,
     );
@@ -35101,13 +35101,13 @@
   @override
   Map<String, Object?> toJson() {
     var result = <String, Object?>{};
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     return result;
   }
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      return _canParseString(obj, reporter, 'uri',
+      return _canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false);
     } else {
       reporter.reportError('must be of type WorkspaceSymbolLocation');
@@ -35406,7 +35406,7 @@
     final resultIdJson = json['resultId'];
     final resultId = resultIdJson as String;
     final uriJson = json['uri'];
-    final uri = uriJson as String;
+    final uri = Uri.parse(uriJson as String);
     final versionJson = json['version'];
     final version = versionJson as int?;
     return WorkspaceUnchangedDocumentDiagnosticReport(
@@ -35439,7 +35439,7 @@
     var result = <String, Object?>{};
     result['kind'] = kind;
     result['resultId'] = resultId;
-    result['uri'] = uri;
+    result['uri'] = uri.toString();
     result['version'] = version;
     return result;
   }
@@ -35454,7 +35454,7 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
-      if (!_canParseString(obj, reporter, 'uri',
+      if (!_canParseUri(obj, reporter, 'uri',
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
@@ -40201,7 +40201,7 @@
 }
 
 bool
-    _canParseMapStringFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
+    _canParseMapUriFullDocumentDiagnosticReportUnchangedDocumentDiagnosticReport(
         Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
         {required bool allowsUndefined, required bool allowsNull}) {
   reporter.push(fieldName);
@@ -40219,7 +40219,7 @@
     if ((!nullCheck || value != null) &&
         (value is! Map ||
             (value.keys.any((item) =>
-                item is! String ||
+                (item is! String || Uri.tryParse(item) == null) ||
                 value.values.any((item) =>
                     !FullDocumentDiagnosticReport.canParse(item, reporter) &&
                     !UnchangedDocumentDiagnosticReport.canParse(
@@ -40234,7 +40234,7 @@
   return true;
 }
 
-bool _canParseMapStringListTextEdit(
+bool _canParseMapUriListTextEdit(
     Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
     {required bool allowsUndefined, required bool allowsNull}) {
   reporter.push(fieldName);
@@ -40252,7 +40252,7 @@
     if ((!nullCheck || value != null) &&
         (value is! Map ||
             (value.keys.any((item) =>
-                item is! String ||
+                (item is! String || Uri.tryParse(item) == null) ||
                 value.values.any((item) =>
                     item is! List<Object?> ||
                     item.any(
@@ -41641,32 +41641,6 @@
   return true;
 }
 
-bool _canParseStringWorkspaceFolder(
-    Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
-    {required bool allowsUndefined, required bool allowsNull}) {
-  reporter.push(fieldName);
-  try {
-    if (!allowsUndefined && !map.containsKey(fieldName)) {
-      reporter.reportError('must not be undefined');
-      return false;
-    }
-    final value = map[fieldName];
-    final nullCheck = allowsNull || allowsUndefined;
-    if (!nullCheck && value == null) {
-      reporter.reportError('must not be null');
-      return false;
-    }
-    if ((!nullCheck || value != null) &&
-        (value is! String && !WorkspaceFolder.canParse(value, reporter))) {
-      reporter.reportError('must be of type Either2<LspUri, WorkspaceFolder>');
-      return false;
-    }
-  } finally {
-    reporter.pop();
-  }
-  return true;
-}
-
 bool _canParseSymbolKind(
     Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
     {required bool allowsUndefined, required bool allowsNull}) {
@@ -42033,6 +42007,59 @@
   return true;
 }
 
+bool _canParseUri(
+    Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
+    {required bool allowsUndefined, required bool allowsNull}) {
+  reporter.push(fieldName);
+  try {
+    if (!allowsUndefined && !map.containsKey(fieldName)) {
+      reporter.reportError('must not be undefined');
+      return false;
+    }
+    final value = map[fieldName];
+    final nullCheck = allowsNull || allowsUndefined;
+    if (!nullCheck && value == null) {
+      reporter.reportError('must not be null');
+      return false;
+    }
+    if ((!nullCheck || value != null) &&
+        (value is! String || Uri.tryParse(value) == null)) {
+      reporter.reportError('must be of type Uri');
+      return false;
+    }
+  } finally {
+    reporter.pop();
+  }
+  return true;
+}
+
+bool _canParseUriWorkspaceFolder(
+    Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
+    {required bool allowsUndefined, required bool allowsNull}) {
+  reporter.push(fieldName);
+  try {
+    if (!allowsUndefined && !map.containsKey(fieldName)) {
+      reporter.reportError('must not be undefined');
+      return false;
+    }
+    final value = map[fieldName];
+    final nullCheck = allowsNull || allowsUndefined;
+    if (!nullCheck && value == null) {
+      reporter.reportError('must not be null');
+      return false;
+    }
+    if ((!nullCheck || value != null) &&
+        ((value is! String || Uri.tryParse(value) == null) &&
+            !WorkspaceFolder.canParse(value, reporter))) {
+      reporter.reportError('must be of type Either2<LSPUri, WorkspaceFolder>');
+      return false;
+    }
+  } finally {
+    reporter.pop();
+  }
+  return true;
+}
+
 bool _canParseVersionedNotebookDocumentIdentifier(
     Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
     {required bool allowsUndefined, required bool allowsNull}) {
@@ -42910,14 +42937,6 @@
           : throw '$value was not one of (LspPattern, RelativePattern)';
 }
 
-Either2<LspUri, WorkspaceFolder> _eitherStringWorkspaceFolder(Object? value) {
-  return value is String
-      ? Either2.t1(value)
-      : WorkspaceFolder.canParse(value, nullLspJsonReporter)
-          ? Either2.t2(WorkspaceFolder.fromJson(value as Map<String, Object?>))
-          : throw '$value was not one of (LspUri, WorkspaceFolder)';
-}
-
 Either2<TextDocumentContentChangeEvent1, TextDocumentContentChangeEvent2>
     _eitherTextDocumentContentChangeEvent1TextDocumentContentChangeEvent2(
         Object? value) {
@@ -42940,6 +42959,14 @@
           : throw '$value was not one of (TextDocumentSyncKind, TextDocumentSyncOptions)';
 }
 
+Either2<LSPUri, WorkspaceFolder> _eitherUriWorkspaceFolder(Object? value) {
+  return (value is String && Uri.tryParse(value) != null)
+      ? Either2.t1(Uri.parse(value))
+      : WorkspaceFolder.canParse(value, nullLspJsonReporter)
+          ? Either2.t2(WorkspaceFolder.fromJson(value as Map<String, Object?>))
+          : throw '$value was not one of (LSPUri, WorkspaceFolder)';
+}
+
 Either2<WorkspaceFullDocumentDiagnosticReport,
         WorkspaceUnchangedDocumentDiagnosticReport>
     _eitherWorkspaceFullDocumentDiagnosticReportWorkspaceUnchangedDocumentDiagnosticReport(
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index e3675de..ee0be6a 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -6,6 +6,7 @@
 /// entities.
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart';
 import 'package:path/path.dart' as path;
 
 /// Return a protocol [Element] corresponding to the given [engine.Element].
@@ -145,9 +146,9 @@
     }
     parameters = element.parameters.toList();
   } else if (element is engine.TypeAliasElement) {
-    var aliasedElement = element.aliasedElement;
-    if (aliasedElement is engine.GenericFunctionTypeElement) {
-      parameters = aliasedElement.parameters.toList();
+    final aliasedType = element.aliasedType;
+    if (aliasedType is FunctionType) {
+      parameters = aliasedType.parameters.toList();
     } else {
       return null;
     }
@@ -185,7 +186,7 @@
 
 String? _getTypeParametersString(engine.Element element) {
   List<engine.TypeParameterElement>? typeParameters;
-  if (element is engine.ClassElement) {
+  if (element is engine.InterfaceElement) {
     typeParameters = element.typeParameters;
   } else if (element is engine.TypeAliasElement) {
     typeParameters = element.typeParameters;
@@ -203,6 +204,9 @@
   if (element is engine.MethodElement) {
     return element.isAbstract;
   }
+  if (element is engine.MixinElement) {
+    return true;
+  }
   if (element is engine.PropertyAccessorElement) {
     return element.isAbstract;
   }
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index c4c8938..889e138 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -5180,7 +5180,7 @@
 class CompletionRegisterLibraryPathsParams implements RequestParams {
   /// A list of objects each containing a path and the additional libraries
   /// from which the client is interested in receiving completion suggestions.
-  /// If one configured path is beneath another, the descendent will override
+  /// If one configured path is beneath another, the descendant will override
   /// the ancestors' configured libraries of interest.
   List<LibraryPathSet> paths;
 
diff --git a/pkg/analysis_server/lib/src/cider/rename.dart b/pkg/analysis_server/lib/src/cider/rename.dart
index a155512..ebb81cf 100644
--- a/pkg/analysis_server/lib/src/cider/rename.dart
+++ b/pkg/analysis_server/lib/src/cider/rename.dart
@@ -48,7 +48,7 @@
       status = validateMethodName(name);
     } else if (element is TypeAliasElement) {
       status = validateTypeAliasName(name);
-    } else if (element is ClassElement) {
+    } else if (element is InterfaceElement) {
       status = validateClassName(name);
     } else if (element is ConstructorElement) {
       status = validateConstructorName(name);
@@ -65,7 +65,7 @@
 
   void _analyzePossibleConflicts(
       ConstructorElement element, RefactoringStatus result, String newName) {
-    var parentClass = element.enclosingElement3;
+    var parentClass = element.enclosingElement;
     // Check if the "newName" is the name of the enclosing class.
     if (parentClass.name == newName) {
       result.addError('The constructor should not have the same name '
@@ -254,8 +254,8 @@
     var stateName = flutterState.newName;
     var match = await canRename._fileResolver.findReferences2(stateClass);
     var sourcePath = stateClass.source.fullName;
-    var location = stateClass.enclosingElement3.lineInfo
-        .getLocation(stateClass.nameOffset);
+    var location =
+        stateClass.enclosingElement.lineInfo.getLocation(stateClass.nameOffset);
     CiderSearchMatch ciderMatch;
     var searchInfo =
         CiderSearchInfo(location, stateClass.nameLength, MatchKind.DECLARATION);
@@ -297,12 +297,12 @@
 
   Future<CiderReplaceMatch?> _replaceSyntheticConstructor() async {
     var element = canRename.refactoringElement.element;
-    var classElement = element.enclosingElement3;
+    var interfaceElement = element.enclosingElement;
 
     var fileResolver = canRename._fileResolver;
-    var libraryPath = classElement!.library!.source.fullName;
+    var libraryPath = interfaceElement!.library!.source.fullName;
     var resolvedLibrary = await fileResolver.resolveLibrary2(path: libraryPath);
-    var result = resolvedLibrary.getElementDeclaration(classElement);
+    var result = resolvedLibrary.getElementDeclaration(interfaceElement);
     if (result == null) {
       return null;
     }
@@ -321,7 +321,7 @@
         return null;
       }
 
-      var header = '${classElement.name}.$newName();';
+      var header = '${interfaceElement.name}.$newName();';
       return CiderReplaceMatch(libraryPath, [
         ReplaceInfo(location.prefix + header + location.suffix,
             resolvedUnit.lineInfo.getLocation(location.offset), 0)
@@ -333,7 +333,7 @@
         return null;
       }
 
-      var header = 'const ${classElement.name}.$newName();';
+      var header = 'const ${interfaceElement.name}.$newName();';
       return CiderReplaceMatch(libraryPath, [
         ReplaceInfo(location.prefix + header + location.suffix,
             resolvedUnit.lineInfo.getLocation(location.offset), 0)
@@ -382,7 +382,7 @@
   }
 
   bool _canRenameElement(Element element) {
-    var enclosingElement = element.enclosingElement3;
+    var enclosingElement = element.enclosingElement;
     if (element is ConstructorElement) {
       return true;
     }
@@ -392,7 +392,7 @@
     if (element is LabelElement || element is LocalElement) {
       return true;
     }
-    if (enclosingElement is ClassElement ||
+    if (enclosingElement is InterfaceElement ||
         enclosingElement is ExtensionElement ||
         enclosingElement is CompilationUnitElement) {
       return true;
diff --git a/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart b/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart
index 577c75d4..a5d88a5 100644
--- a/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart
@@ -104,7 +104,7 @@
         codeRange = _codeRangeForElement(element),
         file = element.source!.fullName,
         kind = CallHierarchyKind.forElement(element) {
-    final enclosingElement = element.enclosingElement3;
+    final enclosingElement = element.enclosingElement;
     final container =
         enclosingElement != null ? _getContainer(enclosingElement) : null;
     containerName = container != null ? _getDisplayName(container) : null;
@@ -204,8 +204,8 @@
     // `constructor`, because we need to locate them using an `offset`, which
     // implicit constructors do not have.
     // Here, we map them back to the synthetic constructor element.
-    final isImplicitConstructor =
-        element is ClassElement && target.kind == CallHierarchyKind.constructor;
+    final isImplicitConstructor = element is InterfaceElement &&
+        target.kind == CallHierarchyKind.constructor;
     if (isImplicitConstructor) {
       element = element.unnamedConstructor;
     }
@@ -330,7 +330,7 @@
         }
       }
     } else if (node is ConstructorDeclaration) {
-      final name = node.name2;
+      final name = node.name;
       if (name != null && offset < name.offset) {
         return null;
       }
diff --git a/pkg/analysis_server/lib/src/computer/computer_color.dart b/pkg/analysis_server/lib/src/computer/computer_color.dart
index 6649356..1026b0a 100644
--- a/pkg/analysis_server/lib/src/computer/computer_color.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_color.dart
@@ -83,7 +83,7 @@
 
     final constructor = expression.constructorName;
     final staticElement = constructor.staticElement;
-    final classElement = staticElement?.enclosingElement3;
+    final classElement = staticElement?.enclosingElement;
     final className = classElement?.name;
     final constructorName = constructor.name?.name;
     final constructorArgs = expression.argumentList.arguments
diff --git a/pkg/analysis_server/lib/src/computer/computer_folding.dart b/pkg/analysis_server/lib/src/computer/computer_folding.dart
index f5feba2..2f39027 100644
--- a/pkg/analysis_server/lib/src/computer/computer_folding.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_folding.dart
@@ -357,6 +357,13 @@
   }
 
   @override
+  void visitRecordLiteral(RecordLiteral node) {
+    _computer._addRegion(node.leftParenthesis.end, node.rightParenthesis.offset,
+        FoldingKind.LITERAL);
+    super.visitRecordLiteral(node);
+  }
+
+  @override
   void visitSetOrMapLiteral(SetOrMapLiteral node) {
     _computer._addRegion(
         node.leftBracket.end, node.rightBracket.offset, FoldingKind.LITERAL);
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 0916036..e54d399 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -158,7 +158,7 @@
 
   bool _addIdentifierRegion_class(SimpleIdentifier node) {
     var element = node.writeOrReadElement;
-    if (element is! ClassElement) {
+    if (element is! InterfaceElement) {
       return false;
     }
     // prepare type
@@ -305,7 +305,7 @@
     var parent = node.parent;
     var isInvocation = parent is MethodInvocation && parent.methodName == node;
     HighlightRegionType type;
-    var isTopLevel = element.enclosingElement3 is CompilationUnitElement;
+    var isTopLevel = element.enclosingElement is CompilationUnitElement;
     if (node.inDeclarationContext()) {
       type = isTopLevel
           ? HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION
@@ -334,7 +334,7 @@
       return false;
     }
     // getter or setter
-    var isTopLevel = element.enclosingElement3 is CompilationUnitElement;
+    var isTopLevel = element.enclosingElement is CompilationUnitElement;
     HighlightRegionType type;
     if (element.isGetter) {
       if (isTopLevel) {
@@ -662,9 +662,10 @@
 
   @override
   void visitClassDeclaration(ClassDeclaration node) {
-    computer._addRegion_token(node.classKeyword, HighlightRegionType.KEYWORD);
     computer._addRegion_token(
         node.abstractKeyword, HighlightRegionType.BUILT_IN);
+    computer._addRegion_token(node.classKeyword, HighlightRegionType.KEYWORD);
+    computer._addRegion_token(node.name, HighlightRegionType.CLASS);
     super.visitClassDeclaration(node);
   }
 
@@ -683,7 +684,7 @@
         node.factoryKeyword, HighlightRegionType.BUILT_IN);
     computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
     computer._addRegion_token(
-      node.name2,
+      node.name,
       HighlightRegionType.CONSTRUCTOR,
       semanticTokenType: SemanticTokenTypes.method,
       semanticTokenModifiers: {
@@ -724,6 +725,12 @@
   @override
   void visitDeclaredIdentifier(DeclaredIdentifier node) {
     computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
+
+    computer._addRegion_token(
+      node.name,
+      HighlightRegionType.LOCAL_VARIABLE_DECLARATION,
+    );
+
     super.visitDeclaredIdentifier(node);
   }
 
@@ -752,7 +759,7 @@
   @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
     computer._addRegion_token(
-      node.name2,
+      node.name,
       HighlightRegionType.ENUM_CONSTANT,
     );
     node.visitChildren(this);
@@ -761,6 +768,7 @@
   @override
   void visitEnumDeclaration(EnumDeclaration node) {
     computer._addRegion_token(node.enumKeyword, HighlightRegionType.KEYWORD);
+    computer._addRegion_token(node.name, HighlightRegionType.ENUM);
     super.visitEnumDeclaration(node);
   }
 
@@ -788,6 +796,7 @@
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     computer._addRegion_token(
         node.extensionKeyword, HighlightRegionType.KEYWORD);
+    computer._addRegion_token(node.name, HighlightRegionType.EXTENSION);
     computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
     super.visitExtensionDeclaration(node);
   }
@@ -799,13 +808,30 @@
     computer._addRegion_token(
         node.externalKeyword, HighlightRegionType.BUILT_IN);
     computer._addRegion_token(node.staticKeyword, HighlightRegionType.BUILT_IN);
+
+    for (final variable in node.fields.variables) {
+      computer._addRegion_token(
+        variable.name,
+        node.isStatic
+            ? HighlightRegionType.STATIC_FIELD_DECLARATION
+            : HighlightRegionType.INSTANCE_FIELD_DECLARATION,
+      );
+    }
+
     super.visitFieldDeclaration(node);
   }
 
   @override
   void visitFieldFormalParameter(FieldFormalParameter node) {
     computer._addRegion_token(
-        node.requiredKeyword, HighlightRegionType.KEYWORD);
+      node.requiredKeyword,
+      HighlightRegionType.KEYWORD,
+    );
+
+    computer._addRegion_token(
+      node.thisKeyword,
+      HighlightRegionType.KEYWORD,
+    );
 
     var element = node.declaredElement;
     if (element is FieldFormalParameterElement) {
@@ -859,6 +885,19 @@
         node.externalKeyword, HighlightRegionType.BUILT_IN);
     computer._addRegion_token(
         node.propertyKeyword, HighlightRegionType.BUILT_IN);
+
+    final HighlightRegionType nameType;
+    if (node.isGetter) {
+      nameType = HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION;
+    } else if (node.isSetter) {
+      nameType = HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION;
+    } else if (node.parent is CompilationUnit) {
+      nameType = HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION;
+    } else {
+      nameType = HighlightRegionType.LOCAL_FUNCTION_DECLARATION;
+    }
+    computer._addRegion_token(node.name, nameType);
+
     super.visitFunctionDeclaration(node);
   }
 
@@ -866,6 +905,8 @@
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     computer._addRegion_token(
         node.typedefKeyword, HighlightRegionType.BUILT_IN);
+    computer._addRegion_token(
+        node.name, HighlightRegionType.FUNCTION_TYPE_ALIAS);
     super.visitFunctionTypeAlias(node);
   }
 
@@ -887,6 +928,15 @@
   void visitGenericTypeAlias(GenericTypeAlias node) {
     computer._addRegion_token(
         node.typedefKeyword, HighlightRegionType.BUILT_IN);
+
+    final HighlightRegionType nameType;
+    if (node.functionType != null) {
+      nameType = HighlightRegionType.FUNCTION_TYPE_ALIAS;
+    } else {
+      nameType = HighlightRegionType.TYPE_ALIAS;
+    }
+    computer._addRegion_token(node.name, nameType);
+
     super.visitGenericTypeAlias(node);
   }
 
@@ -1014,6 +1064,23 @@
         node.operatorKeyword, HighlightRegionType.BUILT_IN);
     computer._addRegion_token(
         node.propertyKeyword, HighlightRegionType.BUILT_IN);
+
+    final HighlightRegionType nameType;
+    if (node.isGetter) {
+      nameType = node.isStatic
+          ? HighlightRegionType.STATIC_GETTER_DECLARATION
+          : HighlightRegionType.INSTANCE_GETTER_DECLARATION;
+    } else if (node.isSetter) {
+      nameType = node.isStatic
+          ? HighlightRegionType.STATIC_SETTER_DECLARATION
+          : HighlightRegionType.INSTANCE_SETTER_DECLARATION;
+    } else {
+      nameType = node.isStatic
+          ? HighlightRegionType.STATIC_METHOD_DECLARATION
+          : HighlightRegionType.INSTANCE_METHOD_DECLARATION;
+    }
+    computer._addRegion_token(node.name, nameType);
+
     super.visitMethodDeclaration(node);
   }
 
@@ -1075,6 +1142,33 @@
   }
 
   @override
+  void visitRecordLiteral(RecordLiteral node) {
+    computer._addRegion_node(node, HighlightRegionType.LITERAL_RECORD);
+    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
+
+    for (final field in node.fields) {
+      if (field is NamedExpression) {
+        computer._addRegion_token(
+          field.name.label.token,
+          HighlightRegionType.PARAMETER_REFERENCE,
+        );
+        field.expression.accept(this);
+      } else {
+        field.accept(this);
+      }
+    }
+  }
+
+  @override
+  void visitRecordTypeAnnotation(RecordTypeAnnotation node) {
+    for (final field in node.fields) {
+      computer._addRegion_token(field.name, HighlightRegionType.FIELD);
+    }
+
+    super.visitRecordTypeAnnotation(node);
+  }
+
+  @override
   void visitRethrowExpression(RethrowExpression node) {
     computer._addRegion_token(node.rethrowKeyword, HighlightRegionType.KEYWORD,
         semanticTokenModifiers: {CustomSemanticTokenModifiers.control});
@@ -1112,17 +1206,19 @@
   void visitSimpleFormalParameter(SimpleFormalParameter node) {
     computer._addRegion_token(
         node.requiredKeyword, HighlightRegionType.KEYWORD);
+
+    computer._addRegion_token(
+      node.name,
+      node.declaredElement!.type is DynamicType
+          ? HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION
+          : HighlightRegionType.PARAMETER_DECLARATION,
+    );
+
     super.visitSimpleFormalParameter(node);
   }
 
   @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
-    final parent = node.parent;
-    // ignore: deprecated_member_use
-    if (parent is ConstructorDeclaration && parent.name == node) {
-      return;
-    }
-
     computer._addIdentifierRegion(node);
     super.visitSimpleIdentifier(node);
   }
@@ -1202,6 +1298,14 @@
   void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
     computer._addRegion_token(
         node.externalKeyword, HighlightRegionType.BUILT_IN);
+
+    for (final variable in node.variables.variables) {
+      computer._addRegion_token(
+        variable.name,
+        HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION,
+      );
+    }
+
     super.visitTopLevelVariableDeclaration(node);
   }
 
@@ -1215,6 +1319,12 @@
   }
 
   @override
+  void visitTypeParameter(TypeParameter node) {
+    computer._addRegion_token(node.name, HighlightRegionType.TYPE_PARAMETER);
+    super.visitTypeParameter(node);
+  }
+
+  @override
   void visitVariableDeclarationList(VariableDeclarationList node) {
     computer._addRegion_token(node.lateKeyword, HighlightRegionType.KEYWORD);
     computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
@@ -1222,6 +1332,21 @@
   }
 
   @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    for (final variable in node.variables.variables) {
+      final element = variable.declaredElement as LocalVariableElement;
+      computer._addRegion_token(
+        variable.name,
+        element.type is DynamicType
+            ? HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION
+            : HighlightRegionType.LOCAL_VARIABLE_DECLARATION,
+      );
+    }
+
+    super.visitVariableDeclarationStatement(node);
+  }
+
+  @override
   void visitWhileStatement(WhileStatement node) {
     computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD,
         semanticTokenModifiers: {CustomSemanticTokenModifiers.control});
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index bba7cc4..c2c341e 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/computer/computer_overrides.dart';
 import 'package:analysis_server/src/utilities/extensions/ast.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/element_locator.dart';
@@ -29,6 +30,25 @@
     if (node == null) {
       return null;
     }
+
+    SyntacticEntity? locationEntity;
+    if (node is NamedCompilationUnitMember) {
+      locationEntity = node.name;
+    } else if (node is Expression) {
+      locationEntity = node;
+    } else if (node is ExtensionDeclaration) {
+      locationEntity = node.name;
+    } else if (node is FormalParameter) {
+      locationEntity = node.name;
+    } else if (node is MethodDeclaration) {
+      locationEntity = node.name;
+    } else if (node is VariableDeclaration) {
+      locationEntity = node.name;
+    }
+    if (locationEntity == null) {
+      return null;
+    }
+
     var parent = node.parent;
     var grandParent = parent?.parent;
     if (parent is NamedType &&
@@ -39,19 +59,23 @@
         grandParent is InstanceCreationExpression) {
       node = grandParent;
     }
-    if (node is Expression) {
-      var expression = node;
+    if (node != null &&
+        (node is CompilationUnitMember ||
+            node is Expression ||
+            node is FormalParameter ||
+            node is MethodDeclaration ||
+            node is VariableDeclaration)) {
       // For constructor calls the whole expression is selected (above) but this
       // results in the range covering the whole call so narrow it to just the
       // ConstructorName.
-      var hover = expression is InstanceCreationExpression
+      var hover = node is InstanceCreationExpression
           ? HoverInformation(
-              expression.constructorName.offset,
-              expression.constructorName.length,
+              node.constructorName.offset,
+              node.constructorName.length,
             )
-          : HoverInformation(expression.offset, expression.length);
+          : HoverInformation(locationEntity.offset, locationEntity.length);
       // element
-      var element = ElementLocator.locate(expression);
+      var element = ElementLocator.locate(node);
       if (element != null) {
         // variable, if synthetic accessor
         if (element is PropertyAccessorElement) {
@@ -71,9 +95,10 @@
         hover.elementKind = element.kind.displayName;
         hover.isDeprecated = element.hasDeprecated;
         // not local element
-        if (element.enclosingElement3 is! ExecutableElement) {
+        if (element.enclosingElement is! ExecutableElement) {
           // containing class
-          var containingClass = element.thisOrAncestorOfType<ClassElement>();
+          var containingClass =
+              element.thisOrAncestorOfType<InterfaceElement>();
           if (containingClass != null && containingClass != element) {
             hover.containingClassDescription = containingClass.displayName;
           }
@@ -105,17 +130,24 @@
         hover.dartdoc = computeDocumentation(_dartdocInfo, element)?.full;
       }
       // parameter
-      hover.parameter = _elementDisplayString(
-        expression.staticParameterElement,
-      );
+      if (node is Expression) {
+        hover.parameter = _elementDisplayString(
+          node.staticParameterElement,
+        );
+      }
       // types
       {
-        var parent = expression.parent;
+        var parent = node.parent;
         DartType? staticType;
-        if (element == null || element is VariableElement) {
-          staticType = _getTypeOfDeclarationOrReference(node);
+        if (element is VariableElement) {
+          staticType = element.type;
         }
-        if (parent is MethodInvocation && parent.methodName == expression) {
+        if (node is Expression) {
+          if (element == null || element is VariableElement) {
+            staticType = _getTypeOfDeclarationOrReference(node);
+          }
+        }
+        if (parent is MethodInvocation && parent.methodName == node) {
           staticType = parent.staticInvokeType;
           if (staticType != null && staticType.isDynamic) {
             staticType = null;
@@ -152,7 +184,7 @@
       element = element.field;
     }
     if (element is ParameterElement) {
-      element = element.enclosingElement3;
+      element = element.enclosingElement;
     }
     if (element == null) {
       // This can happen when the code is invalid, such as having a field formal
@@ -197,9 +229,9 @@
     var result =
         dartdocInfo.processDartdoc(rawDoc, includeSummary: includeSummary);
 
-    var documentedElementClass = documentedElement.enclosingElement3;
+    var documentedElementClass = documentedElement.enclosingElement;
     if (documentedElementClass != null &&
-        documentedElementClass != element.enclosingElement3) {
+        documentedElementClass != element.enclosingElement) {
       var documentedClass = documentedElementClass.displayName;
       result.full = '${result.full}\n\nCopied from `$documentedClass`.';
     }
diff --git a/pkg/analysis_server/lib/src/computer/computer_inlay_hint.dart b/pkg/analysis_server/lib/src/computer/computer_inlay_hint.dart
new file mode 100644
index 0000000..b6e7a1c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/computer/computer_inlay_hint.dart
@@ -0,0 +1,160 @@
+// Copyright (c) 2022, 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.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/utilities/extensions/ast.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/source/line_info.dart';
+
+/// A computer for LSP Inlay Hints.
+///
+/// Inlay hints are text labels used to show inferred labels such as type and
+/// argument names where they are not already explicitly present in the source
+/// but are being inferred.
+class DartInlayHintComputer {
+  final LineInfo _lineInfo;
+  final CompilationUnit _unit;
+  final bool _isNonNullableByDefault;
+  final List<InlayHint> _hints = [];
+
+  DartInlayHintComputer(ResolvedUnitResult result)
+      : _unit = result.unit,
+        _lineInfo = result.lineInfo,
+        _isNonNullableByDefault = result.unit.isNonNullableByDefault;
+
+  List<InlayHint> compute() {
+    _unit.accept(_DartInlayHintComputerVisitor(this));
+    return _hints;
+  }
+
+  /// Adds a parameter name hint before [node] showing a label for [name].
+  ///
+  /// A colon and padding will be added between the hint and [node]
+  /// automatically.
+  void _addParameterNamePrefix(SyntacticEntity nodeOrToken, String name) {
+    final offset = nodeOrToken.offset;
+    final position = toPosition(_lineInfo.getLocation(offset));
+    final labelParts = Either2<List<InlayHintLabelPart>, String>.t2('$name:');
+    _hints.add(InlayHint(
+      label: labelParts,
+      position: position,
+      kind: InlayHintKind.Parameter,
+      paddingRight: true,
+    ));
+  }
+
+  /// Adds a type hint before [node] showing a label for the type [type].
+  ///
+  /// Padding will be added between the hint and [node] automatically.
+  void _addTypePrefix(SyntacticEntity nodeOrToken, DartType type) {
+    final offset = nodeOrToken.offset;
+    final position = toPosition(_lineInfo.getLocation(offset));
+    final label =
+        type.getDisplayString(withNullability: _isNonNullableByDefault);
+    final labelParts = Either2<List<InlayHintLabelPart>, String>.t2(label);
+    _hints.add(InlayHint(
+      label: labelParts,
+      position: position,
+      kind: InlayHintKind.Type,
+      paddingRight: true,
+    ));
+  }
+}
+
+/// An AST visitor for [DartInlayHintComputer].
+class _DartInlayHintComputerVisitor extends GeneralizingAstVisitor<void> {
+  final DartInlayHintComputer _computer;
+
+  _DartInlayHintComputerVisitor(this._computer);
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    super.visitArgumentList(node);
+
+    for (final argument in node.arguments) {
+      if (argument is! NamedExpression) {
+        final parameter = argument.staticParameterElement;
+        if (parameter != null) {
+          _computer._addParameterNamePrefix(argument, parameter.name);
+        }
+      }
+    }
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    super.visitFunctionDeclaration(node);
+
+    // Has explicit type.
+    if (node.returnType != null) {
+      return;
+    }
+
+    // Don't add "void" for setters.
+    if (node.isSetter) {
+      return;
+    }
+
+    final declaration = node.declaredElement;
+    if (declaration != null) {
+      // For getters/setters, the type must come before the property keyword,
+      // not the name.
+      final token = node.propertyKeyword ?? node.name;
+      _computer._addTypePrefix(token, declaration.returnType);
+    }
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    super.visitMethodDeclaration(node);
+
+    // Has explicit type.
+    if (node.returnType != null) {
+      return;
+    }
+
+    final declaration = node.declaredElement;
+    if (declaration != null) {
+      _computer._addTypePrefix(node.name, declaration.returnType);
+    }
+  }
+
+  @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    super.visitSimpleFormalParameter(node);
+
+    // Has explicit type.
+    if (node.isExplicitlyTyped) {
+      return;
+    }
+
+    final declaration = node.declaredElement;
+    if (declaration != null) {
+      // Prefer to insert before `name` to avoid going before keywords like
+      // `required`.
+      _computer._addTypePrefix(node.name ?? node, declaration.type);
+    }
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    super.visitVariableDeclaration(node);
+
+    final parent = node.parent;
+    // Unexpected parent or has explicit type.
+    if (parent is! VariableDeclarationList || parent.type != null) {
+      return;
+    }
+
+    final declaration = node.declaredElement;
+    if (declaration != null) {
+      _computer._addTypePrefix(node, declaration.type);
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 417657f..95b8fa0 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -96,7 +96,7 @@
   }
 
   Outline _newClassOutline(ClassDeclaration node, List<Outline> classContents) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
     var element = Element(
         ElementKind.CLASS,
@@ -111,7 +111,7 @@
   }
 
   Outline _newClassTypeAlias(ClassTypeAlias node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
     var element = Element(
         ElementKind.CLASS_TYPE_ALIAS,
@@ -130,7 +130,7 @@
     var name = returnType.name;
     var offset = returnType.offset;
     var length = returnType.length;
-    var constructorNameToken = constructor.name2;
+    var constructorNameToken = constructor.name;
     var isPrivate = false;
     if (constructorNameToken != null) {
       var constructorName = constructorNameToken.lexeme;
@@ -153,7 +153,7 @@
   }
 
   Outline _newEnumConstant(EnumConstantDeclaration node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
     var element = Element(
         ElementKind.ENUM_CONSTANT,
@@ -166,7 +166,7 @@
   }
 
   Outline _newEnumOutline(EnumDeclaration node, List<Outline> children) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
     var element = Element(
         ElementKind.ENUM,
@@ -180,7 +180,7 @@
 
   Outline _newExtensionOutline(
       ExtensionDeclaration node, List<Outline> extensionContents) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken?.lexeme ?? '';
     var element = Element(
         ElementKind.EXTENSION,
@@ -197,7 +197,7 @@
 
   Outline _newFunctionOutline(FunctionDeclaration function, bool isStatic) {
     var returnType = function.returnType;
-    var nameToken = function.name2;
+    var nameToken = function.name;
     var name = nameToken.lexeme;
     var functionExpression = function.functionExpression;
     var parameters = functionExpression.parameters;
@@ -229,7 +229,7 @@
 
   Outline _newFunctionTypeAliasOutline(FunctionTypeAlias node) {
     var returnType = node.returnType;
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
     var parameters = node.parameters;
     var parametersStr = _safeToSource(parameters);
@@ -248,7 +248,7 @@
   }
 
   Outline _newGenericTypeAliasOutline(GenericTypeAlias node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
 
     var aliasedType = node.type;
@@ -280,7 +280,7 @@
 
   Outline _newMethodOutline(MethodDeclaration method) {
     var returnType = method.returnType;
-    var nameToken = method.name2;
+    var nameToken = method.name;
     var name = nameToken.lexeme;
     var parameters = method.parameters;
     ElementKind kind;
@@ -311,7 +311,7 @@
 
   Outline _newMixinOutline(MixinDeclaration node, List<Outline> mixinContents) {
     node.firstTokenAfterCommentAndMetadata;
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
     var element = Element(
         ElementKind.MIXIN,
@@ -334,7 +334,7 @@
 
   Outline _newVariableOutline(String typeName, ElementKind kind,
       VariableDeclaration variable, bool isStatic) {
-    var nameToken = variable.name2;
+    var nameToken = variable.name;
     var name = nameToken.lexeme;
     var element = Element(
         kind,
@@ -414,7 +414,7 @@
 
   /// Returns `true` if the given [element] is not `null` and deprecated.
   static bool _isDeprecated(Declaration declaration) {
-    var element = declaration.declaredElement2;
+    var element = declaration.declaredElement;
     return element != null && element.hasDeprecated;
   }
 
@@ -528,7 +528,7 @@
   /// Return `true` if the given [element] is a top-level member of the test
   /// package.
   bool _isInsideTestPackage(engine.FunctionElement element) {
-    var parent = element.enclosingElement3;
+    var parent = element.enclosingElement;
     return parent is engine.CompilationUnitElement &&
         parent.source.fullName.endsWith('test.dart');
   }
diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
index 4600f6f..ed92d77 100644
--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
@@ -11,7 +11,7 @@
 
 /// Return the elements that the given [element] overrides.
 OverriddenElements findOverriddenElements(Element element) {
-  if (element.enclosingElement3 is ClassElement) {
+  if (element.enclosingElement is InterfaceElement) {
     return _OverriddenElementsFinder(element).find();
   }
   return OverriddenElements(element, <Element>[], <Element>[]);
@@ -68,7 +68,7 @@
         if (classMember.isStatic) {
           continue;
         }
-        _addOverride(classMember.name2, classMember.declaredElement2);
+        _addOverride(classMember.name, classMember.declaredElement);
       }
       if (classMember is FieldDeclaration) {
         if (classMember.isStatic) {
@@ -76,7 +76,7 @@
         }
         List<VariableDeclaration> fields = classMember.fields.variables;
         for (var field in fields) {
-          _addOverride(field.name2, field.declaredElement2);
+          _addOverride(field.name, field.declaredElement);
         }
       }
     }
@@ -102,7 +102,7 @@
 class _OverriddenElementsFinder {
   Element _seed;
   LibraryElement _library;
-  ClassElement _class;
+  InterfaceElement _class;
   String _name;
   List<ElementKind> _kinds;
 
@@ -111,7 +111,7 @@
   final Set<InterfaceElement> _visited = {};
 
   factory _OverriddenElementsFinder(Element seed) {
-    var class_ = seed.enclosingElement3 as ClassElement;
+    var class_ = seed.enclosingElement as InterfaceElement;
     var library = class_.library;
     var name = seed.displayName;
     List<ElementKind> kinds;
@@ -164,9 +164,7 @@
       _addInterfaceOverrides(interfaceType.element2, true);
     }
     // super
-    if (class_ is ClassElement) {
-      _addInterfaceOverrides(class_.supertype?.element2, checkType);
-    }
+    _addInterfaceOverrides(class_.supertype?.element2, checkType);
   }
 
   void _addSuperOverrides(InterfaceElement? class_,
@@ -185,9 +183,7 @@
       }
     }
 
-    if (class_ is ClassElement) {
-      _addSuperOverrides(class_.supertype?.element2);
-    }
+    _addSuperOverrides(class_.supertype?.element2);
     for (var mixin_ in class_.mixins) {
       _addSuperOverrides(mixin_.element2);
     }
diff --git a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
index e1a152f..94d1951 100644
--- a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
@@ -45,6 +45,9 @@
 
     var builder = ChangeBuilder(session: libraryResult.session);
     await builder.addDartFileEdit(libraryResult.path, (builder) {
+      final quote = libraryResult
+          .session.analysisContext.analysisOptions.codeStyleOptions
+          .preferredQuoteForUris(existingImports);
       for (var importedElements in filteredImportedElements) {
         var matchingImports =
             _findMatchingImports(existingImports, importedElements);
@@ -62,9 +65,9 @@
             for (var i = 0; i < description.newLinesBefore; i++) {
               builder.writeln();
             }
-            builder.write("import '");
+            builder.write("import $quote");
             builder.write(importUri);
-            builder.write("'");
+            builder.write(quote);
             if (importedElements.prefix.isNotEmpty) {
               builder.write(' as ');
               builder.write(importedElements.prefix);
diff --git a/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart b/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart
index e500165..85352f0 100644
--- a/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart
@@ -82,7 +82,7 @@
         !_isConstructorDeclarationReturnType(node)) {
       var nodeElement = node.writeOrReadElement;
       if (nodeElement != null &&
-          nodeElement.enclosingElement3 is CompilationUnitElement) {
+          nodeElement.enclosingElement is CompilationUnitElement) {
         var nodeLibrary = nodeElement.library;
         var path = nodeLibrary?.definingCompilationUnit.source.fullName;
         if (path == null) {
diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
index adc06b9..0bdc253 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
@@ -28,12 +28,47 @@
 
   @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    _addOccurrence(node.declaredElement2!, node.name2.offset);
+    _addOccurrence(node.declaredElement!, node.name.offset);
 
     super.visitEnumConstantDeclaration(node);
   }
 
   @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    final declaredElement = node.declaredElement;
+    if (declaredElement is FieldFormalParameterElement) {
+      final field = declaredElement.field;
+      if (field != null) {
+        _addOccurrence(field, node.name.offset);
+      }
+    }
+
+    super.visitFieldFormalParameter(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    _addOccurrence(node.declaredElement!, node.name.offset);
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    _addOccurrence(node.declaredElement!, node.name.offset);
+    super.visitMethodDeclaration(node);
+  }
+
+  @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    final nameToken = node.name;
+    if (nameToken != null) {
+      _addOccurrence(node.declaredElement!, nameToken.offset);
+    }
+
+    super.visitSimpleFormalParameter(node);
+  }
+
+  @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
     var element = node.writeOrReadElement;
     if (element != null) {
@@ -42,6 +77,18 @@
     return super.visitSimpleIdentifier(node);
   }
 
+  @override
+  void visitSuperFormalParameter(SuperFormalParameter node) {
+    _addOccurrence(node.declaredElement!, node.name.offset);
+    super.visitSuperFormalParameter(node);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    _addOccurrence(node.declaredElement!, node.name.offset);
+    super.visitVariableDeclaration(node);
+  }
+
   void _addOccurrence(Element element, int offset) {
     var canonicalElement = _canonicalizeElement(element);
     if (canonicalElement == null || element == DynamicElementImpl.instance) {
diff --git a/pkg/analysis_server/lib/src/handler/legacy/search_get_element_declarations.dart b/pkg/analysis_server/lib/src/handler/legacy/search_get_element_declarations.dart
index 3e4c0fa..939df05 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/search_get_element_declarations.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/search_get_element_declarations.dart
@@ -78,11 +78,10 @@
 
     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);
-    }
+    await search.FindDeclarations(
+            analysisDrivers, workspaceSymbols, regExp, params.maxResults,
+            onlyForFile: params.file)
+        .compute();
 
     var declarations = workspaceSymbols.declarations;
     var elementDeclarations = declarations.map((declaration) {
diff --git a/pkg/analysis_server/lib/src/lsp/client_capabilities.dart b/pkg/analysis_server/lib/src/lsp/client_capabilities.dart
index 7b621b1..31bfdfb 100644
--- a/pkg/analysis_server/lib/src/lsp/client_capabilities.dart
+++ b/pkg/analysis_server/lib/src/lsp/client_capabilities.dart
@@ -81,90 +81,145 @@
   final Set<SymbolKind> workspaceSymbolKinds;
   final Set<CompletionItemKind> completionItemKinds;
   final Set<InsertTextMode> completionInsertTextModes;
+  final bool completionDefaultEditRange;
+  final bool completionDefaultTextMode;
   final bool experimentalSnippetTextEdit;
   final bool codeActionCommandParameterSupport;
 
-  LspClientCapabilities(this.raw)
-      : applyEdit = raw.workspace?.applyEdit ?? false,
-        codeActionKinds = _listToSet(raw.textDocument?.codeAction
-            ?.codeActionLiteralSupport?.codeActionKind.valueSet),
-        completionDeprecatedFlag =
-            raw.textDocument?.completion?.completionItem?.deprecatedSupport ??
-                false,
-        completionDocumentationFormats = _completionDocumentationFormats(raw),
-        completionInsertTextModes = _listToSet(raw.textDocument?.completion
-            ?.completionItem?.insertTextModeSupport?.valueSet),
-        completionItemKinds = _listToSet(
-            raw.textDocument?.completion?.completionItemKind?.valueSet,
-            defaults: defaultSupportedCompletionKinds),
-        completionSnippets =
-            raw.textDocument?.completion?.completionItem?.snippetSupport ??
-                false,
-        configuration = raw.workspace?.configuration ?? false,
-        createResourceOperations = raw
-                .workspace?.workspaceEdit?.resourceOperations
-                ?.contains(ResourceOperationKind.Create) ??
-            false,
-        renameResourceOperations = raw
-                .workspace?.workspaceEdit?.resourceOperations
-                ?.contains(ResourceOperationKind.Rename) ??
-            false,
-        definitionLocationLink =
-            raw.textDocument?.definition?.linkSupport ?? false,
-        typeDefinitionLocationLink =
-            raw.textDocument?.typeDefinition?.linkSupport ?? false,
-        completionItemTags = _listToSet(
-            raw.textDocument?.completion?.completionItem?.tagSupport?.valueSet),
-        diagnosticTags = _listToSet(
-            raw.textDocument?.publishDiagnostics?.tagSupport?.valueSet),
-        documentChanges =
-            raw.workspace?.workspaceEdit?.documentChanges ?? false,
-        documentSymbolKinds = _listToSet(
-            raw.textDocument?.documentSymbol?.symbolKind?.valueSet,
-            defaults: defaultSupportedSymbolKinds),
-        hierarchicalSymbols = raw.textDocument?.documentSymbol
-                ?.hierarchicalDocumentSymbolSupport ??
-            false,
-        diagnosticCodeDescription =
-            raw.textDocument?.publishDiagnostics?.codeDescriptionSupport ??
-                false,
-        hoverContentFormats = _hoverContentFormats(raw),
-        insertReplaceCompletionRanges = raw.textDocument?.completion
-                ?.completionItem?.insertReplaceSupport ??
-            false,
-        literalCodeActions =
-            raw.textDocument?.codeAction?.codeActionLiteralSupport != null,
-        renameValidation = raw.textDocument?.rename?.prepareSupport ?? false,
-        signatureHelpDocumentationFormats = _sigHelpDocumentationFormats(raw),
-        workDoneProgress = raw.window?.workDoneProgress ?? false,
-        workspaceSymbolKinds = _listToSet(
-            raw.workspace?.symbol?.symbolKind?.valueSet,
-            defaults: defaultSupportedSymbolKinds),
-        experimentalSnippetTextEdit =
-            raw.experimental is Map<String, Object?> &&
-                (raw.experimental as Map<String, Object?>)['snippetTextEdit'] ==
-                    true,
-        codeActionCommandParameterSupport =
-            raw.experimental is Map<String, Object?> &&
-                (raw.experimental as Map<String, Object?>)['dartCodeAction']
-                    is Map<String, Object?> &&
-                ((raw.experimental as Map<String, Object?>)['dartCodeAction']
-                        as Map<String, Object?>)['commandParameterSupport'] ==
-                    true;
+  factory LspClientCapabilities(ClientCapabilities raw) {
+    final workspace = raw.workspace;
+    final workspaceEdit = workspace?.workspaceEdit;
+    final resourceOperations = workspaceEdit?.resourceOperations;
+    final textDocument = raw.textDocument;
+    final completion = textDocument?.completion;
+    final completionItem = completion?.completionItem;
+    final completionList = completion?.completionList;
+    final completionDefaults = _listToSet(completionList?.itemDefaults);
+    final codeAction = textDocument?.codeAction;
+    final codeActionLiteral = codeAction?.codeActionLiteralSupport;
+    final documentSymbol = textDocument?.documentSymbol;
+    final publishDiagnostics = textDocument?.publishDiagnostics;
+    final signatureHelp = textDocument?.signatureHelp;
+    final signatureInformation = signatureHelp?.signatureInformation;
+    final hover = textDocument?.hover;
+    final definition = textDocument?.definition;
+    final typeDefinition = textDocument?.typeDefinition;
+    final workspaceSymbol = workspace?.symbol;
+    final experimental = _mapOrEmpty(raw.experimental);
+    final experimentalActions = _mapOrEmpty(experimental['dartCodeAction']);
 
-  static Set<MarkupKind>? _completionDocumentationFormats(
-      ClientCapabilities raw) {
-    // For formats, null is valid (which means only raw strings are supported,
-    // not [MarkupContent]).
-    return _listToNullableSet(
-        raw.textDocument?.completion?.completionItem?.documentationFormat);
+    final applyEdit = workspace?.applyEdit ?? false;
+    final codeActionKinds =
+        _listToSet(codeActionLiteral?.codeActionKind.valueSet);
+    final completionDeprecatedFlag = completionItem?.deprecatedSupport ?? false;
+    final completionDocumentationFormats =
+        _listToNullableSet(completionItem?.documentationFormat);
+    final completionInsertTextModes =
+        _listToSet(completionItem?.insertTextModeSupport?.valueSet);
+    final completionItemKinds = _listToSet(
+        completion?.completionItemKind?.valueSet,
+        defaults: defaultSupportedCompletionKinds);
+    final completionSnippets = completionItem?.snippetSupport ?? false;
+    final completionDefaultEditRange = completionDefaults.contains('editRange');
+    final completionDefaultTextMode =
+        completionDefaults.contains('insertTextMode');
+    final configuration = workspace?.configuration ?? false;
+    final createResourceOperations =
+        resourceOperations?.contains(ResourceOperationKind.Create) ?? false;
+    final renameResourceOperations =
+        resourceOperations?.contains(ResourceOperationKind.Rename) ?? false;
+    final definitionLocationLink = definition?.linkSupport ?? false;
+    final typeDefinitionLocationLink = typeDefinition?.linkSupport ?? false;
+    final completionItemTags = _listToSet(completionItem?.tagSupport?.valueSet);
+    final diagnosticTags = _listToSet(publishDiagnostics?.tagSupport?.valueSet);
+    final documentChanges = workspaceEdit?.documentChanges ?? false;
+    final documentSymbolKinds = _listToSet(documentSymbol?.symbolKind?.valueSet,
+        defaults: defaultSupportedSymbolKinds);
+    final hierarchicalSymbols =
+        documentSymbol?.hierarchicalDocumentSymbolSupport ?? false;
+    final diagnosticCodeDescription =
+        publishDiagnostics?.codeDescriptionSupport ?? false;
+    final hoverContentFormats = _listToNullableSet(hover?.contentFormat);
+    final insertReplaceCompletionRanges =
+        completionItem?.insertReplaceSupport ?? false;
+    final literalCodeActions = codeActionLiteral != null;
+    final renameValidation = textDocument?.rename?.prepareSupport ?? false;
+    final signatureHelpDocumentationFormats =
+        _listToNullableSet(signatureInformation?.documentationFormat);
+    final workDoneProgress = raw.window?.workDoneProgress ?? false;
+    final workspaceSymbolKinds = _listToSet(
+        workspaceSymbol?.symbolKind?.valueSet,
+        defaults: defaultSupportedSymbolKinds);
+    final experimentalSnippetTextEdit = experimental['snippetTextEdit'] == true;
+    final codeActionCommandParameterSupport =
+        experimentalActions['commandParameterSupport'] == true;
+
+    return LspClientCapabilities._(
+      raw,
+      documentChanges: documentChanges,
+      configuration: configuration,
+      createResourceOperations: createResourceOperations,
+      renameResourceOperations: renameResourceOperations,
+      completionDeprecatedFlag: completionDeprecatedFlag,
+      applyEdit: applyEdit,
+      workDoneProgress: workDoneProgress,
+      completionSnippets: completionSnippets,
+      renameValidation: renameValidation,
+      literalCodeActions: literalCodeActions,
+      insertReplaceCompletionRanges: insertReplaceCompletionRanges,
+      definitionLocationLink: definitionLocationLink,
+      typeDefinitionLocationLink: typeDefinitionLocationLink,
+      hierarchicalSymbols: hierarchicalSymbols,
+      diagnosticCodeDescription: diagnosticCodeDescription,
+      codeActionKinds: codeActionKinds,
+      completionItemTags: completionItemTags,
+      diagnosticTags: diagnosticTags,
+      completionDocumentationFormats: completionDocumentationFormats,
+      signatureHelpDocumentationFormats: signatureHelpDocumentationFormats,
+      hoverContentFormats: hoverContentFormats,
+      documentSymbolKinds: documentSymbolKinds,
+      workspaceSymbolKinds: workspaceSymbolKinds,
+      completionItemKinds: completionItemKinds,
+      completionInsertTextModes: completionInsertTextModes,
+      completionDefaultEditRange: completionDefaultEditRange,
+      completionDefaultTextMode: completionDefaultTextMode,
+      experimentalSnippetTextEdit: experimentalSnippetTextEdit,
+      codeActionCommandParameterSupport: codeActionCommandParameterSupport,
+    );
   }
 
-  static Set<MarkupKind>? _hoverContentFormats(ClientCapabilities raw) {
-    // For formats, null is valid (which means only raw strings are supported,
-    // not [MarkupContent]), so use null as default.
-    return _listToNullableSet(raw.textDocument?.hover?.contentFormat);
-  }
+  LspClientCapabilities._(
+    this.raw, {
+    required this.documentChanges,
+    required this.configuration,
+    required this.createResourceOperations,
+    required this.renameResourceOperations,
+    required this.completionDeprecatedFlag,
+    required this.applyEdit,
+    required this.workDoneProgress,
+    required this.completionSnippets,
+    required this.renameValidation,
+    required this.literalCodeActions,
+    required this.insertReplaceCompletionRanges,
+    required this.definitionLocationLink,
+    required this.typeDefinitionLocationLink,
+    required this.hierarchicalSymbols,
+    required this.diagnosticCodeDescription,
+    required this.codeActionKinds,
+    required this.completionItemTags,
+    required this.diagnosticTags,
+    required this.completionDocumentationFormats,
+    required this.signatureHelpDocumentationFormats,
+    required this.hoverContentFormats,
+    required this.documentSymbolKinds,
+    required this.workspaceSymbolKinds,
+    required this.completionItemKinds,
+    required this.completionInsertTextModes,
+    required this.completionDefaultEditRange,
+    required this.completionDefaultTextMode,
+    required this.experimentalSnippetTextEdit,
+    required this.codeActionCommandParameterSupport,
+  });
 
   /// Converts a list to a `Set`, returning null if the list is null.
   static Set<T>? _listToNullableSet<T>(List<T>? items) {
@@ -178,10 +233,7 @@
     return items != null ? {...items} : defaults;
   }
 
-  static Set<MarkupKind>? _sigHelpDocumentationFormats(ClientCapabilities raw) {
-    // For formats, null is valid (which means only raw strings are supported,
-    // not [MarkupContent]), so use null as default.
-    return _listToNullableSet(raw.textDocument?.signatureHelp
-        ?.signatureInformation?.documentationFormat);
+  static Map<String, Object?> _mapOrEmpty(Object? item) {
+    return item is Map<String, Object?> ? item : const {};
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/client_configuration.dart b/pkg/analysis_server/lib/src/lsp/client_configuration.dart
index 26ba811..1b3ed6b 100644
--- a/pkg/analysis_server/lib/src/lsp/client_configuration.dart
+++ b/pkg/analysis_server/lib/src/lsp/client_configuration.dart
@@ -10,6 +10,13 @@
 /// Resource-specific config is currently only supported at the WorkspaceFolder
 /// level so when looking up config for a resource, the nearest WorkspaceFolders
 /// config will be used.
+///
+/// Settings prefixed with 'preview' are things that may not be completed but
+/// may be exposed to users as something they can try out.
+///
+/// Settings prefixed with 'experimental' are things that may be incomplete or
+/// still in development and users are not encouraged to try (but may be useful
+/// for Dart developers to enable for development/testing).
 class LspClientConfiguration {
   /// Global settings for the workspace.
   ///
@@ -117,6 +124,10 @@
   bool get completeFunctionCalls =>
       _settings['completeFunctionCalls'] as bool? ?? false;
 
+  /// A hidden experimental flag for enabling new refactors during development.
+  bool get experimentalNewRefactors =>
+      _settings['experimentalNewRefactors'] as bool? ?? false;
+
   /// A preview flag for enabling commit characters for completions.
   ///
   /// This is a temporary setting to allow this feature to be tested without
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index 2bcebf6..c26af22 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/lsp_protocol/protocol.dart';
+import 'package:analysis_server/src/services/refactoring/framework/refactoring_processor.dart';
 
 /// The characters that will cause the editor to automatically commit the selected
 /// completion item.
@@ -54,12 +55,14 @@
   /// A list of all commands IDs that can be sent to the client to inform which
   /// commands should be sent to the server for execution (as opposed to being
   /// executed in the local plugin).
-  static const serverSupportedCommands = [
+  static final serverSupportedCommands = [
     sortMembers,
     organizeImports,
     fixAll,
     sendWorkspaceEdit,
     performRefactor,
+    // Add commands for each of the new refactorings.
+    ...RefactoringProcessor.generators.keys,
   ];
   static const sortMembers = 'edit.sortMembers';
   static const organizeImports = 'edit.organizeImports';
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 57dae65..56ee9ab 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
@@ -33,6 +33,10 @@
       final refactoring = await getRefactoring(
           RefactoringKind(kind), result, offset, length, options);
       return refactoring.mapResult((refactoring) async {
+        // Don't include potential edits in refactorings until there is some UI
+        // for the user to control this.
+        refactoring.includePotential = false;
+
         // If the token we were given is not cancelable, wrap it with one that
         // is for the rest of this request as a future refactor may need to
         // cancel this request.
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/refactor_command_handler.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/refactor_command_handler.dart
index 2646ea9..2b01e47 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/refactor_command_handler.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/refactor_command_handler.dart
@@ -40,7 +40,7 @@
               'filePath: String, '
               'offset: int, '
               'length: int, '
-              'arguments: List<String>'));
+              'arguments: List'));
     }
 
     final clientCapabilities = server.clientCapabilities;
@@ -77,27 +77,20 @@
         }
         final docIdentifier = server.getVersionedDocumentIdentifier(path);
         fileEdits.add(FileEditInformation(
-            docIdentifier, fileResult.lineInfo, edit.edits));
+            docIdentifier, fileResult.lineInfo, edit.edits,
+            newFile: edit.fileStamp == -1));
       }
       final workspaceEdit = toWorkspaceEdit(clientCapabilities, fileEdits);
       return sendWorkspaceEditToClient(workspaceEdit);
     });
   }
 
-  /// If the [arguments] is a list whose elements are all strings, then return
-  /// them. Otherwise, return `null` to indicate that they aren't what we were
-  /// expecting.
-  List<String>? _validateArguments(Object? arguments) {
+  /// If the [arguments] is a list, then return it. Otherwise, return `null`
+  /// to indicate that they aren't what we were expecting.
+  List<Object?>? _validateArguments(Object? arguments) {
     if (arguments is! List<Object?>) {
       return null;
     }
-    var result = <String>[];
-    for (var element in arguments) {
-      if (element is! String) {
-        return null;
-      }
-      result.add(element);
-    }
-    return result;
+    return arguments;
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
index 467039d..707c27c 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
@@ -44,7 +44,17 @@
     final lineInfo = unit.lineInfo;
     final workspaceEdit = toWorkspaceEdit(
       clientCapabilities,
-      [FileEditInformation(docIdentifier, lineInfo, edits)],
+      [
+        FileEditInformation(
+          docIdentifier,
+          lineInfo,
+          edits,
+          // New files are not supported from raw source edits. This is used
+          // only for Organize Imports / Sort Members which do not produce new
+          // files.
+          newFile: false,
+        )
+      ],
     );
 
     return sendWorkspaceEditToClient(workspaceEdit);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart
index b9b0cd9..9533e5f 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/search/type_hierarchy.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:collection/collection.dart';
 
 class SuperHandler
@@ -32,7 +33,7 @@
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
 
     return offset.mapResult((offset) async {
-      var node = await server.getNodeAtOffset(path.result, offset);
+      var node = NodeLocator(offset).searchWithin(unit.result.unit);
       if (node == null) {
         return success(null);
       }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_call_hierarchy.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_call_hierarchy.dart
index 725ea58..3328059 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_call_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_call_hierarchy.dart
@@ -244,7 +244,7 @@
     }
 
     final pos = item.selectionRange.start;
-    final path = pathOfUri(Uri.parse(item.uri));
+    final path = pathOfUri(item.uri);
     final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
     return offset.mapResult((offset) async {
@@ -373,7 +373,7 @@
       name: item.displayName,
       detail: item.containerName,
       kind: toSymbolKind(supportedSymbolKinds, item.kind),
-      uri: Uri.file(item.file).toString(),
+      uri: Uri.file(item.file),
       range: sourceRangeToRange(lineInfo, item.codeRange),
       selectionRange: sourceRangeToRange(lineInfo, item.nameRange),
     );
@@ -399,7 +399,7 @@
       displayName: item.name,
       containerName: item.detail,
       kind: fromSymbolKind(item.kind),
-      file: Uri.parse(item.uri).toFilePath(),
+      file: item.uri.toFilePath(),
       nameRange: nameRange.result,
       codeRange: codeRange.result,
     );
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_change_workspace_folders.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_change_workspace_folders.dart
index d1dc6f9..6591186 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_change_workspace_folders.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_change_workspace_folders.dart
@@ -41,6 +41,6 @@
   /// Return the result of converting the list of workspace [folders] to file
   /// paths.
   List<String> _convertWorkspaceFolders(List<WorkspaceFolder> folders) {
-    return folders.map((wf) => Uri.parse(wf.uri).toFilePath()).toList();
+    return folders.map((wf) => wf.uri.toFilePath()).toList();
   }
 }
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 e11e588..2a0df50 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
@@ -13,6 +13,8 @@
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analysis_server/src/services/refactoring/framework/refactoring_context.dart';
+import 'package:analysis_server/src/services/refactoring/framework/refactoring_processor.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/refactoring.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart'
@@ -564,6 +566,19 @@
     try {
       final refactorActions = <Either2<CodeAction, Command>>[];
 
+      // New refactors.
+      if (server.clientConfiguration.global.experimentalNewRefactors) {
+        final context = RefactoringContext(
+          server: server,
+          resolvedResult: unit,
+          selectionOffset: offset,
+          selectionLength: length,
+        );
+        final processor = RefactoringProcessor(context);
+        final actions = await processor.compute();
+        refactorActions.addAll(actions.map(Either2<CodeAction, Command>.t1));
+      }
+
       // Extracts
       if (shouldIncludeKind(CodeActionKind.RefactorExtract)) {
         // Extract Method
@@ -610,6 +625,7 @@
       if (shouldIncludeKind(CodeActionKind.RefactorRewrite)) {
         final node = NodeLocator(offset).searchWithin(unit.unit);
         final element = server.getElementOfNode(node);
+
         // Getter to Method
         if (element is PropertyAccessorElement &&
             ConvertGetterToMethodRefactoring(
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 db6bbe5..3baf17f 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -202,10 +202,11 @@
     if (serverResults.isError) return failure(serverResults);
     if (pluginResults.isError) return failure(pluginResults);
 
-    final untruncatedRankedItems = serverResults.result.rankedItems
+    final serverResult = serverResults.result;
+    final untruncatedRankedItems = serverResult.rankedItems
         .followedBy(pluginResults.result.items)
         .toList();
-    final unrankedItems = serverResults.result.unrankedItems;
+    final unrankedItems = serverResult.unrankedItems;
 
     // Truncate ranked items allowing for all unranked items.
     final maxRankedItems = math.max(maxResults - unrankedItems.length, 0);
@@ -213,7 +214,7 @@
         ? untruncatedRankedItems
         : _truncateResults(
             untruncatedRankedItems,
-            serverResults.result.targetPrefix,
+            serverResult.targetPrefix,
             maxRankedItems,
           );
 
@@ -227,13 +228,59 @@
     return success(CompletionList(
       // If any set of the results is incomplete, the whole batch must be
       // marked as such.
-      isIncomplete: serverResults.result.isIncomplete ||
+      isIncomplete: serverResult.isIncomplete ||
           pluginResults.result.isIncomplete ||
           truncatedRankedItems.length != untruncatedRankedItems.length,
       items: truncatedItems,
+      itemDefaults: serverResult.defaults,
     ));
   }
 
+  /// Computes all supported defaults for completion items based on
+  /// [capabilities].
+  CompletionListItemDefaults? _computeCompletionDefaults(
+    LspClientCapabilities capabilities,
+    Range insertionRange,
+    Range replacementRange,
+  ) {
+    // None of the items we use are set.
+    if (!capabilities.completionDefaultEditRange &&
+        !capabilities.completionDefaultTextMode) {
+      return null;
+    }
+
+    return CompletionListItemDefaults(
+      insertTextMode:
+          capabilities.completionDefaultTextMode ? InsertTextMode.asIs : null,
+      editRange: _computeDefaultEditRange(
+          capabilities, insertionRange, replacementRange),
+    );
+  }
+
+  /// Computes the default completion edit range based on [capabilities] and
+  /// whether the insert/replacement ranges differ.
+  Either2<CompletionItemEditRange, Range>? _computeDefaultEditRange(
+    LspClientCapabilities capabilities,
+    Range insertionRange,
+    Range replacementRange,
+  ) {
+    if (!capabilities.completionDefaultEditRange) {
+      return null;
+    }
+
+    if (!capabilities.insertReplaceCompletionRanges ||
+        insertionRange == replacementRange) {
+      return Either2<CompletionItemEditRange, Range>.t2(replacementRange);
+    } else {
+      return Either2<CompletionItemEditRange, Range>.t1(
+        CompletionItemEditRange(
+          insert: insertionRange,
+          replace: replacementRange,
+        ),
+      );
+    }
+  }
+
   /// The insert length is the shorter of the replacementLength or the
   /// difference between the replacementOffset and the caret position.
   int _computeInsertLength(
@@ -355,10 +402,12 @@
             .toList();
       });
 
+      final replacementOffset = completionRequest.replacementOffset;
+      final replacementLength = completionRequest.replacementLength;
       final insertLength = _computeInsertLength(
         offset,
-        completionRequest.replacementOffset,
-        completionRequest.replacementLength,
+        replacementOffset,
+        replacementLength,
       );
 
       if (token.isCancellationRequested) {
@@ -372,6 +421,14 @@
           ? false
           : server.clientConfiguration.global.completeFunctionCalls;
 
+      // Compute defaults that will allow us to reduce payload size.
+      final defaultReplacementRange =
+          toRange(unit.lineInfo, replacementOffset, replacementLength);
+      final defaultInsertionRange =
+          toRange(unit.lineInfo, replacementOffset, insertLength);
+      final defaults = _computeCompletionDefaults(
+          capabilities, defaultInsertionRange, defaultReplacementRange);
+
       /// Helper to convert [CompletionSuggestions] to [CompletionItem].
       CompletionItem suggestionToCompletionItem(CompletionSuggestion item) {
         var itemReplacementOffset =
@@ -387,9 +444,9 @@
         }
 
         // Convert to LSP ranges using the LineInfo.
-        var replacementRange = toRange(
+        final replacementRange = toRange(
             unit.lineInfo, itemReplacementOffset, itemReplacementLength);
-        var insertionRange =
+        final insertionRange =
             toRange(unit.lineInfo, itemReplacementOffset, itemInsertLength);
 
         // For not-imported items, we need to include the file+uri to be able
@@ -410,6 +467,10 @@
           capabilities,
           unit.lineInfo,
           item,
+          hasDefaultTextMode: defaults?.insertTextMode != null,
+          hasDefaultEditRange: defaults?.editRange != null &&
+              insertionRange == defaultInsertionRange &&
+              replacementRange == defaultReplacementRange,
           replacementRange: replacementRange,
           insertionRange: insertionRange,
           commitCharactersEnabled:
@@ -474,10 +535,12 @@
           rankedResults.length + unrankedResults.length;
 
       return success(_CompletionResults(
-          isIncomplete: isIncomplete,
-          targetPrefix: targetPrefix,
-          rankedItems: rankedResults,
-          unrankedItems: unrankedResults));
+        isIncomplete: isIncomplete,
+        targetPrefix: targetPrefix,
+        rankedItems: rankedResults,
+        unrankedItems: unrankedResults,
+        defaults: defaults,
+      ));
     } on AbortCompletion {
       return success(_CompletionResults.emptyIncomplete());
     } on InconsistentAnalysisException {
@@ -701,11 +764,17 @@
 
   final bool isIncomplete;
 
+  /// Item defaults for completion items.
+  ///
+  /// Defaults are only supported on Dart server items (not plugins).
+  final CompletionListItemDefaults? defaults;
+
   _CompletionResults({
     this.rankedItems = const [],
     this.unrankedItems = const [],
     required this.targetPrefix,
     required this.isIncomplete,
+    this.defaults,
   });
 
   _CompletionResults.empty() : this(targetPrefix: '', isIncomplete: false);
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 87a6347..de5bf4e 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
@@ -73,15 +73,6 @@
           return cancelled();
         }
 
-        final element = await _getElement(session, libraryUri, item);
-        if (element == null) {
-          return error(
-            ErrorCodes.InvalidParams,
-            'No such element: ${item.label} in $libraryUri',
-            item.label,
-          );
-        }
-
         if (token.isCancellationRequested) {
           return cancelled();
         }
@@ -115,15 +106,20 @@
               ]);
         }
 
-        final formats = clientCapabilities.completionDocumentationFormats;
-        final dartDocInfo = server.getDartdocDirectiveInfoForSession(session);
-        final dartDocData =
-            DartUnitHoverComputer.computeDocumentation(dartDocInfo, element);
-        final dartDoc = dartDocData?.full;
-        // `dartDoc` can be both null or empty.
-        final documentation = dartDoc != null && dartDoc.isNotEmpty
-            ? asMarkupContentOrString(formats, dartDoc)
-            : null;
+        // Look up documentation if we can get an element for this item.
+        Either2<MarkupContent, String>? documentation;
+        final element = await _getElement(session, libraryUri, item);
+        if (element != null) {
+          final formats = clientCapabilities.completionDocumentationFormats;
+          final dartDocInfo = server.getDartdocDirectiveInfoForSession(session);
+          final dartDocData =
+              DartUnitHoverComputer.computeDocumentation(dartDocInfo, element);
+          final dartDoc = dartDocData?.full;
+          // `dartDoc` can be both null or empty.
+          documentation = dartDoc != null && dartDoc.isNotEmpty
+              ? asMarkupContentOrString(formats, dartDoc)
+              : null;
+        }
 
         // If the only URI we have is a file:// URI, display it as relative to
         // the file we're importing into, rather than the full URI.
@@ -250,8 +246,9 @@
     }
 
     // TODO(dantup): This is not handling default constructors or enums
-    // correctly, so they will both show dart docs from the class/enum and not
-    // the constructor/enum member.
+    //  correctly, so they will both show dart docs from the class/enum and not
+    //  the constructor/enum member. Extension members are not found at all and
+    //  will provide no docs.
 
     final result = await session.getLibraryByUri(libraryUri.toString());
     return result is LibraryElementResult
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
index 530a30f..0e4fe4d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
@@ -151,9 +151,9 @@
   /// line/location) generically, handling either type of Location class.
   List<T> _filterResults<T>(
     List<T> results,
-    String sourceUri,
+    Uri sourceUri,
     int sourceLineNumber,
-    String Function(T) uriSelector,
+    Uri Function(T) uriSelector,
     Range Function(T) rangeSelector,
   ) {
     // If we fetch navigation on a keyword like `var`, the results will include
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
index e5958a2..fc64b39 100644
--- 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
@@ -63,7 +63,7 @@
   Future<ColorPresentation> _createColorPresentation(
     ResolvedUnitResult unit,
     SourceRange editRange,
-    ClassElement colorType,
+    InterfaceElement colorType,
     String label,
     String invocationString,
   ) async {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
index 4f0a96c..ce05d15 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
@@ -65,7 +65,7 @@
   SymbolInformation? _asSymbolInformation(
     String? containerName,
     Set<SymbolKind> supportedKinds,
-    String documentUri,
+    Uri documentUri,
     LineInfo lineInfo,
     Outline outline,
   ) {
@@ -112,7 +112,7 @@
     } else {
       // Otherwise, we need to use the original flat SymbolInformation.
       final allSymbols = <SymbolInformation>[];
-      final documentUri = Uri.file(path).toString();
+      final documentUri = Uri.file(path);
 
       // Adds a symbol and it's children recursively, supplying the parent
       // name as required by SymbolInformation.
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
index 30ca65f..a977b84 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
@@ -62,7 +62,9 @@
         ..writeln('```');
     }
     if (staticType != null) {
-      content.writeln('Type: `$staticType`');
+      content
+        ..writeln('Type: `$staticType`')
+        ..writeln();
     }
 
     // Source library.
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.dart
index 923248d..23f762d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.dart
@@ -8,6 +8,8 @@
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/search/type_hierarchy.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:collection/collection.dart';
 
 class ImplementationHandler
@@ -32,12 +34,13 @@
     final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
     return offset
-        .mapResult((offset) => _getImplementations(path.result, offset, token));
+        .mapResult((offset) => _getImplementations(unit.result, offset, token));
   }
 
   Future<ErrorOr<List<Location>>> _getImplementations(
-      String file, int offset, CancellationToken token) async {
-    final element = await server.getElementAtOffset(file, offset);
+      ResolvedUnitResult result, int offset, CancellationToken token) async {
+    final node = NodeLocator(offset).searchWithin(result.unit);
+    final element = server.getElementOfNode(node);
     if (element == null) {
       return success([]);
     }
@@ -93,7 +96,7 @@
           }
 
           return Location(
-            uri: Uri.file(elementLocation.file).toString(),
+            uri: Uri.file(elementLocation.file),
             range: toRange(
                 lineInfo, elementLocation.offset, elementLocation.length),
           );
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
index de5f0da..4914ad4 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
@@ -39,7 +39,7 @@
     if (!server.initializationOptions.onlyAnalyzeProjectsWithOpenFiles) {
       if (workspaceFolders != null) {
         for (var wf in workspaceFolders) {
-          final uri = Uri.parse(wf.uri);
+          final uri = wf.uri;
           // Only file URIs are supported, but there's no way to signal this to
           // the LSP client (and certainly not before initialization).
           if (uri.isScheme('file')) {
@@ -48,9 +48,8 @@
         }
       }
       if (rootUri != null) {
-        final uri = Uri.parse(rootUri);
-        if (uri.isScheme('file')) {
-          workspacePaths.add(uri.toFilePath());
+        if (rootUri.isScheme('file')) {
+          workspacePaths.add(rootUri.toFilePath());
         }
       } else if (rootPath != null) {
         workspacePaths.add(rootPath);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_inlay_hint.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_inlay_hint.dart
new file mode 100644
index 0000000..f97dfb8
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_inlay_hint.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2022, 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.dart';
+import 'package:analysis_server/src/computer/computer_inlay_hint.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+
+class InlayHintHandler
+    extends MessageHandler<InlayHintParams, List<InlayHint>> {
+  InlayHintHandler(super.server);
+  @override
+  Method get handlesMessage => Method.textDocument_inlayHint;
+
+  @override
+  LspJsonHandler<InlayHintParams> get jsonHandler =>
+      InlayHintParams.jsonHandler;
+
+  @override
+  Future<ErrorOr<List<InlayHint>>> handle(InlayHintParams params,
+      MessageInfo message, CancellationToken token) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success([]);
+    }
+
+    final path = pathOfDoc(params.textDocument);
+
+    // It's particularly important to provide results consistent with the
+    // document in the client in this handler to avoid inlay hints "jumping
+    // around" while the user types, so ensure no other requests (content
+    // updates) are processed while we do async work to get the resolved unit.
+    late ErrorOr<ResolvedUnitResult> result;
+    await server.lockRequestsWhile(() async {
+      result = await path.mapResult(requireResolvedUnit);
+    });
+
+    if (token.isCancellationRequested) {
+      return cancelled();
+    }
+
+    return result.mapResult((result) async {
+      if (!result.exists) {
+        return success([]);
+      }
+
+      final computer = DartInlayHintComputer(result);
+      final hints = computer.compute();
+
+      return success(hints);
+    });
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
index 42bf37e..dd41a088 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
 import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
 import 'package:collection/collection.dart';
@@ -38,7 +39,7 @@
     final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
     return offset.mapResult(
-        (offset) => _getReferences(path.result, offset, params, unit.result));
+        (offset) => _getReferences(unit.result, offset, params, unit.result));
   }
 
   List<Location> _getDeclarations(CompilationUnit unit, int offset) {
@@ -54,9 +55,10 @@
     }).whereNotNull().toList();
   }
 
-  Future<ErrorOr<List<Location>?>> _getReferences(String path, int offset,
-      ReferenceParams params, ResolvedUnitResult unit) async {
-    var element = await server.getElementAtOffset(path, offset);
+  Future<ErrorOr<List<Location>?>> _getReferences(ResolvedUnitResult result,
+      int offset, ReferenceParams params, ResolvedUnitResult unit) async {
+    final node = NodeLocator(offset).searchWithin(result.unit);
+    var element = server.getElementOfNode(node);
     if (element is LibraryImportElement) {
       element = element.prefix?.element;
     }
@@ -80,7 +82,7 @@
         return null;
       }
       return Location(
-        uri: Uri.file(result.file).toString(),
+        uri: Uri.file(result.file),
         range: toRange(
           file.lineInfo,
           result.sourceRange.offset,
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
index 8c57881..840216e 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/src/services/refactoring/legacy/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename_unit_member.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 
 class PrepareRenameHandler extends MessageHandler<TextDocumentPositionParams,
     TextDocumentPrepareRenameResult> {
@@ -36,7 +37,7 @@
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
 
     return offset.mapResult((offset) async {
-      final node = await server.getNodeAtOffset(path.result, offset);
+      final node = NodeLocator(offset).searchWithin(unit.result.unit);
       final element = server.getElementOfNode(node);
       if (node == null || element == null) {
         return success(null);
@@ -124,7 +125,7 @@
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
 
     return offset.mapResult((offset) async {
-      final node = await server.getNodeAtOffset(path.result, offset);
+      final node = NodeLocator(offset).searchWithin(unit.result.unit);
       final element = server.getElementOfNode(node);
       if (node == null || element == null) {
         return success(null);
@@ -192,6 +193,13 @@
       }
 
       // Compute the actual change.
+      // Don't include potential edits while we don't have a way for the user
+      // to opt-in/out.
+      // https://github.com/Dart-Code/Dart-Code/issues/4131.
+      // TODO(dantup): Check whether LSP's annotated edits would allow us to
+      //  send potential edits in their own group that can be easily toggled by
+      //  the user.
+      refactoring.includePotential = false;
       final change = await refactoring.createChange();
       if (token.isCancellationRequested) {
         return cancelled();
@@ -254,7 +262,7 @@
 
   bool _isClassRename(RenameRefactoring refactoring) =>
       refactoring is RenameUnitMemberRefactoringImpl &&
-      refactoring.element is ClassElement;
+      refactoring.element is InterfaceElement;
 
   /// Asks the user whether they would like to rename the file along with the
   /// class.
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 d19f007..94ab848 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -29,6 +29,7 @@
 import 'package:analysis_server/src/lsp/handlers/handler_implementation.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_initialize.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_initialized.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_inlay_hint.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_references.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_rename.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_select_range.dart';
@@ -110,6 +111,7 @@
     registerHandler(SelectionRangeHandler(server));
     registerHandler(SemanticTokensFullHandler(server));
     registerHandler(SemanticTokensRangeHandler(server));
+    registerHandler(InlayHintHandler(server));
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_type_definition.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_type_definition.dart
index 6f5b226..55dd492 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_type_definition.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_type_definition.dart
@@ -6,6 +6,7 @@
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/element.dart' as analyzer;
 import 'package:analyzer/dart/element/type.dart';
@@ -69,7 +70,18 @@
           return success(_emptyResult);
         }
 
-        final type = node is Expression ? _getType(node) : null;
+        final SyntacticEntity originEntity;
+        DartType? type;
+        if (node is VariableDeclaration) {
+          originEntity = node.name;
+          type = node.declaredElement?.type;
+        } else if (node is Expression) {
+          originEntity = node;
+          type = _getType(node);
+        } else {
+          return success(_emptyResult);
+        }
+
         analyzer.Element? element;
         if (type is InterfaceType) {
           element = type.element2;
@@ -96,8 +108,8 @@
 
         if (supportsLocationLink) {
           return success(TextDocumentTypeDefinitionResult.t2([
-            _toLocationLink(
-                result.lineInfo, targetLineInfo, node, element, location)
+            _toLocationLink(result.lineInfo, targetLineInfo, originEntity,
+                element, location)
           ]));
         } else {
           return success(TextDocumentTypeDefinitionResult.t1(
@@ -111,19 +123,19 @@
   /// Creates an LSP [Location] for the server [location].
   Location _toLocation(plugin.Location location, LineInfo lineInfo) {
     return Location(
-      uri: Uri.file(location.file).toString(),
+      uri: Uri.file(location.file),
       range: toRange(lineInfo, location.offset, location.length),
     );
   }
 
   /// Creates an LSP [LocationLink] for the server [targetLocation].
   ///
-  /// Uses [originLineInfo] and [originNode] to compute `originSelectionRange`
+  /// Uses [originLineInfo] and [originEntity] to compute `originSelectionRange`
   /// and [targetLineInfo] and [targetElement] for code ranges.
   LocationLink _toLocationLink(
     LineInfo originLineInfo,
     LineInfo targetLineInfo,
-    AstNode originNode,
+    SyntacticEntity originEntity,
     analyzer.ElementImpl targetElement,
     plugin.Location targetLocation,
   ) {
@@ -138,8 +150,8 @@
 
     return LocationLink(
       originSelectionRange:
-          toRange(originLineInfo, originNode.offset, originNode.length),
-      targetUri: Uri.file(targetLocation.file).toString(),
+          toRange(originLineInfo, originEntity.offset, originEntity.length),
+      targetUri: Uri.file(targetLocation.file),
       targetRange: codeRange,
       targetSelectionRange: nameRange,
     );
@@ -150,7 +162,7 @@
   static DartType? _getType(Expression node) {
     if (node is SimpleIdentifier) {
       final element = node.staticElement;
-      if (element is ClassElement) {
+      if (element is InterfaceElement) {
         return element.thisType;
       } else if (element is VariableElement) {
         if (node.inDeclarationContext()) {
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 83e5bb5..7f1123c 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
@@ -51,17 +51,15 @@
 
     var workspaceSymbols = search.WorkspaceSymbols();
     var analysisDrivers = server.driverMap.values.toList();
-    for (var analysisDriver in analysisDrivers) {
-      await analysisDriver.search.declarations(
-        workspaceSymbols,
-        regex,
-        remainingResults,
-        cancellationToken: token,
-      );
+    await search.FindDeclarations(
+      analysisDrivers,
+      workspaceSymbols,
+      regex,
+      remainingResults,
+    ).compute(token);
 
-      if (workspaceSymbols.cancelled) {
-        return cancelled();
-      }
+    if (workspaceSymbols.cancelled) {
+      return cancelled();
     }
 
     // Map the results to SymbolInformations and flatten the list of lists.
@@ -93,7 +91,7 @@
       declaration.codeLength,
     );
     final location = Location(
-      uri: Uri.file(filePath).toString(),
+      uri: Uri.file(filePath),
       range: range,
     );
 
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 b010076..17428de 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -308,8 +308,7 @@
   OptionalVersionedTextDocumentIdentifier getVersionedDocumentIdentifier(
       String path) {
     return OptionalVersionedTextDocumentIdentifier(
-        uri: Uri.file(path).toString(),
-        version: documentVersions[path]?.version);
+        uri: Uri.file(path), version: documentVersions[path]?.version);
   }
 
   void handleClientConnection(
@@ -552,8 +551,8 @@
   }
 
   void publishClosingLabels(String path, List<ClosingLabel> labels) {
-    final params = PublishClosingLabelsParams(
-        uri: Uri.file(path).toString(), labels: labels);
+    final params =
+        PublishClosingLabelsParams(uri: Uri.file(path), labels: labels);
     final message = NotificationMessage(
       method: CustomMethods.publishClosingLabels,
       params: params,
@@ -563,8 +562,8 @@
   }
 
   void publishDiagnostics(String path, List<Diagnostic> errors) {
-    final params = PublishDiagnosticsParams(
-        uri: Uri.file(path).toString(), diagnostics: errors);
+    final params =
+        PublishDiagnosticsParams(uri: Uri.file(path), diagnostics: errors);
     final message = NotificationMessage(
       method: Method.textDocument_publishDiagnostics,
       params: params,
@@ -574,8 +573,8 @@
   }
 
   void publishFlutterOutline(String path, FlutterOutline outline) {
-    final params = PublishFlutterOutlineParams(
-        uri: Uri.file(path).toString(), outline: outline);
+    final params =
+        PublishFlutterOutlineParams(uri: Uri.file(path), outline: outline);
     final message = NotificationMessage(
       method: CustomMethods.publishFlutterOutline,
       params: params,
@@ -585,8 +584,7 @@
   }
 
   void publishOutline(String path, Outline outline) {
-    final params =
-        PublishOutlineParams(uri: Uri.file(path).toString(), outline: outline);
+    final params = PublishOutlineParams(uri: Uri.file(path), outline: outline);
     final message = NotificationMessage(
       method: CustomMethods.publishOutline,
       params: params,
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 90a335f..553e2ad 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -93,8 +93,8 @@
       <Either4<CreateFile, DeleteFile, RenameFile, TextDocumentEdit>>[];
 
   final rename = RenameFile(
-    oldUri: Uri.file(oldPath).toString(),
-    newUri: Uri.file(newPath).toString(),
+    oldUri: Uri.file(oldPath),
+    newUri: Uri.file(newPath),
   );
 
   final renameUnion =
@@ -426,7 +426,7 @@
 
 bool isDartDocument(lsp.TextDocumentIdentifier doc) => isDartUri(doc.uri);
 
-bool isDartUri(String uri) => uri.endsWith('.dart');
+bool isDartUri(Uri uri) => uri.path.endsWith('.dart');
 
 /// Converts a [server.Location] to an [lsp.Range] by translating the
 /// offset/length using a `LineInfo`.
@@ -480,7 +480,7 @@
   server.LineInfo targetLineInfo,
 ) {
   return lsp.Location(
-    uri: Uri.file(targetFilePath).toString(),
+    uri: Uri.file(targetFilePath),
     range: toRange(targetLineInfo, target.offset, target.length),
   );
 }
@@ -501,19 +501,17 @@
 
   return lsp.LocationLink(
     originSelectionRange: toRange(regionLineInfo, region.offset, region.length),
-    targetUri: Uri.file(targetFilePath).toString(),
+    targetUri: Uri.file(targetFilePath),
     targetRange: codeRange,
     targetSelectionRange: nameRange,
   );
 }
 
 /// Returns the file system path for a TextDocumentIdentifier.
-ErrorOr<String> pathOfDoc(lsp.TextDocumentIdentifier doc) =>
-    pathOfUri(Uri.tryParse(doc.uri));
+ErrorOr<String> pathOfDoc(lsp.TextDocumentIdentifier doc) => pathOfUri(doc.uri);
 
 /// Returns the file system path for a TextDocumentItem.
-ErrorOr<String> pathOfDocItem(lsp.TextDocumentItem doc) =>
-    pathOfUri(Uri.tryParse(doc.uri));
+ErrorOr<String> pathOfDocItem(lsp.TextDocumentItem doc) => pathOfUri(doc.uri);
 
 /// Returns the file system path for a file URI.
 ErrorOr<String> pathOfUri(Uri? uri) {
@@ -597,7 +595,7 @@
     // Only include codeDescription if the client explicitly supports it
     // (a minor optimization to avoid unnecessary payload/(de)serialization).
     codeDescription: clientSupportsCodeDescription && documentationUrl != null
-        ? CodeDescription(href: documentationUrl)
+        ? CodeDescription(href: Uri.parse(documentationUrl))
         : null,
   );
 }
@@ -614,7 +612,7 @@
   }
   return lsp.DiagnosticRelatedInformation(
       location: lsp.Location(
-        uri: Uri.file(file).toString(),
+        uri: Uri.file(file),
         // TODO(dantup): Switch to using line/col information from the context
         // message once confirmed that AnalyzerConverter is not using the wrong
         // LineInfo.
@@ -872,6 +870,8 @@
   LspClientCapabilities capabilities,
   server.LineInfo lineInfo,
   server.CompletionSuggestion suggestion, {
+  bool hasDefaultEditRange = false,
+  bool hasDefaultTextMode = false,
   required Range replacementRange,
   required Range insertionRange,
   bool includeDocs = true,
@@ -984,23 +984,30 @@
     insertTextFormat: insertTextFormat != lsp.InsertTextFormat.PlainText
         ? insertTextFormat
         : null, // Defaults to PlainText if not supplied
-    insertTextMode: supportsAsIsInsertMode && isMultilineCompletion
-        ? InsertTextMode.asIs
-        : null,
-    textEdit: supportsInsertReplace && insertionRange != replacementRange
-        ? Either2<InsertReplaceEdit, TextEdit>.t1(
-            InsertReplaceEdit(
-              insert: insertionRange,
-              replace: replacementRange,
-              newText: insertText,
-            ),
-          )
-        : Either2<InsertReplaceEdit, TextEdit>.t2(
-            TextEdit(
-              range: replacementRange,
-              newText: insertText,
-            ),
-          ),
+    insertTextMode:
+        !hasDefaultTextMode && supportsAsIsInsertMode && isMultilineCompletion
+            ? InsertTextMode.asIs
+            : null,
+    // When using defaults for edit range, don't use textEdit.
+    textEdit: hasDefaultEditRange
+        ? null
+        : supportsInsertReplace && insertionRange != replacementRange
+            ? Either2<InsertReplaceEdit, TextEdit>.t1(
+                InsertReplaceEdit(
+                  insert: insertionRange,
+                  replace: replacementRange,
+                  newText: insertText,
+                ),
+              )
+            : Either2<InsertReplaceEdit, TextEdit>.t2(
+                TextEdit(
+                  range: replacementRange,
+                  newText: insertText,
+                ),
+              ),
+    // When using defaults for edit range, use textEditText.
+    textEditText:
+        hasDefaultEditRange && insertText != label ? insertText : null,
   );
 }
 
@@ -1109,7 +1116,7 @@
 
 lsp.Location toLocation(server.Location location, server.LineInfo lineInfo) =>
     lsp.Location(
-      uri: Uri.file(location.file).toString(),
+      uri: Uri.file(location.file),
       range: toRange(
         lineInfo,
         location.offset,
@@ -1369,15 +1376,15 @@
   }
 }
 
-Map<String, List<lsp.TextEdit>> toWorkspaceEditChanges(
+Map<Uri, List<lsp.TextEdit>> toWorkspaceEditChanges(
     List<FileEditInformation> edits) {
-  MapEntry<String, List<lsp.TextEdit>> createEdit(FileEditInformation file) {
+  MapEntry<Uri, List<lsp.TextEdit>> createEdit(FileEditInformation file) {
     final edits =
         file.edits.map((edit) => toTextEdit(file.lineInfo, edit)).toList();
     return MapEntry(file.doc.uri, edits);
   }
 
-  return Map<String, List<lsp.TextEdit>>.fromEntries(edits.map(createEdit));
+  return Map<Uri, List<lsp.TextEdit>>.fromEntries(edits.map(createEdit));
 }
 
 lsp.MarkupContent _asMarkup(
diff --git a/pkg/analysis_server/lib/src/lsp/notification_manager.dart b/pkg/analysis_server/lib/src/lsp/notification_manager.dart
index 46796d3..8aa5522 100644
--- a/pkg/analysis_server/lib/src/lsp/notification_manager.dart
+++ b/pkg/analysis_server/lib/src/lsp/notification_manager.dart
@@ -38,7 +38,7 @@
         .toList();
 
     final params = PublishDiagnosticsParams(
-        uri: Uri.file(filePath).toString(), diagnostics: diagnostics);
+        uri: Uri.file(filePath), diagnostics: diagnostics);
     final message = NotificationMessage(
       method: Method.textDocument_publishDiagnostics,
       params: params,
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 b25addb..789a7c0 100644
--- a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
+++ b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
@@ -26,6 +26,7 @@
     Method.textDocument_didClose,
     Method.textDocument_completion,
     Method.textDocument_hover,
+    Method.textDocument_inlayHint,
     Method.textDocument_signatureHelp,
     Method.textDocument_references,
     Method.textDocument_documentHighlight,
@@ -92,6 +93,9 @@
   bool get implementation =>
       _capabilities.textDocument?.implementation?.dynamicRegistration ?? false;
 
+  bool get inlayHints =>
+      _capabilities.textDocument?.inlayHint?.dynamicRegistration ?? false;
+
   bool get rangeFormatting =>
       _capabilities.textDocument?.rangeFormatting?.dynamicRegistration ?? false;
 
@@ -259,6 +263,11 @@
       documentRangeFormattingProvider: dynamicRegistrations.typeFormatting
           ? null
           : Either2<bool, DocumentRangeFormattingOptions>.t1(enableFormatter),
+      inlayHintProvider: dynamicRegistrations.inlayHints
+          ? null
+          : Either3<bool, InlayHintOptions, InlayHintRegistrationOptions>.t2(
+              InlayHintOptions(resolveProvider: false),
+            ),
       renameProvider: dynamicRegistrations.rename
           ? null
           : renameOptionsSupport
@@ -537,6 +546,14 @@
         range: Either2<bool, SemanticTokensOptionsRange>.t1(true),
       ),
     );
+    register(
+      dynamicRegistrations.inlayHints,
+      Method.textDocument_inlayHint,
+      InlayHintRegistrationOptions(
+        documentSelector: [dartFiles],
+        resolveProvider: false,
+      ),
+    );
 
     await _applyRegistrations(registrations);
   }
diff --git a/pkg/analysis_server/lib/src/lsp/source_edits.dart b/pkg/analysis_server/lib/src/lsp/source_edits.dart
index cea729e..6d2fc4f 100644
--- a/pkg/analysis_server/lib/src/lsp/source_edits.dart
+++ b/pkg/analysis_server/lib/src/lsp/source_edits.dart
@@ -348,10 +348,14 @@
   final int? selectionOffsetRelative;
   final int? selectionLength;
 
-  FileEditInformation(this.doc, this.lineInfo, this.edits,
-      {this.newFile = false,
-      this.selectionOffsetRelative,
-      this.selectionLength});
+  FileEditInformation(
+    this.doc,
+    this.lineInfo,
+    this.edits, {
+    required this.newFile,
+    this.selectionOffsetRelative,
+    this.selectionLength,
+  });
 }
 
 class _SourceMock implements Source {
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index 04ab624..9f94cc7 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -130,7 +130,7 @@
 String? _computeLibraryName(CompilationUnit unit) {
   for (var directive in unit.directives) {
     if (directive is LibraryDirective) {
-      return directive.name.name;
+      return directive.name2?.name;
     }
   }
   for (var directive in unit.directives) {
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index b64b933..ad1fa21 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/src/utilities/extensions/element.dart';
 import 'package:analyzer/dart/analysis/results.dart' as engine;
 import 'package:analyzer/dart/ast/ast.dart' as engine;
+import 'package:analyzer/dart/ast/token.dart' as engine;
 import 'package:analyzer/dart/element/element.dart' as engine;
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/diagnostic/diagnostic.dart' as engine;
@@ -205,6 +206,15 @@
   return _locationForArgs(unitElement, range);
 }
 
+/// Create a Location based on an [engine.AstNode].
+Location newLocation_fromToken({
+  required engine.CompilationUnitElement unitElement,
+  required engine.Token token,
+}) {
+  var range = engine.SourceRange(token.offset, token.length);
+  return _locationForArgs(unitElement, range);
+}
+
 /// Create a Location based on an [engine.CompilationUnit].
 Location newLocation_fromUnit(
     engine.CompilationUnit unit, engine.SourceRange range) {
@@ -215,7 +225,7 @@
 OverriddenMember newOverriddenMember_fromEngine(engine.Element member,
     {required bool withNullability}) {
   var element = convertElement(member, withNullability: withNullability);
-  var className = member.enclosingElement3!.displayName;
+  var className = member.enclosingElement!.displayName;
   return OverriddenMember(element, className);
 }
 
@@ -262,7 +272,7 @@
   var path = <Element>[];
 
   if (element is engine.PrefixElement) {
-    element = element.enclosingElement3.definingCompilationUnit;
+    element = element.enclosingElement.definingCompilationUnit;
   }
 
   var withNullability = element.library?.isNonNullableByDefault ?? false;
@@ -277,7 +287,7 @@
     return element;
   }
 
-  var enclosingElement = element.enclosingElement3;
+  var enclosingElement = element.enclosingElement;
   if (enclosingElement is engine.LibraryElement) {
     element = enclosingElement;
   }
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index cfa38cd..23c5bc9 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -73,6 +73,6 @@
     if (element is ConstructorElement) {
       return false;
     }
-    return element.enclosingElement3 is ClassElement;
+    return element.enclosingElement is InterfaceElement;
   }
 }
diff --git a/pkg/analysis_server/lib/src/search/type_hierarchy.dart b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
index 0ca5a6b..f5441d3 100644
--- a/pkg/analysis_server/lib/src/search/type_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
@@ -20,7 +20,7 @@
   final ElementKind _pivotKind;
   final String? _pivotName;
   late bool _pivotFieldFinal;
-  ClassElement? _pivotClass;
+  InterfaceElement? _pivotClass;
 
   final List<TypeHierarchyItem> _items = <TypeHierarchyItem>[];
   final List<InterfaceElement> _itemClassElements = [];
@@ -35,12 +35,12 @@
     Element? element = _pivotElement;
     if (_pivotElement is FieldElement) {
       _pivotFieldFinal = (_pivotElement as FieldElement).isFinal;
-      element = _pivotElement.enclosingElement3;
+      element = _pivotElement.enclosingElement;
     }
     if (_pivotElement is ExecutableElement) {
-      element = _pivotElement.enclosingElement3;
+      element = _pivotElement.enclosingElement;
     }
-    if (element is ClassElement) {
+    if (element is InterfaceElement) {
       _pivotClass = element;
     }
   }
@@ -154,7 +154,7 @@
       _itemClassElements.add(classElement);
     }
     // superclass
-    if (classElement is ClassElement) {
+    {
       var superType = classElement.supertype;
       if (superType != null) {
         item.superclass = _createSuperItem(
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 1e7784c..2903066 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
@@ -22,6 +22,7 @@
 import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/not_imported_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/override_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/record_literal_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/redirecting_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/relevance_tables.g.dart';
 import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
@@ -153,6 +154,7 @@
       LocalReferenceContributor(request, builder),
       NamedConstructorContributor(request, builder),
       if (enableOverrideContributor) OverrideContributor(request, builder),
+      RecordLiteralContributor(request, builder),
       RedirectingContributor(request, builder),
       StaticMemberContributor(request, builder),
       SuperFormalContributor(request, builder),
@@ -495,6 +497,12 @@
       return '';
     }
 
+    if (entity is Token) {
+      if (entity.end == offset && entity.isKeywordOrIdentifier) {
+        return fromToken(entity);
+      }
+    }
+
     while (entity is AstNode) {
       if (entity is SimpleIdentifier) {
         return fromToken(entity.token);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/enum_constant_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/enum_constant_constructor_contributor.dart
index b6215c3..488c5bc 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/enum_constant_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/enum_constant_constructor_contributor.dart
@@ -45,7 +45,7 @@
       return;
     }
 
-    var enumElement = enumDeclaration.declaredElement2!;
+    var enumElement = enumDeclaration.declaredElement!;
     for (var constructor in enumElement.constructors) {
       builder.suggestConstructor(
         constructor,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
index 6338419..5eb8d05 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
@@ -59,7 +59,7 @@
     }
     if (expression is Identifier) {
       var elem = expression.staticElement;
-      if (elem is ClassElement) {
+      if (elem is InterfaceElement) {
         // Suggestions provided by StaticMemberContributor.
         return;
       } else if (elem is ExtensionElement) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
index 2898c90..4940609 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
@@ -18,8 +18,10 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/element/extensions.dart';
 import 'package:analyzer/src/dart/resolver/body_inference_context.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
+import 'package:collection/collection.dart';
 
 const List<String> intNames = ['i', 'j', 'index', 'length'];
 const List<String> listNames = ['list', 'items'];
@@ -366,13 +368,13 @@
             : (node as ForElement).forLoopParts;
         if (loopParts is ForPartsWithDeclarations) {
           for (var declaredVariable in loopParts.variables.variables.reversed) {
-            if (declaredVariable.declaredElement2 == variable) {
+            if (declaredVariable.declaredElement == variable) {
               return distance;
             }
             distance++;
           }
         } else if (loopParts is ForEachPartsWithDeclaration) {
-          if (loopParts.loopVariable.declaredElement2 == variable) {
+          if (loopParts.loopVariable.declaredElement == variable) {
             return distance;
           }
           distance++;
@@ -384,7 +386,7 @@
           var index = variables.indexOf(node);
           for (var i = index - 1; i >= 0; i--) {
             var declaredVariable = variables[i];
-            if (declaredVariable.declaredElement2 == variable) {
+            if (declaredVariable.declaredElement == variable) {
               return distance;
             }
             distance++;
@@ -412,7 +414,7 @@
           if (statement is VariableDeclarationStatement) {
             for (var declaredVariable
                 in statement.variables.variables.reversed) {
-              if (declaredVariable.declaredElement2 == variable) {
+              if (declaredVariable.declaredElement == variable) {
                 return distance;
               }
               distance++;
@@ -469,11 +471,8 @@
     } else if (!visited.add(subclass)) {
       return -1;
     }
-    var minDepth = 0;
-    if (subclass is ClassElement) {
-      minDepth = _inheritanceDistance(
-          subclass.supertype?.element2, superclass, visited);
-    }
+    var minDepth =
+        _inheritanceDistance(subclass.supertype?.element2, superclass, visited);
 
     void visitTypes(List<InterfaceType> types) {
       for (var type in types) {
@@ -881,7 +880,14 @@
 
   @override
   DartType? visitParenthesizedExpression(ParenthesizedExpression node) {
-    return _visitParent(node);
+    final type = _visitParent(node);
+
+    // `RecordType := (^)` without any fields.
+    if (type is RecordType) {
+      return type.positionalFields.firstOrNull?.type;
+    }
+
+    return type;
   }
 
   @override
@@ -905,6 +911,45 @@
   }
 
   @override
+  DartType? visitRecordLiteral(RecordLiteral node) {
+    final type = node.parent?.accept(this);
+    if (type is! RecordType) {
+      return null;
+    }
+
+    var index = 0;
+
+    DartType? typeOfIndexPositionalField() {
+      if (index < type.positionalFields.length) {
+        return type.positionalFields[index].type;
+      }
+      return null;
+    }
+
+    for (final argument in node.fields) {
+      if (argument is NamedExpression) {
+        if (offset <= argument.offset) {
+          return typeOfIndexPositionalField();
+        }
+        if (argument.contains(offset)) {
+          if (offset >= argument.name.colon.end) {
+            final name = argument.name.label.name;
+            return type.namedField(name)?.type;
+          }
+          return null;
+        }
+      } else {
+        if (offset <= argument.end) {
+          return typeOfIndexPositionalField();
+        }
+        index++;
+      }
+    }
+
+    return typeOfIndexPositionalField();
+  }
+
+  @override
   DartType? visitReturnStatement(ReturnStatement node) {
     if (node.returnKeyword.end < offset) {
       var functionBody = node.thisOrAncestorOfType<FunctionBody>();
@@ -984,7 +1029,7 @@
       var parent = node.parent;
       if (parent is VariableDeclarationList) {
         return parent.type?.type ??
-            _impliedDartTypeWithName(typeProvider, node.name2.lexeme);
+            _impliedDartTypeWithName(typeProvider, node.name.lexeme);
       }
     }
     return null;
@@ -997,7 +1042,7 @@
         var equals = varDecl.equals;
         if (equals != null && equals.end <= offset) {
           return node.type?.type ??
-              _impliedDartTypeWithName(typeProvider, varDecl.name2.lexeme);
+              _impliedDartTypeWithName(typeProvider, varDecl.name.lexeme);
         }
       }
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
index 2bf08ba..ecb2e25 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
@@ -50,9 +50,9 @@
     InterfaceElement? enclosingClass;
     var constructorParent = constructor.parent;
     if (constructorParent is ClassDeclaration) {
-      enclosingClass = constructorParent.declaredElement2;
+      enclosingClass = constructorParent.declaredElement;
     } else if (constructorParent is EnumDeclaration) {
-      enclosingClass = constructorParent.declaredElement2;
+      enclosingClass = constructorParent.declaredElement;
     } else {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 060361b..ad2274a 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -146,7 +146,7 @@
   void visitClassDeclaration(ClassDeclaration node) {
     final entity = this.entity;
     // Don't suggest class name
-    if (entity == node.name2) {
+    if (entity == node.name) {
       return;
     }
     if (entity == node.rightBracket) {
@@ -266,7 +266,7 @@
       return;
     }
 
-    if (entity == node.name2) {
+    if (entity == node.name) {
       return;
     }
 
@@ -298,7 +298,7 @@
   @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     // Don't suggest extension name
-    if (entity == node.name2) {
+    if (entity == node.name) {
       return;
     }
     if (entity == node.rightBracket) {
@@ -492,7 +492,7 @@
   void visitFunctionDeclaration(FunctionDeclaration node) {
     // If the cursor is at the beginning of the declaration, include the
     // compilation unit keywords.  See dartbug.com/41039.
-    if (entity == node.returnType || entity == node.name2) {
+    if (entity == node.returnType || entity == node.name) {
       _addSuggestion(Keyword.DYNAMIC);
       _addSuggestion(Keyword.VOID);
     }
@@ -615,7 +615,7 @@
           _addSuggestion2(SYNC_STAR);
         }
       }
-    } else if (entity == node.returnType || entity == node.name2) {
+    } else if (entity == node.returnType || entity == node.name) {
       // If the cursor is at the beginning of the declaration, include the class
       // body keywords.  See dartbug.com/41039.
       _addClassBodyKeywords();
@@ -643,7 +643,7 @@
   void visitMixinDeclaration(MixinDeclaration node) {
     final entity = this.entity;
     // Don't suggest mixin name
-    if (entity == node.name2) {
+    if (entity == node.name) {
       return;
     }
     if (entity == node.rightBracket) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
index b83b9c5..86368fd 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -52,7 +52,7 @@
                 }
               }
             } else {
-              if (element is ClassElement ||
+              if (element is InterfaceElement ||
                   element is ExtensionElement ||
                   element is TypeAliasElement) {
                 builder.suggestElement(element,
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 d61035d..6819442 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
@@ -46,27 +46,7 @@
 
   @override
   void visitClassElement(ClassElement element) {
-    if (opType.includeTypeNameSuggestions) {
-      builder.suggestInterface(element, prefix: prefix);
-    }
-    if (opType.includeConstructorSuggestions) {
-      _addConstructorSuggestions(element);
-    } else if (opType.includeAnnotationSuggestions) {
-      _addConstructorSuggestions(element, onlyConst: true);
-    }
-    if (opType.includeReturnValueSuggestions) {
-      final typeSystem = request.libraryElement.typeSystem;
-      final contextType = request.contextType;
-      if (contextType is InterfaceType) {
-        // TODO(scheglov) This looks not ideal - we should suggest getters.
-        for (final field in element.fields) {
-          if (field.isStatic &&
-              typeSystem.isSubtypeOf(field.type, contextType)) {
-            builder.suggestStaticField(field, prefix: prefix);
-          }
-        }
-      }
-    }
+    _visitInterfaceElement(element);
   }
 
   @override
@@ -80,6 +60,11 @@
   }
 
   @override
+  visitEnumElement(EnumElement element) {
+    _visitInterfaceElement(element);
+  }
+
+  @override
   void visitExtensionElement(ExtensionElement element) {
     if (opType.includeReturnValueSuggestions) {
       builder.suggestExtension(element, kind: kind, prefix: prefix);
@@ -92,7 +77,7 @@
     if (element.isOperator) {
       return;
     }
-    if (element.enclosingElement3 is! CompilationUnitElement) {
+    if (element.enclosingElement is! CompilationUnitElement) {
       return;
     }
     var returnType = element.returnType;
@@ -115,11 +100,16 @@
   }
 
   @override
+  visitMixinElement(MixinElement element) {
+    _visitInterfaceElement(element);
+  }
+
+  @override
   void visitPropertyAccessorElement(PropertyAccessorElement element) {
     if (opType.includeReturnValueSuggestions ||
         (opType.includeAnnotationSuggestions && element.variable.isConst)) {
-      var parent = element.enclosingElement3;
-      if (parent is ClassElement || parent is ExtensionElement) {
+      var parent = element.enclosingElement;
+      if (parent is InterfaceElement || parent is ExtensionElement) {
         builder.suggestAccessor(element, inheritanceDistance: 0.0);
       } else {
         builder.suggestTopLevelPropertyAccessor(element, prefix: prefix);
@@ -165,6 +155,32 @@
       builder.suggestConstructor(constructor, kind: kind, prefix: prefix);
     }
   }
+
+  void _visitInterfaceElement(InterfaceElement element) {
+    if (opType.includeTypeNameSuggestions) {
+      builder.suggestInterface(element, prefix: prefix);
+    }
+    if (element is ClassElement) {
+      if (opType.includeConstructorSuggestions) {
+        _addConstructorSuggestions(element);
+      } else if (opType.includeAnnotationSuggestions) {
+        _addConstructorSuggestions(element, onlyConst: true);
+      }
+    }
+    if (opType.includeReturnValueSuggestions) {
+      final typeSystem = request.libraryElement.typeSystem;
+      final contextType = request.contextType;
+      if (contextType is InterfaceType) {
+        // TODO(scheglov) This looks not ideal - we should suggest getters.
+        for (final field in element.fields) {
+          if (field.isStatic &&
+              typeSystem.isSubtypeOf(field.type, contextType)) {
+            builder.suggestStaticField(field, prefix: prefix);
+          }
+        }
+      }
+    }
+  }
 }
 
 /// A contributor that produces suggestions based on the top level members in
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
index 6a74266..4b1d417 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -86,9 +86,9 @@
       if (member != null) {
         var enclosingNode = member.parent;
         if (enclosingNode is ClassDeclaration) {
-          _addForInterface(enclosingNode.declaredElement2!);
+          _addForInterface(enclosingNode.declaredElement!);
         } else if (enclosingNode is MixinDeclaration) {
-          _addForInterface(enclosingNode.declaredElement2!);
+          _addForInterface(enclosingNode.declaredElement!);
         }
       }
     }
@@ -218,12 +218,12 @@
 
   @override
   void declaredClass(ClassDeclaration declaration) {
-    _declaredInterfaceElement(declaration.declaredElement2);
+    _declaredInterfaceElement(declaration.declaredElement);
   }
 
   @override
   void declaredClassTypeAlias(ClassTypeAlias declaration) {
-    var declaredElement = declaration.declaredElement2;
+    var declaredElement = declaration.declaredElement;
     if (declaredElement != null && opType.includeTypeNameSuggestions) {
       builder.suggestInterface(declaredElement);
     }
@@ -236,23 +236,23 @@
 
   @override
   void declaredEnum(EnumDeclaration declaration) {
-    _declaredInterfaceElement(declaration.declaredElement2);
+    _declaredInterfaceElement(declaration.declaredElement);
   }
 
   @override
   void declaredExtension(ExtensionDeclaration declaration) {
-    var declaredElement = declaration.declaredElement2;
+    var declaredElement = declaration.declaredElement;
     if (declaredElement != null &&
         visibilityTracker._isVisible(declaredElement) &&
         opType.includeReturnValueSuggestions &&
-        declaration.name2 != null) {
+        declaration.name != null) {
       builder.suggestExtension(declaredElement, kind: _defaultKind);
     }
   }
 
   @override
   void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-    var field = varDecl.declaredElement2;
+    var field = varDecl.declaredElement;
     if (field is FieldElement &&
         ((visibilityTracker._isVisible(field) &&
                 opType.includeReturnValueSuggestions &&
@@ -261,10 +261,10 @@
       var inheritanceDistance = 0.0;
       var enclosingClass = request.target.containingNode
           .thisOrAncestorOfType<ClassDeclaration>();
-      var enclosingElement = enclosingClass?.declaredElement2;
+      var enclosingElement = enclosingClass?.declaredElement;
       if (enclosingElement != null) {
-        var enclosingElement = field.enclosingElement3;
-        if (enclosingElement is ClassElement) {
+        var enclosingElement = field.enclosingElement;
+        if (enclosingElement is InterfaceElement) {
           inheritanceDistance = request.featureComputer
               .inheritanceDistanceFeature(enclosingElement, enclosingElement);
         }
@@ -275,7 +275,7 @@
 
   @override
   void declaredFunction(FunctionDeclaration declaration) {
-    if (visibilityTracker._isVisible(declaration.declaredElement2) &&
+    if (visibilityTracker._isVisible(declaration.declaredElement) &&
         (opType.includeReturnValueSuggestions ||
             opType.includeVoidReturnSuggestions)) {
       if (declaration.isSetter) {
@@ -288,7 +288,7 @@
           return;
         }
       }
-      var declaredElement = declaration.declaredElement2;
+      var declaredElement = declaration.declaredElement;
       if (declaredElement is FunctionElement) {
         builder.suggestTopLevelFunction(declaredElement, kind: _defaultKind);
       } else if (declaredElement is PropertyAccessorElement) {
@@ -299,7 +299,7 @@
 
   @override
   void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
-    var declaredElement = declaration.declaredElement2;
+    var declaredElement = declaration.declaredElement;
     if (declaredElement != null && opType.includeTypeNameSuggestions) {
       builder.suggestTypeAlias(declaredElement);
     }
@@ -307,7 +307,7 @@
 
   @override
   void declaredGenericTypeAlias(GenericTypeAlias declaration) {
-    var declaredElement = declaration.declaredElement2;
+    var declaredElement = declaration.declaredElement;
     if (declaredElement is TypeAliasElement &&
         opType.includeTypeNameSuggestions) {
       builder.suggestTypeAlias(declaredElement);
@@ -333,7 +333,7 @@
 
   @override
   void declaredMethod(MethodDeclaration declaration) {
-    var element = declaration.declaredElement2;
+    var element = declaration.declaredElement;
     if (visibilityTracker._isVisible(element) &&
         (opType.includeReturnValueSuggestions ||
             opType.includeVoidReturnSuggestions) &&
@@ -342,11 +342,11 @@
       var enclosingClass = request.target.containingNode
           .thisOrAncestorOfType<ClassDeclaration>();
       if (enclosingClass != null) {
-        var enclosingElement = element?.enclosingElement3;
-        if (enclosingElement is ClassElement) {
+        var enclosingElement = element?.enclosingElement;
+        if (enclosingElement is InterfaceElement) {
           inheritanceDistance = request.featureComputer
               .inheritanceDistanceFeature(
-                  enclosingClass.declaredElement2!, enclosingElement);
+                  enclosingClass.declaredElement!, enclosingElement);
         }
       }
       if (element is MethodElement) {
@@ -361,7 +361,7 @@
 
   @override
   void declaredMixin(MixinDeclaration declaration) {
-    var declaredElement = declaration.declaredElement2;
+    var declaredElement = declaration.declaredElement;
     if (!inExtendsClause &&
         declaredElement != null &&
         visibilityTracker._isVisible(declaredElement) &&
@@ -388,7 +388,7 @@
   @override
   void declaredTopLevelVar(
       VariableDeclarationList varList, VariableDeclaration varDecl) {
-    var variableElement = varDecl.declaredElement2;
+    var variableElement = varDecl.declaredElement;
     if (variableElement is TopLevelVariableElement &&
         visibilityTracker._isVisible(variableElement) &&
         opType.includeReturnValueSuggestions) {
@@ -401,7 +401,7 @@
 
   @override
   void declaredTypeParameter(TypeParameter node) {
-    var declaredElement = node.declaredElement2;
+    var declaredElement = node.declaredElement;
     if (declaredElement != null &&
         visibilityTracker._isVisible(declaredElement) &&
         opType.includeTypeNameSuggestions) {
@@ -428,9 +428,7 @@
               !opType.includeConstructorSuggestions;
       if (!opType.isPrefixed &&
           includeConstructors &&
-          element is ClassElement &&
-          // TODO(scheglov) Remove when separated EnumElement from ClassElement
-          element is! EnumElement) {
+          element is ClassElement) {
         for (final constructor in element.constructors) {
           if (element.isAbstract && !constructor.isFactory) {
             continue;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index 971f200..deef15b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -72,7 +72,7 @@
     var type = fields.type;
     if (variables.length == 1) {
       var variable = variables[0];
-      var targetId = variable.name2;
+      var targetId = variable.name;
       if (targetId.lexeme.isEmpty) {
         // analyzer parser
         // Actual: class C { foo^ }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/record_literal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/record_literal_contributor.dart
new file mode 100644
index 0000000..18ca1da
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/record_literal_contributor.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2022, 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/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
+
+class RecordLiteralContributor extends DartCompletionContributor {
+  RecordLiteralContributor(super.request, super.builder);
+
+  @override
+  Future<void> computeSuggestions() async {
+    final containingNode = request.target.containingNode;
+
+    final parent = containingNode.parent;
+    if (parent == null) {
+      return;
+    }
+
+    final contextType =
+        request.featureComputer.computeContextType(parent, request.offset);
+    if (contextType is! RecordType) {
+      return;
+    }
+
+    if (containingNode is ParenthesizedExpression) {
+      _compute(contextType, const []);
+    } else if (containingNode is RecordLiteral) {
+      _compute(contextType, containingNode.fields);
+    }
+  }
+
+  void _compute(RecordType contextType, List<Expression> literalFields) {
+    final includedNames = literalFields
+        .whereType<NamedExpression>()
+        .map((e) => e.name.label.name)
+        .toSet();
+
+    final isEditingName = _isEditingName();
+
+    for (final field in contextType.namedFields) {
+      if (!includedNames.contains(field.name)) {
+        builder.suggestNamedRecordField(
+          field,
+          appendColon: !isEditingName,
+          appendComma: !isEditingName &&
+              !request.target.isFollowedByComma &&
+              !request.target.isFollowedByRightParenthesis,
+        );
+      }
+    }
+  }
+
+  bool _isEditingName() {
+    final entity = request.target.entity;
+    if (entity is NamedExpression) {
+      final name = entity.name;
+      final offset = request.offset;
+      return name.offset <= offset && offset <= name.colon.offset;
+    }
+    return false;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/redirecting_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/redirecting_contributor.dart
index 23777a9..10561f1 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/redirecting_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/redirecting_contributor.dart
@@ -23,8 +23,8 @@
         // C() : this.^
         var containingConstructor =
             parent.thisOrAncestorOfType<ConstructorDeclaration>();
-        var constructorElement = containingConstructor?.declaredElement2;
-        var classElement = constructorElement?.enclosingElement3;
+        var constructorElement = containingConstructor?.declaredElement;
+        var classElement = constructorElement?.enclosingElement;
         if (classElement != null) {
           for (var constructor in classElement.constructors) {
             if (constructor != constructorElement) {
@@ -51,8 +51,8 @@
         // factory C() = ^
         var containingConstructor =
             parent.thisOrAncestorOfType<ConstructorDeclaration>();
-        var constructorElement = containingConstructor?.declaredElement2;
-        var classElement = constructorElement?.enclosingElement3;
+        var constructorElement = containingConstructor?.declaredElement;
+        var classElement = constructorElement?.enclosingElement;
         var libraryElement = request.libraryElement;
         if (classElement == null) {
           return;
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 38fdc71..d14953e 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
@@ -223,7 +223,7 @@
         var containingMethod = request.target.containingNode
             .thisOrAncestorOfType<MethodDeclaration>();
         if (containingMethod != null) {
-          _cachedContainingMemberName = containingMethod.name2.lexeme;
+          _cachedContainingMemberName = containingMethod.name.lexeme;
         }
       }
     }
@@ -394,7 +394,7 @@
     // If the class name is already in the text, then we don't support
     // prepending a prefix.
     assert(!hasClassName || prefix == null);
-    var enclosingClass = constructor.enclosingElement3;
+    var enclosingClass = constructor.enclosingElement;
     var className = enclosingClass.name;
     if (className.isEmpty) {
       return;
@@ -435,17 +435,17 @@
   /// will be used as the kind for the suggestion.
   void suggestElement(Element element,
       {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
-    if (element is ClassElement) {
+    if (element is InterfaceElement) {
       suggestInterface(element);
     } else if (element is ConstructorElement) {
       suggestConstructor(element, kind: kind);
     } else if (element is ExtensionElement) {
       suggestExtension(element, kind: kind);
     } else if (element is FunctionElement &&
-        element.enclosingElement3 is CompilationUnitElement) {
+        element.enclosingElement is CompilationUnitElement) {
       suggestTopLevelFunction(element, kind: kind);
     } else if (element is PropertyAccessorElement &&
-        element.enclosingElement3 is CompilationUnitElement) {
+        element.enclosingElement is CompilationUnitElement) {
       suggestTopLevelPropertyAccessor(element);
     } else if (element is TypeAliasElement) {
       suggestTypeAlias(element);
@@ -458,7 +458,7 @@
   /// referenced using a prefix, then the [prefix] should be provided.
   void suggestEnumConstant(FieldElement constant, {String? prefix}) {
     var constantName = constant.name;
-    var enumElement = constant.enclosingElement3;
+    var enumElement = constant.enclosingElement;
     var enumName = enumElement.name;
     var completion = '$enumName.$constantName';
     var relevance =
@@ -706,7 +706,7 @@
       inheritanceDistance: inheritanceDistance,
     );
 
-    var enclosingElement = method.enclosingElement3;
+    var enclosingElement = method.enclosingElement;
     if (method.name == 'setState' &&
         enclosingElement is ClassElement &&
         flutter.isExactState(enclosingElement)) {
@@ -778,13 +778,16 @@
 
     // Optionally add Flutter child widget details.
     // todo (pq): revisit this special casing; likely it can be generalized away
-    var element = parameter.enclosingElement3;
+    var element = parameter.enclosingElement;
     // If appendColon is false, default values should never be appended.
     if (element is ConstructorElement && appendColon) {
-      if (Flutter.instance.isWidget(element.enclosingElement3)) {
+      if (Flutter.instance.isWidget(element.enclosingElement)) {
+        var codeStyleOptions = request
+            .analysisSession.analysisContext.analysisOptions.codeStyleOptions;
         // Don't bother with nullability. It won't affect default list values.
-        var defaultValue =
-            getDefaultStringParameterValue(parameter, withNullability: false);
+        var defaultValue = getDefaultStringParameterValue(
+            parameter, codeStyleOptions,
+            withNullability: false);
         // TODO(devoncarew): Should we remove the check here? We would then
         // suggest values for param types like closures.
         if (defaultValue != null && defaultValue.text == '[]') {
@@ -829,6 +832,45 @@
     _addSuggestion(suggestion);
   }
 
+  /// Add a suggestion to add a named argument corresponding to the [field].
+  /// If [appendColon] is `true` then a colon will be added after the name. If
+  /// [appendComma] is `true` then a comma will be included at the end of the
+  /// completion text.
+  void suggestNamedRecordField(RecordTypeNamedField field,
+      {required bool appendColon,
+      required bool appendComma,
+      int? replacementLength}) {
+    final name = field.name;
+    final type = field.type.getDisplayString(
+      withNullability: _isNonNullableByDefault,
+    );
+
+    var completion = name;
+    if (appendColon) {
+      completion += ': ';
+    }
+    final selectionOffset = completion.length;
+
+    if (appendComma) {
+      completion += ',';
+    }
+
+    _addSuggestion(
+      CompletionSuggestion(
+        CompletionSuggestionKind.NAMED_ARGUMENT,
+        Relevance.requiredNamedArgument,
+        completion,
+        selectionOffset,
+        0,
+        false,
+        false,
+        parameterName: name,
+        parameterType: type,
+        replacementLength: replacementLength,
+      ),
+    );
+  }
+
   /// Add a suggestion to replace the [targetId] with an override of the given
   /// [element]. If [invokeSuper] is `true`, then the override will contain an
   /// invocation of an overridden member.
@@ -937,6 +979,36 @@
     );
   }
 
+  void suggestRecordField({
+    required RecordTypeField field,
+    required String name,
+  }) {
+    final type = field.type;
+    final featureComputer = request.featureComputer;
+    final contextType =
+        featureComputer.contextTypeFeature(request.contextType, type);
+    final relevance = _computeRelevance(
+      contextType: contextType,
+    );
+
+    final returnType = field.type.getDisplayString(
+      withNullability: _isNonNullableByDefault,
+    );
+
+    _addSuggestion(
+      CompletionSuggestion(
+        CompletionSuggestionKind.IDENTIFIER,
+        relevance,
+        name,
+        name.length,
+        0,
+        false,
+        false,
+        returnType: returnType,
+      ),
+    );
+  }
+
   /// Add a suggestion for a static field declared within a class or extension.
   /// If the field is synthetic, add the corresponding getter instead.
   ///
@@ -1010,9 +1082,9 @@
   void suggestTopLevelPropertyAccessor(PropertyAccessorElement accessor,
       {String? prefix}) {
     assert(
-        accessor.enclosingElement3 is CompilationUnitElement,
+        accessor.enclosingElement is CompilationUnitElement,
         'Enclosing element of ${accessor.runtimeType} is '
-        '${accessor.enclosingElement3.runtimeType}.');
+        '${accessor.enclosingElement.runtimeType}.');
     if (accessor.isSynthetic) {
       // Avoid visiting a field twice. All fields induce a getter, but only
       // non-final fields induce a setter, so we don't add a suggestion for a
@@ -1062,7 +1134,7 @@
   /// referenced using a prefix, then the [prefix] should be provided.
   void suggestTopLevelVariable(TopLevelVariableElement variable,
       {String? prefix}) {
-    assert(variable.enclosingElement3 is CompilationUnitElement);
+    assert(variable.enclosingElement is CompilationUnitElement);
     var relevance =
         _computeTopLevelRelevance(variable, elementType: variable.type);
     _addBuilder(
@@ -1295,10 +1367,10 @@
       withNullability: _isNonNullableByDefault,
     );
 
-    var enclosingElement = element.enclosingElement3;
+    var enclosingElement = element.enclosingElement;
 
     String? declaringType;
-    if (enclosingElement is ClassElement) {
+    if (enclosingElement is InterfaceElement) {
       declaringType = enclosingElement.displayName;
     }
 
@@ -1354,8 +1426,8 @@
   /// The enclosing element must be either a class, or extension; otherwise
   /// we either fail with assertion, or return `null`.
   String? _enclosingClassOrExtensionName(Element element) {
-    var enclosing = element.enclosingElement3;
-    if (enclosing is ClassElement) {
+    var enclosing = element.enclosingElement;
+    if (enclosing is InterfaceElement) {
       return enclosing.name;
     } else if (enclosing is ExtensionElement) {
       return enclosing.name;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/super_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/super_formal_contributor.dart
index adfadc6..574e844 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/super_formal_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/super_formal_contributor.dart
@@ -27,7 +27,7 @@
       return;
     }
 
-    var constructorElement = constructor.declaredElement2;
+    var constructorElement = constructor.declaredElement;
     constructorElement as ConstructorElementImpl;
 
     var superConstructor = constructorElement.superConstructor;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 482a4cd..280ad65 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart';
+import 'package:collection/collection.dart';
 
 /// A contributor that produces suggestions based on the instance members of a
 /// given type, whether declared by that type directly or inherited from a
@@ -30,7 +31,7 @@
     }
     if (expression is Identifier) {
       var elem = expression.staticElement;
-      if (elem is ClassElement) {
+      if (elem is InterfaceElement) {
         // Suggestions provided by StaticMemberContributor.
         return;
       }
@@ -89,6 +90,24 @@
       var memberBuilder = _SuggestionBuilder(request, builder);
       memberBuilder.buildSuggestions(type,
           mixins: mixins, superclassConstraints: superclassConstraints);
+    } else if (type is RecordType) {
+      _suggestFromRecordType(type);
+    }
+  }
+
+  void _suggestFromRecordType(RecordType type) {
+    type.positionalFields.forEachIndexed((index, field) {
+      builder.suggestRecordField(
+        field: field,
+        name: '\$$index',
+      );
+    });
+
+    for (final field in type.namedFields) {
+      builder.suggestRecordField(
+        field: field,
+        name: field.name,
+      );
     }
   }
 }
@@ -108,7 +127,7 @@
 
   @override
   void declaredClass(ClassDeclaration declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       // no type
       finished();
     }
@@ -116,7 +135,7 @@
 
   @override
   void declaredClassTypeAlias(ClassTypeAlias declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       // no type
       finished();
     }
@@ -124,7 +143,7 @@
 
   @override
   void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-    if (varDecl.name2.lexeme == targetName) {
+    if (varDecl.name.lexeme == targetName) {
       // Type provided by the element in computeFull above
       finished();
     }
@@ -132,7 +151,7 @@
 
   @override
   void declaredFunction(FunctionDeclaration declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       var returnType = declaration.returnType;
       if (returnType != null) {
         var type = returnType.type;
@@ -146,7 +165,7 @@
 
   @override
   void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       var returnType = declaration.returnType;
       if (returnType != null) {
         var type = returnType.type;
@@ -160,7 +179,7 @@
 
   @override
   void declaredGenericTypeAlias(GenericTypeAlias declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       var returnType = declaration.functionType?.returnType;
       if (returnType != null) {
         var type = returnType.type;
@@ -194,7 +213,7 @@
 
   @override
   void declaredMethod(MethodDeclaration declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       var returnType = declaration.returnType;
       if (returnType != null) {
         var type = returnType.type;
@@ -217,7 +236,7 @@
   @override
   void declaredTopLevelVar(
       VariableDeclarationList varList, VariableDeclaration varDecl) {
-    if (varDecl.name2.lexeme == targetName) {
+    if (varDecl.name.lexeme == targetName) {
       // Type provided by the element in computeFull above.
       finished();
     }
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 ebab076..a2f978e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
@@ -6,6 +6,7 @@
 import 'package:analysis_server/src/protocol_server.dart'
     show CompletionSuggestion, Location;
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analyzer/dart/analysis/code_style_options.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -165,7 +166,8 @@
 }
 
 /// Return a default argument value for the given [parameter].
-DefaultArgument? getDefaultStringParameterValue(ParameterElement parameter,
+DefaultArgument? getDefaultStringParameterValue(
+    ParameterElement parameter, CodeStyleOptions codeStyleOptions,
     {required bool withNullability}) {
   var type = parameter.type;
   if (type is InterfaceType) {
@@ -174,7 +176,8 @@
     } else if (type.isDartCoreMap) {
       return DefaultArgument('{}', cursorPosition: 1);
     } else if (type.isDartCoreString) {
-      return DefaultArgument("''", cursorPosition: 1);
+      var quote = codeStyleOptions.preferredQuoteForStrings;
+      return DefaultArgument('$quote$quote', cursorPosition: 1);
     }
   } else if (type is FunctionType) {
     var params = type.parameters
@@ -226,9 +229,9 @@
     }
     type = element.returnType;
   } else if (element is TypeAliasElement) {
-    var aliasedElement = element.aliasedElement;
-    if (aliasedElement is GenericFunctionTypeElement) {
-      type = aliasedElement.returnType;
+    final aliasedType = element.aliasedType;
+    if (aliasedType is FunctionType) {
+      type = aliasedType.returnType;
     } else {
       return null;
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
index bd09b5e..e8fe820 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
@@ -36,6 +36,11 @@
         if (expression is Identifier) {
           strName = _getStringName(expression);
         }
+      } else if (node is RecordTypeAnnotationField) {
+        final identifier = _typeAnnotationIdentifier(node.type);
+        if (identifier != null) {
+          strName = _getStringName(identifier);
+        }
       } else if (node is SimpleFormalParameter) {
         var identifier = _formalParameterTypeIdentifier2(node);
         if (identifier != null) {
@@ -61,7 +66,7 @@
           var varDeclarations = varDeclarationList.variables;
           if (varDeclarations.length == 1) {
             var declaration = varDeclarations.first;
-            strName = declaration.name2.lexeme;
+            strName = declaration.name.lexeme;
           }
         }
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 31f1cb5..e6c4c76 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -85,13 +85,13 @@
 
   /// Return the class element associated with the [target], or `null` if there
   /// is no such class element.
-  InterfaceElement? getTargetClassElement(Expression target) {
+  InterfaceElement? getTargetInterfaceElement(Expression target) {
     var type = target.staticType;
     if (type is InterfaceType) {
       return type.element2;
     } else if (target is Identifier) {
       var element = target.staticElement;
-      if (element is ClassElement) {
+      if (element is InterfaceElement) {
         return element;
       }
     }
@@ -117,7 +117,7 @@
     if (parent is VariableDeclaration) {
       var variableDeclaration = parent;
       if (variableDeclaration.initializer == expression) {
-        var variableElement = variableDeclaration.declaredElement2;
+        var variableElement = variableDeclaration.declaredElement;
         if (variableElement != null) {
           return variableElement.type;
         }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
index db7c3a0..1393d21 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
@@ -36,15 +36,15 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     if (isForMissingReturn) {
-      var parent = node.parent;
+      final node = this.node;
       FunctionBody? body;
       DartType? returnType;
-      if (parent is FunctionDeclaration) {
-        body = parent.functionExpression.body;
-        returnType = parent.declaredElement2!.returnType;
-      } else if (parent is MethodDeclaration) {
-        body = parent.body;
-        returnType = parent.declaredElement2!.returnType;
+      if (node is FunctionDeclaration) {
+        body = node.functionExpression.body;
+        returnType = node.declaredElement!.returnType;
+      } else if (node is MethodDeclaration) {
+        body = node.body;
+        returnType = node.declaredElement!.returnType;
       }
       if (body == null || returnType == null) {
         return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_call_super.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_call_super.dart
index 7bb200b..88b1aaa 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_call_super.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_call_super.dart
@@ -30,17 +30,16 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var node = this.node;
-    if (node is! SimpleIdentifier) return;
-    var methodDeclaration = node.thisOrAncestorOfType<MethodDeclaration>();
-    if (methodDeclaration == null) return;
+    final methodDeclaration = node;
+    if (methodDeclaration is! MethodDeclaration) return;
     var classElement = methodDeclaration
         .thisOrAncestorOfType<ClassDeclaration>()
-        ?.declaredElement2;
+        ?.declaredElement;
     if (classElement == null) return;
 
-    var name = Name(classElement.library.source.uri, node.name);
-    var overridden = InheritanceManager3().getInherited2(classElement, name);
+    var name = methodDeclaration.name.lexeme;
+    var nameObj = Name(classElement.library.source.uri, name);
+    var overridden = InheritanceManager3().getInherited2(classElement, nameObj);
     if (overridden == null) return;
     var overriddenParameters = overridden.parameters.map((p) => p.name);
 
@@ -58,7 +57,7 @@
             .join(', ') ??
         '';
 
-    _addition = '${node.name}($argumentList)';
+    _addition = '$name($argumentList)';
 
     if (body is BlockFunctionBody) {
       await _block(builder, body);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
index 948d9af..9322da0 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
@@ -34,20 +34,22 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     final node = this.node;
-    if (node is! SimpleIdentifier) {
+    final String name;
+    if (node is MethodDeclaration) {
+      name = node.name.lexeme;
+    } else if (node is VariableDeclaration) {
+      name = node.name.lexeme;
+    } else {
       return;
     }
 
     final classDeclaration = node.thisOrAncestorOfType<ClassDeclaration>();
     if (classDeclaration == null ||
-        !flutter
-            .isDiagnosticable(classDeclaration.declaredElement2!.thisType)) {
+        !flutter.isDiagnosticable(classDeclaration.declaredElement!.thisType)) {
       return;
     }
 
-    final parent = node.parent!;
-
-    var type = _getReturnType(parent);
+    var type = _getReturnType(node);
     if (type == null) {
       return;
     }
@@ -99,8 +101,8 @@
         if (decl != null) {
           declType = decl.type;
           // getter
-        } else if (parent is MethodDeclaration) {
-          declType = parent.returnType;
+        } else if (node is MethodDeclaration) {
+          declType = node.returnType;
         }
 
         if (declType != null) {
@@ -112,12 +114,12 @@
           }
         }
       }
-      builder.writeln("$constructorName('${node.name}', ${node.name}));");
+      builder.writeln("$constructorName('$name', $name));");
     }
 
     final debugFillProperties = classDeclaration.members
         .whereType<MethodDeclaration>()
-        .where((e) => e.name2.lexeme == 'debugFillProperties')
+        .where((e) => e.name.lexeme == 'debugFillProperties')
         .singleOrNull;
     if (debugFillProperties == null) {
       var location = utils.prepareNewMethodLocation(classDeclaration);
@@ -195,13 +197,13 @@
   DartType? _getReturnType(AstNode node) {
     if (node is MethodDeclaration) {
       // Getter.
-      var element = node.declaredElement2;
+      var element = node.declaredElement;
       if (element is PropertyAccessorElement) {
         return element.returnType;
       }
     } else if (node is VariableDeclaration) {
       // Field.
-      var element = node.declaredElement2;
+      var element = node.declaredElement;
       if (element is FieldElement) {
         return element.type;
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_enum_constant.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_enum_constant.dart
index 39919e2..ecf5e59 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_enum_constant.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_enum_constant.dart
@@ -64,7 +64,7 @@
     var length = constructors.length;
     if (length > 1) return;
 
-    var name = length == 1 ? constructors.first.name2?.lexeme : null;
+    var name = length == 1 ? constructors.first.name?.lexeme : null;
 
     var offset = targetNode.constants.last.end;
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart
index 8f132a9..3592713 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart
@@ -38,9 +38,12 @@
     if (parent is AssignmentExpression && target == parent.rightHandSide) {
       toType = parent.writeType!;
     } else if (parent is VariableDeclaration && target == parent.initializer) {
-      toType = parent.declaredElement2!.type;
+      toType = parent.declaredElement!.type;
+    } else if (parent is ArgumentList) {
+      var staticType = target.staticParameterElement?.type;
+      if (staticType == null) return;
+      toType = staticType;
     } else {
-      // TODO(brianwilkerson) Handle function arguments.
       return;
     }
     if (typeSystem.isAssignableTo(
@@ -49,8 +52,7 @@
       // because it's nullable, in which case a cast won't fix the problem.
       return;
     }
-    // TODO(brianwilkerson) Handle `toSet` in a manner similar to the below.
-    if (target.isToListMethodInvocation) {
+    if (target.isToListMethodInvocation || target.isToSetMethodInvocation) {
       var targetTarget = (target as MethodInvocation).target;
       if (targetTarget != null) {
         var targetTargetType = targetTarget.typeOrThrow;
@@ -71,12 +73,11 @@
     final target_final = target;
 
     var needsParentheses = target.precedence < Precedence.postfix;
-    if (((fromType.isDartCoreIterable || fromType.isDartCoreList) &&
-            toType is InterfaceType &&
-            toType.isDartCoreList) ||
-        (fromType.isDartCoreSet &&
-            toType is InterfaceType &&
-            toType.isDartCoreSet)) {
+    if (toType is InterfaceType &&
+        (((fromType.isDartCoreIterable || fromType.isDartCoreList) &&
+                toType.isDartCoreList) ||
+            (fromType.isDartCoreIterable || fromType.isDartCoreSet) &&
+                toType.isDartCoreSet)) {
       if (target.isCastMethodInvocation) {
         // TODO(brianwilkerson) Consider updating the type arguments to the
         // `cast` invocation.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_extension_override.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_extension_override.dart
new file mode 100644
index 0000000..c56b442
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_extension_override.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2022, 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/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/resolver/applicable_extensions.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class AddExtensionOverride extends MultiCorrectionProducer {
+  @override
+  Stream<CorrectionProducer> get producers async* {
+    final node = this.node;
+    if (node is! SimpleIdentifier) return;
+    final parent = node.parent;
+    if (parent is! PropertyAccess) return;
+    var target = parent.target;
+    if (target == null) return;
+
+    var extensions =
+        libraryElement.accessibleExtensions.hasMemberWithBaseName(node.name);
+    for (var extension in extensions) {
+      var name = extension.extension.name;
+      if (name != null) {
+        yield _AddOverride(target, name);
+      }
+    }
+  }
+}
+
+/// A correction processor that can make one of the possible changes computed by
+/// the [AddExtensionOverride] producer.
+class _AddOverride extends CorrectionProducer {
+  /// The expression around which to add the override.
+  final Expression _expression;
+
+  /// The extension name to be inserted.
+  final String _name;
+
+  _AddOverride(this._expression, this._name);
+
+  @override
+  List<Object> get fixArguments => [_name];
+
+  @override
+  FixKind get fixKind => DartFixKind.ADD_EXTENSION_OVERRIDE;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    var needsParentheses = _expression is! ParenthesizedExpression;
+    await builder.addDartFileEdit(file, (builder) {
+      builder.addInsertion(_expression.offset, (builder) {
+        builder.write(_name);
+        if (needsParentheses) {
+          builder.write('(');
+        }
+      });
+      if (needsParentheses) {
+        builder.addSimpleInsertion(_expression.end, ')');
+      }
+    });
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
index d28bf0a..b2e5dbe 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
@@ -28,7 +28,7 @@
       return;
     }
 
-    var superType = classNode.declaredElement2!.supertype;
+    var superType = classNode.declaredElement!.supertype;
     if (superType == null) {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_key_to_constructors.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_key_to_constructors.dart
index 4f4b864..b74156e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_key_to_constructors.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_key_to_constructors.dart
@@ -24,10 +24,10 @@
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     var parent = node.parent;
-    if (node is SimpleIdentifier && parent is ClassDeclaration) {
+    if (node is ClassDeclaration) {
       // The lint is on the name of the class when there are no constructors.
       var targetLocation =
-          utils.prepareNewConstructorLocation(resolvedResult.session, parent);
+          utils.prepareNewConstructorLocation(resolvedResult.session, node);
       if (targetLocation == null) {
         return;
       }
@@ -35,13 +35,13 @@
       if (keyType == null) {
         return;
       }
-      var className = node.name;
-      var constructors = parent.declaredElement2?.supertype?.constructors;
+      var className = node.name.lexeme;
+      var constructors = node.declaredElement?.supertype?.constructors;
       if (constructors == null) {
         return;
       }
 
-      var canBeConst = _canBeConst(parent, constructors);
+      var canBeConst = _canBeConst(node, constructors);
       await builder.addDartFileEdit(file, (builder) {
         builder.addInsertion(targetLocation.offset, (builder) {
           builder.write(targetLocation.prefix);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart
index 53ef91d..b6dc2ec 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart
@@ -22,11 +22,9 @@
       return;
     }
     final node = this.node;
-    if (node is SimpleIdentifier) {
-      var variable = node.parent;
-      var variableList = variable?.parent;
-      if (variable is VariableDeclaration &&
-          variableList is VariableDeclarationList) {
+    if (node is VariableDeclaration) {
+      var variableList = node.parent;
+      if (variableList is VariableDeclarationList) {
         if (!variableList.isLate) {
           if (variableList.type == null) {
             var keyword = variableList.keyword;
@@ -54,31 +52,31 @@
             }
           }
         }
-      } else {
-        var getter = node.writeOrReadElement;
-        if (getter is PropertyAccessorElement &&
-            getter.isGetter &&
-            getter.isSynthetic &&
-            !getter.variable.isSynthetic &&
-            getter.variable.setter == null &&
-            getter.enclosingElement3 is ClassElement) {
-          var declarationResult =
-              await sessionHelper.getElementDeclaration(getter.variable);
-          if (declarationResult == null) {
-            return;
-          }
-          var variable = declarationResult.node;
-          var variableList = variable.parent;
-          if (variable is VariableDeclaration &&
-              variableList is VariableDeclarationList &&
-              variableList.parent is FieldDeclaration) {
-            var keywordToken = variableList.keyword;
-            if (variableList.variables.length == 1 &&
-                keywordToken != null &&
-                keywordToken.keyword == Keyword.FINAL) {
-              await _insertAt(builder, keywordToken.offset,
-                  source: declarationResult.element.source);
-            }
+      }
+    } else if (node is SimpleIdentifier) {
+      var getter = node.writeOrReadElement;
+      if (getter is PropertyAccessorElement &&
+          getter.isGetter &&
+          getter.isSynthetic &&
+          !getter.variable.isSynthetic &&
+          getter.variable.setter == null &&
+          getter.enclosingElement is InterfaceElement) {
+        var declarationResult =
+            await sessionHelper.getElementDeclaration(getter.variable);
+        if (declarationResult == null) {
+          return;
+        }
+        var variable = declarationResult.node;
+        var variableList = variable.parent;
+        if (variable is VariableDeclaration &&
+            variableList is VariableDeclarationList &&
+            variableList.parent is FieldDeclaration) {
+          var keywordToken = variableList.keyword;
+          if (variableList.variables.length == 1 &&
+              keywordToken != null &&
+              keywordToken.keyword == Keyword.FINAL) {
+            await _insertAt(builder, keywordToken.offset,
+                source: declarationResult.element.source);
           }
         }
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart
index 954bf68..83cf945 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart
@@ -38,7 +38,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [AddMissingParameter] producer.
 class _AddMissingOptionalPositionalParameter extends _AddMissingParameter {
   _AddMissingOptionalPositionalParameter(super.context);
@@ -60,7 +60,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [AddMissingParameter] producer.
 abstract class _AddMissingParameter extends CorrectionProducer {
   ExecutableParameters context;
@@ -93,7 +93,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [AddMissingParameter] producer.
 class _AddMissingRequiredPositionalParameter extends _AddMissingParameter {
   _AddMissingRequiredPositionalParameter(super.context);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
index e818a51..2831117 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
@@ -74,7 +74,7 @@
       int offset;
       var hasTrailingComma = false;
       var insertBetweenParams = false;
-      List<Expression> arguments = argumentList.arguments;
+      var arguments = argumentList.arguments;
       if (arguments.isEmpty) {
         offset = argumentList.leftParenthesis.end;
       } else {
@@ -93,7 +93,10 @@
         }
       }
 
-      var defaultValue = getDefaultStringParameterValue(missingParameter,
+      var codeStyleOptions = sessionHelper
+          .session.analysisContext.analysisOptions.codeStyleOptions;
+      var defaultValue = getDefaultStringParameterValue(
+          missingParameter, codeStyleOptions,
           withNullability: libraryElement.isNonNullableByDefault &&
               (missingParameter.library?.isNonNullableByDefault ?? false));
 
@@ -107,13 +110,14 @@
 
           // Use defaultValue.cursorPosition if it's not null.
           if (defaultValue != null) {
+            var text = defaultValue.text;
             var cursorPosition = defaultValue.cursorPosition;
             if (cursorPosition != null) {
-              builder.write(defaultValue.text.substring(0, cursorPosition));
+              builder.write(text.substring(0, cursorPosition));
               builder.selectHere();
-              builder.write(defaultValue.text.substring(cursorPosition));
+              builder.write(text.substring(cursorPosition));
             } else {
-              builder.addSimpleLinkedEdit('VALUE', defaultValue.text);
+              builder.addSimpleLinkedEdit('VALUE', text);
             }
           } else {
             builder.addSimpleLinkedEdit('VALUE', 'null');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_not_null_assert.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_not_null_assert.dart
index f0510f3..02c799d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_not_null_assert.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_not_null_assert.dart
@@ -17,12 +17,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    final identifier = node;
-    if (identifier is! SimpleIdentifier) {
-      return;
-    }
-
-    var formalParameter = identifier.parent;
+    final formalParameter = node;
     if (formalParameter is! FormalParameter) {
       return;
     }
@@ -48,7 +43,8 @@
           if (condition is BinaryExpression) {
             final leftOperand = condition.leftOperand;
             if (leftOperand is SimpleIdentifier) {
-              if (leftOperand.staticElement == identifier.staticElement &&
+              if (leftOperand.staticElement ==
+                      formalParameter.declaredElement &&
                   condition.operator.type == TokenType.BANG_EQ &&
                   condition.rightOperand is NullLiteral) {
                 return;
@@ -60,7 +56,7 @@
 
       final body_final = body;
       await builder.addDartFileEdit(file, (builder) {
-        final id = identifier.name;
+        final id = formalParameter.name!.lexeme;
         final prefix = utils.getNodePrefix(executable);
         final indent = utils.getIndent(1);
         // todo (pq): follow-ups:
@@ -70,8 +66,8 @@
         // adding the statement to the beginning of the list, special casing
         // when there are no statements (or when there's a single statement
         // and the whole block is on the same line).
-        var offset = min(utils.getLineNext(body_final.beginToken.offset),
-            body_final.endToken.offset);
+        var offset = min(
+            utils.getLineNext(body_final.offset), body_final.endToken.offset);
         builder.addSimpleInsertion(
             offset, '$prefix${indent}assert($id != null);$eol');
       });
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.dart
index a1bb384..2447e96 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/precedence.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
@@ -33,8 +34,6 @@
         target = coveredNodeParent.prefix;
       } else if (coveredNodeParent is PropertyAccess) {
         target = coveredNodeParent.realTarget;
-      } else if (coveredNodeParent is BinaryExpression) {
-        target = coveredNodeParent.rightOperand;
       } else {
         target = coveredNode;
       }
@@ -53,7 +52,20 @@
     } else if (coveredNode is PrefixExpression) {
       target = coveredNode.operand;
     } else if (coveredNode is BinaryExpression) {
-      target = coveredNode.leftOperand;
+      if (coveredNode.operator.type != TokenType.QUESTION_QUESTION) {
+        target = coveredNode.leftOperand;
+      } else {
+        var expectedType = coveredNode.staticParameterElement?.type;
+        if (expectedType == null) return;
+
+        var leftType = coveredNode.leftOperand.staticType;
+        var leftAssignable = leftType != null &&
+            typeSystem.isAssignableTo(
+                typeSystem.promoteToNonNull(leftType), expectedType);
+        if (leftAssignable) {
+          target = coveredNode.rightOperand;
+        }
+      }
     }
 
     if (target == null) {
@@ -74,14 +86,14 @@
     if (parent is AssignmentExpression && target == parent.rightHandSide) {
       toType = parent.writeType;
     } else if (parent is VariableDeclaration && target == parent.initializer) {
-      toType = parent.declaredElement2?.type;
+      toType = parent.declaredElement?.type;
     } else if (parent is ArgumentList) {
       toType = target.staticParameterElement?.type;
     } else if (parent is IndexExpression) {
       toType = parent.realTarget.typeOrThrow;
     } else if (parent is ForEachPartsWithDeclaration) {
       toType =
-          typeProvider.iterableType(parent.loopVariable.declaredElement2!.type);
+          typeProvider.iterableType(parent.loopVariable.declaredElement!.type);
     } else if (parent is ForEachPartsWithIdentifier) {
       toType = typeProvider.iterableType(parent.identifier.typeOrThrow);
     } else if (parent is SpreadElement) {
@@ -103,10 +115,19 @@
       } else if (enclosingExecutable is FunctionExpression) {
         toType = enclosingExecutable.declaredElement!.returnType;
       }
+    } else if (parent is BinaryExpression) {
+      if (typeSystem.isNonNullable(fromType)) {
+        return;
+      }
+      var expectedType = parent.staticParameterElement?.type;
+      if (expectedType != null &&
+          !typeSystem.isAssignableTo(
+              typeSystem.promoteToNonNull(fromType), expectedType)) {
+        return;
+      }
     } else if ((parent is PrefixedIdentifier && target == parent.prefix) ||
         parent is PostfixExpression ||
         parent is PrefixExpression ||
-        parent is BinaryExpression ||
         (parent is PropertyAccess && target == parent.target) ||
         (parent is CascadeExpression && target == parent.target) ||
         (parent is MethodInvocation && target == parent.target) ||
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
index 7a7b402..f0c969f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
@@ -28,8 +28,7 @@
       if (metadata.isNotEmpty) {
         for (var annotation in metadata) {
           if (annotation.elementAnnotation!.isRequired) {
-            var length =
-                annotation.endToken.next!.offset - annotation.beginToken.offset;
+            var length = annotation.endToken.next!.offset - annotation.offset;
             builder.addDeletion(SourceRange(annotation.offset, length));
             break;
           }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_return_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_return_null.dart
index ec7e11b..c8e66d8 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_return_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_return_null.dart
@@ -25,25 +25,20 @@
   Future<void> compute(ChangeBuilder builder) async {
     Block block;
 
-    var coveringNode = coveredNode;
-    if (coveringNode is Block) {
-      block = coveringNode;
-    } else if (coveringNode is SimpleIdentifier) {
-      var declaration = coveringNode.parent;
-      if (declaration is FunctionDeclaration) {
-        var body = declaration.functionExpression.body;
-        if (body is BlockFunctionBody) {
-          block = body.block;
-        } else {
-          return;
-        }
-      } else if (declaration is MethodDeclaration) {
-        var body = declaration.body;
-        if (body is BlockFunctionBody) {
-          block = body.block;
-        } else {
-          return;
-        }
+    final node = this.node;
+    if (node is Block) {
+      block = node;
+    } else if (node is FunctionDeclaration) {
+      var body = node.functionExpression.body;
+      if (body is BlockFunctionBody) {
+        block = body.block;
+      } else {
+        return;
+      }
+    } else if (node is MethodDeclaration) {
+      var body = node.body;
+      if (body is BlockFunctionBody) {
+        block = body.block;
       } else {
         return;
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
index 4475b82..97e7e94 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
@@ -35,33 +35,28 @@
   Future<void> compute(ChangeBuilder builder) async {
     Token? insertBeforeEntity;
     FunctionBody? body;
-    if (node is SimpleIdentifier) {
-      var executable = node.parent;
-      if (executable is MethodDeclaration && executable.name2 == token) {
-        if (executable.returnType != null) {
-          return;
-        }
-        if (executable.isSetter) {
-          return;
-        }
-        insertBeforeEntity = executable.propertyKeyword ?? executable.name2;
-        body = executable.body;
-      } else if (executable is FunctionDeclaration &&
-          executable.name2 == token) {
-        if (executable.returnType != null) {
-          return;
-        }
-        if (executable.isSetter) {
-          return;
-        }
-        insertBeforeEntity = executable.propertyKeyword ?? executable.name2;
-        body = executable.functionExpression.body;
-      } else {
+    final executable = node;
+    if (executable is MethodDeclaration && executable.name == token) {
+      if (executable.returnType != null) {
         return;
       }
-    }
-
-    if (insertBeforeEntity == null || body == null) {
+      if (executable.isSetter) {
+        return;
+      }
+      insertBeforeEntity = executable.operatorKeyword ??
+          executable.propertyKeyword ??
+          executable.name;
+      body = executable.body;
+    } else if (executable is FunctionDeclaration && executable.name == token) {
+      if (executable.returnType != null) {
+        return;
+      }
+      if (executable.isSetter) {
+        return;
+      }
+      insertBeforeEntity = executable.propertyKeyword ?? executable.name;
+      body = executable.functionExpression.body;
+    } else {
       return;
     }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart
index b5553aa..f878d59 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart
@@ -24,7 +24,7 @@
       return;
     }
 
-    var targetClassElement = targetClassNode.declaredElement2!;
+    var targetClassElement = targetClassNode.declaredElement!;
     var superType = targetClassElement.supertype;
     if (superType == null) {
       return;
@@ -50,7 +50,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [AddSuperConstructorInvocation] producer.
 class _AddInvocation extends CorrectionProducer {
   /// The constructor to be invoked.
@@ -106,6 +106,10 @@
           } else {
             builder.write(', ');
           }
+
+          if (parameter.isNamed) {
+            builder.write('${parameter.name}: ');
+          }
           // default value
           builder.addSimpleLinkedEdit(
               parameter.name, getDefaultValueCode(parameter.type));
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
index fc824f2..62ab0ae 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
@@ -47,12 +47,9 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     final node = this.node;
-    if (node is SimpleIdentifier) {
-      var parent = node.parent;
-      if (parent is SimpleFormalParameter) {
-        await _forSimpleFormalParameter(builder, node, parent);
-        return;
-      }
+    if (node is SimpleFormalParameter) {
+      await _forSimpleFormalParameter(builder, node.name!, node);
+      return;
     }
 
     for (var node in this.node.withParents) {
@@ -104,7 +101,7 @@
       var targetClassDeclaration =
           target.thisOrAncestorOfType<ClassDeclaration>();
       if (targetClassDeclaration != null) {
-        utils.targetClassElement = targetClassDeclaration.declaredElement2;
+        utils.targetClassElement = targetClassDeclaration.declaredElement;
       }
     }
   }
@@ -115,7 +112,7 @@
     if (declaredIdentifier.type != null) {
       return;
     }
-    var type = declaredIdentifier.declaredElement2!.type;
+    var type = declaredIdentifier.declaredElement!.type;
     if (type is! InterfaceType && type is! FunctionType) {
       return;
     }
@@ -123,8 +120,8 @@
         declaredIdentifier.name.offset, type);
   }
 
-  Future<void> _forSimpleFormalParameter(ChangeBuilder builder,
-      SimpleIdentifier name, SimpleFormalParameter parameter) async {
+  Future<void> _forSimpleFormalParameter(ChangeBuilder builder, Token name,
+      SimpleFormalParameter parameter) async {
     // Ensure that there isn't already a type annotation.
     if (parameter.type != null) {
       return;
@@ -150,7 +147,7 @@
     final variables = declarationList.variables;
     final variable = variables[0];
     // Ensure that the selection is not after the name of the variable.
-    if (selectionOffset > variable.name2.end) {
+    if (selectionOffset > variable.name.end) {
       return;
     }
     // Ensure that there is an initializer to get the type from.
@@ -183,7 +180,7 @@
     if (statement is! VariableDeclarationStatement || block is! Block) {
       return null;
     }
-    var element = variable.declaredElement2;
+    var element = variable.declaredElement;
     if (element is! LocalVariableElement) {
       return null;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
index fc50a38..5c05976 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
@@ -71,7 +71,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [ChangeArgumentName] producer.
 class _ChangeName extends CorrectionProducer {
   /// The name of the argument being changed.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
index dbe0e7b..21b68ae 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
@@ -113,7 +113,7 @@
     if (name != null) {
       // Prepare for selecting the closest element.
       var finder = _ClosestElementFinder(
-          name, (Element element) => element is ClassElement);
+          name, (Element element) => element is InterfaceElement);
       // Check elements of this library.
       if (prefixName == null) {
         for (var unit in resolvedResult.libraryElement.units) {
@@ -141,17 +141,17 @@
     if (target == null) {
       var clazz = this.node.thisOrAncestorOfType<ClassDeclaration>();
       if (clazz != null) {
-        var classElement = clazz.declaredElement2!;
-        _updateFinderWithClassMembers(finder, classElement);
+        var interfaceElement = clazz.declaredElement!;
+        _updateFinderWithClassMembers(finder, interfaceElement);
       }
     } else if (target is ExtensionOverride) {
       _updateFinderWithExtensionMembers(finder, target.staticElement);
     } else if (targetIdentifierElement is ExtensionElement) {
       _updateFinderWithExtensionMembers(finder, targetIdentifierElement);
     } else {
-      var classElement = getTargetClassElement(target);
-      if (classElement != null) {
-        _updateFinderWithClassMembers(finder, classElement);
+      var interfaceElement = getTargetInterfaceElement(target);
+      if (interfaceElement != null) {
+        _updateFinderWithClassMembers(finder, interfaceElement);
       }
     }
     // if we have close enough element, suggest to use it
@@ -268,17 +268,18 @@
   }
 
   Future<void> _proposeSuperFormalParameter(ChangeBuilder builder) async {
-    var parent = node.parent;
-    if (parent is! SuperFormalParameter) return;
+    final superParameter = node;
+    if (superParameter is! SuperFormalParameter) return;
 
     var constructorDeclaration =
-        parent.thisOrAncestorOfType<ConstructorDeclaration>();
+        superParameter.thisOrAncestorOfType<ConstructorDeclaration>();
     if (constructorDeclaration == null) return;
 
     var formalParameters = constructorDeclaration.parameters.parameters
         .whereType<DefaultFormalParameter>();
 
-    var finder = _ClosestElementFinder(parent.name.lexeme, (Element e) => true);
+    var finder =
+        _ClosestElementFinder(superParameter.name.lexeme, (Element e) => true);
 
     var superInvocation = constructorDeclaration.initializers.lastOrNull;
 
@@ -289,10 +290,11 @@
       var list = _formalParameterSuggestions(staticElement, formalParameters);
       finder._updateList(list);
     } else {
-      var targetClassNode = parent.thisOrAncestorOfType<ClassDeclaration>();
+      var targetClassNode =
+          superParameter.thisOrAncestorOfType<ClassDeclaration>();
       if (targetClassNode == null) return;
 
-      var targetClassElement = targetClassNode.declaredElement2!;
+      var targetClassElement = targetClassNode.declaredElement!;
       var superType = targetClassElement.supertype;
       if (superType == null) return;
 
@@ -306,7 +308,7 @@
     }
 
     // If we have a close enough element, suggest to use it.
-    await _suggest(builder, node, finder._element?.name);
+    await _suggest(builder, superParameter.name, finder._element?.name);
   }
 
   Future<void> _suggest(
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.dart
index c4bb940..05ca6a5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.dart
@@ -43,9 +43,9 @@
     }
 
     final target_final = target;
-    var declaringElement = invokedElement.enclosingElement3;
+    var declaringElement = invokedElement.enclosingElement;
 
-    if (declaringElement is ClassElement) {
+    if (declaringElement is InterfaceElement) {
       _className = declaringElement.name;
       await builder.addDartFileEdit(file, (builder) {
         builder.addReplacement(range.node(target_final), (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_enum.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_enum.dart
index 7baee11..b050fd1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_enum.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_enum.dart
@@ -51,9 +51,9 @@
       // the class.
       return;
     }
-    var parent = node.parent;
-    if (parent is ClassDeclaration && parent.name2 == token) {
-      var description = _EnumDescription.fromClass(parent);
+    final declaration = node;
+    if (declaration is ClassDeclaration && declaration.name == token) {
+      var description = _EnumDescription.fromClass(declaration);
       if (description != null) {
         await builder.addDartFileEdit(file, (builder) {
           description.applyChanges(builder, utils);
@@ -76,7 +76,7 @@
     var constructorElement = node.constructorName.staticElement;
     return constructorElement != null &&
         !constructorElement.isFactory &&
-        constructorElement.enclosingElement3 == classElement;
+        constructorElement.enclosingElement == classElement;
   }
 }
 
@@ -305,7 +305,7 @@
       return null;
     }
     var constructor = constructors[0];
-    var name = constructor.name2?.lexeme;
+    var name = constructor.name?.lexeme;
     if (name != null && name != 'new') {
       return null;
     }
@@ -347,7 +347,7 @@
   /// description of the conversion work to be done. Otherwise, return `null`.
   static _EnumDescription? fromClass(ClassDeclaration node) {
     // The class must be a concrete class.
-    var classElement = node.declaredElement2;
+    var classElement = node.declaredElement;
     if (classElement == null || classElement.isAbstract) {
       return null;
     }
@@ -516,7 +516,7 @@
     var constructors = _Constructors();
     for (var member in classDeclaration.members) {
       if (member is ConstructorDeclaration) {
-        var constructor = member.declaredElement2;
+        var constructor = member.declaredElement;
         if (constructor is ConstructorElement) {
           if (!classElement.isPrivate && !constructor.isPrivate) {
             // Public constructor in public enum.
@@ -550,7 +550,7 @@
         var fields = fieldList.variables;
         if (member.isStatic) {
           for (var field in fields) {
-            var fieldElement = field.declaredElement2;
+            var fieldElement = field.declaredElement;
             if (fieldElement is FieldElement) {
               var fieldType = fieldElement.type;
               // The field can be converted to be an enum constant if it
@@ -567,7 +567,7 @@
                       initializer.constructorName.staticElement;
                   if (constructorElement != null &&
                       !constructorElement.isFactory &&
-                      constructorElement.enclosingElement3 == classElement) {
+                      constructorElement.enclosingElement == classElement) {
                     var fieldValue = fieldElement.computeConstantValue();
                     if (fieldValue != null) {
                       if (fieldList.variables.length != 1) {
@@ -597,7 +597,7 @@
               // Non-final instance field.
               return null;
             }
-            var fieldElement = field.declaredElement2;
+            var fieldElement = field.declaredElement;
             if (fieldElement is FieldElement) {
               var fieldType = fieldElement.type;
               if (fieldElement.name == 'index' && fieldType.isDartCoreInt) {
@@ -630,7 +630,7 @@
   static bool _validateMethods(ClassDeclaration classDeclaration) {
     for (var member in classDeclaration.members) {
       if (member is MethodDeclaration) {
-        final name = member.name2.lexeme;
+        final name = member.name.lexeme;
         if (name == '==' || name == 'hashCode') {
           return false;
         }
@@ -697,7 +697,7 @@
       this.fieldDeclaration);
 
   /// Return the name of the field.
-  String get name => declaration.name2.lexeme;
+  String get name => declaration.name.lexeme;
 }
 
 /// A representation of all the fields of interest in the class being converted.
@@ -723,7 +723,7 @@
 
   @override
   void visitClassDeclaration(ClassDeclaration node) {
-    var element = node.declaredElement2;
+    var element = node.declaredElement;
     if (element == null) {
       throw _CannotConvertException('Unresolved');
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_mixin.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_mixin.dart
index 7d04dc0..f31dc29 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_mixin.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_mixin.dart
@@ -22,7 +22,7 @@
     if (classDeclaration == null) {
       return;
     }
-    if (selectionOffset > classDeclaration.name2.end ||
+    if (selectionOffset > classDeclaration.name.end ||
         selectionEnd < classDeclaration.classKeyword.offset) {
       return;
     }
@@ -36,7 +36,7 @@
     var superclassConstraints = <InterfaceType>[];
     var interfaces = <InterfaceType>[];
 
-    var classElement = classDeclaration.declaredElement2!;
+    var classElement = classDeclaration.declaredElement!;
     for (var type in classElement.mixins) {
       if (referencedClasses.contains(type.element2)) {
         superclassConstraints.add(type);
@@ -61,7 +61,7 @@
               classDeclaration.abstractKeyword ?? classDeclaration.classKeyword,
               classDeclaration.leftBracket), (builder) {
         builder.write('mixin ');
-        builder.write(classDeclaration.name2.lexeme);
+        builder.write(classDeclaration.name.lexeme);
         builder.writeTypeParameters(classElement.typeParameters);
         builder.writeTypes(superclassConstraints, prefix: ' on ');
         builder.writeTypes(interfaces, prefix: ' implements ');
@@ -97,7 +97,7 @@
 
   void _addElement(Element? element) {
     if (element is ExecutableElement) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement is ClassElement) {
         referencedClasses.add(enclosingElement);
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
index 64e21d8..01ae5e6 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
@@ -54,24 +54,26 @@
           return;
         }
         line = line.substring(expectedPrefix.length).trim();
+        if (line.endsWith('*/')) {
+          line = line.substring(0, line.length - 2).trim();
+        }
         if (line.isNotEmpty) {
           newLines.add('/// $line');
           linePrefix = eol + prefix;
         }
       } else {
-        if (line.startsWith('$prefix */')) {
+        line = line.trimLeft();
+        if (line.startsWith('*/')) {
           break;
         }
-        var expectedPrefix = '$prefix *';
-        if (!line.startsWith(expectedPrefix)) {
+        if (!line.startsWith('*')) {
           return;
         }
-        line = line.substring(expectedPrefix.length);
-        if (line.isEmpty) {
-          newLines.add('$linePrefix///');
-        } else {
-          newLines.add('$linePrefix///$line');
+        line = line.substring(1);
+        if (line.endsWith('*/')) {
+          line = line.substring(0, line.length - 2).trimRight();
         }
+        newLines.add('$linePrefix///$line');
         linePrefix = eol + prefix;
       }
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart
index 2307386..c8e9c08 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart
@@ -96,9 +96,9 @@
 
   ExecutableElement? _getFunctionElement(AstNode? node) {
     if (node is MethodDeclaration) {
-      return node.declaredElement2;
+      return node.declaredElement;
     } else if (node is ConstructorDeclaration) {
-      return node.declaredElement2;
+      return node.declaredElement;
     } else if (node is FunctionExpression) {
       return node.declaredElement;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_final_field.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_final_field.dart
index d8fef08..2870da6 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_final_field.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_final_field.dart
@@ -42,12 +42,12 @@
 
     // Check that there is no corresponding setter.
     {
-      var element = getter.declaredElement2;
+      var element = getter.declaredElement;
       if (element == null) {
         return;
       }
-      var enclosing = element.enclosingElement3;
-      if (enclosing is ClassElement) {
+      var enclosing = element.enclosingElement;
+      if (enclosing is InterfaceElement) {
         if (enclosing.getSetter(element.name) != null) {
           return;
         }
@@ -76,7 +76,7 @@
       if (returnType != null) {
         code += ' ${utils.getNodeText(returnType)}';
       }
-      code += ' ${getter.name2.lexeme}';
+      code += ' ${getter.name.lexeme}';
       if (expression is! NullLiteral) {
         code += ' = ${utils.getNodeText(expression)}';
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_getter.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_getter.dart
index 9fa75fc..1e06339 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_getter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_getter.dart
@@ -54,7 +54,7 @@
       code += '${utils.getNodeText(typeAnnotation)} ';
     }
     code += 'get';
-    code += ' ${field.name2.lexeme}';
+    code += ' ${field.name.lexeme}';
     code += ' => ${utils.getNodeText(initializer)}';
     code += ';';
     var replacementRange = range.startEnd(finalKeyword, fieldDeclaration);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not_empty.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not_empty.dart
index 2a1ab48..cc2ed4d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not_empty.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not_empty.dart
@@ -43,7 +43,7 @@
       return;
     }
     // should have "isNotEmpty"
-    var propertyTarget = propertyElement.enclosingElement3;
+    var propertyTarget = propertyElement.enclosingElement;
     if (propertyTarget == null ||
         getChildren(propertyTarget, 'isNotEmpty').isEmpty) {
       return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
index bb1adf8..df050b2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
@@ -42,7 +42,7 @@
     var element = creation.constructorName.staticElement;
     if (element == null ||
         element.name != 'fromIterable' ||
-        element.enclosingElement3 != typeProvider.mapElement) {
+        element.enclosingElement != typeProvider.mapElement) {
       return;
     }
     //
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart
index 3421dbd..1d316b9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart
@@ -88,18 +88,18 @@
 
   static _Context? _findParameter(AstNode node) {
     var parent = node.parent;
-    if (parent is SimpleFormalParameter) {
-      var identifier = parent.name;
+    if (node is SimpleFormalParameter) {
+      var identifier = node.name;
       if (identifier == null) return null;
 
-      var formalParameterList = parent.parent;
+      var formalParameterList = parent;
       if (formalParameterList is! FormalParameterList) return null;
 
       var constructor = formalParameterList.parent;
       if (constructor is! ConstructorDeclaration) return null;
 
       return _Context(
-        parameter: parent,
+        parameter: node,
         identifier: identifier,
         constructor: constructor,
       );
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
index 4727e20..45c4b99 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
@@ -76,7 +76,7 @@
     }
 
     var functionName = utils.getRangeText(
-        range.startEnd(node.name2, node.typeParameters ?? node.name2));
+        range.startEnd(node.name, node.typeParameters ?? node.name));
     var parameters = utils.getNodeText(node.parameters);
     String replacement;
     if (returnType == null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
index 2d7cbd2..efacfbcd 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
@@ -47,6 +47,8 @@
       await builder.addDartFileEdit(file, (builder) {
         builder.addReplacement(range.node(node), (builder) {
           builder.write(utils.getNodeText(nullableExpression));
+
+          if (defaultExpression is NullLiteral) return;
           builder.write(' ?? ');
           if (parentheses) {
             builder.write('(');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart
index f4bec66..2084c65 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart
@@ -15,10 +15,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var identifier = node;
-    if (identifier is! SimpleIdentifier) return;
-
-    var parameter = identifier.parent;
+    var parameter = node;
     if (parameter is! FieldFormalParameter) return;
 
     var parameterList = parameter.parent;
@@ -28,7 +25,7 @@
     if (constructor is! ConstructorDeclaration) return;
 
     var parameterElement = parameter.declaredElement!;
-    var name = identifier.name;
+    var name = parameter.name.lexeme;
     var type = parameterElement.type;
 
     await builder.addDartFileEdit(file, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
index 0fc2c61..b2429f7 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
@@ -19,14 +19,14 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     var exceptionParameter = node;
-    if (exceptionParameter is SimpleIdentifier) {
-      var catchClause = exceptionParameter.parent?.parent;
+    if (exceptionParameter is CatchClauseParameter) {
+      var catchClause = exceptionParameter.parent;
       if (catchClause is CatchClause) {
         var catchKeyword = catchClause.catchKeyword;
         var rightParenthesis = catchClause.rightParenthesis;
         if (catchKeyword != null &&
             catchClause.exceptionType == null &&
-            catchClause.exceptionParameter2?.name == exceptionParameter.token &&
+            catchClause.exceptionParameter2 == exceptionParameter &&
             rightParenthesis != null) {
           var exceptionTypeName = exceptionParameter.name;
           fixArguments.add(exceptionTypeName);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_super_parameters.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_super_parameters.dart
index d75f4ee..208bfbd 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_super_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_super_parameters.dart
@@ -298,6 +298,9 @@
   /// the name of a constructor.
   ConstructorDeclaration? _findConstructor() {
     final node = this.node;
+    if (node is ConstructorDeclaration) {
+      return node;
+    }
     if (node is SimpleIdentifier) {
       var parent = node.parent;
       if (parent is ConstructorDeclaration) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart
index 3b01b2f..f18ea38 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart
@@ -43,8 +43,7 @@
       }
       var parent = node.thisOrAncestorOfType<EnumConstantDeclaration>();
       if (parent != null) {
-        await _proposeFromEnumConstantDeclaration(
-            builder, parent.name2, parent);
+        await _proposeFromEnumConstantDeclaration(builder, parent.name, parent);
       }
     }
   }
@@ -109,7 +108,7 @@
     if (grandParent is! EnumDeclaration) {
       return;
     }
-    var targetElement = grandParent.declaredElement2;
+    var targetElement = grandParent.declaredElement;
     if (targetElement == null) {
       return;
     }
@@ -139,7 +138,7 @@
 
     var arguments = parent.arguments;
     _constructorName =
-        '${targetNode.name2.lexeme}${arguments?.constructorSelector ?? ''}';
+        '${targetNode.name.lexeme}${arguments?.constructorSelector ?? ''}';
 
     await _write(
       builder,
@@ -165,7 +164,7 @@
     }
 
     // prepare target ClassDeclaration
-    var targetElement = constructorElement.enclosingElement3;
+    var targetElement = constructorElement.enclosingElement;
     var targetResult = await sessionHelper.getElementDeclaration(targetElement);
     if (targetResult == null) {
       return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart
index 002f469..e2187b1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart
@@ -19,7 +19,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    if (node is! SimpleIdentifier || node.parent is! VariableDeclaration) {
+    if (node is! VariableDeclaration) {
       return;
     }
 
@@ -28,8 +28,8 @@
       return;
     }
 
-    var className = classDeclaration.name2.lexeme;
-    var superType = classDeclaration.declaredElement2?.supertype;
+    var className = classDeclaration.name.lexeme;
+    var superType = classDeclaration.declaredElement?.supertype;
     if (superType == null) {
       return;
     }
@@ -70,7 +70,7 @@
       for (var variableList in variableLists) {
         fieldNames.addAll(variableList.variables
             .where((v) => v.initializer == null)
-            .map((v) => v.name2.lexeme));
+            .map((v) => v.name.lexeme));
       }
 
       await builder.addDartFileEdit(file, (builder) {
@@ -143,7 +143,7 @@
     for (var variableList in variableLists) {
       var fieldNames = variableList.variables
           .where((v) => v.initializer == null)
-          .map((v) => v.name2.lexeme);
+          .map((v) => v.name.lexeme);
 
       for (var fieldName in fieldNames) {
         if (fieldName == 'child' || fieldName == 'children') {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart
index 498da4c..ba38547 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart
@@ -19,7 +19,7 @@
       return;
     }
 
-    var targetClassElement = targetClassNode.declaredElement2!;
+    var targetClassElement = targetClassNode.declaredElement!;
     var superType = targetClassElement.supertype;
     if (superType == null) {
       return;
@@ -40,7 +40,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [CreateConstructorSuper] producer.
 class _CreateConstructor extends CorrectionProducer {
   /// The constructor to be invoked.
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 33c0b85..a9ae969 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
@@ -79,7 +79,7 @@
     var staticModifier = false;
     InterfaceElement? targetClassElement;
     if (target != null) {
-      targetClassElement = getTargetClassElement(target);
+      targetClassElement = getTargetInterfaceElement(target);
       // maybe static
       if (target is Identifier) {
         var targetIdentifier = target;
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 ac13fd9..4ef6f5a 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
@@ -65,10 +65,10 @@
     }
     final classDecl = memberDecl.thisOrAncestorOfType<ClassDeclaration>();
     if (classDecl != null) {
-      final classElement = classDecl.declaredElement2!;
+      final classElement = classDecl.declaredElement!;
 
       var missingEquals = memberDecl is FieldDeclaration ||
-          (memberDecl as MethodDeclaration).name2.lexeme == 'hashCode';
+          (memberDecl as MethodDeclaration).name.lexeme == 'hashCode';
       ExecutableElement? element;
       if (missingEquals) {
         _memberName = '==';
@@ -147,7 +147,7 @@
         staticModifier = inStaticContext;
       }
     } else {
-      var targetClassElement = getTargetClassElement(target);
+      var targetClassElement = getTargetInterfaceElement(target);
       if (targetClassElement == null) {
         return;
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart
index 5d80e0e..5499446 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart
@@ -24,11 +24,11 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    if (node.parent is! ClassDeclaration) {
+    final targetClass = node;
+    if (targetClass is! ClassDeclaration) {
       return;
     }
-    var targetClass = node.parent as ClassDeclaration;
-    utils.targetClassElement = targetClass.declaredElement2;
+    utils.targetClassElement = targetClass.declaredElement;
     var signatures =
         InheritanceOverrideVerifier.missingOverrides(targetClass).toList();
     // sort by name, getters before setters
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.dart
index 86a1ed0..6994df9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.dart
@@ -14,10 +14,10 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    if (node.parent is! ClassDeclaration) {
+    final targetClass = node;
+    if (targetClass is! ClassDeclaration) {
       return;
     }
-    var targetClass = node.parent as ClassDeclaration;
     // prepare environment
     var prefix = utils.getIndent(1);
     var insertOffset = targetClass.end - 1;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart b/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
index 0512f36..09cc969 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
@@ -66,7 +66,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [DataDriven] producer.
 class DataDrivenFix extends CorrectionProducer {
   /// The transform being applied to implement this fix.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart b/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart
index 1757e44..96357d6 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart
@@ -35,13 +35,13 @@
       return;
     }
     // should have exactly one field
-    List<VariableDeclaration> fields = variableList.variables;
+    var fields = variableList.variables;
     if (fields.length != 1) {
       return;
     }
     var field = fields.first;
-    var nameToken = field.name2;
-    var fieldElement = field.declaredElement2 as FieldElement;
+    var nameToken = field.name;
+    var fieldElement = field.declaredElement as FieldElement;
     // should have a public name
     var name = nameToken.lexeme;
     if (Identifier.isPrivateName(name)) {
@@ -67,17 +67,42 @@
       // rename field
       builder.addSimpleReplacement(range.token(nameToken), '_$name');
       // update references in constructors
-      for (var member in classMembers) {
-        if (member is ConstructorDeclaration) {
-          for (var parameter in member.parameters.parameters) {
+      for (var constructor in classMembers) {
+        if (constructor is ConstructorDeclaration) {
+          for (var parameter in constructor.parameters.parameters) {
             var identifier = parameter.name;
             var parameterElement = parameter.declaredElement;
             if (identifier != null &&
                 parameterElement is FieldFormalParameterElement &&
                 parameterElement.field == fieldElement) {
+              if (parameter.isNamed && parameter is DefaultFormalParameter) {
+                var normalParam = parameter.parameter;
+                if (normalParam is FieldFormalParameter) {
+                  var start = normalParam.thisKeyword;
+                  var type = parameterElement.type
+                      .getDisplayString(withNullability: true);
+                  builder.addSimpleReplacement(
+                      range.startEnd(start, normalParam.period), '$type ');
+
+                  var previous =
+                      constructor.separator ?? constructor.parameters;
+                  var replacement = constructor.initializers.isEmpty
+                      ? ' : _$name = $name'
+                      : ' _$name = $name,';
+                  builder.addSimpleInsertion(previous.end, replacement);
+                  break;
+                }
+              }
               builder.addSimpleReplacement(range.token(identifier), '_$name');
             }
           }
+          for (var initializer in constructor.initializers) {
+            if (initializer is ConstructorFieldInitializer &&
+                initializer.fieldName.staticElement == fieldElement) {
+              builder.addSimpleReplacement(
+                  range.node(initializer.fieldName), '_$name');
+            }
+          }
         }
       }
 
@@ -111,8 +136,8 @@
           builder.write('  ');
           builder.writeln(docCode);
         }
-        builder.writeln('  set $name($typeCode$name) {');
-        builder.writeln('    _$name = $name;');
+        builder.writeln('  set $name(${typeCode}value) {');
+        builder.writeln('    _$name = value;');
         builder.write('  }');
       });
     });
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.dart b/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.dart
index 74eaf76..ee1735a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.dart
@@ -34,7 +34,7 @@
       _typeName = message.substring(startIndex, endIndex);
       await builder.addDartFileEdit(file, (builder) {
         builder.addSimpleInsertion(
-            declaration.typeParameters?.end ?? declaration.name2.end,
+            declaration.typeParameters?.end ?? declaration.name.end,
             ' extends $_typeName');
       });
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateful_widget.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateful_widget.dart
index 5675aa2..a4013bf 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateful_widget.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateful_widget.dart
@@ -35,7 +35,7 @@
     }
 
     // Must be a StatelessWidget subclass.
-    var widgetClassElement = widgetClass.declaredElement2!;
+    var widgetClassElement = widgetClass.declaredElement!;
     var superType = widgetClassElement.supertype;
     if (superType == null || !flutter.isExactlyStatelessWidgetType(superType)) {
       return;
@@ -66,7 +66,7 @@
     for (var member in widgetClass.members) {
       if (member is FieldDeclaration && !member.isStatic) {
         for (var fieldNode in member.fields.variables) {
-          var fieldElement = fieldNode.declaredElement2 as FieldElement;
+          var fieldElement = fieldNode.declaredElement as FieldElement;
           if (!fieldsAssignedInConstructors.contains(fieldElement)) {
             nodesToMove.add(member);
             elementsToMove.add(fieldElement);
@@ -84,7 +84,7 @@
         }
       } else if (member is MethodDeclaration && !member.isStatic) {
         nodesToMove.add(member);
-        elementsToMove.add(member.declaredElement2!);
+        elementsToMove.add(member.declaredElement!);
       }
     }
 
@@ -146,7 +146,7 @@
               builder.writeln('  @override');
               builder.write('  ');
               builder.writeReference(stateClass);
-              builder.write('<${widgetClass.name2.lexeme}$typeParams>');
+              builder.write('<${widgetClass.name.lexeme}$typeParams>');
               builder.writeln(' createState() => $stateName$typeParams();');
               if (hasEmptyLineAfterCreateState) {
                 builder.writeln();
@@ -205,7 +205,7 @@
         builder.writeReference(stateClass);
 
         // Write just param names (and not bounds, metadata and docs).
-        builder.write('<${widgetClass.name2.lexeme}');
+        builder.write('<${widgetClass.name.lexeme}');
         if (typeParameters != null) {
           builder.write('<');
           var first = true;
@@ -214,7 +214,7 @@
               builder.write(', ');
               first = false;
             }
-            builder.write(param.name2.lexeme);
+            builder.write(param.name.lexeme);
           }
           builder.write('>');
         }
@@ -247,7 +247,7 @@
 
   MethodDeclaration? _findBuildMethod(ClassDeclaration widgetClass) {
     for (var member in widgetClass.members) {
-      if (member is MethodDeclaration && member.name2.lexeme == 'build') {
+      if (member is MethodDeclaration && member.name.lexeme == 'build') {
         var parameters = member.parameters;
         if (parameters != null && parameters.parameters.length == 1) {
           return member;
@@ -262,16 +262,20 @@
   Set<FieldElement> fieldsAssignedInConstructors = {};
 
   @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    if (node.parent is FieldFormalParameter) {
-      var element = node.staticElement;
-      if (element is FieldFormalParameterElement) {
-        var field = element.field;
-        if (field != null) {
-          fieldsAssignedInConstructors.add(field);
-        }
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    final element = node.declaredElement;
+    if (element is FieldFormalParameterElement) {
+      var field = element.field;
+      if (field != null) {
+        fieldsAssignedInConstructors.add(field);
       }
     }
+
+    super.visitFieldFormalParameter(node);
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
     if (node.parent is ConstructorFieldInitializer) {
       var element = node.staticElement;
       if (element is FieldElement) {
@@ -309,7 +313,7 @@
     }
     var element = node.staticElement;
     if (element is ExecutableElement &&
-        element.enclosingElement3 == widgetClassElement &&
+        element.enclosingElement == widgetClassElement &&
         !elementsToMove.contains(element)) {
       var offset = node.offset - linesRange.offset;
       var qualifier =
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateless_widget.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateless_widget.dart
index ff11699..f635044 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateless_widget.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateless_widget.dart
@@ -36,7 +36,7 @@
     }
 
     // Must be a StatefulWidget subclass.
-    var widgetClassElement = widgetClass.declaredElement2!;
+    var widgetClassElement = widgetClass.declaredElement!;
     var superType = widgetClassElement.supertype;
     if (superType == null || !flutter.isExactlyStatefulWidgetType(superType)) {
       return;
@@ -46,10 +46,10 @@
     if (createStateMethod == null) return;
 
     var stateClass = _findStateClass(widgetClassElement);
-    var stateClassElement = stateClass?.declaredElement2;
+    var stateClassElement = stateClass?.declaredElement;
     if (stateClass == null ||
         stateClassElement == null ||
-        !Identifier.isPrivateName(stateClass.name2.lexeme) ||
+        !Identifier.isPrivateName(stateClass.name.lexeme) ||
         !_isSameTypeParameters(widgetClass, stateClass)) {
       return;
     }
@@ -84,7 +84,7 @@
           return;
         }
         for (var fieldNode in member.fields.variables) {
-          var fieldElement = fieldNode.declaredElement2 as FieldElement;
+          var fieldElement = fieldNode.declaredElement as FieldElement;
           if (!fieldsAssignedInConstructors.contains(fieldElement)) {
             nodesToMove.add(member);
             elementsToMove.add(fieldElement);
@@ -106,7 +106,7 @@
         }
         if (!_isDefaultOverride(member)) {
           nodesToMove.add(member);
-          elementsToMove.add(member.declaredElement2!);
+          elementsToMove.add(member.declaredElement!);
         }
       }
     }
@@ -171,7 +171,7 @@
 
   MethodDeclaration? _findCreateStateMethod(ClassDeclaration widgetClass) {
     for (var member in widgetClass.members) {
-      if (member is MethodDeclaration && member.name2.lexeme == 'createState') {
+      if (member is MethodDeclaration && member.name.lexeme == 'createState') {
         var parameters = member.parameters;
         if (parameters?.parameters.isEmpty ?? false) {
           return member;
@@ -215,7 +215,7 @@
     outer:
     for (var stateParam in stateParams) {
       for (var widgetParam in widgetParams) {
-        if (stateParam.name2.lexeme == widgetParam.name2.lexeme &&
+        if (stateParam.name.lexeme == widgetParam.name.lexeme &&
             stateParam.bound?.type == widgetParam.bound?.type) {
           continue outer;
         }
@@ -243,7 +243,7 @@
       }
       if (expression is MethodInvocation &&
           expression.target is SuperExpression &&
-          methodDeclaration!.name2.lexeme == expression.methodName.name) {
+          methodDeclaration!.name.lexeme == expression.methodName.name) {
         return true;
       }
     }
@@ -316,7 +316,7 @@
     }
     var element = node.staticElement;
     if (element is ExecutableElement &&
-        element.enclosingElement3 == widgetClassElement &&
+        element.enclosingElement == widgetClassElement &&
         !elementsToMove.contains(element)) {
       var parent = node.parent;
       if (parent is PrefixedIdentifier) {
@@ -343,7 +343,7 @@
         var target = parent.target;
         var operator = parent.operator;
         if (target != null && operator != null) {
-          var offset = target.beginToken.offset;
+          var offset = target.offset;
           var length = operator.end - offset;
           edits.add(SourceEdit(offset - linesRange.offset, length, ''));
         }
@@ -359,7 +359,7 @@
   void visitMethodInvocation(MethodInvocation node) {
     var methodElement = node.methodName.staticElement?.declaration;
     if (methodElement is ClassMemberElement) {
-      var classElement = methodElement.enclosingElement3;
+      var classElement = methodElement.enclosingElement;
       if (classElement is ClassElement &&
           Flutter.instance.isExactState(classElement) &&
           !FlutterConvertToStatelessWidget._isDefaultOverride(
@@ -390,8 +390,8 @@
     var classDeclaration =
         methodDeclaration?.thisOrAncestorOfType<ClassDeclaration>();
 
-    if (methodDeclaration?.name2.lexeme != 'createState' ||
-        classDeclaration?.declaredElement2 != widgetClassElement) {
+    if (methodDeclaration?.name.lexeme != 'createState' ||
+        classDeclaration?.declaredElement != widgetClassElement) {
       used = true;
     }
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart
index fc06a4f..de86121 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart
@@ -6,10 +6,14 @@
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.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';
+import 'package:collection/collection.dart';
 
 class FlutterRemoveWidget extends CorrectionProducer {
   @override
@@ -47,25 +51,42 @@
     } else {
       var childArgument = flutter.findChildArgument(widgetCreation);
       if (childArgument != null) {
-        await _removeChild(builder, widgetCreation, childArgument);
+        await _removeSingle(builder, widgetCreation, childArgument.expression);
+      } else {
+        var builderArgument = flutter.findBuilderArgument(widgetCreation);
+        if (builderArgument != null) {
+          await _removeBuilder(builder, widgetCreation, builderArgument);
+        }
       }
     }
   }
 
-  Future<void> _removeChild(
+  Future<void> _removeBuilder(
       ChangeBuilder builder,
       InstanceCreationExpression widgetCreation,
-      NamedExpression childArgument) async {
-    // child: ThisWidget(child: ourChild)
-    // children: [foo, ThisWidget(child: ourChild), bar]
-    await builder.addDartFileEdit(file, (builder) {
-      var childExpression = childArgument.expression;
-      var childText = utils.getNodeText(childExpression);
-      var indentOld = utils.getLinePrefix(childExpression.offset);
-      var indentNew = utils.getLinePrefix(widgetCreation.offset);
-      childText = replaceSourceIndent(childText, indentOld, indentNew);
-      builder.addSimpleReplacement(range.node(widgetCreation), childText);
-    });
+      NamedExpression builderArgument) async {
+    var builderExpression = builderArgument.expression;
+    if (builderExpression is! FunctionExpression) return;
+    var parameterElement =
+        builderExpression.parameters?.parameters.firstOrNull?.declaredElement;
+    if (parameterElement == null) return;
+
+    var visitor = _UsageFinder(parameterElement);
+    var body = builderExpression.body;
+    body.visitChildren(visitor);
+    if (visitor.used) return;
+
+    if (body is BlockFunctionBody) {
+      var statements = body.block.statements;
+      if (statements.length != 1) return;
+      var statement = statements.first;
+      if (statement is! ReturnStatement) return;
+      var expression = statement.expression;
+      if (expression == null) return;
+      await _removeSingle(builder, widgetCreation, expression);
+    } else if (body is ExpressionFunctionBody) {
+      await _removeSingle(builder, widgetCreation, body.expression);
+    }
   }
 
   Future<void> _removeChildren(
@@ -88,4 +109,32 @@
       builder.addSimpleReplacement(range.node(widgetCreation), childText);
     });
   }
+
+  Future<void> _removeSingle(
+    ChangeBuilder builder,
+    InstanceCreationExpression widgetCreation,
+    Expression expression,
+  ) async {
+    await builder.addDartFileEdit(file, (builder) {
+      var childText = utils.getNodeText(expression);
+      var indentOld = utils.getLinePrefix(expression.offset);
+      var indentNew = utils.getLinePrefix(widgetCreation.offset);
+      childText = replaceSourceIndent(childText, indentOld, indentNew);
+      builder.addSimpleReplacement(range.node(widgetCreation), childText);
+    });
+  }
+}
+
+class _UsageFinder extends RecursiveAstVisitor<void> {
+  final Element element;
+  bool used = false;
+
+  _UsageFinder(this.element);
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    if (node.writeOrReadElement == element) {
+      used = true;
+    }
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart
index 50f4251..bacec0c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart
@@ -89,7 +89,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [FlutterWrap] producer.
 class _FlutterWrapCenter extends _WrapSingleWidget {
   _FlutterWrapCenter(super.widgetExpr);
@@ -104,7 +104,7 @@
   String get _parentLibraryUri => flutter.widgetsUri;
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [FlutterWrap] producer.
 class _FlutterWrapColumn extends _WrapMultipleWidgets {
   _FlutterWrapColumn(super.firstWidget, super.lastWidget);
@@ -116,7 +116,7 @@
   String get _parentClassName => 'Column';
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [FlutterWrap] producer.
 class _FlutterWrapContainer extends _WrapSingleWidget {
   _FlutterWrapContainer(super.widgetExpr);
@@ -131,7 +131,7 @@
   String get _parentLibraryUri => flutter.widgetsUri;
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [FlutterWrap] producer.
 class _FlutterWrapGeneric extends _WrapSingleWidget {
   _FlutterWrapGeneric(super.widgetExpr);
@@ -140,7 +140,7 @@
   AssistKind get assistKind => DartAssistKind.FLUTTER_WRAP_GENERIC;
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [FlutterWrap] producer.
 class _FlutterWrapPadding extends _WrapSingleWidget {
   _FlutterWrapPadding(super.widgetExpr);
@@ -161,7 +161,7 @@
   String get _parentLibraryUri => flutter.widgetsUri;
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [FlutterWrap] producer.
 class _FlutterWrapRow extends _WrapMultipleWidgets {
   _FlutterWrapRow(super.firstWidget, super.lastWidget);
@@ -173,7 +173,7 @@
   String get _parentClassName => 'Row';
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [FlutterWrap] producer.
 class _FlutterWrapSizedBox extends _WrapSingleWidget {
   _FlutterWrapSizedBox(super.widgetExpr);
@@ -188,7 +188,7 @@
   String get _parentLibraryUri => flutter.widgetsUri;
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [FlutterWrap] producer.
 abstract class _WrapMultipleWidgets extends CorrectionProducer {
   final Expression firstWidget;
@@ -245,7 +245,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [FlutterWrap] producer.
 abstract class _WrapSingleWidget extends CorrectionProducer {
   final Expression widgetExpr;
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 b5454bb..9badb6c 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
@@ -356,11 +356,11 @@
     DartType? enclosingThisType(AstNode node) {
       var parent = node.parent;
       if (parent is ClassDeclaration) {
-        return parent.declaredElement2?.thisType;
+        return parent.declaredElement?.thisType;
       } else if (parent is ExtensionDeclaration) {
         return parent.extendedType.type;
       } else if (parent is MixinDeclaration) {
-        return parent.declaredElement2?.thisType;
+        return parent.declaredElement?.thisType;
       } else {
         return null;
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart b/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
index 3cd39a5..2ec1d55 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
@@ -31,10 +31,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var parent = node.parent;
-    if (parent == null) {
-      return;
-    }
+    final node = this.node;
 
     //
     // Extract the information needed to build the edit.
@@ -42,21 +39,21 @@
     TypeAnnotation? returnType;
     TypeParameterList? typeParameters;
     List<FormalParameter> parameters;
-    if (parent is FunctionTypeAlias) {
-      returnType = parent.returnType;
-      _name = parent.name2.lexeme;
-      typeParameters = parent.typeParameters;
-      parameters = parent.parameters.parameters;
-    } else if (parent is GenericTypeAlias) {
-      if (parent.typeParameters != null) {
+    if (node is FunctionTypeAlias) {
+      returnType = node.returnType;
+      _name = node.name.lexeme;
+      typeParameters = node.typeParameters;
+      parameters = node.parameters.parameters;
+    } else if (node is GenericTypeAlias) {
+      if (node.typeParameters != null) {
         return;
       }
-      var functionType = parent.functionType;
+      var functionType = node.functionType;
       if (functionType == null) {
         return;
       }
       returnType = functionType.returnType;
-      _name = parent.name2.lexeme;
+      _name = node.name.lexeme;
       typeParameters = functionType.typeParameters;
       parameters = functionType.parameters.parameters;
     } else {
@@ -73,7 +70,7 @@
     // Build the edit.
     //
     await builder.addDartFileEdit(file, (builder) {
-      builder.addDeletion(utils.getLinesRange(range.node(parent)));
+      builder.addDeletion(utils.getLinesRange(range.node(node)));
       builder.addReplacement(range.node(reference), (builder) {
         if (returnType != null) {
           builder.write(utils.getNodeText(returnType));
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/join_variable_declaration.dart b/pkg/analysis_server/lib/src/services/correction/dart/join_variable_declaration.dart
index 1c7b999..54a8773 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/join_variable_declaration.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/join_variable_declaration.dart
@@ -75,7 +75,7 @@
     // The declared variable must be the one that is assigned.
     // There must be no initializer.
     var declaredVariable = declaredVariables.single;
-    if (declaredVariable.declaredElement2 != left.staticElement ||
+    if (declaredVariable.declaredElement != left.staticElement ||
         declaredVariable.initializer != null) {
       return;
     }
@@ -137,7 +137,7 @@
     }
 
     // The assignment should write into the declared variable.
-    if (assignment.writeElement != declaredVariable.declaredElement2) {
+    if (assignment.writeElement != declaredVariable.declaredElement) {
       return;
     }
 
@@ -148,7 +148,7 @@
 
     await builder.addDartFileEdit(file, (builder) {
       builder.addSimpleReplacement(
-        range.endStart(declaredVariable.name2, assignment.operator),
+        range.endStart(declaredVariable.name, assignment.operator),
         ' ',
       );
     });
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.dart
index 826fb84..d034ed3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.dart
@@ -23,7 +23,7 @@
     if (enclosingClass == null) {
       return;
     }
-    _className = enclosingClass.name2.lexeme;
+    _className = enclosingClass.name.lexeme;
     await builder.addDartFileEdit(file, (builder) {
       builder.addSimpleInsertion(
           enclosingClass.classKeyword.offset, 'abstract ');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart
index 3a9a404..e667453 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart
@@ -45,7 +45,7 @@
     }
 
     // It must be a field declaration.
-    if (getter.enclosingElement3 is! ClassElement) {
+    if (getter.enclosingElement is! ClassElement) {
       return;
     }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_field_public.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_field_public.dart
index f80a9ed..4790e44a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_field_public.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_field_public.dart
@@ -21,18 +21,15 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var node = this.node;
-    if (node is! SimpleIdentifier) {
+    final declaration = node;
+    if (declaration is! MethodDeclaration) {
       return;
     }
-    var getterName = node.name;
+    var getterName = declaration.name.lexeme;
     _fieldName = '_$getterName';
-    var parent = node.parent;
-    if (parent is MethodDeclaration &&
-        parent.name2 == token &&
-        parent.isGetter) {
+    if (declaration.name == token && declaration.isGetter) {
       NodeList<ClassMember> members;
-      var container = parent.parent;
+      var container = declaration.parent;
       if (container is ClassDeclaration) {
         members = container.members;
       } else if (container is MixinDeclaration) {
@@ -45,12 +42,12 @@
       VariableDeclaration? field;
       for (var member in members) {
         if (member is MethodDeclaration &&
-            member.name2.lexeme == getterName &&
+            member.name.lexeme == getterName &&
             member.isSetter) {
           setter = member;
         } else if (member is FieldDeclaration) {
           for (var variable in member.fields.variables) {
-            if (variable.name2.lexeme == _fieldName) {
+            if (variable.name.lexeme == _fieldName) {
               field = variable;
             }
           }
@@ -60,8 +57,8 @@
         return;
       }
       await builder.addDartFileEdit(file, (builder) {
-        builder.addSimpleReplacement(range.token(field!.name2), getterName);
-        builder.removeMember(members, parent);
+        builder.addSimpleReplacement(range.token(field!.name), getterName);
+        builder.removeMember(members, declaration);
         builder.removeMember(members, setter!);
       });
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
index c3dbb10..9c0a06d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
@@ -26,18 +26,15 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     final node = this.node;
-    var parent = node.parent;
-    var grandParent = parent?.parent;
+    final parent = node.parent;
 
-    if (node is SimpleIdentifier &&
-        parent is DeclaredIdentifier &&
-        grandParent is ForEachPartsWithDeclaration) {
+    if (node is DeclaredIdentifier && parent is ForEachPartsWithDeclaration) {
       await builder.addDartFileEdit(file, (builder) {
-        var keyword = parent.keyword;
+        var keyword = node.keyword;
         if (keyword != null && keyword.keyword == Keyword.VAR) {
           builder.addSimpleReplacement(range.token(keyword), 'final');
         } else if (keyword == null) {
-          builder.addSimpleInsertion(parent.offset, 'final ');
+          builder.addSimpleInsertion(node.offset, 'final ');
         }
       });
       return;
@@ -73,20 +70,15 @@
       return;
     }
 
-    if (node is SimpleIdentifier && parent is SimpleFormalParameter) {
+    if (node is SimpleFormalParameter) {
       await builder.addDartFileEdit(file, (builder) {
-        builder.addSimpleInsertion(node.offset, 'final ');
+        builder.addSimpleInsertion(node.name!.offset, 'final ');
       });
       return;
     }
 
     VariableDeclarationList list;
-    if (node is SimpleIdentifier &&
-        parent is VariableDeclaration &&
-        grandParent is VariableDeclarationList) {
-      list = grandParent;
-    } else if (node is VariableDeclaration &&
-        parent is VariableDeclarationList) {
+    if (node is VariableDeclaration && parent is VariableDeclarationList) {
       list = parent;
     } else if (node is VariableDeclarationList) {
       list = node;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.dart
index 8a77e88..14dbeb3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.dart
@@ -33,8 +33,7 @@
       return;
     }
 
-    var id = NodeLocator(variable.nameOffset).searchWithin(unit);
-    var declaration = id?.parent;
+    var declaration = NodeLocator(variable.nameOffset).searchWithin(unit);
     var declarationList = declaration?.parent;
 
     if (declaration is VariableDeclaration &&
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_variable_nullable.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_variable_nullable.dart
index 5181b0a..51d635c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_variable_nullable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_variable_nullable.dart
@@ -28,26 +28,24 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var node = coveredNode;
-    var parent = node?.parent;
+    final node = this.node;
     if (unit.featureSet.isEnabled(Feature.non_nullable)) {
-      if (node is SimpleIdentifier && parent is SimpleFormalParameter) {
-        await _forSimpleFormalParameter(builder, node, parent);
-      } else if (node is SimpleIdentifier &&
-          parent is FunctionTypedFormalParameter) {
-        await _forFunctionTypedFormalParameter(builder, node, parent);
-      } else if (node is SimpleIdentifier && parent is FieldFormalParameter) {
-        await _forFieldFormalParameter(builder, node, parent);
-      } else if (node is SimpleIdentifier && parent is SuperFormalParameter) {
-        await _forSuperFormalParameter(builder, node, parent);
-      } else if (node is Expression &&
-          parent is AssignmentExpression &&
-          parent.rightHandSide == node) {
-        await _forAssignment(builder, node, parent);
-      } else if (node is Expression &&
-          parent is VariableDeclaration &&
-          parent.initializer == node) {
-        await _forVariableDeclaration(builder, node, parent);
+      if (node is SimpleFormalParameter) {
+        await _forSimpleFormalParameter(builder, node);
+      } else if (node is FunctionTypedFormalParameter) {
+        await _forFunctionTypedFormalParameter(builder, node);
+      } else if (node is FieldFormalParameter) {
+        await _forFieldFormalParameter(builder, node);
+      } else if (node is SuperFormalParameter) {
+        await _forSuperFormalParameter(builder, node);
+      } else if (node is Expression) {
+        final parent = node.parent;
+        if (parent is AssignmentExpression && parent.rightHandSide == node) {
+          await _forAssignment(builder, node, parent);
+        } else if (parent is VariableDeclaration &&
+            parent.initializer == node) {
+          await _forVariableDeclaration(builder, node, parent);
+        }
       }
     }
   }
@@ -63,7 +61,7 @@
         if (statement is VariableDeclarationStatement) {
           var variableList = statement.variables;
           for (var declaration in variableList.variables) {
-            if (declaration.declaredElement2 == variable) {
+            if (declaration.declaredElement == variable) {
               return variableList;
             }
           }
@@ -111,8 +109,8 @@
   }
 
   /// Makes [parameter] nullable if possible.
-  Future<void> _forFieldFormalParameter(ChangeBuilder builder,
-      SimpleIdentifier name, FieldFormalParameter parameter) async {
+  Future<void> _forFieldFormalParameter(
+      ChangeBuilder builder, FieldFormalParameter parameter) async {
     if (parameter.parameters != null) {
       // A function-typed field formal parameter.
       if (parameter.question != null) {
@@ -121,7 +119,7 @@
       _variableName = parameter.name.lexeme;
       await builder.addDartFileEdit(file, (builder) {
         // Add '?' after `)`.
-        builder.addSimpleInsertion(parameter.endToken.end, '?');
+        builder.addSimpleInsertion(parameter.end, '?');
       });
     } else {
       var type = parameter.type;
@@ -136,20 +134,20 @@
   }
 
   /// Makes [parameter] nullable if possible.
-  Future<void> _forFunctionTypedFormalParameter(ChangeBuilder builder,
-      SimpleIdentifier name, FunctionTypedFormalParameter parameter) async {
+  Future<void> _forFunctionTypedFormalParameter(
+      ChangeBuilder builder, FunctionTypedFormalParameter parameter) async {
     if (parameter.question != null) {
       return;
     }
     _variableName = parameter.name.lexeme;
     await builder.addDartFileEdit(file, (builder) {
       // Add '?' after `)`.
-      builder.addSimpleInsertion(parameter.endToken.end, '?');
+      builder.addSimpleInsertion(parameter.end, '?');
     });
   }
 
-  Future<void> _forSimpleFormalParameter(ChangeBuilder builder,
-      SimpleIdentifier name, SimpleFormalParameter parameter) async {
+  Future<void> _forSimpleFormalParameter(
+      ChangeBuilder builder, SimpleFormalParameter parameter) async {
     var type = parameter.type;
     if (type == null || !_typeCanBeMadeNullable(type)) {
       return;
@@ -167,8 +165,8 @@
   }
 
   /// Makes [parameter] nullable if possible.
-  Future<void> _forSuperFormalParameter(ChangeBuilder builder,
-      SimpleIdentifier name, SuperFormalParameter parameter) async {
+  Future<void> _forSuperFormalParameter(
+      ChangeBuilder builder, SuperFormalParameter parameter) async {
     if (parameter.parameters != null) {
       // A function-typed field formal parameter.
       if (parameter.question != null) {
@@ -177,7 +175,7 @@
       _variableName = parameter.name.lexeme;
       await builder.addDartFileEdit(file, (builder) {
         // Add '?' after `)`.
-        builder.addSimpleInsertion(parameter.endToken.end, '?');
+        builder.addSimpleInsertion(parameter.end, '?');
       });
     } else {
       var type = parameter.type;
@@ -201,7 +199,7 @@
       return;
     }
 
-    var oldType = parent.declaredElement2!.type;
+    var oldType = parent.declaredElement!.type;
     if (oldType is! InterfaceTypeImpl) {
       return;
     }
@@ -226,7 +224,7 @@
   Future<void> _updateVariableType(ChangeBuilder builder,
       VariableDeclarationList declarationList, DartType newType) async {
     var variable = declarationList.variables[0];
-    _variableName = variable.name2.lexeme;
+    _variableName = variable.name.lexeme;
     await builder.addDartFileEdit(file, (builder) {
       var keyword = declarationList.keyword;
       if (keyword != null && keyword.type == Keyword.VAR) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.dart b/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.dart
index 21b7a43..07e51bb 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.dart
@@ -40,7 +40,7 @@
       return;
     }
 
-    var enclosingElement = memberElement.enclosingElement3;
+    var enclosingElement = memberElement.enclosingElement;
     if (enclosingElement == null ||
         enclosingElement.library != libraryElement) {
       // TODO(brianwilkerson) Support qualifying references to members defined
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_abstract.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_abstract.dart
index 9e94840..0cac215 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_abstract.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_abstract.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/source/source_range.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -37,16 +38,24 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var node = this.node;
-    if (node is SimpleIdentifier) {
-      await _compute(node, builder);
+    final node = this.node;
+    final parent = node.parent;
+    final classDeclaration = node.thisOrAncestorOfType<ClassDeclaration>();
+    if (node is VariableDeclaration) {
+      await _compute(classDeclaration, node.declaredElement, builder);
+    } else if (node is SimpleIdentifier &&
+        parent is ConstructorFieldInitializer) {
+      await _compute(classDeclaration, node.staticElement, builder);
     } else if (node is CompilationUnitMember) {
       await _computeAbstractClassMember(builder);
     }
   }
 
-  Future<void> _compute(SimpleIdentifier node, ChangeBuilder builder) async {
-    var classDeclaration = node.thisOrAncestorOfType<ClassDeclaration>();
+  Future<void> _compute(
+    ClassDeclaration? classDeclaration,
+    Element? fieldElement,
+    ChangeBuilder builder,
+  ) async {
     if (classDeclaration == null) return;
 
     for (var member in classDeclaration.members) {
@@ -59,7 +68,7 @@
           continue;
         }
         for (var variable in variables) {
-          if (variable.declaredElement2 == node.staticElement) {
+          if (variable.declaredElement == fieldElement) {
             var abstractKeyword = member.abstractKeyword;
             if (abstractKeyword != null) {
               await builder.addDartFileEdit(file, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
index 93362fb..1c332c4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
@@ -5,7 +5,6 @@
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/ast.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';
@@ -55,15 +54,12 @@
       await addFix(findAnnotation(node.parameter.metadata, 'required'));
     } else if (node is NormalFormalParameter) {
       await addFix(findAnnotation(node.metadata, 'required'));
-    } else if (node is DeclaredSimpleIdentifier) {
-      var parent = node.parent;
-      if (parent is MethodDeclaration) {
-        await addFix(findAnnotation(parent.metadata, 'override'));
-      } else if (parent is VariableDeclaration) {
-        var fieldDeclaration = parent.thisOrAncestorOfType<FieldDeclaration>();
-        if (fieldDeclaration != null) {
-          await addFix(findAnnotation(fieldDeclaration.metadata, 'override'));
-        }
+    } else if (node is MethodDeclaration) {
+      await addFix(findAnnotation(node.metadata, 'override'));
+    } else if (node is VariableDeclaration) {
+      var fieldDeclaration = node.thisOrAncestorOfType<FieldDeclaration>();
+      if (fieldDeclaration != null) {
+        await addFix(findAnnotation(fieldDeclaration.metadata, 'override'));
       }
     }
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_constructor_name.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_constructor_name.dart
index e168cf6..fbd01c9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_constructor_name.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_constructor_name.dart
@@ -24,13 +24,17 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    final identifier = node;
-    if (identifier is! SimpleIdentifier) return;
-
-    // The '.' in ".new"
-    var dotToken = identifier.token.previous!;
-    await builder.addDartFileEdit(file, (builder) {
-      builder.addDeletion(range.startStart(dotToken, identifier.token.next!));
-    });
+    final node = this.node;
+    if (node is ConstructorDeclaration) {
+      await builder.addDartFileEdit(file, (builder) {
+        builder.addDeletion(range.startStart(node.period!, node.name!.next!));
+      });
+    } else if (node is SimpleIdentifier) {
+      // The '.' in ".new"
+      var dotToken = node.token.previous!;
+      await builder.addDartFileEdit(file, (builder) {
+        builder.addDeletion(range.startStart(dotToken, node.token.next!));
+      });
+    }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart
index d203609..5d9596d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart
@@ -54,7 +54,7 @@
       if (variable != null && initializer != null) {
         await builder.addDartFileEdit(file, (builder) {
           builder.addDeletion(
-            range.endEnd(variable.name2, initializer),
+            range.endEnd(variable.name, initializer),
           );
         });
       } else {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_leading_underscore.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_leading_underscore.dart
index 756474d..76a82d2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_leading_underscore.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_leading_underscore.dart
@@ -6,6 +6,7 @@
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -26,21 +27,35 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var identifier = node;
-    if (identifier is! SimpleIdentifier) {
+    final node = this.node;
+    final Token? nameToken;
+    final Element? element;
+    if (node is SimpleIdentifier) {
+      nameToken = node.token;
+      element = node.staticElement;
+    } else if (node is FormalParameter) {
+      nameToken = node.name;
+      element = node.declaredElement;
+    } else if (node is VariableDeclaration) {
+      nameToken = node.name;
+      element = node.declaredElement;
+    } else {
       return;
     }
 
-    var name = identifier.name;
-    if (name.length < 2) {
+    if (nameToken == null || element == null) {
       return;
     }
 
-    var newName = name.substring(1);
+    final oldName = nameToken.lexeme;
+    if (oldName.length < 2) {
+      return;
+    }
+
+    var newName = oldName.substring(1);
 
     // Find references to the identifier.
     List<SimpleIdentifier>? references;
-    var element = identifier.staticElement;
     if (element is LocalVariableElement) {
       var root = node.thisOrAncestorOfType<Block>();
       if (root != null) {
@@ -68,10 +83,13 @@
     }
 
     // Compute the change.
-    var references_final = references;
+    final sourceRanges = {
+      range.token(nameToken),
+      ...references.map(range.node),
+    };
     await builder.addDartFileEdit(file, (builder) {
-      for (var reference in references_final) {
-        builder.addSimpleReplacement(range.node(reference), newName);
+      for (var sourceRange in sourceRanges) {
+        builder.addSimpleReplacement(sourceRange, newName);
       }
     });
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.dart
index a239ba6..69409b5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.dart
@@ -20,7 +20,7 @@
     final node = this.node;
     if (node is MethodDeclaration) {
       // Support for the analyzer error.
-      var name = node.name2;
+      var name = node.name;
       var body = node.body;
       await builder.addDartFileEdit(file, (builder) {
         builder.addSimpleReplacement(range.endStart(name, body), ' ');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_required.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_required.dart
index b738440..bf785d4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_required.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_required.dart
@@ -23,10 +23,10 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var parent = node.parent;
-    if (parent is! FormalParameter) return;
+    final node = this.node;
+    if (node is! FormalParameter) return;
 
-    var required = parent.requiredKeyword;
+    var required = node.requiredKeyword;
     if (required == null) return;
 
     await builder.addDartFileEdit(file, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
index fb8a5fa..f514e4d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
@@ -55,12 +55,12 @@
     }
     // ignore if an incomplete variable declaration
     if (declarationList.variables.length == 1 &&
-        declarationList.variables[0].name2.isSynthetic) {
+        declarationList.variables[0].name.isSynthetic) {
       return;
     }
     // must be not after the name of the variable
     var firstVariable = declarationList.variables[0];
-    if (selectionOffset > firstVariable.name2.end) {
+    if (selectionOffset > firstVariable.name.end) {
       return;
     }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_late.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_late.dart
index 7dbcafc..9a08396 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_late.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_late.dart
@@ -24,7 +24,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    final declaration = node.parent;
+    final declaration = node;
     if (declaration is! VariableDeclaration) {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
index b1ff2f3..d424988 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
@@ -30,11 +30,7 @@
   Future<void> compute(ChangeBuilder builder) async {
     final sourceRanges = <SourceRange>[];
 
-    final referencedNode = node.parent;
-    if (referencedNode == null) {
-      return;
-    }
-
+    final referencedNode = node;
     if (referencedNode is ClassDeclaration ||
         referencedNode is EnumDeclaration ||
         referencedNode is FunctionDeclaration ||
@@ -42,11 +38,11 @@
         referencedNode is MethodDeclaration ||
         referencedNode is VariableDeclaration) {
       final element = referencedNode is Declaration
-          ? referencedNode.declaredElement2!
-          : (referencedNode as NamedCompilationUnitMember).declaredElement2!;
+          ? referencedNode.declaredElement!
+          : (referencedNode as NamedCompilationUnitMember).declaredElement!;
       final references = _findAllReferences(unit, element);
       // todo (pq): consider filtering for references that are limited to within the class.
-      if (references.length == 1) {
+      if (references.isEmpty) {
         var parent = referencedNode.parent;
         var grandParent = parent?.parent;
         SourceRange sourceRange;
@@ -87,18 +83,21 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    final declaration = node.parent;
+    final declaration = node;
     if (declaration is! VariableDeclaration) {
       return;
     }
 
-    final element = declaration.declaredElement2;
+    final element = declaration.declaredElement;
     if (element is! FieldElement) {
       return;
     }
 
     final sourceRanges = <SourceRange>[];
-    final references = _findAllReferences(unit, element);
+    final references = [
+      node,
+      ..._findAllReferences(unit, element),
+    ];
     for (var reference in references) {
       // todo (pq): consider scoping this to parent or parent.parent.
       final referenceNode = reference.thisOrAncestorMatching((node) =>
@@ -217,11 +216,23 @@
 
 class _ElementReferenceCollector extends RecursiveAstVisitor<void> {
   final Element element;
-  final List<SimpleIdentifier> references = [];
+  final List<AstNode> references = [];
 
   _ElementReferenceCollector(this.element);
 
   @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    final declaredElement = node.declaredElement;
+    if (declaredElement is FieldFormalParameterElement) {
+      if (declaredElement.field == element) {
+        references.add(node);
+      }
+    }
+
+    super.visitFieldFormalParameter(node);
+  }
+
+  @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
     final staticElement = node.writeOrReadElement;
     if (staticElement == element) {
@@ -239,7 +250,7 @@
 }
 
 abstract class _RemoveUnused extends CorrectionProducer {
-  List<SimpleIdentifier> _findAllReferences(AstNode root, Element element) {
+  List<AstNode> _findAllReferences(AstNode root, Element element) {
     var collector = _ElementReferenceCollector(element);
     root.accept(collector);
     return collector.references;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
index 6fc350e..a9117b9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
@@ -24,7 +24,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    final exceptionParameter = node.parent;
+    final exceptionParameter = node;
     if (exceptionParameter is! CatchClauseParameter) {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
index 8a7f342..f1ca983 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
@@ -24,7 +24,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    final stackTraceParameter = node.parent;
+    final stackTraceParameter = node;
     if (stackTraceParameter is! CatchClauseParameter) {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
index 5d1b908..9263dfc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
@@ -26,24 +26,28 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    final declaration = node.parent;
-    if (!(declaration is VariableDeclaration && declaration.name2 == token)) {
+    final node = this.node;
+    if (!(node is VariableDeclaration && node.name == token)) {
       return;
     }
 
-    var element = declaration.declaredElement2;
+    var element = node.declaredElement;
     if (element is! LocalVariableElement) {
       return;
     }
 
     final sourceRanges = <SourceRange>[];
 
-    final functionBody = declaration.thisOrAncestorOfType<FunctionBody>();
+    final functionBody = node.thisOrAncestorOfType<FunctionBody>();
     if (functionBody == null) {
       return;
     }
 
-    final references = findLocalElementReferences(functionBody, element);
+    final references = [
+      node,
+      ...findLocalElementReferences(functionBody, element),
+    ];
+
     for (var reference in references) {
       final node = reference.thisOrAncestorMatching((node) =>
           node is VariableDeclaration || node is AssignmentExpression);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/rename_method_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/rename_method_parameter.dart
index c39f129..7de19f8 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/rename_method_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/rename_method_parameter.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -23,7 +24,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    final parameter = node.parent;
+    final parameter = node;
     if (parameter is! FormalParameter) return;
     var paramIdentifier = parameter.name;
     if (paramIdentifier == null) return;
@@ -34,11 +35,11 @@
     if (methodParameters == null) return;
 
     var classDeclaration = method.parent as Declaration;
-    var classElement = classDeclaration.declaredElement2;
-    if (classElement is! ClassElement) return;
+    var classElement = classDeclaration.declaredElement;
+    if (classElement is! InterfaceElement) return;
 
     var parentMethod = classElement.lookUpInheritedMethod(
-        method.name2.lexeme, classElement.library);
+        method.name.lexeme, classElement.library);
     if (parentMethod == null) return;
 
     var parameters = methodParameters.parameters;
@@ -57,8 +58,8 @@
         _newName = newName;
 
         await builder.addDartFileEdit(file, (builder) {
-          for (var i in collector.oldIdentifiers) {
-            builder.addSimpleReplacement(range.node(i), newName);
+          for (var token in collector.oldTokens) {
+            builder.addSimpleReplacement(range.token(token), newName);
           }
         });
       }
@@ -67,23 +68,40 @@
 }
 
 class _Collector extends RecursiveAstVisitor<void> {
-  var error = false;
+  bool error = false;
   final String newName;
   final ParameterElement target;
 
-  final oldIdentifiers = <SimpleIdentifier>[];
+  final oldTokens = <Token>[];
 
   _Collector(this.newName, this.target);
 
   @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    _addNameToken(node.name, node.declaredElement);
+    super.visitSimpleFormalParameter(node);
+  }
+
+  @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
+    _addNameToken(node.token, node.staticElement);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    _addNameToken(node.name, node.declaredElement);
+    super.visitVariableDeclaration(node);
+  }
+
+  void _addNameToken(Token? nameToken, Element? element) {
     if (error) return;
 
-    var nodeElement = node.staticElement;
-    if (nodeElement == target) {
-      oldIdentifiers.add(node);
-    } else if (node.name == newName) {
-      error = true;
+    if (nameToken != null) {
+      if (element == target) {
+        oldTokens.add(nameToken);
+      } else if (nameToken.lexeme == newName) {
+        error = true;
+      }
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
index 83f4f0a..7c36201 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/utilities/extensions/string.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -33,13 +34,22 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var identifier = node;
-    if (identifier is! SimpleIdentifier) {
+    Token? nameToken;
+    Element? element;
+    final node = this.node;
+    if (node is SimpleFormalParameter) {
+      nameToken = node.name;
+      element = node.declaredElement;
+    } else if (node is VariableDeclaration) {
+      nameToken = node.name;
+      element = node.declaredElement;
+    }
+    if (nameToken == null || element == null) {
       return;
     }
 
     // Prepare the new name.
-    var newName = identifier.name.toLowerCamelCase;
+    var newName = nameToken.lexeme.toLowerCamelCase;
     if (newName == null) {
       return;
     }
@@ -47,7 +57,6 @@
 
     // Find references to the identifier.
     List<SimpleIdentifier>? references;
-    var element = identifier.staticElement;
     if (element is LocalVariableElement) {
       var root = node.thisOrAncestorOfType<Block>();
       if (root != null) {
@@ -70,10 +79,13 @@
     }
 
     // Compute the change.
-    var references_final = references;
+    final sourceRanges = {
+      range.token(nameToken),
+      ...references.map(range.node),
+    };
     await builder.addDartFileEdit(file, (builder) {
-      for (var reference in references_final) {
-        builder.addSimpleReplacement(range.node(reference), _newName);
+      for (var sourceRange in sourceRanges) {
+        builder.addSimpleReplacement(sourceRange, _newName);
       }
     });
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_conditional_with_if_else.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_conditional_with_if_else.dart
index 45bbc99..2be0da5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_conditional_with_if_else.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_conditional_with_if_else.dart
@@ -107,24 +107,24 @@
           var variable = conditional.parent as VariableDeclaration;
           var variableList = variable.parent as VariableDeclarationList;
           if (variableList.type == null) {
-            var type = variable.declaredElement2!.type;
+            var type = variable.declaredElement!.type;
             var keyword = variableList.keyword;
             if (keyword != null && keyword.keyword == Keyword.VAR) {
               builder.addReplacement(range.token(keyword), (builder) {
                 builder.writeType(type);
               });
             } else {
-              builder.addInsertion(variable.name2.offset, (builder) {
+              builder.addInsertion(variable.name.offset, (builder) {
                 builder.writeType(type);
                 builder.write(' ');
               });
             }
           }
-          builder.addDeletion(range.endEnd(variable.name2, conditional));
+          builder.addDeletion(range.endEnd(variable.name, conditional));
           var conditionSrc = utils.getNodeText(conditional.condition);
           var thenSrc = utils.getNodeText(conditional.thenExpression);
           var elseSrc = utils.getNodeText(conditional.elseExpression);
-          var name = variable.name2.lexeme;
+          var name = variable.name.lexeme;
           var src = eol;
           src += '${prefix}if ($conditionSrc) {$eol';
           src += '$prefix$indent$name = $thenSrc;$eol';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type.dart
index f51ac51..92a695b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type.dart
@@ -84,12 +84,12 @@
     if (newType != null) {
       var clazz = method.thisOrAncestorOfType<ClassDeclaration>();
       if (clazz != null) {
-        var classElement = clazz.declaredElement2!;
+        var classElement = clazz.declaredElement!;
         var overriddenList = InheritanceManager3().getOverridden2(
             classElement,
             Name(
               classElement.library.source.uri,
-              method.declaredElement2!.name,
+              method.declaredElement!.name,
             ));
 
         if (overriddenList != null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart b/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart
index 5ed846e..ace51ce 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart
@@ -28,7 +28,7 @@
       return;
     }
 
-    if (!accessor.isGetter || accessor.enclosingElement3 is! ClassElement) {
+    if (!accessor.isGetter || accessor.enclosingElement is! InterfaceElement) {
       // TODO(brianwilkerson) Should we also require that the getter be synthetic?
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/sort_combinators.dart b/pkg/analysis_server/lib/src/services/correction/dart/sort_combinators.dart
new file mode 100644
index 0000000..7f19611
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/sort_combinators.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2022, 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/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.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';
+import 'package:collection/collection.dart';
+
+class SortCombinators extends CorrectionProducer {
+  @override
+  bool get canBeAppliedInBulk => true;
+
+  @override
+  bool get canBeAppliedToFile => true;
+
+  @override
+  FixKind get fixKind => DartFixKind.SORT_COMBINATORS;
+
+  @override
+  FixKind get multiFixKind => DartFixKind.SORT_COMBINATORS_MULTI;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    var node = this.node;
+
+    NodeList<SimpleIdentifier> names;
+    if (node is ShowCombinator) {
+      names = node.shownNames;
+    } else if (node is HideCombinator) {
+      names = node.hiddenNames;
+    } else {
+      return;
+    }
+
+    var sorted = names.map((e) => e.name).sorted();
+
+    await builder.addDartFileEdit(file, (builder) {
+      for (var i = 0; i < names.length; i++) {
+        builder.addSimpleReplacement(range.node(names[i]), sorted[i]);
+      }
+    });
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/sort_unnamed_constructor_first.dart b/pkg/analysis_server/lib/src/services/correction/dart/sort_unnamed_constructor_first.dart
index a55adde..eabad6e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/sort_unnamed_constructor_first.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/sort_unnamed_constructor_first.dart
@@ -32,11 +32,11 @@
             .firstWhereOrNull((child) => child is ConstructorDeclaration)
         as ConstructorDeclaration?;
     if (firstConstructor == null ||
-        firstConstructor.name2 == null ||
-        firstConstructor.name2?.lexeme == 'new') return;
+        firstConstructor.name == null ||
+        firstConstructor.name?.lexeme == 'new') return;
 
     final unnamedConstructor = clazz.childEntities.firstWhereOrNull(
-            (child) => child is ConstructorDeclaration && child.name2 == null)
+            (child) => child is ConstructorDeclaration && child.name == null)
         as ConstructorDeclaration?;
     if (unnamedConstructor == null) return;
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/split_variable_declaration.dart b/pkg/analysis_server/lib/src/services/correction/dart/split_variable_declaration.dart
index 8540d43..f2f5c81 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/split_variable_declaration.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/split_variable_declaration.dart
@@ -41,7 +41,7 @@
 
     // The caret must be between the type and the variable name.
     var variable = variables[0];
-    if (!range.startEnd(statement, variable.name2).contains(selectionOffset)) {
+    if (!range.startEnd(statement, variable.name).contains(selectionOffset)) {
       return;
     }
 
@@ -52,7 +52,7 @@
 
     await builder.addDartFileEdit(file, (builder) {
       if (variableList.type == null) {
-        final type = variable.declaredElement2!.type;
+        final type = variable.declaredElement!.type;
         if (!type.isDynamic && keyword != null) {
           if (!builder.canWriteType(type)) {
             return;
@@ -64,8 +64,8 @@
       }
 
       var indent = utils.getNodePrefix(statement);
-      var name = variable.name2.lexeme;
-      builder.addSimpleInsertion(variable.name2.end, ';$eol$indent$name');
+      var name = variable.name.lexeme;
+      builder.addSimpleInsertion(variable.name.end, ';$eol$indent$name');
     });
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart b/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart
index fd88d0d..c230793 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart
@@ -70,7 +70,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [SurroundWith] producer.
 abstract class _SurroundWith extends CorrectionProducer {
   final SourceRange statementsRange;
@@ -85,7 +85,7 @@
       this.statementsRange, this.indentOld, this.indentNew, this.indentedCode);
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [SurroundWith] producer.
 class _SurroundWithBlock extends _SurroundWith {
   _SurroundWithBlock(super.statementsRange, super.indentOld, super.indentNew,
@@ -107,7 +107,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [SurroundWith] producer.
 class _SurroundWithDoWhile extends _SurroundWith {
   _SurroundWithDoWhile(super.statementsRange, super.indentOld, super.indentNew,
@@ -135,7 +135,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [SurroundWith] producer.
 class _SurroundWithFor extends _SurroundWith {
   _SurroundWithFor(super.statementsRange, super.indentOld, super.indentNew,
@@ -169,7 +169,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [SurroundWith] producer.
 class _SurroundWithForIn extends _SurroundWith {
   _SurroundWithForIn(super.statementsRange, super.indentOld, super.indentNew,
@@ -199,7 +199,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [SurroundWith] producer.
 class _SurroundWithIf extends _SurroundWith {
   _SurroundWithIf(super.statementsRange, super.indentOld, super.indentNew,
@@ -227,7 +227,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [SurroundWith] producer.
 class _SurroundWithSetState extends _SurroundWith {
   _SurroundWithSetState(super.statementsRange, super.indentOld, super.indentNew,
@@ -241,7 +241,7 @@
     var classDeclaration =
         node.parent?.thisOrAncestorOfType<ClassDeclaration>();
     if (classDeclaration != null &&
-        flutter.isState(classDeclaration.declaredElement2)) {
+        flutter.isState(classDeclaration.declaredElement)) {
       await builder.addDartFileEdit(file, (builder) {
         builder.addReplacement(statementsRange, (builder) {
           builder.write(indentOld);
@@ -256,7 +256,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [SurroundWith] producer.
 class _SurroundWithTryCatch extends _SurroundWith {
   _SurroundWithTryCatch(super.statementsRange, super.indentOld, super.indentNew,
@@ -294,7 +294,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [SurroundWith] producer.
 class _SurroundWithTryFinally extends _SurroundWith {
   _SurroundWithTryFinally(super.statementsRange, super.indentOld,
@@ -330,7 +330,7 @@
   }
 }
 
-/// A correction processor that can make one of the possible change computed by
+/// A correction processor that can make one of the possible changes computed by
 /// the [SurroundWith] producer.
 class _SurroundWithWhile extends _SurroundWith {
   _SurroundWithWhile(super.statementsRange, super.indentOld, super.indentNew,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
index 41a495d..d8d5134 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
@@ -6,8 +6,11 @@
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
+import 'package:analyzer/source/source_range.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 
@@ -77,17 +80,21 @@
     var indent = prefix + utils.getIndent(1);
 
     await builder.addDartFileEdit(file, (builder) {
-      builder.addSimpleReplacement(
-        range.endStart(node.doKeyword, body),
-        ' {$eol$indent',
-      );
-      builder.addSimpleReplacement(
-        range.endStart(body, node.whileKeyword),
-        '$eol$prefix} ',
-      );
+      _replaceRange(
+          builder, node.doKeyword, body, node.whileKeyword, indent, prefix);
     });
   }
 
+  int _endAfterComments(AstNode node) {
+    var end = node.end;
+    var comments = node.endToken.next?.precedingComments;
+    if (comments != null &&
+        utils.getLineThis(end) == utils.getLineThis(comments.offset)) {
+      end = comments.end;
+    }
+    return end;
+  }
+
   Future<void> _forStatement(ChangeBuilder builder, ForStatement node) async {
     var body = node.body;
     if (body is Block) return;
@@ -96,11 +103,7 @@
     var indent = prefix + utils.getIndent(1);
 
     await builder.addDartFileEdit(file, (builder) {
-      builder.addSimpleReplacement(
-        range.endStart(node.rightParenthesis, body),
-        ' {$eol$indent',
-      );
-      builder.addSimpleInsertion(body.end, '$eol$prefix}');
+      _replace(builder, node.rightParenthesis, body, indent, prefix);
     });
   }
 
@@ -114,17 +117,12 @@
       var elseKeyword = node.elseKeyword;
       if (thenStatement is! Block &&
           (thenOrElse == null || thenOrElse == thenStatement)) {
-        builder.addSimpleReplacement(
-          range.endStart(node.rightParenthesis, thenStatement),
-          ' {$eol$indent',
-        );
-        if (elseKeyword != null) {
-          builder.addSimpleReplacement(
-            range.endStart(thenStatement, elseKeyword),
-            '$eol$prefix} ',
-          );
+        if (elseKeyword == null) {
+          _replace(
+              builder, node.rightParenthesis, thenStatement, indent, prefix);
         } else {
-          builder.addSimpleInsertion(thenStatement.end, '$eol$prefix}');
+          _replaceRange(builder, node.rightParenthesis, thenStatement,
+              elseKeyword, indent, prefix);
         }
       }
 
@@ -133,15 +131,37 @@
           elseStatement != null &&
           elseStatement is! Block &&
           (thenOrElse == null || thenOrElse == elseStatement)) {
-        builder.addSimpleReplacement(
-          range.endStart(elseKeyword, elseStatement),
-          ' {$eol$indent',
-        );
-        builder.addSimpleInsertion(elseStatement.end, '$eol$prefix}');
+        _replace(builder, elseKeyword, elseStatement, indent, prefix);
       }
     });
   }
 
+  void _replace(DartFileEditBuilder builder, SyntacticEntity left,
+      AstNode right, String indent, String prefix) {
+    _replaceLeftParenthesis(builder, left, right, indent);
+
+    builder.addSimpleInsertion(_endAfterComments(right), '$eol$prefix}');
+  }
+
+  void _replaceLeftParenthesis(DartFileEditBuilder builder,
+      SyntacticEntity left, SyntacticEntity right, String indent) {
+    builder.addSimpleReplacement(
+      range.endStart(left, right),
+      ' {$eol$indent',
+    );
+  }
+
+  void _replaceRange(DartFileEditBuilder builder, SyntacticEntity left,
+      AstNode node, SyntacticEntity right, String indent, String prefix) {
+    _replaceLeftParenthesis(builder, left, node, indent);
+
+    var end = _endAfterComments(node);
+    builder.addSimpleReplacement(
+      SourceRange(end, right.offset - end),
+      '$eol$prefix} ',
+    );
+  }
+
   Future<void> _whileStatement(
       ChangeBuilder builder, WhileStatement node) async {
     var body = node.body;
@@ -151,11 +171,7 @@
     var indent = prefix + utils.getIndent(1);
 
     await builder.addDartFileEdit(file, (builder) {
-      builder.addSimpleReplacement(
-        range.endStart(node.rightParenthesis, body),
-        ' {$eol$indent',
-      );
-      builder.addSimpleInsertion(body.end, '$eol$prefix}');
+      _replace(builder, node.rightParenthesis, body, indent, prefix);
     });
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
index 9967293..58d7581 100644
--- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
+++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
@@ -24,10 +24,10 @@
 #   issue created for it.
 #
 # Stats:
-# - 739 "needsEvaluation"
-# -  45 "needsFix"
-# - 284 "hasFix"
-# -  47 "noFix"
+# - 726 "needsEvaluation"
+# -  58 "needsFix"
+# - 287 "hasFix"
+# -  48 "noFix"
 
 AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR:
   status: noFix
@@ -40,20 +40,13 @@
     be able to provide a fix.
 AnalysisOptionsHintCode.PREVIEW_DART_2_SETTING_DEPRECATED:
   status: needsFix
-  notes: |-
-    Provide a fix to remove the deprecated setting.
+  notes: Fixed.
 AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED:
   status: needsFix
-  notes: |-
-    Provide a fix to remove the deprecated setting.
+  notes: Fixed.
 AnalysisOptionsHintCode.SUPER_MIXINS_SETTING_DEPRECATED:
   status: needsFix
-  notes: |-
-    Provide a fix to remove the deprecated setting.
-AnalysisOptionsWarningCode.ANALYSIS_OPTION_DEPRECATED:
-  status: needsFix
-  notes: |-
-    Provide a fix to remove the deprecated setting.
+  notes: Fixed.
 AnalysisOptionsWarningCode.INCLUDE_FILE_NOT_FOUND:
   status: noFix
   notes: |-
@@ -102,9 +95,7 @@
   notes: |-
     For each exported name, add a fix to hide the name.
 CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS:
-  status: needsFix
-  notes: |-
-    For each extension, add a fix to add an extension override.
+  status: hasFix
 CompileTimeErrorCode.AMBIGUOUS_IMPORT:
   status: needsFix
   notes: |-
@@ -363,10 +354,13 @@
 CompileTimeErrorCode.DUPLICATE_PART:
   status: needsEvaluation
 CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING:
-  status: needsEvaluation
-CompileTimeErrorCode.ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR:
   status: noFix
+  notes: |-
+    The fix is to rename one of the two, but we can't know what name to use.
+CompileTimeErrorCode.ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR:
+  status: needsFix
   since: 2.17
+  notes: Use AddConst.new
 CompileTimeErrorCode.ENUM_INSTANTIATED_TO_BOUNDS_IS_NOT_WELL_BOUNDED:
   status: noFix
   since: 2.17
@@ -678,6 +672,8 @@
   status: needsEvaluation
 CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER:
   status: hasFix
+CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL:
+  status: hasFix
 CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION:
   status: hasFix
 CompileTimeErrorCode.MISSING_REQUIRED_ARGUMENT:
@@ -784,7 +780,8 @@
 CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT:
   status: needsEvaluation
 CompileTimeErrorCode.NON_FINAL_FIELD_IN_ENUM:
-  status: needsEvaluation
+  status: needsFix
+  notes: Use MakeFinal.new
 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR:
   status: needsEvaluation
 CompileTimeErrorCode.NON_GENERATIVE_IMPLICIT_CONSTRUCTOR:
@@ -1546,31 +1543,63 @@
 HintCode.UNUSED_SHOWN_NAME:
   status: hasFix
 LanguageCode.IMPLICIT_DYNAMIC_FIELD:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    The correction says to add an explicit type or remove implicit-dynamic from
+    analysis options. We can add a fix to add an explicit `dynamic`.
 LanguageCode.IMPLICIT_DYNAMIC_FUNCTION:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    The correction says to add an explicit type or remove implicit-dynamic from
+    analysis options. We can add a fix to add an explicit `dynamic`.
 LanguageCode.IMPLICIT_DYNAMIC_INVOKE:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    The correction says to add an explicit type or remove implicit-dynamic from
+    analysis options. We can add a fix to add an explicit `dynamic`.
 LanguageCode.IMPLICIT_DYNAMIC_LIST_LITERAL:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    The correction says to add an explicit type or remove implicit-dynamic from
+    analysis options. We can add a fix to add an explicit `dynamic`.
 LanguageCode.IMPLICIT_DYNAMIC_MAP_LITERAL:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    The correction says to add an explicit type or remove implicit-dynamic from
+    analysis options. We can add a fix to add an explicit `dynamic`.
 LanguageCode.IMPLICIT_DYNAMIC_METHOD:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    The correction says to add an explicit type or remove implicit-dynamic from
+    analysis options. We can add a fix to add an explicit `dynamic`.
 LanguageCode.IMPLICIT_DYNAMIC_PARAMETER:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    The correction says to add an explicit type or remove implicit-dynamic from
+    analysis options. We can add a fix to add an explicit `dynamic`.
 LanguageCode.IMPLICIT_DYNAMIC_RETURN:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    The correction says to add an explicit type or remove implicit-dynamic from
+    analysis options. We can add a fix to add an explicit `dynamic`.
 LanguageCode.IMPLICIT_DYNAMIC_TYPE:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    The correction says to add an explicit type or remove implicit-dynamic from
+    analysis options. We can add a fix to add an explicit `dynamic`.
 LanguageCode.IMPLICIT_DYNAMIC_VARIABLE:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    The correction says to add an explicit type or remove implicit-dynamic from
+    analysis options. We can add a fix to add an explicit `dynamic`.
 LintCode.always_declare_return_types:
   status: hasFix
 LintCode.always_put_control_body_on_new_line:
   status: hasFix
 LintCode.always_put_required_named_parameters_first:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    Can fix by moving required named parameters before non-required ones.
 LintCode.always_require_non_null_named_parameters:
   status: hasFix
 LintCode.always_specify_types:
@@ -1582,9 +1611,15 @@
 LintCode.avoid_annotating_with_dynamic:
   status: hasFix
 LintCode.avoid_as:
-  status: needsEvaluation
+  status: noFix
+  notes: |-
+    We could try to account for special situations, but this cannot be fixed
+    universally, and the lint rule is deprecated.
 LintCode.avoid_bool_literals_in_conditional_expressions:
-  status: needsEvaluation
+  status: needsFix
+  notes: |-
+    Each expression like `condition ? true : boolExpression` can be universally
+    fixed to not contain a bool literal.
 LintCode.avoid_catches_without_on_clauses:
   status: needsEvaluation
 LintCode.avoid_catching_errors:
@@ -1676,7 +1711,7 @@
 LintCode.close_sinks:
   status: needsEvaluation
 LintCode.combinators_ordering:
-  status: needsEvaluation
+  status: hasFix
 LintCode.comment_references:
   status: needsEvaluation
 LintCode.conditional_uri_does_not_exist:
@@ -2022,7 +2057,8 @@
 ParserErrorCode.ABSTRACT_CLASS_MEMBER:
   status: hasFix
 ParserErrorCode.ABSTRACT_ENUM:
-  status: needsEvaluation
+  status: needsFix
+  notes: Remove abstract keyword
 ParserErrorCode.ABSTRACT_EXTERNAL_FIELD:
   status: needsEvaluation
 ParserErrorCode.ABSTRACT_LATE_FIELD:
@@ -2109,6 +2145,8 @@
   notes: |-
     We can't guess at the names or number of the enum constants that should be
     added.
+ParserErrorCode.EMPTY_RECORD_TYPE_NAMED_FIELDS_LIST:
+  status: needsEvaluation
 ParserErrorCode.ENUM_IN_CLASS:
   status: needsEvaluation
 ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND:
@@ -2129,6 +2167,14 @@
   status: needsEvaluation
 ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL:
   status: needsEvaluation
+ParserErrorCode.EXPECTED_NAMED_TYPE_EXTENDS:
+  status: noFix
+ParserErrorCode.EXPECTED_NAMED_TYPE_IMPLEMENTS:
+  status: noFix
+ParserErrorCode.EXPECTED_NAMED_TYPE_ON:
+  status: noFix
+ParserErrorCode.EXPECTED_NAMED_TYPE_WITH:
+  status: noFix
 ParserErrorCode.EXPECTED_STRING_LITERAL:
   status: needsEvaluation
 ParserErrorCode.EXPECTED_TOKEN:
@@ -2383,6 +2429,12 @@
   status: needsEvaluation
 ParserErrorCode.PREFIX_AFTER_COMBINATOR:
   status: needsEvaluation
+ParserErrorCode.RECORD_LITERAL_EMPTY:
+  status: needsEvaluation
+ParserErrorCode.RECORD_LITERAL_ONE_POSITIONAL_NO_TRAILING_COMMA:
+  status: needsEvaluation
+ParserErrorCode.RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA:
+  status: needsEvaluation
 ParserErrorCode.REDIRECTING_CONSTRUCTOR_WITH_BODY:
   status: needsEvaluation
 ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR:
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index df9a57f..f7bbe36 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -138,6 +138,11 @@
     DartFixKindPriority.DEFAULT,
     'Add EOL at end of file',
   );
+  static const ADD_EXTENSION_OVERRIDE = FixKind(
+    'dart.fix.add.extensionOverride',
+    DartFixKindPriority.DEFAULT,
+    "Add an extension override for '{0}'",
+  );
   static const ADD_FIELD_FORMAL_PARAMETERS = FixKind(
     'dart.fix.add.fieldFormalParameters',
     70,
@@ -1570,6 +1575,16 @@
     DartFixKindPriority.IN_FILE,
     'Move child properties to ends of arguments everywhere in file',
   );
+  static const SORT_COMBINATORS = FixKind(
+    'dart.fix.sort.combinators',
+    DartFixKindPriority.DEFAULT,
+    'Sort combinators',
+  );
+  static const SORT_COMBINATORS_MULTI = FixKind(
+    'dart.fix.sort.combinators.multi',
+    DartFixKindPriority.IN_FILE,
+    'Sort combinators everywhere in file',
+  );
   static const SORT_CONSTRUCTOR_FIRST = FixKind(
     'dart.fix.sort.sortConstructorFirst',
     DartFixKindPriority.DEFAULT,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
index 8c148db..2ba2ed1 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
@@ -61,19 +61,18 @@
     var errorCode = error.errorCode;
 //    if (errorCode == AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR) {
 //    } else if (errorCode == AnalysisOptionsErrorCode.PARSE_ERROR) {
-//    } else if (errorCode ==
-//        AnalysisOptionsHintCode.PREVIEW_DART_2_SETTING_DEPRECATED) {
-//    } else if (errorCode ==
-//        AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED) {
 //    } else
-
-    if (errorCode == DEPRECATED_LINT_HINT) {
+    if (errorCode ==
+        AnalysisOptionsHintCode.PREVIEW_DART_2_SETTING_DEPRECATED) {
+      await _addFix_removeSetting(coveringNodePath);
+    } else if (errorCode ==
+        AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED) {
+      await _addFix_removeSetting(coveringNodePath);
+    } else if (errorCode == DEPRECATED_LINT_HINT) {
       await _addFix_removeLint(coveringNodePath);
     } else if (errorCode ==
         AnalysisOptionsHintCode.SUPER_MIXINS_SETTING_DEPRECATED) {
       await _addFix_removeSetting(coveringNodePath);
-//    } else if (errorCode ==
-//        AnalysisOptionsWarningCode.ANALYSIS_OPTION_DEPRECATED) {
 //    } else if (errorCode == AnalysisOptionsWarningCode.INCLUDED_FILE_WARNING) {
 //    } else if (errorCode == AnalysisOptionsWarningCode.INCLUDE_FILE_NOT_FOUND) {
 //    } else if (errorCode == AnalysisOptionsWarningCode.INVALID_OPTION) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart
index 135155a..af71d62 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart
@@ -77,17 +77,17 @@
         return null;
       }
       return _TypeArgumentData(typeArguments, parent.argumentList.offset);
-    } else if (parent is MethodDeclaration) {
+    } else if (node is MethodDeclaration) {
       // invalid_override
       final extendedType = this.extendedType;
       if (extendedType != null && !extendedType.validate(context)) {
         return null;
       }
-      var typeParameters = parent.typeParameters;
+      var typeParameters = node.typeParameters;
       if (_isInvalidIndex(typeParameters?.typeParameters)) {
         return null;
       }
-      return _TypeParameterData(typeParameters, parent.name2.end);
+      return _TypeParameterData(typeParameters, node.name.end);
     } else if (node is TypeArgumentList && parent is ExtensionOverride) {
       // wrong_number_of_type_arguments_extension
       if (!argumentValue.validate(context)) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
index 0ea7777..d107148 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
@@ -4,7 +4,7 @@
 
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart' show ClassElement;
+import 'package:analyzer/dart/element/element.dart' show InterfaceElement;
 import 'package:analyzer/dart/element/type.dart';
 
 /// A description of an element.
@@ -143,8 +143,8 @@
           var type = target.staticType;
           if (type == null && target is SimpleIdentifier) {
             var element = target.staticElement;
-            // TODO(brianwilkerson) Handle more than `ClassElement`.
-            if (element is ClassElement) {
+            // TODO(brianwilkerson) Handle more than `InterfaceElement`.
+            if (element is InterfaceElement) {
               type = element.thisType;
             }
           }
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 3bb402a..d4a64a4 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
@@ -7,7 +7,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart'
-    show ClassElement, ExtensionElement, PrefixElement;
+    show ExtensionElement, InterfaceElement, PrefixElement;
 import 'package:analyzer/dart/element/type.dart';
 
 /// An object that can be used to determine whether an element is appropriate
@@ -151,6 +151,8 @@
       _buildFromBinaryExpression(node);
     } else if (node is ConstructorName) {
       _buildFromConstructorName(node);
+    } else if (node is FunctionDeclaration) {
+      _addMatcher(components: [node.name.lexeme], kinds: []);
     } else if (node is Literal) {
       var parent = node.parent;
       if (parent is ArgumentList) {
@@ -160,10 +162,14 @@
       _buildFromNamedType(node);
     } else if (node is PrefixedIdentifier) {
       _buildFromPrefixedIdentifier(node);
+    } else if (node is MethodDeclaration) {
+      _buildFromMethodDeclaration(node);
     } else if (node is SimpleIdentifier && nameToken != null) {
       _buildFromSimpleIdentifier(node, nameToken);
     } else if (node is TypeArgumentList) {
       _buildFromTypeArgumentList(node);
+    } else if (node is VariableDeclaration) {
+      _addMatcher(components: [node.name.lexeme], kinds: []);
     }
   }
 
@@ -202,7 +208,7 @@
         );
       }
     } else if (parent is SuperConstructorInvocation) {
-      var superclassName = parent.staticElement?.enclosingElement3.name;
+      var superclassName = parent.staticElement?.enclosingElement.name;
       if (superclassName != null) {
         _addMatcher(
           components: [parent.constructorName?.name ?? '', superclassName],
@@ -258,7 +264,7 @@
   /// Build a matcher for the method being declared.
   void _buildFromMethodDeclaration(MethodDeclaration node) {
     _addMatcher(
-      components: [node.name2.lexeme],
+      components: [node.name.lexeme],
       kinds: [ElementKind.methodKind],
     );
   }
@@ -395,7 +401,7 @@
     // It looks like we're accessing a member, but we don't know what kind of
     // member, so we include all of the member kinds.
     var container = node.prefix.staticElement;
-    if (container is ClassElement) {
+    if (container is InterfaceElement) {
       _addMatcher(
         components: [node.identifier.name, container.name],
         kinds: const [
@@ -459,7 +465,7 @@
       _buildFromArgumentList(parent.parent!.parent as ArgumentList);
     } else if (parent is NamedType) {
       _buildFromNamedType(parent);
-    } else if (parent is MethodDeclaration && nameToken == parent.name2) {
+    } else if (parent is MethodDeclaration && nameToken == parent.name) {
       _buildFromMethodDeclaration(parent);
     } else if (parent is MethodInvocation &&
         node == parent.methodName &&
@@ -503,8 +509,8 @@
       }
     }
     if (element != null) {
-      var enclosingElement = element.enclosingElement3;
-      if (enclosingElement is ClassElement) {
+      var enclosingElement = element.enclosingElement;
+      if (enclosingElement is InterfaceElement) {
         return [identifier.name, enclosingElement.name];
       } else if (enclosingElement is ExtensionElement) {
         var name = enclosingElement.name;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
index cb0fd92..63cf19b 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
@@ -5,6 +5,7 @@
 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 
@@ -22,34 +23,35 @@
   // the super-method and the class's super-class.
   // ignore: library_private_types_in_public_api
   void apply(DartFileEditBuilder builder, DataDrivenFix fix, _Data data) {
-    var nameNode = data.nameNode;
+    var nameToken = data.nameToken;
     if (fix.element.isConstructor) {
-      var parent = nameNode?.parent;
-      if (parent is ConstructorName) {
-        if (nameNode != null && newName.isEmpty) {
+      final node = data.node;
+      final parent = node.parent;
+      if (node is ConstructorName) {
+        if (nameToken != null && newName.isEmpty) {
           // The constructor was renamed from a named constructor to an unnamed
           // constructor.
-          builder.addDeletion(range.startEnd(parent.period!, parent));
-        } else if (nameNode == null && newName.isNotEmpty) {
+          builder.addDeletion(range.startEnd(node.period!, node));
+        } else if (nameToken == null && newName.isNotEmpty) {
           // The constructor was renamed from an unnamed constructor to a named
           // constructor.
-          builder.addSimpleInsertion(parent.end, '.$newName');
-        } else if (nameNode != null) {
+          builder.addSimpleInsertion(node.end, '.$newName');
+        } else if (nameToken != null) {
           // The constructor was renamed from a named constructor to another
           // named constructor.
-          builder.addSimpleReplacement(range.node(nameNode), newName);
+          builder.addSimpleReplacement(range.token(nameToken), newName);
         }
-      } else if (nameNode == null) {
+      } else if (nameToken == null) {
         return;
       } else if (parent is MethodInvocation) {
         if (newName.isEmpty) {
           // The constructor was renamed from a named constructor to an unnamed
           // constructor.
-          builder.addDeletion(range.startEnd(parent.operator!, nameNode));
+          builder.addDeletion(range.startEnd(parent.operator!, nameToken));
         } else {
           // The constructor was renamed from a named constructor to another
           // named constructor.
-          builder.addSimpleReplacement(range.node(nameNode), newName);
+          builder.addSimpleReplacement(range.token(nameToken), newName);
         }
       } else if (parent is NamedType && parent.parent is ConstructorName) {
         // The constructor was renamed from an unnamed constructor to a named
@@ -62,11 +64,11 @@
       } else {
         // The constructor was renamed from a named constructor to another named
         // constructor.
-        builder.addSimpleReplacement(range.node(nameNode), newName);
+        builder.addSimpleReplacement(range.token(nameToken), newName);
       }
-    } else if (nameNode != null) {
+    } else if (nameToken != null) {
       // The name is a simple identifier.
-      builder.addSimpleReplacement(range.node(nameNode), newName);
+      builder.addSimpleReplacement(range.token(nameToken), newName);
     }
   }
 
@@ -76,7 +78,9 @@
   // ignore: library_private_types_in_public_api
   _Data? validate(DataDrivenFix fix) {
     var node = fix.node;
-    if (node is SimpleIdentifier) {
+    if (node is MethodDeclaration) {
+      return _Data(node, node.name);
+    } else if (node is SimpleIdentifier) {
       var parent = node.parent;
       var grandParent = parent?.parent;
       if (parent is Label && grandParent is NamedExpression) {
@@ -84,15 +88,15 @@
         if (invocation is InstanceCreationExpression) {
           invocation.constructorName.name;
         } else if (invocation is MethodInvocation) {
-          return _Data(invocation.methodName);
+          return _Data(node, invocation.methodName.token);
         }
         return null;
       }
-      return _Data(node);
+      return _Data(node, node.token);
     } else if (node is ConstructorName) {
-      return _Data(node.name);
+      return _Data(node, node.name?.token);
     } else if (node is PrefixedIdentifier) {
-      return _Data(node.identifier);
+      return _Data(node.identifier, node.identifier.token);
     }
     return null;
   }
@@ -100,7 +104,8 @@
 
 /// The data renaming a declaration.
 class _Data {
-  final SimpleIdentifier? nameNode;
+  final AstNode node;
+  final Token? nameToken;
 
-  _Data(this.nameNode);
+  _Data(this.node, this.nameToken);
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart
index 004b5be..7be4444 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart
@@ -70,7 +70,9 @@
   // ignore: library_private_types_in_public_api
   _Data validate(DataDrivenFix fix) {
     var node = fix.node;
-    if (node is SimpleIdentifier) {
+    if (node is MethodDeclaration) {
+      return _OverrideData(node);
+    } else if (node is SimpleIdentifier) {
       var parent = node.parent;
       var grandParent = parent?.parent;
       if (node.name == oldName &&
@@ -80,8 +82,6 @@
         if (invocation != null && fix.element.matches(invocation)) {
           return _InvocationData(node);
         }
-      } else if (parent is MethodDeclaration) {
-        return _OverrideData(parent);
       }
     }
     return const _IgnoredData();
@@ -120,10 +120,10 @@
   /// Return the element that this method overrides, or `null` if this method
   /// doesn't override any inherited member.
   ExecutableElement? overriddenElement() {
-    var element = declaredElement2;
+    var element = declaredElement;
     if (element != null) {
-      var enclosingElement = element.enclosingElement3;
-      if (enclosingElement is ClassElement) {
+      var enclosingElement = element.enclosingElement;
+      if (enclosingElement is InterfaceElement) {
         var name = Name(enclosingElement.library.source.uri, element.name);
         return InheritanceManager3().getInherited2(enclosingElement, name);
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
index 9270917..8de7d9e 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
@@ -16,6 +16,9 @@
   /// The name of the data file.
   static const String dataFileName = 'fix_data.yaml';
 
+  /// The name of the data folder.
+  static const String dataFolderName = 'fix_data';
+
   /// Initialize a newly created transform set manager.
   TransformSetManager._();
 
@@ -37,6 +40,10 @@
       if (transformSet != null) {
         transformSets.add(transformSet);
       }
+      var folder = directory.getChildAssumingFolder(dataFolderName);
+      if (folder.exists) {
+        _loadTransforms(transformSets, folder);
+      }
     }
     var sdkRoot = analysisContext.sdkRoot;
     if (sdkRoot != null) {
@@ -49,6 +56,23 @@
     return transformSets;
   }
 
+  /// Recursively search all the children of the specified [folder],
+  /// and add the transform sets found to the [transforms].
+  void _loadTransforms(List<TransformSet> transforms, Folder folder) {
+    for (var resource in folder.getChildren()) {
+      if (resource is File) {
+        if (resource.shortName.endsWith('.yaml')) {
+          var transformSet = _loadTransformSet(resource);
+          if (transformSet != null) {
+            transforms.add(transformSet);
+          }
+        }
+      } else if (resource is Folder) {
+        _loadTransforms(transforms, resource);
+      }
+    }
+  }
+
   /// Read the [file] and parse the content. Return the transform set that was
   /// parsed, or `null` if the file doesn't exist, isn't readable, or if the
   /// content couldn't be parsed.
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 0b9cd4f..9480d96 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -14,6 +14,7 @@
 import 'package:analysis_server/src/services/correction/dart/add_enum_constant.dart';
 import 'package:analysis_server/src/services/correction/dart/add_eol_at_end_of_file.dart';
 import 'package:analysis_server/src/services/correction/dart/add_explicit_cast.dart';
+import 'package:analysis_server/src/services/correction/dart/add_extension_override.dart';
 import 'package:analysis_server/src/services/correction/dart/add_field_formal_parameters.dart';
 import 'package:analysis_server/src/services/correction/dart/add_key_to_constructors.dart';
 import 'package:analysis_server/src/services/correction/dart/add_late.dart';
@@ -187,6 +188,7 @@
 import 'package:analysis_server/src/services/correction/dart/replace_with_tear_off.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_with_var.dart';
 import 'package:analysis_server/src/services/correction/dart/sort_child_property_last.dart';
+import 'package:analysis_server/src/services/correction/dart/sort_combinators.dart';
 import 'package:analysis_server/src/services/correction/dart/sort_constructor_first.dart';
 import 'package:analysis_server/src/services/correction/dart/sort_unnamed_constructor_first.dart';
 import 'package:analysis_server/src/services/correction/dart/update_sdk_constraints.dart';
@@ -447,6 +449,9 @@
     LintNames.cascade_invocations: [
       ConvertToCascade.new,
     ],
+    LintNames.combinators_ordering: [
+      SortCombinators.new,
+    ],
     LintNames.curly_braces_in_flow_control_structures: [
       UseCurlyBraces.new,
     ],
@@ -716,6 +721,9 @@
   /// generators used for lint rules are in the [lintMultiProducerMap].
   static const Map<ErrorCode, List<MultiProducerGenerator>>
       nonLintMultiProducerMap = {
+    CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS: [
+      AddExtensionOverride.new,
+    ],
     CompileTimeErrorCode.CAST_TO_NON_TYPE: [
       ImportLibrary.forType,
     ],
@@ -884,6 +892,7 @@
       MakeVariableNotFinal.new,
     ],
     CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE: [
+      AddExplicitCast.new,
       AddNullCheck.new,
       WrapInText.new,
     ],
@@ -996,6 +1005,9 @@
       AddRequiredKeyword.new,
       MakeVariableNullable.new,
     ],
+    CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL: [
+      MakeVariableNullable.new,
+    ],
     CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION: [
       AddRequiredKeyword.new,
     ],
diff --git a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
index e231951..85c3549 100644
--- a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
+++ b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
@@ -34,7 +34,7 @@
     // If we're in a build() method, use 'build' as the name prefix.
     var method = assignedExpression?.thisOrAncestorOfType<MethodDeclaration>();
     if (method != null) {
-      var enclosingName = method.name2.lexeme;
+      var enclosingName = method.name.lexeme;
       if (enclosingName.startsWith('build')) {
         prefix = 'build';
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/namespace.dart b/pkg/analysis_server/lib/src/services/correction/namespace.dart
index a2abded..051e3fd 100644
--- a/pkg/analysis_server/lib/src/services/correction/namespace.dart
+++ b/pkg/analysis_server/lib/src/services/correction/namespace.dart
@@ -42,7 +42,7 @@
     String prefix,
     Element element,
     Map<LibraryImportElement, Set<Element>> importElementsMap) {
-  if (element.enclosingElement3 is! CompilationUnitElement) {
+  if (element.enclosingElement is! CompilationUnitElement) {
     return null;
   }
   var usedLibrary = element.library;
diff --git a/pkg/analysis_server/lib/src/services/correction/sort_members.dart b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
index 301aef5..a117ec9 100644
--- a/pkg/analysis_server/lib/src/services/correction/sort_members.dart
+++ b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
@@ -114,14 +114,14 @@
       String name;
       if (member is ConstructorDeclaration) {
         kind = _MemberKind.CLASS_CONSTRUCTOR;
-        name = member.name2?.lexeme ?? '';
+        name = member.name?.lexeme ?? '';
       } else if (member is FieldDeclaration) {
         var fieldDeclaration = member;
         List<VariableDeclaration> fields = fieldDeclaration.fields.variables;
         if (fields.isNotEmpty) {
           kind = _MemberKind.CLASS_FIELD;
           isStatic = fieldDeclaration.isStatic;
-          name = fields[0].name2.lexeme;
+          name = fields[0].name.lexeme;
         } else {
           // Don't sort members if there are errors in the code.
           return;
@@ -129,7 +129,7 @@
       } else if (member is MethodDeclaration) {
         var method = member;
         isStatic = method.isStatic;
-        name = method.name2.lexeme;
+        name = method.name.lexeme;
         if (method.isGetter) {
           kind = _MemberKind.CLASS_ACCESSOR;
           name += ' getter';
@@ -169,18 +169,18 @@
       String name;
       if (member is ClassDeclaration) {
         kind = _MemberKind.UNIT_CLASS;
-        name = member.name2.lexeme;
+        name = member.name.lexeme;
       } else if (member is ClassTypeAlias) {
         kind = _MemberKind.UNIT_CLASS;
-        name = member.name2.lexeme;
+        name = member.name.lexeme;
       } else if (member is EnumDeclaration) {
         kind = _MemberKind.UNIT_CLASS;
-        name = member.name2.lexeme;
+        name = member.name.lexeme;
       } else if (member is ExtensionDeclaration) {
         kind = _MemberKind.UNIT_EXTENSION;
-        name = member.name2?.lexeme ?? '';
+        name = member.name?.lexeme ?? '';
       } else if (member is FunctionDeclaration) {
-        name = member.name2.lexeme;
+        name = member.name.lexeme;
         if (member.isGetter) {
           kind = _MemberKind.UNIT_ACCESSOR;
           name += ' getter';
@@ -196,13 +196,13 @@
         }
       } else if (member is FunctionTypeAlias) {
         kind = _MemberKind.UNIT_FUNCTION_TYPE;
-        name = member.name2.lexeme;
+        name = member.name.lexeme;
       } else if (member is GenericTypeAlias) {
         kind = _MemberKind.UNIT_GENERIC_TYPE_ALIAS;
-        name = member.name2.lexeme;
+        name = member.name.lexeme;
       } else if (member is MixinDeclaration) {
         kind = _MemberKind.UNIT_CLASS;
-        name = member.name2.lexeme;
+        name = member.name.lexeme;
       } else if (member is TopLevelVariableDeclaration) {
         var variableDeclaration = member;
         List<VariableDeclaration> variables =
@@ -213,7 +213,7 @@
           } else {
             kind = _MemberKind.UNIT_VARIABLE;
           }
-          name = variables[0].name2.lexeme;
+          name = variables[0].name.lexeme;
         } else {
           // Don't sort members if there are errors in the code.
           return;
@@ -262,8 +262,8 @@
         }
         // sort all other members by name
         var name1 = o1.name.toLowerCase();
-        var name2 = o2.name.toLowerCase();
-        return name1.compareTo(name2);
+        var name = o2.name.toLowerCase();
+        return name1.compareTo(name);
       }
       return priority1 - priority2;
     });
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 6cff502..afceabc 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -47,15 +47,19 @@
   // Prepare information about existing imports.
   LibraryDirective? libraryDirective;
   var importDirectives = <_ImportDirectiveInfo>[];
+  var directives = <NamespaceDirective>[];
   for (var directive in libUtils.unit.directives) {
     if (directive is LibraryDirective) {
       libraryDirective = directive;
-    } else if (directive is ImportDirective) {
-      var uriStr = directive.uri.stringValue;
-      if (uriStr != null) {
-        importDirectives.add(
-          _ImportDirectiveInfo(uriStr, directive.offset, directive.end),
-        );
+    } else if (directive is NamespaceDirective) {
+      directives.add(directive);
+      if (directive is ImportDirective) {
+        var uriStr = directive.uri.stringValue;
+        if (uriStr != null) {
+          importDirectives.add(
+            _ImportDirectiveInfo(uriStr, directive.offset, directive.end),
+          );
+        }
       }
     }
   }
@@ -67,6 +71,9 @@
       .toList();
   uriList.sort((a, b) => a.compareTo(b));
 
+  var quote = session.analysisContext.analysisOptions.codeStyleOptions
+      .preferredQuoteForUris(directives);
+
   // Insert imports: between existing imports.
   if (importDirectives.isNotEmpty) {
     var isFirstPackage = true;
@@ -82,7 +89,7 @@
           isFirstPackage = false;
         }
         if (importUri.compareTo(existingImport.uri) < 0) {
-          var importCode = "import '$importUri';$eol";
+          var importCode = "import $quote$importUri$quote;$eol";
           doSourceChange_addElementEdit(change, targetLibrary,
               SourceEdit(existingImport.offset, 0, importCode));
           inserted = true;
@@ -90,7 +97,7 @@
         }
       }
       if (!inserted) {
-        var importCode = "${eol}import '$importUri';";
+        var importCode = "${eol}import $quote$importUri$quote;";
         if (isPackage && isFirstPackage && isAfterDart) {
           importCode = eol + importCode;
         }
@@ -108,7 +115,7 @@
   if (libraryDirective != null) {
     var prefix = eol + eol;
     for (var importUri in uriList) {
-      var importCode = "${prefix}import '$importUri';";
+      var importCode = "${prefix}import $quote$importUri$quote;";
       prefix = eol;
       doSourceChange_addElementEdit(change, targetLibrary,
           SourceEdit(libraryDirective.end, 0, importCode));
@@ -122,7 +129,7 @@
     var offset = desc.offset;
     for (var i = 0; i < uriList.length; i++) {
       var importUri = uriList[i];
-      var importCode = "import '$importUri';$eol";
+      var importCode = "import $quote$importUri$quote;$eol";
       if (i == 0) {
         importCode = desc.prefix + importCode;
       }
@@ -219,7 +226,7 @@
 String getElementQualifiedName(Element element) {
   var kind = element.kind;
   if (kind == ElementKind.FIELD || kind == ElementKind.METHOD) {
-    return '${element.enclosingElement3!.displayName}.${element.displayName}';
+    return '${element.enclosingElement!.displayName}.${element.displayName}';
   } else if (kind == ElementKind.LIBRARY) {
     // Libraries may not have names, so use a path relative to the context root.
     final session = element.session!;
@@ -255,13 +262,13 @@
 ExecutableElement? getEnclosingExecutableElement(AstNode input) {
   for (var node in input.withParents) {
     if (node is FunctionDeclaration) {
-      return node.declaredElement2;
+      return node.declaredElement;
     }
     if (node is ConstructorDeclaration) {
-      return node.declaredElement2;
+      return node.declaredElement;
     }
     if (node is MethodDeclaration) {
-      return node.declaredElement2;
+      return node.declaredElement;
     }
   }
   return null;
@@ -466,7 +473,7 @@
     return true;
   }
   return node.parent is VariableDeclaration &&
-      (node.parent as VariableDeclaration).name2 == node.token;
+      (node.parent as VariableDeclaration).name == node.token;
 }
 
 /// Return `true` if the given [node] is the name of a [NamedExpression].
@@ -914,6 +921,13 @@
       return 'Never';
     }
 
+    if (type is RecordType) {
+      return _getTypeCodeRecord(
+        librariesToImport: librariesToImport,
+        type: type,
+      );
+    }
+
     if (type is TypeParameterType) {
       var element = type.element2;
       if (_isTypeParameterVisible(element)) {
@@ -1304,6 +1318,51 @@
     return sb.toString();
   }
 
+  String _getTypeCodeRecord({
+    required Set<Source> librariesToImport,
+    required RecordType type,
+  }) {
+    final buffer = StringBuffer();
+
+    final positionalFields = type.positionalFields;
+    final namedFields = type.namedFields;
+    final fieldCount = positionalFields.length + namedFields.length;
+    buffer.write('(');
+
+    var index = 0;
+    for (final field in positionalFields) {
+      buffer.write(
+        getTypeSource(field.type, librariesToImport),
+      );
+      if (index++ < fieldCount - 1) {
+        buffer.write(', ');
+      }
+    }
+
+    if (namedFields.isNotEmpty) {
+      buffer.write('{');
+      for (final field in namedFields) {
+        buffer.write(
+          getTypeSource(field.type, librariesToImport),
+        );
+        buffer.write(' ');
+        buffer.write(field.name);
+        if (index++ < fieldCount - 1) {
+          buffer.write(', ');
+        }
+      }
+      buffer.write('}');
+    }
+
+    buffer.write(')');
+
+    if (type.nullabilitySuffix == NullabilitySuffix.question) {
+      buffer.write('?');
+    }
+
+    return buffer.toString();
+  }
+
   /// @return the [InvertedCondition] for the given logical expression.
   _InvertedCondition _invertCondition0(Expression expression) {
     if (expression is BooleanLiteral) {
@@ -1375,7 +1434,7 @@
   /// Checks if [element] is visible in [targetExecutableElement] or
   /// [targetClassElement].
   bool _isTypeParameterVisible(TypeParameterElement element) {
-    var enclosing = element.enclosingElement3;
+    var enclosing = element.enclosingElement;
     return identical(enclosing, targetExecutableElement) ||
         identical(enclosing, targetClassElement);
   }
@@ -1466,6 +1525,12 @@
     }
   }
 
+  @override
+  visitVariableDeclaration(VariableDeclaration node) {
+    names.add(node.name.lexeme);
+    return super.visitVariableDeclaration(node);
+  }
+
   static bool _isPrefixed(SimpleIdentifier node) {
     var parent = node.parent;
     return parent is ConstructorName && parent.name == node ||
@@ -1541,13 +1606,13 @@
   final elements = <LocalElement>[];
 
   @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    if (node.inDeclarationContext()) {
-      var element = node.staticElement;
-      if (element is LocalElement) {
-        elements.add(element);
-      }
+  void visitVariableDeclaration(VariableDeclaration node) {
+    final element = node.declaredElement;
+    if (element is LocalVariableElement) {
+      elements.add(element);
     }
+
+    super.visitVariableDeclaration(node);
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/services/flutter/property.dart b/pkg/analysis_server/lib/src/services/flutter/property.dart
index 31bda1e..65fc5a6 100644
--- a/pkg/analysis_server/lib/src/services/flutter/property.dart
+++ b/pkg/analysis_server/lib/src/services/flutter/property.dart
@@ -108,11 +108,15 @@
 
     var builder = ChangeBuilder(session: resolvedUnit.session);
 
-    ClassElement? enumClassElement;
+    InterfaceElement? enumElement;
     var enumValue = value.enumValue;
     if (enumValue != null) {
       var helper = AnalysisSessionHelper(resolvedUnit.session);
-      enumClassElement = await helper.getClass(
+      enumElement = await helper.getClass(
+        enumValue.libraryUri,
+        enumValue.className,
+      );
+      enumElement ??= await helper.getEnum(
         enumValue.libraryUri,
         enumValue.className,
       );
@@ -123,8 +127,8 @@
         var expression = value.expression;
         if (expression != null) {
           builder.write(expression);
-        } else if (enumClassElement != null && enumValue != null) {
-          builder.writeReference(enumClassElement);
+        } else if (enumElement != null && enumValue != null) {
+          builder.writeReference(enumElement);
           builder.write('.');
           builder.write(enumValue.name);
         } else {
@@ -463,7 +467,7 @@
       var constructor = propertyExpression.constructorName.staticElement;
       if (flutter != null &&
           constructor != null &&
-          constructor.enclosingElement3 == classEdgeInsets) {
+          constructor.enclosingElement == classEdgeInsets) {
         var arguments = propertyExpression.argumentList.arguments;
         var constructorName = constructor.name;
         if (constructorName == 'all') {
diff --git a/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart b/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
index 417fa0b..40b7cba 100644
--- a/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
+++ b/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
@@ -278,7 +278,7 @@
     constructorElement ??= classDescription?.constructor;
     if (constructorElement == null) return;
 
-    var classElement = constructorElement.enclosingElement3;
+    var classElement = constructorElement.enclosingElement;
     if (!elementsBeingProcessed.add(classElement)) return;
 
     var existingNamed = <String>{};
@@ -520,13 +520,13 @@
   }
 
   protocol.FlutterWidgetPropertyValueEnumItem _toEnumItem(FieldElement field) {
-    var classElement = field.enclosingElement3 as ClassElement;
-    var libraryUriStr = '${classElement.library.source.uri}';
+    var interfaceElement = field.enclosingElement as InterfaceElement;
+    var libraryUriStr = '${interfaceElement.library.source.uri}';
     var documentation = getFieldDocumentation(field);
 
     return protocol.FlutterWidgetPropertyValueEnumItem(
       libraryUriStr,
-      classElement.name,
+      interfaceElement.name,
       field.name,
       documentation: documentation,
     );
@@ -546,7 +546,7 @@
       if (element is PropertyAccessorElement && element.isGetter) {
         var field = element.variable;
         if (field is FieldElement && field.isStatic) {
-          var enclosingClass = field.enclosingElement3 as ClassElement;
+          var enclosingClass = field.enclosingElement as InterfaceElement;
           if (field.isEnumConstant ||
               _flutter.isExactAlignment(enclosingClass) ||
               _flutter.isExactAlignmentDirectional(enclosingClass)) {
diff --git a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
index dc3569f..162347e 100644
--- a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
+++ b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
@@ -28,7 +28,7 @@
 /// name of the constructor, unless the constructor is a named constructor in
 /// which '<class-name>.<constructor-name>' is returned.
 String _computeConstructorElementName(ConstructorElement element) {
-  var name = element.enclosingElement3.name;
+  var name = element.enclosingElement.name;
   var constructorName = element.name;
   if (constructorName.isNotEmpty) {
     name = '$name.$constructorName';
@@ -50,7 +50,7 @@
     return schema.VARIABLE_KIND;
   } else if (e is ExecutableElement) {
     return schema.FUNCTION_KIND;
-  } else if (e is ClassElement || e is TypeParameterElement) {
+  } else if (e is InterfaceElement || e is TypeParameterElement) {
     // TODO(jwren): this should be using absvar instead, see
     // https://kythe.io/docs/schema/#absvar
     return schema.RECORD_KIND;
@@ -169,7 +169,7 @@
 
   late String _enclosingFilePath = '';
   Element? _enclosingElement;
-  ClassElement? _enclosingClassElement;
+  InterfaceElement? _enclosingClassElement;
   KytheVName? _enclosingVName;
   KytheVName? _enclosingFileVName;
   KytheVName? _enclosingClassVName;
@@ -202,7 +202,7 @@
     if (refVName != null) {
       var parentNode = node.parent;
       if (parentNode is Declaration) {
-        var parentElement = parentNode.declaredElement2;
+        var parentElement = parentNode.declaredElement;
         if (parentNode is TopLevelVariableDeclaration) {
           _handleVariableDeclarationListAnnotations(
               parentNode.variables, refVName);
@@ -279,7 +279,7 @@
 
   @override
   void visitClassDeclaration(ClassDeclaration node) {
-    return _withEnclosingElement(node.declaredElement2!, () {
+    return _withEnclosingElement(node.declaredElement!, () {
       // record/ class node
       addNodeAndFacts(schema.RECORD_KIND,
           nodeVName: _enclosingClassVName,
@@ -288,7 +288,7 @@
 
       // anchor- defines/binding
       addAnchorEdgesContainingEdge(
-          syntacticEntity: node.name2,
+          syntacticEntity: node.name,
           edges: [
             schema.DEFINES_BINDING_EDGE,
           ],
@@ -346,7 +346,7 @@
 
   @override
   void visitClassTypeAlias(ClassTypeAlias node) {
-    return _withEnclosingElement(node.declaredElement2!, () {
+    return _withEnclosingElement(node.declaredElement!, () {
       // record/ class node
       addNodeAndFacts(schema.RECORD_KIND,
           nodeVName: _enclosingClassVName,
@@ -355,7 +355,7 @@
 
       // anchor
       addAnchorEdgesContainingEdge(
-          syntacticEntity: node.name2,
+          syntacticEntity: node.name,
           edges: [
             schema.DEFINES_BINDING_EDGE,
           ],
@@ -432,12 +432,9 @@
           }
         }
 
-        var start = 0;
-        var end = 0;
-        if (libraryDirective != null) {
-          start = libraryDirective.name.offset;
-          end = libraryDirective.name.end;
-        }
+        final libraryName = libraryDirective?.name2;
+        final start = libraryName?.offset ?? 0;
+        final end = libraryName?.end ?? 0;
 
         // package node
         var packageVName = addNodeAndFacts(schema.PACKAGE_KIND,
@@ -460,7 +457,7 @@
 
   @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
-    var declaredElement = node.declaredElement2!;
+    var declaredElement = node.declaredElement!;
     return _withEnclosingElement(declaredElement, () {
       // function/ constructor node
       var constructorVName = addNodeAndFacts(schema.FUNCTION_KIND,
@@ -471,7 +468,7 @@
       // anchor
       var start = node.returnType.offset;
       var end = node.returnType.end;
-      var nameToken = node.name2;
+      var nameToken = node.name;
       if (nameToken != null) {
         end = nameToken.end;
       }
@@ -502,7 +499,7 @@
 
   @override
   void visitDeclaredIdentifier(DeclaredIdentifier node) {
-    var declaredElement = node.declaredElement2!;
+    var declaredElement = node.declaredElement!;
     _handleVariableDeclaration(declaredElement, node.name,
         subKind: schema.LOCAL_SUBKIND, type: declaredElement.type);
 
@@ -513,11 +510,11 @@
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
     // constant node
     var constDeclVName =
-        addNodeAndFacts(schema.CONSTANT_KIND, element: node.declaredElement2);
+        addNodeAndFacts(schema.CONSTANT_KIND, element: node.declaredElement);
 
     // anchor- defines/binding, defines
     addAnchorEdgesContainingEdge(
-        syntacticEntity: node.name2,
+        syntacticEntity: node.name,
         edges: [
           schema.DEFINES_BINDING_EDGE,
           schema.DEFINES_EDGE,
@@ -530,7 +527,7 @@
 
   @override
   void visitEnumDeclaration(EnumDeclaration node) {
-    return _withEnclosingElement(node.declaredElement2!, () {
+    return _withEnclosingElement(node.declaredElement!, () {
       // record/ enum node
       addNodeAndFacts(schema.RECORD_KIND,
           nodeVName: _enclosingClassVName,
@@ -539,7 +536,7 @@
 
       // anchor- defines/binding
       addAnchorEdgesContainingEdge(
-          syntacticEntity: node.name2,
+          syntacticEntity: node.name,
           edges: [
             schema.DEFINES_BINDING_EDGE,
           ],
@@ -591,7 +588,7 @@
 
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
-    var declaredElement = node.declaredElement2!;
+    var declaredElement = node.declaredElement!;
     return _withEnclosingElement(declaredElement, () {
       // function node
       var functionVName = addNodeAndFacts(schema.FUNCTION_KIND,
@@ -599,7 +596,7 @@
 
       // anchor- defines/binding
       addAnchorEdgesContainingEdge(
-          syntacticEntity: node.name2,
+          syntacticEntity: node.name,
           edges: [
             schema.DEFINES_BINDING_EDGE,
           ],
@@ -728,7 +725,7 @@
       // We can't call _handleRefEdge as the anchor node has already been
       // written out.
       var enclosingEltVName = _vNameFromElement(
-          constructorElement.enclosingElement3, schema.RECORD_KIND);
+          constructorElement.enclosingElement, schema.RECORD_KIND);
       var anchorVName =
           _vNameAnchor(constructorName.offset, constructorName.end);
       addEdge(anchorVName, schema.REF_EDGE, enclosingEltVName);
@@ -743,7 +740,7 @@
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
-    var declaredElement = node.declaredElement2!;
+    var declaredElement = node.declaredElement!;
     return _withEnclosingElement(declaredElement, () {
       // function node
       var methodVName = addNodeAndFacts(schema.FUNCTION_KIND,
@@ -751,7 +748,7 @@
 
       // anchor- defines/binding
       addAnchorEdgesContainingEdge(
-          syntacticEntity: node.name2,
+          syntacticEntity: node.name,
           edges: [
             schema.DEFINES_BINDING_EDGE,
           ],
@@ -918,8 +915,8 @@
         _enclosingVName != _enclosingFileVName;
 
     // variable
-    var declaredElement = node.declaredElement2!;
-    _handleVariableDeclaration(declaredElement, node.name2,
+    var declaredElement = node.declaredElement!;
+    _handleVariableDeclaration(declaredElement, node.name,
         subKind: isLocal ? schema.LOCAL_SUBKIND : schema.FIELD_SUBKIND,
         type: declaredElement.type);
 
@@ -1104,9 +1101,9 @@
   void _handleVariableDeclarationListAnnotations(
       VariableDeclarationList variableDeclarationList, KytheVName refVName) {
     for (var varDecl in variableDeclarationList.variables) {
-      if (varDecl.declaredElement2 != null) {
+      if (varDecl.declaredElement != null) {
         var parentVName =
-            _vNameFromElement(varDecl.declaredElement2, schema.VARIABLE_KIND);
+            _vNameFromElement(varDecl.declaredElement, schema.VARIABLE_KIND);
         addEdge(parentVName, schema.ANNOTATED_BY_EDGE, refVName);
       } else {
         // The element out of the VarDeclarationList is null
@@ -1138,7 +1135,7 @@
       _enclosingElement = element;
       if (element is CompilationUnitElement) {
         _enclosingFileVName = _enclosingVName = _vNameFile();
-      } else if (element is ClassElement) {
+      } else if (element is InterfaceElement) {
         _enclosingClassElement = element;
         _enclosingClassVName = _enclosingVName =
             _vNameFromElement(_enclosingClassElement, schema.RECORD_KIND);
@@ -1419,7 +1416,7 @@
   @override
   StringBuffer visitElement(Element element) {
     assert(element is! MultiplyInheritedExecutableElement);
-    var enclosingElt = element.enclosingElement3!;
+    var enclosingElt = element.enclosingElement!;
     var buffer = enclosingElt.accept(this)!;
     if (buffer.isNotEmpty) {
       buffer.write('#');
@@ -1451,7 +1448,7 @@
     // It is legal to have a named constructor with the same name as a type
     // parameter.  So we distinguish them by using '.' between the class (or
     // typedef) name and the type parameter name.
-    return element.enclosingElement3!.accept(this)!
+    return element.enclosingElement!.accept(this)!
       ..write('.')
       ..write(element.name);
   }
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index eebcda7..60eb7f0 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -50,6 +50,7 @@
   static const String avoid_void_async = 'avoid_void_async';
   static const String await_only_futures = 'await_only_futures';
   static const String cascade_invocations = 'cascade_invocations';
+  static const String combinators_ordering = 'combinators_ordering';
   static const String curly_braces_in_flow_control_structures =
       'curly_braces_in_flow_control_structures';
   static const String diagnostic_describe_all_properties =
diff --git a/pkg/analysis_server/lib/src/services/refactoring/framework/refactoring_processor.dart b/pkg/analysis_server/lib/src/services/refactoring/framework/refactoring_processor.dart
index f79f223..7f89135 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/framework/refactoring_processor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/framework/refactoring_processor.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/services/refactoring/framework/refactoring_context.dart';
 import 'package:analysis_server/src/services/refactoring/framework/refactoring_producer.dart';
+import 'package:analysis_server/src/services/refactoring/move_top_level_to_file.dart';
 
 /// A function that can be executed to create a refactoring producer.
 typedef ProducerGenerator = RefactoringProducer Function(RefactoringContext);
@@ -12,7 +13,7 @@
 class RefactoringProcessor {
   /// A list of the generators used to produce refactorings.
   static const Map<String, ProducerGenerator> generators = {
-    // MoveTopLevelToFile.commandName: MoveTopLevelToFile.new,
+    MoveTopLevelToFile.commandName: MoveTopLevelToFile.new,
   };
 
   /// The context in which the refactorings could be applied.
@@ -40,8 +41,9 @@
                     'filePath': context.resolvedResult.path,
                     'selectionOffset': context.selectionOffset,
                     'selectionLength': context.selectionLength,
-                    'arguments':
-                        producer.parameters.map((param) => param.defaultValue),
+                    'arguments': producer.parameters
+                        .map((param) => param.defaultValue)
+                        .toList(),
                   }
                 ],
               ),
diff --git a/pkg/analysis_server/lib/src/services/refactoring/framework/refactoring_producer.dart b/pkg/analysis_server/lib/src/services/refactoring/framework/refactoring_producer.dart
index 4ae9171..88e52d6 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/framework/refactoring_producer.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/framework/refactoring_producer.dart
@@ -4,8 +4,13 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/services/refactoring/framework/refactoring_context.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/analysis/session_helper.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 
 /// An object that can compute a refactoring in a Dart file.
@@ -26,6 +31,14 @@
   /// Return a list of the parameters to send to the client.
   List<CommandParameter> get parameters;
 
+  /// Return the result of resolving the file in which the refactoring was
+  /// invoked.
+  ResolvedUnitResult get result => _context.resolvedResult;
+
+  /// Return the node that was selected.
+  AstNode? get selectedNode =>
+      NodeLocator2(selectionOffset, selectionEnd).searchWithin(result.unit);
+
   /// Return the offset of the first character after the selection range.
   int get selectionEnd => selectionOffset + selectionLength;
 
@@ -45,13 +58,29 @@
       _context.server.clientCapabilities?.codeActionCommandParameterSupport ==
       true;
 
+  /// Return `true` if the client has support for creating files. Subclasses
+  /// that require the ability to create new files must not create a refactoring
+  /// if this getter returns `false`.
+  bool get supportsFileCreation =>
+      _context.server.clientCapabilities?.documentChanges == true &&
+      _context.server.clientCapabilities?.createResourceOperations == true;
+
   /// Return the title of this refactoring.
   String get title;
 
+  /// Return the correction utilities for this refactoring.
+  CorrectionUtils get utils => _context.utils;
+
   /// Given the [commandArguments] associated with the command, use the
   /// [builder] to generate the edits necessary to apply this refactoring.
-  Future<void> compute(List<String> commandArguments, ChangeBuilder builder);
+  Future<void> compute(List<Object?> commandArguments, ChangeBuilder builder);
 
   /// Return `true` if this refactoring is available in the given context.
   bool isAvailable();
+
+  /// Return `true` if the selection is inside the given [token].
+  bool selectionIsInToken(Token? token) =>
+      token != null &&
+      selectionOffset >= token.offset &&
+      selectionEnd <= token.end;
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_getter_to_method.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_getter_to_method.dart
index b10f214..f2d4cd8 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_getter_to_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_getter_to_method.dart
@@ -46,15 +46,15 @@
   Future<SourceChange> createChange() async {
     change = SourceChange(refactoringName);
     // function
-    if (element.enclosingElement3 is CompilationUnitElement) {
+    if (element.enclosingElement is CompilationUnitElement) {
       await _updateElementDeclaration(element);
       await _updateElementReferences(element);
     }
     // method
     var field = element.variable;
     if (field is FieldElement &&
-        (field.enclosingElement3 is ClassElement ||
-            field.enclosingElement3 is ExtensionElement)) {
+        (field.enclosingElement is InterfaceElement ||
+            field.enclosingElement is ExtensionElement)) {
       var elements = await getHierarchyMembers(searchEngine, field);
       await Future.forEach(elements, (ClassMemberElement member) async {
         if (member is FieldElement) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_method_to_getter.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_method_to_getter.dart
index 069baef..38ed56c 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_method_to_getter.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_method_to_getter.dart
@@ -72,7 +72,7 @@
   RefactoringStatus _checkElement() {
     // check Element type
     if (element is FunctionElement) {
-      if (element.enclosingElement3 is! CompilationUnitElement) {
+      if (element.enclosingElement is! CompilationUnitElement) {
         return RefactoringStatus.fatal(
             'Only top-level functions can be converted to getters.');
       }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_local.dart
index 2bd7555..458f2a9 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_local.dart
@@ -523,9 +523,7 @@
   @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
     var parent = node.parent;
-    // ignore: deprecated_member_use
-    if (parent is VariableDeclaration && parent.name == node ||
-        parent is AssignmentExpression && parent.leftHandSide == node) {
+    if (parent is AssignmentExpression && parent.leftHandSide == node) {
       return;
     }
     super.visitSimpleIdentifier(node);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_method.dart
index d62012f..ef6bd79 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_method.dart
@@ -19,6 +19,7 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -33,12 +34,16 @@
 
 const String _TOKEN_SEPARATOR = '\uFFFF';
 
-Element? _getLocalElement(SimpleIdentifier node) {
-  var element = node.writeOrReadElement;
-  if (element is LocalVariableElement ||
+bool isLocalElement(Element? element) {
+  return element is LocalVariableElement ||
       element is ParameterElement ||
       element is FunctionElement &&
-          element.enclosingElement3 is! CompilationUnitElement) {
+          element.enclosingElement is! CompilationUnitElement;
+}
+
+Element? _getLocalElement(SimpleIdentifier node) {
+  var element = node.writeOrReadElement;
+  if (isLocalElement(element)) {
     return element;
   }
   return null;
@@ -437,16 +442,16 @@
     // method of class
     InterfaceElement? interfaceElement;
     if (parent is ClassDeclaration) {
-      interfaceElement = parent.declaredElement2!;
+      interfaceElement = parent.declaredElement!;
     } else if (parent is EnumDeclaration) {
-      interfaceElement = parent.declaredElement2!;
+      interfaceElement = parent.declaredElement!;
     }
     if (interfaceElement != null) {
       return validateCreateMethod(searchEngine,
           AnalysisSessionHelper(resolveResult.session), interfaceElement, name);
     }
     // OK
-    return Future<RefactoringStatus>.value(result);
+    return result;
   }
 
   /// Checks if [selectionRange] selects [Expression] which can be extracted,
@@ -1048,16 +1053,35 @@
   _GetSourcePatternVisitor(this.partRange, this.pattern, this.replaceEdits);
 
   @override
+  void visitNamedExpression(NamedExpression node) {
+    node.expression.accept(this);
+  }
+
+  @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
-    var nodeRange = range.node(node);
-    if (partRange.covers(nodeRange)) {
-      var element = _getLocalElement(node);
-      if (element != null) {
-        // name of a named expression
-        if (isNamedExpressionName(node)) {
-          return;
-        }
-        // continue
+    _addPatterns(
+      nameToken: node.token,
+      element: node.staticElement,
+    );
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    _addPatterns(
+      nameToken: node.name,
+      element: node.declaredElement,
+    );
+
+    super.visitVariableDeclaration(node);
+  }
+
+  void _addPatterns({
+    required Token nameToken,
+    required Element? element,
+  }) {
+    var nameRange = range.token(nameToken);
+    if (partRange.covers(nameRange)) {
+      if (element != null && isLocalElement(element)) {
         var originalName = element.displayName;
         var patternName = pattern.originalToPatternNames[originalName];
         if (patternName == null) {
@@ -1066,8 +1090,8 @@
           patternName = '__refVar${pattern.originalToPatternNames.length}';
           pattern.originalToPatternNames[originalName] = patternName;
         }
-        replaceEdits.add(SourceEdit(nodeRange.offset - partRange.offset,
-            nodeRange.length, patternName));
+        replaceEdits.add(SourceEdit(nameRange.offset - partRange.offset,
+            nameRange.length, patternName));
       }
     }
   }
@@ -1292,6 +1316,34 @@
       }
     }
   }
+
+  @override
+  visitVariableDeclaration(VariableDeclaration node) {
+    var nodeRange = range.node(node);
+    if (ref.selectionRange.covers(nodeRange)) {
+      final element = node.declaredElement!;
+
+      // remember, if assigned and used after selection
+      if (ref._isUsedAfterSelection(element)) {
+        if (!assignedUsedVariables.contains(element)) {
+          assignedUsedVariables.add(element);
+        }
+      }
+
+      // remember information for conflicts checking
+      if (element is LocalElement) {
+        // declared local elements
+        var range = ref._visibleRangeMap[element];
+        if (range != null) {
+          final name = node.name.lexeme;
+          var ranges = ref._localNames.putIfAbsent(name, () => <SourceRange>[]);
+          ranges.add(range);
+        }
+      }
+    }
+
+    return super.visitVariableDeclaration(node);
+  }
 }
 
 class _IsUsedAfterSelectionVisitor extends GeneralizingAstVisitor<void> {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_widget.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_widget.dart
index d9aab7d..f1c5758 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_widget.dart
@@ -184,7 +184,7 @@
 
     // Find the enclosing class.
     _enclosingClassNode = node?.thisOrAncestorOfType<ClassDeclaration>();
-    _enclosingClassElement = _enclosingClassNode?.declaredElement2;
+    _enclosingClassElement = _enclosingClassNode?.declaredElement;
 
     // new MyWidget(...)
     var newExpression = _flutter.identifyNewExpression(node);
@@ -372,7 +372,7 @@
   /// Replace invocations of the [_method] with instantiations of the new
   /// widget class.
   void _replaceInvocationsWithInstantiations(DartFileEditBuilder builder) {
-    var collector = _MethodInvocationsCollector(_method!.declaredElement2!);
+    var collector = _MethodInvocationsCollector(_method!.declaredElement!);
     _enclosingClassNode!.accept(collector);
     for (var invocation in collector.invocations) {
       List<Expression> arguments = invocation.argumentList.arguments;
@@ -610,7 +610,7 @@
 }
 
 class _ParametersCollector extends RecursiveAstVisitor<void> {
-  final ClassElement? enclosingClass;
+  final InterfaceElement? enclosingClass;
   final SourceRange expressionRange;
 
   final RefactoringStatus status = RefactoringStatus();
@@ -669,7 +669,7 @@
         enclosingClass,
         ...enclosingClass.allSupertypes.map((t) => t.element2)
       ];
-      return enclosingClasses.contains(element.enclosingElement3);
+      return enclosingClasses.contains(element.enclosingElement);
     }
     return false;
   }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_local.dart
index 62b9140..d132238 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_local.dart
@@ -52,12 +52,14 @@
   @override
   Future<RefactoringStatus> checkInitialConditions() async {
     // prepare variable
+    Element? element;
     var offsetNode = NodeLocator(offset).searchWithin(resolveResult.unit);
-    if (offsetNode is! SimpleIdentifier) {
-      return _noLocalVariableStatus();
+    if (offsetNode is SimpleIdentifier) {
+      element = offsetNode.staticElement;
+    } else if (offsetNode is VariableDeclaration) {
+      element = offsetNode.declaredElement;
     }
 
-    var element = offsetNode.staticElement;
     if (element is! LocalVariableElement) {
       return _noLocalVariableStatus();
     }
@@ -171,12 +173,14 @@
 
   /// Checks if [offset] is a variable that can be inlined.
   RefactoringStatus _checkOffset() {
+    Element? element;
     var offsetNode = NodeLocator(offset).searchWithin(resolveResult.unit);
-    if (offsetNode is! SimpleIdentifier) {
-      return _noLocalVariableStatus();
+    if (offsetNode is SimpleIdentifier) {
+      element = offsetNode.staticElement;
+    } else if (offsetNode is VariableDeclaration) {
+      element = offsetNode.declaredElement;
     }
 
-    var element = offsetNode.staticElement;
     if (element is! LocalVariableElement) {
       return _noLocalVariableStatus();
     }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_method.dart
index 4d7dab2..ecabaa1 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_method.dart
@@ -55,7 +55,9 @@
     // prepare argument
     Expression? argument;
     for (var arg in arguments) {
-      if (arg.staticParameterElement == parameter) {
+      // Compare using names because parameter elements may not be the same
+      // instance for methods with generic type arguments.
+      if (arg.staticParameterElement?.name == parameter.name) {
         argument = arg;
         break;
       }
@@ -160,14 +162,14 @@
   }
   // fields
   {
-    var enclosingClassElement = node.enclosingInterfaceElement;
-    if (enclosingClassElement != null) {
+    var enclosingInterfaceElement = node.enclosingInterfaceElement;
+    if (enclosingInterfaceElement != null) {
       var elements = [
-        ...enclosingClassElement.allSupertypes.map((e) => e.element2),
-        enclosingClassElement,
+        ...enclosingInterfaceElement.allSupertypes.map((e) => e.element2),
+        enclosingInterfaceElement,
       ];
-      for (var classElement in elements) {
-        var classMembers = getChildren(classElement);
+      for (var interfaceElement in elements) {
+        var classMembers = getChildren(interfaceElement);
         for (var classMemberElement in classMembers) {
           result.add(classMemberElement.displayName);
         }
@@ -213,9 +215,9 @@
 
   @override
   String? get className {
-    var classElement = _methodElement?.enclosingElement3;
-    if (classElement is ClassElement) {
-      return classElement.displayName;
+    var interfaceElement = _methodElement?.enclosingElement;
+    if (interfaceElement is InterfaceElement) {
+      return interfaceElement.displayName;
     }
     return null;
   }
@@ -264,17 +266,17 @@
     // prepare method information
     result.addStatus(await _prepareMethod());
     if (result.hasFatalError) {
-      return Future<RefactoringStatus>.value(result);
+      return result;
     }
     // maybe operator
     if (_methodElement!.isOperator) {
       result = RefactoringStatus.fatal('Cannot inline operator.');
-      return Future<RefactoringStatus>.value(result);
+      return result;
     }
     // maybe [a]sync*
     if (_methodElement!.isGenerator) {
       result = RefactoringStatus.fatal('Cannot inline a generator.');
-      return Future<RefactoringStatus>.value(result);
+      return result;
     }
     // analyze method body
     result.addStatus(_prepareMethodParts());
@@ -304,11 +306,20 @@
     var fatalStatus = RefactoringStatus.fatal(
         'Method declaration or reference must be selected to activate this refactoring.');
 
-    var identifier = NodeLocator(offset).searchWithin(resolveResult.unit);
-    if (identifier is! SimpleIdentifier) {
+    final selectedNode = NodeLocator(offset).searchWithin(resolveResult.unit);
+    final Element? element;
+
+    if (selectedNode is FunctionDeclaration) {
+      element = selectedNode.declaredElement;
+      isDeclaration = true;
+    } else if (selectedNode is MethodDeclaration) {
+      element = selectedNode.declaredElement;
+      isDeclaration = true;
+    } else if (selectedNode is SimpleIdentifier) {
+      element = selectedNode.writeOrReadElement;
+    } else {
       return fatalStatus;
     }
-    var element = identifier.writeOrReadElement;
     if (element is! ExecutableElement) {
       return fatalStatus;
     }
@@ -347,13 +358,23 @@
     // prepare for failure
     var fatalStatus = RefactoringStatus.fatal(
         'Method declaration or reference must be selected to activate this refactoring.');
+
     // prepare selected SimpleIdentifier
-    var identifier = NodeLocator(offset).searchWithin(resolveResult.unit);
-    if (identifier is! SimpleIdentifier) {
+    final selectedNode = NodeLocator(offset).searchWithin(resolveResult.unit);
+    final Element? element;
+    if (selectedNode is FunctionDeclaration) {
+      element = selectedNode.declaredElement;
+      isDeclaration = true;
+    } else if (selectedNode is MethodDeclaration) {
+      element = selectedNode.declaredElement;
+      isDeclaration = true;
+    } else if (selectedNode is SimpleIdentifier) {
+      element = selectedNode.writeOrReadElement;
+    } else {
       return fatalStatus;
     }
+
     // prepare selected ExecutableElement
-    var element = identifier.writeOrReadElement;
     if (element is! ExecutableElement) {
       return fatalStatus;
     }
@@ -380,8 +401,6 @@
       return fatalStatus;
     }
 
-    isDeclaration = resolveResult.uri == element.source.uri &&
-        identifier.offset == element.nameOffset;
     deleteSource = isDeclaration;
     inlineAll = deleteSource;
     return RefactoringStatus();
@@ -789,6 +808,19 @@
     }
   }
 
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    final nameRange = range.token(node.name);
+    if (bodyRange.covers(nameRange)) {
+      final declaredElement = node.declaredElement;
+      if (declaredElement != null) {
+        result.addVariable(declaredElement, nameRange);
+      }
+    }
+
+    super.visitVariableDeclaration(node);
+  }
+
   void _addMemberQualifier(SimpleIdentifier node) {
     // should be unqualified
     var qualifier = getNodeQualifier(node);
@@ -806,13 +838,13 @@
     } else {
       return;
     }
-    if (element.enclosingElement3 is! ClassElement) {
+    if (element.enclosingElement is! InterfaceElement) {
       return;
     }
     // record the implicit static or instance reference
     var offset = node.offset;
     if (element.isStatic) {
-      var className = element.enclosingElement3.displayName;
+      var className = element.enclosingElement.displayName;
       result.addImplicitClassNameOffset(className, offset);
     } else {
       result.addImplicitThisOffset(offset);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring.dart
index 12758bf..3d19013 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring.dart
@@ -18,15 +18,18 @@
 import 'package:analysis_server/src/services/refactoring/legacy/rename_label.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename_library.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename_local.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/rename_parameter.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename_unit_member.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/index.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/utilities/cancellation.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     show RefactoringMethodParameter, SourceChange;
@@ -315,6 +318,13 @@
 abstract class Refactoring {
   set cancellationToken(CancellationToken token);
 
+  /// Sets whether potential edits (see [potentialEditIds]) should be computed.
+  ///
+  /// If it is known in advance that potential edits will not be used, setting
+  /// this flag will skip the work to locate the identifiers to include in
+  /// potential edits.
+  set includePotential(bool value);
+
   /// The ids of source edits that are not known to be valid.
   ///
   /// An edit is not known to be valid if there was insufficient type
@@ -399,39 +409,45 @@
   /// type.
   static RenameRefactoring? create(RefactoringWorkspace workspace,
       ResolvedUnitResult resolvedUnit, Element? element) {
-    var session = resolvedUnit.session;
     if (element == null) {
       return null;
     }
+    var session = resolvedUnit.session;
+    var sessionHelper = AnalysisSessionHelper(session);
     if (element is PropertyAccessorElement) {
       element = element.variable;
     }
-    var enclosingElement = element.enclosingElement3;
+    var enclosingElement = element.enclosingElement;
     if (enclosingElement is CompilationUnitElement) {
-      return RenameUnitMemberRefactoringImpl(workspace, resolvedUnit, element);
+      return RenameUnitMemberRefactoringImpl(
+          workspace, sessionHelper, resolvedUnit, element);
     }
     if (element is ConstructorElement) {
-      return RenameConstructorRefactoringImpl(workspace, session, element);
+      return RenameConstructorRefactoringImpl(
+          workspace, sessionHelper, element);
     }
     if (element is LibraryImportElement) {
-      return RenameImportRefactoringImpl(workspace, session, element);
+      return RenameImportRefactoringImpl(workspace, sessionHelper, element);
     }
     if (element is LabelElement) {
-      return RenameLabelRefactoringImpl(workspace, element);
+      return RenameLabelRefactoringImpl(workspace, sessionHelper, element);
     }
     if (element is LibraryElement) {
-      return RenameLibraryRefactoringImpl(workspace, element);
+      return RenameLibraryRefactoringImpl(workspace, sessionHelper, element);
+    }
+    if (element is ParameterElement) {
+      return RenameParameterRefactoringImpl(workspace, sessionHelper, element);
     }
     if (element is LocalElement) {
-      return RenameLocalRefactoringImpl(workspace, session, element);
+      return RenameLocalRefactoringImpl(workspace, sessionHelper, element);
     }
-    if (enclosingElement is ClassElement) {
+    if (enclosingElement is InterfaceElement) {
       return RenameClassMemberRefactoringImpl(
-          workspace, session, enclosingElement, element);
+          workspace, sessionHelper, enclosingElement, element);
     }
     if (enclosingElement is ExtensionElement) {
       return RenameExtensionMemberRefactoringImpl(
-          workspace, session, enclosingElement, element);
+          workspace, sessionHelper, enclosingElement, element);
     }
     return null;
   }
@@ -440,17 +456,41 @@
   /// the class when on the `new` keyword).
   static RenameRefactoringElement? getElementToRename(
       AstNode node, Element? element) {
-    var offset = node.offset;
-    var length = node.length;
+    // TODO(scheglov) This is bad code.
+    SyntacticEntity? nameNode;
+    if (node is ConstructorDeclaration) {
+      nameNode = node;
+    } else if (node is ConstructorSelector) {
+      nameNode = node;
+    } else if (node is FieldFormalParameter) {
+      nameNode = node.name;
+    } else if (node is ImportDirective) {
+      nameNode = node;
+    } else if (node is InstanceCreationExpression) {
+      nameNode = node;
+    } else if (node is LibraryDirective) {
+      nameNode = node;
+    } else if (node is MethodDeclaration) {
+      nameNode = node.name;
+    } else if (node is NamedCompilationUnitMember) {
+      nameNode = node.name;
+    } else if (node is SimpleFormalParameter) {
+      nameNode = node.name;
+    } else if (node is SimpleIdentifier) {
+      nameNode = node.token;
+    } else if (node is VariableDeclaration) {
+      nameNode = node.name;
+    }
+    if (nameNode == null) {
+      return null;
+    }
+    var offset = nameNode.offset;
+    var length = nameNode.length;
 
     if (node is SimpleIdentifier && element is ParameterElement) {
       element = declaredParameterElement(node, element);
     }
 
-    if (element is FieldFormalParameterElement) {
-      element = element.field;
-    }
-
     // Use the prefix offset/length when renaming an import directive.
     if (node is ImportDirective && element is LibraryImportElement) {
       var prefix = node.prefix;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring_internal.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring_internal.dart
index 76be8d4..fc2218f 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring_internal.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring_internal.dart
@@ -38,6 +38,9 @@
   @override
   final List<String> potentialEditIds = <String>[];
 
+  @override
+  bool includePotential = true;
+
   CancellationToken? cancellationToken;
 
   bool get isCancellationRequested =>
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename.dart
index bc26e15..4cd7efe 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename.dart
@@ -9,16 +9,19 @@
 import 'package:analysis_server/src/services/refactoring/legacy/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 
 /// Helper for renaming one or more [Element]s.
 class RenameProcessor {
   final RefactoringWorkspace workspace;
+  final AnalysisSessionHelper sessionHelper;
   final SourceChange change;
   final String newName;
 
-  RenameProcessor(this.workspace, this.change, this.newName);
+  RenameProcessor(
+      this.workspace, this.sessionHelper, this.change, this.newName);
 
   /// Add the edit that updates the [element] declaration.
   void addDeclarationEdit(Element? element) {
@@ -52,6 +55,7 @@
 abstract class RenameRefactoringImpl extends RefactoringImpl
     implements RenameRefactoring {
   final RefactoringWorkspace workspace;
+  final AnalysisSessionHelper sessionHelper;
   final SearchEngine searchEngine;
   final Element _element;
   @override
@@ -62,7 +66,7 @@
 
   late String newName;
 
-  RenameRefactoringImpl(this.workspace, Element element)
+  RenameRefactoringImpl(this.workspace, this.sessionHelper, Element element)
       : searchEngine = workspace.searchEngine,
         _element = element,
         elementKindName = element.kind.displayName,
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_class_member.dart
index 199c73f..e43571d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_class_member.dart
@@ -14,7 +14,6 @@
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analysis_server/src/utilities/strings.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -36,15 +35,16 @@
 
 /// A [Refactoring] for renaming class member [Element]s.
 class RenameClassMemberRefactoringImpl extends RenameRefactoringImpl {
-  final AnalysisSessionHelper sessionHelper;
-  final ClassElement classElement;
+  final InterfaceElement interfaceElement;
 
   late _RenameClassMemberValidator _validator;
 
-  RenameClassMemberRefactoringImpl(RefactoringWorkspace workspace,
-      AnalysisSession session, this.classElement, Element element)
-      : sessionHelper = AnalysisSessionHelper(session),
-        super(workspace, element);
+  RenameClassMemberRefactoringImpl(
+      RefactoringWorkspace workspace,
+      AnalysisSessionHelper sessionHelper,
+      this.interfaceElement,
+      Element element)
+      : super(workspace, sessionHelper, element);
 
   @override
   String get refactoringName {
@@ -60,7 +60,7 @@
   @override
   Future<RefactoringStatus> checkFinalConditions() {
     _validator = _RenameClassMemberValidator(
-        searchEngine, sessionHelper, classElement, element, newName);
+        searchEngine, sessionHelper, interfaceElement, element, newName);
     return _validator.validate();
   }
 
@@ -70,7 +70,7 @@
     if (element is MethodElement && (element as MethodElement).isOperator) {
       result.addFatalError('Cannot rename operator.');
     }
-    return Future<RefactoringStatus>.value(result);
+    return result;
   }
 
   @override
@@ -87,7 +87,7 @@
 
   @override
   Future<void> fillChange() async {
-    var processor = RenameProcessor(workspace, change, newName);
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
     // update declarations
     for (var renameElement in _validator.elements) {
       if (renameElement.isSynthetic && renameElement is FieldElement) {
@@ -95,32 +95,93 @@
         processor.addDeclarationEdit(renameElement.setter);
       } else {
         processor.addDeclarationEdit(renameElement);
+        if (!newName.startsWith('_')) {
+          var interfaceElement = renameElement.enclosingElement;
+          if (interfaceElement is InterfaceElement) {
+            for (var constructor in interfaceElement.constructors) {
+              for (var parameter in constructor.parameters) {
+                if (parameter is FieldFormalParameterElement &&
+                    parameter.field == renameElement) {
+                  await workspace.searchEngine
+                      .searchReferences(parameter)
+                      .then(processor.addReferenceEdits);
+                }
+              }
+            }
+          }
+        }
       }
     }
-    // update references
-    processor.addReferenceEdits(_validator.references);
+    await _updateReferences();
     // potential matches
-    var nameMatches = await searchEngine.searchMemberReferences(oldName);
-    var nameRefs = getSourceReferences(nameMatches);
-    for (var reference in nameRefs) {
-      // ignore references from SDK and pub cache
-      if (!workspace.containsElement(reference.element)) {
-        continue;
+    if (includePotential) {
+      var nameMatches = await searchEngine.searchMemberReferences(oldName);
+      var nameRefs = getSourceReferences(nameMatches);
+      for (var reference in nameRefs) {
+        // ignore references from SDK and pub cache
+        if (!workspace.containsElement(reference.element)) {
+          continue;
+        }
+        // check the element being renamed is accessible
+        if (!element.isAccessibleIn2(reference.libraryElement)) {
+          continue;
+        }
+        // add edit
+        reference.addEdit(change, newName, id: _newPotentialId());
       }
-      // check the element being renamed is accessible
-      if (!element.isAccessibleIn2(reference.libraryElement)) {
-        continue;
-      }
-      // add edit
-      reference.addEdit(change, newName, id: _newPotentialId());
+    }
+  }
+
+  Future<void> _addPrivateNamedFormalParameterEdit(
+      SourceReference reference, FieldFormalParameterElement element) async {
+    var result = await sessionHelper.getElementDeclaration(element);
+    var node = result?.node;
+    if (node is! DefaultFormalParameter) return;
+    var parameter = node.parameter as FieldFormalParameter;
+
+    var start = parameter.thisKeyword.offset;
+    var type = element.type.getDisplayString(withNullability: true);
+    var edit = SourceEdit(start, parameter.period.end - start, '$type ');
+    doSourceChange_addSourceEdit(change, reference.unitSource, edit);
+
+    var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
+    if (constructor != null) {
+      var previous = constructor.separator ?? constructor.parameters;
+      var replacement = '$newName = ${parameter.name.lexeme}';
+      replacement = constructor.initializers.isEmpty
+          ? ' : $replacement'
+          : ' $replacement,';
+      var edit = SourceEdit(previous.end, 0, replacement);
+      doSourceChange_addSourceEdit(change, reference.unitSource, edit);
     }
   }
 
   String _newPotentialId() {
+    assert(includePotential);
     var id = potentialEditIds.length.toString();
     potentialEditIds.add(id);
     return id;
   }
+
+  Future<void> _updateReferences() async {
+    var references = getSourceReferences(_validator.references);
+
+    for (var reference in references) {
+      var element = reference.element;
+      if (!workspace.containsElement(element)) {
+        continue;
+      }
+
+      if (newName.startsWith('_') &&
+          element is FieldFormalParameterElement &&
+          element.isNamed) {
+        await _addPrivateNamedFormalParameterEdit(reference, element);
+        continue;
+      }
+
+      reference.addEdit(change, newName);
+    }
+  }
 }
 
 /// The base class for the create and rename validators.
@@ -169,7 +230,7 @@
     var declarations = await searchEngine.searchMemberDeclarations(name);
     for (var declaration in declarations) {
       var nameElement = getSyntheticAccessorVariable(declaration.element);
-      var nameClass = nameElement.enclosingElement3;
+      var nameClass = nameElement.enclosingElement;
       // the renamed Element shadows a member of a superclass
       if (superClasses.contains(nameClass)) {
         result.addError(
@@ -240,11 +301,39 @@
   _LocalElementsCollector(this.name);
 
   @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    var element = node.staticElement;
-    if (element is LocalElement && element.name == name) {
-      elements.add(element);
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    if (node.name.lexeme == name) {
+      final element = node.declaredElement;
+      if (element is FunctionElement) {
+        elements.add(element);
+      }
     }
+
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    if (node.name?.lexeme == name) {
+      final element = node.declaredElement;
+      if (element != null) {
+        elements.add(element);
+      }
+    }
+
+    super.visitSimpleFormalParameter(node);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    if (node.name.lexeme == name) {
+      final element = node.declaredElement;
+      if (element is LocalVariableElement) {
+        elements.add(element);
+      }
+    }
+
+    super.visitVariableDeclaration(node);
   }
 }
 
@@ -259,16 +348,16 @@
 class _RenameClassMemberValidator extends _BaseClassMemberValidator {
   final Element element;
 
-  Set<Element> elements = <Element>{};
-  List<SearchMatch> references = <SearchMatch>[];
+  Set<Element> elements = {};
+  List<SearchMatch> references = [];
 
   _RenameClassMemberValidator(
     SearchEngine searchEngine,
     AnalysisSessionHelper sessionHelper,
-    ClassElement elementClass,
+    InterfaceElement elementInterface,
     this.element,
     String name,
-  ) : super(searchEngine, sessionHelper, elementClass, element.kind, name);
+  ) : super(searchEngine, sessionHelper, elementInterface, element.kind, name);
 
   Future<RefactoringStatus> validate() async {
     _checkClassAlreadyDeclares();
@@ -277,8 +366,9 @@
     var subClasses = await searchEngine.searchAllSubtypes(interfaceElement);
     // check shadowing of class names
     for (var element in elements) {
-      var enclosingElement = element.enclosingElement3;
-      if (enclosingElement is ClassElement && enclosingElement.name == name) {
+      var enclosingElement = element.enclosingElement;
+      if (enclosingElement is InterfaceElement &&
+          enclosingElement.name == name) {
         result.addError(
           'Renamed ${elementKind.displayName} has the same name as the '
           "declaring ${enclosingElement.kind.displayName} '$name'.",
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_constructor.dart
index d4972cb..034d985 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_constructor.dart
@@ -10,21 +10,16 @@
 import 'package:analysis_server/src/services/refactoring/legacy/refactoring_internal.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 
 /// A [Refactoring] for renaming [ConstructorElement]s.
 class RenameConstructorRefactoringImpl extends RenameRefactoringImpl {
-  final AnalysisSession session;
-
   RenameConstructorRefactoringImpl(
-      RefactoringWorkspace workspace, this.session, ConstructorElement element)
-      : super(workspace, element);
+      super.workspace, super.sessionHelper, ConstructorElement super.element);
 
   @override
   ConstructorElement get element => super.element as ConstructorElement;
@@ -82,7 +77,7 @@
   }
 
   void _analyzePossibleConflicts(RefactoringStatus result) {
-    var parentClass = element.enclosingElement3;
+    var parentClass = element.enclosingElement;
     // Check if the "newName" is the name of the enclosing class.
     if (parentClass.name == newName) {
       result.addError('The constructor should not have the same name '
@@ -107,10 +102,9 @@
   }
 
   Future<void> _replaceSynthetic() async {
-    var classElement = element.enclosingElement3;
+    var classElement = element.enclosingElement;
 
-    var result = await AnalysisSessionHelper(session)
-        .getElementDeclaration(classElement);
+    var result = await sessionHelper.getElementDeclaration(classElement);
     if (result == null) {
       return;
     }
@@ -123,7 +117,8 @@
     var node = result.node;
     if (node is ClassDeclaration) {
       var utils = CorrectionUtils(resolvedUnit);
-      var location = utils.prepareNewConstructorLocation(session, node);
+      var location =
+          utils.prepareNewConstructorLocation(sessionHelper.session, node);
       if (location == null) {
         return;
       }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_extension_member.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_extension_member.dart
index c1bb99b..5f11c41 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_extension_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_extension_member.dart
@@ -12,7 +12,6 @@
 import 'package:analysis_server/src/services/refactoring/legacy/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -22,15 +21,16 @@
 
 /// A [Refactoring] for renaming extension member [Element]s.
 class RenameExtensionMemberRefactoringImpl extends RenameRefactoringImpl {
-  final AnalysisSessionHelper sessionHelper;
   final ExtensionElement extensionElement;
 
   late _ExtensionMemberValidator _validator;
 
-  RenameExtensionMemberRefactoringImpl(RefactoringWorkspace workspace,
-      AnalysisSession session, this.extensionElement, Element element)
-      : sessionHelper = AnalysisSessionHelper(session),
-        super(workspace, element);
+  RenameExtensionMemberRefactoringImpl(
+      RefactoringWorkspace workspace,
+      AnalysisSessionHelper sessionHelper,
+      this.extensionElement,
+      Element element)
+      : super(workspace, sessionHelper, element);
 
   @override
   String get refactoringName {
@@ -56,7 +56,7 @@
     if (element is MethodElement && (element as MethodElement).isOperator) {
       result.addFatalError('Cannot rename operator.');
     }
-    return Future<RefactoringStatus>.value(result);
+    return result;
   }
 
   @override
@@ -73,7 +73,7 @@
 
   @override
   Future<void> fillChange() async {
-    var processor = RenameProcessor(workspace, change, newName);
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
 
     // Update the declaration.
     var renameElement = element;
@@ -212,11 +212,39 @@
   _LocalElementsCollector(this.name);
 
   @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    var element = node.staticElement;
-    if (element is LocalElement && element.name == name) {
-      elements.add(element);
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    if (node.name.lexeme == name) {
+      final element = node.declaredElement;
+      if (element is FunctionElement) {
+        elements.add(element);
+      }
     }
+
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    if (node.name?.lexeme == name) {
+      final element = node.declaredElement;
+      if (element != null) {
+        elements.add(element);
+      }
+    }
+
+    super.visitSimpleFormalParameter(node);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    if (node.name.lexeme == name) {
+      final element = node.declaredElement;
+      if (element is LocalVariableElement) {
+        elements.add(element);
+      }
+    }
+
+    super.visitVariableDeclaration(node);
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_import.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_import.dart
index 01e2ccd..d01ad6f 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_import.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_import.dart
@@ -9,7 +9,6 @@
 import 'package:analysis_server/src/services/refactoring/legacy/refactoring_internal.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename.dart';
 import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
@@ -18,11 +17,8 @@
 
 /// A [Refactoring] for renaming [LibraryImportElement]s.
 class RenameImportRefactoringImpl extends RenameRefactoringImpl {
-  final AnalysisSession session;
-
-  RenameImportRefactoringImpl(RefactoringWorkspace workspace, this.session,
-      LibraryImportElement element)
-      : super(workspace, element);
+  RenameImportRefactoringImpl(
+      super.workspace, super.sessionHelper, LibraryImportElement super.element);
 
   @override
   LibraryImportElement get element => super.element as LibraryImportElement;
@@ -102,7 +98,7 @@
   Future<ImportDirective?> _findNode() async {
     var library = element.library;
     var path = library.source.fullName;
-    var unitResult = session.getParsedUnit(path);
+    var unitResult = sessionHelper.session.getParsedUnit(path);
     if (unitResult is! ParsedUnitResult) {
       return null;
     }
@@ -118,7 +114,7 @@
     SourceReference reference,
   ) async {
     var source = reference.element.source!;
-    var unitResult = session.getParsedUnit(source.fullName);
+    var unitResult = sessionHelper.session.getParsedUnit(source.fullName);
     if (unitResult is! ParsedUnitResult) {
       return null;
     }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_label.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_label.dart
index b6c3710..9421528 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_label.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_label.dart
@@ -10,7 +10,8 @@
 
 /// A [Refactoring] for renaming [LabelElement]s.
 class RenameLabelRefactoringImpl extends RenameRefactoringImpl {
-  RenameLabelRefactoringImpl(super.workspace, LabelElement super.element);
+  RenameLabelRefactoringImpl(
+      super.workspace, super.sessionHelper, LabelElement super.element);
 
   @override
   LabelElement get element => super.element as LabelElement;
@@ -33,7 +34,7 @@
 
   @override
   Future<void> fillChange() {
-    var processor = RenameProcessor(workspace, change, newName);
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
     return processor.renameElement(element);
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_library.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_library.dart
index 1423092..74371dc 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_library.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_library.dart
@@ -10,7 +10,8 @@
 
 /// A [Refactoring] for renaming [LibraryElement]s.
 class RenameLibraryRefactoringImpl extends RenameRefactoringImpl {
-  RenameLibraryRefactoringImpl(super.workspace, LibraryElement super.element);
+  RenameLibraryRefactoringImpl(
+      super.workspace, super.sessionHelper, LibraryElement super.element);
 
   @override
   LibraryElement get element => super.element as LibraryElement;
@@ -35,7 +36,7 @@
 
   @override
   Future<void> fillChange() async {
-    var processor = RenameProcessor(workspace, change, newName);
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
     await processor.renameElement(element);
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_local.dart
index 1df2986..18da253 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_local.dart
@@ -11,113 +11,20 @@
 import 'package:analysis_server/src/services/refactoring/legacy/rename.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/generated/source.dart';
 
-/// A [Refactoring] for renaming [LocalElement]s.
-class RenameLocalRefactoringImpl extends RenameRefactoringImpl {
-  final AnalysisSessionHelper sessionHelper;
-
-  List<LocalElement> elements = [];
-
-  RenameLocalRefactoringImpl(
-      super.workspace, AnalysisSession session, LocalElement super.element)
-      : sessionHelper = AnalysisSessionHelper(session);
-
-  @override
-  LocalElement get element => super.element as LocalElement;
-
-  @override
-  String get refactoringName {
-    if (element is ParameterElement) {
-      return 'Rename Parameter';
-    }
-    if (element is FunctionElement) {
-      return 'Rename Local Function';
-    }
-    return 'Rename Local Variable';
-  }
-
-  @override
-  Future<RefactoringStatus> checkFinalConditions() async {
-    var result = RefactoringStatus();
-    await _prepareElements();
-    for (var element in elements) {
-      var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
-      var unit = resolvedUnit?.unit;
-      unit?.accept(
-        _ConflictValidatorVisitor(
-          result,
-          newName,
-          element,
-          VisibleRangesComputer.forNode(unit),
-        ),
-      );
-    }
-    return result;
-  }
-
-  @override
-  RefactoringStatus checkNewName() {
-    var result = super.checkNewName();
-    if (element is LocalVariableElement) {
-      result.addStatus(validateVariableName(newName));
-    } else if (element is ParameterElement) {
-      result.addStatus(validateParameterName(newName));
-    } else if (element is FunctionElement) {
-      result.addStatus(validateFunctionName(newName));
-    }
-    return result;
-  }
-
-  @override
-  Future<void> fillChange() async {
-    var processor = RenameProcessor(workspace, change, newName);
-    for (Element element in elements) {
-      processor.addDeclarationEdit(element);
-      var references = await searchEngine.searchReferences(element);
-
-      // Remove references that don't have to have the same name.
-      if (element is ParameterElement) {
-        // Implicit references to optional positional parameters.
-        if (element.isOptionalPositional) {
-          references.removeWhere((match) => match.sourceRange.length == 0);
-        }
-        // References to positional parameters from super-formal.
-        if (element.isPositional) {
-          references.removeWhere(
-            (match) => match.element is SuperFormalParameterElement,
-          );
-        }
-      }
-
-      processor.addReferenceEdits(references);
-    }
-  }
-
-  /// Fills [elements] with [Element]s to rename.
-  Future _prepareElements() async {
-    final element = this.element;
-    if (element is ParameterElement && element.isNamed) {
-      elements = await getHierarchyNamedParameters(searchEngine, element);
-    } else {
-      elements = [element];
-    }
-  }
-}
-
-class _ConflictValidatorVisitor extends RecursiveAstVisitor<void> {
+class ConflictValidatorVisitor extends RecursiveAstVisitor<void> {
   final RefactoringStatus result;
   final String newName;
   final LocalElement target;
   final Map<Element, SourceRange> visibleRangeMap;
   final Set<Element> conflictingLocals = <Element>{};
 
-  _ConflictValidatorVisitor(
+  ConflictValidatorVisitor(
     this.result,
     this.newName,
     this.target,
@@ -125,17 +32,19 @@
   );
 
   @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    _checkDeclaration(
+      declaredElement: node.declaredElement!,
+      nameToken: node.name,
+    );
+
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
     var nodeElement = node.staticElement;
     if (nodeElement != null && nodeElement.name == newName) {
-      // Duplicate declaration.
-      if (node.inDeclarationContext() && _isVisibleWithTarget(nodeElement)) {
-        conflictingLocals.add(nodeElement);
-        var nodeKind = nodeElement.kind.displayName;
-        var message = "Duplicate $nodeKind '$newName'.";
-        result.addError(message, newLocation_fromElement(nodeElement));
-        return;
-      }
       if (conflictingLocals.contains(nodeElement)) {
         return;
       }
@@ -157,6 +66,32 @@
     }
   }
 
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    _checkDeclaration(
+      declaredElement: node.declaredElement!,
+      nameToken: node.name,
+    );
+
+    super.visitVariableDeclaration(node);
+  }
+
+  void _checkDeclaration({
+    required Element? declaredElement,
+    required Token nameToken,
+  }) {
+    if (declaredElement != null && nameToken.lexeme == newName) {
+      // Duplicate declaration.
+      if (_isVisibleWithTarget(declaredElement)) {
+        conflictingLocals.add(declaredElement);
+        var nodeKind = declaredElement.kind.displayName;
+        var message = "Duplicate $nodeKind '$newName'.";
+        result.addError(message, newLocation_fromElement(declaredElement));
+        return;
+      }
+    }
+  }
+
   SourceRange? _getVisibleRange(LocalElement element) {
     return visibleRangeMap[element];
   }
@@ -176,3 +111,55 @@
     return parent is Label && parent.parent is NamedExpression;
   }
 }
+
+/// A [Refactoring] for renaming [LocalElement]s (excluding [ParameterElement]).
+class RenameLocalRefactoringImpl extends RenameRefactoringImpl {
+  RenameLocalRefactoringImpl(
+      super.workspace, super.sessionHelper, LocalElement super.element);
+
+  @override
+  LocalElement get element => super.element as LocalElement;
+
+  @override
+  String get refactoringName {
+    if (element is FunctionElement) {
+      return 'Rename Local Function';
+    }
+    return 'Rename Local Variable';
+  }
+
+  @override
+  Future<RefactoringStatus> checkFinalConditions() async {
+    var result = RefactoringStatus();
+    var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
+    var unit = resolvedUnit?.unit;
+    unit?.accept(
+      ConflictValidatorVisitor(
+        result,
+        newName,
+        element,
+        VisibleRangesComputer.forNode(unit),
+      ),
+    );
+    return result;
+  }
+
+  @override
+  RefactoringStatus checkNewName() {
+    var result = super.checkNewName();
+    if (element is LocalVariableElement) {
+      result.addStatus(validateVariableName(newName));
+    } else if (element is FunctionElement) {
+      result.addStatus(validateFunctionName(newName));
+    }
+    return result;
+  }
+
+  @override
+  Future<void> fillChange() async {
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
+    processor.addDeclarationEdit(element);
+    var references = await searchEngine.searchReferences(element);
+    processor.addReferenceEdits(references);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_parameter.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_parameter.dart
new file mode 100644
index 0000000..0e81559
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_parameter.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2022, 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/status.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/naming_conventions.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/refactoring.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/rename.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/rename_local.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/visible_ranges_computer.dart';
+import 'package:analysis_server/src/services/search/hierarchy.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+
+/// A [Refactoring] for renaming [ParameterElement]s.
+class RenameParameterRefactoringImpl extends RenameRefactoringImpl {
+  List<ParameterElement> elements = [];
+
+  RenameParameterRefactoringImpl(
+      super.workspace, super.sessionHelper, ParameterElement super.element);
+
+  @override
+  ParameterElement get element => super.element as ParameterElement;
+
+  @override
+  String get refactoringName {
+    return 'Rename Parameter';
+  }
+
+  @override
+  Future<RefactoringStatus> checkFinalConditions() async {
+    var result = RefactoringStatus();
+    await _prepareElements();
+    for (var element in elements) {
+      if (newName.startsWith('_') && element.isNamed) {
+        result.addError(
+          format("The parameter '{0}' is named and can not be private.",
+              element.name),
+        );
+        break;
+      }
+      var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
+      var unit = resolvedUnit?.unit;
+      unit?.accept(
+        ConflictValidatorVisitor(
+          result,
+          newName,
+          element,
+          VisibleRangesComputer.forNode(unit),
+        ),
+      );
+    }
+    return result;
+  }
+
+  @override
+  RefactoringStatus checkNewName() {
+    var result = super.checkNewName();
+    result.addStatus(validateParameterName(newName));
+    return result;
+  }
+
+  @override
+  Future<void> fillChange() async {
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
+    for (var element in elements) {
+      var fieldRenamed = false;
+      if (element is FieldFormalParameterElement) {
+        var field = element.field;
+        if (field != null) {
+          await processor.renameElement(field);
+          fieldRenamed = true;
+        }
+      }
+
+      if (!fieldRenamed) {
+        processor.addDeclarationEdit(element);
+      }
+      var references = await searchEngine.searchReferences(element);
+
+      // Remove references that don't have to have the same name.
+
+      // Implicit references to optional positional parameters.
+      if (element.isOptionalPositional) {
+        references.removeWhere((match) => match.sourceRange.length == 0);
+      }
+      // References to positional parameters from super-formal.
+      if (element.isPositional) {
+        references.removeWhere(
+          (match) => match.element is SuperFormalParameterElement,
+        );
+      }
+
+      processor.addReferenceEdits(references);
+    }
+  }
+
+  /// Fills [elements] with [Element]s to rename.
+  Future<void> _prepareElements() async {
+    final element = this.element;
+    if (element.isNamed) {
+      elements = await getHierarchyNamedParameters(searchEngine, element);
+    } else {
+      elements = [element];
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_unit_member.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_unit_member.dart
index 30f982f..f2e22b4 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_unit_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_unit_member.dart
@@ -15,6 +15,7 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart' show Identifier;
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 
 /// Checks if creating a top-level function with the given [name] in [library]
@@ -44,9 +45,9 @@
   /// If [_flutterWidgetState] is set, this is the new name of it.
   String? _flutterWidgetStateNewName;
 
-  RenameUnitMemberRefactoringImpl(
-      RefactoringWorkspace workspace, this.resolvedUnit, Element element)
-      : super(workspace, element);
+  RenameUnitMemberRefactoringImpl(RefactoringWorkspace workspace,
+      AnalysisSessionHelper sessionHelper, this.resolvedUnit, Element element)
+      : super(workspace, sessionHelper, element);
 
   @override
   String get refactoringName {
@@ -98,7 +99,7 @@
     if (element is TypeAliasElement) {
       result.addStatus(validateTypeAliasName(newName));
     }
-    if (element is ClassElement) {
+    if (element is InterfaceElement) {
       result.addStatus(validateClassName(newName));
     }
     return result;
@@ -123,7 +124,7 @@
     }
 
     // Rename each element and references to it.
-    var processor = RenameProcessor(workspace, change, newName);
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
     for (var element in elements) {
       await processor.renameElement(element);
     }
@@ -134,6 +135,7 @@
       _updateFlutterWidgetStateName();
       await RenameProcessor(
         workspace,
+        sessionHelper,
         change,
         _flutterWidgetStateNewName!,
       ).renameElement(flutterWidgetState);
@@ -214,7 +216,7 @@
     var declarations = await searchEngine.searchMemberDeclarations(name);
     for (var declaration in declarations) {
       var member = declaration.element;
-      var declaringClass = member.enclosingElement3 as ClassElement;
+      var declaringClass = member.enclosingElement as InterfaceElement;
       var memberReferences = await searchEngine.searchReferences(member);
       for (var memberReference in memberReferences) {
         var refElement = memberReference.element;
@@ -223,7 +225,7 @@
           continue;
         }
         // cannot be shadowed if declared in the same class as reference
-        var refClass = refElement.thisOrAncestorOfType<ClassElement>();
+        var refClass = refElement.thisOrAncestorOfType<InterfaceElement>();
         if (refClass == declaringClass) {
           continue;
         }
@@ -301,7 +303,7 @@
   void _validateWillBeShadowed() {
     for (var reference in references) {
       var refElement = reference.element;
-      var refClass = refElement.thisOrAncestorOfType<ClassElement>();
+      var refClass = refElement.thisOrAncestorOfType<InterfaceElement>();
       if (refClass != null) {
         visitChildren(refClass, (shadow) {
           if (hasDisplayName(shadow, name)) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/visible_ranges_computer.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/visible_ranges_computer.dart
index 7c2a94b..6e8b38e 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/visible_ranges_computer.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/visible_ranges_computer.dart
@@ -37,7 +37,7 @@
     var loop = node.parent;
     if (loop != null) {
       for (var variable in node.variables.variables) {
-        _addLocalVariable(loop, variable.declaredElement2);
+        _addLocalVariable(loop, variable.declaredElement);
         variable.initializer?.accept(this);
       }
     }
@@ -47,7 +47,7 @@
   void visitFunctionDeclaration(FunctionDeclaration node) {
     var block = node.parent?.parent;
     if (block is Block) {
-      var element = node.declaredElement2 as FunctionElement;
+      var element = node.declaredElement as FunctionElement;
       _map[element] = range.node(block);
     }
 
@@ -59,7 +59,7 @@
     var block = node.parent;
     if (block != null) {
       for (var variable in node.variables.variables) {
-        _addLocalVariable(block, variable.declaredElement2);
+        _addLocalVariable(block, variable.declaredElement);
         variable.initializer?.accept(this);
       }
     }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_top_level_to_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_top_level_to_file.dart
index f350f89..8d618719c 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_top_level_to_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_top_level_to_file.dart
@@ -4,7 +4,9 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
 import 'package:analysis_server/src/services/refactoring/framework/refactoring_producer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
 
 /// An object that can compute a refactoring in a Dart file.
 class MoveTopLevelToFile extends RefactoringProducer {
@@ -23,25 +25,143 @@
 
   @override
   List<CommandParameter> get parameters => [
-        CommandParameter(
-          label: 'Move to:',
-          type: CommandParameterType.filePath,
-          defaultValue: defaultFilePath,
+        SaveUriCommandParameter(
+          parameterLabel: 'Move to:',
+          parameterTitle: 'Select a file to move to',
+          actionLabel: 'Move',
+          // defaultValue is a String URI.
+          defaultValue: Uri.file(defaultFilePath).toString(),
+          filters: {
+            'Dart': ['dart']
+          },
         ),
       ];
 
-  @override
-  Future<void> compute(List<String> commandArguments, ChangeBuilder builder) {
-    // TODO: implement compute
-    throw UnimplementedError();
+  /// Return the member to be moved. As a side-effect, initialize the [title]
+  /// and [defaultFilePath].
+  _MemberToMove? get _memberToMove {
+    // TODO(brianwilkerson) Extend this to support the selection of multiple
+    //  top-level declarations by returning a list of the members to be moved.
+    var node = selectedNode;
+    // TODO(brianwilkerson) If the caret is at the end of the name and before
+    //  the parameter list, then the `node` is the parameter list. This code
+    //  doesn't handle that case yet.
+    if (node is VariableDeclaration) {
+      var declaration = node.parent?.parent;
+      if (declaration is TopLevelVariableDeclaration &&
+          declaration.variables.variables.length == 1 &&
+          selectionIsInToken(node.name)) {
+        return _memberFor(declaration, node.name.lexeme);
+      }
+    }
+    if (node is! CompilationUnitMember) {
+      return null;
+    }
+    String name;
+    if (node is ClassDeclaration && selectionIsInToken(node.name)) {
+      name = node.name.lexeme;
+    } else if (node is EnumDeclaration && selectionIsInToken(node.name)) {
+      name = node.name.lexeme;
+    } else if (node is ExtensionDeclaration && selectionIsInToken(node.name)) {
+      name = node.name!.lexeme;
+    } else if (node is FunctionDeclaration &&
+        node.parent is CompilationUnit &&
+        selectionIsInToken(node.name)) {
+      name = node.name.lexeme;
+    } else if (node is MixinDeclaration && selectionIsInToken(node.name)) {
+      name = node.name.lexeme;
+    } else if (node is TypeAlias && selectionIsInToken(node.name)) {
+      name = node.name.lexeme;
+    } else {
+      return null;
+    }
+    return _memberFor(node, name);
   }
 
   @override
-  bool isAvailable() {
-    // TODO: implement isAvailable
-    // TODO: initialize `title` to "Move '$name' to file"
-    // TODO: initialize `defaultFilePath` to a path based on the name of the
-    //  declaration.
-    return false;
+  Future<void> compute(
+      List<Object?> commandArguments, ChangeBuilder builder) async {
+    var member = _memberToMove;
+    if (member == null) {
+      return;
+    }
+    var sourcePath = member.containingFile;
+    // TODO(dantup): Add refactor-specific validation for incoming arguments.
+    // Argument is a String URI.
+    var destinationUri = Uri.parse(commandArguments[0] as String);
+    var destinationFilePath = destinationUri.toFilePath();
+
+    var importUri = result.session.uriConverter
+        .pathToUri(destinationFilePath, containingPath: sourcePath);
+    if (importUri == null) {
+      return;
+    }
+    await builder.addDartFileEdit(destinationFilePath, (builder) {
+      // TODO(brianwilkerson) Copy the file header to the new file.
+      // TODO(brianwilkerson) Use `ImportedElementsComputer` to add imports
+      //  required by the newly copied code. Better yet, combine that with the
+      //  import analysis used to find unused and unnecessary imports so that we
+      //  can also remove any unused or unnecessary imports from the source
+      //  library.
+      // TODO(dantup): Ensure the range inserted and deleted match (allowing for
+      //  whitespace), including handling of leading/trailing comments etc.
+      builder.addInsertion(0, (builder) {
+        builder.writeln(utils.getNodeText(member.node));
+      });
+    });
+    await builder.addDartFileEdit(sourcePath, (builder) {
+      // TODO(brianwilkerson) Only add an import for the new file if the
+      //  remaining code references the moved code.
+      // builder.importLibrary(destinationUri);
+      builder.addDeletion(range.deletionRange(member.node));
+    });
+    // TODO(brianwilkerson) Find references to the moved declaration(s) outside
+    //  the source library and update the imports in those files.
   }
+
+  @override
+  bool isAvailable() => supportsFileCreation && _memberToMove != null;
+
+  /// Computes a filename for a given class name (convert from PascalCase to
+  /// snake_case).
+  // TODO(brianwilkerson) Copied from handler_rename.dart. Move this code to a
+  //  common location, preferably as an extension on `String`.
+  String _fileNameForClassName(String className) {
+    final fileName = className
+        .replaceAllMapped(RegExp('[A-Z]'),
+            (match) => match.start == 0 ? match[0]! : '_${match[0]}')
+        .toLowerCase();
+    return '$fileName.dart';
+  }
+
+  _MemberToMove? _memberFor(CompilationUnitMember declaration, String name) {
+    // TODO(brianwilkeson) Handle other top-level members, including
+    //  augmentations.
+    var unitPath = result.unit.declaredElement?.source.fullName;
+    if (unitPath == null) {
+      return null;
+    }
+    var context = result.session.resourceProvider.pathContext;
+
+    title = "Move '$name' to file";
+    defaultFilePath =
+        context.join(context.dirname(unitPath), _fileNameForClassName(name));
+    return _MemberToMove(unitPath, declaration, name);
+  }
+}
+
+/// Information about the member to be moved.
+class _MemberToMove {
+  /// The absolute and normalized path of the file containing the member.
+  final String containingFile;
+
+  /// The member to be moved.
+  final CompilationUnitMember node;
+
+  /// The name of the member.
+  final String name;
+
+  /// Initialize a newly created instance representing the [member] with the
+  /// given [name].
+  _MemberToMove(this.containingFile, this.node, this.name);
 }
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 6fb64ec..d99b873 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -20,7 +20,7 @@
   return children;
 }
 
-/// Returns direct non-synthetic children of the given [ClassElement].
+/// Returns direct non-synthetic children of the given [InterfaceElement].
 ///
 /// Includes: fields, accessors and methods.
 /// Excludes: constructors and synthetic elements.
@@ -48,10 +48,10 @@
 }
 
 /// Returns a [Set] with direct subclasses of [seed].
-Future<Set<ClassElement>> getDirectSubClasses(
+Future<Set<InterfaceElement>> getDirectSubClasses(
     SearchEngine searchEngine, InterfaceElement seed) async {
   var matches = await searchEngine.searchSubtypes(seed);
-  return matches.map((match) => match.element).cast<ClassElement>().toSet();
+  return matches.map((match) => match.element).cast<InterfaceElement>().toSet();
 }
 
 /// Return the non-synthetic children of the given [extension]. This includes
@@ -82,7 +82,7 @@
     SearchEngine searchEngine, ClassMemberElement member) async {
   Set<ClassMemberElement> result = HashSet<ClassMemberElement>();
   // extension member
-  var enclosingElement = member.enclosingElement3;
+  var enclosingElement = member.enclosingElement;
   if (enclosingElement is ExtensionElement) {
     result.add(member);
     return Future.value(result);
@@ -90,10 +90,10 @@
   // static elements
   if (member.isStatic || member is ConstructorElement) {
     result.add(member);
-    return Future.value(result);
+    return result;
   }
   // method, field, etc
-  if (enclosingElement is ClassElement) {
+  if (enclosingElement is InterfaceElement) {
     var name = member.displayName;
     var searchClasses = [
       ...enclosingElement.allSupertypes.map((e) => e.element2),
@@ -126,7 +126,7 @@
 Future<List<ParameterElement>> getHierarchyNamedParameters(
     SearchEngine searchEngine, ParameterElement element) async {
   if (element.isNamed) {
-    var method = element.enclosingElement3;
+    var method = element.enclosingElement;
     if (method is MethodElement) {
       var hierarchyParameters = <ParameterElement>[];
       var hierarchyMembers = await getHierarchyMembers(searchEngine, method);
@@ -147,7 +147,7 @@
   return [element];
 }
 
-/// Returns non-synthetic members of the given [ClassElement] and its super
+/// Returns non-synthetic members of the given [InterfaceElement] and its super
 /// classes.
 ///
 /// Includes: fields, accessors and methods.
diff --git a/pkg/analysis_server/lib/src/services/snippets/dart/flutter_stateful_widget_with_animation.dart b/pkg/analysis_server/lib/src/services/snippets/dart/flutter_stateful_widget_with_animation.dart
index 48f9208..48377f2 100644
--- a/pkg/analysis_server/lib/src/services/snippets/dart/flutter_stateful_widget_with_animation.dart
+++ b/pkg/analysis_server/lib/src/services/snippets/dart/flutter_stateful_widget_with_animation.dart
@@ -22,7 +22,7 @@
   @override
   late ClassElement? classKey;
   late ClassElement? classAnimationController;
-  late ClassElement? classSingleTickerProviderStateMixin;
+  late MixinElement? classSingleTickerProviderStateMixin;
 
   FlutterStatefulWidgetWithAnimationController(super.request);
 
@@ -132,7 +132,7 @@
         (classAnimationController = await getClass('AnimationController')) ==
             null ||
         (classSingleTickerProviderStateMixin =
-                await getClass('SingleTickerProviderStateMixin')) ==
+                await getMixin('SingleTickerProviderStateMixin')) ==
             null) {
       return false;
     }
diff --git a/pkg/analysis_server/lib/src/services/snippets/snippet_producer.dart b/pkg/analysis_server/lib/src/services/snippets/snippet_producer.dart
index eec21be..c3debac 100644
--- a/pkg/analysis_server/lib/src/services/snippets/snippet_producer.dart
+++ b/pkg/analysis_server/lib/src/services/snippets/snippet_producer.dart
@@ -55,8 +55,11 @@
   Future<ClassElement?> getClass(String name) =>
       sessionHelper.getClass(flutter.widgetsUri, name);
 
+  Future<MixinElement?> getMixin(String name) =>
+      sessionHelper.getMixin(flutter.widgetsUri, name);
+
   DartType getType(
-    ClassElement classElement, [
+    InterfaceElement classElement, [
     NullabilitySuffix nullabilitySuffix = NullabilitySuffix.none,
   ]) =>
       classElement.instantiate(
diff --git a/pkg/analysis_server/lib/src/status/ast_writer.dart b/pkg/analysis_server/lib/src/status/ast_writer.dart
index 8b8e20d..d077e80 100644
--- a/pkg/analysis_server/lib/src/status/ast_writer.dart
+++ b/pkg/analysis_server/lib/src/status/ast_writer.dart
@@ -43,10 +43,10 @@
       properties['static element'] = node.staticElement;
       properties['static type'] = node.staticType;
     } else if (node is ClassDeclaration) {
-      properties['declaredElement'] = node.declaredElement2;
+      properties['declaredElement'] = node.declaredElement;
       properties['abstract keyword'] = node.abstractKeyword;
     } else if (node is ClassTypeAlias) {
-      properties['declaredElement'] = node.declaredElement2;
+      properties['declaredElement'] = node.declaredElement;
       properties['abstract keyword'] = node.abstractKeyword;
     } else if (node is CompilationUnit) {
       properties['declaredElement'] = node.declaredElement;
@@ -55,7 +55,7 @@
     } else if (node is ConstructorName) {
       properties['static element'] = node.staticElement;
     } else if (node is DeclaredIdentifier) {
-      properties['element'] = node.declaredElement2;
+      properties['element'] = node.declaredElement;
       properties['keyword'] = node.keyword;
     } else if (node is ExportDirective) {
       properties['element'] = node.element2;
@@ -75,7 +75,7 @@
         properties['kind'] = 'unknown kind';
       }
     } else if (node is FunctionDeclaration) {
-      properties['declaredElement'] = node.declaredElement2;
+      properties['declaredElement'] = node.declaredElement;
       properties['external keyword'] = node.externalKeyword;
       properties['property keyword'] = node.propertyKeyword;
     } else if (node is FunctionExpressionInvocation) {
@@ -94,7 +94,7 @@
     } else if (node is LibraryDirective) {
       properties['element'] = node.element2;
     } else if (node is MethodDeclaration) {
-      properties['declaredElement'] = node.declaredElement2;
+      properties['declaredElement'] = node.declaredElement;
       properties['external keyword'] = node.externalKeyword;
       properties['modifier keyword'] = node.modifierKeyword;
       properties['operator keyword'] = node.operatorKeyword;
@@ -126,7 +126,7 @@
     } else if (node is VariableDeclarationList) {
       properties['keyword'] = node.keyword;
     } else if (node is Declaration) {
-      properties['declaredElement'] = node.declaredElement2;
+      properties['declaredElement'] = node.declaredElement;
     } else if (node is Expression) {
       properties['static type'] = node.staticType;
     } else if (node is FunctionBody) {
@@ -144,11 +144,11 @@
   /// declaration.
   String? _getName(AstNode node) {
     if (node is ClassTypeAlias) {
-      return node.name2.lexeme;
+      return node.name.lexeme;
     } else if (node is ClassDeclaration) {
-      return node.name2.lexeme;
+      return node.name.lexeme;
     } else if (node is ConstructorDeclaration) {
-      var name = node.name2;
+      var name = node.name;
       if (name == null) {
         return node.returnType.name;
       } else {
@@ -159,21 +159,21 @@
     } else if (node is FieldDeclaration) {
       return _getNames(node.fields);
     } else if (node is FunctionDeclaration) {
-      return node.name2.lexeme;
+      return node.name.lexeme;
     } else if (node is FunctionTypeAlias) {
-      return node.name2.lexeme;
+      return node.name.lexeme;
     } else if (node is Identifier) {
       return node.name;
     } else if (node is MethodDeclaration) {
-      return node.name2.lexeme;
+      return node.name.lexeme;
     } else if (node is TopLevelVariableDeclaration) {
       return _getNames(node.variables);
     } else if (node is TypeAnnotation) {
       return node.toSource();
     } else if (node is TypeParameter) {
-      return node.name2.lexeme;
+      return node.name.lexeme;
     } else if (node is VariableDeclaration) {
-      return node.name2.lexeme;
+      return node.name.lexeme;
     }
     return null;
   }
@@ -189,7 +189,7 @@
       } else {
         buffer.write(', ');
       }
-      buffer.write(variable.name2.lexeme);
+      buffer.write(variable.name.lexeme);
     }
     return buffer.toString();
   }
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index 61fbaef..86cbf8f 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -37,16 +37,17 @@
 
     properties['metadata'] = element.metadata;
     properties['nameOffset'] = element.nameOffset;
-    if (element is ClassElement) {
-      properties['hasNonFinalField'] = element.hasNonFinalField;
+    if (element is InterfaceElement) {
       properties['interfaces'] = element.interfaces;
-      properties['isAbstract'] = element.isAbstract;
       properties['isEnum'] = element is EnumElement;
-      properties['isMixinApplication'] = element.isMixinApplication;
-      properties['isValidMixin'] = element.isValidMixin;
       properties['mixins'] = element.mixins;
-      properties['superclassConstraints'] = element.superclassConstraints;
       properties['supertype'] = element.supertype;
+      if (element is ClassElement) {
+        properties['hasNonFinalField'] = element.hasNonFinalField;
+        properties['isAbstract'] = element.isAbstract;
+        properties['isMixinApplication'] = element.isMixinApplication;
+        properties['isValidMixin'] = element.isValidMixin;
+      }
     }
     if (element is ClassMemberElement) {
       properties['isStatic'] = element.isStatic;
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
index 703779c..01b1159 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
@@ -24,7 +24,7 @@
   ExtensionElement? get enclosingExtensionElement {
     for (final node in withParents) {
       if (node is ExtensionDeclaration) {
-        return node.declaredElement2;
+        return node.declaredElement;
       }
     }
     return null;
@@ -46,9 +46,9 @@
   InterfaceElement? get enclosingInterfaceElement {
     for (final node in withParents) {
       if (node is ClassDeclaration) {
-        return node.declaredElement2;
+        return node.declaredElement;
       } else if (node is MixinDeclaration) {
-        return node.declaredElement2;
+        return node.declaredElement;
       }
     }
     return null;
@@ -180,7 +180,7 @@
   }
 
   /// Return `true` if this expression is an invocation of the method `toList`
-  /// from either `Iterable` or `List`.
+  /// from `Iterable`.
   bool get isToListMethodInvocation {
     if (this is MethodInvocation) {
       var element = (this as MethodInvocation).methodName.staticElement;
@@ -188,6 +188,16 @@
     }
     return false;
   }
+
+  /// Return `true` if this expression is an invocation of the method `toSet`
+  /// from `Iterable`.
+  bool get isToSetMethodInvocation {
+    if (this is MethodInvocation) {
+      var element = (this as MethodInvocation).methodName.staticElement;
+      return element is MethodElement && element.isToSetMethod;
+    }
+    return false;
+  }
 }
 
 extension FunctionBodyExtensions on FunctionBody {
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/element.dart b/pkg/analysis_server/lib/src/utilities/extensions/element.dart
index cc38a89..43f190d 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/element.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/element.dart
@@ -30,15 +30,15 @@
     if (hasDeprecated) {
       return true;
     }
-    var ancestor = enclosingElement3;
-    if (ancestor is ClassElement) {
+    var ancestor = enclosingElement;
+    if (ancestor is InterfaceElement) {
       if (ancestor.hasDeprecated) {
         return true;
       }
-      ancestor = ancestor.enclosingElement3;
+      ancestor = ancestor.enclosingElement;
     }
     return ancestor is CompilationUnitElement &&
-        ancestor.enclosingElement3.hasDeprecated;
+        ancestor.enclosingElement.hasDeprecated;
   }
 
   /// Return this element and all its enclosing elements.
@@ -46,7 +46,7 @@
     var current = this;
     while (true) {
       yield current;
-      var enclosing = current.enclosingElement3;
+      var enclosing = current.enclosingElement;
       if (enclosing == null) {
         break;
       }
@@ -69,7 +69,7 @@
     if (name != 'cast') {
       return false;
     }
-    var definingClass = enclosingElement3;
+    var definingClass = enclosingElement;
     if (definingClass is! ClassElement) {
       return false;
     }
@@ -79,16 +79,29 @@
         definingClass.isDartCoreSet;
   }
 
-  /// Return `true` if this element represents the method `toList` from either
-  /// `Iterable` or `List`.
+  /// Return `true` if this element represents the method `toList` from
+  /// `Iterable`.
   bool get isToListMethod {
     if (name != 'toList') {
       return false;
     }
-    var definingClass = enclosingElement3;
+    var definingClass = enclosingElement;
     if (definingClass is! ClassElement) {
       return false;
     }
-    return definingClass.isDartCoreIterable || definingClass.isDartCoreList;
+    return definingClass.isDartCoreIterable;
+  }
+
+  /// Return `true` if this element represents the method `toSet` from
+  /// `Iterable`.
+  bool get isToSetMethod {
+    if (name != 'toSet') {
+      return false;
+    }
+    var definingClass = enclosingElement;
+    if (definingClass is! ClassElement) {
+      return false;
+    }
+    return definingClass.isDartCoreIterable;
   }
 }
diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart
index 26d5fb8..625d6c8 100644
--- a/pkg/analysis_server/lib/src/utilities/flutter.dart
+++ b/pkg/analysis_server/lib/src/utilities/flutter.dart
@@ -113,6 +113,17 @@
     }
   }
 
+  /// Return the named expression representing the `builder` argument of the
+  /// given [newExpr], or `null` if none.
+  NamedExpression? findBuilderArgument(InstanceCreationExpression newExpr) {
+    for (var argument in newExpr.argumentList.arguments) {
+      if (isBuilderArgument(argument)) {
+        return argument as NamedExpression;
+      }
+    }
+    return null;
+  }
+
   /// Return the named expression representing the `child` argument of the given
   /// [newExpr], or `null` if none.
   NamedExpression? findChildArgument(InstanceCreationExpression newExpr) {
@@ -192,7 +203,7 @@
 
   /// Return the presentation for the given Flutter `Widget` creation [node].
   String? getWidgetPresentationText(InstanceCreationExpression node) {
-    var element = node.constructorName.staticElement?.enclosingElement3;
+    var element = node.constructorName.staticElement?.enclosingElement;
     if (!isWidget(element)) {
       return null;
     }
@@ -220,21 +231,23 @@
 
   /// Return the instance creation expression that surrounds the given
   /// [node], if any, else null. The [node] may be the instance creation
-  /// expression itself or the identifier that names the constructor.
+  /// expression itself or an (optionally prefixed) identifier that names the
+  /// constructor.
   InstanceCreationExpression? identifyNewExpression(AstNode? node) {
     InstanceCreationExpression? newExpr;
     if (node is SimpleIdentifier) {
-      var parent = node.parent;
-      var grandParent = parent?.parent;
-      var greatGrandParent = grandParent?.parent;
-      if (parent is ConstructorName &&
-          grandParent is InstanceCreationExpression) {
-        newExpr = grandParent;
-      } else if (grandParent is ConstructorName &&
-          greatGrandParent is InstanceCreationExpression) {
-        newExpr = greatGrandParent;
-      }
-    } else if (node is InstanceCreationExpression) {
+      node = node.parent;
+    }
+    if (node is PrefixedIdentifier) {
+      node = node.parent;
+    }
+    if (node is NamedType) {
+      node = node.parent;
+    }
+    if (node is ConstructorName) {
+      node = node.parent;
+    }
+    if (node is InstanceCreationExpression) {
       newExpr = node;
     }
     return newExpr;
@@ -278,6 +291,10 @@
     return null;
   }
 
+  /// Return `true` is the given [argument] is the `builder` argument.
+  bool isBuilderArgument(Expression argument) =>
+      argument is NamedExpression && argument.name.label.name == 'builder';
+
   /// Return `true` is the given [argument] is the `child` argument.
   bool isChildArgument(Expression argument) =>
       argument is NamedExpression && argument.name.label.name == 'child';
@@ -338,13 +355,13 @@
   }
 
   /// Return `true` if the [element] is the Flutter class `Alignment`.
-  bool isExactAlignment(ClassElement element) {
+  bool isExactAlignment(InterfaceElement element) {
     return _isExactWidget(element, 'Alignment', _uriAlignment);
   }
 
   /// Return `true` if the [element] is the Flutter class
   /// `AlignmentDirectional`.
-  bool isExactAlignmentDirectional(ClassElement element) {
+  bool isExactAlignmentDirectional(InterfaceElement element) {
     return _isExactWidget(element, 'AlignmentDirectional', _uriAlignment);
   }
 
@@ -504,7 +521,7 @@
   /// Return `true` if the given [expr] is a constructor invocation for a
   /// class that has the Flutter class `Widget` as a superclass.
   bool isWidgetCreation(InstanceCreationExpression? expr) {
-    var element = expr?.constructorName.staticElement?.enclosingElement3;
+    var element = expr?.constructorName.staticElement?.enclosingElement;
     return isWidget(element);
   }
 
@@ -538,7 +555,7 @@
   /// Return `true` if the given [element] has a supertype with the
   /// [requiredName] defined in the file with the [requiredUri].
   bool _hasSupertype(
-      ClassElement? element, Uri requiredUri, String requiredName) {
+      InterfaceElement? element, Uri requiredUri, String requiredName) {
     if (element == null) {
       return false;
     }
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 555ede3..4713633 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -32,4 +32,5 @@
   lints: any
   logging: any
   matcher: any
+  string_scanner: any
   test_reflective_loader: any
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 4c55722..eb96892 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -52,6 +52,7 @@
         EnableString.enhanced_enums,
         EnableString.macros,
         EnableString.named_arguments_anywhere,
+        EnableString.records,
         EnableString.super_parameters,
       ];
 
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index a31aa2d..09f422c 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -1059,6 +1059,25 @@
     expect(hover.propagatedType, null);
   }
 
+  Future<void> test_methodInvocation_recordType() async {
+    newFile(testFilePath, '''
+class C {
+  List<int> m(int i, (int, String) r) => [];
+}
+void f(C c) {
+  c.m((1, '1'));
+}
+''');
+    var hover = await prepareHover('m((1');
+    expect(hover.containingLibraryName, 'package:test/test.dart');
+    expect(hover.containingLibraryPath, testFile.path);
+    expect(hover.containingClassDescription, 'C');
+    expect(hover.dartdoc, isNull);
+    expect(hover.elementDescription, 'List<int> m(int i, (int, String) r)');
+    expect(hover.elementKind, 'method');
+    expect(hover.staticType, 'List<int> Function(int, (int, String))');
+  }
+
   Future<void> test_mixin_declaration() async {
     newFile(testFilePath, '''
 mixin A on B, C implements D, E {}
@@ -1232,6 +1251,38 @@
     expect(hover.staticType, 'int');
   }
 
+  Future<void> test_parameter_reference_recordType() async {
+    newFile(testFilePath, '''
+void f((int, String) r) {
+  print(r);
+}
+''');
+    var hover = await prepareHover('r);');
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, isNull);
+    expect(hover.elementDescription, '(int, String) r');
+    expect(hover.elementKind, 'parameter');
+    expect(hover.staticType, '(int, String)');
+  }
+
+  Future<void> test_recordLiteral() async {
+    newFile(testFilePath, '''
+Object f() {
+  return ( 1, 'two', true );
+}
+''');
+    var hover = await prepareHover('( 1');
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, isNull);
+    expect(hover.elementDescription, isNull);
+    expect(hover.elementKind, isNull);
+    expect(hover.staticType, '(int, String, bool)');
+  }
+
   Future<void> test_simpleIdentifier_typedef_functionType() async {
     newFile(testFilePath, '''
 typedef A = void Function(int);
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index e12cbc1..451f438 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_test.dart
@@ -75,6 +75,28 @@
     assertHasRegion(examplePath, examplePath.length);
   }
 
+  Future<void> test_comment_toolSeeCodeComment_multiple() async {
+    var examplePath = 'examples/api/foo.dart';
+    var example2Path = 'examples/api/foo2.dart';
+    newFile('$testPackageLibPath/$examplePath', '');
+    newFile('$testPackageLibPath/$example2Path', '');
+    addTestFile('''
+/// {@tool dartpad}
+/// ** See code in $examplePath **
+/// {@end-tool}
+/// 
+/// {@tool dartpad}
+/// ** See code in $example2Path **
+/// {@end-tool}
+String f() {
+}''');
+    await waitForTasksFinished();
+    // Ensure we only get the expected region when there are multiple.
+    await _getNavigation(search: example2Path, length: 1);
+    expect(regions, hasLength(1));
+    assertHasRegion(example2Path, example2Path.length);
+  }
+
   Future<void> test_constructorInvocation() async {
     // Check that a constructor invocation navigates to the constructor and not
     // the class.
diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
index 4a0fd6c..6dae229 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
@@ -451,6 +451,18 @@
     assertHasRegion(HighlightRegionType.CLASS, 'AAA aaa');
   }
 
+  Future<void> test_class_constructor_fieldFormalParameter() async {
+    addTestFile('''
+class A {
+  final int foo;
+  A(this.foo);
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'this.');
+    assertHasRegion(HighlightRegionType.INSTANCE_FIELD_REFERENCE, 'foo);');
+  }
+
   Future<void> test_CLASS_notDynamic() async {
     addTestFile('''
 dynamic f() {}
@@ -712,7 +724,7 @@
     await prepareHighlights();
     assertHasRegion(HighlightRegionType.CLASS, 'int ');
     assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'a = 0');
-    assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'a);');
+    assertHasRegion(HighlightRegionType.INSTANCE_FIELD_REFERENCE, 'a);');
     assertHasRegion(HighlightRegionType.INSTANCE_GETTER_REFERENCE, 'a;');
   }
 
@@ -1325,6 +1337,19 @@
     assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'add(null)');
   }
 
+  Future<void> test_namedExpression_namedParameter() async {
+    addTestFile('''
+void f({int a}) {}
+
+void g() {
+  f(a: 0);
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'a})');
+    assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'a: 0');
+  }
+
   Future<void> test_PARAMETER() async {
     addTestFile('''
 void f(int p) {
@@ -1413,6 +1438,41 @@
     assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'aaa /*0*/');
   }
 
+  Future<void> test_recordTypeAnnotation_named() async {
+    addTestFile('''
+({int f1, String f2})? r;
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.CLASS, 'int f1');
+    assertHasRegion(HighlightRegionType.FIELD, 'f1');
+    assertHasRegion(HighlightRegionType.CLASS, 'String f2');
+    assertHasRegion(HighlightRegionType.FIELD, 'f2');
+  }
+
+  Future<void> test_recordTypeAnnotation_positional() async {
+    addTestFile('''
+(int, String f2)? r;
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.CLASS, 'int, ');
+    assertHasRegion(HighlightRegionType.CLASS, 'String f2)');
+    assertHasRegion(HighlightRegionType.FIELD, 'f2)');
+  }
+
+  Future<void> test_recordTypeLiteral_named() async {
+    final code = '(0, f1: 1, f2: 2)';
+    addTestFile('''
+final r = $code;
+''');
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LITERAL_RECORD, code);
+    assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '0,');
+    assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'f1:');
+    assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '1,');
+    assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'f2:');
+    assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '2)');
+  }
+
   Future<void> test_SETTER_DECLARATION() async {
     addTestFile('''
 set aaa(x) {}
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index 3dd3955..e117a79 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -30,7 +30,7 @@
   late List<NavigationTarget> testTargets;
   late NavigationTarget testTarget;
 
-  /// Validates that there is a target in [testTargetIndexes] with [file],
+  /// Validates that there is a target in [testTargets] with [file],
   /// at [offset] and with the given [length].
   void assertHasFileTarget(String file, int offset, int length) {
     for (var target in testTargets) {
@@ -115,20 +115,20 @@
     assertHasTarget(str, str.length);
   }
 
-  /// Validates that there is no a region at [search] and with the given
+  /// Validates that there is not a region at [search] and with the given
   /// [length].
   void assertNoRegion(String search, int length) {
     var offset = findOffset(search);
     findRegion(offset, length, false);
   }
 
-  /// Validates that there is no a region at [search] with any length.
+  /// Validates that there is not a region at [search] with any length.
   void assertNoRegionAt(String search) {
     var offset = findOffset(search);
     findRegion(offset, -1, false);
   }
 
-  /// Validates that there is no a region for [search] string.
+  /// Validates that there is not a region for [search] string.
   void assertNoRegionString(String search) {
     var offset = findOffset(search);
     var length = search.length;
@@ -150,7 +150,7 @@
   /// If [length] is `-1`, then it is ignored.
   ///
   /// If [exists] is `true`, then fails if such region does not exist.
-  /// Otherwise remembers this it into [testRegion].
+  /// Otherwise remembers it in [testRegion].
   /// Also fills [testTargets] with its targets.
   ///
   /// If [exists] is `false`, then fails if such region exists.
@@ -1227,6 +1227,68 @@
     assertHasRegionTarget('d: 3', 'd}) {}');
   }
 
+  Future<void> test_navigation_dart_example_api() async {
+    final exampleLinkPath = 'examples/api/lib/test_file.dart';
+    final exampleApiFile =
+        join(convertPath(workspaceRootPath), convertPath(exampleLinkPath));
+    newFile(exampleApiFile, '/// Test');
+    addTestFile('''
+/// Dartdoc comment
+/// {@tool dartpad}
+/// Example description.
+///
+/// ** See code in examples/api/lib/test_file.dart **
+/// {@end-tool}
+const int foo = 0;
+''');
+    await prepareNavigation();
+    assertHasRegion(exampleLinkPath, 31);
+    assertHasFileTarget(
+        exampleApiFile.substring(
+            resourceProvider.pathContext.rootPrefix(exampleApiFile).length),
+        0,
+        0);
+  }
+
+  Future<void> test_navigation_dart_example_api_multiple() async {
+    final exampleLinkPath0 = 'examples/api/lib/test_file.0.dart';
+    final exampleLinkPath1 = 'examples/api/lib/test_file.1.dart';
+    final exampleApiFile0 = join(workspaceRootPath, exampleLinkPath0);
+    final exampleApiFile1 = join(workspaceRootPath, exampleLinkPath1);
+    newFile(exampleApiFile0, '/// Test 0');
+    newFile(exampleApiFile1, '/// Test 1');
+    addTestFile('''
+/// Dartdoc comment
+/// {@tool dartpad}
+/// Example description.
+///
+/// ** See code in examples/api/lib/test_file.0.dart **
+/// {@end-tool}
+///
+/// {@tool dartpad}
+/// Example description.
+///
+/// ** See code in examples/api/lib/test_file.1.dart **
+/// {@end-tool}
+const int foo = 0;
+''');
+    await prepareNavigation();
+    assertHasRegion(exampleLinkPath0, 33);
+    // Files created with newFile have to be absolute paths, but we're looking
+    // for root-relative paths.
+    assertHasFileTarget(
+        convertPath(exampleApiFile0.substring(
+            resourceProvider.pathContext.rootPrefix(exampleApiFile0).length)),
+        0,
+        0);
+    assertHasRegion(exampleLinkPath1, 33);
+    assertHasFileTarget(
+        convertPath(exampleApiFile1.substring(
+            resourceProvider.pathContext.rootPrefix(exampleApiFile1).length)),
+        0,
+        0);
+  }
+
   Future<void> test_operator_arithmetic() async {
     addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/client/completion_driver_test.dart b/pkg/analysis_server/test/client/completion_driver_test.dart
index 03df530..0a6bb9f 100644
--- a/pkg/analysis_server/test/client/completion_driver_test.dart
+++ b/pkg/analysis_server/test/client/completion_driver_test.dart
@@ -11,6 +11,8 @@
 import '../analysis_server_base.dart';
 import '../services/completion/dart/completion_check.dart';
 import '../services/completion/dart/completion_contributor_util.dart';
+import '../services/completion/dart/completion_printer.dart' as printer;
+import '../services/completion/dart/text_expectations.dart';
 import 'impl/completion_driver.dart';
 
 void main() {
@@ -27,6 +29,12 @@
   late CompletionDriver driver;
   late List<CompletionSuggestion> suggestions;
 
+  /// The configuration for [assertResponseText].
+  /// You almost always want to change it, usually in [setUp].
+  printer.Configuration printerConfiguration = printer.Configuration(
+    filter: (suggestion) => true,
+  );
+
   bool get isProtocolVersion1 {
     return protocol == TestingCompletionProtocol.version1;
   }
@@ -66,6 +74,30 @@
         isEmpty);
   }
 
+  /// Asserts that the [response] has the [expected] textual dump produced
+  /// using [printerConfiguration].
+  void assertResponseText(
+    CompletionResponseForTesting response,
+    String expected, {
+    bool printIfFailed = true,
+  }) {
+    final buffer = StringBuffer();
+    printer.CompletionResponsePrinter(
+      buffer: buffer,
+      configuration: printerConfiguration,
+      response: response,
+    ).writeResponse();
+    final actual = buffer.toString();
+
+    if (actual != expected) {
+      if (printIfFailed) {
+        print(actual);
+      }
+      TextExpectationsCollector.add(actual);
+    }
+    expect(actual, expected);
+  }
+
   void assertSuggestion({
     required String completion,
     ElementKind? element,
@@ -105,6 +137,9 @@
   Future<CompletionResponseForTesting> getTestCodeSuggestions(
     String content,
   ) async {
+    // Give the server time to create analysis contexts.
+    await pumpEventQueue(times: 1000);
+
     await addTestFile(content);
 
     return CompletionResponseForTesting(
diff --git a/pkg/analysis_server/test/client/impl/completion_driver.dart b/pkg/analysis_server/test/client/impl/completion_driver.dart
index c6b01d4..5f0c12e 100644
--- a/pkg/analysis_server/test/client/impl/completion_driver.dart
+++ b/pkg/analysis_server/test/client/impl/completion_driver.dart
@@ -48,7 +48,7 @@
     suggestionKind,
     suggestionSetRelevance + relevanceBoost,
     suggestion.label,
-    0,
+    suggestion.label.length,
     0,
     suggestion.element.isDeprecated,
     false,
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 3a86b88..a4fa83e 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -7,12 +7,11 @@
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/src/test_utilities/package_config_file_builder.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';
 
@@ -20,8 +19,9 @@
 import 'domain_completion_util.dart';
 import 'mocks.dart';
 import 'services/completion/dart/completion_check.dart';
+import 'services/completion/dart/completion_printer.dart' as printer;
+import 'services/completion/dart/text_expectations.dart';
 import 'src/plugin/plugin_manager_test.dart';
-import 'utils/change_check.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -34,6 +34,29 @@
 @reflectiveTest
 class CompletionDomainHandlerGetSuggestionDetails2Test
     extends PubPackageAnalysisServerTest {
+  void assertDetailsText(
+    CompletionGetSuggestionDetails2Result result,
+    String expected, {
+    bool printIfFailed = true,
+  }) {
+    final buffer = StringBuffer();
+    _SuggestionDetailsPrinter(
+      resourceProvider: resourceProvider,
+      fileDisplayMap: {testFile: 'testFile'},
+      buffer: buffer,
+      result: result,
+    ).writeResult();
+    final actual = buffer.toString();
+
+    if (actual != expected) {
+      if (printIfFailed) {
+        print(actual);
+      }
+      TextExpectationsCollector.add(actual);
+    }
+    expect(actual, expected);
+  }
+
   Future<void> test_alreadyImported() async {
     await _configureWithWorkspaceRoot();
 
@@ -43,9 +66,11 @@
   Rand^
 }
 ''', completion: 'Random', libraryUri: 'dart:math');
-    check(details)
-      ..completion.isEqualTo('Random')
-      ..change.edits.isEmpty;
+
+    assertDetailsText(details, r'''
+completion: Random
+  change
+''');
   }
 
   Future<void> test_import_dart() async {
@@ -56,17 +81,14 @@
   R^
 }
 ''', completion: 'Random', libraryUri: 'dart:math');
-    check(details)
-      ..completion.isEqualTo('Random')
-      ..change
-          .hasFileEdit(testFile.path)
-          .appliedTo(testFileContent)
-          .isEqualTo(r'''
-import 'dart:math';
 
-void f() {
-  R
-}
+    assertDetailsText(details, r'''
+completion: Random
+  change
+    testFile
+      offset: 0
+      length: 0
+      replacement: import 'dart:math';\n\n
 ''');
   }
 
@@ -94,17 +116,14 @@
   T^
 }
 ''', completion: 'Test', libraryUri: 'package:aaa/a.dart');
-    check(details)
-      ..completion.isEqualTo('Test')
-      ..change
-          .hasFileEdit(testFile.path)
-          .appliedTo(testFileContent)
-          .isEqualTo(r'''
-import 'package:aaa/a.dart';
 
-void f() {
-  T
-}
+    assertDetailsText(details, r'''
+completion: Test
+  change
+    testFile
+      offset: 0
+      length: 0
+      replacement: import 'package:aaa/a.dart';\n\n
 ''');
   }
 
@@ -120,17 +139,14 @@
   T^
 }
 ''', completion: 'Test', libraryUri: 'package:test/a.dart');
-    check(details)
-      ..completion.isEqualTo('Test')
-      ..change
-          .hasFileEdit(testFile.path)
-          .appliedTo(testFileContent)
-          .isEqualTo(r'''
-import 'package:test/a.dart';
 
-void f() {
-  T
-}
+    assertDetailsText(details, r'''
+completion: Test
+  change
+    testFile
+      offset: 0
+      length: 0
+      replacement: import 'package:test/a.dart';\n\n
 ''');
   }
 
@@ -221,6 +237,42 @@
 @reflectiveTest
 class CompletionDomainHandlerGetSuggestions2Test
     extends PubPackageAnalysisServerTest {
+  printer.Configuration printerConfiguration = printer.Configuration(
+    filter: (suggestion) {
+      final completion = suggestion.completion;
+      if (completion.startsWith('A0')) {
+        return suggestion.isClass;
+      }
+      return const {'foo0'}.any(completion.startsWith);
+    },
+    withIsNotImported: true,
+    withLibraryUri: true,
+  );
+
+  /// Asserts that the [response] has the [expected] textual dump produced
+  /// using [printerConfiguration].
+  void assertResponseText(
+    CompletionResponseForTesting response,
+    String expected, {
+    bool printIfFailed = true,
+  }) {
+    final buffer = StringBuffer();
+    printer.CompletionResponsePrinter(
+      buffer: buffer,
+      configuration: printerConfiguration,
+      response: response,
+    ).writeResponse();
+    final actual = buffer.toString();
+
+    if (actual != expected) {
+      if (printIfFailed) {
+        print(actual);
+      }
+      TextExpectationsCollector.add(actual);
+    }
+    expect(actual, expected);
+  }
+
   @override
   void setUp() {
     super.setUp();
@@ -250,19 +302,28 @@
     // The first two should be aborted.
     expect(abortedIdSet, {'0', '1'});
 
-    check(response0)
-      ..assertIncomplete()
-      ..suggestions.isEmpty;
+    printerConfiguration.filter = (suggestion) {
+      if (suggestion.isClass) {
+        return const {'int'}.contains(suggestion.completion);
+      }
+      return false;
+    };
 
-    check(response1)
-      ..assertIncomplete()
-      ..suggestions.isEmpty;
+    assertResponseText(response0, r'''
+suggestions
+''');
 
-    check(response2)
-      ..assertComplete()
-      ..suggestions.containsMatch(
-        (suggestion) => suggestion.completion.isEqualTo('int'),
-      );
+    assertResponseText(response1, r'''
+suggestions
+''');
+
+    assertResponseText(response2, r'''
+suggestions
+  int
+    kind: class
+    isNotImported: null
+    libraryUri: dart:core
+''');
   }
 
   Future<void> test_abort_onUpdateContent() async {
@@ -289,9 +350,9 @@
     var response = await request.toResponse();
     expect(abortedIdSet, {'0'});
 
-    check(response)
-      ..assertIncomplete()
-      ..suggestions.isEmpty;
+    assertResponseText(response, r'''
+suggestions
+''');
   }
 
   Future<void> test_applyPendingFileChanges() async {
@@ -304,11 +365,22 @@
     // Should apply pending file changes before resolving.
     var response = await _getTestCodeSuggestions('Str^');
 
-    check(response).suggestions.includesAll([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('String')
-        ..isClass,
-    ]);
+    printerConfiguration.filter = (suggestion) {
+      if (suggestion.isClass) {
+        return const {'String'}.contains(suggestion.completion);
+      }
+      return false;
+    };
+
+    assertResponseText(response, r'''
+replacement
+  left: 3
+suggestions
+  String
+    kind: class
+    isNotImported: null
+    libraryUri: dart:core
+''');
   }
 
   Future<void> test_isNotImportedFeature_prefixed_classInstanceMethod() async {
@@ -336,21 +408,22 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
     // The fact that `b.dart` is imported, and `a.dart` is not, does not affect
     // the order of suggestions added with an expression prefix. We are not
     // going to import anything, so this does not matter.
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..libraryUriToImport.isNull,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_notImported_dart() async {
@@ -362,15 +435,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
+    printerConfiguration.filter = (suggestion) {
+      return suggestion.isClass;
+    };
 
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('Random')
-        ..libraryUriToImport.isEqualTo('dart:math'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  Random
+    kind: class
+    isNotImported: true
+    libraryUri: dart:math
+''');
   }
 
   Future<void> test_notImported_emptyBudget() async {
@@ -385,10 +462,13 @@
 }
 ''');
 
-    check(response)
-      ..assertIncomplete()
-      ..hasReplacement(left: 4)
-      ..suggestions.withElementClass.isEmpty;
+    printerConfiguration.filter = (_) => true;
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+''');
   }
 
   Future<void> test_notImported_lowerRelevance_extension_getter() async {
@@ -414,19 +494,20 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
     // `foo01` relevance is decreased because it is not yet imported.
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo02
+    kind: getter
+    isNotImported: null
+    libraryUri: null
+  foo01
+    kind: getter
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_notImported_lowerRelevance_extension_method() async {
@@ -452,19 +533,20 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
     // `foo01` relevance is decreased because it is not yet imported.
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo02
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+  foo01
+    kind: methodInvocation
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_notImported_lowerRelevance_extension_setter() async {
@@ -490,19 +572,20 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
     // `foo01` relevance is decreased because it is not yet imported.
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo02
+    kind: setter
+    isNotImported: null
+    libraryUri: null
+  foo01
+    kind: setter
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_notImported_lowerRelevance_topLevel_class() async {
@@ -524,19 +607,20 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
     // `A01` relevance is decreased because it is not yet imported.
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A02')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A02
+    kind: class
+    isNotImported: null
+    libraryUri: package:test/b.dart
+  A01
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_notImported_lowerRelevance_topLevel_getter() async {
@@ -558,19 +642,20 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
     // `foo01` relevance is decreased because it is not yet imported.
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo02
+    kind: getter
+    isNotImported: null
+    libraryUri: package:test/b.dart
+  foo01
+    kind: getter
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_notImported_lowerRelevance_topLevel_setter() async {
@@ -592,19 +677,20 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
     // `foo01` relevance is decreased because it is not yet imported.
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo02
+    kind: setter
+    isNotImported: null
+    libraryUri: package:test/b.dart
+  foo01
+    kind: setter
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_notImported_lowerRelevance_topLevel_variable() async {
@@ -626,19 +712,20 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
     // `foo01` relevance is decreased because it is not yet imported.
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo02
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: package:test/b.dart
+  foo01
+    kind: topLevelVariable
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_notImported_pub_dependencies_inLib() async {
@@ -680,15 +767,15 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..libraryUriToImport.isEqualTo('package:aaa/f.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+    isNotImported: true
+    libraryUri: package:aaa/f.dart
+''');
   }
 
   Future<void> test_notImported_pub_dependencies_inTest() async {
@@ -734,18 +821,19 @@
 ''',
     );
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..libraryUriToImport.isEqualTo('package:aaa/f.dart'),
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A03')
-        ..libraryUriToImport.isEqualTo('package:bbb/f.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+    isNotImported: true
+    libraryUri: package:aaa/f.dart
+  A03
+    kind: class
+    isNotImported: true
+    libraryUri: package:bbb/f.dart
+''');
   }
 
   Future<void> test_notImported_pub_this() async {
@@ -765,18 +853,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A02')
-        ..libraryUriToImport.isEqualTo('package:test/b.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/a.dart
+  A02
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/b.dart
+''');
   }
 
   Future<void> test_notImported_pub_this_hasImport() async {
@@ -799,21 +888,23 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A02')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A03')
-        ..libraryUriToImport.isEqualTo('package:test/b.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+    isNotImported: null
+    libraryUri: package:test/a.dart
+  A02
+    kind: class
+    isNotImported: null
+    libraryUri: package:test/a.dart
+  A03
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/b.dart
+''');
   }
 
   Future<void> test_notImported_pub_this_hasImport_hasShow() async {
@@ -836,25 +927,27 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
     // Note:
     // 1. A02 is the first, because it is already imported.
     // 2. A01 is still suggested, but with lower relevance.
     // 3. A03 has the same relevance (not tested), but sorted by name.
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A02')
-        ..libraryUriToImport.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A03')
-        ..libraryUriToImport.isEqualTo('package:test/b.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A02
+    kind: class
+    isNotImported: null
+    libraryUri: package:test/a.dart
+  A01
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/a.dart
+  A03
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/b.dart
+''');
   }
 
   Future<void> test_notImported_pub_this_inLib_excludesTest() async {
@@ -878,15 +971,15 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_notImported_pub_this_inLib_includesThisSrc() async {
@@ -910,18 +1003,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..libraryUriToImport.isEqualTo('package:test/f.dart'),
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A02')
-        ..libraryUriToImport.isEqualTo('package:test/src/f.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/f.dart
+  A02
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/src/f.dart
+''');
   }
 
   Future<void> test_notImported_pub_this_inTest_includesTest() async {
@@ -950,18 +1044,19 @@
 ''',
     );
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A02')
-        ..libraryUriToImport.isEqualTo(b_uriStr),
-    ]);
+    assertResponseText(response, '''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/a.dart
+  A02
+    kind: class
+    isNotImported: true
+    libraryUri: $b_uriStr
+''');
   }
 
   Future<void> test_notImported_pub_this_inTest_includesThisSrc() async {
@@ -989,18 +1084,19 @@
 ''',
     );
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..libraryUriToImport.isEqualTo('package:test/f.dart'),
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A02')
-        ..libraryUriToImport.isEqualTo('package:test/src/f.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/f.dart
+  A02
+    kind: class
+    isNotImported: true
+    libraryUri: package:test/src/f.dart
+''');
   }
 
   Future<void> test_numResults_class_methods() async {
@@ -1018,18 +1114,19 @@
 }
 ''', maxResults: 2);
 
-    check(response)
-      ..assertIncomplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isMethodInvocation,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isMethodInvocation,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_numResults_topLevelVariables() async {
@@ -1045,18 +1142,19 @@
 }
 ''', maxResults: 2);
 
-    check(response)
-      ..assertIncomplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isTopLevelVariable,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isTopLevelVariable,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_numResults_topLevelVariables_imported_withPrefix() async {
@@ -1076,18 +1174,17 @@
 }
 ''', maxResults: 2);
 
-    check(response)
-      ..assertIncomplete()
-      ..hasEmptyReplacement();
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isTopLevelVariable,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isTopLevelVariable,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  foo01
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: package:test/a.dart
+  foo02
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_prefixed_class_constructors() async {
@@ -1104,18 +1201,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isConstructorInvocation,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isConstructorInvocation,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: constructorInvocation
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: constructorInvocation
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_prefixed_class_getters() async {
@@ -1132,22 +1230,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isGetter
-        ..libraryUri.isNull
-        ..isNotImported.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isGetter
-        ..libraryUri.isNull
-        ..isNotImported.isNull,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: getter
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: getter
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_prefixed_class_methods_instance() async {
@@ -1164,18 +1259,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isMethodInvocation,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isMethodInvocation,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_prefixed_class_methods_static() async {
@@ -1192,18 +1288,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isMethodInvocation,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isMethodInvocation,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_prefixed_expression_extensionGetters() async {
@@ -1225,18 +1322,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isGetter,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isGetter,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: getter
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: getter
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_prefixed_expression_extensionGetters_notImported() async {
@@ -1263,20 +1361,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isGetter
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isGetter
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: getter
+    isNotImported: true
+    libraryUri: package:test/a.dart
+  foo02
+    kind: getter
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void>
@@ -1303,16 +1400,15 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isGetter
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: getter
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_prefixed_expression_extensionMethods() async {
@@ -1334,18 +1430,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isMethodInvocation,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isMethodInvocation,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_prefixed_expression_extensionMethods_notImported() async {
@@ -1372,20 +1469,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isMethodInvocation
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isMethodInvocation
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: methodInvocation
+    isNotImported: true
+    libraryUri: package:test/a.dart
+  foo02
+    kind: methodInvocation
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_prefixed_expression_extensionSetters() async {
@@ -1407,18 +1503,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isSetter,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isSetter,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: setter
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: setter
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_prefixed_expression_extensionSetters_notImported() async {
@@ -1445,20 +1542,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isSetter
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isSetter
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: setter
+    isNotImported: true
+    libraryUri: package:test/a.dart
+  foo02
+    kind: setter
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void>
@@ -1485,16 +1581,15 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isSetter
-        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: setter
+    isNotImported: true
+    libraryUri: package:test/a.dart
+''');
   }
 
   Future<void> test_prefixed_extensionGetters_imported() async {
@@ -1520,18 +1615,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isGetter,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isGetter,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: getter
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: getter
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_prefixed_extensionOverride_extensionGetters() async {
@@ -1551,15 +1647,15 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isGetter,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: getter
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_prefixed_extensionOverride_extensionMethods() async {
@@ -1579,15 +1675,15 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isMethodInvocation,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: methodInvocation
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_prefixed_importPrefix_class() async {
@@ -1601,16 +1697,17 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
+    printerConfiguration.filter = (_) => true;
 
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('Random')
-        ..libraryUri.isEqualTo('dart:math')
-        ..isNotImported.isNull,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  Random
+    kind: class
+    isNotImported: null
+    libraryUri: dart:math
+''');
   }
 
   Future<void> test_unprefixed_filters() async {
@@ -1627,18 +1724,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isTopLevelVariable,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isTopLevelVariable,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: null
+  foo02
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: null
+''');
   }
 
   Future<void> test_unprefixed_imported_class() async {
@@ -1661,22 +1759,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 2);
-
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
-        ..isClass
-        ..libraryUri.isEqualTo('package:test/a.dart')
-        ..isNotImported.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('A02')
-        ..isClass
-        ..libraryUri.isEqualTo('package:test/b.dart')
-        ..isNotImported.isNull,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+    isNotImported: null
+    libraryUri: package:test/a.dart
+  A02
+    kind: class
+    isNotImported: null
+    libraryUri: package:test/b.dart
+''');
   }
 
   Future<void> test_unprefixed_imported_topLevelVariable() async {
@@ -1699,22 +1794,19 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
-
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isTopLevelVariable
-        ..libraryUri.isEqualTo('package:test/a.dart')
-        ..isNotImported.isNull,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isTopLevelVariable
-        ..libraryUri.isEqualTo('package:test/b.dart')
-        ..isNotImported.isNull,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: package:test/a.dart
+  foo02
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: package:test/b.dart
+''');
   }
 
   Future<void> test_unprefixed_imported_withPrefix_class() async {
@@ -1728,17 +1820,20 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
+    printerConfiguration.filter = (suggestion) {
+      return suggestion.isClass;
+    };
 
     // No suggestion without the `math` prefix.
-    check(response).suggestions.withElementClass.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('math.Random')
-        ..libraryUri.isEqualTo('dart:math')
-        ..isNotImported.isNull,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  math.Random
+    kind: class
+    isNotImported: null
+    libraryUri: dart:math
+''');
   }
 
   Future<void> test_unprefixed_sorts_byScore() async {
@@ -1753,19 +1848,29 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
+    printerConfiguration
+      ..filter = (suggestion) {
+        return suggestion.completion.startsWith('foo');
+      }
+      ..sorting = printer.Sorting.asIs
+      ..withRelevance = true;
 
     // `fooBB` has better score than `fooAB` - prefix match
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('fooBB')
-        ..isTopLevelVariable,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('fooAB')
-        ..isTopLevelVariable,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  fooBB
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: null
+    relevance: 504
+  fooAB
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: null
+    relevance: 504
+''');
   }
 
   Future<void> test_unprefixed_sorts_byType() async {
@@ -1780,19 +1885,25 @@
 }
 ''');
 
-    check(response)
-      ..assertComplete()
-      ..hasReplacement(left: 4);
+    printerConfiguration
+      ..sorting = printer.Sorting.asIs
+      ..withRelevance = true;
 
-    // `foo02` has better relevance, its type matches the context type
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isTopLevelVariable,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isTopLevelVariable,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo02
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: null
+    relevance: 565
+  foo01
+    kind: topLevelVariable
+    isNotImported: null
+    libraryUri: null
+    relevance: 511
+''');
   }
 
   Future<void> test_yaml_analysisOptions_root() async {
@@ -1804,24 +1915,22 @@
       content: '^',
     );
 
-    check(response)
-      ..assertComplete()
-      ..hasEmptyReplacement();
+    printerConfiguration
+      ..filter = ((_) => true)
+      ..withIsNotImported = false
+      ..withLibraryUri = false;
 
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('analyzer: ')
-        ..kind.isIdentifier,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('code-style: ')
-        ..kind.isIdentifier,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('include: ')
-        ..kind.isIdentifier,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('linter: ')
-        ..kind.isIdentifier,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  |analyzer: |
+    kind: identifier
+  |code-style: |
+    kind: identifier
+  |include: |
+    kind: identifier
+  |linter: |
+    kind: identifier
+''');
   }
 
   Future<void> test_yaml_fixData_root() async {
@@ -1833,18 +1942,18 @@
       content: '^',
     );
 
-    check(response)
-      ..assertComplete()
-      ..hasEmptyReplacement();
+    printerConfiguration
+      ..filter = ((_) => true)
+      ..withIsNotImported = false
+      ..withLibraryUri = false;
 
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('version: ')
-        ..kind.isIdentifier,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('transforms:')
-        ..kind.isIdentifier,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  transforms:
+    kind: identifier
+  |version: |
+    kind: identifier
+''');
   }
 
   Future<void> test_yaml_pubspec_root() async {
@@ -1856,21 +1965,42 @@
       content: '^',
     );
 
-    check(response)
-      ..assertComplete()
-      ..hasEmptyReplacement();
+    printerConfiguration
+      ..filter = ((_) => true)
+      ..withIsNotImported = false
+      ..withLibraryUri = false;
 
-    check(response).suggestions.includesAll([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('name: ')
-        ..kind.isIdentifier,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('dependencies: ')
-        ..kind.isIdentifier,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('dev_dependencies: ')
-        ..kind.isIdentifier,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  |dependencies: |
+    kind: identifier
+  |dependency_overrides: |
+    kind: identifier
+  |description: |
+    kind: identifier
+  |dev_dependencies: |
+    kind: identifier
+  |documentation: |
+    kind: identifier
+  |environment: |
+    kind: identifier
+  |executables: |
+    kind: identifier
+  |flutter: |
+    kind: identifier
+  |homepage: |
+    kind: identifier
+  |issue_tracker: |
+    kind: identifier
+  |name: |
+    kind: identifier
+  |publish_to: |
+    kind: identifier
+  |repository: |
+    kind: identifier
+  |version: |
+    kind: identifier
+''');
   }
 
   Future<void> _configureWithWorkspaceRoot() async {
@@ -2828,20 +2958,73 @@
   }
 }
 
-extension on CheckTarget<CompletionGetSuggestionDetails2Result> {
-  @useResult
-  CheckTarget<SourceChange> get change {
-    return nest(
-      value.change,
-      (selected) => 'has change ${valueStr(selected)}',
-    );
+class _SuggestionDetailsPrinter {
+  final StringBuffer buffer;
+  final CompletionGetSuggestionDetails2Result result;
+  final ResourceProvider resourceProvider;
+  final Map<File, String> fileDisplayMap;
+
+  String _indent = '';
+
+  _SuggestionDetailsPrinter({
+    required this.buffer,
+    required this.result,
+    required this.resourceProvider,
+    required this.fileDisplayMap,
+  });
+
+  void writeResult() {
+    _writelnWithIndent('completion: ${result.completion}');
+    _withIndent(() {
+      _writeChange(result.change);
+    });
   }
 
-  @useResult
-  CheckTarget<String> get completion {
-    return nest(
-      value.completion,
-      (selected) => 'has completion ${valueStr(selected)}',
-    );
+  void _withIndent(void Function() f) {
+    var indent = _indent;
+    _indent = '$_indent  ';
+    f();
+    _indent = indent;
+  }
+
+  void _writeChange(SourceChange change) {
+    _writelnWithIndent('change');
+    _withIndent(() {
+      for (final fileEdit in change.edits) {
+        _writeSourceFileEdit(fileEdit);
+      }
+    });
+  }
+
+  void _writelnWithIndent(String line) {
+    buffer.write(_indent);
+    buffer.writeln(line);
+  }
+
+  void _writeSourceEdit(SourceEdit edit) {
+    _writelnWithIndent('offset: ${edit.offset}');
+    _writelnWithIndent('length: ${edit.length}');
+
+    final replacementStr = edit.replacement.replaceAll('\n', r'\n');
+    _writelnWithIndent('replacement: $replacementStr');
+  }
+
+  void _writeSourceFileEdit(SourceFileEdit fileEdit) {
+    final file = resourceProvider.getFile(fileEdit.file);
+    final fileStr = fileDisplayMap[file] ?? fail('No display name: $file');
+    _writelnWithIndent(fileStr);
+
+    _withIndent(() {
+      for (final edit in fileEdit.edits) {
+        _writeSourceEdit(edit);
+      }
+    });
+  }
+}
+
+extension on CompletionSuggestion {
+  bool get isClass {
+    return kind == CompletionSuggestionKind.IDENTIFIER &&
+        element?.kind == ElementKind.CLASS;
   }
 }
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index f080f50..c759aa8 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -1745,6 +1745,27 @@
 ''');
   }
 
+  Future<void> test_classMember_field_onFieldFormalParameter_named_private() {
+    addTestFile('''
+class A {
+  final int test;
+  A({this.test = 0});
+}
+void f() {
+  A(test: 42);
+}
+''');
+
+    return getRefactoringResult(() {
+      return sendRenameRequest('test: 42', '_new');
+    }).then((result) {
+      var problems = result.finalProblems;
+      expect(problems, hasLength(1));
+      assertResultProblemsError(
+          problems, "The parameter 'test' is named and can not be private.");
+    });
+  }
+
   Future<void> test_classMember_getter() {
     addTestFile('''
 class A {
@@ -2187,6 +2208,27 @@
     });
   }
 
+  Future<void> test_parameter_onDefaultParameter() {
+    addTestFile('''
+class A {
+  final int test;
+  A({int t = 0}) : test = t;
+}
+void f() {
+  A(t: 42);
+}
+''');
+
+    return getRefactoringResult(() {
+      return sendRenameRequest('t: 42', '_new');
+    }).then((result) {
+      var problems = result.finalProblems;
+      expect(problems, hasLength(1));
+      assertResultProblemsError(
+          problems, "The parameter 't' is named and can not be private.");
+    });
+  }
+
   Future<void> test_reset_afterCreateChange() {
     test_simulateRefactoringReset_afterCreateChange = true;
     addTestFile('''
diff --git a/pkg/analysis_server/test/integration/linter/lint_names_test.dart b/pkg/analysis_server/test/integration/linter/lint_names_test.dart
index 2372824..ed2c416 100644
--- a/pkg/analysis_server/test/integration/linter/lint_names_test.dart
+++ b/pkg/analysis_server/test/integration/linter/lint_names_test.dart
@@ -33,7 +33,7 @@
     }
 
     var lintNamesClass = parseResult.unit.declarations.firstWhere(
-        (m) => m is ClassDeclaration && m.name2.lexeme == 'LintNames');
+        (m) => m is ClassDeclaration && m.name.lexeme == 'LintNames');
 
     var collector = _FixCollector();
     lintNamesClass.accept(collector);
@@ -65,7 +65,7 @@
   @override
   void visitFieldDeclaration(FieldDeclaration node) {
     for (var v in node.fields.variables) {
-      lintNames.add(v.name2.lexeme);
+      lintNames.add(v.name.lexeme);
     }
   }
 }
diff --git a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
index bc5ee9a4..c36a326 100644
--- a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
@@ -40,7 +40,7 @@
     expect(relatedInformation, hasLength(1));
     final relatedInfo = relatedInformation.first;
     expect(relatedInfo.message, equals("The declaration of 'x' is here."));
-    expect(relatedInfo.location.uri, equals('$mainFileUri'));
+    expect(relatedInfo.location.uri, equals(mainFileUri));
     expect(relatedInfo.location.range, equals(rangeFromMarkers(content)));
   }
 
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 7794e0f..250ed36 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1086,7 +1086,7 @@
   ///
   ///   A list of objects each containing a path and the additional libraries
   ///   from which the client is interested in receiving completion
-  ///   suggestions. If one configured path is beneath another, the descendent
+  ///   suggestions. If one configured path is beneath another, the descendant
   ///   will override the ancestors' configured libraries of interest.
   @deprecated
   Future sendCompletionRegisterLibraryPaths(List<LibraryPathSet> paths) async {
diff --git a/pkg/analysis_server/test/lsp/call_hierarchy_test.dart b/pkg/analysis_server/test/lsp/call_hierarchy_test.dart
index 9e90f33..2773b4f 100644
--- a/pkg/analysis_server/test/lsp/call_hierarchy_test.dart
+++ b/pkg/analysis_server/test/lsp/call_hierarchy_test.dart
@@ -76,7 +76,7 @@
             name: 'Bar',
             detail: 'other.dart',
             kind: SymbolKind.Class,
-            uri: otherFileUri.toString(),
+            uri: otherFileUri,
             range: rangeOfPattern(
                 otherContents, RegExp(r'class Bar \{.*\}', dotAll: true)),
             selectionRange: rangeOfString(otherContents, 'Bar'),
@@ -111,7 +111,7 @@
             name: 'other.dart',
             detail: null,
             kind: SymbolKind.File,
-            uri: otherFileUri.toString(),
+            uri: otherFileUri,
             range: entireRange(otherContents),
             selectionRange: startOfDocRange,
           ),
@@ -147,7 +147,7 @@
             name: 'main',
             detail: 'main.dart',
             kind: SymbolKind.Function,
-            uri: mainFileUri.toString(),
+            uri: mainFileUri,
             range: rangeOfPattern(
                 contents, RegExp(r'void main\(\) \{.*\}', dotAll: true)),
             selectionRange: rangeOfString(contents, 'main'),
@@ -188,7 +188,7 @@
             name: 'bar',
             detail: 'B',
             kind: SymbolKind.Method,
-            uri: otherFileUri.toString(),
+            uri: otherFileUri,
             range: rangeOfPattern(otherContents,
                 RegExp(r'String bar\(\) \{.*\      }', dotAll: true)),
             selectionRange: rangeOfString(otherContents, 'bar'),
@@ -227,7 +227,7 @@
             name: 'Bar',
             detail: 'other.dart',
             kind: SymbolKind.Class,
-            uri: otherFileUri.toString(),
+            uri: otherFileUri,
             range: rangeOfPattern(
                 otherContents, RegExp(r'class Bar \{.*\}', dotAll: true)),
             selectionRange: rangeOfString(otherContents, 'Bar'),
@@ -304,7 +304,7 @@
             name: 'Bar',
             detail: 'Bar',
             kind: SymbolKind.Constructor,
-            uri: otherFileUri.toString(),
+            uri: otherFileUri,
             range: rangeOfString(otherContents, 'Bar();'),
             selectionRange:
                 rangeStartingAtString(otherContents, 'Bar();', 'Bar'),
@@ -341,7 +341,7 @@
             name: 'bar',
             detail: 'other.dart',
             kind: SymbolKind.Function,
-            uri: otherFileUri.toString(),
+            uri: otherFileUri,
             range: rangeOfString(otherContents, 'void bar() {}'),
             selectionRange: rangeOfString(otherContents, 'bar'),
           ),
@@ -379,7 +379,7 @@
             name: 'Bar',
             detail: 'Bar',
             kind: SymbolKind.Constructor,
-            uri: otherFileUri.toString(),
+            uri: otherFileUri,
             range: rangeOfString(otherContents, 'class Bar {}'),
             selectionRange: rangeOfString(otherContents, 'Bar'),
           ),
@@ -420,7 +420,7 @@
             name: 'bar',
             detail: 'Bar',
             kind: SymbolKind.Method,
-            uri: otherFileUri.toString(),
+            uri: otherFileUri,
             range: rangeOfString(otherContents, 'void bar() {}'),
             selectionRange: rangeOfString(otherContents, 'bar'),
           ),
@@ -460,7 +460,7 @@
             name: 'Bar.named',
             detail: 'Bar',
             kind: SymbolKind.Constructor,
-            uri: otherFileUri.toString(),
+            uri: otherFileUri,
             range: rangeOfString(otherContents, 'Bar.named();'),
             selectionRange: rangeOfString(otherContents, 'named'),
           ),
@@ -545,7 +545,7 @@
           name: 'Foo',
           detail: 'Foo', // Containing class name
           kind: SymbolKind.Constructor,
-          uri: mainFileUri.toString(),
+          uri: mainFileUri,
           range: rangeOfString(contents, 'Foo(String a) {}'),
           selectionRange: rangeFromMarkers(contents)),
     );
@@ -573,7 +573,7 @@
             name: 'Foo',
             detail: 'Foo', // Containing class name
             kind: SymbolKind.Constructor,
-            uri: otherFileUri.toString(),
+            uri: otherFileUri,
             range: rangeOfString(otherContents, 'Foo();'),
             selectionRange: rangeFromMarkers(otherContents)));
   }
@@ -589,7 +589,7 @@
           name: 'myFunction',
           detail: 'main.dart', // Containing file name
           kind: SymbolKind.Function,
-          uri: mainFileUri.toString(),
+          uri: mainFileUri,
           range: rangeOfString(contents, 'void myFunction() {}'),
           selectionRange: rangeOfString(contents, 'myFunction')),
     );
@@ -615,7 +615,7 @@
           name: 'myFunction',
           detail: 'other.dart', // Containing file name
           kind: SymbolKind.Function,
-          uri: otherFileUri.toString(),
+          uri: otherFileUri,
           range: rangeOfString(otherContents, 'void myFunction() {}'),
           selectionRange: rangeOfString(otherContents, 'myFunction')),
     );
@@ -644,7 +644,7 @@
           name: 'Foo',
           detail: 'Foo', // Containing class name
           kind: SymbolKind.Constructor,
-          uri: otherFileUri.toString(),
+          uri: otherFileUri,
           range: rangeOfString(otherContents, 'class Foo {}'),
           selectionRange: rangeOfString(otherContents, 'Foo')),
     );
@@ -663,7 +663,7 @@
           name: 'myMethod',
           detail: 'Foo', // Containing class name
           kind: SymbolKind.Method,
-          uri: mainFileUri.toString(),
+          uri: mainFileUri,
           range: rangeOfString(contents, 'void myMethod() {}'),
           selectionRange: rangeOfString(contents, 'myMethod')),
     );
@@ -691,7 +691,7 @@
           name: 'myMethod',
           detail: 'Foo', // Containing class name
           kind: SymbolKind.Method,
-          uri: otherFileUri.toString(),
+          uri: otherFileUri,
           range: rangeOfString(otherContents, 'void myMethod() {}'),
           selectionRange: rangeOfString(otherContents, 'myMethod')),
     );
@@ -710,7 +710,7 @@
           name: 'Foo.Bar',
           detail: 'Foo', // Containing class name
           kind: SymbolKind.Constructor,
-          uri: mainFileUri.toString(),
+          uri: mainFileUri,
           range: rangeOfString(contents, 'Foo.Bar(String a) {}'),
           selectionRange: rangeOfString(contents, 'Bar')),
     );
@@ -738,7 +738,7 @@
           name: 'Foo.Bar',
           detail: 'Foo', // Containing class name
           kind: SymbolKind.Constructor,
-          uri: otherFileUri.toString(),
+          uri: otherFileUri,
           range: rangeOfString(otherContents, 'Foo.Bar();'),
           selectionRange: rangeOfString(otherContents, 'Bar')),
     );
diff --git a/pkg/analysis_server/test/lsp/cancel_request_test.dart b/pkg/analysis_server/test/lsp/cancel_request_test.dart
index 0101b06..3a4d999 100644
--- a/pkg/analysis_server/test/lsp/cancel_request_test.dart
+++ b/pkg/analysis_server/test/lsp/cancel_request_test.dart
@@ -33,7 +33,7 @@
     final completionRequest = makeRequest(
       Method.textDocument_completion,
       CompletionParams(
-        textDocument: TextDocumentIdentifier(uri: mainFileUri.toString()),
+        textDocument: TextDocumentIdentifier(uri: mainFileUri),
         position: positionFromMarker(content),
       ),
     );
diff --git a/pkg/analysis_server/test/lsp/code_actions_abstract.dart b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
index c4d4e68..436f3ac 100644
--- a/pkg/analysis_server/test/lsp/code_actions_abstract.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
@@ -19,7 +19,7 @@
     bool asCommand = false,
   }) async {
     final codeActions =
-        await getCodeActions(uri.toString(), range: range, position: position);
+        await getCodeActions(uri, range: range, position: position);
     final codeAction = findCommand(codeActions, command)!;
 
     codeAction.map(
@@ -51,6 +51,52 @@
     );
   }
 
+  /// Executes [command] which is expected to call back to the client to apply
+  /// a [WorkspaceEdit].
+  ///
+  /// Changes are applied to [contents] to be verified by the caller.
+  Future<void> executeCommandForEdits(
+    Command command,
+    // TODO(dantup): Change this map to use Uris for files.
+    Map<String, String> contents, {
+    bool expectDocumentChanges = false,
+    ProgressToken? workDoneToken,
+  }) async {
+    ApplyWorkspaceEditParams? editParams;
+
+    final commandResponse = await handleExpectedRequest<Object?,
+        ApplyWorkspaceEditParams, ApplyWorkspaceEditResult>(
+      Method.workspace_applyEdit,
+      ApplyWorkspaceEditParams.fromJson,
+      () => executeCommand(command, workDoneToken: workDoneToken),
+      handler: (edit) {
+        // When the server sends the edit back, just keep a copy and say we
+        // applied successfully (it'll be verified by the caller).
+        editParams = edit;
+        return ApplyWorkspaceEditResult(applied: true);
+      },
+    );
+    // Successful edits return an empty success() response.
+    expect(commandResponse, isNull);
+
+    // Ensure the edit came back, and using the expected change type.
+    expect(editParams, isNotNull);
+    final edit = editParams!.edit;
+    if (expectDocumentChanges) {
+      expect(edit.changes, isNull);
+      expect(edit.documentChanges, isNotNull);
+    } else {
+      expect(edit.changes, isNotNull);
+      expect(edit.documentChanges, isNull);
+    }
+
+    if (expectDocumentChanges) {
+      applyDocumentChanges(contents, edit.documentChanges!);
+    } else {
+      applyChanges(contents, edit.changes!);
+    }
+  }
+
   Either2<Command, CodeAction>? findCommand(
       List<Either2<Command, CodeAction>> actions, String commandID,
       [String? wantedTitle]) {
@@ -87,7 +133,7 @@
   }
 
   /// Verifies that executing the given code actions command on the server
-  /// results in an edit being sent in the client that updates the file to match
+  /// results in an edit being sent to the client that updates the file to match
   /// the expected content.
   Future verifyCodeActionEdits(Either2<Command, CodeAction> codeAction,
       String content, String expectedContent,
@@ -104,50 +150,26 @@
   }
 
   /// Verifies that executing the given command on the server results in an edit
-  /// being sent in the client that updates the file to match the expected
+  /// being sent in the client that updates the main file to match the expected
   /// content.
   Future<void> verifyCommandEdits(
-      Command command, String content, String expectedContent,
-      {bool expectDocumentChanges = false,
-      ProgressToken? workDoneToken}) async {
-    ApplyWorkspaceEditParams? editParams;
-
-    final commandResponse = await handleExpectedRequest<Object?,
-        ApplyWorkspaceEditParams, ApplyWorkspaceEditResult>(
-      Method.workspace_applyEdit,
-      ApplyWorkspaceEditParams.fromJson,
-      () => executeCommand(command, workDoneToken: workDoneToken),
-      handler: (edit) {
-        // When the server sends the edit back, just keep a copy and say we
-        // applied successfully (it'll be verified below).
-        editParams = edit;
-        return ApplyWorkspaceEditResult(applied: true);
-      },
-    );
-    // Successful edits return an empty success() response.
-    expect(commandResponse, isNull);
-
-    // Ensure the edit came back, and using the expected changes.
-    expect(editParams, isNotNull);
-    final edit = editParams!.edit;
-    if (expectDocumentChanges) {
-      expect(edit.changes, isNull);
-      expect(edit.documentChanges, isNotNull);
-    } else {
-      expect(edit.changes, isNotNull);
-      expect(edit.documentChanges, isNull);
-    }
-
-    // Ensure applying the changes will give us the expected content.
+    Command command,
+    String content,
+    String expectedContent, {
+    bool expectDocumentChanges = false,
+    ProgressToken? workDoneToken,
+  }) async {
     final contents = {
       mainFilePath: withoutMarkers(content),
     };
 
-    if (expectDocumentChanges) {
-      applyDocumentChanges(contents, edit.documentChanges!);
-    } else {
-      applyChanges(contents, edit.changes!);
-    }
+    await executeCommandForEdits(
+      command,
+      contents,
+      expectDocumentChanges: expectDocumentChanges,
+      workDoneToken: workDoneToken,
+    );
+
     expect(contents[mainFilePath], equals(expectedContent));
   }
 }
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 7dda476..11d37be 100644
--- a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
@@ -51,8 +51,8 @@
           withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final assist = findEditAction(
         codeActions,
         CodeActionKind('refactor.add.showCombinator'),
@@ -90,8 +90,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final assistAction = findEditAction(
         codeActions,
         CodeActionKind('refactor.add.showCombinator'),
@@ -128,7 +128,7 @@
       _RawParams('''
       {
         "textDocument": {
-          "uri": "${mainFileUri.toString()}"
+          "uri": "$mainFileUri"
         },
         "context": {
           "diagnostics": []
@@ -186,7 +186,7 @@
       },
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final assist = findEditAction(codeActions,
         CodeActionKind('refactor.flutter.wrap.center'), 'Wrap with Center')!;
@@ -207,7 +207,7 @@
     );
 
     final codeActions =
-        await getCodeActions(pubspecFileUri.toString(), range: startOfDocRange);
+        await getCodeActions(pubspecFileUri, range: startOfDocRange);
     expect(codeActions, isEmpty);
   }
 
@@ -240,8 +240,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final assist = findEditAction(codeActions,
         CodeActionKind('refactor.fooToBar'), "Change 'foo' to 'bar'")!;
 
@@ -277,8 +277,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeActionTitles = codeActions.map((action) =>
         action.map((command) => command.title, (action) => action.title));
 
@@ -339,7 +339,7 @@
       },
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final assist = findEditAction(
         codeActions,
@@ -411,7 +411,7 @@
       },
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final assist = findEditAction(
         codeActions,
@@ -472,7 +472,7 @@
           withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final assist = findEditAction(
         codeActions,
@@ -514,7 +514,7 @@
           withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final names = codeActions.map(
       (e) => e.map((command) => command.title, (action) => action.title),
@@ -558,8 +558,8 @@
       },
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final assist = findEditAction(codeActions,
         CodeActionKind('refactor.surround.if'), "Surround with 'if'")!;
 
diff --git a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
index 3145f67..195f4c6 100644
--- a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
@@ -42,8 +42,8 @@
           withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final fixAction = findEditAction(
         codeActions,
         CodeActionKind('quickfix.remove.unusedImport'),
@@ -82,8 +82,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final fixAction = findEditAction(
         codeActions,
         CodeActionKind('quickfix.remove.unusedImport'),
@@ -118,8 +118,8 @@
           emptyWorkspaceClientCapabilities, [ResourceOperationKind.Create]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final fixAction = findEditAction(codeActions,
         CodeActionKind('quickfix.create.file'), "Create file 'newfile.dart'")!;
 
@@ -145,7 +145,7 @@
     await initialize();
 
     ofKind(CodeActionKind kind) => getCodeActions(
-          mainFileUri.toString(),
+          mainFileUri,
           range: rangeFromMarkers(content),
           kinds: [kind],
         );
@@ -172,8 +172,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
     );
 
-    final allFixes = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final allFixes =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
 
     // Expect only the single-fix, there should be no apply-all.
     expect(allFixes, hasLength(1));
@@ -194,8 +194,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final fixAction = findEditAction(
         codeActions, CodeActionKind('quickfix'), "Remove '!'s in file");
 
@@ -223,8 +223,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final fixAction = findEditAction(
         codeActions, CodeActionKind('quickfix'), "Remove '!'s in file")!;
 
@@ -267,8 +267,8 @@
     );
 
     // Find the ignore action.
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final fixAction = findEditAction(
         codeActions,
         CodeActionKind('quickfix.ignore.file'),
@@ -302,8 +302,8 @@
     );
 
     // Find the ignore action.
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final fixAction = findEditAction(
         codeActions,
         CodeActionKind('quickfix.ignore.line'),
@@ -336,7 +336,7 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final removeNnaAction = findEditActions(codeActions,
         CodeActionKind('quickfix.remove.nonNullAssertion'), "Remove the '!'");
@@ -364,8 +364,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final createClassActions = findEditActions(codeActions,
         CodeActionKind('quickfix.create.class'), "Create class 'Test'");
 
@@ -385,8 +385,8 @@
         workspaceCapabilities: withApplyEditSupport(
             withDocumentChangesSupport(emptyWorkspaceClientCapabilities)));
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final createClassActions = findEditActions(codeActions,
         CodeActionKind('quickfix.create.class'), "Create class 'Test'");
 
@@ -402,7 +402,7 @@
     );
 
     final codeActions =
-        await getCodeActions(pubspecFileUri.toString(), range: startOfDocRange);
+        await getCodeActions(pubspecFileUri, range: startOfDocRange);
     expect(codeActions, isEmpty);
   }
 
@@ -436,8 +436,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final fixAction = findEditAction(codeActions,
         CodeActionKind('quickfix.organize.imports'), 'Organize Imports')!;
 
@@ -464,7 +464,7 @@
     );
 
     final codeActions = await getCodeActions(
-      otherFileUri.toString(),
+      otherFileUri,
       position: startOfDocPos,
     );
     expect(codeActions, isEmpty);
@@ -510,8 +510,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final assist = findEditAction(codeActions,
         CodeActionKind('quickfix.fooToBar'), "Change 'foo' to 'bar'")!;
 
@@ -560,8 +560,8 @@
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeActionTitles = codeActions.map((action) =>
         action.map((command) => command.title, (action) => action.title));
 
@@ -603,7 +603,7 @@
       },
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final fixAction = findEditAction(codeActions,
         CodeActionKind('quickfix.create.method'), "Create method 'c'")!;
@@ -651,7 +651,7 @@
       },
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final fixAction = findEditAction(
         codeActions,
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index e334a60..57f3d67 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -49,7 +49,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, refactorTitle)!;
@@ -66,7 +66,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, refactorTitle);
@@ -88,7 +88,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, refactorTitle);
@@ -114,7 +114,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, refactorTitle)!;
@@ -182,8 +182,8 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;
 
@@ -211,8 +211,8 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;
 
@@ -255,8 +255,8 @@
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;
 
@@ -286,7 +286,7 @@
     );
 
     ofKind(CodeActionKind kind) => getCodeActions(
-          mainFileUri.toString(),
+          mainFileUri,
           range: rangeFromMarkers(content),
           kinds: [kind],
         );
@@ -340,8 +340,8 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;
 
@@ -358,7 +358,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle);
@@ -374,7 +374,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle);
@@ -407,8 +407,8 @@
     // token was supplied by us (the client).
     expect(progressUpdates, emitsInOrder(['BEGIN', 'END']));
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;
 
@@ -442,8 +442,8 @@
         .where((n) => n.method == Method.progress)
         .listen((_) => didGetProgressNotifications = true);
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;
 
@@ -475,8 +475,8 @@
         windowCapabilities:
             withWorkDoneProgressSupport(emptyWindowClientCapabilities));
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;
 
@@ -501,8 +501,8 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;
 
@@ -545,8 +545,8 @@
       failTestOnAnyErrorNotification: false,
     );
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;
 
@@ -584,8 +584,8 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;
 
@@ -612,7 +612,9 @@
 
 @reflectiveTest
 class ExtractVariableRefactorCodeActionsTest extends AbstractCodeActionsTest {
+  final convertMethodToGetterTitle = 'Convert Method to Getter';
   final extractVariableTitle = 'Extract Local Variable';
+  final inlineMethodTitle = 'Inline Method';
 
   Future<void> test_appliesCorrectEdits() async {
     const content = '''
@@ -633,8 +635,8 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction = findCommand(
         codeActions, Commands.performRefactor, extractVariableTitle)!;
 
@@ -663,14 +665,218 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction = findCommand(
         codeActions, Commands.performRefactor, extractVariableTitle)!;
 
     await verifyCodeActionEdits(
         codeAction, withoutMarkers(content), expectedContent);
   }
+
+  Future<void> test_inlineMethod_function_startOfParameterList() async {
+    const content = '''
+test[[]](a, b) {
+  print(a);
+  print(b);
+}
+void f() {
+  test(1, 2);
+}
+    ''';
+    const expectedContent = '''
+void f() {
+  print(1);
+  print(2);
+}
+    ''';
+    newFile(mainFilePath, withoutMarkers(content));
+    await initialize();
+
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
+    final codeAction =
+        findCommand(codeActions, Commands.performRefactor, inlineMethodTitle)!;
+
+    await verifyCodeActionEdits(
+        codeAction, withoutMarkers(content), expectedContent);
+  }
+
+  Future<void> test_inlineMethod_function_startOfTypeParameterList() async {
+    const content = '''
+test[[]]<T>(T a, T b) {
+  print(a);
+  print(b);
+}
+void f() {
+  test(1, 2);
+}
+    ''';
+    const expectedContent = '''
+void f() {
+  print(1);
+  print(2);
+}
+    ''';
+    newFile(mainFilePath, withoutMarkers(content));
+    await initialize();
+
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
+    final codeAction =
+        findCommand(codeActions, Commands.performRefactor, inlineMethodTitle)!;
+
+    await verifyCodeActionEdits(
+        codeAction, withoutMarkers(content), expectedContent);
+  }
+
+  Future<void> test_inlineMethod_method_startOfParameterList() async {
+    const content = '''
+class A {
+  test[[]](a, b) {
+    print(a);
+    print(b);
+  }
+  void f() {
+    test(1, 2);
+  }
+}
+    ''';
+    const expectedContent = '''
+class A {
+  void f() {
+    print(1);
+    print(2);
+  }
+}
+    ''';
+    newFile(mainFilePath, withoutMarkers(content));
+    await initialize();
+
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
+    final codeAction =
+        findCommand(codeActions, Commands.performRefactor, inlineMethodTitle)!;
+
+    await verifyCodeActionEdits(
+        codeAction, withoutMarkers(content), expectedContent);
+  }
+
+  Future<void> test_inlineMethod_method_startOfTypeParameterList() async {
+    const content = '''
+class A {
+  test[[]]<T>(T a, T b) {
+    print(a);
+    print(b);
+  }
+  void f() {
+    test(1, 2);
+  }
+}
+    ''';
+    const expectedContent = '''
+class A {
+  void f() {
+    print(1);
+    print(2);
+  }
+}
+    ''';
+    newFile(mainFilePath, withoutMarkers(content));
+    await initialize();
+
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
+    final codeAction =
+        findCommand(codeActions, Commands.performRefactor, inlineMethodTitle)!;
+
+    await verifyCodeActionEdits(
+        codeAction, withoutMarkers(content), expectedContent);
+  }
+
+  Future<void> test_methodToGetter_function_startOfParameterList() async {
+    const content = '''
+int test[[]]() => 42;
+    ''';
+    const expectedContent = '''
+int get test => 42;
+    ''';
+    newFile(mainFilePath, withoutMarkers(content));
+    await initialize();
+
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
+    final codeAction = findCommand(
+        codeActions, Commands.performRefactor, convertMethodToGetterTitle)!;
+
+    await verifyCodeActionEdits(
+        codeAction, withoutMarkers(content), expectedContent);
+  }
+
+  Future<void> test_methodToGetter_function_startOfTypeParameterList() async {
+    const content = '''
+int test[[]]<T>() => 42;
+    ''';
+    const expectedContent = '''
+int get test<T> => 42;
+    ''';
+    newFile(mainFilePath, withoutMarkers(content));
+    await initialize();
+
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
+    final codeAction = findCommand(
+        codeActions, Commands.performRefactor, convertMethodToGetterTitle)!;
+
+    await verifyCodeActionEdits(
+        codeAction, withoutMarkers(content), expectedContent);
+  }
+
+  Future<void> test_methodToGetter_method_startOfParameterList() async {
+    const content = '''
+class A {
+  int test[[]]() => 42;
+}
+    ''';
+    const expectedContent = '''
+class A {
+  int get test => 42;
+}
+    ''';
+    newFile(mainFilePath, withoutMarkers(content));
+    await initialize();
+
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
+    final codeAction = findCommand(
+        codeActions, Commands.performRefactor, convertMethodToGetterTitle)!;
+
+    await verifyCodeActionEdits(
+        codeAction, withoutMarkers(content), expectedContent);
+  }
+
+  Future<void> test_methodToGetter_method_startOfTypeParameterList() async {
+    const content = '''
+class A {
+  int test[[]]<T>() => 42;
+}
+    ''';
+    const expectedContent = '''
+class A {
+  int get test<T> => 42;
+}
+    ''';
+    newFile(mainFilePath, withoutMarkers(content));
+    await initialize();
+
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
+    final codeAction = findCommand(
+        codeActions, Commands.performRefactor, convertMethodToGetterTitle)!;
+
+    await verifyCodeActionEdits(
+        codeAction, withoutMarkers(content), expectedContent);
+  }
 }
 
 @reflectiveTest
@@ -745,8 +951,8 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
-        range: rangeFromMarkers(content));
+    final codeActions =
+        await getCodeActions(mainFileUri, range: rangeFromMarkers(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractWidgetTitle)!;
 
@@ -763,7 +969,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, extractWidgetTitle);
@@ -809,7 +1015,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final codeAction = findCommand(
         codeActions, Commands.performRefactor, inlineVariableTitle)!;
@@ -853,7 +1059,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, inlineMethodTitle)!;
@@ -888,7 +1094,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final codeActions = await getCodeActions(mainFileUri.toString(),
+    final codeActions = await getCodeActions(mainFileUri,
         position: positionFromMarker(content));
     final codeAction =
         findCommand(codeActions, Commands.performRefactor, inlineMethodTitle)!;
diff --git a/pkg/analysis_server/test/lsp/code_actions_source_test.dart b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
index b803a3c..07df82e 100644
--- a/pkg/analysis_server/test/lsp/code_actions_source_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
@@ -42,7 +42,7 @@
   /// Wrapper around [getCodeActions] for Source actions where position/range is
   /// irrelevant (so uses [startOfDocPos]).
   Future<List<Either2<Command, CodeAction>>> getSourceCodeActions(
-    String fileUri, {
+    Uri fileUri, {
     List<CodeActionKind>? kinds,
     CodeActionTriggerKind? triggerKind,
   }) {
@@ -81,7 +81,7 @@
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.fixAll)!;
 
     await verifyCodeActionEdits(codeAction, content, expectedContent);
@@ -112,7 +112,7 @@
         workspaceCapabilities: withApplyEditSupport(
             withDocumentChangesSupport(emptyWorkspaceClientCapabilities)));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.organizeImports)!;
 
     await verifyCodeActionEdits(codeAction, content, expectedContent,
@@ -140,7 +140,7 @@
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.organizeImports)!;
 
     await verifyCodeActionEdits(codeAction, content, expectedContent);
@@ -184,7 +184,7 @@
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
     final codeActions = await getSourceCodeActions(
-      mainFileUri.toString(),
+      mainFileUri,
       triggerKind: CodeActionTriggerKind.Automatic,
     );
     final codeAction = findCommand(codeActions, Commands.organizeImports)!;
@@ -206,7 +206,7 @@
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.organizeImports)!;
 
     final command = codeAction.map(
@@ -227,7 +227,7 @@
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
     ofKind(CodeActionKind kind) => getSourceCodeActions(
-          mainFileUri.toString(),
+          mainFileUri,
           kinds: [kind],
         );
 
@@ -252,7 +252,7 @@
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.organizeImports)!;
 
     final command = codeAction.map(
@@ -275,7 +275,7 @@
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.organizeImports);
     expect(codeAction, isNull);
   }
@@ -284,7 +284,7 @@
     newFile(mainFilePath, '');
     await initialize();
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.organizeImports);
     expect(codeAction, isNull);
   }
@@ -306,7 +306,7 @@
         workspaceCapabilities: withApplyEditSupport(
             withDocumentChangesSupport(emptyWorkspaceClientCapabilities)));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.sortMembers)!;
 
     await verifyCodeActionEdits(codeAction, content, expectedContent,
@@ -327,7 +327,7 @@
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.sortMembers)!;
 
     await verifyCodeActionEdits(codeAction, content, expectedContent);
@@ -373,7 +373,7 @@
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.sortMembers)!;
 
     final command = codeAction.map(
@@ -407,7 +407,7 @@
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
     final codeActions = await getSourceCodeActions(
-      mainFileUri.toString(),
+      mainFileUri,
       triggerKind: CodeActionTriggerKind.Automatic,
     );
     final codeAction = findCommand(codeActions, Commands.sortMembers)!;
@@ -429,7 +429,7 @@
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.sortMembers)!;
 
     final command = codeAction.map(
@@ -451,7 +451,7 @@
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
-    final codeActions = await getSourceCodeActions(pubspecFileUri.toString());
+    final codeActions = await getSourceCodeActions(pubspecFileUri);
     expect(codeActions, isEmpty);
   }
 
@@ -463,7 +463,7 @@
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.sortMembers);
     expect(codeAction, isNull);
   }
@@ -472,7 +472,7 @@
     newFile(mainFilePath, '');
     await initialize();
 
-    final codeActions = await getSourceCodeActions(mainFileUri.toString());
+    final codeActions = await getSourceCodeActions(mainFileUri);
     final codeAction = findCommand(codeActions, Commands.sortMembers);
     expect(codeAction, isNull);
   }
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index d7883ab..5829b13 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -94,6 +94,13 @@
     );
   }
 
+  /// Expect [item] to use the default edit range, inserting the value [text].
+  void expectUsesDefaultEditRange(CompletionItem item, String text) {
+    expect(item.textEditText ?? item.label, text);
+    expect(item.insertText, isNull);
+    expect(item.textEdit, isNull);
+  }
+
   @override
   void setUp() {
     super.setUp();
@@ -1227,6 +1234,129 @@
     expect(res.items.map((item) => item.label).contains('aaa'), isTrue);
   }
 
+  Future<void> test_itemDefaults_editRange() async {
+    final content = '''
+    void myFunction() {
+      [[myFunctio^]]
+    }
+    ''';
+
+    await initialize(
+      textDocumentCapabilities: withCompletionItemInsertReplaceSupport(
+        withCompletionListDefaults(
+          emptyTextDocumentClientCapabilities,
+          ['editRange'],
+        ),
+      ),
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    final list =
+        await getCompletionList(mainFileUri, positionFromMarker(content));
+    final item =
+        list.items.singleWhere((c) => c.label.startsWith('myFunction'));
+    final defaultEditRange = list.itemDefaults!.editRange!.map(
+      (insertReplace) => throw 'Expected Range, got CompletionItemEditRange',
+      (range) => range,
+    );
+
+    // Range covers the ranged marked with [[braces]] in `content`.
+    expect(defaultEditRange, rangeFromMarkers(content));
+
+    // Item should use the default range.
+    expectUsesDefaultEditRange(item, 'myFunction');
+  }
+
+  Future<void> test_itemDefaults_editRange_includesNonDefaultItem() async {
+    // In this code, we will get two completions with different edit ranges:
+    //
+    //   - 'b: ' will have a zero-width range because names don't replace args
+    //   -  'a' will replace 'b'
+    //
+    // Therefore we expect 'a' to use the default range (and not have its own)
+    // but 'b'` to have its own.
+    //
+    // Additionally, because the caret is before the identifier, we will have
+    // seperate default insert/replace ranges.
+    final content = '''
+void f(String a, {String? b}) {
+  f([[^b]]);
+}
+    ''';
+
+    await initialize(
+      textDocumentCapabilities: withCompletionItemInsertReplaceSupport(
+        withCompletionListDefaults(
+          emptyTextDocumentClientCapabilities,
+          ['editRange'],
+        ),
+      ),
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    final list =
+        await getCompletionList(mainFileUri, positionFromMarker(content));
+    final itemA = list.items.singleWhere((c) => c.label == 'a');
+    final itemB = list.items.singleWhere((c) => c.label == 'b: ');
+
+    // Default replace range should span `b`.
+    final expectedRange = rangeFromMarkers(content);
+    final defaultEditRange = list.itemDefaults!.editRange!.map(
+      (insertReplace) => insertReplace,
+      (range) => throw 'Expected Range, got CompletionItemEditRange',
+    );
+    expect(defaultEditRange.replace, equals(expectedRange));
+
+    // Default insert range should be in front of `b`.
+    expect(
+      defaultEditRange.insert,
+      Range(start: expectedRange.start, end: expectedRange.start),
+    );
+
+    // And item A should use that default.
+    expectUsesDefaultEditRange(itemA, 'a');
+
+    // Item B should have its own range, which is a single range for both
+    // insert and replace that matches the insert range (in front of `b`) of
+    // the default.
+    final itemBTextEdit = toTextEdit(itemB.textEdit!);
+    expect(itemBTextEdit.range, defaultEditRange.insert);
+    expect(itemBTextEdit.newText, 'b: ');
+  }
+
+  Future<void> test_itemDefaults_textMode() async {
+    // We only normally set InsertTextMode on multiline completions (where it
+    // matters), so ensure there's a multiline completion in the results for
+    // testing.
+    final content = '''
+    import 'package:flutter/material.dart';
+
+    class _MyWidgetState extends State<MyWidget> {
+      @override
+      Widget build(BuildContext context) {
+        [[setSt^]]
+        return Container();
+      }
+    }
+    ''';
+
+    await initialize(
+      textDocumentCapabilities: withCompletionItemInsertTextModeSupport(
+        withCompletionListDefaults(
+          emptyTextDocumentClientCapabilities,
+          ['insertTextMode'],
+        ),
+      ),
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    final list =
+        await getCompletionList(mainFileUri, positionFromMarker(content));
+    final item = list.items.singleWhere((c) => c.label.startsWith('setState'));
+
+    // Default should be set.
+    expect(list.itemDefaults?.insertTextMode, InsertTextMode.asIs);
+    // Item should not.
+    expect(item.insertTextMode, isNull);
+  }
+
   /// Exact matches should always be included when completion lists are
   /// truncated, even if they ranked poorly.
   Future<void> test_maxCompletionItems_doesNotExcludeExactMatches() async {
@@ -2106,6 +2236,37 @@
   }
 
   Future<void>
+      test_unimportedSymbols_importsPackageUri_extensionMember() async {
+    newFile(join(projectFolderPath, 'lib', 'my_extension.dart'), '''
+extension MyExtension on String {
+  void myExtensionMethod() {}
+}
+      ''');
+
+    final content = '''
+void f() {
+  ''.myExtensionMet^
+}
+    ''';
+
+    final expectedContent = '''
+import 'package:test/my_extension.dart';
+
+void f() {
+  ''.myExtensionMethod
+}
+    ''';
+
+    final completionLabel = 'myExtensionMethod()';
+    await _checkCompletionEdits(
+      mainFileUri,
+      content,
+      completionLabel,
+      expectedContent,
+    );
+  }
+
+  Future<void>
       test_unimportedSymbols_includesReexportedSymbolsForEachFile() async {
     newFile(
       join(projectFolderPath, 'source_file.dart'),
diff --git a/pkg/analysis_server/test/lsp/definition_test.dart b/pkg/analysis_server/test/lsp/definition_test.dart
index 68ff034..79e3131 100644
--- a/pkg/analysis_server/test/lsp/definition_test.dart
+++ b/pkg/analysis_server/test/lsp/definition_test.dart
@@ -52,7 +52,7 @@
     expect(res, hasLength(1));
     var loc = res.single;
     expect(loc.range, equals(rangeFromMarkers(referencedContents)));
-    expect(loc.uri, equals(referencedFileUri.toString()));
+    expect(loc.uri, equals(referencedFileUri));
   }
 
   Future<void> test_atDeclaration_class() async {
@@ -286,7 +286,7 @@
         equals(lsp.Range(
             start: lsp.Position(line: 0, character: 0),
             end: lsp.Position(line: 0, character: 5))));
-    expect(loc.uri, equals(pluginAnalyzedFileUri.toString()));
+    expect(loc.uri, equals(pluginAnalyzedFileUri));
   }
 
   Future<void> test_function() async {
@@ -334,7 +334,7 @@
     expect(res, hasLength(1));
     var loc = res.single;
     expect(loc.originSelectionRange, equals(rangeFromMarkers(mainContents)));
-    expect(loc.targetUri, equals(referencedFileUri.toString()));
+    expect(loc.targetUri, equals(referencedFileUri));
     expect(loc.targetRange, equals(rangeFromMarkers(referencedContents)));
     expect(
       loc.targetSelectionRange,
@@ -377,7 +377,7 @@
     expect(res, hasLength(1));
     var loc = res.single;
     expect(loc.originSelectionRange, equals(rangeFromMarkers(mainContents)));
-    expect(loc.targetUri, equals(referencedFileUri.toString()));
+    expect(loc.targetUri, equals(referencedFileUri));
     expect(loc.targetRange, equals(rangeFromMarkers(referencedContents)));
     expect(
       loc.targetSelectionRange,
@@ -435,7 +435,7 @@
     expect(res, hasLength(1));
     var loc = res.single;
     expect(loc.originSelectionRange, equals(rangeFromMarkers(mainContents)));
-    expect(loc.targetUri, equals(partFileUri.toString()));
+    expect(loc.targetUri, equals(partFileUri));
     expect(loc.targetRange, equals(rangeFromMarkers(partContents)));
     expect(
       loc.targetSelectionRange,
@@ -460,7 +460,7 @@
     final res = await getDefinitionAsLocation(
         mainFileUri, positionFromMarker(mainContents));
 
-    expect(res.single.uri, equals(partFileUri.toString()));
+    expect(res.single.uri, equals(partFileUri));
   }
 
   Future<void> test_partOfFilename() async {
@@ -480,7 +480,7 @@
     final res = await getDefinitionAsLocation(
         partFileUri, positionFromMarker(partContents));
 
-    expect(res.single.uri, equals(mainFileUri.toString()));
+    expect(res.single.uri, equals(mainFileUri));
   }
 
   Future<void> test_sameLine() async {
@@ -550,6 +550,6 @@
     expect(res, hasLength(1));
     var loc = res.single;
     expect(loc.range, equals(rangeFromMarkers(contents)));
-    expect(loc.uri, equals(mainFileUri.toString()));
+    expect(loc.uri, equals(mainFileUri));
   }
 }
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index 98330d6..73424db 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -245,7 +245,8 @@
     expect(diagnostic.code, equals('built_in_identifier_in_declaration'));
     expect(
       diagnostic.codeDescription!.href,
-      equals('https://dart.dev/diagnostics/built_in_identifier_in_declaration'),
+      equals(Uri.parse(
+          'https://dart.dev/diagnostics/built_in_identifier_in_declaration')),
     );
   }
 
@@ -272,7 +273,7 @@
     newFile(dotFolderFilePath, 'String a = 1;');
 
     List<Diagnostic>? diagnostics;
-    // Record if diagnostics are recieved, but since we don't expect them
+    // Record if diagnostics are received, but since we don't expect them
     // don't await them.
     unawaited(
         waitForDiagnostics(dotFolderFileUri).then((d) => diagnostics = d));
diff --git a/pkg/analysis_server/test/lsp/document_color_test.dart b/pkg/analysis_server/test/lsp/document_color_test.dart
index 5e3a80d..a9cbd27 100644
--- a/pkg/analysis_server/test/lsp/document_color_test.dart
+++ b/pkg/analysis_server/test/lsp/document_color_test.dart
@@ -44,7 +44,7 @@
     await initialize();
 
     final colorPresentations = await getColorPresentation(
-      mainFileUri.toString(),
+      mainFileUri,
       colorRange,
       Color(alpha: 1, red: 1, green: 1, blue: 1),
     );
@@ -64,7 +64,7 @@
     await initialize();
 
     final colors = await getColorPresentation(
-      pubspecFileUri.toString(),
+      pubspecFileUri,
       startOfDocRange,
       Color(alpha: 1, red: 1, green: 1, blue: 1),
     );
@@ -84,7 +84,7 @@
     await initialize();
 
     final colorPresentations = await getColorPresentation(
-      Uri.file(outsideRootFilePath).toString(),
+      Uri.file(outsideRootFilePath),
       colorRange,
       Color(alpha: 1, red: 1, green: 0, blue: 0),
     );
@@ -106,7 +106,7 @@
     await initialize();
 
     final colorPresentations = await getColorPresentation(
-      mainFileUri.toString(),
+      mainFileUri,
       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
@@ -158,7 +158,7 @@
     newFile(pubspecFilePath, simplePubspecContent);
     await initialize();
 
-    final colors = await getDocumentColors(pubspecFileUri.toString());
+    final colors = await getDocumentColors(pubspecFileUri);
     expect(colors, isEmpty);
   }
 
@@ -171,7 +171,7 @@
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
-    final colors = await getDocumentColors(mainFileUri.toString());
+    final colors = await getDocumentColors(mainFileUri);
     expect(colors, hasLength(1));
 
     final color = colors[0];
diff --git a/pkg/analysis_server/test/lsp/folding_test.dart b/pkg/analysis_server/test/lsp/folding_test.dart
index ecb3690..e802842 100644
--- a/pkg/analysis_server/test/lsp/folding_test.dart
+++ b/pkg/analysis_server/test/lsp/folding_test.dart
@@ -87,15 +87,7 @@
     }
     ''';
 
-    final ranges = rangesFromMarkers(content);
-    final expectedRegions = ranges
-        .map((range) => FoldingRange(
-              startLine: range.start.line,
-              startCharacter: range.start.character,
-              endLine: range.end.line,
-              endCharacter: range.end.character,
-            ))
-        .toList();
+    final expectedRegions = _expectedRangesFromMarkers(content);
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -233,15 +225,7 @@
     }
     ''';
 
-    final ranges = rangesFromMarkers(content);
-    final expectedRegions = ranges
-        .map((range) => FoldingRange(
-              startLine: range.start.line,
-              startCharacter: range.start.character,
-              endLine: range.end.line,
-              endCharacter: range.end.character,
-            ))
-        .toList();
+    final expectedRegions = _expectedRangesFromMarkers(content);
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -258,6 +242,25 @@
     expect(regions, isEmpty);
   }
 
+  Future<void> test_recordLiteral() async {
+    final content = '''
+    void f() {
+      var r = ([[
+        2,
+        'string',
+      ]]);
+    }
+    ''';
+
+    final expectedRegions = _expectedRangesFromMarkers(content);
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    final regions = await getFoldingRegions(mainFileUri);
+    expect(regions, containsAll(expectedRegions));
+  }
+
   Future<void> test_whileLoop() async {
     final content = '''
     f(int i) {
@@ -278,8 +281,17 @@
     }
     ''';
 
-    final ranges = rangesFromMarkers(content);
-    final expectedRegions = ranges
+    final expectedRegions = _expectedRangesFromMarkers(content);
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    final regions = await getFoldingRegions(mainFileUri);
+    expect(regions, containsAll(expectedRegions));
+  }
+
+  List<FoldingRange> _expectedRangesFromMarkers(String content) {
+    return rangesFromMarkers(content)
         .map((range) => FoldingRange(
               startLine: range.start.line,
               startCharacter: range.start.character,
@@ -287,12 +299,6 @@
               endCharacter: range.end.character,
             ))
         .toList();
-
-    await initialize();
-    await openFile(mainFileUri, withoutMarkers(content));
-
-    final regions = await getFoldingRegions(mainFileUri);
-    expect(regions, containsAll(expectedRegions));
   }
 
   FoldingRange _toFoldingRange(Range range, FoldingRangeKind? kind) {
diff --git a/pkg/analysis_server/test/lsp/format_test.dart b/pkg/analysis_server/test/lsp/format_test.dart
index 238d141..457e192 100644
--- a/pkg/analysis_server/test/lsp/format_test.dart
+++ b/pkg/analysis_server/test/lsp/format_test.dart
@@ -20,7 +20,7 @@
 class FormatTest extends AbstractLspAnalysisServerTest {
   Future<List<TextEdit>> expectFormattedContents(
       Uri uri, String original, String expected) async {
-    final formatEdits = (await formatDocument(uri.toString()))!;
+    final formatEdits = (await formatDocument(uri))!;
     final formattedContents = applyTextEdits(original, formatEdits);
     expect(formattedContents, equals(expected));
     return formatEdits;
@@ -28,8 +28,7 @@
 
   Future<List<TextEdit>> expectRangeFormattedContents(
       Uri uri, String original, String expected) async {
-    final formatEdits =
-        (await formatRange(uri.toString(), rangeFromMarkers(original)))!;
+    final formatEdits = (await formatRange(uri, rangeFromMarkers(original)))!;
     final formattedContents =
         applyTextEdits(withoutMarkers(original), formatEdits);
     expect(formattedContents, equals(expected));
@@ -44,7 +43,7 @@
     await initialize();
     await openFile(mainFileUri, contents);
 
-    final formatEdits = await formatDocument(mainFileUri.toString());
+    final formatEdits = await formatDocument(mainFileUri);
     expect(formatEdits, isNull);
   }
 
@@ -179,8 +178,8 @@
     await initialize();
     await openFile(mainFileUri, withoutMarkers(contents));
 
-    final formatEdits = (await formatOnType(
-        mainFileUri.toString(), positionFromMarker(contents), '}'))!;
+    final formatEdits =
+        (await formatOnType(mainFileUri, positionFromMarker(contents), '}'))!;
     final formattedContents =
         applyTextEdits(withoutMarkers(contents), formatEdits);
     expect(formattedContents, equals(expected));
@@ -244,7 +243,7 @@
     await initialize();
     await openFile(mainFileUri, withoutMarkers(contents));
     final formatRangeRequest = formatRange(
-      mainFileUri.toString(),
+      mainFileUri,
       Range(
           start: Position(line: 0, character: 0),
           end: Position(line: 10000, character: 0)),
@@ -323,7 +322,7 @@
     await initialize();
     await openFile(mainFileUri, contents);
 
-    final formatEdits = await formatDocument(mainFileUri.toString());
+    final formatEdits = await formatDocument(mainFileUri);
     expect(formatEdits, isNull);
   }
 
@@ -629,8 +628,7 @@
     await initialize();
     await openFile(pubspecFileUri, simplePubspecContent);
 
-    final formatEdits =
-        await formatOnType(pubspecFileUri.toString(), startOfDocPos, '}');
+    final formatEdits = await formatOnType(pubspecFileUri, startOfDocPos, '}');
     expect(formatEdits, isNull);
   }
 
@@ -638,8 +636,7 @@
     await initialize();
 
     await expectLater(
-      formatDocument(
-          Uri.file(join(projectFolderPath, 'missing.dart')).toString()),
+      formatDocument(Uri.file(join(projectFolderPath, 'missing.dart'))),
       throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
           message: 'File does not exist')),
     );
@@ -649,8 +646,10 @@
     await initialize();
 
     await expectLater(
-      // Add some invalid path characters to the end of a valid file:// URI.
-      formatDocument(mainFileUri.toString() + r'***###\\\///:::.dart'),
+      formatDocument(
+        // Add some invalid path characters to the end of a valid file:// URI.
+        Uri.parse(mainFileUri.toString() + r'###***\\\///:::.dart'),
+      ),
       throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
           message: 'File URI did not contain a valid file path')),
     );
@@ -660,7 +659,7 @@
     await initialize();
 
     await expectLater(
-      formatDocument('a:/a.dart'),
+      formatDocument(Uri.parse('a:/a.dart')),
       throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
           message: 'URI was not a valid file:// URI')),
     );
diff --git a/pkg/analysis_server/test/lsp/hover_test.dart b/pkg/analysis_server/test/lsp/hover_test.dart
index a20f335..e684647 100644
--- a/pkg/analysis_server/test/lsp/hover_test.dart
+++ b/pkg/analysis_server/test/lsp/hover_test.dart
@@ -39,6 +39,42 @@
     expect(_getStringContents(hover), endsWith('This is shared content.'));
   }
 
+  Future<void> test_function_startOfParameterList() async {
+    final content = '''
+    /// This is a function.
+    String [[abc]]^() {}
+    ''';
+
+    await initialize(
+        textDocumentCapabilities: withHoverContentFormat(
+            emptyTextDocumentClientCapabilities, [MarkupKind.PlainText]));
+    await openFile(mainFileUri, withoutMarkers(content));
+    final hover = await getHover(mainFileUri, positionFromMarker(content));
+    expect(hover, isNotNull);
+    expect(hover!.range, equals(rangeFromMarkers(content)));
+    expect(hover.contents, isNotNull);
+    final markup = _getMarkupContents(hover);
+    expect(markup.value, contains('This is a function.'));
+  }
+
+  Future<void> test_function_startOfTypeParameterList() async {
+    final content = '''
+    /// This is a function.
+    String [[abc]]^<T>(T a) {}
+    ''';
+
+    await initialize(
+        textDocumentCapabilities: withHoverContentFormat(
+            emptyTextDocumentClientCapabilities, [MarkupKind.PlainText]));
+    await openFile(mainFileUri, withoutMarkers(content));
+    final hover = await getHover(mainFileUri, positionFromMarker(content));
+    expect(hover, isNotNull);
+    expect(hover!.range, equals(rangeFromMarkers(content)));
+    expect(hover.contents, isNotNull);
+    final markup = _getMarkupContents(hover);
+    expect(markup.value, contains('This is a function.'));
+  }
+
   Future<void> test_hover_bad_position() async {
     await initialize();
     await openFile(mainFileUri, '');
@@ -68,6 +104,7 @@
 String abc
 ```
 Type: `String`
+
 *package:test/main.dart*
 
 ---
@@ -114,6 +151,46 @@
     expect(markup.value, contains('This is a string.'));
   }
 
+  Future<void> test_method_startOfParameterList() async {
+    final content = '''
+    class A {
+      /// This is a method.
+      String [[abc]]^() {}
+    }
+    ''';
+
+    await initialize(
+        textDocumentCapabilities: withHoverContentFormat(
+            emptyTextDocumentClientCapabilities, [MarkupKind.PlainText]));
+    await openFile(mainFileUri, withoutMarkers(content));
+    final hover = await getHover(mainFileUri, positionFromMarker(content));
+    expect(hover, isNotNull);
+    expect(hover!.range, equals(rangeFromMarkers(content)));
+    expect(hover.contents, isNotNull);
+    final markup = _getMarkupContents(hover);
+    expect(markup.value, contains('This is a method.'));
+  }
+
+  Future<void> test_method_startOfTypeParameterList() async {
+    final content = '''
+    class A {
+      /// This is a method.
+      String [[abc]]^<T>(T a) {}
+    }
+    ''';
+
+    await initialize(
+        textDocumentCapabilities: withHoverContentFormat(
+            emptyTextDocumentClientCapabilities, [MarkupKind.PlainText]));
+    await openFile(mainFileUri, withoutMarkers(content));
+    final hover = await getHover(mainFileUri, positionFromMarker(content));
+    expect(hover, isNotNull);
+    expect(hover!.range, equals(rangeFromMarkers(content)));
+    expect(hover.contents, isNotNull);
+    final markup = _getMarkupContents(hover);
+    expect(markup.value, contains('This is a method.'));
+  }
+
   Future<void> test_noElement() async {
     final content = '''
     String abc;
@@ -148,6 +225,7 @@
 String? abc
 ```
 Type: `String?`
+
 *package:test/main.dart*
     '''
         .trim();
@@ -279,6 +357,7 @@
 String abc
 ```
 Type: `String`
+
 *package:test/main.dart*
     '''
         .trim();
diff --git a/pkg/analysis_server/test/lsp/implementation_test.dart b/pkg/analysis_server/test/lsp/implementation_test.dart
index 75ebbd0..55e7e9e 100644
--- a/pkg/analysis_server/test/lsp/implementation_test.dart
+++ b/pkg/analysis_server/test/lsp/implementation_test.dart
@@ -116,6 +116,26 @@
       }
     ''');
 
+  Future<void> test_method_startOfParameterList() => _testMarkedContent('''
+      abstract class A {
+        void m^();
+      }
+
+      class B extends A {
+        void [[m]]() {}
+      }
+    ''');
+
+  Future<void> test_method_startOfTypeParameterList() => _testMarkedContent('''
+      abstract class A {
+        void m^<T>();
+      }
+
+      class B extends A {
+        void [[m]]<T>() {}
+      }
+    ''');
+
   Future<void> test_method_sub() => _testMarkedContent('''
       abstract class A {
         void ^b();
@@ -177,7 +197,7 @@
     );
 
     final expectedLocations = rangesFromMarkers(content)
-        .map((r) => Location(uri: mainFileUri.toString(), range: r));
+        .map((r) => Location(uri: mainFileUri, range: r));
 
     if (expectResults) {
       expect(res, equals(expectedLocations));
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 9e066454..0bb30ce 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -39,9 +39,12 @@
     List<Registration> registrations,
     Method method,
   ) {
+    final options = registrationFor(registrations, method)?.registerOptions;
+    if (options == null) {
+      throw 'Registration options for $method were not found';
+    }
     return TextDocumentRegistrationOptions.fromJson(
-        registrationFor(registrations, method)?.registerOptions
-            as Map<String, Object?>);
+        options as Map<String, Object?>);
   }
 
   Future<void> test_blazeWorkspace() async {
@@ -392,6 +395,7 @@
     expect(initResult.capabilities.callHierarchyProvider, isNull);
     expect(initResult.capabilities.completionProvider, isNull);
     expect(initResult.capabilities.hoverProvider, isNull);
+    expect(initResult.capabilities.inlayHintProvider, isNull);
     expect(initResult.capabilities.signatureHelpProvider, isNull);
     expect(initResult.capabilities.referencesProvider, isNull);
     expect(initResult.capabilities.colorProvider, isNull);
diff --git a/pkg/analysis_server/test/lsp/inlay_hint_test.dart b/pkg/analysis_server/test/lsp/inlay_hint_test.dart
new file mode 100644
index 0000000..634ca9a
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/inlay_hint_test.dart
@@ -0,0 +1,468 @@
+// Copyright (c) 2022, 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/lsp_protocol/protocol.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(TypeInlayHintTest);
+    defineReflectiveTests(ParameterNameInlayHintTest);
+  });
+}
+
+@reflectiveTest
+class ParameterNameInlayHintTest extends _AbstractInlayHintTest {
+  Future<void> test_named() async {
+    final content = '''
+void f({required int? a, int? b}) {
+  f(a: a); // already named
+}
+''';
+    final expected = '''
+void f({required int? a, int? b}) {
+  f(a: a); // already named
+}
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_optionalPositional() async {
+    final content = '''
+void f([int? a, int? b]) {
+  f(a);
+}
+''';
+    final expected = '''
+void f([int? a, int? b]) {
+  f((Parameter:a:) a);
+}
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_requiredPositional() async {
+    final content = '''
+void f(int a, int b) {
+  f(a, b);
+}
+''';
+    final expected = '''
+void f(int a, int b) {
+  f((Parameter:a:) a, (Parameter:b:) b);
+}
+''';
+    await _testHints(content, expected);
+  }
+}
+
+@reflectiveTest
+class TypeInlayHintTest extends _AbstractInlayHintTest {
+  Future<void> test_class_field() async {
+    final content = '''
+class A {
+  final i1 = 1;
+}
+''';
+    final expected = '''
+class A {
+  final (Type:int) i1 = 1;
+}
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_documentUpdates() async {
+    final content = '''
+final a = 1;
+''';
+    await initialize();
+
+    // Start with a blank document expecting no hints,
+    await openFile(mainFileUri, '');
+    final hintsBeforeChange = await getInlayHints(
+      mainFileUri,
+      startOfDocRange,
+    );
+
+    // Update the document to ensure we get latest hints.
+    // Don't await `replaceFile` because we want to check the server correctly
+    // handles an inlayHints request that immediately follows a document update.
+    unawaited(replaceFile(1, mainFileUri, content));
+    final hintsAfterChange = await getInlayHints(
+      mainFileUri,
+      rangeOfWholeContent(content),
+    );
+
+    expect(hintsBeforeChange, isEmpty);
+    expect(hintsAfterChange, isNotEmpty);
+  }
+
+  Future<void> test_getter() async {
+    final content = '''
+get f => 1;
+''';
+    final expected = '''
+(Type:dynamic) get f => 1;
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_leadingAnnotation() async {
+    final content = '''
+@deprecated
+f() => '';
+
+class A {
+  @deprecated
+  f() => '';
+}
+''';
+    final expected = '''
+@deprecated
+(Type:dynamic) f() => '';
+
+class A {
+  @deprecated
+  (Type:dynamic) f() => '';
+}
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_leadingComment() async {
+    final content = '''
+// Comment
+f() => '';
+
+class A {
+  // Comment
+  f() => '';
+}
+''';
+    final expected = '''
+// Comment
+(Type:dynamic) f() => '';
+
+class A {
+  // Comment
+  (Type:dynamic) f() => '';
+}
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_leadingDocumentation() async {
+    final content = '''
+/// Documentation
+f() => '';
+
+class A {
+  /// Documentation
+  f() => '';
+}
+''';
+    final expected = '''
+/// Documentation
+(Type:dynamic) f() => '';
+
+class A {
+  /// Documentation
+  (Type:dynamic) f() => '';
+}
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_localFunction_returnType() async {
+    // Check inferred return types for local functions have type hints.
+    final content = '''
+void f() {
+  g() => '';
+  h() { return ''; }
+  i() {}
+  void j() {}
+}
+''';
+    final expected = '''
+void f() {
+  (Type:String) g() => '';
+  (Type:String) h() { return ''; }
+  (Type:Null) i() {}
+  void j() {}
+}
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_method_parameters() async {
+    final content = '''
+class A {
+  void m1(int a, [String? b]) {}
+  void m2(int a, {String? b, required String c}) {}
+}
+class B extends A {
+  @override
+  void m1(a, [b]) {}
+  void m2(a, {b, required c}) {}
+  void m3(a, {b}) {}
+}
+''';
+    final expected = '''
+class A {
+  void m1(int a, [String? b]) {}
+  void m2(int a, {String? b, required String c}) {}
+}
+class B extends A {
+  @override
+  void m1((Type:int) a, [(Type:String?) b]) {}
+  void m2((Type:int) a, {(Type:String?) b, required (Type:String) c}) {}
+  void m3((Type:dynamic) a, {(Type:dynamic) b}) {}
+}
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_method_returnType() async {
+    final content = '''
+class A {
+  f() => '';
+}
+''';
+    // method return types are not inferred and always `dynamic`.
+    final expected = '''
+class A {
+  (Type:dynamic) f() => '';
+}
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_setter() async {
+    final content = '''
+set f(int i) {}
+''';
+    // Setters are always `void` so we don't show a label there.
+    final expected = '''
+set f(int i) {}
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_topLevelFunction_returnType() async {
+    final content = '''
+f() => '';
+''';
+    // top-level function return types are not inferred and always `dynamic`
+    final expected = '''
+(Type:dynamic) f() => '';
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_topLevelVariable_closureResult() async {
+    final content = '''
+var c1 = (() => 3)();
+int c2 = (() => 3)(); // already typed
+''';
+    final expected = '''
+var (Type:int) c1 = (() => 3)();
+int c2 = (() => 3)(); // already typed
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_topLevelVariable_functionResult() async {
+    final content = '''
+String f() => '';
+final s1 = f();
+final String s2 = f(); // already typed
+''';
+    final expected = '''
+String f() => '';
+final (Type:String) s1 = f();
+final String s2 = f(); // already typed
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_topLevelVariable_functionType() async {
+    final content = '''
+final f1 = (List<String> x) => x;
+final List<String> Function(List<String>) f2 = (List<String> x) => x; // already typed
+''';
+    final expected = '''
+final (Type:List<String> Function(List<String>)) f1 = (List<String> x) => x;
+final List<String> Function(List<String>) f2 = (List<String> x) => x; // already typed
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_topLevelVariable_literal() async {
+    final content = '''
+final i1 = 1;
+const i2 = 1;
+var i3 = 1;
+final i4 = 2, s1 = '';
+int i5 = 1; // already typed
+''';
+    final expected = '''
+final (Type:int) i1 = 1;
+const (Type:int) i2 = 1;
+var (Type:int) i3 = 1;
+final (Type:int) i4 = 2, (Type:String) s1 = '';
+int i5 = 1; // already typed
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_topLevelVariable_literalList() async {
+    final content = '''
+final l1 = [1, 2, 3];
+final l2 = [1, '', 3];
+final l3 = ['', null, ''];
+final l4 = <Object>[1, 2, 3];
+final List<Object> l5 = [1, 2, 3]; // already typed
+''';
+    final expected = '''
+final (Type:List<int>) l1 = [1, 2, 3];
+final (Type:List<Object>) l2 = [1, '', 3];
+final (Type:List<String?>) l3 = ['', null, ''];
+final (Type:List<Object>) l4 = <Object>[1, 2, 3];
+final List<Object> l5 = [1, 2, 3]; // already typed
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_topLevelVariable_literalMap() async {
+    final content = '''
+final m1 = {1: '', 2: ''};
+final m2 = {'': [1]};
+final m3 = {'': null};
+final m4 = <Object, String>{1: '', 2: ''};
+final Map<int, String> m1 = {1: '', 2: ''}; // already typed
+''';
+    final expected = '''
+final (Type:Map<int, String>) m1 = {1: '', 2: ''};
+final (Type:Map<String, List<int>>) m2 = {'': [1]};
+final (Type:Map<String, Null>) m3 = {'': null};
+final (Type:Map<Object, String>) m4 = <Object, String>{1: '', 2: ''};
+final Map<int, String> m1 = {1: '', 2: ''}; // already typed
+''';
+    await _testHints(content, expected);
+  }
+
+  Future<void> test_topLevelVariable_literalSet() async {
+    final content = '''
+final s1 = {1, 2, 3};
+final s2 = {1, '', 3};
+final s3 = {'', null, ''};
+final s4 = <Object>{1, 2, 3};
+final Set<Object> s5 = {1, 2, 3}; // already typed
+''';
+    final expected = '''
+final (Type:Set<int>) s1 = {1, 2, 3};
+final (Type:Set<Object>) s2 = {1, '', 3};
+final (Type:Set<String?>) s3 = {'', null, ''};
+final (Type:Set<Object>) s4 = <Object>{1, 2, 3};
+final Set<Object> s5 = {1, 2, 3}; // already typed
+''';
+    await _testHints(content, expected);
+  }
+}
+
+class _AbstractInlayHintTest extends AbstractLspAnalysisServerTest {
+  /// Substitutes text from [hints] into [content] to produce a text
+  /// representation that can be easily tested.
+  ///
+  /// Label kinds will be included as well as their text, with leading or
+  /// trailing spaces based on padding flags on the hint.
+  ///
+  /// ```
+  /// final a = 1;
+  /// ```
+  ///
+  /// May become:
+  ///
+  /// ```
+  /// final (Type:int) a = 1;
+  /// ```
+  String substituteHints(String content, List<InlayHint> hints) {
+    hints.sort((h1, h2) => positionCompare(h1.position, h2.position));
+    final buffer = StringBuffer();
+    final lineInfo = LineInfo.fromContent(content);
+
+    var lastOffset = 0;
+    for (final hint in hints) {
+      // First add any text from the last hint up to this hint.
+      final offset = toOffset(lineInfo, hint.position).result;
+      buffer.write(content.substring(lastOffset, offset));
+
+      // Then add the hint. Include the kind in parens so it can be tested too,
+      // and add a trailing/leading space based on settings.
+      _writeHintDescription(buffer, hint);
+      lastOffset = offset;
+    }
+    // Finally, write anything after the last hint.
+    buffer.write(content.substring(lastOffset));
+
+    return buffer.toString();
+  }
+
+  Future<void> _testHints(
+      String content, String expectedContentWithHints) async {
+    await initialize();
+
+    await openFile(mainFileUri, content);
+    final hints = await getInlayHints(
+      mainFileUri,
+      rangeOfWholeContent(content),
+    );
+
+    final actualContentWithHints = substituteHints(content, hints);
+    expect(actualContentWithHints, expectedContentWithHints);
+  }
+
+  /// Helper to write a text representation of [hint] into [buffer].
+  void _writeHintDescription(StringBuffer buffer, InlayHint hint) {
+    // TODO(dantup): Improve the LSP enum codegen to allow us to get the names
+    //  of int-based enums.
+    final kindNames = {
+      InlayHintKind.Type: 'Type',
+      InlayHintKind.Parameter: 'Parameter',
+    };
+
+    if (hint.paddingLeft ?? false) {
+      buffer.write(' ');
+    }
+    buffer.write('(');
+    if (hint.kind != null) {
+      buffer
+        ..write(kindNames[hint.kind])
+        ..write(':');
+    }
+    buffer.write(hint.textLabel);
+    buffer.write(')');
+    if (hint.paddingRight ?? false) {
+      buffer.write(' ');
+    }
+  }
+}
+
+extension _InlayHintExtension on InlayHint {
+  /// Returns the visible text of the InlayHint, concatenating any parts.
+  String get textLabel => label.map(
+        // Unwrap where an InlayHint may provide its label in multiple
+        // `InlayHintLabelPart`s.
+        (t1) => t1.map((part) => part.value).join(),
+        (t2) => t2,
+      );
+}
diff --git a/pkg/analysis_server/test/lsp/references_test.dart b/pkg/analysis_server/test/lsp/references_test.dart
index 47bdd84..d8a7c43 100644
--- a/pkg/analysis_server/test/lsp/references_test.dart
+++ b/pkg/analysis_server/test/lsp/references_test.dart
@@ -54,13 +54,12 @@
     expect(res, hasLength(2));
     expect(
         res,
-        contains(Location(
-            uri: mainFileUri.toString(),
-            range: rangeFromMarkers(mainContents))));
+        contains(
+            Location(uri: mainFileUri, range: rangeFromMarkers(mainContents))));
     expect(
         res,
         contains(Location(
-            uri: referencedFileUri.toString(),
+            uri: referencedFileUri,
             range: rangeFromMarkers(referencedContents))));
   }
 
@@ -98,7 +97,91 @@
     expect(res, hasLength(1));
     var loc = res.single;
     expect(loc.range, equals(rangeFromMarkers(mainContents)));
-    expect(loc.uri, equals(mainFileUri.toString()));
+    expect(loc.uri, equals(mainFileUri));
+  }
+
+  Future<void> test_function_startOfParameterList() async {
+    final contents = '''
+    foo^() {
+      [[foo]]();
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    final res = await getReferences(mainFileUri, positionFromMarker(contents));
+
+    expect(res, hasLength(1));
+    expect(
+      res,
+      contains(
+        Location(uri: mainFileUri, range: rangeFromMarkers(contents)),
+      ),
+    );
+  }
+
+  Future<void> test_function_startOfTypeParameterList() async {
+    final contents = '''
+    foo^<T>() {
+      [[foo]]();
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    final res = await getReferences(mainFileUri, positionFromMarker(contents));
+
+    expect(res, hasLength(1));
+    expect(
+      res,
+      contains(
+        Location(uri: mainFileUri, range: rangeFromMarkers(contents)),
+      ),
+    );
+  }
+
+  Future<void> test_method_startOfParameterList() async {
+    final contents = '''
+    class A {
+      foo^() {
+        [[foo]]();
+      }
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    final res = await getReferences(mainFileUri, positionFromMarker(contents));
+
+    expect(res, hasLength(1));
+    expect(
+      res,
+      contains(
+        Location(uri: mainFileUri, range: rangeFromMarkers(contents)),
+      ),
+    );
+  }
+
+  Future<void> test_method_startOfTypeParameterList() async {
+    final contents = '''
+    class A {
+      foo^<T>() {
+        [[foo]]();
+      }
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    final res = await getReferences(mainFileUri, positionFromMarker(contents));
+
+    expect(res, hasLength(1));
+    expect(
+      res,
+      contains(
+        Location(uri: mainFileUri, range: rangeFromMarkers(contents)),
+      ),
+    );
   }
 
   Future<void> test_nonDartFile() async {
@@ -124,8 +207,7 @@
     expect(
       res,
       contains(
-        Location(
-            uri: mainFileUri.toString(), range: rangeFromMarkers(contents)),
+        Location(uri: mainFileUri, range: rangeFromMarkers(contents)),
       ),
     );
   }
@@ -145,8 +227,7 @@
     expect(
       res,
       contains(
-        Location(
-            uri: mainFileUri.toString(), range: rangeFromMarkers(contents)),
+        Location(uri: mainFileUri, range: rangeFromMarkers(contents)),
       ),
     );
   }
diff --git a/pkg/analysis_server/test/lsp/rename_test.dart b/pkg/analysis_server/test/lsp/rename_test.dart
index ab9bf56..8701c3f 100644
--- a/pkg/analysis_server/test/lsp/rename_test.dart
+++ b/pkg/analysis_server/test/lsp/rename_test.dart
@@ -36,6 +36,22 @@
     return _test_prepare(content, 'MyClass');
   }
 
+  Future<void> test_prepare_function_startOfParameterList() {
+    const content = '''
+    void [[aaaa]]^() {}
+    ''';
+
+    return _test_prepare(content, 'aaaa');
+  }
+
+  Future<void> test_prepare_function_startOfTypeParameterList() {
+    const content = '''
+    void [[aaaa]]^<T>() {}
+    ''';
+
+    return _test_prepare(content, 'aaaa');
+  }
+
   Future<void> test_prepare_importPrefix() async {
     const content = '''
     import 'dart:async' as [[myPr^efix]];
@@ -70,6 +86,26 @@
     return _test_prepare(content, null);
   }
 
+  Future<void> test_prepare_method_startOfParameterList() {
+    const content = '''
+    class A {
+      void [[aaaa]]^() {}
+    }
+    ''';
+
+    return _test_prepare(content, 'aaaa');
+  }
+
+  Future<void> test_prepare_method_startOfTypeParameterList() {
+    const content = '''
+    class A {
+      void [[aaaa]]^<T>() {}
+    }
+    ''';
+
+    return _test_prepare(content, 'aaaa');
+  }
+
   Future<void> test_prepare_sdkClass() async {
     const content = '''
     final a = new [[Ob^ject]]();
@@ -81,7 +117,7 @@
     final request = makeRequest(
       Method.textDocument_prepareRename,
       TextDocumentPositionParams(
-        textDocument: TextDocumentIdentifier(uri: mainFileUri.toString()),
+        textDocument: TextDocumentIdentifier(uri: mainFileUri),
         position: positionFromMarker(content),
       ),
     );
@@ -366,6 +402,28 @@
     );
   }
 
+  Future<void> test_rename_function_startOfParameterList() {
+    const content = '''
+    void f^() {}
+    ''';
+    const expectedContent = '''
+    void newName() {}
+    ''';
+    return _test_rename_withDocumentChanges(
+        content, 'newName', expectedContent);
+  }
+
+  Future<void> test_rename_function_startOfTypeParameterList() {
+    const content = '''
+    void f^<T>() {}
+    ''';
+    const expectedContent = '''
+    void newName<T>() {}
+    ''';
+    return _test_rename_withDocumentChanges(
+        content, 'newName', expectedContent);
+  }
+
   Future<void> test_rename_importPrefix() {
     const content = '''
     import 'dart:async' as myPr^efix;
@@ -408,6 +466,36 @@
     return _test_rename_withDocumentChanges(content, 'MyNewClass', null);
   }
 
+  Future<void> test_rename_method_startOfParameterList() {
+    const content = '''
+    class MyClass {
+      void m^() {}
+    }
+    ''';
+    const expectedContent = '''
+    class MyClass {
+      void newName() {}
+    }
+    ''';
+    return _test_rename_withDocumentChanges(
+        content, 'newName', expectedContent);
+  }
+
+  Future<void> test_rename_method_startOfTypeParameterList() {
+    const content = '''
+    class MyClass {
+      void m^<T>() {}
+    }
+    ''';
+    const expectedContent = '''
+    class MyClass {
+      void newName<T>() {}
+    }
+    ''';
+    return _test_rename_withDocumentChanges(
+        content, 'newName', expectedContent);
+  }
+
   Future<void> test_rename_multipleFiles() async {
     final referencedFilePath =
         join(projectFolderPath, 'lib', 'referenced.dart');
@@ -546,7 +634,7 @@
       Method.textDocument_rename,
       RenameParams(
         newName: 'Object2',
-        textDocument: TextDocumentIdentifier(uri: mainFileUri.toString()),
+        textDocument: TextDocumentIdentifier(uri: mainFileUri),
         position: positionFromMarker(content),
       ),
     );
@@ -559,6 +647,42 @@
     expect(response.error!.message, contains('is defined in the SDK'));
   }
 
+  /// Unrelated dartdoc references should not be renamed.
+  ///
+  /// https://github.com/Dart-Code/Dart-Code/issues/4131
+  Future<void> test_rename_updatesCorrectDartdocReferences() {
+    const content = '''
+    class A {
+      int? origi^nalName;
+    }
+
+    class B {
+      int? originalName;
+    }
+
+    /// [A.originalName]
+    /// [B.originalName]
+    /// [C.originalName]
+    var a;
+    ''';
+    const expectedContent = '''
+    class A {
+      int? newName;
+    }
+
+    class B {
+      int? originalName;
+    }
+
+    /// [A.newName]
+    /// [B.originalName]
+    /// [C.originalName]
+    var a;
+    ''';
+    return _test_rename_withDocumentChanges(
+        content, 'newName', expectedContent);
+  }
+
   Future<void> test_rename_usingLegacyChangeInterface() async {
     // This test initializes without support for DocumentChanges (versioning)
     // whereas the other tests all use DocumentChanges support (preferred).
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 69b8171e..1b469db 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -302,6 +302,7 @@
       'callHierarchy': {'dynamicRegistration': true},
       'completion': {'dynamicRegistration': true},
       'hover': {'dynamicRegistration': true},
+      'inlayHint': {'dynamicRegistration': true},
       'signatureHelp': {'dynamicRegistration': true},
       'references': {'dynamicRegistration': true},
       'documentHighlight': {'dynamicRegistration': true},
@@ -428,6 +429,19 @@
     });
   }
 
+  TextDocumentClientCapabilities withCompletionListDefaults(
+    TextDocumentClientCapabilities source,
+    List<String> defaults,
+  ) {
+    return extendTextDocumentCapabilities(source, {
+      'completion': {
+        'completionList': {
+          'itemDefaults': defaults,
+        }
+      }
+    });
+  }
+
   WorkspaceClientCapabilities withConfigurationSupport(
     WorkspaceClientCapabilities source,
   ) {
@@ -698,10 +712,10 @@
 
   void applyChanges(
     Map<String, String> fileContents,
-    Map<String, List<TextEdit>> changes,
+    Map<Uri, List<TextEdit>> changes,
   ) {
     changes.forEach((fileUri, edits) {
-      final path = Uri.parse(fileUri).toFilePath();
+      final path = fileUri.toFilePath();
       fileContents[path] = applyTextEdits(fileContents[path]!, edits);
     });
   }
@@ -736,7 +750,7 @@
 
   void applyResourceCreate(
       Map<String, String> oldFileContent, CreateFile create) {
-    final path = Uri.parse(create.uri).toFilePath();
+    final path = create.uri.toFilePath();
     if (oldFileContent.containsKey(path)) {
       throw 'Received create instruction for $path which already existed.';
     }
@@ -745,8 +759,8 @@
 
   void applyResourceRename(
       Map<String, String> oldFileContent, RenameFile rename) {
-    final oldPath = Uri.parse(rename.oldUri).toFilePath();
-    final newPath = Uri.parse(rename.newUri).toFilePath();
+    final oldPath = rename.oldUri.toFilePath();
+    final newPath = rename.newUri.toFilePath();
     if (!oldFileContent.containsKey(oldPath)) {
       throw 'Received rename instruction for $oldPath which did not exist.';
     }
@@ -761,7 +775,7 @@
   void applyTextDocumentEdits(
       Map<String, String> oldFileContent, List<TextDocumentEdit> edits) {
     for (var edit in edits) {
-      final path = Uri.parse(edit.textDocument.uri).toFilePath();
+      final path = edit.textDocument.uri.toFilePath();
       if (!oldFileContent.containsKey(path)) {
         throw 'Received edits for $path which was not provided as a file to be edited. '
             'Perhaps a CreateFile change was missing from the edits?';
@@ -869,8 +883,8 @@
     var notification = makeNotification(
       Method.textDocument_didChange,
       DidChangeTextDocumentParams(
-        textDocument: VersionedTextDocumentIdentifier(
-            version: newVersion, uri: uri.toString()),
+        textDocument:
+            VersionedTextDocumentIdentifier(version: newVersion, uri: uri),
         contentChanges: changes,
       ),
     );
@@ -894,7 +908,7 @@
     var notification = makeNotification(
       Method.textDocument_didClose,
       DidCloseTextDocumentParams(
-          textDocument: TextDocumentIdentifier(uri: uri.toString())),
+          textDocument: TextDocumentIdentifier(uri: uri)),
     );
     await sendNotificationToServer(notification);
   }
@@ -938,7 +952,7 @@
     TextDocumentEdit edit,
     Map<String, int> expectedVersions,
   ) {
-    final path = Uri.parse(edit.textDocument.uri).toFilePath();
+    final path = edit.textDocument.uri.toFilePath();
     final expectedVersion = expectedVersions[path];
 
     expect(edit.textDocument.version, equals(expectedVersion));
@@ -1010,7 +1024,7 @@
   Future<T> expectSuccessfulResponseTo<T, R>(
       RequestMessage request, T Function(R) fromJson);
 
-  Future<List<TextEdit>?> formatDocument(String fileUri) {
+  Future<List<TextEdit>?> formatDocument(Uri fileUri) {
     final request = makeRequest(
       Method.textDocument_formatting,
       DocumentFormattingParams(
@@ -1025,7 +1039,7 @@
   }
 
   Future<List<TextEdit>?> formatOnType(
-      String fileUri, Position pos, String character) {
+      Uri fileUri, Position pos, String character) {
     final request = makeRequest(
       Method.textDocument_onTypeFormatting,
       DocumentOnTypeFormattingParams(
@@ -1041,7 +1055,7 @@
         request, _fromJsonList(TextEdit.fromJson));
   }
 
-  Future<List<TextEdit>?> formatRange(String fileUri, Range range) {
+  Future<List<TextEdit>?> formatRange(Uri fileUri, Range range) {
     final request = makeRequest(
       Method.textDocument_rangeFormatting,
       DocumentRangeFormattingParams(
@@ -1057,7 +1071,7 @@
   }
 
   Future<List<Either2<Command, CodeAction>>> getCodeActions(
-    String fileUri, {
+    Uri fileUri, {
     Range? range,
     Position? position,
     List<CodeActionKind>? kinds,
@@ -1089,7 +1103,7 @@
   }
 
   Future<List<ColorPresentation>> getColorPresentation(
-      String fileUri, Range range, Color color) {
+      Uri fileUri, Range range, Color color) {
     final request = makeRequest(
       Method.textDocument_colorPresentation,
       ColorPresentationParams(
@@ -1116,7 +1130,7 @@
       Method.textDocument_completion,
       CompletionParams(
         context: context,
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         position: pos,
       ),
     );
@@ -1128,7 +1142,7 @@
     final request = makeRequest(
       Method.textDocument_definition,
       TextDocumentPositionParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         position: pos,
       ),
     );
@@ -1167,7 +1181,7 @@
     return expectSuccessfulResponseTo(request, DartDiagnosticServer.fromJson);
   }
 
-  Future<List<ColorInformation>> getDocumentColors(String fileUri) {
+  Future<List<ColorInformation>> getDocumentColors(Uri fileUri) {
     final request = makeRequest(
       Method.textDocument_documentColor,
       DocumentColorParams(
@@ -1185,7 +1199,7 @@
     final request = makeRequest(
       Method.textDocument_documentHighlight,
       TextDocumentPositionParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         position: pos,
       ),
     );
@@ -1198,7 +1212,7 @@
     final request = makeRequest(
       Method.textDocument_documentSymbol,
       DocumentSymbolParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
       ),
     );
     return expectSuccessfulResponseTo(
@@ -1215,7 +1229,7 @@
     final request = makeRequest(
       Method.textDocument_foldingRange,
       FoldingRangeParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
       ),
     );
     return expectSuccessfulResponseTo(
@@ -1226,8 +1240,7 @@
     final request = makeRequest(
       Method.textDocument_hover,
       TextDocumentPositionParams(
-          textDocument: TextDocumentIdentifier(uri: uri.toString()),
-          position: pos),
+          textDocument: TextDocumentIdentifier(uri: uri), position: pos),
     );
     return expectSuccessfulResponseTo(request, Hover.fromJson);
   }
@@ -1240,7 +1253,7 @@
     final request = makeRequest(
       Method.textDocument_implementation,
       TextDocumentPositionParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         position: pos,
       ),
     );
@@ -1248,6 +1261,18 @@
         request, _fromJsonList(Location.fromJson));
   }
 
+  Future<List<InlayHint>> getInlayHints(Uri uri, Range range) {
+    final request = makeRequest(
+      Method.textDocument_inlayHint,
+      InlayHintParams(
+        textDocument: TextDocumentIdentifier(uri: uri),
+        range: range,
+      ),
+    );
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(InlayHint.fromJson));
+  }
+
   Future<List<Location>> getReferences(
     Uri uri,
     Position pos, {
@@ -1257,7 +1282,7 @@
       Method.textDocument_references,
       ReferenceParams(
         context: ReferenceContext(includeDeclaration: includeDeclarations),
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         position: pos,
       ),
     );
@@ -1284,8 +1309,7 @@
     final request = makeRequest(
       Method.textDocument_selectionRange,
       SelectionRangeParams(
-          textDocument: TextDocumentIdentifier(uri: uri.toString()),
-          positions: positions),
+          textDocument: TextDocumentIdentifier(uri: uri), positions: positions),
     );
     return expectSuccessfulResponseTo(
         request, _fromJsonList(SelectionRange.fromJson));
@@ -1295,7 +1319,7 @@
     final request = makeRequest(
       Method.textDocument_semanticTokens_full,
       SemanticTokensParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
       ),
     );
     return expectSuccessfulResponseTo(request, SemanticTokens.fromJson);
@@ -1305,7 +1329,7 @@
     final request = makeRequest(
       Method.textDocument_semanticTokens_range,
       SemanticTokensRangeParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         range: range,
       ),
     );
@@ -1317,7 +1341,7 @@
     final request = makeRequest(
       Method.textDocument_signatureHelp,
       SignatureHelpParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         position: pos,
         context: context,
       ),
@@ -1332,7 +1356,7 @@
     final request = makeRequest(
       CustomMethods.super_,
       TextDocumentPositionParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         position: pos,
       ),
     );
@@ -1344,7 +1368,7 @@
     final request = makeRequest(
       Method.textDocument_typeDefinition,
       TypeDefinitionParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         position: pos,
       ),
     );
@@ -1519,7 +1543,7 @@
         Method.initialize,
         InitializeParams(
           rootPath: rootPath,
-          rootUri: rootUri?.toString(),
+          rootUri: rootUri,
           initializationOptions:
               initializationOptions ?? defaultInitializationOptions,
           capabilities: clientCapabilities,
@@ -1556,8 +1580,8 @@
   RequestMessage makeRenameRequest(
       int? version, Uri uri, Position pos, String newName) {
     final docIdentifier = version != null
-        ? VersionedTextDocumentIdentifier(version: version, uri: uri.toString())
-        : TextDocumentIdentifier(uri: uri.toString());
+        ? VersionedTextDocumentIdentifier(version: version, uri: uri)
+        : TextDocumentIdentifier(uri: uri);
     final request = makeRequest(
       Method.textDocument_rename,
       RenameParams(
@@ -1636,7 +1660,7 @@
       Method.textDocument_didOpen,
       DidOpenTextDocumentParams(
           textDocument: TextDocumentItem(
-              uri: uri.toString(),
+              uri: uri,
               languageId: dartLanguageId,
               version: version,
               text: content)),
@@ -1667,7 +1691,7 @@
     final request = makeRequest(
       Method.textDocument_prepareCallHierarchy,
       CallHierarchyPrepareParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         position: pos,
       ),
     );
@@ -1679,7 +1703,7 @@
     final request = makeRequest(
       Method.textDocument_prepareRename,
       TextDocumentPositionParams(
-        textDocument: TextDocumentIdentifier(uri: uri.toString()),
+        textDocument: TextDocumentIdentifier(uri: uri),
         position: pos,
       ),
     );
@@ -1747,6 +1771,14 @@
   Range rangeOfString(String content, String searchText) =>
       rangeOfPattern(content, searchText);
 
+  /// Returns a [Range] that covers the entire of [content].
+  Range rangeOfWholeContent(String content) {
+    return Range(
+      start: positionFromOffset(0, content),
+      end: positionFromOffset(content.length, content),
+    );
+  }
+
   /// Returns all ranges surrounded by `[[markers]]` in the provided string,
   /// excluding the markers themselves (as well as position markers `^` from
   /// the offsets).
@@ -1887,7 +1919,7 @@
 
   WorkspaceFolder toWorkspaceFolder(Uri uri) {
     return WorkspaceFolder(
-      uri: uri.toString(),
+      uri: uri,
       name: path.basename(uri.path),
     );
   }
@@ -1959,7 +1991,7 @@
         closingLabelsParams = PublishClosingLabelsParams.fromJson(
             message.params as Map<String, Object?>);
 
-        return closingLabelsParams.uri == uri.toString();
+        return closingLabelsParams.uri == uri;
       }
       return false;
     });
@@ -1974,7 +2006,7 @@
           message.method == Method.textDocument_publishDiagnostics) {
         diagnosticParams = PublishDiagnosticsParams.fromJson(
             message.params as Map<String, Object?>);
-        return diagnosticParams!.uri == uri.toString();
+        return diagnosticParams!.uri == uri;
       }
       return false;
     }, orElse: () => null);
@@ -1989,7 +2021,7 @@
         outlineParams = PublishFlutterOutlineParams.fromJson(
             message.params as Map<String, Object?>);
 
-        return outlineParams.uri == uri.toString();
+        return outlineParams.uri == uri;
       }
       return false;
     });
@@ -2004,7 +2036,7 @@
         outlineParams = PublishOutlineParams.fromJson(
             message.params as Map<String, Object?>);
 
-        return outlineParams.uri == uri.toString();
+        return outlineParams.uri == uri;
       }
       return false;
     });
diff --git a/pkg/analysis_server/test/lsp/server_test.dart b/pkg/analysis_server/test/lsp/server_test.dart
index 8bcb631..949386c 100644
--- a/pkg/analysis_server/test/lsp/server_test.dart
+++ b/pkg/analysis_server/test/lsp/server_test.dart
@@ -86,8 +86,10 @@
   Future<void> test_path_invalidFormat() async {
     await initialize();
     await expectLater(
-      // Add some invalid path characters to the end of a valid file:// URI.
-      formatDocument(mainFileUri.toString() + r'***###\\\///:::.dart'),
+      formatDocument(
+        // Add some invalid path characters to the end of a valid file:// URI.
+        Uri.parse(mainFileUri.toString() + r'###***\\\///:::.dart'),
+      ),
       throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
           message: 'File URI did not contain a valid file path')),
     );
diff --git a/pkg/analysis_server/test/lsp/signature_help_test.dart b/pkg/analysis_server/test/lsp/signature_help_test.dart
index f7559fe..8f28ac8 100644
--- a/pkg/analysis_server/test/lsp/signature_help_test.dart
+++ b/pkg/analysis_server/test/lsp/signature_help_test.dart
@@ -410,6 +410,31 @@
     );
   }
 
+  Future<void> test_params_recordType() async {
+    final content = '''
+/// Does something.
+void f((String, int) r) {
+  f(^);
+}
+''';
+
+    final expectedLabel = 'f((String, int) r)';
+    final expectedDoc = 'Does something.';
+
+    await initialize(
+        textDocumentCapabilities: withSignatureHelpContentFormat(
+            emptyTextDocumentClientCapabilities, [MarkupKind.Markdown]));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await testSignature(
+      content,
+      expectedLabel,
+      expectedDoc,
+      [
+        ParameterInformation(label: '(String, int) r'),
+      ],
+    );
+  }
+
   Future<void> test_params_requiredNamed() async {
     // This test requires support for the "required" keyword.
     final content = '''
diff --git a/pkg/analysis_server/test/lsp/super_test.dart b/pkg/analysis_server/test/lsp/super_test.dart
index e0609c4..36efbd4 100644
--- a/pkg/analysis_server/test/lsp/super_test.dart
+++ b/pkg/analysis_server/test/lsp/super_test.dart
@@ -31,10 +31,8 @@
       positionFromMarker(content),
     );
 
-    expect(
-        res,
-        equals(Location(
-            uri: mainFileUri.toString(), range: rangeFromMarkers(content))));
+    expect(res,
+        equals(Location(uri: mainFileUri, range: rangeFromMarkers(content))));
   }
 
   Future<void> test_insideClass() async {
@@ -54,10 +52,8 @@
       positionFromMarker(content),
     );
 
-    expect(
-        res,
-        equals(Location(
-            uri: mainFileUri.toString(), range: rangeFromMarkers(content))));
+    expect(res,
+        equals(Location(uri: mainFileUri, range: rangeFromMarkers(content))));
   }
 
   Future<void> test_insideMethod() async {
@@ -82,10 +78,8 @@
       positionFromMarker(content),
     );
 
-    expect(
-        res,
-        equals(Location(
-            uri: mainFileUri.toString(), range: rangeFromMarkers(content))));
+    expect(res,
+        equals(Location(uri: mainFileUri, range: rangeFromMarkers(content))));
   }
 
   Future<void> test_methodName() async {
@@ -110,10 +104,60 @@
       positionFromMarker(content),
     );
 
-    expect(
-        res,
-        equals(Location(
-            uri: mainFileUri.toString(), range: rangeFromMarkers(content))));
+    expect(res,
+        equals(Location(uri: mainFileUri, range: rangeFromMarkers(content))));
+  }
+
+  Future<void> test_methodName_startOfParameterList() async {
+    final content = '''
+class A {
+  void [[foo]]() {}
+}
+
+class B extends A {}
+
+class C extends B {
+  @override
+  void foo^() {
+    // fooC
+  }
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getSuper(
+      mainFileUri,
+      positionFromMarker(content),
+    );
+
+    expect(res,
+        equals(Location(uri: mainFileUri, range: rangeFromMarkers(content))));
+  }
+
+  Future<void> test_methodName_startOfTypeParameterList() async {
+    final content = '''
+class A {
+  void [[foo]]<T>() {}
+}
+
+class B extends A {}
+
+class C extends B {
+  @override
+  void foo^<T>() {
+    // fooC
+  }
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getSuper(
+      mainFileUri,
+      positionFromMarker(content),
+    );
+
+    expect(res,
+        equals(Location(uri: mainFileUri, range: rangeFromMarkers(content))));
   }
 
   Future<void> test_methodReturnType() async {
@@ -138,9 +182,7 @@
       positionFromMarker(content),
     );
 
-    expect(
-        res,
-        equals(Location(
-            uri: mainFileUri.toString(), range: rangeFromMarkers(content))));
+    expect(res,
+        equals(Location(uri: mainFileUri, range: rangeFromMarkers(content))));
   }
 }
diff --git a/pkg/analysis_server/test/lsp/test_all.dart b/pkg/analysis_server/test/lsp/test_all.dart
index 9bf0972..8b9ee4a 100644
--- a/pkg/analysis_server/test/lsp/test_all.dart
+++ b/pkg/analysis_server/test/lsp/test_all.dart
@@ -31,6 +31,7 @@
 import 'hover_test.dart' as hover;
 import 'implementation_test.dart' as implementation;
 import 'initialization_test.dart' as initialization;
+import 'inlay_hint_test.dart' as inlay_hint;
 import 'mapping_test.dart' as mapping;
 import 'outline_test.dart' as outline;
 import 'priority_files_test.dart' as priority_files;
@@ -77,6 +78,7 @@
     hover.main();
     implementation.main();
     initialization.main();
+    inlay_hint.main();
     lsp_packet_transformer.main();
     mapping.main();
     outline.main();
diff --git a/pkg/analysis_server/test/lsp/type_definition_test.dart b/pkg/analysis_server/test/lsp/type_definition_test.dart
index b363207..61ca506 100644
--- a/pkg/analysis_server/test/lsp/type_definition_test.dart
+++ b/pkg/analysis_server/test/lsp/type_definition_test.dart
@@ -33,7 +33,7 @@
     final originRange = ranges[1];
     final result = await _getResult(contents);
     expect(result.originSelectionRange, originRange);
-    expect(result.targetUri, mainFileUri.toString());
+    expect(result.targetUri, mainFileUri);
     expect(result.targetSelectionRange, targetRange);
     expect(result.targetRange, rangeOfString(contents, 'class A {}'));
   }
@@ -83,7 +83,7 @@
 ''';
 
     final result = await _getLocationResult(contents);
-    expect(result.uri, '$sdkCoreUri');
+    expect(result.uri, sdkCoreUri);
     _expectNameRange(result.range, 'String');
   }
 
@@ -115,7 +115,7 @@
     newFile(otherFilePath, withoutMarkers(otherContents));
     final result = await _getResult(contents);
     expect(result.originSelectionRange, rangeFromMarkers(contents));
-    expect(result.targetUri, otherFileUri.toString());
+    expect(result.targetUri, otherFileUri);
     expect(result.targetSelectionRange, rangeFromMarkers(otherContents));
     expect(result.targetRange, rangeOfString(otherContents, 'class A {}'));
   }
@@ -269,7 +269,7 @@
   /// This is used for SDK sources where the exact location is not known to the
   /// test.
   void _expectSdkCoreType(LocationLink result, String typeName) {
-    expect(result.targetUri, '$sdkCoreUri');
+    expect(result.targetUri, sdkCoreUri);
     _expectNameRange(result.targetSelectionRange, typeName);
     _expectCodeRange(result.targetRange);
   }
diff --git a/pkg/analysis_server/test/lsp/workspace_symbols_test.dart b/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
index 1bda682..9b35bad 100644
--- a/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
+++ b/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
@@ -91,7 +91,7 @@
     final topLevel = symbols.firstWhere((s) => s.name == 'topLevel');
     expect(topLevel.kind, equals(SymbolKind.Variable));
     expect(topLevel.containerName, isNull);
-    expect(topLevel.location.uri, equals(mainFileUri.toString()));
+    expect(topLevel.location.uri, equals(mainFileUri));
     expect(topLevel.location.range, equals(rangeFromMarkers(content)));
 
     // Ensure we didn't get some things that definitely do not match.
@@ -117,7 +117,7 @@
     final field = symbols.firstWhere((s) => s.name == 'myField');
     expect(field.kind, equals(SymbolKind.Field));
     expect(field.containerName, equals('MyClass'));
-    expect(field.location.uri, equals(mainFileUri.toString()));
+    expect(field.location.uri, equals(mainFileUri));
     expect(field.location.range, equals(rangeFromMarkers(content)));
 
     // Ensure we didn't get some things that definitely do not match.
@@ -147,6 +147,29 @@
     );
   }
 
+  /// Ensure that multiple projects/drivers do not result in duplicate results
+  /// for things referenced in both projects.
+  Future<void> test_overlappingDrivers() async {
+    // Reference an SDK lib.
+    const content = "import 'dart:core';";
+    // Project 1
+    newFile(mainFilePath, content);
+    // Project 2
+    final otherFilePath = convertPath('/home/otherProject/foo.dart');
+    newFile(otherFilePath, content);
+
+    // Initialize with both projects as roots.
+    await initialize(workspaceFolders: [
+      projectFolderUri,
+      Uri.file(convertPath('/home/otherProject')),
+    ]);
+
+    // Search for something in the SDK that's referenced by both projects and
+    // expect it only shows up once.
+    final symbols = await getWorkspaceSymbols('Duration');
+    expect(symbols.where((s) => s.name == 'Duration'), hasLength(1));
+  }
+
   Future<void> test_partialMatch() async {
     const content = '''
     String topLevel = '';
@@ -169,25 +192,25 @@
     final field = symbols.firstWhere((s) => s.name == 'myField');
     expect(field.kind, equals(SymbolKind.Field));
     expect(field.containerName, equals('MyClass'));
-    expect(field.location.uri, equals(mainFileUri.toString()));
+    expect(field.location.uri, equals(mainFileUri));
     expect(field.location.range, equals(fieldRange));
 
     final klass = symbols.firstWhere((s) => s.name == 'MyClass');
     expect(klass.kind, equals(SymbolKind.Class));
     expect(klass.containerName, isNull);
-    expect(klass.location.uri, equals(mainFileUri.toString()));
+    expect(klass.location.uri, equals(mainFileUri));
 
     final method = symbols.firstWhere((s) => s.name == 'myMethod()');
     expect(method.kind, equals(SymbolKind.Method));
     expect(method.containerName, equals('MyClass'));
-    expect(method.location.uri, equals(mainFileUri.toString()));
+    expect(method.location.uri, equals(mainFileUri));
     expect(method.location.range, equals(methodRange));
 
     final methodWithArgs =
         symbols.firstWhere((s) => s.name == 'myMethodWithArgs(…)');
     expect(methodWithArgs.kind, equals(SymbolKind.Method));
     expect(methodWithArgs.containerName, equals('MyClass'));
-    expect(methodWithArgs.location.uri, equals(mainFileUri.toString()));
+    expect(methodWithArgs.location.uri, equals(mainFileUri));
     expect(methodWithArgs.location.range, equals(methodWithArgsRange));
 
     // Ensure we didn't get some things that definitely do not match.
diff --git a/pkg/analysis_server/test/mock_packages/flutter/lib/src/widgets/basic.dart b/pkg/analysis_server/test/mock_packages/flutter/lib/src/widgets/basic.dart
index 83eb5d0..39313bd 100644
--- a/pkg/analysis_server/test/mock_packages/flutter/lib/src/widgets/basic.dart
+++ b/pkg/analysis_server/test/mock_packages/flutter/lib/src/widgets/basic.dart
@@ -162,7 +162,8 @@
 
 typedef WidgetBuilder = Widget Function(BuildContext context);
 
-class Builder {
+class Builder extends StatelessWidget {
   final WidgetBuilder builder;
+
   const Builder({Key? key, @required this.builder});
 }
diff --git a/pkg/analysis_server/test/search/declarations_test.dart b/pkg/analysis_server/test/search/declarations_test.dart
index faf5df9..25ecaaf 100644
--- a/pkg/analysis_server/test/search/declarations_test.dart
+++ b/pkg/analysis_server/test/search/declarations_test.dart
@@ -177,6 +177,30 @@
     expect(declaration.parameters, '(bool a, String b)');
   }
 
+  /// Elements in part files should return paths of the definitions, not the
+  /// parent library.
+  Future<void> test_parts() async {
+    var a = newFile('$testPackageLibPath/a.dart', "part 'b.dart';").path;
+    var b = newFile('$testPackageLibPath/b.dart', '''
+part of 'a.dart';
+class A {}
+''').path;
+
+    await _getDeclarations(pattern: 'A');
+
+    expect(declarationsResult.files, isNot(contains(a)));
+    expect(declarationsResult.files, contains(b));
+
+    var declaration =
+        declarationsResult.declarations.singleWhere((d) => d.name == 'A');
+    expect(declaration.name, 'A');
+    expect(declaration.kind, ElementKind.CLASS);
+    expect(declarationsResult.files[declaration.fileIndex], b);
+    expect(declaration.offset, 24);
+    expect(declaration.line, 2);
+    expect(declaration.column, 7);
+  }
+
   Future<void> test_regExp() async {
     addTestFile(r'''
 class A {}
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 e764ec3..c443939 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
@@ -2,37 +2,41 @@
 // 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/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analyzer_utilities/check/check.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../client/completion_driver_test.dart';
 import 'completion_check.dart';
-import 'completion_contributor_util.dart';
+import 'completion_printer.dart' as printer;
 
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ArgListContributorTest);
+    defineReflectiveTests(ArgumentListContributorNamedTest);
   });
 }
 
-mixin ArgListContributorMixin on DartCompletionContributorTest {
-  @override
-  DartCompletionContributor createContributor(
-    DartCompletionRequest request,
-    SuggestionBuilder builder,
-  ) {
-    return ArgListContributor(request, builder);
-  }
-}
-
 @reflectiveTest
-class ArgListContributorTest extends DartCompletionContributorTest
-    with ArgListContributorMixin {
+class ArgListContributorTest extends AbstractCompletionDriverTest {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        return true;
+      },
+    );
+  }
+
   Future<void> test_fieldFormal_documentation() async {
-    var content = '''
+    printerConfiguration
+      ..withDocumentation = true
+      ..withElement = true;
+
+    final response = await getTestCodeSuggestions('''
 class A {
   /// aaa
   ///
@@ -44,24 +48,26 @@
 void f() {
   new A(^);
 }
-''';
-    addTestSource(content);
+''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).matchesInAnyOrder([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('fff: ')
-        ..docComplete.isEqualTo('aaa\n\nbbb\nccc')
-        ..docSummary.isEqualTo('aaa')
-        ..hasSelection(offset: 5)
-        ..element.isNotNull.which((e) => e
-          ..kind.isParameter
-          ..name.isEqualTo('fff'))
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  |fff: |
+    kind: namedArgument
+    docComplete: aaa\n\nbbb\nccc
+    docSummary: aaa
+    element
+      name: fff
+      kind: parameter
+''');
   }
 
   Future<void> test_fieldFormal_noDocumentation() async {
-    addTestSource('''
+    printerConfiguration
+      ..withDocumentation = true
+      ..withElement = true;
+
+    final response = await getTestCodeSuggestions('''
 class A {
   int fff;
   A({this.fff});
@@ -71,23 +77,20 @@
 }
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).matchesInAnyOrder([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('fff: ')
-        ..docComplete.isNull
-        ..docSummary.isNull
-        ..hasSelection(offset: 5)
-        ..element.isNotNull.which((e) => e
-          ..kind.isParameter
-          ..name.isEqualTo('fff'))
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  |fff: |
+    kind: namedArgument
+    element
+      name: fff
+      kind: parameter
+''');
   }
 
   Future<void> test_flutter_InstanceCreationExpression_0() async {
     writeTestPackageConfig(flutter: true);
 
-    addTestSource('''
+    final response = await getTestCodeSuggestions('''
 import 'package:flutter/widgets.dart';
 
 build() => new Row(
@@ -95,41 +98,47 @@
   );
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).containsMatch((suggestion) {
-      suggestion
-        ..completion.isEqualTo('children: [],')
-        ..defaultArgumentListString.isNull
-        ..hasSelection(offset: 11);
-    });
+    printerConfiguration.filter = (suggestion) {
+      return suggestion.completion.startsWith('children');
+    };
+
+    assertResponseText(response, r'''
+suggestions
+  children: [],
+    kind: namedArgument
+    selection: 11
+''');
   }
 
   Future<void> test_flutter_InstanceCreationExpression_01() async {
     writeTestPackageConfig(flutter: true);
 
-    addTestSource('''
+    final response = await getTestCodeSuggestions('''
 import 'package:flutter/material.dart';
 
-  build() => new Scaffold(
-        appBar: new AppBar(
-          ^
-        ),
-  );
+build() => new Scaffold(
+      appBar: new AppBar(
+        ^
+      ),
+);
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).containsMatch((suggestion) {
-      suggestion
-        ..completion.isEqualTo('backgroundColor: ,')
-        ..defaultArgumentListString.isNull
-        ..hasSelection(offset: 17);
-    });
+    printerConfiguration.filter = (suggestion) {
+      return suggestion.completion.startsWith('backgroundColor');
+    };
+
+    assertResponseText(response, r'''
+suggestions
+  backgroundColor: ,
+    kind: namedArgument
+    selection: 17
+''');
   }
 
   Future<void> test_flutter_InstanceCreationExpression_1() async {
     writeTestPackageConfig(flutter: true);
 
-    addTestSource('''
+    final response = await getTestCodeSuggestions('''
 import 'package:flutter/material.dart';
 
 build() => new Row(
@@ -138,19 +147,22 @@
   );
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).containsMatch((suggestion) {
-      suggestion
-        ..completion.isEqualTo('children: [],')
-        ..defaultArgumentListString.isNull
-        ..hasSelection(offset: 11);
-    });
+    printerConfiguration.filter = (suggestion) {
+      return suggestion.completion.startsWith('children');
+    };
+
+    assertResponseText(response, r'''
+suggestions
+  children: [],
+    kind: namedArgument
+    selection: 11
+''');
   }
 
   Future<void> test_flutter_InstanceCreationExpression_2() async {
     writeTestPackageConfig(flutter: true);
 
-    addTestSource('''
+    final response = await getTestCodeSuggestions('''
 import 'package:flutter/material.dart';
 
 build() => new Row(
@@ -159,20 +171,23 @@
   );
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).containsMatch((suggestion) {
-      suggestion
-        ..completion.isEqualTo('children: [],')
-        ..defaultArgumentListString.isNull
-        ..hasSelection(offset: 11);
-    });
+    printerConfiguration.filter = (suggestion) {
+      return suggestion.completion.startsWith('children');
+    };
+
+    assertResponseText(response, r'''
+suggestions
+  children: [],
+    kind: namedArgument
+    selection: 11
+''');
   }
 
   Future<void> test_flutter_InstanceCreationExpression_3() async {
     // Ensure a trailing comma is not added when only replacing the name.
     writeTestPackageConfig(flutter: true);
 
-    addTestSource('''
+    final response = await getTestCodeSuggestions('''
 import 'package:flutter/material.dart';
 
 build() => new Row(
@@ -180,13 +195,17 @@
   );
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).containsMatch((suggestion) {
-      suggestion
-        ..completion.isEqualTo('key')
-        ..defaultArgumentListString.isNull
-        ..hasSelection(offset: 3);
-    });
+    printerConfiguration.filter = (suggestion) {
+      return suggestion.completion.startsWith('key');
+    };
+
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  key
+    kind: namedArgument
+''');
   }
 
   Future<void>
@@ -195,7 +214,7 @@
     // type it's children.
     writeTestPackageConfig(flutter: true);
 
-    addTestSource('''
+    final response = await getTestCodeSuggestions('''
 import 'package:flutter/material.dart';
 
 build() => new Container(
@@ -207,13 +226,12 @@
 }
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).matchesInAnyOrder([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('children: [],')
-        ..defaultArgumentListString.isNull
-        ..hasSelection(offset: 11),
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  children: [],
+    kind: namedArgument
+    selection: 11
+''');
   }
 
   Future<void>
@@ -221,7 +239,7 @@
     // Ensure we don't include list markers if there's already a value.
     writeTestPackageConfig(flutter: true);
 
-    addTestSource('''
+    final response = await getTestCodeSuggestions('''
 import 'package:flutter/material.dart';
 
 build() => new Row(
@@ -229,20 +247,20 @@
   );
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).containsMatch(
-      (suggestion) => suggestion
-        ..completion.isEqualTo('children')
-        ..defaultArgumentListString.isNull
-        ..hasSelection(offset: 8),
-    );
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  children
+    kind: namedArgument
+''');
   }
 
   Future<void> test_flutter_InstanceCreationExpression_children_Map() async {
     // Ensure we don't generate Map params for a future API
     writeTestPackageConfig(flutter: true);
 
-    addTestSource('''
+    final response = await getTestCodeSuggestions('''
 import 'package:flutter/material.dart';
 
 build() => new Container(
@@ -254,19 +272,18 @@
 }
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).matchesInAnyOrder([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('children: ,')
-        ..defaultArgumentListString.isNull
-        ..hasSelection(offset: 10),
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  children: ,
+    kind: namedArgument
+    selection: 10
+''');
   }
 
   Future<void> test_flutter_InstanceCreationExpression_slivers() async {
     writeTestPackageConfig(flutter: true);
 
-    addTestSource('''
+    final response = await getTestCodeSuggestions('''
 import 'package:flutter/material.dart';
 
 build() => new CustomScrollView(
@@ -278,13 +295,12 @@
 }
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).matchesInAnyOrder([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('slivers: [],')
-        ..defaultArgumentListString.isNull
-        ..hasSelection(offset: 10),
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  slivers: [],
+    kind: namedArgument
+    selection: 10
+''');
   }
 
   Future<void> test_flutter_MethodExpression_children() async {
@@ -294,7 +310,7 @@
     // the 'material' library). Determine whether the test is still valid.
     writeTestPackageConfig(flutter: true);
 
-    addTestSource('''
+    final response = await getTestCodeSuggestions('''
 import 'package:flutter/material.dart';
 
 void f() {
@@ -304,234 +320,218 @@
 foo({String children}) {}
 ''');
 
-    var response = await computeSuggestions2();
-    _checkNamedArguments(response).matchesInAnyOrder([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('children: ')
-        ..defaultArgumentListString.isNull
-        ..defaultArgumentListTextRanges.isNull,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  |children: |
+    kind: namedArgument
+''');
+  }
+}
+
+@reflectiveTest
+class ArgumentListContributorNamedTest extends AbstractCompletionDriverTest {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        return suggestion.completion.startsWith('foo0');
+      },
+      withKind: false,
+    );
   }
 
   Future<void> test_named_01() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
+      parameters: '({int? foo01, int? foo02})',
       arguments: '(^)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-          (suggestion) => suggestion
-            ..completion.isEqualTo('two: ')
-            ..parameterType.isEqualTo('int')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+suggestions
+  |foo01: |
+  |foo02: |
+''');
       },
     );
   }
 
   Future<void> test_named_02() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(o^)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(foo0^)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasReplacement(left: 1)
-            ..hasSelection(offset: 5),
-          (suggestion) => suggestion
-            ..completion.isEqualTo('two: ')
-            ..parameterType.isEqualTo('int')
-            ..hasReplacement(left: 1)
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  |foo01: |
+  |foo02: |
+''');
       },
     );
   }
 
   Future<void> test_named_03() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(o^ two: 2)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(f^ foo02: 2)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ,')
-            ..parameterType.isEqualTo('bool')
-            ..hasReplacement(left: 1)
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 1
+suggestions
+  foo01: ,
+    selection: 7
+''');
       },
     );
   }
 
   Future<void> test_named_04() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(o^, two: 2)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(f^, foo02: 2)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasReplacement(left: 1)
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 1
+suggestions
+  |foo01: |
+''');
       },
     );
   }
 
   Future<void> test_named_05() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(o^ , two: 2)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(f^ , foo02: 2)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasReplacement(left: 1)
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 1
+suggestions
+  |foo01: |
+''');
       },
     );
   }
 
   Future<void> test_named_06() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(^o,)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(^f,)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-          (suggestion) => suggestion
-            ..completion.isEqualTo('two: ')
-            ..parameterType.isEqualTo('int')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  right: 1
+suggestions
+  |foo01: |
+  |foo02: |
+''');
       },
     );
   }
 
   Future<void> test_named_07() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(^ two: 2)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(^ foo02: 2)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ,')
-            ..parameterType.isEqualTo('bool')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+suggestions
+  foo01: ,
+    selection: 7
+''');
       },
     );
   }
 
   Future<void> test_named_08() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(^two: 2)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(^foo02: 2)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ,')
-            ..parameterType.isEqualTo('bool')
-            ..hasReplacement(right: 3)
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  right: 5
+suggestions
+  foo01: ,
+    selection: 7
+''');
       },
     );
   }
 
   Future<void> test_named_09() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(^, two: 2)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(^, foo02: 2)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+suggestions
+  |foo01: |
+''');
       },
     );
   }
 
   Future<void> test_named_10() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(^ , two: 2)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(^ , foo02: 2)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+suggestions
+  |foo01: |
+''');
       },
     );
   }
 
   Future<void> test_named_11() async {
     await _tryParametersArguments(
-      parameters: '(int one, {bool two, int three})',
-      arguments: '(1, ^, three: 3)',
+      parameters: '(int foo01, {int? foo02, int? foo03})',
+      arguments: '(1, ^, foo03: 3)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('two: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+suggestions
+  |foo02: |
+''');
       },
     );
   }
 
   Future<void> test_named_12() async {
     await _tryParametersArguments(
-      parameters: '(int one, {bool two, int three})',
-      arguments: '(1, ^ three: 3)',
+      parameters: '(int foo01, {int? foo02, int? foo03})',
+      arguments: '(1, ^ foo03: 3)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('two: ,')
-            ..parameterType.isEqualTo('bool')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+suggestions
+  foo02: ,
+    selection: 7
+''');
       },
     );
   }
 
   Future<void> test_named_13() async {
     await _tryParametersArguments(
-      parameters: '(int one, {bool two, int three})',
-      arguments: '(1, ^three: 3)',
+      parameters: '(int foo01, {int? foo02, int? foo03})',
+      arguments: '(1, ^foo03: 3)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('two: ,')
-            ..parameterType.isEqualTo('bool')
-            ..hasReplacement(right: 5)
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  right: 5
+suggestions
+  foo02: ,
+    selection: 7
+''');
       },
     );
   }
@@ -539,10 +539,15 @@
   @failingTest
   Future<void> test_named_14() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(two: 2^)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(foo02: 2^)',
       check: (response) {
-        _checkNamedArguments(response).isEmpty;
+        assertResponseText(
+            response,
+            r'''
+suggestions
+''',
+            printIfFailed: false);
       },
     );
   }
@@ -550,79 +555,73 @@
   @failingTest
   Future<void> test_named_15() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(two: 2 ^)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(foo02: 2 ^)',
       check: (response) {
-        _checkNamedArguments(response).isEmpty;
+        assertResponseText(
+            response,
+            r'''
+suggestions
+  |, foo01: |
+''',
+            printIfFailed: false);
       },
     );
   }
 
   Future<void> test_named_16() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(two: 2, ^)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(foo02: 2, ^)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+suggestions
+  |foo01: |
+''');
       },
     );
   }
 
   Future<void> test_named_17() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(two: 2, o^)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(foo02: 2, f^)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasReplacement(left: 1)
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 1
+suggestions
+  |foo01: |
+''');
       },
     );
   }
 
   Future<void> test_named_18() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(two: 2, o^,)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(foo02: 2, f^,)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one: ')
-            ..parameterType.isEqualTo('bool')
-            ..hasReplacement(left: 1)
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 1
+suggestions
+  |foo01: |
+''');
       },
     );
   }
 
   Future<void> test_named_19() async {
     await _tryParametersArguments(
-      parameters: '(int one, int two, int three, {int four, int five})',
+      parameters: '(int foo01, int foo02, int foo03, {int? foo04, int? foo05})',
       arguments: '(1, ^, 3)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('four: ')
-            ..parameterType.isEqualTo('int')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 6),
-          (suggestion) => suggestion
-            ..completion.isEqualTo('five: ')
-            ..parameterType.isEqualTo('int')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 6),
-        ]);
+        assertResponseText(response, r'''
+suggestions
+  |foo04: |
+  |foo05: |
+''');
       },
     );
   }
@@ -630,99 +629,88 @@
   Future<void> test_named_20() async {
     await _tryParametersArguments(
       languageVersion: '2.15',
-      parameters: '(int one, int two, int three, {int four, int five})',
+      parameters: '(int foo01, int foo02, int foo03, {int? foo04, int? foo05})',
       arguments: '(1, ^, 3)',
       check: (response) {
-        _checkNamedArguments(response).isEmpty;
+        assertResponseText(response, r'''
+suggestions
+''');
       },
     );
   }
 
   Future<void> test_named_21() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(o^: false)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(f^: 0)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('one')
-            ..parameterType.isEqualTo('bool')
-            ..hasReplacement(left: 1)
-            ..hasSelection(offset: 3),
-          (suggestion) => suggestion
-            ..completion.isEqualTo('two')
-            ..parameterType.isEqualTo('int')
-            ..hasReplacement(left: 1)
-            ..hasSelection(offset: 3),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 1
+suggestions
+  foo01
+  foo02
+''');
       },
     );
   }
 
   Future<void> test_named_22() async {
     await _tryParametersArguments(
-      parameters: '(bool one, {int two, double three})',
-      arguments: '(false, ^t: 2)',
+      parameters: '(bool foo01, {int? foo02, int? foo03})',
+      arguments: '(false, ^f: 2)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('two: ,')
-            ..parameterType.isEqualTo('int')
-            ..hasReplacement(right: 1)
-            ..hasSelection(offset: 5),
-          (suggestion) => suggestion
-            ..completion.isEqualTo('three: ,')
-            ..parameterType.isEqualTo('double')
-            ..hasReplacement(right: 1)
-            ..hasSelection(offset: 7),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  right: 1
+suggestions
+  foo02: ,
+    selection: 7
+  foo03: ,
+    selection: 7
+''');
       },
     );
   }
 
   Future<void> test_named_23() async {
     await _tryParametersArguments(
-      parameters: '(bool one, {int two})',
-      arguments: '(false, foo^ba: 2)',
+      parameters: '(int foo01, {int? foo02})',
+      arguments: '(0, foo^ba: 2)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('two')
-            ..parameterType.isEqualTo('int')
-            ..hasReplacement(left: 3, right: 2)
-            ..hasSelection(offset: 3),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 3
+  right: 2
+suggestions
+  foo02
+''');
       },
     );
   }
 
   Future<void> test_named_24() async {
     await _tryParametersArguments(
-      parameters: '(bool one, {int two, double three})',
-      arguments: '(false, ^: 2)',
+      parameters: '(bool foo01, {int? foo02, int? foo03})',
+      arguments: '(0, ^: 2)',
       check: (response) {
-        _checkNamedArguments(response).matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('two')
-            ..parameterType.isEqualTo('int')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 3),
-          (suggestion) => suggestion
-            ..completion.isEqualTo('three')
-            ..parameterType.isEqualTo('double')
-            ..hasEmptyReplacement()
-            ..hasSelection(offset: 5),
-        ]);
+        assertResponseText(response, r'''
+suggestions
+  foo02
+  foo03
+''');
       },
     );
   }
 
   Future<void> test_named_25() async {
     await _tryParametersArguments(
-      parameters: '({bool one, int two})',
-      arguments: '(one: ^)',
+      parameters: '({int? foo01, int? foo02})',
+      arguments: '(foo01: ^)',
       check: (response) {
-        _checkNamedArguments(response).isEmpty;
+        assertResponseText(response, r'''
+suggestions
+''');
       },
     );
   }
@@ -737,13 +725,13 @@
         ? '// @dart = $languageVersion'
         : '// no language version override';
 
-    Future<void> computeAndCheck() async {
-      var response = await computeSuggestions2();
+    Future<void> computeAndCheck(String code) async {
+      final response = await getTestCodeSuggestions(code);
       check(response);
     }
 
     // Annotation, local class.
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 class A {
   const A$parameters;
@@ -751,7 +739,6 @@
 @A$arguments
 void f() {}
 ''');
-    await computeAndCheck();
 
     // Annotation, imported class.
     newFile('$testPackageLibPath/a.dart', '''
@@ -759,13 +746,12 @@
   const A$parameters;
 }
 ''');
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 import 'a.dart';
 @A$arguments
 void f() {}
 ''');
-    await computeAndCheck();
 
     // Annotation, imported class, prefixed.
     newFile('$testPackageLibPath/a.dart', '''
@@ -773,42 +759,38 @@
   const A$parameters;
 }
 ''');
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 import 'a.dart' as p;
 @p.A$arguments
 void f() {}
 ''');
-    await computeAndCheck();
 
     // Enum constant.
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 enum E {
   v$arguments;
   const E$parameters;
 }
 ''');
-    await computeAndCheck();
 
     // Function expression invocation.
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 import 'a.dart';
-void f$parameters() {}
+void f$parameters {}
 var v = (f)$arguments;
 ''');
-    await computeAndCheck();
 
     // Instance creation, local class, generative.
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 class A {
   A$parameters;
 }
 var v = A$arguments;
 ''');
-    await computeAndCheck();
 
     // Instance creation, imported class, generative.
     newFile('$testPackageLibPath/a.dart', '''
@@ -816,12 +798,11 @@
   A$parameters;
 }
 ''');
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 import 'a.dart';
 var v = A$arguments;
 ''');
-    await computeAndCheck();
 
     // Instance creation, imported class, factory.
     newFile('$testPackageLibPath/a.dart', '''
@@ -829,44 +810,40 @@
   factory A$parameters => throw 0;
 }
 ''');
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 import 'a.dart';
 var v = A$arguments;
 ''');
-    await computeAndCheck();
 
     // Method invocation, local method.
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 class A {
-  void foo$parameters() {}
+  void foo$parameters {}
 }
 var v = A().foo$arguments;
 ''');
-    await computeAndCheck();
 
     // Method invocation, local function.
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
-void f$parameters() {}
+void f$parameters {}
 var v = f$arguments;
 ''');
-    await computeAndCheck();
 
     // Method invocation, imported function.
     newFile('$testPackageLibPath/a.dart', '''
-void f$parameters() {}
+void f$parameters {}
 ''');
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 import 'a.dart';
 var v = f$arguments;
 ''');
-    await computeAndCheck();
 
     // Super constructor invocation.
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 class A {
   A$parameters;
@@ -875,31 +852,14 @@
   B() : super$arguments;
 }
 ''');
-    await computeAndCheck();
 
     // This constructor invocation.
-    addTestSource2('''
+    await computeAndCheck('''
 $languageVersionLine
 class A {
   A$parameters;
   A.named() : this$arguments;
 }
 ''');
-    await computeAndCheck();
-
-    // Invalid: getter invocation.
-    // Parameters not used. Check not used.
-    addTestSource2('''
-$languageVersionLine
-int get foo => 0;
-var v = foo$arguments;
-''');
-    await computeSuggestions();
-    assertNoSuggestions();
-  }
-
-  static CheckTarget<Iterable<CompletionSuggestionForTesting>>
-      _checkNamedArguments(CompletionResponseForTesting response) {
-    return check(response).suggestions.namedArguments;
   }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_check.dart b/pkg/analysis_server/test/services/completion/dart/completion_check.dart
index 313959e..a327485 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_check.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_check.dart
@@ -3,16 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/protocol_server.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer_utilities/check/check.dart';
-import 'package:meta/meta.dart';
-
-typedef CompletionSuggestionChecker = void Function(
-  CompletionSuggestionTarget suggestion,
-);
-
-typedef CompletionSuggestionTarget
-    = CheckTarget<CompletionSuggestionForTesting>;
 
 class CompletionResponseForTesting {
   final int requestOffset;
@@ -42,597 +32,3 @@
     );
   }
 }
-
-/// A completion suggestion with the response for context.
-class CompletionSuggestionForTesting {
-  final CompletionResponseForTesting response;
-  final CompletionSuggestion suggestion;
-
-  CompletionSuggestionForTesting({
-    required this.response,
-    required this.suggestion,
-  });
-
-  /// Return the effective replacement length.
-  int get replacementLength =>
-      suggestion.replacementLength ?? response.replacementLength;
-
-  /// Return the effective replacement offset.
-  int get replacementOffset =>
-      suggestion.replacementOffset ?? response.replacementOffset;
-
-  @override
-  String toString() => '(completion: ${suggestion.completion})';
-}
-
-extension CompletionResponseExtension
-    on CheckTarget<CompletionResponseForTesting> {
-  @useResult
-  CheckTarget<bool> get isIncomplete {
-    return nest(
-      value.isIncomplete,
-      (selected) => 'has isIncomplete ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<int> get replacementLength {
-    return nest(
-      value.replacementLength,
-      (selected) => 'has replacementLength ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<int> get replacementOffset {
-    return nest(
-      value.replacementOffset,
-      (selected) => 'has replacementOffset ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<List<CompletionSuggestionForTesting>> get suggestions {
-    var suggestions = value.suggestions.map((e) {
-      return CompletionSuggestionForTesting(
-        response: value,
-        suggestion: e,
-      );
-    }).toList();
-    return nest(
-      suggestions,
-      (selected) => 'suggestions ${valueStr(selected)}',
-    );
-  }
-
-  void assertComplete() {
-    isIncomplete.isFalse;
-  }
-
-  void assertIncomplete() {
-    isIncomplete.isTrue;
-  }
-
-  /// Check that the replacement offset is the completion request offset,
-  /// and the length of the replacement is zero.
-  void hasEmptyReplacement() {
-    hasReplacement(left: 0, right: 0);
-  }
-
-  /// Check that the replacement offset is the completion request offset
-  /// minus [left], and the length of the replacement is `left + right`.
-  void hasReplacement({int left = 0, int right = 0}) {
-    replacementOffset.isEqualTo(value.requestOffset - left);
-    replacementLength.isEqualTo(left + right);
-  }
-}
-
-extension CompletionSuggestionExtension
-    on CheckTarget<CompletionSuggestionForTesting> {
-  @useResult
-  CheckTarget<String> get completion {
-    return nest(
-      value.suggestion.completion,
-      (selected) => 'has completion ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<String?> get defaultArgumentListString {
-    return nest(
-      value.suggestion.defaultArgumentListString,
-      (selected) => 'has defaultArgumentListString ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<List<int>?> get defaultArgumentListTextRanges {
-    return nest(
-      value.suggestion.defaultArgumentListTextRanges,
-      (selected) => 'has defaultArgumentListTextRanges ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<String?> get displayText {
-    return nest(
-      value.suggestion.displayText,
-      (selected) => 'has displayText ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<String?> get docComplete {
-    return nest(
-      value.suggestion.docComplete,
-      (selected) => 'has docComplete ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<String?> get docSummary {
-    return nest(
-      value.suggestion.docSummary,
-      (selected) => 'has docSummary ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<Element?> get element {
-    return nest(
-      value.suggestion.element,
-      (selected) => 'has element ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<bool?> get hasNamedParameters {
-    return nest(
-      value.suggestion.hasNamedParameters,
-      (selected) => 'has hasNamedParameters ${valueStr(selected)}',
-    );
-  }
-
-  void get isClass {
-    kind.isIdentifier;
-    element.isNotNull.kind.isClass;
-  }
-
-  void get isConstructorInvocation {
-    kind.isInvocation;
-    element.isNotNull.kind.isConstructor;
-  }
-
-  void get isEnum {
-    kind.isIdentifier;
-    element.isNotNull.kind.isEnum;
-  }
-
-  void get isEnumConstant {
-    kind.isIdentifier;
-    element.isNotNull.kind.isEnumConstant;
-  }
-
-  void get isField {
-    kind.isIdentifier;
-    element.isNotNull.kind.isField;
-  }
-
-  void get isFunctionReference {
-    kind.isIdentifier;
-    element.isNotNull.kind.isFunction;
-  }
-
-  void get isGetter {
-    kind.isIdentifier;
-    element.isNotNull.kind.isGetter;
-  }
-
-  void get isImport {
-    kind.isImport;
-  }
-
-  void get isImportPrefix {
-    kind.isIdentifier;
-    element.isNotNull.kind.isPrefix;
-  }
-
-  void get isKeywordAny {
-    kind.isKeyword;
-  }
-
-  void get isMethodInvocation {
-    kind.isInvocation;
-    element.isNotNull.kind.isMethod;
-  }
-
-  void get isMixin {
-    kind.isIdentifier;
-    element.isNotNull.kind.isMixin;
-  }
-
-  void get isNamedArgument {
-    kind.isNamedArgument;
-    element.isNull;
-  }
-
-  @useResult
-  CheckTarget<bool?> get isNotImported {
-    return nest(
-      value.suggestion.isNotImported,
-      (selected) => 'has isNotImported ${valueStr(selected)}',
-    );
-  }
-
-  void get isParameter {
-    kind.isIdentifier;
-    element.isNotNull.kind.isParameter;
-  }
-
-  void get isSetter {
-    kind.isIdentifier;
-    element.isNotNull.kind.isSetter;
-  }
-
-  void get isStatic {
-    element.isNotNull.isStatic.isTrue;
-  }
-
-  void get isStaticField {
-    isStatic;
-    isField;
-  }
-
-  void get isStaticGetter {
-    isStatic;
-    isGetter;
-  }
-
-  void get isTopLevelVariable {
-    kind.isIdentifier;
-    element.isNotNull.kind.isTopLevelVariable;
-  }
-
-  @useResult
-  CheckTarget<CompletionSuggestionKind> get kind {
-    return nest(
-      value.suggestion.kind,
-      (selected) => 'has kind ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<String?> get libraryUri {
-    return nest(
-      value.suggestion.libraryUri,
-      (selected) => 'has libraryUri ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<String?> get libraryUriToImport {
-    return nest(
-      value.suggestion.isNotImported == true
-          ? value.suggestion.libraryUri
-          : null,
-      (selected) => 'has libraryUriToImport ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<List<String>?> get parameterNames {
-    return nest(
-      value.suggestion.parameterNames,
-      (selected) => 'has parameterNames ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<String?> get parameterType {
-    return nest(
-      value.suggestion.parameterType,
-      (selected) => 'has parameterType ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<List<String>?> get parameterTypes {
-    return nest(
-      value.suggestion.parameterTypes,
-      (selected) => 'has parameterTypes ${valueStr(selected)}',
-    );
-  }
-
-  /// Return the effective replacement length.
-  @useResult
-  CheckTarget<int> get replacementLength {
-    return nest(
-      value.replacementLength,
-      (selected) => 'has replacementLength ${valueStr(selected)}',
-    );
-  }
-
-  /// Return the effective replacement offset.
-  @useResult
-  CheckTarget<int> get replacementOffset {
-    return nest(
-      value.replacementOffset,
-      (selected) => 'has replacementOffset ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<int?> get requiredParameterCount {
-    return nest(
-      value.suggestion.requiredParameterCount,
-      (selected) => 'has requiredParameterCount ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<String?> get returnType {
-    return nest(
-      value.suggestion.returnType,
-      (selected) => 'has returnType ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<int> get selectionLength {
-    return nest(
-      value.suggestion.selectionLength,
-      (selected) => 'has selectionLength ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<int> get selectionOffset {
-    return nest(
-      value.suggestion.selectionOffset,
-      (selected) => 'has selectionOffset ${valueStr(selected)}',
-    );
-  }
-
-  /// Check that the effective replacement offset is the completion request
-  /// offset, and the length of the replacement is zero.
-  void hasEmptyReplacement() {
-    hasReplacement(left: 0, right: 0);
-  }
-
-  /// Check that the effective replacement offset is the completion request
-  /// offset minus [left], and the length of the replacement is `left + right`.
-  void hasReplacement({int left = 0, int right = 0}) {
-    replacementOffset.isEqualTo(value.response.requestOffset - left);
-    replacementLength.isEqualTo(left + right);
-  }
-
-  void hasSelection({required int offset, int length = 0}) {
-    selectionOffset.isEqualTo(offset);
-    selectionLength.isEqualTo(length);
-  }
-
-  void isKeyword(Keyword keyword) {
-    kind.isKeyword;
-    completion.isEqualTo(keyword.lexeme);
-  }
-}
-
-extension CompletionSuggestionKindExtension
-    on CheckTarget<CompletionSuggestionKind> {
-  void get isIdentifier {
-    isEqualTo(CompletionSuggestionKind.IDENTIFIER);
-  }
-
-  void get isImport {
-    isEqualTo(CompletionSuggestionKind.IMPORT);
-  }
-
-  void get isInvocation {
-    isEqualTo(CompletionSuggestionKind.INVOCATION);
-  }
-
-  void get isKeyword {
-    isEqualTo(CompletionSuggestionKind.KEYWORD);
-  }
-
-  void get isNamedArgument {
-    isEqualTo(CompletionSuggestionKind.NAMED_ARGUMENT);
-  }
-}
-
-extension CompletionSuggestionsExtension
-    on CheckTarget<Iterable<CompletionSuggestionForTesting>> {
-  @useResult
-  CheckTarget<List<String>> get completions {
-    return nest(
-      value.map((e) => e.suggestion.completion).toList(),
-      (selected) => 'completions ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<Iterable<CompletionSuggestionForTesting>> get fields {
-    var result = value
-        .where((suggestion) =>
-            suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER &&
-            suggestion.suggestion.element?.kind == ElementKind.FIELD)
-        .toList();
-    return nest(
-      result,
-      (selected) => 'fields ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<Iterable<CompletionSuggestionForTesting>> get getters {
-    var result = value
-        .where((suggestion) =>
-            suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER &&
-            suggestion.suggestion.element?.kind == ElementKind.GETTER)
-        .toList();
-    return nest(
-      result,
-      (selected) => 'getters ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<Iterable<CompletionSuggestionForTesting>> get methods {
-    var result = value
-        .where((suggestion) =>
-            suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER &&
-            suggestion.suggestion.element?.kind == ElementKind.METHOD)
-        .toList();
-    return nest(
-      result,
-      (selected) => 'setters ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<Iterable<CompletionSuggestionForTesting>> get namedArguments {
-    var result = value
-        .where((suggestion) =>
-            suggestion.suggestion.kind ==
-            CompletionSuggestionKind.NAMED_ARGUMENT)
-        .toList();
-    return nest(
-      result,
-      (selected) => 'named arguments ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<Iterable<CompletionSuggestionForTesting>> get overrides {
-    var result = value
-        .where((suggestion) =>
-            suggestion.suggestion.kind == CompletionSuggestionKind.OVERRIDE)
-        .toList();
-    return nest(
-      result,
-      (selected) => 'overrides ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<Iterable<CompletionSuggestionForTesting>> get setters {
-    var result = value
-        .where((suggestion) =>
-            suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER &&
-            suggestion.suggestion.element?.kind == ElementKind.SETTER)
-        .toList();
-    return nest(
-      result,
-      (selected) => 'setters ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<Iterable<CompletionSuggestionForTesting>> get withElementClass {
-    return nest(
-      value.where((e) {
-        return e.suggestion.element?.kind == ElementKind.CLASS;
-      }).toList(),
-      (selected) => 'withElementClass ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<Iterable<CompletionSuggestionForTesting>> get withKindKeyword {
-    var result = value
-        .where((suggestion) =>
-            suggestion.suggestion.kind == CompletionSuggestionKind.KEYWORD)
-        .toList();
-    return nest(
-      result,
-      (selected) => 'withKindKeyword ${valueStr(selected)}',
-    );
-  }
-}
-
-extension ElementExtension on CheckTarget<Element> {
-  @useResult
-  CheckTarget<bool> get isStatic {
-    return nest(
-      value.isStatic,
-      (selected) => 'isStatic ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<ElementKind> get kind {
-    return nest(
-      value.kind,
-      (selected) => 'has kind ${valueStr(selected)}',
-    );
-  }
-
-  @useResult
-  CheckTarget<String> get name {
-    return nest(
-      value.name,
-      (selected) => 'has name ${valueStr(selected)}',
-    );
-  }
-}
-
-extension ElementKindExtension on CheckTarget<ElementKind> {
-  void get isClass {
-    isEqualTo(ElementKind.CLASS);
-  }
-
-  void get isConstructor {
-    isEqualTo(ElementKind.CONSTRUCTOR);
-  }
-
-  void get isEnum {
-    isEqualTo(ElementKind.ENUM);
-  }
-
-  void get isEnumConstant {
-    isEqualTo(ElementKind.ENUM_CONSTANT);
-  }
-
-  void get isField {
-    isEqualTo(ElementKind.FIELD);
-  }
-
-  void get isFunction {
-    isEqualTo(ElementKind.FUNCTION);
-  }
-
-  void get isGetter {
-    isEqualTo(ElementKind.GETTER);
-  }
-
-  void get isMethod {
-    isEqualTo(ElementKind.METHOD);
-  }
-
-  void get isMixin {
-    isEqualTo(ElementKind.MIXIN);
-  }
-
-  void get isParameter {
-    isEqualTo(ElementKind.PARAMETER);
-  }
-
-  void get isPrefix {
-    isEqualTo(ElementKind.PREFIX);
-  }
-
-  void get isSetter {
-    isEqualTo(ElementKind.SETTER);
-  }
-
-  void get isTopLevelVariable {
-    isEqualTo(ElementKind.TOP_LEVEL_VARIABLE);
-  }
-}
-
-extension KeywordsExtension on Iterable<Keyword> {
-  List<CompletionSuggestionChecker> get asKeywordChecks {
-    return map((e) => (CompletionSuggestionTarget suggestion) =>
-        suggestion.isKeyword(e)).toList();
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_printer.dart b/pkg/analysis_server/test/services/completion/dart/completion_printer.dart
new file mode 100644
index 0000000..844282d
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/completion_printer.dart
@@ -0,0 +1,314 @@
+// Copyright (c) 2022, 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:collection/collection.dart';
+
+import 'completion_check.dart';
+
+class CompletionResponsePrinter {
+  final StringBuffer buffer;
+  final Configuration configuration;
+  final CompletionResponseForTesting response;
+
+  String _indent = '';
+
+  CompletionResponsePrinter({
+    required this.buffer,
+    required this.configuration,
+    required this.response,
+  });
+
+  void writeResponse() {
+    _writeResponseReplacement();
+    _writeSuggestions();
+  }
+
+  String _escapeMultiLine(String text) {
+    return text.replaceAll('\n', r'\n');
+  }
+
+  String _getElementKindName(ElementKind kind) {
+    if (kind == ElementKind.CLASS) {
+      return 'class';
+    } else if (kind == ElementKind.CONSTRUCTOR) {
+      return 'constructor';
+    } else if (kind == ElementKind.ENUM) {
+      return 'enum';
+    } else if (kind == ElementKind.EXTENSION) {
+      return 'extension';
+    } else if (kind == ElementKind.FIELD) {
+      return 'field';
+    } else if (kind == ElementKind.FUNCTION) {
+      return 'function';
+    } else if (kind == ElementKind.PARAMETER) {
+      return 'parameter';
+    } else if (kind == ElementKind.TOP_LEVEL_VARIABLE) {
+      return 'topLevelVariable';
+    } else if (kind == ElementKind.TYPE_ALIAS) {
+      return 'typeAlias';
+    }
+    throw UnimplementedError('kind: $kind');
+  }
+
+  String _getSuggestionKindName(CompletionSuggestion suggestion) {
+    final kind = suggestion.kind;
+    if (kind == CompletionSuggestionKind.KEYWORD) {
+      return 'keyword';
+    } else if (kind == CompletionSuggestionKind.IDENTIFIER) {
+      final elementKind = suggestion.element?.kind;
+      if (elementKind == null) {
+        return 'identifier';
+      } else if (elementKind == ElementKind.CLASS) {
+        return 'class';
+      } else if (elementKind == ElementKind.ENUM) {
+        return 'enum';
+      } else if (elementKind == ElementKind.ENUM_CONSTANT) {
+        return 'enumConstant';
+      } else if (elementKind == ElementKind.FIELD) {
+        return 'field';
+      } else if (elementKind == ElementKind.GETTER) {
+        return 'getter';
+      } else if (elementKind == ElementKind.LIBRARY) {
+        return 'library';
+      } else if (elementKind == ElementKind.PARAMETER) {
+        return 'parameter';
+      } else if (elementKind == ElementKind.SETTER) {
+        return 'setter';
+      } else if (elementKind == ElementKind.TOP_LEVEL_VARIABLE) {
+        return 'topLevelVariable';
+      } else if (elementKind == ElementKind.TYPE_ALIAS) {
+        return 'typeAlias';
+      }
+      throw UnimplementedError('elementKind: $elementKind');
+    } else if (kind == CompletionSuggestionKind.INVOCATION) {
+      final elementKind = suggestion.element?.kind;
+      if (elementKind == null) {
+        return 'invocation';
+      } else if (elementKind == ElementKind.CONSTRUCTOR) {
+        return 'constructorInvocation';
+      } else if (elementKind == ElementKind.EXTENSION) {
+        return 'extensionInvocation';
+      } else if (elementKind == ElementKind.FUNCTION) {
+        return 'functionInvocation';
+      } else if (elementKind == ElementKind.METHOD) {
+        return 'methodInvocation';
+      }
+      throw UnimplementedError('elementKind: $elementKind');
+    } else if (kind == CompletionSuggestionKind.IMPORT) {
+      return 'import';
+    } else if (kind == CompletionSuggestionKind.NAMED_ARGUMENT) {
+      return 'namedArgument';
+    } else if (kind == CompletionSuggestionKind.OVERRIDE) {
+      return 'override';
+    }
+    throw UnimplementedError('kind: $kind');
+  }
+
+  void _withIndent(void Function() f) {
+    var indent = _indent;
+    _indent = '$_indent  ';
+    f();
+    _indent = indent;
+  }
+
+  void _writeCompletion(CompletionSuggestion suggestion) {
+    final completion = suggestion.completion;
+    if (RegExp(r'^\s').hasMatch(completion) ||
+        RegExp(r'\s$').hasMatch(completion)) {
+      _writelnWithIndent('|$completion|');
+    } else {
+      _writelnWithIndent(completion);
+    }
+  }
+
+  void _writeDisplayText(CompletionSuggestion suggestion) {
+    if (configuration.withDisplayText) {
+      _writelnWithIndent('displayText: ${suggestion.displayText}');
+    }
+  }
+
+  void _writeDocumentation(CompletionSuggestion suggestion) {
+    if (configuration.withDocumentation) {
+      final docComplete = suggestion.docComplete;
+      if (docComplete != null) {
+        final text = _escapeMultiLine(docComplete);
+        _writelnWithIndent('docComplete: $text');
+      }
+
+      final docSummary = suggestion.docSummary;
+      if (docSummary != null) {
+        final text = _escapeMultiLine(docSummary);
+        _writelnWithIndent('docSummary: $text');
+      }
+    }
+  }
+
+  void _writeElement(CompletionSuggestion suggestion) {
+    if (configuration.withElement) {
+      final element = suggestion.element;
+      if (element != null) {
+        _writelnWithIndent('element');
+        _withIndent(() {
+          final kindStr = _getElementKindName(element.kind);
+          _writelnWithIndent('name: ${element.name}');
+          _writelnWithIndent('kind: $kindStr');
+        });
+      }
+    }
+  }
+
+  void _writeIsNotImported(CompletionSuggestion suggestion) {
+    if (configuration.withIsNotImported) {
+      _writelnWithIndent('isNotImported: ${suggestion.isNotImported}');
+    }
+  }
+
+  void _writeLibraryUri(CompletionSuggestion suggestion) {
+    if (configuration.withLibraryUri) {
+      _writelnWithIndent('libraryUri: ${suggestion.libraryUri}');
+    }
+  }
+
+  void _writelnWithIndent(String line) {
+    buffer.write(_indent);
+    buffer.writeln(line);
+  }
+
+  void _writeRelevance(CompletionSuggestion suggestion) {
+    if (configuration.withRelevance) {
+      _writelnWithIndent('relevance: ${suggestion.relevance}');
+    }
+  }
+
+  void _writeResponseReplacement() {
+    if (configuration.withReplacement) {
+      final offset = response.replacementOffset;
+      final length = response.replacementLength;
+      final left = response.requestOffset - offset;
+      final right = (offset + length) - response.requestOffset;
+      if (left > 0 || right > 0) {
+        _writelnWithIndent('replacement');
+        if (left > 0) {
+          _withIndent(() {
+            _writelnWithIndent('left: $left');
+          });
+        }
+        if (right > 0) {
+          _withIndent(() {
+            _writelnWithIndent('right: $right');
+          });
+        }
+      }
+    }
+  }
+
+  void _writeReturnType(CompletionSuggestion suggestion) {
+    if (configuration.withReturnType) {
+      final returnType = suggestion.returnType;
+      if (returnType != null) {
+        _writelnWithIndent('returnType: $returnType');
+      }
+    }
+  }
+
+  void _writeSelection(CompletionSuggestion suggestion) {
+    if (configuration.withSelection) {
+      final offset = suggestion.selectionOffset;
+      final length = suggestion.selectionLength;
+      if (length != 0) {
+        _writelnWithIndent('selection: $offset $length');
+      } else if (offset != suggestion.completion.length) {
+        _writelnWithIndent('selection: $offset');
+      }
+    }
+  }
+
+  void _writeSuggestion(CompletionSuggestion suggestion) {
+    _writeCompletion(suggestion);
+    _withIndent(() {
+      _writeSuggestionKind(suggestion);
+      _writeDisplayText(suggestion);
+      _writeDocumentation(suggestion);
+      _writeElement(suggestion);
+      _writeIsNotImported(suggestion);
+      _writeLibraryUri(suggestion);
+      _writeRelevance(suggestion);
+      _writeReturnType(suggestion);
+      _writeSelection(suggestion);
+    });
+  }
+
+  void _writeSuggestionKind(CompletionSuggestion suggestion) {
+    if (configuration.withKind) {
+      final kind = _getSuggestionKindName(suggestion);
+      _writelnWithIndent('kind: $kind');
+    }
+  }
+
+  void _writeSuggestions() {
+    final filtered = response.suggestions.where(configuration.filter);
+    final sorted = filtered.sorted((a, b) {
+      switch (configuration.sorting) {
+        case Sorting.asIs:
+          return 0;
+        case Sorting.completion:
+          return a.completion.compareTo(b.completion);
+        case Sorting.relevanceThenCompletion:
+          final relevanceDiff = a.relevance - b.relevance;
+          if (relevanceDiff != 0) {
+            return -relevanceDiff;
+          } else {
+            return a.completion.compareTo(b.completion);
+          }
+      }
+    });
+
+    _writelnWithIndent('suggestions');
+
+    _withIndent(() {
+      for (final suggestion in sorted) {
+        if (configuration.filter(suggestion)) {
+          _writeSuggestion(suggestion);
+        }
+      }
+    });
+  }
+}
+
+class Configuration {
+  Sorting sorting;
+  bool withDisplayText;
+  bool withDocumentation;
+  bool withElement;
+  bool withIsNotImported;
+  bool withKind;
+  bool withLibraryUri;
+  bool withRelevance;
+  bool withReplacement;
+  bool withReturnType;
+  bool withSelection;
+  bool Function(CompletionSuggestion suggestion) filter;
+
+  Configuration({
+    this.sorting = Sorting.relevanceThenCompletion,
+    this.withDisplayText = false,
+    this.withDocumentation = false,
+    this.withElement = false,
+    this.withIsNotImported = false,
+    this.withKind = true,
+    this.withLibraryUri = false,
+    this.withReplacement = true,
+    this.withRelevance = false,
+    this.withReturnType = false,
+    this.withSelection = true,
+    required this.filter,
+  });
+}
+
+enum Sorting {
+  asIs,
+  completion,
+  relevanceThenCompletion,
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/class_test.dart b/pkg/analysis_server/test/services/completion/dart/declaration/class_test.dart
index cd5382bb..6b61f8c 100644
--- a/pkg/analysis_server/test/services/completion/dart/declaration/class_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/declaration/class_test.dart
@@ -2,11 +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 'package:analyzer_utilities/check/check.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
 import '../completion_check.dart';
+import '../completion_printer.dart' as printer;
 
 void main() {
   defineReflectiveSuite(() {
@@ -20,6 +20,18 @@
   @override
   TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
 
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        final completion = suggestion.completion;
+        return completion.contains('foo0');
+      },
+    );
+  }
+
   Future<void> test_field_hasContextType_exact() async {
     await _checkLocations(
       classCode: r'''
@@ -36,9 +48,13 @@
 }
 ''',
       validator: (response) {
-        check(response).suggestions.fields.completions.matchesInAnyOrder([
-          (e) => e.isEqualTo('A.foo01'),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  A.foo01
+    kind: field
+''');
       },
     );
   }
@@ -59,11 +75,17 @@
 }
 ''',
       validator: (response) {
-        check(response).suggestions.fields.completions.matchesInAnyOrder([
-          (e) => e.isEqualTo('A.foo01'),
-          (e) => e.isEqualTo('A.foo02'),
-          (e) => e.isEqualTo('A.foo03'),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  A.foo03
+    kind: field
+  A.foo01
+    kind: field
+  A.foo02
+    kind: field
+''');
       },
     );
   }
@@ -83,7 +105,11 @@
 }
 ''',
       validator: (response) {
-        check(response).suggestions.fields.isEmpty;
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+''');
       },
     );
   }
@@ -103,9 +129,13 @@
 }
 ''',
       validator: (response) {
-        check(response).suggestions.getters.completions.matchesInAnyOrder([
-          (e) => e.isEqualTo('A.foo01'),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  A.foo01
+    kind: getter
+''');
       },
     );
   }
@@ -126,11 +156,17 @@
 }
 ''',
       validator: (response) {
-        check(response).suggestions.getters.completions.matchesInAnyOrder([
-          (e) => e.isEqualTo('A.foo01'),
-          (e) => e.isEqualTo('A.foo02'),
-          (e) => e.isEqualTo('A.foo03'),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  A.foo03
+    kind: getter
+  A.foo01
+    kind: getter
+  A.foo02
+    kind: getter
+''');
       },
     );
   }
@@ -148,7 +184,11 @@
 }
 ''',
       validator: (response) {
-        check(response).suggestions.getters.isEmpty;
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+''');
       },
     );
   }
@@ -166,7 +206,11 @@
 }
 ''',
       validator: (response) {
-        check(response).suggestions.methods.isEmpty;
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+''');
       },
     );
   }
@@ -186,7 +230,11 @@
 }
 ''',
       validator: (response) {
-        check(response).suggestions.setters.isEmpty;
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+''');
       },
     );
   }
@@ -204,7 +252,11 @@
 }
 ''',
       validator: (response) {
-        check(response).suggestions.setters.isEmpty;
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+''');
       },
     );
   }
diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart b/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart
index e15b337..f40bdf8 100644
--- a/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart
@@ -2,11 +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 'package:analyzer_utilities/check/check.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
 import '../completion_check.dart';
+import '../completion_printer.dart' as printer;
 
 void main() {
   defineReflectiveSuite(() {
@@ -28,6 +28,15 @@
 }
 
 mixin EnumTestCases on AbstractCompletionDriverTest {
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) => true,
+    );
+  }
+
   Future<void> test_enumConstantName() async {
     await _check_locations(
       declaration: '''
@@ -36,27 +45,30 @@
 ''',
       declarationForContextType: 'void useMyEnum(MyEnum _) {}',
       codeAtCompletion: 'useMyEnum(foo0^);',
-      validator: (response) {
-        check(response).hasReplacement(left: 4);
-
+      validator: (response, context) {
         if (isProtocolVersion2) {
-          check(response).suggestions.matches([
-            (suggestion) => suggestion
-              ..completion.isEqualTo('MyEnum.foo01')
-              ..isEnumConstant,
-          ]);
-          // No other suggestions.
+          assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  MyEnum.foo01
+    kind: enumConstant
+''');
         } else {
-          check(response).suggestions.includesAll([
-            (suggestion) => suggestion
-              ..completion.isEqualTo('MyEnum.foo01')
-              ..isEnumConstant,
-            // The response includes much more, such as `MyEnum` itself.
-            // We don't expect though that the client will show it.
-            (suggestion) => suggestion
-              ..completion.isEqualTo('MyEnum')
-              ..isEnum,
-          ]);
+          _configureWithMyEnum();
+          // The response includes much more, such as `MyEnum` itself.
+          // We don't expect though that the client will show it.
+          if (context == _Context.local) {
+            assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  MyEnum
+    kind: enum
+  MyEnum.foo01
+    kind: enumConstant
+''');
+          }
         }
       },
     );
@@ -82,21 +94,28 @@
 }
 ''');
 
-    check(response).hasReplacement(left: 4);
-
     if (isProtocolVersion2) {
-      check(response).suggestions.matches([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('prefix.MyEnum.foo01')
-          ..isEnumConstant,
-      ]);
+      assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  prefix.MyEnum.foo01
+    kind: enumConstant
+''');
     } else {
+      _configureWithMyEnum();
       // TODO(scheglov) This is wrong.
-      check(response).suggestions.includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('MyEnum.foo01')
-          ..isEnumConstant,
-      ]);
+      assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  MyEnum
+    kind: enum
+  MyEnum.foo01
+    kind: enumConstant
+  OtherEnum.foo02
+    kind: enumConstant
+''');
     }
   }
 
@@ -104,22 +123,41 @@
     await _check_locations(
       declaration: 'enum MyEnum { foo01 }',
       codeAtCompletion: 'MyEnu^',
-      validator: (response) {
-        check(response).hasReplacement(left: 5);
-
+      validator: (response, context) {
         if (isProtocolVersion2) {
-          check(response).suggestions.matches([
-            (suggestion) => suggestion
-              ..completion.isEqualTo('MyEnum')
-              ..isEnum,
-          ]);
           // No enum constants.
+          assertResponseText(response, r'''
+replacement
+  left: 5
+suggestions
+  MyEnum
+    kind: enum
+''');
         } else {
-          check(response).suggestions.includesAll([
-            (suggestion) => suggestion
-              ..completion.isEqualTo('MyEnum')
-              ..isEnum,
-          ]);
+          _configureWithMyEnum();
+          switch (context) {
+            case _Context.local:
+              assertResponseText(response, r'''
+replacement
+  left: 5
+suggestions
+  MyEnum
+    kind: enum
+''');
+              break;
+            case _Context.imported:
+            case _Context.notImported:
+              assertResponseText(response, r'''
+replacement
+  left: 5
+suggestions
+  MyEnum
+    kind: enum
+  MyEnum.foo01
+    kind: enumConstant
+''');
+              break;
+          }
         }
       },
     );
@@ -142,25 +180,29 @@
 }
 ''');
 
-    check(response).hasReplacement(left: 5);
-
     if (isProtocolVersion2) {
-      check(response).suggestions.matches([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('prefix.MyEnum')
-          ..isEnum,
-      ]);
+      assertResponseText(response, r'''
+replacement
+  left: 5
+suggestions
+  prefix.MyEnum
+    kind: enum
+''');
     } else {
+      _configureWithMyEnum();
       // TODO(scheglov) This is wrong.
-      check(response).suggestions.includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('MyEnum')
-          ..isEnum,
-      ]);
+      assertResponseText(response, r'''
+replacement
+  left: 5
+suggestions
+  MyEnum
+    kind: enum
+  MyEnum.foo01
+    kind: enumConstant
+''');
     }
   }
 
-  @FailingTest(reason: 'element.kind is LIBRARY')
   Future<void> test_importPrefix() async {
     newFile('$testPackageLibPath/a.dart', r'''
 enum MyEnum { v }
@@ -178,20 +220,27 @@
 }
 ''');
 
-    check(response).hasReplacement(left: 7);
-
     if (isProtocolVersion2) {
-      check(response).suggestions.matches([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('prefix01')
-          ..isImportPrefix,
-      ]);
+      // TODO(scheglov) The kind should be a prefix.
+      assertResponseText(response, r'''
+replacement
+  left: 7
+suggestions
+  prefix01
+    kind: library
+''');
     } else {
-      check(response).suggestions.includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('prefix01')
-          ..isImportPrefix,
-      ]);
+      _configureWithMyEnum();
+      // TODO(scheglov) This is wrong.
+      assertResponseText(response, r'''
+replacement
+  left: 7
+suggestions
+  MyEnum
+    kind: enum
+  MyEnum.v
+    kind: enumConstant
+''');
     }
   }
 
@@ -212,55 +261,66 @@
 }
 ''');
 
-    check(response).hasEmptyReplacement();
-
-    check(response).suggestions
-      ..includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('MyEnum')
-          ..isEnum,
-      ])
-      // TODO(scheglov) This is wrong.
-      // Should include constants, as [test_nothing_imported_withPrefix] does.
-      ..excludesAll([
-        (suggestion) => suggestion.isEnumConstant,
-      ]);
+    // TODO(scheglov) This is wrong.
+    // Should include constants, as [test_nothing_imported_withPrefix] does.
+    assertResponseText(response, r'''
+suggestions
+  MyEnum
+    kind: enum
+''');
   }
 
   Future<void> test_nothing() async {
+    _configureWithMyEnum();
+
     await _check_locations(
-      declaration: 'enum MyEnum { v }',
+      declaration: 'enum MyEnum { foo01 }',
       declarationForContextType: 'void useMyEnum(MyEnum _) {}',
       codeAtCompletion: 'useMyEnum(^);',
-      validator: (response) {
-        check(response).hasEmptyReplacement();
-
-        check(response).suggestions
-          ..includesAll([
-            (suggestion) => suggestion
-              ..completion.isEqualTo('MyEnum')
-              ..isEnum,
-            (suggestion) => suggestion
-              ..completion.isEqualTo('MyEnum.v')
-              ..isEnumConstant,
-          ])
-          ..excludesAll([
-            (suggestion) => suggestion
-              ..completion.startsWith('MyEnum')
-              ..isConstructorInvocation,
-          ]);
+      validator: (response, context) {
+        if (isProtocolVersion2) {
+          assertResponseText(response, r'''
+suggestions
+  MyEnum
+    kind: enum
+  MyEnum.foo01
+    kind: enumConstant
+''');
+        } else {
+          switch (context) {
+            case _Context.local:
+            case _Context.imported:
+              assertResponseText(response, r'''
+suggestions
+  MyEnum
+    kind: enum
+  MyEnum.foo01
+    kind: enumConstant
+''');
+              break;
+            case _Context.notImported:
+              assertResponseText(response, r'''
+suggestions
+  MyEnum
+    kind: enum
+  MyEnum.foo01
+    kind: enumConstant
+  useMyEnum
+    kind: functionInvocation
+''');
+              break;
+          }
+        }
       },
     );
   }
 
   Future<void> test_nothing_imported_withPrefix() async {
-    newFile('$testPackageLibPath/a.dart', r'''
-enum MyEnum { v }
-''');
+    _configureWithMyEnum();
 
-    if (isProtocolVersion1) {
-      await waitForSetWithUri('package:test/a.dart');
-    }
+    newFile('$testPackageLibPath/a.dart', r'''
+enum MyEnum { foo01 }
+''');
 
     var response = await getTestCodeSuggestions('''
 import 'a.dart' as prefix;
@@ -272,27 +332,23 @@
 }
 ''');
 
-    check(response).hasEmptyReplacement();
-
     if (isProtocolVersion2) {
-      check(response).suggestions.includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('prefix.MyEnum')
-          ..isEnum,
-        (suggestion) => suggestion
-          ..completion.isEqualTo('prefix.MyEnum.v')
-          ..isEnumConstant,
-      ]);
+      assertResponseText(response, r'''
+suggestions
+  prefix.MyEnum
+    kind: enum
+  prefix.MyEnum.foo01
+    kind: enumConstant
+''');
     } else {
       // TODO(scheglov) This is wrong.
-      check(response).suggestions.includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('MyEnum')
-          ..isEnum,
-        (suggestion) => suggestion
-          ..completion.isEqualTo('MyEnum.v')
-          ..isEnumConstant,
-      ]);
+      assertResponseText(response, r'''
+suggestions
+  MyEnum
+    kind: enum
+  MyEnum.foo01
+    kind: enumConstant
+''');
     }
   }
 
@@ -300,7 +356,11 @@
     required String declaration,
     String declarationForContextType = '',
     required String codeAtCompletion,
-    required void Function(CompletionResponseForTesting response) validator,
+    required void Function(
+      CompletionResponseForTesting response,
+      _Context context,
+    )
+        validator,
   }) async {
     // local
     {
@@ -311,7 +371,7 @@
   $codeAtCompletion
 }
 ''');
-      validator(response);
+      validator(response, _Context.local);
     }
 
     // imported
@@ -329,7 +389,7 @@
   $codeAtCompletion
 }
 ''');
-      validator(response);
+      validator(response, _Context.imported);
     }
 
     // not imported
@@ -350,7 +410,16 @@
   $codeAtCompletion
 }
 ''');
-      validator(response);
+      validator(response, _Context.notImported);
     }
   }
+
+  void _configureWithMyEnum() {
+    printerConfiguration.filter = (suggestion) {
+      final completion = suggestion.completion;
+      return completion.contains('MyEnum') || completion.contains('foo0');
+    };
+  }
 }
+
+enum _Context { local, imported, notImported }
diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/library_test.dart b/pkg/analysis_server/test/services/completion/dart/declaration/library_test.dart
index e5eea3f..5a763e77 100644
--- a/pkg/analysis_server/test/services/completion/dart/declaration/library_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/declaration/library_test.dart
@@ -2,11 +2,10 @@
 // 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';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
-import '../completion_check.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -23,9 +22,12 @@
 }
 ''');
 
-    check(response).suggestions.excludesAll([
-      (suggestion) => suggestion.libraryUri.isNotNull.startsWith('dart:_'),
-    ]);
+    for (final suggestion in response.suggestions) {
+      final libraryUri = suggestion.libraryUri;
+      if (libraryUri != null && libraryUri.startsWith('dart:_')) {
+        fail('Private SDK library: $libraryUri');
+      }
+    }
   }
 }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/record_type_test.dart b/pkg/analysis_server/test/services/completion/dart/declaration/record_type_test.dart
new file mode 100644
index 0000000..f215367
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/declaration/record_type_test.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import '../../../../client/completion_driver_test.dart';
+import '../completion_printer.dart' as printer;
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RecordTypeTest1);
+    defineReflectiveTests(RecordTypeTest2);
+  });
+}
+
+@reflectiveTest
+class RecordTypeTest1 extends AbstractCompletionDriverTest
+    with RecordTypeTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class RecordTypeTest2 extends AbstractCompletionDriverTest
+    with RecordTypeTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin RecordTypeTestCases on AbstractCompletionDriverTest {
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) => true,
+      withReturnType: true,
+    );
+  }
+
+  Future<void> test_mixin() async {
+    var response = await getTestCodeSuggestions('''
+void f((int, {String foo02}) r) {
+  r.^
+}
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  $0
+    kind: identifier
+    returnType: int
+  foo02
+    kind: identifier
+    returnType: String
+''');
+  }
+
+  Future<void> test_named() async {
+    var response = await getTestCodeSuggestions('''
+void f(({int foo01, String foo02}) r) {
+  r.^
+}
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  foo01
+    kind: identifier
+    returnType: int
+  foo02
+    kind: identifier
+    returnType: String
+''');
+  }
+
+  Future<void> test_positional() async {
+    var response = await getTestCodeSuggestions('''
+void f((int, String) r) {
+  r.^
+}
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  $0
+    kind: identifier
+    returnType: int
+  $1
+    kind: identifier
+    returnType: String
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart b/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart
index c74d1a0..8df10d5 100644
--- a/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart
@@ -7,6 +7,7 @@
 import 'class_test.dart' as class_;
 import 'enum_test.dart' as enum_;
 import 'library_test.dart' as library_;
+import 'record_type_test.dart' as record_type;
 
 /// Tests suggestions produced for various kinds of declarations.
 void main() {
@@ -14,5 +15,6 @@
     class_.main();
     enum_.main();
     library_.main();
+    record_type.main();
   });
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/location/block_test.dart b/pkg/analysis_server/test/services/completion/dart/location/block_test.dart
index bf80f1b..9ee6270 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/block_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/block_test.dart
@@ -2,11 +2,10 @@
 // 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_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
-import '../completion_check.dart';
+import '../completion_printer.dart' as printer;
 
 void main() {
   defineReflectiveSuite(() {
@@ -33,42 +32,45 @@
   static final spaces_8 = ' ' * 8;
 
   Future<void> test_flutter_setState_indent6_hasPrefix() async {
-    await _check_flutter_setState(
-      line: '${spaces_6}setSt^',
-      completion: '''
-setState(() {
+    await _check_flutter_setState(line: '${spaces_6}setSt^', expected: '''
+replacement
+  left: 5
+suggestions
+  setState(() {
 $spaces_8
-$spaces_6});''',
-      selectionOffset: 22,
-    );
+$spaces_6});
+    kind: invocation
+    selection: 22
+''');
   }
 
   Future<void> test_flutter_setState_indent_hasPrefix() async {
-    await _check_flutter_setState(
-      line: '${spaces_4}setSt^',
-      completion: '''
-setState(() {
+    await _check_flutter_setState(line: '${spaces_4}setSt^', expected: '''
+replacement
+  left: 5
+suggestions
+  setState(() {
 $spaces_6
-$spaces_4});''',
-      selectionOffset: 20,
-    );
+$spaces_4});
+    kind: invocation
+    selection: 20
+''');
   }
 
   Future<void> test_flutter_setState_indent_noPrefix() async {
-    await _check_flutter_setState(
-      line: '$spaces_4^',
-      completion: '''
-setState(() {
+    await _check_flutter_setState(line: '$spaces_4^', expected: '''
+suggestions
+  setState(() {
 $spaces_6
-$spaces_4});''',
-      selectionOffset: 20,
-    );
+$spaces_4});
+    kind: invocation
+    selection: 20
+''');
   }
 
   Future<void> _check_flutter_setState({
     required String line,
-    required String completion,
-    required int selectionOffset,
+    required String expected,
   }) async {
     writeTestPackageConfig(flutter: true);
 
@@ -90,18 +92,12 @@
 }
 ''');
 
-    check(response).suggestions.includesAll([
-      (suggestion) => suggestion
-        ..completion.startsWith('setState')
-        ..completion.isEqualTo(completion)
-        ..hasSelection(offset: selectionOffset)
-        // It is an invocation, but we don't need any additional info for it.
-        // So, all parameter information is absent.
-        ..kind.isInvocation
-        ..parameterNames.isNull
-        ..parameterTypes.isNull
-        ..requiredParameterCount.isNull
-        ..hasNamedParameters.isNull,
-    ]);
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        return suggestion.completion.contains('setState(');
+      },
+    );
+
+    assertResponseText(response, expected);
   }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/location/class_body_test.dart b/pkg/analysis_server/test/services/completion/dart/location/class_body_test.dart
index c9003f8..604fbae 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/class_body_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/class_body_test.dart
@@ -2,73 +2,68 @@
 // 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/dart/ast/token.dart';
-import 'package:analyzer_utilities/check/check.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
 import '../completion_check.dart';
+import '../completion_printer.dart' as printer;
+import '../completion_printer.dart';
 
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ClassBodyTest1);
     defineReflectiveTests(ClassBodyTest2);
+    defineReflectiveTests(ClassOverrideTest1);
+    defineReflectiveTests(ClassOverrideTest2);
   });
 }
 
 @reflectiveTest
 class ClassBodyTest1 extends AbstractCompletionDriverTest
-    with ClassBodyTestCases, OverrideTestCases {
+    with ClassBodyTestCases {
   @override
   TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
 }
 
 @reflectiveTest
 class ClassBodyTest2 extends AbstractCompletionDriverTest
-    with ClassBodyTestCases, OverrideTestCases {
+    with ClassBodyTestCases {
   @override
   TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
 }
 
 mixin ClassBodyTestCases on AbstractCompletionDriverTest {
-  /// It does not really matter which classes we list here, in this test
-  /// suite we only need to know that we suggest classes at all.
-  List<CompletionSuggestionChecker> get sampleClassChecks {
-    return const {
-      'Object',
-    }.map((name) {
-      return (CompletionSuggestionTarget suggestion) {
-        suggestion
-          ..completion.isEqualTo(name)
-          ..isClass;
-      };
-    }).toList();
-  }
-
   Future<void> test_nothing_x() async {
     await _checkContainers(
       line: '^',
       validator: (context, response) {
-        check(response).suggestions
-          ..withKindKeyword.matchesInAnyOrder(
-            {
-              // TODO(scheglov) Not quite right, without static.
-              Keyword.CONST,
-              if (context.isClass || context.isMixin) Keyword.COVARIANT,
-              Keyword.DYNAMIC,
-              // TODO(scheglov) This does not look right, mixin.
-              if (context.isClass || context.isMixin) Keyword.FACTORY,
-              Keyword.FINAL,
-              Keyword.GET,
-              Keyword.LATE,
-              Keyword.OPERATOR,
-              Keyword.SET,
-              Keyword.STATIC,
-              Keyword.VAR,
-              Keyword.VOID,
-            }.asKeywordChecks,
-          )
-          ..includesAll(sampleClassChecks);
+        _printKeywordsOrClass();
+
+        final keywords = {
+          // TODO(scheglov) Not quite right, without static.
+          Keyword.CONST,
+          if (context.isClass || context.isMixin) Keyword.COVARIANT,
+          Keyword.DYNAMIC,
+          // TODO(scheglov) This does not look right, mixin.
+          if (context.isClass || context.isMixin) Keyword.FACTORY,
+          Keyword.FINAL,
+          Keyword.GET,
+          Keyword.LATE,
+          Keyword.OPERATOR,
+          Keyword.SET,
+          Keyword.STATIC,
+          Keyword.VAR,
+          Keyword.VOID,
+        };
+
+        assertResponseText(response, '''
+suggestions
+  Object
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
       },
     );
   }
@@ -77,14 +72,19 @@
     await _checkContainers(
       line: 'static const ^',
       validator: (context, response) {
-        check(response).suggestions
-          ..withKindKeyword.matchesInAnyOrder(
-            {
-              Keyword.DYNAMIC,
-              Keyword.VOID,
-            }.asKeywordChecks,
-          )
-          ..includesAll(sampleClassChecks);
+        _printKeywordsOrClass();
+
+        final keywords = {
+          Keyword.DYNAMIC,
+          Keyword.VOID,
+        };
+
+        assertResponseText(response, '''
+suggestions
+  Object
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
       },
     );
   }
@@ -94,18 +94,30 @@
       line: 'static final O^',
       validator: (context, response) {
         if (isProtocolVersion2) {
-          check(response).suggestions
-            ..withKindKeyword.isEmpty
-            ..includesAll(sampleClassChecks);
+          _printKeywordsOrClass();
+          assertResponseText(response, '''
+replacement
+  left: 1
+suggestions
+  Object
+    kind: class
+''');
         } else {
-          check(response).suggestions
-            ..withKindKeyword.matchesInAnyOrder(
-              {
-                Keyword.DYNAMIC,
-                Keyword.VOID,
-              }.asKeywordChecks,
-            )
-            ..includesAll(sampleClassChecks);
+          _printKeywordsOrClass();
+
+          final keywords = {
+            Keyword.DYNAMIC,
+            Keyword.VOID,
+          };
+
+          assertResponseText(response, '''
+replacement
+  left: 1
+suggestions
+  Object
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
         }
       },
     );
@@ -115,48 +127,64 @@
     await _checkContainers(
       line: 'static final ^',
       validator: (context, response) {
-        check(response).suggestions
-          ..withKindKeyword.matchesInAnyOrder(
-            {
-              Keyword.DYNAMIC,
-              Keyword.VOID,
-            }.asKeywordChecks,
-          )
-          ..includesAll(sampleClassChecks);
+        _printKeywordsOrClass();
+
+        final keywords = {
+          Keyword.DYNAMIC,
+          Keyword.VOID,
+        };
+
+        assertResponseText(response, '''
+suggestions
+  Object
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
       },
     );
   }
 
   Future<void> test_static_fx() async {
+    _printKeywordsOrClass(
+      sampleClassName: 'FutureOr',
+    );
+
     await _checkContainers(
       line: 'static f^',
       validator: (context, response) {
         if (isProtocolVersion2) {
-          check(response).suggestions
-            ..withKindKeyword.matchesInAnyOrder(
-              {
-                Keyword.FINAL,
-              }.asKeywordChecks,
-            )
-            ..includesAll([
-              (suggestion) => suggestion
-                ..completion.isEqualTo('FutureOr')
-                ..isClass,
-            ]);
+          final keywords = {
+            Keyword.FINAL,
+          };
+
+          assertResponseText(response, '''
+replacement
+  left: 1
+suggestions
+  FutureOr
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
         } else {
-          check(response).suggestions
-            ..withKindKeyword.matchesInAnyOrder(
-              {
-                Keyword.ABSTRACT,
-                Keyword.CONST,
-                Keyword.COVARIANT,
-                Keyword.DYNAMIC,
-                Keyword.EXTERNAL,
-                Keyword.FINAL,
-                Keyword.LATE,
-              }.asKeywordChecks,
-            )
-            ..includesAll(sampleClassChecks);
+          // TODO(scheglov) This is wrong.
+          final keywords = {
+            Keyword.ABSTRACT,
+            Keyword.CONST,
+            Keyword.COVARIANT,
+            Keyword.DYNAMIC,
+            Keyword.EXTERNAL,
+            Keyword.FINAL,
+            Keyword.LATE,
+          };
+
+          assertResponseText(response, '''
+replacement
+  left: 1
+suggestions
+  FutureOr
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
         }
       },
     );
@@ -166,14 +194,19 @@
     await _checkContainers(
       line: 'static late ^',
       validator: (context, response) {
-        check(response).suggestions
-          ..withKindKeyword.matchesInAnyOrder(
-            {
-              Keyword.DYNAMIC,
-              Keyword.FINAL,
-            }.asKeywordChecks,
-          )
-          ..includesAll(sampleClassChecks);
+        _printKeywordsOrClass();
+
+        final keywords = {
+          Keyword.DYNAMIC,
+          Keyword.FINAL,
+        };
+
+        assertResponseText(response, '''
+suggestions
+  Object
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
       },
     );
   }
@@ -182,16 +215,21 @@
     await _checkContainers(
       line: 'static ^',
       validator: (context, response) {
-        check(response).suggestions
-          ..withKindKeyword.matchesInAnyOrder(
-            {
-              Keyword.CONST,
-              Keyword.DYNAMIC,
-              Keyword.FINAL,
-              Keyword.LATE,
-            }.asKeywordChecks,
-          )
-          ..includesAll(sampleClassChecks);
+        _printKeywordsOrClass();
+
+        final keywords = {
+          Keyword.CONST,
+          Keyword.DYNAMIC,
+          Keyword.FINAL,
+          Keyword.LATE,
+        };
+
+        assertResponseText(response, '''
+suggestions
+  Object
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
       },
     );
   }
@@ -200,64 +238,79 @@
     await _checkContainers(
       line: 'static ^ name = 0;',
       validator: (context, response) {
-        check(response).suggestions
-          ..withKindKeyword.matchesInAnyOrder(
-            {
-              // TODO(scheglov) This does not look right.
-              Keyword.ABSTRACT,
-              Keyword.CONST,
-              // TODO(scheglov) This does not look right.
-              Keyword.COVARIANT,
-              Keyword.DYNAMIC,
-              // TODO(scheglov) This does not look right.
-              Keyword.EXTERNAL,
-              Keyword.FINAL,
-              Keyword.LATE,
-            }.asKeywordChecks,
-          )
-          ..includesAll(sampleClassChecks);
+        _printKeywordsOrClass();
+
+        final keywords = {
+          // TODO(scheglov) This does not look right.
+          Keyword.ABSTRACT,
+          Keyword.CONST,
+          // TODO(scheglov) This does not look right.
+          Keyword.COVARIANT,
+          Keyword.DYNAMIC,
+          // TODO(scheglov) This does not look right.
+          Keyword.EXTERNAL,
+          Keyword.FINAL,
+          Keyword.LATE,
+        };
+
+        assertResponseText(response, '''
+suggestions
+  Object
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
       },
     );
   }
 
   Future<void> test_sx() async {
+    _printKeywordsOrClass(
+      sampleClassName: 'String',
+    );
+
     await _checkContainers(
       line: 's^',
       validator: (context, response) {
         if (isProtocolVersion2) {
-          check(response).suggestions
-            ..withKindKeyword.matchesInAnyOrder(
-              {
-                Keyword.SET,
-                Keyword.STATIC,
-              }.asKeywordChecks,
-            )
-            ..includesAll([
-              (suggestion) => suggestion
-                ..completion.isEqualTo('String')
-                ..isClass,
-            ]);
+          final keywords = {
+            Keyword.SET,
+            Keyword.STATIC,
+          };
+
+          assertResponseText(response, '''
+replacement
+  left: 1
+suggestions
+  String
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
         } else {
-          check(response).suggestions
-            ..withKindKeyword.matchesInAnyOrder(
-              {
-                // TODO(scheglov) Not quite right, without static.
-                Keyword.CONST,
-                if (context.isClass || context.isMixin) Keyword.COVARIANT,
-                Keyword.DYNAMIC,
-                // TODO(scheglov) This does not look right, mixin.
-                if (context.isClass || context.isMixin) Keyword.FACTORY,
-                Keyword.FINAL,
-                Keyword.GET,
-                Keyword.LATE,
-                Keyword.OPERATOR,
-                Keyword.SET,
-                Keyword.STATIC,
-                Keyword.VAR,
-                Keyword.VOID,
-              }.asKeywordChecks,
-            )
-            ..includesAll(sampleClassChecks);
+          final keywords = {
+            // TODO(scheglov) Not quite right, without static.
+            Keyword.CONST,
+            if (context.isClass || context.isMixin) Keyword.COVARIANT,
+            Keyword.DYNAMIC,
+            // TODO(scheglov) This does not look right, mixin.
+            if (context.isClass || context.isMixin) Keyword.FACTORY,
+            Keyword.FINAL,
+            Keyword.GET,
+            Keyword.LATE,
+            Keyword.OPERATOR,
+            Keyword.SET,
+            Keyword.STATIC,
+            Keyword.VAR,
+            Keyword.VOID,
+          };
+
+          assertResponseText(response, '''
+replacement
+  left: 1
+suggestions
+  String
+    kind: class
+${keywords.asKeywordSuggestions}
+''');
         }
       },
     );
@@ -309,9 +362,54 @@
       validator(_Context(isMixin: true), response);
     }
   }
+
+  void _printKeywordsOrClass({
+    String sampleClassName = 'Object',
+  }) {
+    printerConfiguration
+      ..filter = (suggestion) {
+        final completion = suggestion.completion;
+        if (suggestion.kind == CompletionSuggestionKind.KEYWORD) {
+          return true;
+        } else if (completion == sampleClassName) {
+          return true;
+        }
+        return false;
+      }
+      ..sorting = Sorting.completion;
+  }
+}
+
+@reflectiveTest
+class ClassOverrideTest1 extends AbstractCompletionDriverTest
+    with OverrideTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class ClassOverrideTest2 extends AbstractCompletionDriverTest
+    with OverrideTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
 }
 
 mixin OverrideTestCases on AbstractCompletionDriverTest {
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        if (suggestion.kind == CompletionSuggestionKind.OVERRIDE) {
+          return suggestion.completion.contains('foo0');
+        }
+        return false;
+      },
+      withDisplayText: true,
+    );
+  }
+
   Future<void> test_class_inComment() async {
     final response = await getTestCodeSuggestions('''
 class A {
@@ -324,7 +422,9 @@
 }
 ''');
 
-    check(response).suggestions.overrides.isEmpty;
+    assertResponseText(response, r'''
+suggestions
+''');
   }
 
   Future<void> test_class_inComment_dartdoc() async {
@@ -339,7 +439,9 @@
 }
 ''');
 
-    check(response).suggestions.overrides.isEmpty;
+    assertResponseText(response, r'''
+suggestions
+''');
   }
 
   Future<void> test_class_inComment_reference() async {
@@ -354,7 +456,11 @@
 }
 ''');
 
-    check(response).suggestions.overrides.isEmpty;
+    assertResponseText(response, r'''
+replacement
+  left: 3
+suggestions
+''');
   }
 
   Future<void> test_class_method_alreadyOverridden() async {
@@ -370,13 +476,19 @@
 }
 ''');
 
-    check(response).suggestions.overrides
-      ..includesAll([
-        _isOverrideWithSuper_foo01,
-      ])
-      ..excludesAll([
-        (suggestion) => suggestion.completion.contains('foo02'),
-      ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo01() {
+    // TODO: implement foo01
+    super.foo01();
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 60 14
+''');
   }
 
   Future<void> test_class_method_beforeField() async {
@@ -392,9 +504,19 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      _isOverrideWithSuper_foo01,
-    ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo01() {
+    // TODO: implement foo01
+    super.foo01();
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 60 14
+''');
   }
 
   Future<void> test_class_method_beforeMethod() async {
@@ -410,9 +532,19 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      _isOverrideWithSuper_foo01,
-    ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo01() {
+    // TODO: implement foo01
+    super.foo01();
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 60 14
+''');
   }
 
   Future<void> test_class_method_fromExtends() async {
@@ -426,9 +558,19 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      _isOverrideWithSuper_foo01,
-    ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo01() {
+    // TODO: implement foo01
+    super.foo01();
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 60 14
+''');
   }
 
   Future<void> test_class_method_fromExtends_fromPart() async {
@@ -448,9 +590,19 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      _isOverrideWithSuper_foo01,
-    ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo01() {
+    // TODO: implement foo01
+    super.foo01();
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 60 14
+''');
   }
 
   Future<void> test_class_method_fromExtends_multiple() async {
@@ -468,10 +620,27 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      _isOverrideWithSuper_foo01,
-      _isOverrideWithSuper_foo02,
-    ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo01() {
+    // TODO: implement foo01
+    super.foo01();
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 60 14
+  @override
+  void foo02() {
+    // TODO: implement foo02
+    super.foo02();
+  }
+    kind: override
+    displayText: foo02() { … }
+    selection: 60 14
+''');
   }
 
   Future<void> test_class_method_fromExtends_private_otherLibrary() async {
@@ -491,13 +660,19 @@
 }
 ''');
 
-    check(response).suggestions.overrides
-      ..includesAll([
-        _isOverrideWithSuper_foo02,
-      ])
-      ..excludesAll([
-        _isOverrideWithSuper_private_foo01,
-      ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo02() {
+    // TODO: implement foo02
+    super.foo02();
+  }
+    kind: override
+    displayText: foo02() { … }
+    selection: 60 14
+''');
   }
 
   Future<void> test_class_method_fromExtends_private_thisLibrary() async {
@@ -512,10 +687,27 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      _isOverrideWithSuper_private_foo01,
-      _isOverrideWithSuper_foo02,
-    ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void _foo01() {
+    // TODO: implement _foo01
+    super._foo01();
+  }
+    kind: override
+    displayText: _foo01() { … }
+    selection: 62 15
+  @override
+  void foo02() {
+    // TODO: implement foo02
+    super.foo02();
+  }
+    kind: override
+    displayText: foo02() { … }
+    selection: 60 14
+''');
   }
 
   Future<void> test_class_method_fromExtends_withOverride() async {
@@ -530,16 +722,18 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      (suggestion) => suggestion
-        ..displayText.isEqualTo('foo01() { … }')
-        ..hasSelection(offset: 48, length: 14)
-        ..completion.isEqualTo(r'''
-void foo01() {
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  void foo01() {
     // TODO: implement foo01
     super.foo01();
-  }'''),
-    ]);
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 48 14
+''');
   }
 
   Future<void> test_class_method_fromImplements() async {
@@ -553,9 +747,18 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      _isOverrideWithoutSuper_foo01,
-    ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo01() {
+    // TODO: implement foo01
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 55
+''');
   }
 
   Future<void> test_class_method_fromWith() async {
@@ -569,9 +772,19 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      _isOverrideWithSuper_foo01,
-    ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo01() {
+    // TODO: implement foo01
+    super.foo01();
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 60 14
+''');
   }
 
   Future<void> test_class_operator_eqEq() async {
@@ -581,17 +794,23 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      (suggestion) => suggestion
-        ..displayText.isEqualTo('==(Object other) { … }')
-        ..hasSelection(offset: 75, length: 22)
-        ..completion.isEqualTo(r'''
-@override
+    printerConfiguration.filter = (suggestion) {
+      return suggestion.completion.contains('==(');
+    };
+
+    assertResponseText(response, '''
+replacement
+  left: 5
+suggestions
+  @override
   bool operator ==(Object other) {
     // TODO: implement ==
     return super == other;
-  }'''),
-    ]);
+  }
+    kind: override
+    displayText: ==(Object other) { … }
+    selection: 75 22
+''');
   }
 
   Future<void> test_class_operator_plus() async {
@@ -605,17 +824,23 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      (suggestion) => suggestion
-        ..displayText.isEqualTo('+(int other) { … }')
-        ..hasSelection(offset: 69, length: 21)
-        ..completion.isEqualTo(r'''
-@override
+    printerConfiguration.filter = (suggestion) {
+      return suggestion.completion.contains('+(');
+    };
+
+    assertResponseText(response, '''
+replacement
+  left: 5
+suggestions
+  @override
   int operator +(int other) {
     // TODO: implement +
     return super + other;
-  }'''),
-    ]);
+  }
+    kind: override
+    displayText: +(int other) { … }
+    selection: 69 21
+''');
   }
 
   Future<void> test_extension_method() async {
@@ -629,7 +854,11 @@
 }
 ''');
 
-    check(response).suggestions.overrides.isEmpty;
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+''');
   }
 
   Future<void> test_mixin_method_fromConstraints_alreadyOverridden() async {
@@ -645,13 +874,19 @@
 }
 ''');
 
-    check(response).suggestions.overrides
-      ..includesAll([
-        _isOverrideWithSuper_foo01,
-      ])
-      ..excludesAll([
-        (suggestion) => suggestion.completion.contains('foo02'),
-      ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo01() {
+    // TODO: implement foo01
+    super.foo01();
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 60 14
+''');
   }
 
   Future<void> test_mixin_method_fromImplements() async {
@@ -665,9 +900,18 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      _isOverrideWithoutSuper_foo01,
-    ]);
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
+  void foo01() {
+    // TODO: implement foo01
+  }
+    kind: override
+    displayText: foo01() { … }
+    selection: 55
+''');
   }
 
   Future<void> test_mixin_method_fromSuperclassConstraint() async {
@@ -681,64 +925,19 @@
 }
 ''');
 
-    check(response).suggestions.overrides.includesAll([
-      _isOverrideWithSuper_foo01,
-    ]);
-  }
-
-  static void _isOverrideWithoutSuper_foo01(
-    CheckTarget<CompletionSuggestionForTesting> suggestion,
-  ) {
-    suggestion
-      ..displayText.isEqualTo('foo01() { … }')
-      ..hasSelection(offset: 55)
-      ..completion.isEqualTo(r'''
-@override
-  void foo01() {
-    // TODO: implement foo01
-  }''');
-  }
-
-  static void _isOverrideWithSuper_foo01(
-    CheckTarget<CompletionSuggestionForTesting> suggestion,
-  ) {
-    suggestion
-      ..displayText.isEqualTo('foo01() { … }')
-      ..hasSelection(offset: 60, length: 14)
-      ..completion.isEqualTo(r'''
-@override
+    assertResponseText(response, '''
+replacement
+  left: 3
+suggestions
+  @override
   void foo01() {
     // TODO: implement foo01
     super.foo01();
-  }''');
   }
-
-  static void _isOverrideWithSuper_foo02(
-    CheckTarget<CompletionSuggestionForTesting> suggestion,
-  ) {
-    suggestion
-      ..displayText.isEqualTo('foo02() { … }')
-      ..hasSelection(offset: 60, length: 14)
-      ..completion.isEqualTo(r'''
-@override
-  void foo02() {
-    // TODO: implement foo02
-    super.foo02();
-  }''');
-  }
-
-  static void _isOverrideWithSuper_private_foo01(
-    CheckTarget<CompletionSuggestionForTesting> suggestion,
-  ) {
-    suggestion
-      ..displayText.isEqualTo('_foo01() { … }')
-      ..hasSelection(offset: 62, length: 15)
-      ..completion.isEqualTo(r'''
-@override
-  void _foo01() {
-    // TODO: implement _foo01
-    super._foo01();
-  }''');
+    kind: override
+    displayText: foo01() { … }
+    selection: 60 14
+''');
   }
 }
 
@@ -751,3 +950,13 @@
     this.isMixin = false,
   });
 }
+
+extension on Iterable<Keyword> {
+  String get asKeywordSuggestions {
+    return map((keyword) {
+      return '''
+  ${keyword.lexeme}
+    kind: keyword''';
+    }).join('\n');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/location/compilation_unit_test.dart b/pkg/analysis_server/test/services/completion/dart/location/compilation_unit_test.dart
index d5130d5..9be619f 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/compilation_unit_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/compilation_unit_test.dart
@@ -2,11 +2,12 @@
 // 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:analysis_server/src/protocol_server.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
 import '../completion_check.dart';
+import '../completion_printer.dart' as printer;
 
 void main() {
   defineReflectiveSuite(() {
@@ -30,22 +31,39 @@
 }
 
 mixin CompilationUnitTestCases on AbstractCompletionDriverTest {
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        if (isProtocolVersion2) {
+          return suggestion.kind == CompletionSuggestionKind.KEYWORD;
+        } else {
+          final completion = suggestion.completion;
+          return const {'import', 'export', 'part'}.any(completion.contains);
+        }
+      },
+    );
+  }
+
   Future<void> test_definingUnit_export() async {
     var response = await getTestCodeSuggestions('''
 exp^
 ''');
 
-    check(response).suggestions.includesAll([
-      (suggestion) => suggestion
-        ..completion.isEqualTo("export '';")
-        ..kind.isKeyword
-        ..hasSelection(offset: 8),
-    ]);
-
     if (isProtocolVersion2) {
-      check(response).suggestions.excludesAll([
-        (suggestion) => suggestion.completion.startsWith('import'),
-      ]);
+      assertResponseText(response, r'''
+replacement
+  left: 3
+suggestions
+  export '';
+    kind: keyword
+    selection: 8
+''');
+    } else {
+      // TODO(scheglov) This is wrong, should filter.
+      _protocol1Directives(response);
     }
   }
 
@@ -54,17 +72,18 @@
 imp^
 ''');
 
-    check(response).suggestions.includesAll([
-      (suggestion) => suggestion
-        ..completion.isEqualTo("import '';")
-        ..kind.isKeyword
-        ..hasSelection(offset: 8),
-    ]);
-
     if (isProtocolVersion2) {
-      check(response).suggestions.excludesAll([
-        (suggestion) => suggestion.completion.startsWith('export'),
-      ]);
+      assertResponseText(response, r'''
+replacement
+  left: 3
+suggestions
+  import '';
+    kind: keyword
+    selection: 8
+''');
+    } else {
+      // TODO(scheglov) This is wrong, should filter.
+      _protocol1Directives(response);
     }
   }
 
@@ -73,11 +92,35 @@
 par^
 ''');
 
-    check(response).suggestions.includesAll([
-      (suggestion) => suggestion
-        ..completion.isEqualTo("part '';")
-        ..kind.isKeyword
-        ..hasSelection(offset: 6),
-    ]);
+    if (isProtocolVersion2) {
+      assertResponseText(response, r'''
+replacement
+  left: 3
+suggestions
+  part '';
+    kind: keyword
+    selection: 6
+''');
+    } else {
+      // TODO(scheglov) This is wrong, should filter.
+      _protocol1Directives(response);
+    }
+  }
+
+  void _protocol1Directives(CompletionResponseForTesting response) {
+    assertResponseText(response, r'''
+replacement
+  left: 3
+suggestions
+  import '';
+    kind: keyword
+    selection: 8
+  export '';
+    kind: keyword
+    selection: 8
+  part '';
+    kind: keyword
+    selection: 6
+''');
   }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/location/directive_uri_test.dart b/pkg/analysis_server/test/services/completion/dart/location/directive_uri_test.dart
index 6a2db5b..ff9e7b7 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/directive_uri_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/directive_uri_test.dart
@@ -3,12 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
-import 'package:analyzer_utilities/check/check.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
 import '../completion_check.dart';
+import '../completion_printer.dart' as printer;
 
 void main() {
   defineReflectiveSuite(() {
@@ -21,19 +21,31 @@
   @override
   TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
 
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        return true;
+      },
+    );
+  }
+
   Future<void> test_uri_end() async {
     await _checkDirectives(
       uriContent: 'foo0^',
       validator: (response) {
         // We have both `foo0x`, but no `bar`.
-        check(response).suggestions.matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..isImport
-            ..completion.isEqualTo('package:foo/foo01.dart'),
-          (suggestion) => suggestion
-            ..isImport
-            ..completion.isEqualTo('package:foo/foo02.dart'),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  package:foo/foo01.dart
+    kind: import
+  package:foo/foo02.dart
+    kind: import
+''');
       },
     );
   }
@@ -43,14 +55,16 @@
       uriContent: 'foo0^xyz',
       validator: (response) {
         // We ignore 'xyz' after the caret.
-        check(response).suggestions.matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..isImport
-            ..completion.isEqualTo('package:foo/foo01.dart'),
-          (suggestion) => suggestion
-            ..isImport
-            ..completion.isEqualTo('package:foo/foo02.dart'),
-        ]);
+        assertResponseText(response, r'''
+replacement
+  left: 4
+  right: 3
+suggestions
+  package:foo/foo01.dart
+    kind: import
+  package:foo/foo02.dart
+    kind: import
+''');
       },
     );
   }
diff --git a/pkg/analysis_server/test/services/completion/dart/location/enum_constant_test.dart b/pkg/analysis_server/test/services/completion/dart/location/enum_constant_test.dart
index 90a8f54..dd9be5f 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/enum_constant_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/enum_constant_test.dart
@@ -2,11 +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 'package:analyzer_utilities/check/check.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
-import '../completion_check.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -37,6 +35,10 @@
 }
 ''');
 
-    check(response).suggestions.isEmpty;
+    assertResponseText(response, r'''
+replacement
+  left: 1
+suggestions
+''');
   }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/location/enum_test.dart b/pkg/analysis_server/test/services/completion/dart/location/enum_test.dart
index 42fafb8..e32e0e8 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/enum_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/enum_test.dart
@@ -2,12 +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 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer_utilities/check/check.dart';
+import 'package:analysis_server/src/protocol_server.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
-import '../completion_check.dart';
+import '../completion_printer.dart' as printer;
 
 void main() {
   defineReflectiveSuite(() {
@@ -36,15 +35,32 @@
 }
 ''');
 
-    check(response).suggestions.matchesInAnyOrder([
-      ...{
-        Keyword.WITH,
-      }.asKeywordChecks,
-    ]);
+    assertResponseText(response, r'''
+replacement
+  left: 1
+suggestions
+  with
+    kind: keyword
+''');
   }
 }
 
 mixin EnumDeclarationTestCases on AbstractCompletionDriverTest {
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        final completion = suggestion.completion;
+        if (suggestion.kind == CompletionSuggestionKind.IDENTIFIER) {
+          return const {'Object'}.contains(completion);
+        }
+        return true;
+      },
+    );
+  }
+
   Future<void> test_afterConstants_noSemicolon() async {
     var response = await getTestCodeSuggestions('''
 enum E {
@@ -52,7 +68,9 @@
 }
 ''');
 
-    check(response).suggestions.isEmpty;
+    assertResponseText(response, r'''
+suggestions
+''');
   }
 
   Future<void> test_afterImplements() async {
@@ -62,13 +80,11 @@
 }
 ''');
 
-    check(response).suggestions
-      ..withKindKeyword.isEmpty
-      ..includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('Object')
-          ..isClass,
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  Object
+    kind: class
+''');
   }
 
   Future<void> test_afterImplementsClause() async {
@@ -78,11 +94,11 @@
 }
 ''');
 
-    check(response).suggestions.matchesInAnyOrder([
-      ...{
-        Keyword.WITH,
-      }.asKeywordChecks,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  with
+    kind: keyword
+''');
   }
 
   Future<void> test_afterName() async {
@@ -92,12 +108,13 @@
 }
 ''');
 
-    check(response).suggestions.matchesInAnyOrder([
-      ...{
-        Keyword.IMPLEMENTS,
-        Keyword.WITH,
-      }.asKeywordChecks,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  implements
+    kind: keyword
+  with
+    kind: keyword
+''');
   }
 
   Future<void> test_afterName_atEnd() async {
@@ -107,7 +124,11 @@
 }
 ''');
 
-    check(response).suggestions.isEmpty;
+    assertResponseText(response, r'''
+replacement
+  left: 1
+suggestions
+''');
   }
 
   Future<void> test_afterName_atLeftCurlyBracket() async {
@@ -117,12 +138,13 @@
 }
 ''');
 
-    check(response).suggestions.matchesInAnyOrder([
-      ...{
-        Keyword.IMPLEMENTS,
-        Keyword.WITH,
-      }.asKeywordChecks,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  implements
+    kind: keyword
+  with
+    kind: keyword
+''');
   }
 
   Future<void> test_afterName_beforeImplements() async {
@@ -132,11 +154,11 @@
 }
 ''');
 
-    check(response).suggestions.matchesInAnyOrder([
-      ...{
-        Keyword.WITH,
-      }.asKeywordChecks,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  with
+    kind: keyword
+''');
   }
 
   Future<void> test_afterName_hasWith_hasImplements() async {
@@ -146,7 +168,9 @@
 }
 ''');
 
-    check(response).suggestions.isEmpty;
+    assertResponseText(response, r'''
+suggestions
+''');
   }
 
   Future<void> test_afterName_language216() async {
@@ -157,7 +181,9 @@
 }
 ''');
 
-    check(response).suggestions.isEmpty;
+    assertResponseText(response, r'''
+suggestions
+''');
   }
 
   Future<void> test_afterWith() async {
@@ -167,13 +193,11 @@
 }
 ''');
 
-    check(response).suggestions
-      ..withKindKeyword.isEmpty
-      ..includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('Object')
-          ..isClass,
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  Object
+    kind: class
+''');
   }
 
   Future<void> test_afterWithClause() async {
@@ -183,11 +207,11 @@
 }
 ''');
 
-    check(response).suggestions.matchesInAnyOrder([
-      ...{
-        Keyword.IMPLEMENTS,
-      }.asKeywordChecks,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  implements
+    kind: keyword
+''');
   }
 
   Future<void> test_beforeConstants_hasSemicolon() async {
@@ -197,7 +221,9 @@
 }
 ''');
 
-    check(response).suggestions.isEmpty;
+    assertResponseText(response, r'''
+suggestions
+''');
   }
 
   Future<void> test_beforeConstants_noSemicolon() async {
@@ -207,7 +233,9 @@
 }
 ''');
 
-    check(response).suggestions.isEmpty;
+    assertResponseText(response, r'''
+suggestions
+''');
   }
 
   Future<void> test_constantName_dot_name_x_argumentList_named() async {
@@ -221,16 +249,15 @@
 ''');
 
     if (isProtocolVersion2) {
-      check(response)
-        ..hasReplacement(left: 4)
-        ..suggestions.matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('foo01')
-            ..isConstructorInvocation,
-          (suggestion) => suggestion
-            ..completion.isEqualTo('foo02')
-            ..isConstructorInvocation,
-        ]);
+      assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: constructorInvocation
+  foo02
+    kind: constructorInvocation
+''');
     }
   }
 
@@ -245,16 +272,15 @@
 ''');
 
     if (isProtocolVersion2) {
-      check(response)
-        ..hasReplacement(left: 4)
-        ..suggestions.matchesInAnyOrder([
-          (suggestion) => suggestion
-            ..completion.isEqualTo('foo01')
-            ..isConstructorInvocation,
-          (suggestion) => suggestion
-            ..completion.isEqualTo('foo02')
-            ..isConstructorInvocation,
-        ]);
+      assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: constructorInvocation
+  foo02
+    kind: constructorInvocation
+''');
     }
   }
 
@@ -267,14 +293,13 @@
 }
 ''');
 
-    check(response).suggestions.matchesInAnyOrder([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isConstructorInvocation,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isConstructorInvocation,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  foo01
+    kind: constructorInvocation
+  foo02
+    kind: constructorInvocation
+''');
   }
 
   Future<void> test_constantName_dot_x_semicolon_named() async {
@@ -286,14 +311,13 @@
 }
 ''');
 
-    check(response).suggestions.matchesInAnyOrder([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isConstructorInvocation,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isConstructorInvocation,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  foo01
+    kind: constructorInvocation
+  foo02
+    kind: constructorInvocation
+''');
   }
 
   Future<void> test_constantName_dot_x_semicolon_unnamed_declared() async {
@@ -304,11 +328,11 @@
 }
 ''');
 
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('new')
-        ..isConstructorInvocation,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  new
+    kind: constructorInvocation
+''');
   }
 
   Future<void> test_constantName_dot_x_unnamed_implicit() async {
@@ -318,11 +342,11 @@
 }
 ''');
 
-    check(response).suggestions.matches([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('new')
-        ..isConstructorInvocation,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  new
+    kind: constructorInvocation
+''');
   }
 
   Future<void> test_constantName_dot_x_unnamed_language216() async {
@@ -333,7 +357,9 @@
 }
 ''');
 
-    check(response).suggestions.isEmpty;
+    assertResponseText(response, r'''
+suggestions
+''');
   }
 
   Future<void> test_constantName_typeArguments_dot_x_semicolon_named() async {
@@ -345,13 +371,12 @@
 }
 ''');
 
-    check(response).suggestions.matchesInAnyOrder([
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo01')
-        ..isConstructorInvocation,
-      (suggestion) => suggestion
-        ..completion.isEqualTo('foo02')
-        ..isConstructorInvocation,
-    ]);
+    assertResponseText(response, r'''
+suggestions
+  foo01
+    kind: constructorInvocation
+  foo02
+    kind: constructorInvocation
+''');
   }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/location/field_formal_parameter_test.dart b/pkg/analysis_server/test/services/completion/dart/location/field_formal_parameter_test.dart
index 556b765..9d63754 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/field_formal_parameter_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/field_formal_parameter_test.dart
@@ -2,11 +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 'package:analyzer_utilities/check/check.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
 import '../completion_check.dart';
+import '../completion_printer.dart' as printer;
 
 void main() {
   defineReflectiveSuite(() {
@@ -30,36 +30,46 @@
 }
 
 mixin SuperFormalParameterTestCases on AbstractCompletionDriverTest {
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) => true,
+      withReturnType: true,
+    );
+  }
+
   Future<void> test_class_replacement_left() async {
     await _checkContainers(
-      declarations: 'var field = 0;',
+      declarations: 'var foo = 0;',
       constructorParameters: 'this.f^',
       validator: (response) {
-        check(response)
-          ..hasReplacement(left: 1)
-          ..suggestions.matchesInAnyOrder([
-            (suggestion) => suggestion
-              ..completion.isEqualTo('field')
-              ..isField
-              ..returnType.isEqualTo('int'),
-          ]);
+        assertResponseText(response, r'''
+replacement
+  left: 1
+suggestions
+  foo
+    kind: field
+    returnType: int
+''');
       },
     );
   }
 
   Future<void> test_class_replacement_right() async {
     await _checkContainers(
-      declarations: 'var field = 0;',
+      declarations: 'var foo = 0;',
       constructorParameters: 'this.^f',
       validator: (response) {
-        check(response)
-          ..hasReplacement(right: 1)
-          ..suggestions.matchesInAnyOrder([
-            (suggestion) => suggestion
-              ..completion.isEqualTo('field')
-              ..isField
-              ..returnType.isEqualTo('int'),
-          ]);
+        assertResponseText(response, r'''
+replacement
+  right: 1
+suggestions
+  foo
+    kind: field
+    returnType: int
+''');
       },
     );
   }
@@ -90,18 +100,15 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isField
-          ..returnType.isEqualTo('int'),
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isField
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: field
+    returnType: int
+  second
+    kind: field
+    returnType: double
+''');
   }
 
   Future<void> test_class_suggestions_onlyNotSpecified_optionalNamed() async {
@@ -109,14 +116,12 @@
       declarations: 'final int x; final int y;',
       constructorParameters: '{this.x, this.^}',
       validator: (response) {
-        check(response)
-          ..hasEmptyReplacement()
-          ..suggestions.matchesInAnyOrder([
-            (suggestion) => suggestion
-              ..completion.isEqualTo('y')
-              ..isField
-              ..returnType.isEqualTo('int'),
-          ]);
+        assertResponseText(response, r'''
+suggestions
+  y
+    kind: field
+    returnType: int
+''');
       },
     );
   }
@@ -127,14 +132,12 @@
       declarations: 'final int x; final int y;',
       constructorParameters: 'this.x, this.^',
       validator: (response) {
-        check(response)
-          ..hasEmptyReplacement()
-          ..suggestions.matchesInAnyOrder([
-            (suggestion) => suggestion
-              ..completion.isEqualTo('y')
-              ..isField
-              ..returnType.isEqualTo('int'),
-          ]);
+        assertResponseText(response, r'''
+suggestions
+  y
+    kind: field
+    returnType: int
+''');
       },
     );
   }
@@ -157,18 +160,15 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isField
-          ..returnType.isEqualTo('int'),
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isField
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: field
+    returnType: int
+  second
+    kind: field
+    returnType: double
+''');
   }
 
   /// https://github.com/dart-lang/sdk/issues/39028
@@ -180,7 +180,9 @@
 }
 ''');
 
-    check(response).suggestions.isEmpty;
+    assertResponseText(response, r'''
+suggestions
+''');
   }
 
   Future<void> _checkContainers({
diff --git a/pkg/analysis_server/test/services/completion/dart/location/named_expression_test.dart b/pkg/analysis_server/test/services/completion/dart/location/named_expression_test.dart
index c6355ea..42aff47 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/named_expression_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/named_expression_test.dart
@@ -2,11 +2,10 @@
 // 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_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
-import '../completion_check.dart';
+import '../completion_printer.dart' as printer;
 
 void main() {
   defineReflectiveSuite(() {
@@ -30,6 +29,18 @@
 }
 
 mixin NamedExpressionExpressionTestCases on AbstractCompletionDriverTest {
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        final completion = suggestion.completion;
+        return const {'x'}.contains(completion);
+      },
+    );
+  }
+
   Future<void> test_beforePositional() async {
     var response = await getTestCodeSuggestions('''
 void f(int x) {
@@ -39,13 +50,11 @@
 void g(int a, {required int b}) {}
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('x')
-          ..isParameter,
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  x
+    kind: parameter
+''');
   }
 
   Future<void> test_lastArgument() async {
@@ -57,13 +66,11 @@
 void g(int a, {required int b}) {}
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('x')
-          ..isParameter,
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  x
+    kind: parameter
+''');
   }
 
   Future<void> test_onlyArgument() async {
@@ -75,12 +82,10 @@
 void g({required int a}) {}
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.includesAll([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('x')
-          ..isParameter,
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  x
+    kind: parameter
+''');
   }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/location/record_literal_test.dart b/pkg/analysis_server/test/services/completion/dart/location/record_literal_test.dart
new file mode 100644
index 0000000..fa6b02e
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/location/record_literal_test.dart
@@ -0,0 +1,441 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import '../../../../client/completion_driver_test.dart';
+import '../completion_printer.dart' as printer;
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RecordLiteralFieldsTest);
+  });
+}
+
+@reflectiveTest
+class RecordLiteralFieldsTest extends AbstractCompletionDriverTest {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        final completion = suggestion.completion;
+        return ['foo0', 'bar0'].any(completion.startsWith);
+      },
+    );
+  }
+
+  Future<void> test_context02_left_prefix_x_colon_value() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, String foo02}) f() => (foo0^: 0);
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: namedArgument
+  foo02
+    kind: namedArgument
+''');
+  }
+
+  Future<void> test_context02_left_prefix_x_comma() async {
+    var response = await getTestCodeSuggestions('''
+({int foo01, String foo02}) f() => (foo0^,);
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo02: |
+    kind: namedArgument
+''');
+  }
+
+  Future<void> test_context02_left_prefix_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, String foo02}) f() => (foo0^);
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo02: |
+    kind: namedArgument
+''');
+  }
+
+  Future<void> test_context02_left_prefix_x_space_right() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, String foo02}) f() => (foo0^ );
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo02: |
+    kind: namedArgument
+''');
+  }
+
+  Future<void> test_context02_left_space_x_space_right() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, String foo02}) f() => ( ^ );
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo02: |
+    kind: namedArgument
+  bar01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context02_left_value_comma_space_prefix_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, String foo02}) f() => (0, foo0^);
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo02: |
+    kind: namedArgument
+''');
+  }
+
+  Future<void> test_context02_left_value_comma_space_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, String foo02}) f() => (0, ^);
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo02: |
+    kind: namedArgument
+  bar01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context02_left_x_comma() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, String foo02}) f() => (^,);
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo02: |
+    kind: namedArgument
+  bar01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context02_left_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, String foo02}) f() => (^);
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo02: |
+    kind: namedArgument
+  bar01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context02_x_colon_value() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, String foo02}) f() => (^: 0);
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  foo01
+    kind: namedArgument
+  foo02
+    kind: namedArgument
+''');
+  }
+
+  Future<void> test_context03_left_prefix_x_comma_named() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, int foo02, int foo03}) f() => (foo0^, foo02: 0);
+''');
+
+    // We don't suggest already specified `foo02`.
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo03: |
+    kind: namedArgument
+''');
+  }
+
+  Future<void> test_context03_left_x_comma_named() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+({int foo01, int foo02, int foo03}) f() => (^, foo02: 0);
+''');
+
+    // We don't suggest already specified `foo02`.
+    assertResponseText(response, r'''
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo03: |
+    kind: namedArgument
+  bar01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context03_named_comma_space_prefix_x_right() async {
+    var response = await getTestCodeSuggestions('''
+({int foo01, int foo02, int foo03}) f() => (foo02: 0, foo0^);
+''');
+
+    // We don't suggest already specified `foo02`.
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  |foo01: |
+    kind: namedArgument
+  |foo03: |
+    kind: namedArgument
+''');
+  }
+
+  Future<void> test_context10_value_comma_space_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final foo01 = 0;
+(int, ) f() => (0, ^);
+''');
+
+    // We suggest a positional value anyway.
+    assertResponseText(response, r'''
+suggestions
+  foo01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context11_value_comma_prefix_x_space_value() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+(int, {String foo01}) f() => (0, foo^ 0);
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 3
+suggestions
+  foo01: ,
+    kind: namedArgument
+    selection: 7
+''');
+  }
+
+  Future<void> test_context11_value_comma_space_prefix_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+(int, {int foo01}) f() => (0, foo0^);
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  |foo01: |
+    kind: namedArgument
+''');
+  }
+
+  Future<void> test_context11_value_comma_space_prefix_x_space_right() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+(int, {int foo01}) f() => (0, foo0^ );
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  |foo01: |
+    kind: namedArgument
+''');
+  }
+
+  Future<void> test_context11_value_comma_space_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+(int, {int foo01}) f() => (0, ^);
+''');
+
+    // We suggest a positional value anyway.
+    assertResponseText(response, r'''
+suggestions
+  |foo01: |
+    kind: namedArgument
+  bar01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context11_value_comma_space_x_space_right() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+(int, {int foo01}) f() => (0, ^ );
+''');
+
+    // We suggest a positional value anyway.
+    assertResponseText(response, r'''
+suggestions
+  |foo01: |
+    kind: namedArgument
+  bar01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context20_left_prefix_x_comma() async {
+    var response = await getTestCodeSuggestions('''
+final foo01 = 0;
+(int, int) f() => (foo0^, );
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context20_left_prefix_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final foo01 = 0;
+(int, int) f() => (foo0^);
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context20_left_x_comma() async {
+    var response = await getTestCodeSuggestions('''
+final foo01 = 0;
+(int, int) f() => (^, );
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  foo01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context20_left_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final foo01 = 0;
+(int, int) f() => (^);
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  foo01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context20_named_left_x_comma() async {
+    var response = await getTestCodeSuggestions('''
+final bar01 = 0;
+(int foo01, int foo02) f() => (^, );
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  bar01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context20_value_comma_space_prefix_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final foo01 = 0;
+(int, int) f() => (0, foo0^);
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 4
+suggestions
+  foo01
+    kind: topLevelVariable
+''');
+  }
+
+  Future<void> test_context20_value_comma_space_x_right() async {
+    var response = await getTestCodeSuggestions('''
+final foo01 = 0;
+(int, int) f() => (0, ^);
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  foo01
+    kind: topLevelVariable
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/location/record_type_annotation_test.dart b/pkg/analysis_server/test/services/completion/dart/location/record_type_annotation_test.dart
new file mode 100644
index 0000000..ac34a1c
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/location/record_type_annotation_test.dart
@@ -0,0 +1,262 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import '../../../../client/completion_driver_test.dart';
+import '../completion_printer.dart' as printer;
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RecordTypeAnnotationTest);
+  });
+}
+
+@reflectiveTest
+class RecordTypeAnnotationTest extends AbstractCompletionDriverTest {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) {
+        final completion = suggestion.completion;
+        if (['A0', 'B0'].any(completion.startsWith)) {
+          return true;
+        }
+        return {'buffer', 'stringBuffer'}.contains(completion);
+      },
+    );
+  }
+
+  Future<void> test_named_comma_space_prefix_x_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+({int foo01, A0^}) f() {}
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+  A02
+    kind: class
+''');
+  }
+
+  Future<void> test_named_comma_space_prefix_x_space_name_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+({int foo01, A0^ foo02}) f() {}
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+  A02
+    kind: class
+''');
+  }
+
+  Future<void> test_named_comma_space_type_space_prefix_x_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+({int foo01, StringBuffer str^}) f() {}
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 3
+suggestions
+  stringBuffer
+    kind: identifier
+''');
+  }
+
+  Future<void> test_named_comma_space_type_space_x_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+({int foo01, StringBuffer ^}) f() {}
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  buffer
+    kind: identifier
+  stringBuffer
+    kind: identifier
+''');
+  }
+
+  Future<void> test_named_comma_space_x_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+({int foo01, ^}) f() {}
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  A01
+    kind: class
+  A02
+    kind: class
+  B01
+    kind: class
+''');
+  }
+
+  Future<void> test_named_comma_space_x_space_name_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+({int foo01, ^ foo02}) f() {}
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  A01
+    kind: class
+  A02
+    kind: class
+  B01
+    kind: class
+''');
+  }
+
+  Future<void> test_positional_comma_space_prefix_x_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+(int, A0^) f() {}
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+  A02
+    kind: class
+''');
+  }
+
+  Future<void> test_positional_comma_space_prefix_x_space_name_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+(int, A0^ foo) f() {}
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 2
+suggestions
+  A01
+    kind: class
+  A02
+    kind: class
+''');
+  }
+
+  Future<void> test_positional_comma_space_prefix_x_suffix_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+(int, A0^foo) f() {}
+''');
+
+    assertResponseText(response, r'''
+replacement
+  left: 2
+  right: 3
+suggestions
+  A01
+    kind: class
+  A02
+    kind: class
+''');
+  }
+
+  Future<void> test_positional_comma_space_x_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+(int, ^) f() {}
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  A01
+    kind: class
+  A02
+    kind: class
+  B01
+    kind: class
+''');
+  }
+
+  Future<void> test_positional_comma_space_x_space_name_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+(int, ^ foo) f() {}
+''');
+
+    assertResponseText(response, r'''
+suggestions
+  A01
+    kind: class
+  A02
+    kind: class
+  B01
+    kind: class
+''');
+  }
+
+  Future<void> test_positional_comma_space_x_suffix_right() async {
+    var response = await getTestCodeSuggestions('''
+class A01 {}
+class A02 {}
+class B01 {}
+(int, ^foo) f() {}
+''');
+
+    assertResponseText(response, r'''
+replacement
+  right: 3
+suggestions
+  A01
+    kind: class
+  A02
+    kind: class
+  B01
+    kind: class
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/location/super_formal_parameter_test.dart b/pkg/analysis_server/test/services/completion/dart/location/super_formal_parameter_test.dart
index 2d4144a..2e11044 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/super_formal_parameter_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/super_formal_parameter_test.dart
@@ -2,11 +2,10 @@
 // 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_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
-import '../completion_check.dart';
+import '../completion_printer.dart' as printer;
 
 void main() {
   defineReflectiveSuite(() {
@@ -30,6 +29,16 @@
 }
 
 mixin SuperFormalParameterTestCases on AbstractCompletionDriverTest {
+  @override
+  Future<void> setUp() async {
+    await super.setUp();
+
+    printerConfiguration = printer.Configuration(
+      filter: (suggestion) => true,
+      withReturnType: true,
+    );
+  }
+
   Future<void> test_explicit_optionalNamed_hasArgument_named() async {
     var response = await getTestCodeSuggestions('''
 class A {
@@ -41,14 +50,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_explicit_optionalNamed_hasArgument_positional() async {
@@ -62,18 +69,15 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: parameter
+    returnType: int
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   /// It is an error, but the user already typed `super.`, so maybe do it.
@@ -88,14 +92,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: parameter
+    returnType: int
+''');
   }
 
   Future<void> test_explicitNamed_noOther() async {
@@ -110,14 +112,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: parameter
+    returnType: int
+''');
   }
 
   Future<void> test_implicit_optionalNamed_hasNamed_notSuper() async {
@@ -131,18 +131,15 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: parameter
+    returnType: int
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_implicit_optionalNamed_hasNamed_notSuper2() async {
@@ -156,14 +153,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_implicit_optionalNamed_hasNamed_super() async {
@@ -177,14 +172,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_implicit_optionalNamed_hasNamed_super2() async {
@@ -198,14 +191,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: parameter
+    returnType: int
+''');
   }
 
   Future<void> test_implicit_optionalNamed_hasPositional_notSuper() async {
@@ -219,18 +210,15 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: parameter
+    returnType: int
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_implicit_optionalNamed_hasPositional_super() async {
@@ -244,14 +232,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_implicit_optionalNamed_noOther() async {
@@ -265,18 +251,15 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-        (suggestion) => suggestion
-          ..completion.isEqualTo('third')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  second
+    kind: parameter
+    returnType: int
+  third
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_implicit_optionalPositional_hasPositional_notSuper() async {
@@ -290,14 +273,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: parameter
+    returnType: int
+''');
   }
 
   Future<void> test_implicit_optionalPositional_hasPositional_super() async {
@@ -311,14 +292,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_implicit_optionalPositional_hasPositional_super2() async {
@@ -334,14 +313,12 @@
 
     // It does not matter what is the name of the positional parameter.
     // Here `super.second` consumes `int first`.
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_implicit_optionalPositional_noOther() async {
@@ -355,14 +332,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: parameter
+    returnType: int
+''');
   }
 
   Future<void> test_implicit_requiredPositional_hasPositional_notSuper() async {
@@ -376,14 +351,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: parameter
+    returnType: int
+''');
   }
 
   Future<void> test_implicit_requiredPositional_hasPositional_super() async {
@@ -397,14 +370,12 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_implicit_requiredPositional_hasPositional_super2() async {
@@ -420,14 +391,12 @@
 
     // It does not matter what is the name of the positional parameter.
     // Here `super.second` consumes `int first`.
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('second')
-          ..isParameter
-          ..returnType.isEqualTo('double'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  second
+    kind: parameter
+    returnType: double
+''');
   }
 
   Future<void> test_implicit_requiredPositional_noOther() async {
@@ -442,13 +411,11 @@
 }
 ''');
 
-    check(response)
-      ..hasEmptyReplacement()
-      ..suggestions.matchesInAnyOrder([
-        (suggestion) => suggestion
-          ..completion.isEqualTo('first')
-          ..isParameter
-          ..returnType.isEqualTo('int'),
-      ]);
+    assertResponseText(response, r'''
+suggestions
+  first
+    kind: parameter
+    returnType: int
+''');
   }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/location/test_all.dart b/pkg/analysis_server/test/services/completion/dart/location/test_all.dart
index 139de2f..bb9ac93 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/test_all.dart
@@ -12,6 +12,8 @@
 import 'enum_test.dart' as enum_;
 import 'field_formal_parameter_test.dart' as field_formal_parameter;
 import 'named_expression_test.dart' as named_expression;
+import 'record_literal_test.dart' as record_literal;
+import 'record_type_annotation_test.dart' as record_type_annotation;
 import 'super_formal_parameter_test.dart' as super_formal_parameter;
 
 /// Tests suggestions produced at specific locations.
@@ -25,6 +27,8 @@
     enum_.main();
     field_formal_parameter.main();
     named_expression.main();
+    record_literal.main();
+    record_type_annotation.main();
     super_formal_parameter.main();
   });
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
index 73fa3be..3468630 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
@@ -29,7 +29,7 @@
 }
 
 mixin InstanceMemberTestCases on CompletionRelevanceTest {
-  Future<void> test_contextType() async {
+  Future<void> test_contextType_interfaceType_method() async {
     await addTestFile(r'''
 class A {}
 class B extends A {}
@@ -56,6 +56,48 @@
     ]);
   }
 
+  Future<void> test_contextType_recordType_named() async {
+    await addTestFile(r'''
+class A {}
+class B extends A {}
+class C extends B {}
+class D {}
+
+void f(B _) {}
+
+void g(({A foo01, B foo02, C foo03, D foo04}) r) {
+  f(r.^);
+}
+''');
+    assertOrder([
+      suggestionWith(completion: r'foo02'), // same
+      suggestionWith(completion: r'foo03'), // subtype
+      suggestionWith(completion: r'foo04'), // unrelated
+      suggestionWith(completion: r'foo01'), // supertype
+    ]);
+  }
+
+  Future<void> test_contextType_recordType_positional() async {
+    await addTestFile(r'''
+class A {}
+class B extends A {}
+class C extends B {}
+class D {}
+
+void f(B _) {}
+
+void g((A, B, C, D) r) {
+  f(r.^);
+}
+''');
+    assertOrder([
+      suggestionWith(completion: r'$1'), // same
+      suggestionWith(completion: r'$2'), // subtype
+      suggestionWith(completion: r'$3'), // unrelated
+      suggestionWith(completion: r'$0'), // supertype
+    ]);
+  }
+
   Future<void> test_elementKind() async {
     await addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index 041b84c..92d310b 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -21,6 +21,7 @@
 import 'named_constructor_contributor_test.dart' as named_contributor_test;
 import 'relevance/test_all.dart' as relevance_tests;
 import 'static_member_contributor_test.dart' as static_contributor_test;
+import 'text_expectations.dart';
 import 'type_member_contributor_test.dart' as type_member_contributor_test;
 import 'uri_contributor_test.dart' as uri_contributor_test;
 import 'variable_name_contributor_test.dart' as variable_name_contributor_test;
@@ -47,5 +48,6 @@
     type_member_contributor_test.main();
     uri_contributor_test.main();
     variable_name_contributor_test.main();
+    defineReflectiveTests(UpdateTextExpectations);
   }, name: 'dart');
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/text_expectations.dart b/pkg/analysis_server/test/services/completion/dart/text_expectations.dart
new file mode 100644
index 0000000..e1f95d1
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/text_expectations.dart
@@ -0,0 +1,122 @@
+// Copyright (c) 2022, 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:io' as io;
+
+import 'package:analyzer/source/line_info.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+class TextExpectationsCollector {
+  static const _updatingIsEnabled = false;
+
+  static const assertMethods = {
+    'AbstractCompletionDriverTest.assertResponseText',
+  };
+
+  static final Map<String, _File> _files = {};
+
+  static void add(String actual) {
+    if (!_updatingIsEnabled) {
+      return;
+    }
+
+    var traceLines = '${StackTrace.current}'.split('\n');
+    for (var traceIndex = 0; traceIndex < traceLines.length; traceIndex++) {
+      var traceLine = traceLines[traceIndex];
+      for (var assertMethod in assertMethods) {
+        if (traceLine.contains(' $assertMethod ')) {
+          var invocationLine = traceLines[traceIndex + 1];
+          var locationMatch = RegExp(
+            r'file://(.+_test.dart):(\d+):',
+          ).firstMatch(invocationLine);
+          if (locationMatch == null) {
+            fail('Cannot parse: $invocationLine');
+          }
+
+          var path = locationMatch.group(1)!;
+          var line = int.parse(locationMatch.group(2)!);
+          var file = _getFile(path);
+
+          var invocationOffset = file.lineInfo.getOffsetOfLine(line - 1);
+
+          const String rawStringPrefix = "r'''";
+          var expectationOffset = file.content.indexOf(
+            rawStringPrefix,
+            invocationOffset,
+          );
+          expectationOffset += rawStringPrefix.length;
+          var expectationEnd = file.content.indexOf("'''", expectationOffset);
+
+          file.replacements.add(
+            _Replacement(
+              expectationOffset,
+              expectationEnd,
+              '\n$actual',
+            ),
+          );
+        }
+      }
+    }
+  }
+
+  static void _apply() {
+    for (var file in _files.values) {
+      file.applyReplacements();
+    }
+    _files.clear();
+  }
+
+  static _File _getFile(String path) {
+    return _files[path] ??= _File(path);
+  }
+}
+
+@reflectiveTest
+class UpdateTextExpectations {
+  test_applyReplacements() {
+    TextExpectationsCollector._apply();
+  }
+}
+
+class _File {
+  final String path;
+  final String content;
+  final LineInfo lineInfo;
+  final List<_Replacement> replacements = [];
+
+  factory _File(String path) {
+    var content = io.File(path).readAsStringSync();
+    return _File._(
+      path: path,
+      content: content,
+      lineInfo: LineInfo.fromContent(content),
+    );
+  }
+
+  _File._({
+    required this.path,
+    required this.content,
+    required this.lineInfo,
+  });
+
+  void applyReplacements() {
+    replacements.sort((a, b) => b.offset - a.offset);
+    var newCode = content;
+    for (var replacement in replacements) {
+      newCode = newCode.substring(0, replacement.offset) +
+          replacement.text +
+          newCode.substring(replacement.end);
+    }
+    io.File(path).writeAsStringSync(newCode);
+  }
+}
+
+class _Replacement {
+  final int offset;
+  final int end;
+  final String text;
+
+  _Replacement(this.offset, this.end, this.text);
+}
diff --git a/pkg/analysis_server/test/services/correction/status_test.dart b/pkg/analysis_server/test/services/correction/status_test.dart
index 29af706..c08384e 100644
--- a/pkg/analysis_server/test/services/correction/status_test.dart
+++ b/pkg/analysis_server/test/services/correction/status_test.dart
@@ -60,7 +60,7 @@
 void f() {
 }
 ''');
-    var node = findNode.simple('f');
+    var node = findNode.functionDeclaration('f');
     // check
     var location = newLocation_fromNode(node);
     expect(location.file, testFile);
diff --git a/pkg/analysis_server/test/services/correction/util_test.dart b/pkg/analysis_server/test/services/correction/util_test.dart
index 4b5664a..fc4519d 100644
--- a/pkg/analysis_server/test/services/correction/util_test.dart
+++ b/pkg/analysis_server/test/services/correction/util_test.dart
@@ -7,10 +7,12 @@
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
+import 'package:linter/src/rules.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../abstract_single_unit.dart';
+import '../../analysis_server_base.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -42,13 +44,40 @@
     changeFile(testFile);
   }
 
+  Future<void> test_addLibraryImports_dart_doubleQuotes() async {
+    registerLintRules();
+    var config = AnalysisOptionsFileConfig(
+      lints: ['prefer_double_quotes'],
+    );
+    newAnalysisOptionsYamlFile(
+      testPackageRootPath,
+      config.toContent(),
+    );
+
+    await resolveTestCode('''
+/// Comment.
+
+class A {}
+''');
+    var newLibrary1 = _getDartSource('dart:math');
+    var newLibrary2 = _getDartSource('dart:async');
+    await _assertAddLibraryImport([newLibrary1, newLibrary2], '''
+/// Comment.
+
+import "dart:async";
+import "dart:math";
+
+class A {}
+''');
+  }
+
   Future<void> test_addLibraryImports_dart_hasImports_between() async {
     await resolveTestCode('''
 import 'dart:async';
 import 'dart:math';
 ''');
     var newLibrary = _getDartSource('dart:collection');
-    await _assertAddLibraryImport(<Source>[newLibrary], '''
+    await _assertAddLibraryImport([newLibrary], '''
 import 'dart:async';
 import 'dart:collection';
 import 'dart:math';
@@ -61,7 +90,7 @@
 import 'dart:math';
 ''');
     var newLibrary = _getDartSource('dart:async');
-    await _assertAddLibraryImport(<Source>[newLibrary], '''
+    await _assertAddLibraryImport([newLibrary], '''
 import 'dart:async';
 import 'dart:collection';
 import 'dart:math';
@@ -74,7 +103,7 @@
 import 'dart:collection';
 ''');
     var newLibrary = _getDartSource('dart:math');
-    await _assertAddLibraryImport(<Source>[newLibrary], '''
+    await _assertAddLibraryImport([newLibrary], '''
 import 'dart:async';
 import 'dart:collection';
 import 'dart:math';
@@ -88,7 +117,7 @@
 ''');
     var newLibrary1 = _getDartSource('dart:async');
     var newLibrary2 = _getDartSource('dart:html');
-    await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+    await _assertAddLibraryImport([newLibrary1, newLibrary2], '''
 import 'dart:async';
 import 'dart:collection';
 import 'dart:html';
@@ -103,7 +132,7 @@
 ''');
     var newLibrary1 = _getDartSource('dart:async');
     var newLibrary2 = _getDartSource('dart:collection');
-    await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+    await _assertAddLibraryImport([newLibrary1, newLibrary2], '''
 import 'dart:async';
 import 'dart:collection';
 import 'dart:html';
@@ -118,7 +147,7 @@
 ''');
     var newLibrary1 = _getDartSource('dart:html');
     var newLibrary2 = _getDartSource('dart:math');
-    await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+    await _assertAddLibraryImport([newLibrary1, newLibrary2], '''
 import 'dart:async';
 import 'dart:collection';
 import 'dart:html';
@@ -134,7 +163,7 @@
 ''');
     var newLibrary1 = _getDartSource('dart:math');
     var newLibrary2 = _getDartSource('dart:async');
-    await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+    await _assertAddLibraryImport([newLibrary1, newLibrary2], '''
 library test;
 
 import 'dart:async';
@@ -152,7 +181,7 @@
 ''');
     var newLibrary1 = _getDartSource('dart:math');
     var newLibrary2 = _getDartSource('dart:async');
-    await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+    await _assertAddLibraryImport([newLibrary1, newLibrary2], '''
 /// Comment.
 
 import 'dart:async';
@@ -170,7 +199,7 @@
 ''');
     var newLibrary1 = _getDartSource('dart:math');
     var newLibrary2 = _getDartSource('dart:async');
-    await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+    await _assertAddLibraryImport([newLibrary1, newLibrary2], '''
 #!/bin/dart
 
 import 'dart:async';
@@ -186,7 +215,7 @@
 ''');
     var newLibrary1 = _getDartSource('dart:math');
     var newLibrary2 = _getDartSource('dart:async');
-    await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+    await _assertAddLibraryImport([newLibrary1, newLibrary2], '''
 import 'dart:async';
 import 'dart:math';
 
@@ -211,7 +240,7 @@
 import 'package:aaa/aaa.dart';
 ''');
     var newLibrary = _getSource('/lib/bbb.dart', 'package:bbb/bbb.dart');
-    await _assertAddLibraryImport(<Source>[newLibrary], '''
+    await _assertAddLibraryImport([newLibrary], '''
 import 'dart:async';
 
 import 'package:aaa/aaa.dart';
@@ -236,7 +265,7 @@
 import 'package:bbb/bbb.dart';
 ''');
     var newLibrary = _getSource('/lib/aaa.dart', 'package:aaa/aaa.dart');
-    await _assertAddLibraryImport(<Source>[newLibrary], '''
+    await _assertAddLibraryImport([newLibrary], '''
 import 'dart:async';
 
 import 'package:aaa/aaa.dart';
@@ -264,7 +293,7 @@
 ''');
     var newLibrary1 = _getSource('/lib/bbb.dart', 'package:bbb/bbb.dart');
     var newLibrary2 = _getSource('/lib/ccc.dart', 'package:ccc/ccc.dart');
-    await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+    await _assertAddLibraryImport([newLibrary1, newLibrary2], '''
 import 'package:aaa/aaa.dart';
 import 'package:bbb/bbb.dart';
 import 'package:ccc/ccc.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/legacy/abstract_rename.dart b/pkg/analysis_server/test/services/refactoring/legacy/abstract_rename.dart
index 9bbe6a5..92e929c 100644
--- a/pkg/analysis_server/test/services/refactoring/legacy/abstract_rename.dart
+++ b/pkg/analysis_server/test/services/refactoring/legacy/abstract_rename.dart
@@ -40,9 +40,9 @@
   /// Creates a new [RenameRefactoring] in [refactoring] for the [Element] of
   /// the [SimpleIdentifier] at the given [search] pattern.
   void createRenameRefactoringAtString(String search) {
-    var identifier = findNode.simple(search);
+    var identifier = findNode.any(search);
     var element = ElementLocator.locate(identifier);
-    if (element is PrefixElement) {
+    if (identifier is SimpleIdentifier && element is PrefixElement) {
       element = getImportElement(identifier);
     }
     createRenameRefactoringForElement(element);
diff --git a/pkg/analysis_server/test/services/refactoring/legacy/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/legacy/extract_local_test.dart
index b2db53c..f54d74e 100644
--- a/pkg/analysis_server/test/services/refactoring/legacy/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/legacy/extract_local_test.dart
@@ -98,7 +98,8 @@
     // check conditions
     var status = await refactoring.checkAllConditions();
     assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage: 'Cannot extract the name part of a declaration.');
+        expectedMessage:
+            'Expression must be selected to activate this refactoring.');
   }
 
   Future<void>
@@ -112,7 +113,8 @@
     // check conditions
     var status = await refactoring.checkAllConditions();
     assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage: 'Cannot extract the name part of a declaration.');
+        expectedMessage:
+            'Expression must be selected to activate this refactoring.');
   }
 
   Future<void> test_checkInitialConditions_noExpression() async {
diff --git a/pkg/analysis_server/test/services/refactoring/legacy/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/legacy/extract_method_test.dart
index 759b9c5..5d14f75 100644
--- a/pkg/analysis_server/test/services/refactoring/legacy/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/legacy/extract_method_test.dart
@@ -423,7 +423,8 @@
 ''');
     _createRefactoringForString('f');
     return _assertConditionsFatal(
-        'Cannot extract the name part of a declaration.');
+        'The selection does not cover a set of statements or an expression. '
+        'Extend selection to a valid range.');
   }
 
   Future<void> test_bad_namePartOfDeclaration_variable() async {
@@ -434,7 +435,7 @@
 ''');
     _createRefactoringForString('vvv');
     return _assertConditionsFatal(
-        'Cannot extract the name part of a declaration.');
+        'Can only extract a single expression or a set of statements.');
   }
 
   Future<void> test_bad_namePartOfQualified() async {
@@ -1713,6 +1714,40 @@
 ''');
   }
 
+  Future<void> test_singleExpression_recordType_named() async {
+    await indexTestUnit('''
+void f() {
+  var r = (f1: 0, f2: true);
+}
+''');
+    _createRefactoringForString('(f1: 0, f2: true)');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+void f() {
+  var r = res();
+}
+
+({int f1, bool f2}) res() => (f1: 0, f2: true);
+''');
+  }
+
+  Future<void> test_singleExpression_recordType_positional() async {
+    await indexTestUnit('''
+void f() {
+  var r = (0, true);
+}
+''');
+    _createRefactoringForString('(0, true)');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+void f() {
+  var r = res();
+}
+
+(int, bool) res() => (0, true);
+''');
+  }
+
   Future<void> test_singleExpression_returnType_importLibrary() async {
     _addLibraryReturningAsync();
     await indexTestUnit('''
@@ -3059,6 +3094,29 @@
 ''');
   }
 
+  Future<void> test_statements_topFunction_parameters_recordType() async {
+    await indexTestUnit('''
+void f((int, String) r) {
+// start
+  print(r);
+// end
+}
+''');
+    _createRefactoringForStartEndComments();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+void f((int, String) r) {
+// start
+  res(r);
+// end
+}
+
+void res((int, String) r) {
+  print(r);
+}
+''');
+  }
+
   /// We have 3 identical statements, but select only 2.
   /// This should not cause problems.
   Future<void> test_statements_twoOfThree() async {
diff --git a/pkg/analysis_server/test/services/refactoring/legacy/inline_method_test.dart b/pkg/analysis_server/test/services/refactoring/legacy/inline_method_test.dart
index d504889..1ab60b6 100644
--- a/pkg/analysis_server/test/services/refactoring/legacy/inline_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/legacy/inline_method_test.dart
@@ -536,6 +536,24 @@
 ''');
   }
 
+  Future<void> test_function_hasReturn_hasReturnType_hasTypeParameters() async {
+    await indexTestUnit(r'''
+num test<T extends num>(T a, T b) {
+  return a + b;
+}
+void f() {
+  print(test(1, 2));
+}
+''');
+    _createRefactoring('test');
+    // validate change
+    return _assertSuccessfulRefactoring(r'''
+void f() {
+  print(1 + 2);
+}
+''');
+  }
+
   Future<void> test_function_hasReturn_noExpression() async {
     await indexTestUnit(r'''
 test(a, b) {
@@ -894,6 +912,46 @@
 ''');
   }
 
+  Future<void> test_function_startOfParameterList() async {
+    await indexTestUnit(r'''
+test(a, b) {
+  print(a);
+  print(b);
+}
+void f() {
+  test(1, 2);
+}
+''');
+    _createRefactoring('(a, b) {');
+    // validate change
+    return _assertSuccessfulRefactoring(r'''
+void f() {
+  print(1);
+  print(2);
+}
+''');
+  }
+
+  Future<void> test_function_startOfTypeParameterList() async {
+    await indexTestUnit(r'''
+test<T>(a, b) {
+  print(a);
+  print(b);
+}
+void f() {
+  test(1, 2);
+}
+''');
+    _createRefactoring('<T>');
+    // validate change
+    return _assertSuccessfulRefactoring(r'''
+void f() {
+  print(1);
+  print(2);
+}
+''');
+  }
+
   Future<void> test_getter_async_targetIsAsync() async {
     await indexTestUnit(r'''
 import 'dart:async';
diff --git a/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart
index 010a1ca..c464865 100644
--- a/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart
@@ -1487,6 +1487,95 @@
 ''');
   }
 
+  Future<void> test_createChange_FieldElement_private() async {
+    await indexTestUnit('''
+class C {
+  int? field;
+  C(this.field);
+}
+void f() {
+  var c = C(1);
+  c.field = 1;
+}
+''');
+    // configure refactoring
+    createRenameRefactoringAtString('field;');
+    expect(refactoring.refactoringName, 'Rename Field');
+    expect(refactoring.oldName, 'field');
+    refactoring.newName = '_field';
+    // validate change
+    return assertSuccessfulRefactoring('''
+class C {
+  int? _field;
+  C(this._field);
+}
+void f() {
+  var c = C(1);
+  c._field = 1;
+}
+''');
+  }
+
+  Future<void> test_createChange_FieldElement_private_initializer() async {
+    await indexTestUnit('''
+class C {
+  int? field;
+  int? other;
+  C({this.field}) : other = field;
+}
+void f() {
+  var c = C(field: 0);
+  c.field = 1;
+}
+''');
+    // configure refactoring
+    var element = findElement.field('field');
+    createRenameRefactoringForElement(element);
+    expect(refactoring.refactoringName, 'Rename Field');
+    expect(refactoring.oldName, 'field');
+    refactoring.newName = '_field';
+    // validate change
+    return assertSuccessfulRefactoring('''
+class C {
+  int? _field;
+  int? other;
+  C({int? field}) : _field = field, other = field;
+}
+void f() {
+  var c = C(field: 0);
+  c._field = 1;
+}
+''');
+  }
+
+  Future<void> test_createChange_FieldElement_private_positional() async {
+    await indexTestUnit('''
+class C {
+  int? field;
+  C([this.field]);
+}
+void f() {
+  C().field;
+}
+''');
+    // configure refactoring
+    var element = findElement.field('field');
+    createRenameRefactoringForElement(element);
+    expect(refactoring.refactoringName, 'Rename Field');
+    expect(refactoring.oldName, 'field');
+    refactoring.newName = '_field';
+    // validate change
+    return assertSuccessfulRefactoring('''
+class C {
+  int? _field;
+  C([this._field]);
+}
+void f() {
+  C()._field;
+}
+''');
+  }
+
   Future<void> test_createChange_MethodElement() async {
     await indexTestUnit('''
 enum E {
diff --git a/pkg/analysis_server/test/services/refactoring/legacy/rename_constructor_test.dart b/pkg/analysis_server/test/services/refactoring/legacy/rename_constructor_test.dart
index 118b635..a690c71 100644
--- a/pkg/analysis_server/test/services/refactoring/legacy/rename_constructor_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/legacy/rename_constructor_test.dart
@@ -568,7 +568,7 @@
 
 class _RenameConstructorTest extends RenameRefactoringTest {
   void _createConstructorDeclarationRefactoring(String search) {
-    var element = findNode.constructor(search).declaredElement2;
+    var element = findNode.constructor(search).declaredElement;
     createRenameRefactoringForElement(element);
   }
 
diff --git a/pkg/analysis_server/test/services/refactoring/legacy/rename_unit_member_test.dart b/pkg/analysis_server/test/services/refactoring/legacy/rename_unit_member_test.dart
index 4c6fc40..2f746a8 100644
--- a/pkg/analysis_server/test/services/refactoring/legacy/rename_unit_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/legacy/rename_unit_member_test.dart
@@ -519,6 +519,44 @@
 ''');
   }
 
+  Future<void>
+      test_createChange_ClassElement_inRecordTypeAnnotation_named() async {
+    await indexTestUnit('''
+class Test {}
+void f(({int foo, Test bar}) r) {}
+''');
+    // configure refactoring
+    createRenameRefactoringAtString('Test {}');
+    expect(refactoring.refactoringName, 'Rename Class');
+    expect(refactoring.elementKindName, 'class');
+    expect(refactoring.oldName, 'Test');
+    refactoring.newName = 'NewName';
+    // validate change
+    return assertSuccessfulRefactoring('''
+class NewName {}
+void f(({int foo, NewName bar}) r) {}
+''');
+  }
+
+  Future<void>
+      test_createChange_ClassElement_inRecordTypeAnnotation_positional() async {
+    await indexTestUnit('''
+class Test {}
+void f((int, Test) r) {}
+''');
+    // configure refactoring
+    createRenameRefactoringAtString('Test {}');
+    expect(refactoring.refactoringName, 'Rename Class');
+    expect(refactoring.elementKindName, 'class');
+    expect(refactoring.oldName, 'Test');
+    refactoring.newName = 'NewName';
+    // validate change
+    return assertSuccessfulRefactoring('''
+class NewName {}
+void f((int, NewName) r) {}
+''');
+  }
+
   Future<void> test_createChange_ClassElement_invocation() async {
     verifyNoTestUnitErrors = false;
     await indexTestUnit('''
diff --git a/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart b/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart
index c247892..ffefadf 100644
--- a/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/call_hierarchy_computer_test.dart
@@ -255,6 +255,40 @@
         ));
   }
 
+  Future<void> test_function_startOfParameterList() async {
+    final contents = '''
+/*1*/void myFunction^() {}/*1*/
+    ''';
+
+    await expectTarget(
+        contents,
+        _isItem(
+          CallHierarchyKind.function,
+          'myFunction',
+          testFile,
+          containerName: 'test.dart',
+          nameRange: rangeAtSearch('myFunction', contents),
+          codeRange: rangeNumbered(1, contents),
+        ));
+  }
+
+  Future<void> test_function_startOfTypeParameterList() async {
+    final contents = '''
+/*1*/void myFunction^<T>() {}/*1*/
+    ''';
+
+    await expectTarget(
+        contents,
+        _isItem(
+          CallHierarchyKind.function,
+          'myFunction',
+          testFile,
+          containerName: 'test.dart',
+          nameRange: rangeAtSearch('myFunction', contents),
+          codeRange: rangeNumbered(1, contents),
+        ));
+  }
+
   Future<void> test_functionCall() async {
     final contents = '''
 import 'other.dart' as f;
@@ -374,6 +408,44 @@
         ));
   }
 
+  Future<void> test_method_startOfParameterList() async {
+    final contents = '''
+class Foo {
+  /*1*/void myMethod^() {}/*1*/
+}
+    ''';
+
+    await expectTarget(
+        contents,
+        _isItem(
+          CallHierarchyKind.method,
+          'myMethod',
+          testFile,
+          containerName: 'Foo',
+          nameRange: rangeAtSearch('myMethod', contents),
+          codeRange: rangeNumbered(1, contents),
+        ));
+  }
+
+  Future<void> test_method_startOfTypeParameterList() async {
+    final contents = '''
+class Foo {
+  /*1*/void myMethod^<T>() {}/*1*/
+}
+    ''';
+
+    await expectTarget(
+        contents,
+        _isItem(
+          CallHierarchyKind.method,
+          'myMethod',
+          testFile,
+          containerName: 'Foo',
+          nameRange: rangeAtSearch('myMethod', contents),
+          codeRange: rangeNumbered(1, contents),
+        ));
+  }
+
   Future<void> test_methodCall() async {
     final contents = '''
 import 'other.dart';
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 4adaf63..a2b993d 100644
--- a/pkg/analysis_server/test/src/computer/folding_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
@@ -9,6 +9,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../abstract_context.dart';
+import '../../utils/test_code_format.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -25,6 +26,34 @@
   };
 
   late String sourcePath;
+  late TestCode code;
+  List<FoldingRegion> regions = [];
+
+  /// Expects no [FoldingRegion]s.
+  ///
+  /// If [onlyVerify] is provided, folding regions of other kinds are allowed.
+  void expectNoRegions({Set<FoldingKind>? onlyVerify}) {
+    expectRegions({}, onlyVerify: onlyVerify);
+  }
+
+  /// Expects to find a [FoldingRegion] for the code marked [index] with a
+  /// [FoldingKind] of [kind].
+  ///
+  /// If [onlyVerify] is provided, only folding regions with matching kinds will
+  /// be verified.
+  void expectRegions(Map<int, FoldingKind> expected,
+      {Set<FoldingKind>? onlyVerify}) {
+    final expectedRegions = expected.entries.map((entry) {
+      final range = code.ranges[entry.key].sourceRange;
+      return FoldingRegion(entry.value, range.offset, range.length);
+    }).toSet();
+
+    final actualRegions = onlyVerify == null
+        ? regions.toSet()
+        : regions.where((region) => onlyVerify.contains(region.kind)).toSet();
+
+    expect(actualRegions, expectedRegions);
+  }
 
   @override
   void setUp() {
@@ -32,203 +61,310 @@
     sourcePath = convertPath('$testPackageLibPath/test.dart');
   }
 
-  Future<void> test_annotations() async {
+  Future<void> test_annotations_class() async {
     var content = '''
-@myMultilineAnnotation/*1:INC*/(
+@folded.classAnnotation1/*[0*/()
+@foldedClassAnnotation2/*0]*/
+class MyClass {}
+''';
+
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.ANNOTATIONS,
+    });
+  }
+
+  Future<void> test_annotations_class_constructor() async {
+    var content = '''
+class MyClass {
+  @constructorAnnotation1/*[0*/
+  @constructorAnnotation1/*0]*/
+  MyClass() {}
+
+  @constructorAnnotation1/*[1*/
+  @constructorAnnotation1/*1]*/
+  MyClass.named() {}
+}
+''';
+
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.ANNOTATIONS,
+      1: FoldingKind.ANNOTATIONS,
+    }, onlyVerify: {
+      FoldingKind.ANNOTATIONS
+    });
+  }
+
+  Future<void> test_annotations_class_field() async {
+    var content = '''
+class MyClass {
+  @fieldAnnotation1/*[0*/
+  @fieldAnnotation2/*0]*/
+  int myField;
+}
+''';
+
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.ANNOTATIONS,
+    }, onlyVerify: {
+      FoldingKind.ANNOTATIONS
+    });
+  }
+
+  Future<void> test_annotations_class_getterSetter() async {
+    var content = '''
+class MyClass {
+  @getterAnnotation1/*[0*/
+  @getterAnnotation2/*0]*/
+  int get myThing => 1;
+
+  @setterAnnotation1/*[1*/
+  @setterAnnotation2/*1]*/
+  void set myThing(int value) {}
+}
+''';
+
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.ANNOTATIONS,
+      1: FoldingKind.ANNOTATIONS,
+    }, onlyVerify: {
+      FoldingKind.ANNOTATIONS
+    });
+  }
+
+  Future<void> test_annotations_class_method() async {
+    var content = '''
+class MyClass {
+  @methodAnnotation1/*[0*/
+  @methodAnnotation2/*0]*/
+  void myMethod() {}
+}
+''';
+
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.ANNOTATIONS,
+    }, onlyVerify: {
+      FoldingKind.ANNOTATIONS
+    });
+  }
+
+  Future<void> test_annotations_multiline() async {
+    var content = '''
+@myMultilineAnnotation/*[0*/(
   "this",
   "is a test"
-)/*1:EXC:ANNOTATIONS*/
+)/*0]*/
 void f() {}
+''';
 
-@noFoldNecessary
-main2() {}
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.ANNOTATIONS,
+    });
+  }
 
-@multipleAnnotations1/*2:INC*/(
+  Future<void> test_annotations_multiple() async {
+    var content = '''
+@multipleAnnotations1/*[0*/(
   "this",
   "is a test"
 )
 @multipleAnnotations2()
-@multipleAnnotations3/*2:EXC:ANNOTATIONS*/
+@multipleAnnotations3/*0]*/
 main3() {}
+''';
+
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.ANNOTATIONS,
+    });
+  }
+
+  Future<void> test_annotations_singleLine() async {
+    var content = '''
+@noFoldNecessary
+main2() {}
 
 @noFoldsForSingleClassAnnotation
 class MyClass {}
-
-@folded.classAnnotation1/*3:INC*/()
-@foldedClassAnnotation2/*3:EXC:ANNOTATIONS*/
-class MyClass2 {/*4:INC*/
-  @fieldAnnotation1/*5:INC*/
-  @fieldAnnotation2/*5:EXC:ANNOTATIONS*/
-  int myField;
-
-  @getterAnnotation1/*6:INC*/
-  @getterAnnotation2/*6:EXC:ANNOTATIONS*/
-  int get myThing => 1;
-
-  @setterAnnotation1/*7:INC*/
-  @setterAnnotation2/*7:EXC:ANNOTATIONS*/
-  void set myThing(int value) {}
-
-  @methodAnnotation1/*8:INC*/
-  @methodAnnotation2/*8:EXC:ANNOTATIONS*/
-  void myMethod() {}
-
-  @constructorAnnotation1/*9:INC*/
-  @constructorAnnotation1/*9:EXC:ANNOTATIONS*/
-  MyClass2() {}
-/*4:INC:CLASS_BODY*/}
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectNoRegions();
   }
 
   Future<void> test_assertInitializer() async {
     var content = '''
-class C {/*1:INC*/
-  C() : assert(/*2:INC*/
+class C {/*[0*/
+  C() : assert(/*[1*/
     true,
     ''
-  /*2:INC:INVOCATION*/);
-/*1:INC:CLASS_BODY*/}
+  /*1]*/);
+/*0]*/}
 ''';
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.CLASS_BODY,
+      1: FoldingKind.INVOCATION,
+    });
   }
 
   Future<void> test_assertStatement() async {
     var content = '''
-void f() {/*1:INC*/
-  assert(/*2:INC*/
+void f() {/*[0*/
+  assert(/*[1*/
     true,
     ''
-  /*2:INC:INVOCATION*/);
-/*1:INC:FUNCTION_BODY*/}
+  /*1]*/);
+/*0]*/}
 ''';
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FUNCTION_BODY,
+      1: FoldingKind.INVOCATION,
+    });
   }
 
   Future<void> test_class() async {
     var content = '''
 // Content before
 
-class Person {/*1:INC*/
-  Person() {/*2:INC*/
+class Person {/*[0*/
+  Person() {/*[1*/
     print("Hello, world!");
-  /*2:INC:FUNCTION_BODY*/}
+  /*1]*/}
 
-  void sayHello() {/*3:INC*/
+  void sayHello() {/*[2*/
     print("Hello, world!");
-  /*3:INC:FUNCTION_BODY*/}
-/*1:INC:CLASS_BODY*/}
+  /*2]*/}
+/*0]*/}
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.CLASS_BODY,
+      1: FoldingKind.FUNCTION_BODY,
+      2: FoldingKind.FUNCTION_BODY,
+    });
   }
 
   Future<void> test_comment_is_not_considered_file_header() async {
     var content = """
-// This is not the file header/*1:EXC*/
-// It's just a comment/*1:INC:COMMENT*/
+// This is not the file header/*[0*/
+// It's just a comment/*0]*/
 void f() {}
 """;
 
-    // Since there are no region comment markers above
-    // just check the length instead of the contents
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.COMMENT,
+    });
   }
 
   Future<void> test_comment_multiline() async {
     var content = '''
-void f() {
-/*/*1:EXC*/
+/*/*[0*/
  * comment 1
- *//*1:EXC:COMMENT*/
+ *//*0]*/
 
-/* this comment starts on the same line as delimeters/*2:EXC*/
+/* this comment starts on the same line as delimeters/*[1*/
  * second line
- *//*2:EXC:COMMENT*/
-}
+ *//*1]*/
+void f() {}
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content, commentKinds);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.COMMENT,
+      1: FoldingKind.COMMENT,
+    });
   }
 
   Future<void> test_comment_singleFollowedByBlankLine() async {
     var content = '''
 void f() {
-// this is/*1:EXC*/
-// a comment/*1:INC:COMMENT*/
+// this is/*[0*/
+// a comment/*0]*/
 /// this is not part of it
 }
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content, commentKinds);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.COMMENT,
+    }, onlyVerify: commentKinds);
   }
 
   Future<void> test_comment_singleFollowedByMulti() async {
     var content = '''
 void f() {
-  // this is/*1:EXC*/
-  // a comment/*1:INC:COMMENT*/
+  // this is/*[0*/
+  // a comment/*0]*/
   /* this is not part of it */
   String foo;
 }
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content, commentKinds);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.COMMENT,
+    }, onlyVerify: commentKinds);
   }
 
   Future<void> test_comment_singleFollowedByTripleSlash() async {
     var content = '''
 void f() {
-// this is/*1:EXC*/
-// a comment/*1:INC:COMMENT*/
+// this is/*[0*/
+// a comment/*0]*/
 /// this is not part of it
 }
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content, commentKinds);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.COMMENT,
+    }, onlyVerify: commentKinds);
   }
 
   Future<void> test_constructor_invocations() async {
     var content = '''
 // Content before
 
-void f() {/*1:INC*/
-  return new Text(/*2:INC*/
-    "Hello, world!",
-  /*2:INC:INVOCATION*/);
-/*1:INC:FUNCTION_BODY*/}
+final a = new Text(/*[0*/
+  "Hello, world!",
+/*0]*/);
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.INVOCATION,
+    });
   }
 
   Future<void> test_file_header() async {
     var content = """
-// Copyright some year by some people/*1:EXC*/
-// See LICENCE etc./*1:INC:FILE_HEADER*/
+// Copyright some year by some people/*[0*/
+// See LICENCE etc./*0]*/
 
 // This is not the file header
 // It's just a comment
 void f() {}
 """;
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content, {FoldingKind.FILE_HEADER});
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FILE_HEADER,
+    }, onlyVerify: {
+      FoldingKind.FILE_HEADER
+    });
   }
 
   Future<void> test_file_header_does_not_include_block_comments() async {
@@ -242,283 +378,358 @@
 void f() {}
 """;
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content, {FoldingKind.FILE_HEADER});
+    await _computeRegions(content);
+    expectNoRegions(onlyVerify: {FoldingKind.FILE_HEADER});
   }
 
   Future<void> test_file_header_with_no_function_comment() async {
     var content = '''
-// Copyright some year by some people/*1:EXC*/
-// See LICENCE etc./*1:INC:FILE_HEADER*/
+// Copyright some year by some people/*[0*/
+// See LICENCE etc./*0]*/
 
 void f() {}
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content, {FoldingKind.FILE_HEADER});
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FILE_HEADER,
+    });
   }
 
   Future<void> test_file_header_with_non_end_of_line_comment() async {
     var content = """
-// Copyright some year by some people/*1:EXC*/
-// See LICENCE etc./*1:INC:FILE_HEADER*/
+// Copyright some year by some people/*[0*/
+// See LICENCE etc./*0]*/
 /* This shouldn't be part of the file header */
 
 void f() {}
 """;
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content, {FoldingKind.FILE_HEADER});
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FILE_HEADER,
+    });
   }
 
   Future<void> test_file_header_with_script_prefix() async {
     var content = """
 #! /usr/bin/dart
-// Copyright some year by some people/*1:EXC*/
-// See LICENCE etc./*1:INC:FILE_HEADER*/
+// Copyright some year by some people/*[0*/
+// See LICENCE etc./*0]*/
 
 // This is not the file header
 // It's just a comment
 void f() {}
 """;
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content, {FoldingKind.FILE_HEADER});
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FILE_HEADER,
+    }, onlyVerify: {
+      FoldingKind.FILE_HEADER
+    });
   }
 
   Future<void> test_fileHeader_singleFollowedByBlank() async {
     var content = '''
-// this is/*1:EXC*/
-// a file header/*1:INC:FILE_HEADER*/
+// this is/*[0*/
+// a file header/*0]*/
 
 // this is not part of it
 void f() {}
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FILE_HEADER,
+    });
   }
 
   Future<void> test_function() async {
     var content = '''
 // Content before
 
-void f() {/*1:INC*/
+void f() {/*[0*/
   print("Hello, world!");
-/*1:INC:FUNCTION_BODY*/}
+/*0]*/}
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FUNCTION_BODY,
+    });
   }
 
   Future<void> test_function_expression_invocation() async {
     var content = '''
 // Content before
 
-getFunc() => (String a, String b) {/*1:INC*/
+getFunc() => (String a, String b) {/*[0*/
   print(a);
-/*1:INC:FUNCTION_BODY*/};
+/*0]*/};
 
-main2() {/*2:INC*/
-  getFunc()(/*3:INC*/
+main2() {/*[1*/
+  getFunc()(/*[2*/
     "one",
     "two"
-  /*3:INC:INVOCATION*/);
-/*2:INC:FUNCTION_BODY*/}
+  /*2]*/);
+/*1]*/}
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FUNCTION_BODY,
+      1: FoldingKind.FUNCTION_BODY,
+      2: FoldingKind.INVOCATION,
+    });
   }
 
   Future<void> test_function_with_dart_doc() async {
     var content = '''
 // Content before
 
-/// This is a doc comment/*1:EXC*/
-/// that spans lines/*1:INC:DOCUMENTATION_COMMENT*/
-void f() {/*2:INC*/
+/// This is a doc comment/*[0*/
+/// that spans lines/*0]*/
+void f() {/*[1*/
   print("Hello, world!");
-/*2:INC:FUNCTION_BODY*/}
+/*1]*/}
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.DOCUMENTATION_COMMENT,
+      1: FoldingKind.FUNCTION_BODY,
+    });
   }
 
   Future<void> test_invocations() async {
     var content = '''
 // Content before
 
-void f() {/*1:INC*/
-  print(/*2:INC*/
+void f() {/*[0*/
+  print(/*[1*/
     "Hello, world!",
-  /*2:INC:INVOCATION*/);
-/*1:INC:FUNCTION_BODY*/}
+  /*1]*/);
+/*0]*/}
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FUNCTION_BODY,
+      1: FoldingKind.INVOCATION,
+    });
   }
 
   Future<void> test_literal_list() async {
     var content = '''
 // Content before
 
-void f() {/*1:INC*/
-  final List<String> things = <String>[/*2:INC*/
+void f() {/*[0*/
+  final List<String> things = <String>[/*[1*/
     "one",
     "two"
-  /*2:INC:LITERAL*/];
-/*1:INC:FUNCTION_BODY*/}
+  /*1]*/];
+/*0]*/}
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FUNCTION_BODY,
+      1: FoldingKind.LITERAL,
+    });
   }
 
   Future<void> test_literal_map() async {
     var content = '''
 // Content before
 
-main2() {/*1:INC*/
-  final Map<String, String> things = <String, String>{/*2:INC*/
+main2() {/*[0*/
+  final Map<String, String> things = <String, String>{/*[1*/
     "one": "one",
     "two": "two"
-    /*2:INC:LITERAL*/};
-/*1:INC:FUNCTION_BODY*/}
+    /*1]*/};
+/*0]*/}
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FUNCTION_BODY,
+      1: FoldingKind.LITERAL,
+    });
+  }
+
+  Future<void> test_literal_record() async {
+    var content = '''
+// Content before
+
+void f() {/*[0*/
+  final r = (/*[1*/
+    "one",
+    2,
+    (/*[2*/
+    'nested',
+    3,
+    'field record',
+    /*2]*/),
+  /*1]*/);
+/*0]*/}
+
+// Content after
+''';
+
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FUNCTION_BODY,
+      1: FoldingKind.LITERAL,
+      2: FoldingKind.LITERAL,
+    });
   }
 
   Future<void> test_mixin() async {
     var content = '''
 // Content before
 
-mixin M {/*1:INC*/
-  void m() {/*3:INC*/
+mixin M {/*[0*/
+  void m() {/*[1*/
     print("Got to m");
-  /*3:INC:FUNCTION_BODY*/}
-/*1:INC:CLASS_BODY*/}
+  /*1]*/}
+/*0]*/}
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.CLASS_BODY,
+      1: FoldingKind.FUNCTION_BODY,
+    });
   }
 
   Future<void> test_multiple_directive_types() async {
     var content = """
-import/*1:INC*/ 'dart:async';
+import/*[0*/ 'dart:async';
 
 // We can have comments
 import 'package:a/b.dart';
 import 'package:b/c.dart';
 
-export '../a.dart';/*1:EXC:DIRECTIVES*/
+export '../a.dart';/*0]*/
 
 void f() {}
 """;
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.DIRECTIVES,
+    });
   }
 
   Future<void> test_multiple_import_directives() async {
     var content = """
-import/*1:INC*/ 'dart:async';
+import/*[0*/ 'dart:async';
 
 // We can have comments
 import 'package:a/b.dart';
 import 'package:b/c.dart';
 
-import '../a.dart';/*1:EXC:DIRECTIVES*/
+import '../a.dart';/*0]*/
 
 void f() {}
 """;
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.DIRECTIVES,
+    });
   }
 
   Future<void> test_nested_function() async {
     var content = '''
 // Content before
 
-void f() {/*1:INC*/
-  doPrint() {/*2:INC*/
+void f() {/*[0*/
+  doPrint() {/*[1*/
     print("Hello, world!");
-  /*2:INC:FUNCTION_BODY*/}
+  /*1]*/}
   doPrint();
-/*1:INC:FUNCTION_BODY*/}
+/*0]*/}
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FUNCTION_BODY,
+      1: FoldingKind.FUNCTION_BODY,
+    });
   }
 
   Future<void> test_nested_invocations() async {
     var content = '''
 // Content before
 
-void f() {/*1:INC*/
-  a(/*2:INC*/
-    b(/*3:INC*/
-      c(/*4:INC*/
+void f() {/*[0*/
+  a(/*[1*/
+    b(/*[2*/
+      c(/*[3*/
         d()
-      /*4:INC:INVOCATION*/),
-    /*3:INC:INVOCATION*/),
-  /*2:INC:INVOCATION*/);
-/*1:INC:FUNCTION_BODY*/}
+      /*3]*/),
+    /*2]*/),
+  /*1]*/);
+/*0]*/}
 
 // Content after
 ''';
 
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.FUNCTION_BODY,
+      1: FoldingKind.INVOCATION,
+      2: FoldingKind.INVOCATION,
+      3: FoldingKind.INVOCATION,
+    });
   }
 
   Future<void> test_parameters_function() async {
     var content = '''
-foo(/*1:INC*/
+foo(/*[0*/
   String aaaaa,
   String bbbbb, {
   String ccccc,
-  }/*1:INC:PARAMETERS*/) {}
+  }/*0]*/) {}
 ''';
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.PARAMETERS,
+    });
   }
 
   Future<void> test_parameters_method() async {
     var content = '''
-class C {/*1:INC*/
-  C(/*2:INC*/
+class C {/*[0*/
+  C(/*[1*/
     String aaaaa,
     String bbbbb,
-  /*2:INC:PARAMETERS*/) : super();
-/*1:INC:CLASS_BODY*/}
+  /*1]*/) : super();
+/*0]*/}
 ''';
-    final regions = await _computeRegions(content);
-    _compareRegions(regions, content);
+    await _computeRegions(content);
+    expectRegions({
+      0: FoldingKind.CLASS_BODY,
+      1: FoldingKind.PARAMETERS,
+    });
   }
 
   Future<void> test_single_import_directives() async {
@@ -528,62 +739,16 @@
 void f() {}
 """;
 
-    // Since there are no region comment markers above
-    // just check the length instead of the contents
-    final regions = await _computeRegions(content);
-    expect(regions, hasLength(0));
+    await _computeRegions(content);
+    expectNoRegions();
   }
 
-  /// Compares provided folding regions with expected
-  /// regions extracted from the comments in the provided content.
-  ///
-  /// If [onlyKinds] is supplied only regions of that type will be compared.
-  void _compareRegions(List<FoldingRegion> regions, String content,
-      [Set<FoldingKind>? onlyKinds]) {
-    // Find all numeric markers for region starts.
-    final regex = RegExp(r'/\*(\d+):(INC|EXC)\*/');
-    final expectedRegions = regex.allMatches(content);
-
-    if (onlyKinds != null) {
-      regions =
-          regions.where((region) => onlyKinds.contains(region.kind)).toList();
-    }
-
-    // Check we didn't get more than expected, since the loop below only
-    // checks for the presence of matches, not absence.
-    expect(regions, hasLength(expectedRegions.length));
-
-    // Go through each marker, find the expected region start/end and
-    // ensure it's in the results.
-    for (var m in expectedRegions) {
-      final i = m.group(1);
-      final inclusiveStart = m.group(2) == 'INC';
-      // Find the end marker.
-      final endMatch =
-          RegExp('/\\*$i:(INC|EXC):(.+?)\\*/').firstMatch(content)!;
-
-      final inclusiveEnd = endMatch.group(1) == 'INC';
-      final expectedKindString = endMatch.group(2);
-      final expectedKind = FoldingKind.VALUES.firstWhere(
-          (f) => f.toString() == 'FoldingKind.$expectedKindString',
-          orElse: () => throw Exception(
-              'Annotated test code references $expectedKindString but '
-              'this does not exist in FoldingKind'));
-
-      final expectedStart = inclusiveStart ? m.start : m.end;
-      final expectedLength =
-          (inclusiveEnd ? endMatch.end : endMatch.start) - expectedStart;
-
-      expect(regions,
-          contains(FoldingRegion(expectedKind, expectedStart, expectedLength)));
-    }
-  }
-
-  Future<List<FoldingRegion>> _computeRegions(String sourceContent) async {
-    newFile(sourcePath, sourceContent);
+  Future<void> _computeRegions(String sourceContent) async {
+    code = TestCode.parse(sourceContent);
+    newFile(sourcePath, code.code);
     var result =
         await (await session).getResolvedUnit(sourcePath) as ResolvedUnitResult;
     var computer = DartUnitFoldingComputer(result.lineInfo, result.unit);
-    return computer.compute();
+    regions = computer.compute();
   }
 }
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 e4e1704..dc08d2a 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
@@ -7,10 +7,12 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:linter/src/rules.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../abstract_context.dart';
+import '../../analysis_server_base.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -61,15 +63,41 @@
     path = convertPath('$testPackageLibPath/test.dart');
   }
 
+  Future<void> test_createEdits_addImport_doubleQuotes() async {
+    registerLintRules();
+    var config = AnalysisOptionsFileConfig(
+      lints: ['prefer_double_quotes'],
+    );
+    newAnalysisOptionsYamlFile(
+      testPackageRootPath,
+      config.toContent(),
+    );
+
+    await createBuilder('''
+void f() {
+  // paste here
+}
+''');
+    await computeChanges([
+      ImportedElements(convertPath('/sdk/lib/math/math.dart'), '', ['Random'])
+    ]);
+    assertChanges('''
+import "dart:math";
+
+void f() {
+  // paste here
+}
+''');
+  }
+
   Future<void> test_createEdits_addImport_noDirectives() async {
     await createBuilder('''
 void f() {
   // paste here
 }
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(
-          convertPath('/sdk/lib/math/math.dart'), '', <String>['Random'])
+    await computeChanges([
+      ImportedElements(convertPath('/sdk/lib/math/math.dart'), '', ['Random'])
     ]);
     assertChanges('''
 import 'dart:math';
@@ -91,8 +119,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' as foo;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' as foo;
@@ -111,8 +139,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart';
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, 'foo', <String>['A'])
+    await computeChanges([
+      ImportedElements(fooFile.path, 'foo', ['A'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart';
@@ -132,8 +160,8 @@
 import 'package:pkg/foo.dart' show B;
 import 'package:pkg/foo.dart' as foo;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A', 'C'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A', 'C'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' show B, A, C;
@@ -152,8 +180,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' show A, B hide C, D;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['C'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['C'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' show A, B, C hide D;
@@ -171,8 +199,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' show B;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' show B, A;
@@ -191,8 +219,8 @@
 import 'package:pkg/foo.dart' show C;
 import 'package:pkg/foo.dart' as foo show B;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, 'foo', <String>['A'])
+    await computeChanges([
+      ImportedElements(fooFile.path, 'foo', ['A'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' show C;
@@ -211,8 +239,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart';
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A', 'B'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A', 'B'])
     ]);
     assertNoChanges();
   }
@@ -228,8 +256,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' as foo;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, 'foo', <String>['A', 'B'])
+    await computeChanges([
+      ImportedElements(fooFile.path, 'foo', ['A', 'B'])
     ]);
     assertNoChanges();
   }
@@ -245,8 +273,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' show A;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A'])
     ]);
     assertNoChanges();
   }
@@ -257,8 +285,8 @@
   A parent;
 }
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(path, '', <String>['A'])
+    await computeChanges([
+      ImportedElements(path, '', ['A'])
     ]);
     assertNoChanges();
   }
@@ -274,8 +302,8 @@
     await createBuilder('''
 import 'pakage:pkg/foo.dart';
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A'])
     ]);
     assertChanges('''
 import 'pakage:pkg/foo.dart';
@@ -285,7 +313,7 @@
 
   Future<void> test_createEdits_noElements() async {
     await createBuilder('');
-    await computeChanges(<ImportedElements>[]);
+    await computeChanges([]);
     assertNoChanges();
   }
 
@@ -300,8 +328,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' hide A, B, C;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' hide B, C;
@@ -319,8 +347,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' hide A, B, C;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['C'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['C'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' hide A, B;
@@ -338,8 +366,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' hide A, B, C;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['B'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['B'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' hide A, C;
@@ -357,8 +385,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' hide A, B, C hide A, B, C;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['B'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['B'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' hide A, C hide A, C;
@@ -376,8 +404,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' hide A, B, C hide D, E, F hide G, H, I;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A', 'E', 'I'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A', 'E', 'I'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' hide B, C hide D, F hide G, H;
@@ -395,8 +423,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' hide A hide B hide C;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' hide B hide C;
@@ -414,8 +442,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' hide A hide B hide C;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['C'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['C'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' hide A hide B;
@@ -433,8 +461,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' hide A hide B hide C;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['B'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['B'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart' hide A hide C;
@@ -452,8 +480,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' hide A;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart';
@@ -471,8 +499,8 @@
     await createBuilder('''
 import 'package:pkg/foo.dart' hide A, B;
 ''');
-    await computeChanges(<ImportedElements>[
-      ImportedElements(fooFile.path, '', <String>['A', 'B'])
+    await computeChanges([
+      ImportedElements(fooFile.path, '', ['A', 'B'])
     ]);
     assertChanges('''
 import 'package:pkg/foo.dart';
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 dcf19c6..fd4ddcb 100644
--- a/pkg/analysis_server/test/src/computer/outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
@@ -1572,6 +1572,73 @@
     }
   }
 
+  Future<void> test_topLevelFunction_recordTypes() async {
+    var unitOutline = await _computeOutline('''
+(int, int) f((String, String) r) => throw '';
+''');
+
+    var topOutlines = unitOutline.children!;
+    expect(topOutlines, hasLength(1));
+
+    assertJsonText(topOutlines[0], '''
+{
+  "element": {
+    "kind": "FUNCTION",
+    "name": "f",
+    "location": {
+      "file": $testPathJson,
+      "offset": 11,
+      "length": 1,
+      "startLine": 1,
+      "startColumn": 12,
+      "endLine": 1,
+      "endColumn": 13
+    },
+    "flags": 8,
+    "parameters": "((String, String) r)",
+    "returnType": "(int, int)"
+  },
+  "offset": 0,
+  "length": 45,
+  "codeOffset": 0,
+  "codeLength": 45
+}
+''');
+  }
+
+  Future<void> test_topLevelVariable_recordTypes() async {
+    var unitOutline = await _computeOutline('''
+(int, int)? r = null;
+''');
+
+    var topOutlines = unitOutline.children!;
+    expect(topOutlines, hasLength(1));
+
+    assertJsonText(topOutlines[0], '''
+{
+  "element": {
+    "kind": "TOP_LEVEL_VARIABLE",
+    "name": "r",
+    "location": {
+      "file": $testPathJson,
+      "offset": 12,
+      "length": 1,
+      "startLine": 1,
+      "startColumn": 13,
+      "endLine": 1,
+      "endColumn": 14
+    },
+    "flags": 0,
+    "returnType": "(int, int)?"
+  },
+  "offset": 0,
+  "length": 21,
+  "codeOffset": 12,
+  "codeLength": 8
+}
+''');
+  }
+
   void _expect(Outline outline,
       {ElementKind? kind,
       bool leaf = false,
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 63f1294..05be3b9 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
@@ -103,6 +103,28 @@
     );
   }
 
+  Future<void> test_field_recordType() async {
+    final content = '''
+class C<T> {
+  (int, int) r = (0, 1);
+}
+''';
+    final offset = content.indexOf('int');
+
+    final regions = await _computeSelectionRanges(content, offset);
+    _expectRegions(
+      regions,
+      content,
+      [
+        'int',
+        '(int, int)',
+        '(int, int) r = (0, 1)',
+        '(int, int) r = (0, 1);',
+        'class C<T> {\n  (int, int) r = (0, 1);\n}',
+      ],
+    );
+  }
+
   Future<void> test_method() async {
     final content = '''
 class Foo<T> {
@@ -182,6 +204,33 @@
     );
   }
 
+  Future<void> test_topLevelFunction_record() async {
+    final content = '''
+void f() {
+  var r = (x: 3, y: 2);
+}
+''';
+    final offset = content.indexOf('y');
+
+    final regions = await _computeSelectionRanges(content, offset);
+    _expectRegions(
+      regions,
+      content,
+      [
+        'y',
+        'y:',
+        'y: 2',
+        '(x: 3, y: 2)',
+        'r = (x: 3, y: 2)',
+        'var r = (x: 3, y: 2)',
+        'var r = (x: 3, y: 2);',
+        '{\n  var r = (x: 3, y: 2);\n}',
+        '() {\n  var r = (x: 3, y: 2);\n}',
+        'void f() {\n  var r = (x: 3, y: 2);\n}',
+      ],
+    );
+  }
+
   Future<void> test_whitespace() async {
     final content = '    class Foo {}';
     final offset = 0;
diff --git a/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart b/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
index f866620..6322535 100644
--- a/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
+++ b/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
@@ -660,6 +660,162 @@
 ''', 'int');
   }
 
+  Future<void> test_recordLiteral_named_afterPositional_1() async {
+    await assertContextType('''
+(int a, {String b}) f() => (0, b: ^);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_named_afterPositional_2() async {
+    await assertContextType('''
+(int a, int b, {String c}) f() => (0, c: ^, 1);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_named_first_afterColon_1() async {
+    await assertContextType('''
+({int a, String b}) f() => (b: ^);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_named_first_afterColon_2() async {
+    await assertContextType('''
+({int a, String b}) f() => (b:^);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_named_first_afterColon_3() async {
+    await assertContextType('''
+({int a, String b}) f() => (b: x^);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_named_first_inName() async {
+    await assertContextType('''
+({int a, String b}) f() => (b^:);
+''');
+  }
+
+  Future<void> test_recordLiteral_positional_afterNamed_existing_1() async {
+    await assertContextType('''
+(int, String, {int foo}) f() => (foo: 0, ^);
+''', 'int');
+  }
+
+  Future<void> test_recordLiteral_positional_afterNamed_existing_2() async {
+    await assertContextType('''
+(int, String, {int foo}) f() => (0, foo: 0, ^);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_positional_afterNamed_notExisting() async {
+    await assertContextType('''
+(int, String) f() => (foo: 0, ^);
+''', 'int');
+  }
+
+  Future<void> test_recordLiteral_positional_afterPositional_1() async {
+    await assertContextType('''
+(int, String) f() => (0, ^);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_positional_afterPositional_2() async {
+    await assertContextType('''
+(int, String) f() => (0, x^);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_positional_afterPositional_3() async {
+    await assertContextType('''
+(int, String) f() => (0, ^x);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_positional_afterPositional_4() async {
+    await assertContextType('''
+(int, String) f() => (0, x^y);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_positional_afterPositional_hasNext_1() async {
+    await assertContextType('''
+(int, String) f() => (0, ^, 42);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_positional_afterPositional_hasNext_2() async {
+    await assertContextType('''
+(int, String) f() => (0, x^, 42);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_positional_afterPositional_hasNext_3() async {
+    await assertContextType('''
+(int, String) f() => (0, ^x, 42);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_positional_asNamed() async {
+    await assertContextType('''
+(int a, String b) f() => (b: ^);
+''');
+  }
+
+  Future<void> test_recordLiteral_positional_beforeNamed_noComma_1() async {
+    await assertContextType('''
+(int, String) f() => (^ foo: 0);
+''', 'int');
+  }
+
+  Future<void> test_recordLiteral_positional_beforeNamed_noComma_2() async {
+    await assertContextType('''
+(int, String) f() => (0, ^ foo: 0);
+''', 'String');
+  }
+
+  Future<void> test_recordLiteral_positional_first_1() async {
+    await assertContextType('''
+(int, String) f() => (^);
+''', 'int');
+  }
+
+  Future<void> test_recordLiteral_positional_first_2() async {
+    await assertContextType('''
+(int, String) f() => (x^);
+''', 'int');
+  }
+
+  Future<void> test_recordLiteral_positional_first_3() async {
+    await assertContextType('''
+(int, String) f() => (^x);
+''', 'int');
+  }
+
+  Future<void> test_recordLiteral_positional_first_4() async {
+    await assertContextType('''
+(int, String) f() => (x^y);
+''', 'int');
+  }
+
+  Future<void> test_recordLiteral_positional_first_5() async {
+    await assertContextType('''
+(int, String) f() => (^,);
+''', 'int');
+  }
+
+  Future<void> test_recordLiteral_positional_first_6() async {
+    await assertContextType('''
+(int, String) f() => ( ^ ,);
+''', 'int');
+  }
+
+  Future<void> test_recordLiteral_positional_tooMany() async {
+    await assertContextType('''
+(int, double) f() => (0, 1, ^);
+''');
+  }
+
   Future<void> test_setOrMapLiteral_map_beforeTypeParameter() async {
     await assertContextType('''
 void f() {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart
index 92a8449..923ec88 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart
@@ -49,6 +49,97 @@
 ''');
   }
 
+  Future<void> test_indentation_last() async {
+    await resolveTestCode('''
+/**
+ * AAAAAAA
+  */
+class A {}
+''');
+    await assertHasAssistAt('AAAAAAA', '''
+/// AAAAAAA
+class A {}
+''');
+  }
+
+  Future<void> test_indentation_middle() async {
+    await resolveTestCode('''
+/**
+  * AAAAAAA
+ */
+class A {}
+''');
+    await assertHasAssistAt('AAAAAAA', '''
+/// AAAAAAA
+class A {}
+''');
+  }
+
+  Future<void> test_multiLine() async {
+    await resolveTestCode('''
+class A {
+  /**
+   * AAAAAAA
+   *
+   *    while (i < 100) {
+   *      i++;
+   *    }
+   */
+  mmm() {}
+}
+''');
+    await assertHasAssistAt('AAA', '''
+class A {
+  /// AAAAAAA
+  ///
+  ///    while (i < 100) {
+  ///      i++;
+  ///    }
+  mmm() {}
+}
+''');
+  }
+
+  Future<void> test_multiLine_lastLine() async {
+    await resolveTestCode('''
+class A {
+  /**
+   * AAAAAAA
+   *
+   *    while (i < 100) {
+   *      i++;
+   *    }  */
+  mmm() {}
+}
+''');
+    await assertHasAssistAt('AAA', '''
+class A {
+  /// AAAAAAA
+  ///
+  ///    while (i < 100) {
+  ///      i++;
+  ///    }
+  mmm() {}
+}
+''');
+  }
+
+  Future<void> test_multipleLines() async {
+    await resolveTestCode('''
+class A {
+  /**
+   * AAAAAAA */
+  mmm() {}
+}
+''');
+    await assertHasAssistAt('AAA', '''
+class A {
+  /// AAAAAAA
+  mmm() {}
+}
+''');
+  }
+
   Future<void> test_notDocumentation() async {
     await resolveTestCode('''
 /* AAAA */
@@ -147,4 +238,19 @@
 }
 ''');
   }
+
+  Future<void> test_singleLine() async {
+    await resolveTestCode('''
+class A {
+  /** AAAAAAA */
+  mmm() {}
+}
+''');
+    await assertHasAssistAt('AAA', '''
+class A {
+  /// AAAAAAA
+  mmm() {}
+}
+''');
+  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart b/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart
index f55670e..635d933 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart
@@ -51,8 +51,8 @@
 
   /// AAA
   /// BBB
-  set test(int test) {
-    _test = test;
+  set test(int value) {
+    _test = value;
   }
 }
 ''');
@@ -93,8 +93,8 @@
 
   int get test => _test;
 
-  set test(int test) {
-    _test = test;
+  set test(int value) {
+    _test = value;
   }
   A(this._test);
 }
@@ -116,8 +116,8 @@
 
   int get test => _test;
 
-  set test(int test) {
-    _test = test;
+  set test(int value) {
+    _test = value;
   }
 }
 ''');
@@ -135,6 +135,71 @@
     await assertNoAssistAt('bbb ');
   }
 
+  Future<void> test_named() async {
+    await resolveTestCode('''
+class A {
+  int? field;
+  A({int? field}) : field = field;
+}
+''');
+    await assertHasAssistAt('field', '''
+class A {
+  int? _field;
+
+  int? get field => _field;
+
+  set field(int? value) {
+    _field = value;
+  }
+  A({int? field}) : _field = field;
+}
+''');
+  }
+
+  Future<void> test_named_formalParameter() async {
+    await resolveTestCode('''
+class A {
+  int? field;
+  A({this.field});
+}
+''');
+    await assertHasAssistAt('field', '''
+class A {
+  int? _field;
+
+  int? get field => _field;
+
+  set field(int? value) {
+    _field = value;
+  }
+  A({int? field}) : _field = field;
+}
+''');
+  }
+
+  Future<void> test_named_super_initializer() async {
+    await resolveTestCode('''
+class A {}
+class B extends A {
+  int? field;
+  B({this.field}) : super();
+}
+''');
+    await assertHasAssistAt('field', '''
+class A {}
+class B extends A {
+  int? _field;
+
+  int? get field => _field;
+
+  set field(int? value) {
+    _field = value;
+  }
+  B({int? field}) : _field = field, super();
+}
+''');
+  }
+
   Future<void> test_notOnName() async {
     await resolveTestCode('''
 class A {
@@ -159,8 +224,8 @@
 
   get test => _test;
 
-  set test(test) {
-    _test = test;
+  set test(value) {
+    _test = value;
   }
 }
 void f(A a) {
@@ -182,6 +247,27 @@
     await assertNoAssistAt('; // marker');
   }
 
+  Future<void> test_positional() async {
+    await resolveTestCode('''
+class A {
+  int? field;
+  A([this.field]);
+}
+''');
+    await assertHasAssistAt('field', '''
+class A {
+  int? _field;
+
+  int? get field => _field;
+
+  set field(int? value) {
+    _field = value;
+  }
+  A([this._field]);
+}
+''');
+  }
+
   Future<void> test_static() async {
     await resolveTestCode('''
 class A {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart
index bf52357..bcf880b 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart
@@ -33,6 +33,69 @@
     );
   }
 
+  Future<void> test_builder_blockFunctionBody() async {
+    await resolveTestCode('''
+import 'package:flutter/material.dart';
+void f() {
+  /*caret*/Builder(
+    builder: (context) {
+      return Text('');
+    }
+  );
+}
+''');
+    await assertHasAssist('''
+import 'package:flutter/material.dart';
+void f() {
+  Text('');
+}
+''');
+  }
+
+  Future<void> test_builder_blockFunctionBody_many_statements() async {
+    await resolveTestCode('''
+import 'package:flutter/material.dart';
+void f() {
+  /*caret*/Builder(
+    builder: (context) {
+      var i = 1;
+      return Text('');
+    }
+  );
+}
+''');
+    await assertNoAssist();
+  }
+
+  Future<void> test_builder_expressionFunctionBody() async {
+    await resolveTestCode('''
+import 'package:flutter/material.dart';
+void f() {
+  /*caret*/Builder(
+    builder: (context) => Text('')
+  );
+}
+''');
+    await assertHasAssist('''
+import 'package:flutter/material.dart';
+void f() {
+  Text('');
+}
+''');
+  }
+
+  Future<void> test_builder_parameter_used() async {
+    await resolveTestCode('''
+import 'package:flutter/material.dart';
+void f() {
+  /*caret*/Builder(
+    builder: (context) => context.widget
+  );
+}
+''');
+    await assertNoAssist();
+  }
+
   Future<void> test_childIntoChild_multiLine() async {
     await resolveTestCode('''
 import 'package:flutter/material.dart';
@@ -240,6 +303,52 @@
 }
 ''');
   }
+
+  Future<void> test_prefixedConstructor_onConstructor() async {
+    await resolveTestCode('''
+import 'package:flutter/material.dart';
+import 'package:flutter/material.dart' as m;
+void f() {
+  Center(
+    child: m./*caret*/Center(
+      child: Text(''),
+    ),
+  );
+}
+''');
+    await assertHasAssist('''
+import 'package:flutter/material.dart';
+import 'package:flutter/material.dart' as m;
+void f() {
+  Center(
+    child: Text(''),
+  );
+}
+''');
+  }
+
+  Future<void> test_prefixedConstructor_onPrefix() async {
+    await resolveTestCode('''
+import 'package:flutter/material.dart';
+import 'package:flutter/material.dart' as m;
+void f() {
+  Center(
+    child: /*caret*/m.Center(
+      child: Text(''),
+    ),
+  );
+}
+''');
+    await assertHasAssist('''
+import 'package:flutter/material.dart';
+import 'package:flutter/material.dart' as m;
+void f() {
+  Center(
+    child: Text(''),
+  );
+}
+''');
+  }
 }
 
 @reflectiveTest
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 1024290..77754e6 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
@@ -76,6 +76,20 @@
 ''');
   }
 
+  Future<void> test_onName_recordType() async {
+    await resolveTestCode('''
+void f() {
+  (int, int) v = (1, 2);
+}
+''');
+    await assertHasAssistAt('v =', '''
+void f() {
+  (int, int) v;
+  v = (1, 2);
+}
+''');
+  }
+
   Future<void> test_onType() async {
     await resolveTestCode('''
 void f() {
@@ -105,6 +119,20 @@
 ''');
   }
 
+  Future<void> test_onType_recordType() async {
+    await resolveTestCode('''
+void f() {
+  (int, int) v = (1, 2);
+}
+''');
+    await assertHasAssistAt('int)', '''
+void f() {
+  (int, int) v;
+  v = (1, 2);
+}
+''');
+  }
+
   Future<void> test_onVar() async {
     await resolveTestCode('''
 void f() {
@@ -119,6 +147,20 @@
 ''');
   }
 
+  Future<void> test_onVar_recordLiteral() async {
+    await resolveTestCode('''
+void f() {
+  var v = (1, 2);
+}
+''');
+    await assertHasAssistAt('var', '''
+void f() {
+  (int, int) v;
+  v = (1, 2);
+}
+''');
+  }
+
   Future<void> test_privateType() async {
     addSource('$testPackageLibPath/a.dart', '''
 class A {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart b/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart
index 21961e5..27defa5 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart
@@ -20,6 +20,40 @@
   @override
   AssistKind get kind => DartAssistKind.USE_CURLY_BRACES;
 
+  Future<void> test_comment() async {
+    await resolveTestCode('''
+void f() {
+  /*caret*/while (true)
+    print(0); // something
+}
+''');
+    await assertHasAssist('''
+void f() {
+  while (true) {
+    print(0); // something
+  }
+}
+''');
+  }
+
+  Future<void> test_comment_outside() async {
+    await resolveTestCode('''
+void f() {
+  /*caret*/while (true)
+    print(0);
+  // something
+}
+''');
+    await assertHasAssist('''
+void f() {
+  while (true) {
+    print(0);
+  }
+  // something
+}
+''');
+  }
+
   Future<void> test_do_block() async {
     await resolveTestCode('''
 void f() {
@@ -61,6 +95,22 @@
 ''');
   }
 
+  Future<void> test_do_comment() async {
+    await resolveTestCode('''
+void f() {
+  /*caret*/do print(0); // something
+    while (true);
+}
+''');
+    await assertHasAssist('''
+void f() {
+  do {
+    print(0); // something
+  } while (true);
+}
+''');
+  }
+
   Future<void> test_do_condition() async {
     await resolveTestCode('''
 void f() {
@@ -308,6 +358,25 @@
 ''');
   }
 
+  Future<void> test_if_keyword_withElse_comment() async {
+    await resolveTestCode('''
+void f(int a) {
+  /*caret*/if (a == 0)
+    print(0); // something
+  else print(1);
+}
+''');
+    await assertHasAssist('''
+void f(int a) {
+  if (a == 0) {
+    print(0); // something
+  } else {
+    print(1);
+  }
+}
+''');
+  }
+
   Future<void> test_if_keyword_withoutElse() async {
     await resolveTestCode('''
 void f(int a) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart
index bdcfb2a..a152756 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart
@@ -20,6 +20,27 @@
   @override
   FixKind get kind => DartFixKind.ADD_EXPLICIT_CAST;
 
+  Future<void> test_argument() async {
+    await resolveTestCode('''
+void g(B b) {
+}
+void f(A a) {
+  g(a);
+}
+class A {}
+class B {}
+''');
+    await assertHasFix('''
+void g(B b) {
+}
+void f(A a) {
+  g(a as B);
+}
+class A {}
+class B {}
+''');
+  }
+
   Future<void> test_as() async {
     await resolveTestCode('''
 f(A a) {
@@ -76,6 +97,27 @@
 ''');
   }
 
+  Future<void> test_assignment_iterable_to_set() async {
+    await resolveTestCode('''
+f(List<A> a) {
+  Set<B> b;
+  b = a.where((e) => e is B).toSet();
+  print(b);
+}
+class A {}
+class B {}
+''');
+    await assertHasFix('''
+f(List<A> a) {
+  Set<B> b;
+  b = a.where((e) => e is B).cast<B>().toSet();
+  print(b);
+}
+class A {}
+class B {}
+''');
+  }
+
   Future<void> test_assignment_list() async {
     await resolveTestCode('''
 f(List<A> a) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_extension_override_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_extension_override_test.dart
new file mode 100644
index 0000000..6e3f949
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_extension_override_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2022, 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.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AddExtensionOverrideTest);
+  });
+}
+
+@reflectiveTest
+class AddExtensionOverrideTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.ADD_EXTENSION_OVERRIDE;
+
+  Future<void> test_no_name() async {
+    await resolveTestCode('''
+extension E on int {
+  int get a => 1;
+}
+extension on int {
+  set a(int v) {}
+}
+f() {
+  0.a;
+}
+''');
+    await assertHasFix('''
+extension E on int {
+  int get a => 1;
+}
+extension on int {
+  set a(int v) {}
+}
+f() {
+  E(0).a;
+}
+''', expectedNumberOfFixesForKind: 1, errorFilter: (error) {
+      return error.errorCode ==
+          CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS;
+    });
+  }
+
+  Future<void> test_no_parentheses() async {
+    await resolveTestCode('''
+extension E on int {
+  int get a => 1;
+}
+extension E2 on int {
+  set a(int v) {}
+}
+f() {
+  0.a;
+}
+''');
+    await assertHasFix('''
+extension E on int {
+  int get a => 1;
+}
+extension E2 on int {
+  set a(int v) {}
+}
+f() {
+  E(0).a;
+}
+''');
+
+    await assertHasFixesWithoutApplying(
+        expectedNumberOfFixesForKind: 2,
+        matchFixMessages: [
+          "Add an extension override for 'E'",
+          "Add an extension override for 'E2'",
+        ]);
+  }
+
+  Future<void> test_parentheses() async {
+    await resolveTestCode('''
+extension E on int {
+  int get a => 1;
+}
+extension E2 on int {
+  set a(int v) {}
+}
+f() {
+  (0).a;
+}
+''');
+    await assertHasFix('''
+extension E on int {
+  int get a => 1;
+}
+extension E2 on int {
+  set a(int v) {}
+}
+f() {
+  E(0).a;
+}
+''');
+
+    await assertHasFixesWithoutApplying(
+        expectedNumberOfFixesForKind: 2,
+        matchFixMessages: [
+          "Add an extension override for 'E'",
+          "Add an extension override for 'E2'",
+        ]);
+  }
+}
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 9f07038..f4b1faf 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
@@ -7,6 +7,7 @@
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../analysis_server_base.dart';
 import 'fix_processor.dart';
 
 void main() {
@@ -360,6 +361,29 @@
 ''');
   }
 
+  Future<void> test_doubleQuotes() async {
+    var config = AnalysisOptionsFileConfig(
+      lints: ['prefer_double_quotes'],
+    );
+    newAnalysisOptionsYamlFile(
+      testPackageRootPath,
+      config.toContent(),
+    );
+
+    await resolveTestCode('''
+test({required String a}) {}
+void f() {
+  test();
+}
+''');
+    await assertHasFix('''
+test({required String a}) {}
+void f() {
+  test(a: "");
+}
+''');
+  }
+
   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 57f1f34c..5c8fe18 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
@@ -98,6 +98,25 @@
 ''');
   }
 
+  Future<void> test_binaryExpression_operator() async {
+    await resolveTestCode('''
+class C {
+  String operator +(String s) => '';
+}
+void f(C? c) {
+  c + '';
+}
+''');
+    await assertHasFix('''
+class C {
+  String operator +(String s) => '';
+}
+void f(C? c) {
+  c! + '';
+}
+''');
+  }
+
   Future<void> test_binaryOperator_leftSide() async {
     await resolveTestCode('''
 f(int? i) => i + 1;
@@ -246,6 +265,85 @@
     await assertNoFix();
   }
 
+  Future<void> test_isNullThen_left_notAssignable_nonNullable() async {
+    await resolveTestCode('''
+void f(String s) {}
+void g(int i) {
+  f(i ?? '');
+}
+''');
+    await assertNoFix(errorFilter: (error) {
+      return error.errorCode ==
+          CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE;
+    });
+  }
+
+  Future<void>
+      test_isNullThen_left_notAssignable_nullable_right_nonNullable() async {
+    await resolveTestCode('''
+void f(String s) {}
+void g(int? i) {
+  f(i ?? '');
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void>
+      test_isNullThen_left_notAssignable_nullable_right_nullable() async {
+    await resolveTestCode('''
+void f(String s) {}
+void g(int? i, String? s) {
+  f(i ?? s);
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_isNullThen_right_assignable_nullable() async {
+    await resolveTestCode('''
+void f(int i) {}
+void g(int i, int? x) {
+  f(i ?? x);
+}
+''');
+    await assertHasFix('''
+void f(int i) {}
+void g(int i, int? x) {
+  f(i ?? x!);
+}
+''', errorFilter: (error) {
+      return error.errorCode ==
+          CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE;
+    });
+  }
+
+  Future<void> test_isNullThen_right_notAssignable_nonNullable() async {
+    await resolveTestCode('''
+void f(String s) {}
+void g(int i, int x) {
+  f(i ?? x);
+}
+''');
+    await assertNoFix(errorFilter: (error) {
+      return error.errorCode ==
+          CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE;
+    });
+  }
+
+  Future<void> test_isNullThen_right_notAssignable_nullable() async {
+    await resolveTestCode('''
+void f(String s) {}
+void g(int i, int? x) {
+  f(i ?? x);
+}
+''');
+    await assertNoFix(errorFilter: (error) {
+      return error.errorCode ==
+          CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE;
+    });
+  }
+
   Future<void> test_methodInvocation() async {
     await resolveTestCode('''
 String f(String? s) => s.substring(0);
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 e00bd37..7499207 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
@@ -11,8 +11,8 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(AddReturnTypeLintTest);
     defineReflectiveTests(AddReturnTypeBulkTest);
+    defineReflectiveTests(AddReturnTypeLintTest);
   });
 }
 
@@ -178,6 +178,19 @@
 ''');
   }
 
+  Future<void> test_operator() async {
+    await resolveTestCode('''
+class MyObject extends Object {
+  operator ==(Object other) => false;
+}
+''');
+    await assertHasFix('''
+class MyObject extends Object {
+  bool operator ==(Object other) => false;
+}
+''');
+  }
+
   Future<void> test_privateType() async {
     addSource('$testPackageLibPath/a.dart', '''
 class A {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
index 39cf4a9..0d8813c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
@@ -123,10 +123,6 @@
 ''');
   }
 
-  @FailingTest(
-    reason: 'Generates positional arguments instead of named',
-    issue: 'https://github.com/dart-lang/sdk/issues/49514',
-  )
   Future<void> test_unnamed_requiredNamed() async {
     await resolveTestCode('''
 class A {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
index 2f014ab..9caf170 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
@@ -14,6 +14,20 @@
 
 @reflectiveTest
 class RemoveSettingTest extends AnalysisOptionsFixTest {
+  Future<void> test_enablePreviewDart2() async {
+    await assertHasFix('''
+analyzer:
+  enable-experiment:
+    - test-experiment
+  language:
+    enablePreviewDart2: true
+''', '''
+analyzer:
+  enable-experiment:
+    - test-experiment
+''');
+  }
+
   Future<void> test_enableSuperMixins() async {
     await assertHasFix('''
 analyzer:
@@ -62,4 +76,11 @@
 ''', '''
 ''');
   }
+
+  Future<void> test_strong_mode_settings_deprecated() async {
+    await assertHasFix('''
+analyzer:
+  strong-mode: true
+''', '');
+  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
index 0c4eaa4..791fd59 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
@@ -115,4 +115,17 @@
 }
 ''');
   }
+
+  Future<void> test_nullLiteral() async {
+    await resolveTestCode('''
+void f(String? s) {
+  print(s == null ? null : s);
+}
+''');
+    await assertHasFix('''
+void f(String? s) {
+  print(s);
+}
+''');
+  }
 }
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 31aac11..2782f44 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
@@ -21,7 +21,27 @@
 class TransformSetManagerTest extends AbstractContextTest {
   TransformSetManager manager = TransformSetManager.instance;
 
-  void test_twoFiles() async {
+  Future<void> test_twoFiles_onePackage() async {
+    var folder = '$workspaceRootPath/p1/lib/fix_data';
+
+    _addDataFileIn('$folder/one.yaml', 'p1');
+    _addDataFileIn('$folder/deep/dive/two.yaml', 'p1');
+
+    writeTestPackageConfig(
+      config: PackageConfigFileBuilder()
+        ..add(name: 'p1', rootPath: '$workspaceRootPath/p1'),
+    );
+
+    addSource('/home/test/pubspec.yaml', '');
+
+    var testFile = convertPath('$testPackageLibPath/test.dart');
+    addSource(testFile, '');
+    var result = await (await session).getResolvedLibraryValid(testFile);
+    var sets = manager.forLibrary(result.element);
+    expect(sets, hasLength(2));
+  }
+
+  Future<void> test_twoFiles_twoPackages() async {
     _addDataFile('p1');
     _addDataFile('p2');
 
@@ -40,7 +60,7 @@
     expect(sets, hasLength(2));
   }
 
-  void test_zeroFiles() async {
+  Future<void> test_zeroFiles() async {
     // addTestPackageDependency('p1', '/.pub-cache/p1');
     // addTestPackageDependency('p2', '/.pub-cache/p2');
     addSource('/home/test/pubspec.yaml', '');
@@ -52,7 +72,12 @@
   }
 
   void _addDataFile(String packageName) {
-    newFile('$workspaceRootPath/$packageName/lib/fix_data.yaml', '''
+    _addDataFileIn(
+        '$workspaceRootPath/$packageName/lib/fix_data.yaml', packageName);
+  }
+
+  void _addDataFileIn(String path, String packageName) {
+    newFile(path, '''
 version: 1
 transforms:
 - title: 'Rename A'
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_variable_nullable_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_variable_nullable_test.dart
index 86bdc42..4b60033 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/make_variable_nullable_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_variable_nullable_test.dart
@@ -169,6 +169,15 @@
 ''');
   }
 
+  Future<void> test_positional() async {
+    await resolveTestCode('''
+void f([String s]) {}
+''');
+    await assertHasFix('''
+void f([String? s]) {}
+''');
+  }
+
   Future<void> test_simpleFormalParameter() async {
     await resolveTestCode('''
 void f({String s}) {}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart
index a1c78e8..7d10372 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart
@@ -272,6 +272,21 @@
 ''');
   }
 
+  Future<void> test_generic_setLiteral_recordType() async {
+    await resolveTestCode('''
+Set f() {
+  Set<(int, int)> s = {};
+  return s;
+}
+''');
+    await assertHasFix('''
+Set f() {
+  var s = <(int, int)>{};
+  return s;
+}
+''');
+  }
+
   Future<void> test_simple() async {
     await resolveTestCode('''
 String f() {
@@ -316,4 +331,19 @@
 }
 ''');
   }
+
+  Future<void> test_simple_recordType() async {
+    await resolveTestCode(r'''
+String f() {
+  (int, String) r = (3, '');
+  return r.$1;
+}
+''');
+    await assertHasFix(r'''
+String f() {
+  var r = (3, '');
+  return r.$1;
+}
+''');
+  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/sort_combinators_test.dart b/pkg/analysis_server/test/src/services/correction/fix/sort_combinators_test.dart
new file mode 100644
index 0000000..4ae865e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/sort_combinators_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2022, 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.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/expect.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SortCombinatorsBulkTest);
+    defineReflectiveTests(SortCombinatorsInFileTest);
+    defineReflectiveTests(SortCombinatorsTest);
+  });
+}
+
+@reflectiveTest
+class SortCombinatorsBulkTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.combinators_ordering;
+
+  Future<void> test_bulk() async {
+    await resolveTestCode('''
+import 'dart:io' hide FileSystemEntity, Directory;
+import 'dart:math' hide min, max;
+
+File io() => File('');
+double math() => pi;
+''');
+    await assertHasFix('''
+import 'dart:io' hide Directory, FileSystemEntity;
+import 'dart:math' hide max, min;
+
+File io() => File('');
+double math() => pi;
+''');
+  }
+}
+
+@reflectiveTest
+class SortCombinatorsInFileTest extends FixInFileProcessorTest {
+  Future<void> test_File() async {
+    createAnalysisOptionsFile(lints: [LintNames.combinators_ordering]);
+    await resolveTestCode(r'''
+import 'dart:io' hide FileSystemEntity, Directory;
+import 'dart:math' hide min, max;
+
+File io() => File('');
+double math() => pi;
+''');
+    var fixes = await getFixesForFirstError();
+    expect(fixes, hasLength(1));
+    assertProduces(fixes.first, r'''
+import 'dart:io' hide Directory, FileSystemEntity;
+import 'dart:math' hide max, min;
+
+File io() => File('');
+double math() => pi;
+''');
+  }
+}
+
+@reflectiveTest
+class SortCombinatorsTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.SORT_COMBINATORS;
+
+  @override
+  String get lintCode => LintNames.combinators_ordering;
+
+  Future<void> test_comment() async {
+    await resolveTestCode('''
+import 'dart:math' hide min, /* e */ max;
+
+double f() => pi;
+''');
+    await assertHasFix('''
+import 'dart:math' hide max, /* e */ min;
+
+double f() => pi;
+''');
+  }
+
+  Future<void> test_hide() async {
+    await resolveTestCode('''
+import 'dart:math' hide min, max;
+
+double f() => pi;
+''');
+    await assertHasFix('''
+import 'dart:math' hide max, min;
+
+double f() => pi;
+''');
+  }
+
+  Future<void> test_show() async {
+    await resolveTestCode('''
+import 'dart:math' show min, max;
+
+int f() => max(min(1, 2), 1);
+''');
+    await assertHasFix('''
+import 'dart:math' show max, min;
+
+int f() => max(min(1, 2), 1);
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 2760dbe..5bbf97f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -14,6 +14,7 @@
 import 'add_enum_constant_test.dart' as add_enum_constant_test;
 import 'add_eol_at_end_of_file_test.dart' as add_eol_at_end_of_file;
 import 'add_explicit_cast_test.dart' as add_explicit_cast;
+import 'add_extension_override_test.dart' as add_extension_override;
 import 'add_field_formal_parameters_test.dart' as add_field_formal_parameters;
 import 'add_key_to_constructors_test.dart' as add_key_to_constructors;
 import 'add_late_test.dart' as add_late;
@@ -225,6 +226,7 @@
 import 'replace_with_tear_off_test.dart' as replace_with_tear_off;
 import 'replace_with_var_test.dart' as replace_with_var;
 import 'sort_child_property_last_test.dart' as sort_properties_last;
+import 'sort_combinators_test.dart' as sort_combinators_test;
 import 'sort_constructor_first_test.dart' as sort_constructor_first_test;
 import 'sort_unnamed_constructor_first_test.dart'
     as sort_unnamed_constructor_first_test;
@@ -252,6 +254,7 @@
     add_enum_constant_test.main();
     add_eol_at_end_of_file.main();
     add_explicit_cast.main();
+    add_extension_override.main();
     add_field_formal_parameters.main();
     add_key_to_constructors.main();
     add_late.main();
@@ -438,6 +441,7 @@
     replace_with_var.main();
     sort_properties_last.main();
     sort_constructor_first_test.main();
+    sort_combinators_test.main();
     sort_unnamed_constructor_first_test.main();
     update_sdk_constraints.main();
     use_const.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_curly_braces_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_curly_braces_test.dart
index f1e7891..ace4060 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/use_curly_braces_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_curly_braces_test.dart
@@ -12,7 +12,7 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(UseCurlyBracesTest);
+    defineReflectiveTests(UseCurlyBracesBulkTest);
     defineReflectiveTests(ControlBodyOnNewLineBulkTest);
     defineReflectiveTests(ControlBodyOnNewLineInFileTest);
     defineReflectiveTests(ControlBodyOnNewLineLintTest);
@@ -94,7 +94,7 @@
 }
 
 @reflectiveTest
-class UseCurlyBracesTest extends BulkFixProcessorTest {
+class UseCurlyBracesBulkTest extends BulkFixProcessorTest {
   @override
   String get lintCode => LintNames.curly_braces_in_flow_control_structures;
 
diff --git a/pkg/analysis_server/test/src/services/refactoring/move_top_level_to_file_test.dart b/pkg/analysis_server/test/src/services/refactoring/move_top_level_to_file_test.dart
new file mode 100644
index 0000000..16320e3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/refactoring/move_top_level_to_file_test.dart
@@ -0,0 +1,309 @@
+// Copyright (c) 2022, 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.dart';
+import 'package:analysis_server/src/services/refactoring/move_top_level_to_file.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'refactoring_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(MoveTopLevelToFileTest);
+  });
+}
+
+@reflectiveTest
+class MoveTopLevelToFileTest extends RefactoringTest {
+  /// Simple file content with a single class named 'A'.
+  static const simpleClassContent = 'class ^A {}';
+
+  /// The title of the refactor when using [simpleClassContent].
+  static const simpleClassRefactorTitle = "Move 'A' to file";
+
+  @override
+  String get refactoringName => MoveTopLevelToFile.commandName;
+
+  /// Replaces the "Save URI" argument in [action].
+  void replaceSaveUriArgument(CodeAction action, Uri newFileUri) {
+    final arguments = getRefactorCommandArguments(action);
+    // The filename is the first item we prompt for so is first in the
+    // arguments.
+    arguments[0] = newFileUri.toString();
+  }
+
+  Future<void> test_available() async {
+    addTestSource(simpleClassContent);
+    await initializeServer();
+    await expectCodeAction(simpleClassRefactorTitle);
+  }
+
+  Future<void> test_available_withoutClientCommandParameterSupport() async {
+    addTestSource(simpleClassContent);
+    await initializeServer(commandParameterSupport: false);
+    // This refactor is available without command parameter support because
+    // it has defaults.
+    await expectCodeAction(simpleClassRefactorTitle);
+  }
+
+  Future<void> test_class() async {
+    var originalSource = '''
+class A {}
+
+class ClassToMove^ {}
+
+class B {}
+''';
+    var modifiedSource = '''
+class A {}
+
+class B {}
+''';
+    var declarationName = 'ClassToMove';
+    var newFileName = 'class_to_move.dart';
+    var newFileContent = '''
+class ClassToMove {}
+''';
+    await _singleDeclaration(
+        originalSource: originalSource,
+        modifiedSource: modifiedSource,
+        declarationName: declarationName,
+        newFileName: newFileName,
+        newFileContent: newFileContent);
+  }
+
+  Future<void> test_clientModifiedValues() async {
+    addTestSource(simpleClassContent);
+
+    /// Filename to inject to replace default.
+    final newFilePath = join(projectFolderPath, 'lib', 'my_new_class.dart');
+    final newFileUri = Uri.file(newFilePath);
+
+    /// Expected new file content.
+    const expectedNewFileContent = '''
+class A {}
+''';
+
+    await initializeServer();
+    final action = await expectCodeAction(simpleClassRefactorTitle);
+    // Replace the file URI argument with our custom path.
+    replaceSaveUriArgument(action, newFileUri);
+    await executeRefactor(action);
+
+    expect(content[newFilePath], expectedNewFileContent);
+  }
+
+  Future<void> test_enum() async {
+    var originalSource = '''
+class A {}
+
+enum EnumToMove^ { a, b }
+
+class B {}
+''';
+    var modifiedSource = '''
+class A {}
+
+class B {}
+''';
+    var declarationName = 'EnumToMove';
+    var newFileName = 'enum_to_move.dart';
+    var newFileContent = '''
+enum EnumToMove { a, b }
+''';
+    await _singleDeclaration(
+        originalSource: originalSource,
+        modifiedSource: modifiedSource,
+        declarationName: declarationName,
+        newFileName: newFileName,
+        newFileContent: newFileContent);
+  }
+
+  Future<void> test_existingFile() async {
+    addTestSource(simpleClassContent);
+
+    /// Existing new file contents where 'ClassToMove' will be moved to.
+    final newFilePath = join(projectFolderPath, 'lib', 'a.dart');
+    addSource(newFilePath, '''
+int? a;
+''');
+
+    /// Expected updated new file contents.
+    const expectedNewFileContent = '''
+class A {}
+int? a;
+''';
+
+    await initializeServer();
+    final action = await expectCodeAction(simpleClassRefactorTitle);
+    await executeRefactor(action);
+
+    expect(content[newFilePath], expectedNewFileContent);
+  }
+
+  Future<void> test_extension() async {
+    var originalSource = '''
+class A {}
+
+extension ExtensionToMove^ on int { }
+
+class B {}
+''';
+    var modifiedSource = '''
+class A {}
+
+class B {}
+''';
+    var declarationName = 'ExtensionToMove';
+    var newFileName = 'extension_to_move.dart';
+    var newFileContent = '''
+extension ExtensionToMove on int { }
+''';
+    await _singleDeclaration(
+        originalSource: originalSource,
+        modifiedSource: modifiedSource,
+        declarationName: declarationName,
+        newFileName: newFileName,
+        newFileContent: newFileContent);
+  }
+
+  Future<void> test_function() async {
+    var originalSource = '''
+class A {}
+
+void functionToMo^ve() { }
+
+class B {}
+''';
+    var modifiedSource = '''
+class A {}
+
+class B {}
+''';
+    var declarationName = 'functionToMove';
+    var newFileName = 'function_to_move.dart';
+    var newFileContent = '''
+void functionToMove() { }
+''';
+    await _singleDeclaration(
+        originalSource: originalSource,
+        modifiedSource: modifiedSource,
+        declarationName: declarationName,
+        newFileName: newFileName,
+        newFileContent: newFileContent);
+  }
+
+  Future<void> test_mixin() async {
+    var originalSource = '''
+class A {}
+
+mixin MixinToMove^ { }
+
+class B {}
+''';
+    var modifiedSource = '''
+class A {}
+
+class B {}
+''';
+    var declarationName = 'MixinToMove';
+    var newFileName = 'mixin_to_move.dart';
+    var newFileContent = '''
+mixin MixinToMove { }
+''';
+    await _singleDeclaration(
+        originalSource: originalSource,
+        modifiedSource: modifiedSource,
+        declarationName: declarationName,
+        newFileName: newFileName,
+        newFileContent: newFileContent);
+  }
+
+  Future<void> test_typedef() async {
+    var originalSource = '''
+class A {}
+
+typedef TypeToMove^ = void Function();
+
+class B {}
+''';
+    var modifiedSource = '''
+class A {}
+
+class B {}
+''';
+    var declarationName = 'TypeToMove';
+    var newFileName = 'type_to_move.dart';
+    var newFileContent = '''
+typedef TypeToMove = void Function();
+''';
+    await _singleDeclaration(
+        originalSource: originalSource,
+        modifiedSource: modifiedSource,
+        declarationName: declarationName,
+        newFileName: newFileName,
+        newFileContent: newFileContent);
+  }
+
+  Future<void> test_unavailable_withoutExperimentalOptIn() async {
+    addTestSource(simpleClassContent);
+    await initializeServer(experimentalOptInFlag: false);
+    await expectNoCodeAction(simpleClassRefactorTitle);
+  }
+
+  Future<void> test_unavailable_withoutFileCreateSupport() async {
+    addTestSource(simpleClassContent);
+    await initializeServer(fileCreateSupport: false);
+    await expectNoCodeAction(simpleClassRefactorTitle);
+  }
+
+  Future<void> test_variable() async {
+    var originalSource = '''
+class A {}
+
+int variableT^oMove = 3;
+
+class B {}
+''';
+    var modifiedSource = '''
+class A {}
+
+class B {}
+''';
+    var declarationName = 'variableToMove';
+    var newFileName = 'variable_to_move.dart';
+    var newFileContent = '''
+int variableToMove = 3;
+''';
+    await _singleDeclaration(
+        originalSource: originalSource,
+        modifiedSource: modifiedSource,
+        declarationName: declarationName,
+        newFileName: newFileName,
+        newFileContent: newFileContent);
+  }
+
+  Future<void> _singleDeclaration(
+      {required String originalSource,
+      required String modifiedSource,
+      required String declarationName,
+      required String newFileName,
+      required String newFileContent}) async {
+    addTestSource(originalSource);
+
+    /// Expected new file path/content.
+    final expectedNewFilePath = join(projectFolderPath, 'lib', newFileName);
+
+    await initializeServer();
+    final action = await expectCodeAction("Move '$declarationName' to file");
+    await executeRefactor(action);
+
+    expect(content[mainFilePath], modifiedSource);
+    // Check the new file was added to `content`. If no CreateFile resource
+    // was sent, the executeRefactor helper would've thrown when trying to
+    // apply the changes.
+    expect(content[expectedNewFilePath], newFileContent);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/refactoring/refactoring_test_support.dart b/pkg/analysis_server/test/src/services/refactoring/refactoring_test_support.dart
new file mode 100644
index 0000000..ece6046
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/refactoring/refactoring_test_support.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2022, 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.dart';
+import 'package:test/test.dart';
+
+import '../../../lsp/code_actions_abstract.dart';
+
+abstract class RefactoringTest extends AbstractCodeActionsTest {
+  /// Position of the marker where the refactor will be invoked.
+  late Position _position;
+
+  /// A map of file paths to their current content.
+  ///
+  /// Methods like [executeRefactor] will update this as workspace edits are
+  /// sent from the server back to the client.
+  Map<String, String> content = {};
+
+  /// Return the title of the refactoring command that is expected to be
+  /// available.
+  String get refactoringName;
+
+  void addSource(String filePath, String code) {
+    content[filePath] = code;
+    newFile(filePath, code);
+  }
+
+  void addTestSource(String markedCode) {
+    _position = positionFromMarker(markedCode);
+    final code = withoutMarkers(markedCode);
+    addSource(mainFilePath, code);
+  }
+
+  /// Finds and executes the refactor with [title], updating [content] with
+  /// edits sent by the server.
+  Future<void> executeRefactor(CodeAction action) async {
+    await executeCommandForEdits(
+      action.command!,
+      content,
+      expectDocumentChanges: true,
+    );
+  }
+
+  /// Expects to find a refactor [CodeAction] in [mainFileUri] at the offset of
+  /// the marker with the title [title].
+  Future<CodeAction> expectCodeAction(String title) async {
+    final action = await getCodeAction(title);
+    expect(action, isNotNull, reason: "Action '$title' should be included");
+    return action!;
+  }
+
+  /// Expects to find a refactor [CodeAction] in [mainFileUri] at the offset of
+  /// the marker with the title [title].
+  Future<void> expectNoCodeAction(String title) async {
+    expect(await getCodeAction(title), isNull);
+  }
+
+  /// Attempts to find a refactor [CodeAction] in [mainFileUri] at the offset of
+  /// the marker with the title [title].
+  Future<CodeAction?> getCodeAction(String title) async {
+    final codeActions = await getCodeActions(
+      mainFileUri,
+      position: _position,
+      kinds: const [CodeActionKind.Refactor],
+    );
+    final commandOrCodeAction =
+        findCommand(codeActions, refactoringName, title);
+    final codeAction = commandOrCodeAction?.map(
+      (command) => throw 'Expected CodeAction, got Command',
+      (codeAction) => codeAction,
+    );
+    return codeAction;
+  }
+
+  /// Unwraps the 'arguments' field from the arguments object (which is the
+  /// single argument for the command).
+  List<Object?> getRefactorCommandArguments(CodeAction action) {
+    final commandArguments = action.command!.arguments as List<Object?>;
+
+    // Our refactor command uses a single object in its arguments so we can have
+    // named fields instead of having the client have to know which index
+    // corresponds to the parameters.
+    final argsObject = commandArguments.single as Map<String, Object?>;
+
+    // Within that object, the 'arguments' field is the List<Object?> that
+    // contains the values for the parameters.
+    final arguments = argsObject['arguments'] as List<Object?>;
+
+    return arguments;
+  }
+
+  /// Initializes the server.
+  ///
+  /// Enables all required client capabilities for new refactors unless the
+  /// corresponding flags are set to `false`.
+  Future<void> initializeServer({
+    bool experimentalOptInFlag = true,
+    bool commandParameterSupport = true,
+    bool fileCreateSupport = true,
+    bool applyEditSupport = true,
+  }) async {
+    final config = {
+      if (experimentalOptInFlag) 'experimentalNewRefactors': true,
+    };
+    final experimentalCapabilities = {
+      if (commandParameterSupport) 'commandParameterSupport': true,
+    };
+
+    var workspaceCapabilities =
+        withConfigurationSupport(emptyWorkspaceClientCapabilities);
+    if (applyEditSupport) {
+      workspaceCapabilities = withApplyEditSupport(workspaceCapabilities);
+    }
+    if (fileCreateSupport) {
+      workspaceCapabilities = withDocumentChangesSupport(
+          withResourceOperationKinds(
+              workspaceCapabilities, [ResourceOperationKind.Create]));
+    }
+
+    await provideConfig(
+      () => initialize(
+        workspaceCapabilities: workspaceCapabilities,
+        experimentalCapabilities: experimentalCapabilities,
+      ),
+      config,
+    );
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/refactoring/test_all.dart b/pkg/analysis_server/test/src/services/refactoring/test_all.dart
new file mode 100644
index 0000000..72c4561
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/refactoring/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'move_top_level_to_file_test.dart' as move_top_level_to_file;
+
+void main() {
+  defineReflectiveSuite(() {
+    move_top_level_to_file.main();
+  }, name: 'refactoring');
+}
diff --git a/pkg/analysis_server/test/src/services/test_all.dart b/pkg/analysis_server/test/src/services/test_all.dart
index e5d8aa0..61e2119 100644
--- a/pkg/analysis_server/test/src/services/test_all.dart
+++ b/pkg/analysis_server/test/src/services/test_all.dart
@@ -7,11 +7,13 @@
 import 'completion/test_all.dart' as completion;
 import 'correction/test_all.dart' as correction;
 import 'flutter/test_all.dart' as flutter;
+import 'refactoring/test_all.dart' as refactoring;
 
 void main() {
   defineReflectiveSuite(() {
     completion.main();
     correction.main();
     flutter.main();
+    refactoring.main();
   }, name: 'services');
 }
diff --git a/pkg/analysis_server/test/src/utilities/flutter_test.dart b/pkg/analysis_server/test/src/utilities/flutter_test.dart
index 9cf4a14..5866349 100644
--- a/pkg/analysis_server/test/src/utilities/flutter_test.dart
+++ b/pkg/analysis_server/test/src/utilities/flutter_test.dart
@@ -17,11 +17,6 @@
 
 @reflectiveTest
 class FlutterTest extends AbstractSingleUnitTest {
-  @override
-  // TODO(brianwilkerson) Update these tests. I believe that will require
-  //  updating the mock flutter package.
-  String? get testPackageLanguageVersion => '2.9';
-
   Flutter get _flutter => Flutter.instance;
 
   @override
@@ -113,7 +108,7 @@
 class MyWidget extends StatelessWidget {
   MyWidget(int a);
   MyWidget.named(int a);
-  Widget build(BuildContext context) => null;
+  Widget build(BuildContext context) => Text('');
 }
 ''');
     var f = testUnit.declarations[0] as FunctionDeclaration;
@@ -209,6 +204,8 @@
 
 abstract class Foo extends Widget {
   Widget bar;
+
+  Foo(this.bar);
 }
 
 void f(Foo foo) {
@@ -226,6 +223,8 @@
 
 abstract class Foo extends Widget {
   Widget bar;
+
+  Foo(this.bar);
 }
 
 void f(Foo foo) {
@@ -416,7 +415,7 @@
   useWidget(child: text); // ref
 }
 
-void useWidget({Widget child}) {}
+void useWidget({required Widget child}) {}
 ''');
     var expression = findNode.simple('text); // ref');
     expect(_flutter.identifyWidgetExpression(expression), expression);
@@ -544,7 +543,7 @@
     for (var topDeclaration in unit.declarations) {
       if (topDeclaration is TopLevelVariableDeclaration) {
         for (var variable in topDeclaration.variables.variables) {
-          if (variable.name2.lexeme == name) {
+          if (variable.name.lexeme == name) {
             return variable;
           }
         }
diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart
index bdc3ae4..ab36b93 100644
--- a/pkg/analysis_server/test/test_all.dart
+++ b/pkg/analysis_server/test/test_all.dart
@@ -25,6 +25,7 @@
 import 'services/test_all.dart' as services;
 import 'socket_server_test.dart' as socket_server;
 import 'src/test_all.dart' as src;
+import 'test_code_format_test.dart' as test_code_format;
 import 'tool/test_all.dart' as tool;
 import 'verify_error_fix_status_test.dart' as verify_error_fix_status;
 import 'verify_no_solo_test.dart' as verify_no_solo;
@@ -53,6 +54,7 @@
     services.main();
     socket_server.main();
     src.main();
+    test_code_format.main();
     tool.main();
     verify_error_fix_status.main();
     verify_no_solo.main();
diff --git a/pkg/analysis_server/test/test_code_format_test.dart b/pkg/analysis_server/test/test_code_format_test.dart
new file mode 100644
index 0000000..419ed97
--- /dev/null
+++ b/pkg/analysis_server/test/test_code_format_test.dart
@@ -0,0 +1,176 @@
+// Copyright (c) 2022, 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.dart' as lsp;
+import 'package:analyzer/source/source_range.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'utils/test_code_format.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(TestCodeFormatTest);
+  });
+}
+
+@reflectiveTest
+class TestCodeFormatTest {
+  void test_caret() {
+    final rawCode = '''
+int ^a = 1
+    ''';
+    final expectedCode = '''
+int a = 1
+    ''';
+    final code = TestCode.parse(rawCode);
+    expect(code.rawCode, rawCode);
+    expect(code.code, expectedCode);
+
+    expect(code.positions, hasLength(1));
+    expect(code.position.offset, 4);
+    expect(code.position.offset, code.positions[0].offset);
+    expect(code.position.lsp, lsp.Position(line: 0, character: 4));
+    expect(code.position.lsp, code.positions[0].lsp);
+
+    expect(code.ranges, isEmpty);
+  }
+
+  void test_noMarkers() {
+    final rawCode = '''
+int a = 1;
+''';
+    final code = TestCode.parse(rawCode);
+    expect(code.rawCode, rawCode);
+    expect(code.code, rawCode); // no difference
+    expect(code.positions, isEmpty);
+    expect(code.ranges, isEmpty);
+  }
+
+  void test_nonPositionCaret() {
+    final rawCode = '''
+String /*0*/a = '^^^';
+    ''';
+    final expectedCode = '''
+String a = '^^^';
+    ''';
+    final code = TestCode.parse(rawCode, treatCaretAsPosition: false);
+    expect(code.rawCode, rawCode);
+    expect(code.code, expectedCode);
+
+    expect(code.positions, hasLength(1));
+    expect(code.position.offset, 7);
+    expect(code.position.offset, code.positions[0].offset);
+    expect(code.position.lsp, lsp.Position(line: 0, character: 7));
+    expect(code.position.lsp, code.positions[0].lsp);
+
+    expect(code.ranges, isEmpty);
+  }
+
+  void test_positions() {
+    final rawCode = '''
+int /*0*/a = 1;/*1*/
+int b/*2*/ = 2;
+''';
+    final expectedCode = '''
+int a = 1;
+int b = 2;
+''';
+    final code = TestCode.parse(rawCode);
+    expect(code.rawCode, rawCode);
+    expect(code.code, expectedCode);
+    expect(code.ranges, isEmpty);
+
+    expect(code.positions[0].offset, 4);
+    expect(code.positions[1].offset, 10);
+    expect(code.positions[2].offset, 16);
+
+    expect(code.positions[0].lsp, lsp.Position(line: 0, character: 4));
+    expect(code.positions[1].lsp, lsp.Position(line: 0, character: 10));
+    expect(code.positions[2].lsp, lsp.Position(line: 1, character: 5));
+  }
+
+  void test_positions_reused() {
+    final rawCode = '''
+/*0*/ /*1*/ /*0*/
+''';
+    expect(() => TestCode.parse(rawCode), throwsArgumentError);
+  }
+
+  void test_positions_reusedCaret() {
+    final rawCode = '''
+^ ^
+''';
+    expect(() => TestCode.parse(rawCode), throwsArgumentError);
+  }
+
+  void test_positions_reusedCaretNumber() {
+    final rawCode = '''
+/*1*/ ^
+''';
+    expect(() => TestCode.parse(rawCode), throwsArgumentError);
+  }
+
+  void test_ranges() {
+    final rawCode = '''
+int /*[0*/a = 1;/*0]*/
+/*[1*/int b = 2;/*1]*/
+''';
+    final expectedCode = '''
+int a = 1;
+int b = 2;
+''';
+    final code = TestCode.parse(rawCode);
+    expect(code.rawCode, rawCode);
+    expect(code.code, expectedCode);
+    expect(code.positions, isEmpty);
+
+    expect(code.ranges, hasLength(2));
+    expect(code.ranges[0].sourceRange, SourceRange(4, 6));
+    expect(code.ranges[1].sourceRange, SourceRange(11, 10));
+    expect(
+        code.ranges[0].lsp,
+        lsp.Range(
+            start: lsp.Position(line: 0, character: 4),
+            end: lsp.Position(line: 0, character: 10)));
+    expect(
+        code.ranges[1].lsp,
+        lsp.Range(
+            start: lsp.Position(line: 1, character: 0),
+            end: lsp.Position(line: 1, character: 10)));
+
+    expect(code.ranges[0].text, 'a = 1;');
+    expect(code.ranges[1].text, 'int b = 2;');
+  }
+
+  void test_ranges_endReused() {
+    final rawCode = '''
+/*[0*/ /*0]*/
+/*[1*/ /*0]*/
+''';
+    expect(() => TestCode.parse(rawCode), throwsArgumentError);
+  }
+
+  void test_ranges_endWithoutStart() {
+    final rawCode = '''
+/*0]*/
+''';
+    expect(() => TestCode.parse(rawCode), throwsArgumentError);
+  }
+
+  void test_ranges_startReused() {
+    final rawCode = '''
+/*[0*/ /*0]*/
+/*[0*/ /*1]*/
+''';
+    expect(() => TestCode.parse(rawCode), throwsArgumentError);
+  }
+
+  void test_ranges_startWithoutEnd() {
+    final rawCode = '''
+/*[0*/
+''';
+    expect(() => TestCode.parse(rawCode), throwsArgumentError);
+  }
+}
diff --git a/pkg/analysis_server/test/timing/timing_framework.dart b/pkg/analysis_server/test/timing/timing_framework.dart
index 31ed32a..07f7ade 100644
--- a/pkg/analysis_server/test/timing/timing_framework.dart
+++ b/pkg/analysis_server/test/timing/timing_framework.dart
@@ -178,7 +178,7 @@
     await _repeat(warmupCount, null);
     await _repeat(timingCount, times);
     await oneTimeTearDown();
-    return Future<TimingResult>.value(TimingResult(times));
+    return TimingResult(times);
   }
 
   /// Perform any operations that need to be performed before each iteration.
diff --git a/pkg/analysis_server/test/tool/lsp_spec/generated_classes_test.dart b/pkg/analysis_server/test/tool/lsp_spec/generated_classes_test.dart
index 772f091..a116393 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/generated_classes_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/generated_classes_test.dart
@@ -8,8 +8,8 @@
 void main() {
   group('generated classes', () {
     test('can be checked for equality', () {
-      final a = TextDocumentIdentifier(uri: '/a');
-      final b = TextDocumentIdentifier(uri: '/a');
+      final a = TextDocumentIdentifier(uri: Uri.file('/a'));
+      final b = TextDocumentIdentifier(uri: Uri.file('/a'));
 
       expect(a, equals(b));
       expect(a.hashCode, equals(b.hashCode));
@@ -41,7 +41,7 @@
 
     test('with map fields can be checked for equality', () {
       final a = WorkspaceEdit(changes: {
-        'a': [
+        Uri.file('/a'): [
           TextEdit(
               range: Range(
                   start: Position(line: 0, character: 0),
@@ -50,7 +50,7 @@
         ]
       });
       final b = WorkspaceEdit(changes: {
-        'a': [
+        Uri.file('/a'): [
           TextEdit(
               range: Range(
                   start: Position(line: 0, character: 0),
diff --git a/pkg/analysis_server/test/tool/lsp_spec/json_test.dart b/pkg/analysis_server/test/tool/lsp_spec/json_test.dart
index 6cfdde6..528cdfb 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/json_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/json_test.dart
@@ -38,7 +38,7 @@
                 Either2<List<Location>, Location>.t1([
           Location(
             range: range,
-            uri: '!uri',
+            uri: Uri.parse('http://example.org/'),
           )
         ])),
         jsonrpc: jsonRpcVersion,
@@ -49,23 +49,27 @@
           equals(
             '{"id":1,"jsonrpc":"2.0",'
             '"result":[{"range":{"end":{"character":2,"line":2},"start":{"character":1,"line":1}},'
-            '"uri":"!uri"}]}',
+            '"uri":"http://example.org/"}]}',
           ));
     });
 
     test('returns correct output for union types containing interface types',
         () {
       final params = Either2<String, TextDocumentItem>.t2(TextDocumentItem(
-          uri: '!uri', languageId: '!language', version: 1, text: '!text'));
+          uri: Uri.parse('http://example.org/'),
+          languageId: '!language',
+          version: 1,
+          text: '!text'));
       final output = json.encode(params);
       expect(
           output,
           equals(
-              '{"languageId":"!language","text":"!text","uri":"!uri","version":1}'));
+              '{"languageId":"!language","text":"!text","uri":"http://example.org/","version":1}'));
     });
 
     test('returns correct output for types with lists', () {
-      final location = Location(uri: 'y-uri', range: range);
+      final location =
+          Location(uri: Uri.parse('http://example.org/'), range: range);
       final codeAction = Diagnostic(
         range: range,
         severity: DiagnosticSeverity.Error,
@@ -91,7 +95,7 @@
                     "end":{"character":2,"line":2},
                     "start":{"character":1,"line":1}
                   },
-                  "uri":"y-uri"
+                  "uri":"http://example.org/"
               },
               "message":"message"
             }
@@ -317,7 +321,7 @@
       );
       expect(reporter.errors, hasLength(greaterThanOrEqualTo(1)));
       expect(reporter.errors.first,
-          equals('params.textDocument.uri must be of type String'));
+          equals('params.textDocument.uri must be of type Uri'));
     });
 
     test(
@@ -407,7 +411,7 @@
       // where the class definition only references a TextDocumentIdentifier.
       final input = jsonEncode(TextDocumentPositionParams(
         textDocument: VersionedTextDocumentIdentifier(
-            version: 111, uri: 'file:///foo/bar.dart'),
+            version: 111, uri: Uri.file('/foo/bar.dart')),
         position: Position(line: 1, character: 1),
       ).toJson());
       final params = TextDocumentPositionParams.fromJson(
@@ -439,8 +443,8 @@
 
   test('objects with lists can round-trip through to json and back', () {
     final workspaceFolders = [
-      WorkspaceFolder(uri: '!uri1', name: '!name1'),
-      WorkspaceFolder(uri: '!uri2', name: '!name2'),
+      WorkspaceFolder(uri: Uri.parse('http://example.org/1'), name: '!name1'),
+      WorkspaceFolder(uri: Uri.parse('http://example.org/2'), name: '!name2'),
     ];
     final obj = InitializeParams(
       processId: 1,
@@ -486,9 +490,9 @@
     final start = Position(line: 1, character: 1);
     final end = Position(line: 2, character: 2);
     final range = Range(start: start, end: end);
-    final obj = WorkspaceEdit(changes: <String, List<TextEdit>>{
-      'fileA': [TextEdit(range: range, newText: 'text A')],
-      'fileB': [TextEdit(range: range, newText: 'text B')]
+    final obj = WorkspaceEdit(changes: <Uri, List<TextEdit>>{
+      Uri.file('/fileA'): [TextEdit(range: range, newText: 'text A')],
+      Uri.file('/fileB'): [TextEdit(range: range, newText: 'text B')]
     });
     final json = jsonEncode(obj);
     final restoredObj =
diff --git a/pkg/analysis_server/test/utils/change_check.dart b/pkg/analysis_server/test/utils/change_check.dart
deleted file mode 100644
index 3cd3e2b..0000000
--- a/pkg/analysis_server/test/utils/change_check.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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/test/utils/test_code_format.dart b/pkg/analysis_server/test/utils/test_code_format.dart
new file mode 100644
index 0000000..9255905
--- /dev/null
+++ b/pkg/analysis_server/test/utils/test_code_format.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2022, 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.dart'
+    show Position, Range;
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:collection/collection.dart';
+import 'package:string_scanner/string_scanner.dart';
+
+/// A class for parsing and representing test code that contains special markup
+/// to simplify marking up positions and ranges in test code.
+///
+/// Positions and ranges are marked with brackets inside block comments:
+///
+/// ```
+/// position ::= '/*' integer '*/
+/// rangeStart ::= '/*[' integer '*/
+/// rangeEnd ::= '/*' integer ']*/
+/// ```
+///
+/// Numbers start at 0 and positions and range starts must be consecutive.
+/// The same numbers can be used to represent both positions and ranges.
+///
+/// For convenience, a single position can also be marked with a `^` (which
+/// behaves the same as `/*0*/).
+class TestCode {
+  static final _positionPattern = RegExp(r'\/\*(\d+)\*\/');
+  static final _rangeStartPattern = RegExp(r'\/\*\[(\d+)\*\/');
+  static final _rangeEndPattern = RegExp(r'\/\*(\d+)\]\*\/');
+  final String code;
+  final String rawCode;
+
+  /// A map of positions marked in code, indexed by their number.
+  final List<TestCodePosition> positions;
+
+  /// A map of ranges marked in code, indexed by their number.
+  final List<TestCodeRange> ranges;
+
+  TestCode._({
+    required this.rawCode,
+    required this.code,
+    required this.positions,
+    required this.ranges,
+  });
+
+  TestCodePosition get position => positions.single;
+  TestCodeRange get range => ranges.single;
+
+  static TestCode parse(String rawCode, {bool treatCaretAsPosition = true}) {
+    final scanner = StringScanner(rawCode);
+    final codeBuffer = StringBuffer();
+    final positionOffsets = <int, int>{};
+    final rangeStartOffsets = <int, int>{};
+    final rangeEndOffsets = <int, int>{};
+    late int start;
+
+    int scannedNumber() => int.parse(scanner.lastMatch!.group(1)!);
+
+    void recordPosition(int number) {
+      if (positionOffsets.containsKey(number)) {
+        throw ArgumentError(
+            'Code contains multiple positions numbered $number');
+      } else if (number > positionOffsets.length) {
+        throw ArgumentError(
+            'Code contains position numbered $number but expected ${positionOffsets.length}');
+      }
+      positionOffsets[number] = start;
+    }
+
+    void recordRangeStart(int number) {
+      if (rangeStartOffsets.containsKey(number)) {
+        throw ArgumentError(
+            'Code contains multiple range starts numbered $number');
+      } else if (number > rangeStartOffsets.length) {
+        throw ArgumentError(
+            'Code contains range start numbered $number but expected ${rangeStartOffsets.length}');
+      }
+      rangeStartOffsets[number] = start;
+    }
+
+    void recordRangeEnd(int number) {
+      if (rangeEndOffsets.containsKey(number)) {
+        throw ArgumentError(
+            'Code contains multiple range ends numbered $number');
+      }
+      if (!rangeStartOffsets.containsKey(number)) {
+        throw ArgumentError(
+            'Code contains range end numbered $number without a preceeding start');
+      }
+      rangeEndOffsets[number] = start;
+    }
+
+    while (!scanner.isDone) {
+      start = codeBuffer.length;
+      if (treatCaretAsPosition && scanner.scan('^')) {
+        recordPosition(0);
+      } else if (scanner.scan(_positionPattern)) {
+        recordPosition(scannedNumber());
+      } else if (scanner.scan(_rangeStartPattern)) {
+        recordRangeStart(scannedNumber());
+      } else if (scanner.scan(_rangeEndPattern)) {
+        recordRangeEnd(scannedNumber());
+      } else {
+        codeBuffer.writeCharCode(scanner.readChar());
+      }
+    }
+
+    final unendedRanges =
+        rangeStartOffsets.keys.whereNot(rangeEndOffsets.keys.contains).toList();
+    if (unendedRanges.isNotEmpty) {
+      throw ArgumentError(
+          'Code contains range starts numbered $unendedRanges without ends');
+    }
+
+    final code = codeBuffer.toString();
+    final lineInfo = LineInfo.fromContent(code);
+
+    final positions = positionOffsets.map(
+      (number, offset) => MapEntry(
+        number,
+        TestCodePosition(
+          offset,
+          toPosition(lineInfo.getLocation(offset)),
+        ),
+      ),
+    );
+
+    final ranges = rangeStartOffsets.map(
+      (number, offset) => MapEntry(
+        number,
+        TestCodeRange(
+          code.substring(offset, rangeEndOffsets[number]!),
+          SourceRange(offset, rangeEndOffsets[number]! - offset),
+          toRange(lineInfo, offset, rangeEndOffsets[number]! - offset),
+        ),
+      ),
+    );
+
+    return TestCode._(
+      code: code,
+      rawCode: rawCode,
+      positions: positions.values.toList(),
+      ranges: ranges.values.toList(),
+    );
+  }
+}
+
+/// A marked position in the test code.
+class TestCodePosition {
+  /// The 0-based offset of the marker.
+  ///
+  /// Offsets are based on [TestCode.code], with all parsed markers removed.
+  final int offset;
+
+  /// The LSP [Position] of the marker.
+  ///
+  /// Positions are based on [TestCode.code], with all parsed markers removed.
+  final Position lsp;
+
+  TestCodePosition(this.offset, this.lsp);
+}
+
+class TestCodeRange {
+  /// The text from [TestCode.code] covered by this range.
+  final String text;
+
+  /// The [SourceRange] indicated by the markers.
+  ///
+  /// Offsets/lengths are based on [TestCode.code], with all parsed markers
+  /// removed.
+  final SourceRange sourceRange;
+
+  /// The LSP [Range] indicated by the markers.
+  ///
+  /// Ranges are based on [TestCode.code], with all parsed markers removed.
+  final Range lsp;
+
+  TestCodeRange(this.text, this.sourceRange, this.lsp);
+}
diff --git a/pkg/analysis_server/test/verify_tests_test.dart b/pkg/analysis_server/test/verify_tests_test.dart
index 4f71c5a..93451ca 100644
--- a/pkg/analysis_server/test/verify_tests_test.dart
+++ b/pkg/analysis_server/test/verify_tests_test.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer_utilities/package_root.dart' as package_root;
 import 'package:analyzer_utilities/verify_tests.dart';
+import 'package:path/path.dart' as package_path;
 
 void main() {
   var provider = PhysicalResourceProvider.INSTANCE;
@@ -25,7 +26,9 @@
 
   @override
   bool isOkAsAdditionalTestAllImport(Folder folder, String uri) {
-    if (folder.path == folder.provider.pathContext.join(testDirPath, 'lsp') &&
+    final pathContext = folder.provider.pathContext;
+
+    if (folder.path == pathContext.join(testDirPath, 'lsp') &&
         uri == '../src/lsp/lsp_packet_transformer_test.dart') {
       // `lsp/test_all.dart` also runs this one test in `lsp/src` for
       // convenience.
@@ -37,6 +40,15 @@
       // convenience.
       return true;
     }
+
+    // Allow for updating textual expectations.
+    if (package_path.url.basename(uri) == 'text_expectations.dart') {
+      if (folder.path ==
+          pathContext.join(testDirPath, 'services', 'completion', 'dart')) {
+        return true;
+      }
+    }
+
     return super.isOkAsAdditionalTestAllImport(folder, uri);
   }
 }
diff --git a/pkg/analysis_server/tool/bulk_fix/parse_utils.dart b/pkg/analysis_server/tool/bulk_fix/parse_utils.dart
index 4e63e72..d0264a0 100644
--- a/pkg/analysis_server/tool/bulk_fix/parse_utils.dart
+++ b/pkg/analysis_server/tool/bulk_fix/parse_utils.dart
@@ -29,14 +29,14 @@
           .getResolvedUnit(file.absolute.path) as ResolvedUnitResult;
       for (var classDecl
           in resolvedFile.unit.declarations.whereType<ClassDeclaration>()) {
-        var classElement = classDecl.declaredElement2;
+        var classElement = classDecl.declaredElement;
         if (classElement != null &&
             classElement.allSupertypes.any(
                 (element) => element.element2.name == 'CorrectionProducer')) {
-          var correctionName = classDecl.name2.lexeme;
+          var correctionName = classDecl.name.lexeme;
 
           for (var method in classDecl.members.whereType<MethodDeclaration>()) {
-            if (method.name2.lexeme == 'canBeAppliedInBulk') {
+            if (method.name.lexeme == 'canBeAppliedInBulk') {
               var hasComment =
                   method.returnType?.beginToken.precedingComments != null;
 
diff --git a/pkg/analysis_server/tool/code_completion/code_metrics.dart b/pkg/analysis_server/tool/code_completion/code_metrics.dart
index c30111a..5aeddc0 100644
--- a/pkg/analysis_server/tool/code_completion/code_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/code_metrics.dart
@@ -307,7 +307,7 @@
       'documentationComment': node.documentationComment,
       'metadata': node.metadata,
       'abstractKeyword': node.abstractKeyword,
-      'name': node.name2,
+      'name': node.name,
       'typeParameters': node.typeParameters,
       'extendsClause': node.extendsClause,
       'withClause': node.withClause,
@@ -324,7 +324,7 @@
       'documentationComment': node.documentationComment,
       'metadata': node.metadata,
       'abstractKeyword': node.abstractKeyword,
-      'name': node.name2,
+      'name': node.name,
       'typeParameters': node.typeParameters,
       'superclass': node.superclass,
       'withClause': node.withClause,
@@ -387,7 +387,7 @@
       'constKeyword': node.constKeyword,
       'factoryKeyword': node.factoryKeyword,
       'returnType': node.returnType,
-      'name': node.name2,
+      'name': node.name,
       'parameters': node.parameters,
       'initializers': node.initializers,
       'redirectedConstructor': node.redirectedConstructor,
@@ -482,7 +482,7 @@
     _visitChildren(node, {
       'documentationComment': node.documentationComment,
       'metadata': node.metadata,
-      'name': node.name2,
+      'name': node.name,
     });
     super.visitEnumConstantDeclaration(node);
   }
@@ -492,7 +492,7 @@
     _visitChildren(node, {
       'documentationComment': node.documentationComment,
       'metadata': node.metadata,
-      'name': node.name2,
+      'name': node.name,
       'constants': node.constants,
     });
     super.visitEnumDeclaration(node);
@@ -539,7 +539,7 @@
   @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     _visitChildren(node, {
-      'name': node.name2,
+      'name': node.name,
       'typeParameters': node.typeParameters,
       'extendedType': node.extendedType,
       'member': node.members,
@@ -660,7 +660,7 @@
       'metadata': node.metadata,
       'externalKeyword': node.externalKeyword,
       'propertyKeyword': node.propertyKeyword,
-      'name': node.name2,
+      'name': node.name,
       'functionExpression': node.functionExpression,
       'returnType': node.returnType,
     });
@@ -701,7 +701,7 @@
       'documentationComment': node.documentationComment,
       'metadata': node.metadata,
       'returnType': node.returnType,
-      'name': node.name2,
+      'name': node.name,
       'typeParameters': node.typeParameters,
       'parameters': node.parameters,
     });
@@ -737,7 +737,7 @@
     _visitChildren(node, {
       'documentationComment': node.documentationComment,
       'metadata': node.metadata,
-      'name': node.name2,
+      'name': node.name,
       'typeParameters': node.typeParameters,
       'functionType': node.functionType,
     });
@@ -871,7 +871,7 @@
     _visitChildren(node, {
       'documentationComment': node.documentationComment,
       'metadata': node.metadata,
-      'name': node.name,
+      'name': node.name2,
     });
     super.visitLibraryDirective(node);
   }
@@ -910,7 +910,7 @@
       'externalKeyword': node.externalKeyword,
       'modifierKeyword': node.modifierKeyword,
       'returnType': node.returnType,
-      'name': node.name2,
+      'name': node.name,
       'operatorKeyword': node.operatorKeyword,
       'typeParameters': node.typeParameters,
       'parameters': node.parameters,
@@ -935,7 +935,7 @@
     _visitChildren(node, {
       'documentationComment': node.documentationComment,
       'metadata': node.metadata,
-      'name': node.name2,
+      'name': node.name,
       'typeParameters': node.typeParameters,
       'onClause': node.onClause,
       'implementsClause': node.implementsClause,
@@ -1232,7 +1232,7 @@
   @override
   void visitTypeParameter(TypeParameter node) {
     _visitChildren(node, {
-      'name': node.name2,
+      'name': node.name,
       'bound': node.bound,
     });
     super.visitTypeParameter(node);
@@ -1249,7 +1249,7 @@
     _visitChildren(node, {
       'documentationComment': node.documentationComment,
       'metadata': node.metadata,
-      'name': node.name2,
+      'name': node.name,
       'initializer': node.initializer,
     });
     super.visitVariableDeclaration(node);
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics.dart b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
index c651b9e..3125623 100644
--- a/pkg/analysis_server/tool/code_completion/completion_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
@@ -24,7 +24,6 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart'
     show
-        ClassElement,
         ClassMemberElement,
         CompilationUnitElement,
         Element,
@@ -33,6 +32,7 @@
         ExtensionElement,
         FieldElement,
         FunctionElement,
+        InterfaceElement,
         LocalVariableElement,
         MixinElement,
         ParameterElement,
@@ -1701,15 +1701,15 @@
     var entity = expectedCompletion.syntacticEntity;
     var element = _getElement(entity);
     if (element != null) {
-      var parent = element.enclosingElement3;
-      if (parent is ClassElement || parent is ExtensionElement) {
+      var parent = element.enclosingElement;
+      if (parent is InterfaceElement || parent is ExtensionElement) {
         if (_isStatic(element)) {
           return CompletionGroup.staticMember;
         } else {
           return CompletionGroup.instanceMember;
         }
       } else if (parent is CompilationUnitElement &&
-          element is! ClassElement &&
+          element is! InterfaceElement &&
           element is! ExtensionElement) {
         return CompletionGroup.topLevelMember;
       }
@@ -1718,7 +1718,7 @@
         return CompletionGroup.enumElement;
       } else if (element is MixinElement) {
         return CompletionGroup.mixinElement;
-      } else if (element is ClassElement) {
+      } else if (element is InterfaceElement) {
         if (entity is SimpleIdentifier &&
             entity.parent is NamedType &&
             entity.parent!.parent is ConstructorName &&
diff --git a/pkg/analysis_server/tool/code_completion/flutter_metrics.dart b/pkg/analysis_server/tool/code_completion/flutter_metrics.dart
index fdd758e..edab701 100644
--- a/pkg/analysis_server/tool/code_completion/flutter_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/flutter_metrics.dart
@@ -144,7 +144,7 @@
         throw StateError(
             'Unresolved constructor name: ${node.constructorName}');
       }
-      var childWidget = element.enclosingElement3.name;
+      var childWidget = element.enclosingElement.name;
       if (!element.librarySource.uri
           .toString()
           .startsWith('package:flutter/')) {
diff --git a/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart b/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart
index 256995e..113f914 100644
--- a/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart
+++ b/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart
@@ -110,7 +110,7 @@
       if (rhsType != null && !rhsType.isDynamic) {
         // Record the name with the type.
         data.recordImpliedType(
-          node.name2.lexeme,
+          node.name.lexeme,
           rhsType.getDisplayString(withNullability: false),
         );
       }
diff --git a/pkg/analysis_server/tool/code_completion/relevance_metrics.dart b/pkg/analysis_server/tool/code_completion/relevance_metrics.dart
index 2e8c73a..71dc018 100644
--- a/pkg/analysis_server/tool/code_completion/relevance_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/relevance_metrics.dart
@@ -18,7 +18,6 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart'
     show
-        ClassElement,
         Element,
         ExecutableElement,
         ExtensionElement,
@@ -968,10 +967,10 @@
     // There are no completions.
     data.recordPercentage(
         'Methods with type parameters', node.typeParameters != null);
-    var element = node.declaredElement2!;
-    if (!element.isStatic && element.enclosingElement3 is ClassElement) {
+    var element = node.declaredElement!;
+    if (!element.isStatic && element.enclosingElement is InterfaceElement) {
       var overriddenMembers = inheritanceManager.getOverridden2(
-          element.enclosingElement3 as ClassElement,
+          element.enclosingElement as InterfaceElement,
           Name(element.librarySource.uri, element.name));
       if (overriddenMembers != null) {
         // Consider limiting this to the most immediate override. If the
@@ -994,7 +993,7 @@
     if (node.target is SuperExpression) {
       var enclosingMethod = node.thisOrAncestorOfType<MethodDeclaration>();
       if (enclosingMethod != null) {
-        if (enclosingMethod.name2.lexeme == node.methodName.name) {
+        if (enclosingMethod.name.lexeme == node.methodName.name) {
           data.recordTypeMatch('super invocation member', 'same');
         } else {
           data.recordTypeMatch('super invocation member', 'different');
@@ -1121,7 +1120,7 @@
     if (node.target is SuperExpression) {
       var enclosingMethod = node.thisOrAncestorOfType<MethodDeclaration>();
       if (enclosingMethod != null) {
-        if (enclosingMethod.name2.lexeme == node.propertyName.name) {
+        if (enclosingMethod.name.lexeme == node.propertyName.name) {
           data.recordTypeMatch('super property access member', 'same');
         } else {
           data.recordTypeMatch('super property access member', 'different');
@@ -1407,7 +1406,7 @@
     Element? currentElement = element;
     while (currentElement != enclosingLibrary) {
       depth++;
-      currentElement = currentElement?.enclosingElement3;
+      currentElement = currentElement?.enclosingElement;
     }
     return depth;
   }
@@ -1460,7 +1459,7 @@
     if (element == null) {
       return null;
     }
-    if (element is ClassElement) {
+    if (element is InterfaceElement) {
       var parent = node.parent;
       if (parent is Annotation && parent.arguments != null) {
         element = parent.element!;
@@ -1488,12 +1487,12 @@
     var node = reference;
     while (node != null) {
       if (node is MethodDeclaration) {
-        if (node.declaredElement2 == function) {
+        if (node.declaredElement == function) {
           return depth;
         }
         depth++;
       } else if (node is ConstructorDeclaration) {
-        if (node.declaredElement2 == function) {
+        if (node.declaredElement == function) {
           return depth;
         }
         depth++;
@@ -1579,7 +1578,7 @@
       }
       // TODO(brianwilkerson) It might be interesting to also know whether the
       //  [element] was found in a class, interface, or mixin.
-      var memberClass = member.thisOrAncestorOfType<ClassElement>();
+      var memberClass = member.thisOrAncestorOfType<InterfaceElement>();
       if (memberClass != null) {
         /// Return the distance between the [targetClass] and the [memberClass]
         /// along the superclass chain. This includes all of the implicit
@@ -1598,11 +1597,7 @@
               }
             }
             depth++;
-            if (currentClass is ClassElement) {
-              currentClass = currentClass.supertype?.element2;
-            } else {
-              currentClass = null;
-            }
+            currentClass = currentClass.supertype?.element2;
           }
           return -1;
         }
@@ -1614,11 +1609,7 @@
           InterfaceElement? currentClass = targetClass;
           while (currentClass != null) {
             depth += currentClass.mixins.length + 1;
-            if (currentClass is ClassElement) {
-              currentClass = currentClass.supertype?.element2;
-            } else {
-              break;
-            }
+            currentClass = currentClass.supertype?.element2;
           }
           return depth;
         }
@@ -1697,7 +1688,7 @@
     var reference = _leftMostIdentifier(node);
     var element = reference?.staticElement;
     if (element is ParameterElement) {
-      var definingElement = element.enclosingElement3!;
+      var definingElement = element.enclosingElement!;
       var depth = _parameterReferenceDepth(node, definingElement);
       _recordDistance('function depth of referenced parameter', depth);
     } else if (element is LocalVariableElement) {
@@ -1792,7 +1783,7 @@
       var firstTokenType = identifier.staticType;
       if (firstTokenType == null) {
         var element = identifier.staticElement;
-        if (element is ClassElement) {
+        if (element is InterfaceElement) {
           // This is effectively treating a reference to a class name as having
           // the same type as an instance of the class, which isn't valid, but
           // on the other hand, the spec doesn't define the static type of a
diff --git a/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart b/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart
index 419ffe5..e052c82 100644
--- a/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart
+++ b/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart
@@ -16,7 +16,7 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart'
-    show ClassElement, Element, LibraryElement;
+    show Element, InterfaceElement, LibraryElement;
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/dart/element/type_system.dart';
 import 'package:analyzer/diagnostic/diagnostic.dart';
@@ -1348,7 +1348,7 @@
     if (element == null) {
       return null;
     }
-    if (element is ClassElement) {
+    if (element is InterfaceElement) {
       var parent = node.parent;
       if (parent is Annotation && parent.arguments != null) {
         element = parent.element!;
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index 186d133..e726f23 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -97,7 +97,7 @@
 |   textDocument/rangeFormatting | ✅ | | |
 | textDocument/hover | ✅ | | |
 | textDocument/implementation | ✅ | | |
-| textDocument/inlayHint | | | |
+| textDocument/inlayHint | ✅ | | |
 |   inlayHint/resolve | | | |
 | textDocument/inlineValue | | | |
 | textDocument/linkedEditingRange | | | |
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index 5c04744..5dd51f0 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -8,6 +8,7 @@
 import 'package:collection/collection.dart';
 import 'package:dart_style/dart_style.dart';
 
+import 'generate_all.dart';
 import 'meta_model.dart';
 
 final formatter = DartFormatter();
@@ -237,6 +238,11 @@
           (_namespaces.containsKey(type.name)));
 }
 
+bool _isUriType(TypeBase type) {
+  type = resolveTypeAlias(type);
+  return type is TypeReference && type.dartType == 'Uri';
+}
+
 /// Maps reserved words and identifiers that cause issues in field names.
 String _makeValidIdentifier(String identifier) {
   // Some identifiers used in LSP are reserved words in Dart, so map them to
@@ -684,6 +690,17 @@
 
   if (_isSimpleType(type)) {
     buffer.write('$valueCode$cast');
+  } else if (_isUriType(type)) {
+    if (allowsNull) {
+      buffer.write('$valueCode != null ? ');
+    }
+    buffer
+      ..write('Uri.parse(')
+      ..write(requiresCast ? '$valueCode as String' : valueCode)
+      ..write(')');
+    if (allowsNull) {
+      buffer.write(': null');
+    }
   } else if (_isSpecType(type)) {
     // Our own types have fromJson() constructors we can call.
     if (allowsNull) {
@@ -823,24 +840,40 @@
       ..outdent()
       ..writeIndentedln('}');
   }
-  for (final field in allFields) {
-    // Add a local variable to allow type promotion (and avoid multiple lookups).
-    final localName = _makeValidIdentifier(field.name);
-    final localNameJson = '${localName}Json';
-    buffer.writeIndentedln("final $localNameJson = json['${field.name}'];");
-    buffer.writeIndented('final $localName = ');
-    _writeFromJsonCode(buffer, field.type, localNameJson,
-        allowsNull: field.allowsNull || field.allowsUndefined);
-    buffer.writeln(';');
+  if (interface.abstract) {
+    buffer.writeIndentedln(
+      "throw ArgumentError("
+      "'Supplied map is not valid for any subclass of ${interface.name}'"
+      ");",
+    );
+  } else {
+    for (final field in allFields) {
+      // Add a local variable to allow type promotion (and avoid multiple lookups).
+      final localName = _makeValidIdentifier(field.name);
+      final localNameJson = '${localName}Json';
+      buffer.writeIndentedln("final $localNameJson = json['${field.name}'];");
+      buffer.writeIndented('final $localName = ');
+      _writeFromJsonCode(buffer, field.type, localNameJson,
+          allowsNull: field.allowsNull || field.allowsUndefined);
+      buffer.writeln(';');
+    }
+    buffer
+      ..writeIndented('return ${interface.name}(')
+      ..write(allFields.map((field) => '${field.name}: ${field.name}, ').join())
+      ..writeln(');');
   }
   buffer
-    ..writeIndented('return ${interface.name}(')
-    ..write(allFields.map((field) => '${field.name}: ${field.name}, ').join())
-    ..writeln(');')
     ..outdent()
     ..writeIndented('}');
 }
 
+void _writeGetter(IndentableStringBuffer buffer, AbstractGetter getter) {
+  _writeDocCommentsAndAnnotations(buffer, getter);
+  buffer
+    ..writeIndented(getter.type.dartTypeWithTypeArgs)
+    ..writeln(' get ${getter.name};');
+}
+
 void _writeHashCode(IndentableStringBuffer buffer, Interface interface) {
   buffer
     ..writeIndentedln('@override')
@@ -885,7 +918,9 @@
   final isPrivate = interface.name.startsWith('_');
   _writeDocCommentsAndAnnotations(buffer, interface);
 
-  buffer.writeIndented('class ${interface.name} ');
+  buffer
+    ..writeIndented(interface.abstract ? 'abstract ' : '')
+    ..write('class ${interface.name} ');
   final allBaseTypes =
       interface.baseTypes.map((t) => t.dartTypeWithTypeArgs).toList();
   allBaseTypes.add('ToJsonable');
@@ -903,7 +938,10 @@
   // Handle Consts and Fields separately, since we need to include superclass
   // Fields.
   final consts = interface.members.whereType<Constant>().toList();
+  final getters = interface.members.whereType<AbstractGetter>().toList();
   final fields = _getAllFields(interface);
+  _writeMembers(buffer, interface, getters);
+  buffer.writeln();
   _writeMembers(buffer, interface, consts);
   buffer.writeln();
   _writeMembers(buffer, interface, fields);
@@ -955,6 +993,8 @@
     _writeField(buffer, interface, member);
   } else if (member is Constant) {
     _writeConst(buffer, member);
+  } else if (member is AbstractGetter) {
+    _writeGetter(buffer, member);
   } else {
     throw 'Unknown type';
   }
@@ -973,6 +1013,15 @@
     buffer.write('$valueCode$nullOp.map((item) => ');
     _writeToJsonCode(buffer, type.elementType, 'item', '');
     buffer.write(').toList()');
+  } else if (type is MapType &&
+      (_isUriType(type.indexType) || _isUriType(type.valueType))) {
+    buffer.write('$valueCode$nullOp.map((key, value) => MapEntry(');
+    _writeToJsonCode(buffer, type.indexType, 'key', '');
+    buffer.write(', ');
+    _writeToJsonCode(buffer, type.valueType, 'value', '');
+    buffer.write('))');
+  } else if (_isUriType(type)) {
+    buffer.write('$valueCode$nullOp.toString()');
   } else {
     buffer.write(valueCode);
   }
@@ -1076,17 +1125,22 @@
 
   final operator = negation ? '!' : '';
   final and = negation ? '||' : '&&';
+  final or = negation ? '&&' : '||';
   final every = negation ? 'any' : 'every';
+  final equals = negation ? '!=' : '==';
+  final notEqual = negation ? '==' : '!=';
+  final true_ = negation ? 'false' : 'true';
 
   if (isNullableAnyType(type)) {
-    buffer.write(negation ? 'false' : 'true');
+    buffer.write(true_);
   } else if (isObjectType(type)) {
-    final notEqual = negation ? '==' : '!=';
     buffer.write('$valueCode $notEqual null');
   } else if (_isSimpleType(type)) {
     buffer.write('$valueCode is$operator $fullDartType');
+  } else if (_isUriType(type)) {
+    buffer.write('($valueCode is$operator String $and '
+        'Uri.tryParse($valueCode) $notEqual null)');
   } else if (type is LiteralType) {
-    final equals = negation ? '!=' : '==';
     buffer.write('$valueCode $equals literal');
   } else if (type is LiteralUnionType) {
     buffer.write('${operator}literals.contains(value)');
@@ -1132,7 +1186,7 @@
     if (parenForCollection) {
       buffer.write('(');
     }
-    var or = negation ? '&&' : '||';
+
     // To type check a union, we just recursively check against each of its types.
     for (var i = 0; i < type.types.length; i++) {
       if (i != 0) {
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index c13c828..a58dda1 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -112,9 +112,10 @@
 List<LspEntity> getCustomClasses() {
   /// Helper to create an interface type.
   Interface interface(String name, List<Member> fields,
-      {String? baseType, String? comment}) {
+      {String? baseType, String? comment, bool abstract = false}) {
     return Interface(
       name: name,
+      abstract: abstract,
       comment: comment,
       baseTypes: [if (baseType != null) TypeReference(baseType)],
       members: fields,
@@ -127,16 +128,21 @@
     String? comment,
     required String type,
     bool array = false,
+    bool literal = false,
+    bool canBeNull = false,
     bool canBeUndefined = false,
   }) {
-    final fieldType =
-        array ? ArrayType(TypeReference(type)) : TypeReference(type);
+    final fieldType = array
+        ? ArrayType(TypeReference(type))
+        : literal
+            ? LiteralType(TypeReference.string, type)
+            : TypeReference(type);
 
     return Field(
       name: name,
       comment: comment,
       type: fieldType,
-      allowsNull: false,
+      allowsNull: canBeNull,
       allowsUndefined: canBeUndefined,
     );
   }
@@ -189,7 +195,7 @@
       [
         Field(
           name: 'id',
-          type: UnionType([TypeReference('int'), TypeReference('string')]),
+          type: UnionType([TypeReference.int, TypeReference.string]),
           allowsNull: false,
           allowsUndefined: false,
         )
@@ -206,7 +212,7 @@
       [
         Field(
           name: 'id',
-          type: UnionType([TypeReference('int'), TypeReference('string')]),
+          type: UnionType([TypeReference.int, TypeReference.string]),
           allowsNull: true,
           allowsUndefined: false,
         ),
@@ -236,15 +242,20 @@
     ),
     TypeAlias(
       name: 'DocumentUri',
-      baseType: TypeReference('string'),
+      baseType: TypeReference('Uri'),
+      isRename: false,
+    ),
+    TypeAlias(
+      name: 'LSPUri',
+      baseType: TypeReference('Uri'),
       isRename: false,
     ),
 
     interface('DartDiagnosticServer', [field('port', type: 'int')]),
     interface('AnalyzerStatusParams', [field('isAnalyzing', type: 'boolean')]),
     interface('PublishClosingLabelsParams', [
-      field('uri', type: 'string'),
-      field('labels', type: 'ClosingLabel', array: true)
+      field('uri', type: 'Uri'),
+      field('labels', type: 'ClosingLabel', array: true),
     ]),
     interface('ClosingLabel',
         [field('range', type: 'Range'), field('label', type: 'string')]),
@@ -257,16 +268,16 @@
       field('returnType', type: 'string', canBeUndefined: true),
     ]),
     interface('PublishOutlineParams',
-        [field('uri', type: 'string'), field('outline', type: 'Outline')]),
+        [field('uri', type: 'Uri'), field('outline', type: 'Outline')]),
     interface('Outline', [
       field('element', type: 'Element'),
       field('range', type: 'Range'),
       field('codeRange', type: 'Range'),
-      field('children', type: 'Outline', array: true, canBeUndefined: true)
+      field('children', type: 'Outline', array: true, canBeUndefined: true),
     ]),
     interface('PublishFlutterOutlineParams', [
-      field('uri', type: 'string'),
-      field('outline', type: 'FlutterOutline')
+      field('uri', type: 'Uri'),
+      field('outline', type: 'FlutterOutline'),
     ]),
     interface('FlutterOutline', [
       field('kind', type: 'string'),
@@ -279,7 +290,7 @@
       field('range', type: 'Range'),
       field('codeRange', type: 'Range'),
       field('children',
-          type: 'FlutterOutline', array: true, canBeUndefined: true)
+          type: 'FlutterOutline', array: true, canBeUndefined: true),
     ]),
     interface(
       'FlutterOutlineAttribute',
@@ -353,23 +364,27 @@
       'CommandParameter',
       [
         field(
-          'label',
+          'parameterLabel',
           type: 'String',
           comment:
               'A human-readable label to be displayed in the UI affordance '
               'used to prompt the user for the value of the parameter.',
         ),
-        field(
-          'type',
-          type: 'CommandParameterType',
-          comment: 'The type of the value of the parameter.',
+        AbstractGetter(
+          name: 'kind',
+          type: TypeReference.string,
+          comment: 'The kind of this parameter. The client may use different '
+              'UIs based on this value.',
         ),
-        field(
-          'defaultValue',
-          type: 'String',
-          comment: 'The default value for the parameter.',
+        AbstractGetter(
+          name: 'defaultValue',
+          type: TypeReference.LspAny,
+          comment: 'An optional default value for the parameter. The type of '
+              'this value may vary between parameter kinds but must always be '
+              'something that can be converted directly to/from JSON.',
         ),
       ],
+      abstract: true,
       comment: 'Information about one of the arguments needed by the command.'
           '\n\n'
           'A list of parameters is sent in the `data` field of the '
@@ -377,35 +392,43 @@
           'should appear in the `args` field of the `Command` sent to the '
           'server in the same order as the corresponding parameters.',
     ),
-    LspEnum(
-      name: 'CommandParameterType',
-      comment: 'The type of the value associated with a CommandParameter. All '
-          'values are encoded as strings, but the type indicates how the '
-          'string will be decoded by the server.',
-      members: [
-        Constant(
-          name: 'boolean',
-          value: 'boolean',
-          type: TypeReference('String'),
-          comment: 'The type associated with a bool value.'
-              '\n\n'
-              "The value must either be `'true'` or `'false'`.",
+    interface(
+      'SaveUriCommandParameter',
+      [
+        field(
+          'kind',
+          type: 'saveUri',
+          literal: true,
         ),
-        Constant(
-          name: 'string',
-          value: 'string',
-          type: TypeReference('String'),
-          comment: 'The type associated with a string value.',
+        field(
+          'defaultValue',
+          type: 'String',
+          canBeNull: true,
+          canBeUndefined: true,
+          comment: 'An optional default URI for the parameter.',
         ),
-        Constant(
-          name: 'filePath',
-          value: 'filePath',
-          type: TypeReference('String'),
-          comment:
-              'The type associated with a value representing a path to a file.',
+        field(
+          'parameterTitle',
+          type: 'String',
+          comment: 'A title that may be displayed on a file dialog.',
+        ),
+        field(
+          'actionLabel',
+          type: 'String',
+          comment: 'A label for the file dialogs action button.',
+        ),
+        Field(
+          name: 'filters',
+          type: MapType(TypeReference.string, ArrayType(TypeReference.string)),
+          allowsNull: true,
+          allowsUndefined: true,
+          comment: 'A set of file filters for a file dialog. '
+              'Keys of the map are textual names ("Dart") and the value '
+              'is a list of file extensions (["dart"]).',
         ),
       ],
-      typeOfValues: TypeReference('String'),
+      baseType: 'CommandParameter',
+      comment: 'Information about a Save URI argument needed by the command.',
     ),
   ];
   return customTypes;
@@ -423,3 +446,12 @@
 
   return model.types;
 }
+
+class AbstractGetter extends Member {
+  final TypeBase type;
+  AbstractGetter({
+    required super.name,
+    super.comment,
+    required this.type,
+  });
+}
diff --git a/pkg/analysis_server/tool/lsp_spec/meta_model.dart b/pkg/analysis_server/tool/lsp_spec/meta_model.dart
index 8273079..c745e6f 100644
--- a/pkg/analysis_server/tool/lsp_spec/meta_model.dart
+++ b/pkg/analysis_server/tool/lsp_spec/meta_model.dart
@@ -81,12 +81,14 @@
 class Interface extends LspEntity {
   final List<TypeReference> baseTypes;
   final List<Member> members;
+  final bool abstract;
 
   Interface({
     required super.name,
     super.comment,
     this.baseTypes = const [],
     required this.members,
+    this.abstract = false,
   }) {
     baseTypes.sortBy((type) => type.dartTypeWithTypeArgs.toLowerCase());
     members.sortBy((member) => member.name.toLowerCase());
@@ -249,14 +251,17 @@
 
 /// A reference to a Type by name.
 class TypeReference extends TypeBase {
-  static final TypeBase Undefined = TypeReference('undefined');
-  static final TypeBase Null_ = TypeReference('Null');
+  static final TypeBase undefined = TypeReference('undefined');
+  static final TypeBase null_ = TypeReference('Null');
+  static final TypeBase string = TypeReference('string');
+  static final TypeBase int = TypeReference('int');
 
   /// Any object (but not null).
   static final TypeBase LspObject = TypeReference('Object');
 
   /// Any object (or null/undefined).
-  static final TypeBase LspAny = NullableType(TypeReference('Object'));
+  static final TypeBase LspAny = NullableType(TypeReference.LspObject);
+
   final String name;
   final List<TypeBase> typeArgs;
 
diff --git a/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.dart b/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.dart
index b1b77ef..20abf89 100644
--- a/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.dart
+++ b/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.dart
@@ -39,7 +39,9 @@
         .where((type) => _includeTypeInOutput(type.name))
         .map(_clean)
         .toList();
-    types = _renameTypes(types).toList();
+    types = _renameTypes(types)
+        .where((type) => _includeTypeInOutput(type.name))
+        .toList();
     return types;
   }
 
@@ -293,6 +295,7 @@
       // unions with so many types).
       'LSPAny',
       'LSPObject',
+      'LSPUri',
       // The meta model currently includes an unwanted type named 'T' that we
       // don't want to create a class for.
       // TODO(dantup): Remove this once it's gone from the JSON model.
@@ -303,7 +306,7 @@
       // when getting the .dartType for it.
       'MarkedString'
     };
-    final shouldIgnore = ignoredTypes.contains(name) ||
+    var shouldIgnore = ignoredTypes.contains(name) ||
         ignoredPrefixes.any((ignore) => name.startsWith(ignore));
     return !shouldIgnore;
   }
@@ -365,7 +368,7 @@
       'TextDocumentFilter2': 'TextDocumentFilterWithScheme',
       'PrepareRenameResult1': 'PlaceholderAndRange',
       'Pattern': 'LspPattern',
-      'URI': 'LspUri',
+      'URI': 'LSPUri',
     };
 
     for (final type in types) {
diff --git a/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart b/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart
index aa11e78..f21a242 100644
--- a/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart
+++ b/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart
@@ -80,7 +80,7 @@
       return Constant(
         name: _generateMemberName(value, camelCase: true),
         comment: comment,
-        type: TypeReference('string'),
+        type: TypeReference.string,
         value: value,
       );
     }
@@ -95,7 +95,7 @@
     return LspEnum(
       name: 'Method',
       comment: comment,
-      typeOfValues: TypeReference('string'),
+      typeOfValues: TypeReference.string,
       members: methodConstants,
     );
   }
@@ -194,7 +194,7 @@
       return TypeReference(inlineTypeName);
     } else if (model['kind'] == 'stringLiteral') {
       return LiteralType(
-        TypeReference('string'),
+        TypeReference.string,
         model['value'] as String,
       );
     } else if (model['kind'] == 'or') {
diff --git a/pkg/analysis_server/tool/spec/check_all_test.dart b/pkg/analysis_server/tool/spec/check_all_test.dart
index 3be8ed7..5ae7e1e 100644
--- a/pkg/analysis_server/tool/spec/check_all_test.dart
+++ b/pkg/analysis_server/tool/spec/check_all_test.dart
@@ -11,7 +11,7 @@
 
 /// Check that all targets have been code generated.  If they haven't tell the
 /// user to run generate_all.dart.
-void main() async {
+Future<void> main() async {
   var script = Platform.script.toFilePath(windows: Platform.isWindows);
   var components = split(script);
   var index = components.indexOf('analysis_server');
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index c17311f..e8bafaf 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -511,12 +511,10 @@
       args.add('{${optionalArgs.join(', ')}}');
     }
     write('$className(${args.join(', ')})');
-    if (initializers.isEmpty) {
-      writeln(';');
-    } else {
+    if (initializers.isNotEmpty) {
       writeln(' : ${initializers.join(', ')}');
-      writeln(';');
     }
+    writeln(';');
   }
 
   /// Emit the operator== code for an object class.
diff --git a/pkg/analysis_server/tool/spec/generate_all.dart b/pkg/analysis_server/tool/spec/generate_all.dart
index 20840ce..f6f43af 100644
--- a/pkg/analysis_server/tool/spec/generate_all.dart
+++ b/pkg/analysis_server/tool/spec/generate_all.dart
@@ -18,7 +18,7 @@
 import 'to_html.dart' as to_html;
 
 /// Generate all targets.
-void main() async {
+Future<void> main() async {
   var script = Platform.script.toFilePath(windows: Platform.isWindows);
   var pkgPath = normalize(join(dirname(script), '..', '..'));
   await GeneratedContent.generateAll(pkgPath, allTargets);
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 89c2e07..4f7e7722 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -464,7 +464,7 @@
    *
    * @param paths A list of objects each containing a path and the additional libraries from which
    *        the client is interested in receiving completion suggestions. If one configured path is
-   *        beneath another, the descendent will override the ancestors' configured libraries of
+   *        beneath another, the descendant will override the ancestors' configured libraries of
    *        interest.
    *
    * @deprecated
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 2247e0e..e57fb70 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1640,7 +1640,7 @@
         <p>
           A list of objects each containing a path and the additional libraries from which
           the client is interested in receiving completion suggestions.
-          If one configured path is beneath another, the descendent
+          If one configured path is beneath another, the descendant
           will override the ancestors' configured libraries of interest.
         </p>
       </field>
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 968009d..983875f 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -5180,7 +5180,7 @@
 class CompletionRegisterLibraryPathsParams implements RequestParams {
   /// A list of objects each containing a path and the additional libraries
   /// from which the client is interested in receiving completion suggestions.
-  /// If one configured path is beneath another, the descendent will override
+  /// If one configured path is beneath another, the descendant will override
   /// the ancestors' configured libraries of interest.
   List<LibraryPathSet> paths;
 
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 4c5a91c..d57ecff 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,5 +1,28 @@
-## 4.7.0-dev
+## 5.2.0-dev
+* Deprecated `Element.enclosingElement3`, use `enclosingElement` instead.
+
+## 5.1.0
+* Deprecated `AstNode.name2`, use `name` instead.
+* Deprecated `AstNode.declaredElement2`, use `declaredElement` instead.
+
+## 5.0.0
+* Removed deprecated methods from AST.
+* Removed deprecated `DiagnosticMessage.message`.
+* Removed deprecated `LibraryElement.getImportsWithPrefix()`.
+* Removed deprecated `ParameterElement.isNotOptional`.
+* Removed deprecated `DartType.displayName`.
+* Removed deprecated methods from `AnalysisDriver`.
+* Removed deprecated `ClassOrMixinDeclaration`.
+* Removed deprecated `Declaration.declaredElement`.
+* Removed deprecated `Element.enclosingElement` and `enclosingElement2`.
+* Removed deprecated `ExportElement`, `ImportElement`.
+* Removed deprecated `NamedCompilationUnitMember.name`.
+* Removed deprecated `Declaration.declaredElement`.
+* Removed deprecated `DartType.element`.
+
+## 4.7.0
 * Add missing `addXyz` to `NodeLintRegistry`.
+* Add `lookUpInheritedConcreteX()` to `InterfaceElement`.
 
 ## 4.6.0
 * Added `DartType.element2`, so that `InterfaceType.element2` overrides it.
diff --git a/pkg/analyzer/doc/implementation/ast.md b/pkg/analyzer/doc/implementation/ast.md
new file mode 100644
index 0000000..92d65e6
--- /dev/null
+++ b/pkg/analyzer/doc/implementation/ast.md
@@ -0,0 +1,141 @@
+# Extending the AST
+
+Supporting a new language feature often requires extending the AST. This
+document describes what's involved in adding new fields to exiting nodes or
+adding new nodes. This document does not describe the work that needs to be done
+after the AST structure has been updated; those topics are covered in other
+documents.
+
+Note that not every new language feature requires updating the AST, and the AST
+structure should only be updated when necessary. For example, if Dart were to
+introduce a new binary operator, there likely wouldn't be any need for new nodes
+because the existing nodes would probably cover the changes to the grammar. So,
+the first step should always be to consider whether changes need to be made.
+
+If it is necessary to change the AST, then you'll either be modifying an
+existing node or adding new nodes. Those tasks are discussed separately.
+
+## Extending or changing an existing node
+
+If an existing syntactic construct is being changed, then you should probably
+update the existing node representing that construct. If the change is
+significant enough it's possible that it's better to add a new node, but that
+should be uncommon.
+
+If the change is to add some new tokens or child nodes, then doing so ought to
+be a non-breaking change. For each of the children you'll need to add a new
+getter and a new parameter to the constructor on the implementation class, but
+the implementation classes aren't public API.
+
+If the change requires a modification to an existing part of the public API,
+then it needs to be handled by first adding the replacement for the modified
+member, deprecating the old member, and then removing the old member as part of
+a later breaking change release.
+
+## Adding new nodes
+
+If there are new syntactic constructs that can't cleanly be represented by an
+existing class of node, then you'll need to add new classes. This section
+describes what's involved in doing so.
+
+### Design the node structure
+
+The first step is to design the new node structure. We want the structure of the
+AST to be self-consistent, so this section will discuss a few of the design
+tradeoffs that you'll need to consider.
+
+The node structure generally follows from the language grammar. That doesn't
+mean that the structure follows the grammar exactly, but it _is_ representing
+the syntax of the language, so, with one exception discussed below, it should be
+equivalent to the original grammar, even if it's rewritten slightly.
+
+If a grammar productions contain alternates (`|`), then you should create a
+different node class for each branch of the production.
+
+If a production has an optional group (`(a b c)?`), you should create a separate
+node class for the group. It's generally better to have one nullable getter for
+the whole group than to have separate nullable getters for each element of the
+group when the getters either all return `null` or all return a non-`null`
+value. 
+
+If a production has a repeated element (`a*`), you should create a separate node
+class for the repeated element and the AST will contain a list of such elements.
+
+The one exception (to the rule that the AST should be equivalent to the language
+grammar) is that it is sometimes better for the AST to represent a superset of
+the grammar. We do this primarily to improve recovery in the face of invalid
+code.
+
+### Define the public API
+
+The next step is to define the public API for the new AST nodes. We do that by
+defining abstract classes in `analyzer/lib/dart/ast/ast.dart`. Every member of
+the class should also be abstract because we're using the class as an interface.
+That means that you can define getters and methods, but shouldn't define fields.
+And because the AST is always read-only from a client's perspective, there also
+shouldn't be any setters.
+
+By convention, these classes use `implements` to represent the type hierarchy
+rather than using `extends`. We do that to emphasize that we're defining an
+interface, not a class. Every class (other than `AstNode`) should implement at
+least one other class in this file, with `AstNode` being the root of the type
+hierarchy.
+
+The AST nodes typically have getters for all the tokens and child nodes in the
+AST structure. The one exception is that we generally don't capture the commas
+separating the elements in lists.
+
+It's often useful to get a review of the node structure you've created before
+going on to the next steps because it will save you a lot of work if the node
+structure changes as a result of the code review.
+
+### Define the implementation
+
+After the public API is defined you'll need to implement the nodes. The
+implementation should be defined in `analyzer/lib/src/dart/ast/ast.dart`.
+
+There will typically be one concrete implementation class for each of the
+abstract public classes defined above. The concrete class must implement the
+public class and should extend one of the concrete classes corresponding to one
+of the classes that the abstract class implements.
+
+### Add the nodes to the visitor classes
+
+A new `visit` method should be added to `AstVisitor` for a subset of the new
+public interfaces that were added. In particular, there should be a `visit`
+method for each of the interfaces for which there will be a node in the AST that
+is an instance of that interface but not an instance of a subtype of that
+interface.
+
+Adding these `visit` methods will require you to add corresponding `visit`
+methods to several utility visitors that implement `AstVisitor`. For the most
+part you can replicate one of the existing methods in the utility visitors to
+implement the new `visit` methods.
+
+One exception is the class `GeneralizingAstVisitor`, where you might want to add
+some additional `visit` methods for some supertypes of the interfaces being
+visited.
+
+Another exception is the class `ToSourceVisitor` where each visit method needs
+to textually reproduce the node. The produced text should be as close to valid
+Dart syntax as possible, but doesn't need to attempt to reproduce the original
+text. In particular, the methods don't preserve things like comments or trailing
+commas (unless those trailing commas are semantically meaningful).
+
+### Add linter support
+
+In order for lints to be able to visit the new node classes you also need to
+update the classes in `analyzer/lib/src/lint/linter_visitor.dart`.
+
+For each class of node that was added you need to add one field and one `add`
+method in `NodeLintRegistry`. You then need to add visit methods to
+`LinterVisitor`. All of this code can be modeled after the implementation of
+existing methods.
+
+### Add test support
+
+Many of the tests use a utility class named `FindNode` to locate nodes of
+interest within an AST structure. That class has a separate method for each
+concrete subclass of `AstNode`, so you'll want to add methods to it for each of
+the classes you've added. The class is in
+`analyzer/lib/src/test_utilities/find_node.dart`.
diff --git a/pkg/analyzer/doc/implementation/diagnostics.md b/pkg/analyzer/doc/implementation/diagnostics.md
new file mode 100644
index 0000000..6e70ca0
--- /dev/null
+++ b/pkg/analyzer/doc/implementation/diagnostics.md
@@ -0,0 +1,68 @@
+# Adding a new diagnostic
+
+This document describes the process of adding a new (non-lint) diagnostic to the
+analyzer.
+
+## Define the diagnostic code
+
+The first step is to define the code(s) associated with the diagnostic.
+
+The codes are defined in the file `analyzer/messages.yaml`. There's a comment at
+the top of the file describing the structure of the file.
+
+Every diagnostic has at least one code associated with it. A code defines the
+problem and correction messages that will be shown to users.
+
+For most diagnostics, a single message (code) is sufficient. But sometimes it's
+useful to tailor the message based on the context in which the problem occurs or
+because the message can be made more clear. For example, it's an error to
+declare two or more constructors with the same name. That's true whether the
+name is explicit or implicit (the default constructor). In order for the message
+to match the user's model of the language, we define two messages for this one
+problem: one that refers to the constructors by their name, and one that refers
+to the constructors as "unnamed". The way we define two messages is by defining
+two codes.
+
+Each code has a unique name (the key used in the map in `messages.yaml`) and can
+optionally define a shared name that links all the codes for a single diagnostic
+together. It is the shared name that is displayed to users. If a shared name
+isn't explicitly provided, it will default to being the same as the unique name.
+
+After every edit to the `messages.yaml` file, you will need to run the utility
+`analyzer/tool/messages/generate.dart` to update the generated files.
+
+You also need to manually add the name of the code to the list of codes in two
+files:
+- `analyzer/lib/error/error.dart`
+- `analysis_server/lib/src/services/correction/error_fix_status.yaml`
+
+In the status file, the code should have the line
+```yaml
+  status: needsEvaluation
+```
+nested under the name of the code.
+
+## Write tests
+
+We recommend writing the tests for a diagnostic before writing the code to
+generate the diagnostic. Doing so helps you think about the specific cases that
+the implementation code needs to handle, which can result in cleaner
+implementation code and fewer bugs.
+
+The tests for each diagnostic code (or set of codes that have the same shared
+name) are in a separate file in the directory `analyzer/test/src/diagnostics`.
+Looking at the implementation of tests in a few of the other files can help you
+see the basic pattern, but all the tests essentially work by setting up the code
+to be analyzed, then assert that either the expected diagnostic has been
+produced in the expected locations or that there are no diagnostics being
+generated. (It's often valuable to test that the diagnostic doesn't have any
+false positives.)
+
+## Report the diagnostic
+
+The last step is to write the code to report the diagnostic. Where that code
+lives depends on the kind of diagnostic you're adding. If you're adding a
+diagnostic that's defined by the language specification (with a severity of
+'error'), then the best place to implement it will usually be in one of the
+`<node class>Resolver` classes. If you're adding a warning, then the class
+`BestPracticesVerifier` is usually the best place for it.
\ No newline at end of file
diff --git a/pkg/analyzer/doc/implementation/tests.md b/pkg/analyzer/doc/implementation/tests.md
new file mode 100644
index 0000000..56e3dd1
--- /dev/null
+++ b/pkg/analyzer/doc/implementation/tests.md
@@ -0,0 +1,145 @@
+# Testing the analyzer
+
+## Test mechanics
+
+The analyzer uses the `test_reflective_loader` package for most of its tests.
+The `test_reflective_loader` package uses the `test` package to actually run the
+tests, but it provides a JUnit style mechanism for writing the tests.
+
+### Directory layout
+
+The tests, as expected, are in the top-level `test` directory. The structure of
+the directories within the `test` directory should match the structure of the
+`lib` directory whenever possible. The tests are in files whose name ends with
+`_test.dart`. This convention is used by the test runner on the bots to identify
+the files to be run, so a failure to follow this convention will cause the tests
+to not be run on the bots.
+
+For convenience, every directory in the `test` directory (including the `test`
+directory) contains a file named `test_all.dart`. That file isn't run on the
+bots, but can be run manually in order to run all the tests in the containing
+directory and all subdirectories.
+
+### Test file content
+
+Within a test file, the tests are defined in one or more classes. By convention,
+the class name should end with `Test`. The class must be annotated with
+`@reflectiveTest`.
+
+In order for the file to be executable, it must define a `main` method that
+looks something like the following, with one invocation of
+`defineReflectiveTests` for every reflective test class in the file:
+
+```dart
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(CompilationUnitImplTest);
+    // ...
+  });
+}
+```
+
+When the tests are run the test loader will reflect on the specified class
+(`CompilationUnitImplTest` in the example above) to find all the zero parameter
+instance methods whose name starts with 'test_'. These methods should have a
+return type of either `void` or `Future<void>`.
+
+There are a couple of useful annotations defined for test methods.
+
+- You can annotate a test with `@FailingTest()` to indicate that it is expected
+  to fail when run. This allows us to commit tests for bugs before working on a
+  fix for those bugs. The constructor has some optional parameters that allow
+  you to specify the reason for the failure and an issue URL.
+
+- You can annotate a test with `@SkippedTest()` if the test should not be run.
+  The constructor has the same optional parameters for specifying the reason and
+  an issue URL.
+
+- During development, you can mark one or more tests with `@soloTest` to cause
+  those tests to be the only tests that are run.
+
+### Test names
+
+Defining tests as methods on a class rather than as invocations of the `test`
+and `group` functions has the advantage that we can define common test utilities
+and share them across a large number of tests. To do that without classes would
+be much harder.
+
+But this style of test also has the disadvantage that we can't organize the
+tests into groups. In order to overcome this disadvantage we have adopted an
+uncommon naming convention for the test methods that combines the camel case and
+snake case conventions.
+
+Let's start with an example. Assume that we have a class named `ToSourceVisitor`
+that is a visitor with a separate method for every class of AST node, and that
+we want to test every method. Using `group` and `test`, we'd probably create a
+group for the class, then a subgroup for each visit method. For nodes with
+optional children, such as a list literal (where the `const` modifier and type
+arguments are both optional) you might have a group for literals with or without
+the type arguments, and then tests both with and without the modifier. In other
+words, you might end up with a structure like this:
+
+```dart
+void main() {
+  group('ToSourceVisitor', () {
+    group('visitListLiteral', () {
+      group('with type arguments', () {
+        test('with const', () { ... });
+        test('without const', () { ... });
+      });
+      group('without type arguments', () {
+        test('with const', () { ... });
+        test('without const', () { ... });
+      });
+    });
+  });
+}
+```
+
+In out tests, the top-level group is replaced by the class, which would be
+named `ToSourceVisitorTest`. The methods would all start with `test`, and each
+group's name would be converted to a camelCase identifier with groups being
+separated with an underscore. So the equivalent to the code above would be:
+
+```dart
+class ToSourceVisitorTest {
+  void test_visitListLiteral_withTypeArguments_withConst() { ... }
+
+  void test_visitListLiteral_withTypeArguments_withoutConst() { ... }
+
+  void test_visitListLiteral_withoutTypeArguments_withConst() { ... }
+
+  void test_visitListLiteral_withoutTypeArguments_withoutConst() { ... }
+}
+```
+
+### Test cases
+
+Most of our tests take a small piece of Dart code and test the behavior of some
+piece of functionality. In most cases the Dart code is required to be a whole
+compilation unit, though there are a few tests where only a snippet of code is
+required. We have a couple of conventions that, while not strictly enforced, are
+generally followed.
+
+Test code generally appears in a multi-line string, even when it would fit on a
+single line, with the text fully left justified, and with the closing quotes on
+a separate line. For example:
+
+```dart
+  test_final_noInitializer() async {
+    await assertNoErrorsInCode('''
+abstract class C {
+  abstract final int x;
+}
+''');
+  }
+```
+
+Test code should be kept as short as possible. Use short names and don't
+include code that isn't required in order to test what's being tested.
+
+Test code should generally follow best practices unless the deviation from best
+practices is a necessary part of what's being tested.
+
+Don't use a name with a special meaning, like `main`, unless it's important that
+you do so for the test.
diff --git a/pkg/analyzer/doc/tutorial/ast.md b/pkg/analyzer/doc/tutorial/ast.md
index 145e975..c3e275c 100644
--- a/pkg/analyzer/doc/tutorial/ast.md
+++ b/pkg/analyzer/doc/tutorial/ast.md
@@ -90,19 +90,19 @@
 void printMembers(CompilationUnit unit) {
   for (CompilationUnitMember unitMember in unit.declarations) {
     if (unitMember is ClassDeclaration) {
-      print(unitMember.name2.lexeme);
+      print(unitMember.name.lexeme);
       for (ClassMember classMember in unitMember.members) {
         if (classMember is MethodDeclaration) {
-          print('  ${classMember.name2.lexeme}');
+          print('  ${classMember.name.lexeme}');
         } else if (classMember is FieldDeclaration) {
           for (VariableDeclaration field in classMember.fields.variables) {
-            print('  ${field.name2.lexeme}');
+            print('  ${field.name.lexeme}');
           }
         } else if (classMember is ConstructorDeclaration) {
-          if (classMember.name2 == null) {
-            print('  ${unitMember.name2.lexeme}');
+          if (classMember.name == null) {
+            print('  ${unitMember.name.lexeme}');
           } else {
-            print('  ${unitMember.name2.lexeme}.${classMember.name2.lexeme}');
+            print('  ${unitMember.name.lexeme}.${classMember.name.lexeme}');
           }
         }
       }
diff --git a/pkg/analyzer/lib/dart/analysis/code_style_options.dart b/pkg/analyzer/lib/dart/analysis/code_style_options.dart
index b0e7804..5c968a6 100644
--- a/pkg/analyzer/lib/dart/analysis/code_style_options.dart
+++ b/pkg/analyzer/lib/dart/analysis/code_style_options.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/dart/ast/ast.dart';
+
 /// A set of options related to coding style that apply to the code within a
 /// single analysis context.
 ///
@@ -14,6 +16,10 @@
   /// Return `true` if local variables should be `final` whenever possible.
   bool get makeLocalsFinal;
 
+  /// Return the preferred quote based on the enabled lints, otherwise a single
+  /// quote.
+  String get preferredQuoteForStrings;
+
   /// Return `true` if constructors should be sorted first, before other
   /// class members.
   bool get sortConstructorsFirst;
@@ -25,4 +31,8 @@
   /// Return `true` if URIs should be "relative", meaning without a scheme,
   /// whenever possible.
   bool get useRelativeUris;
+
+  /// Return the preferred quote based on the enabled lints, otherwise based
+  /// on the most common quote, otherwise a single quote.
+  String preferredQuoteForUris(List<NamespaceDirective> directives);
 }
diff --git a/pkg/analyzer/lib/dart/analysis/features.dart b/pkg/analyzer/lib/dart/analysis/features.dart
index 390c532..395c6ef 100644
--- a/pkg/analyzer/lib/dart/analysis/features.dart
+++ b/pkg/analyzer/lib/dart/analysis/features.dart
@@ -40,6 +40,9 @@
   /// Feature information for macros.
   static final macros = ExperimentalFeatures.macros;
 
+  /// Feature information for patterns.
+  static final patterns = ExperimentalFeatures.patterns;
+
   /// Feature information for records.
   static final records = ExperimentalFeatures.records;
 
@@ -63,6 +66,9 @@
   static final nonfunction_type_aliases =
       ExperimentalFeatures.nonfunction_type_aliases;
 
+  /// Feature information for unnamed libraries.
+  static final unnamedLibraries = ExperimentalFeatures.unnamed_libraries;
+
   /// Feature information for variance.
   static final variance = ExperimentalFeatures.variance;
 
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 7347f47..dbf7969 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -38,7 +38,7 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
+import 'package:analyzer/src/generated/source.dart' show LineInfo;
 import 'package:meta/meta.dart';
 
 /// Two or more string literals that are implicitly concatenated because of
@@ -371,6 +371,8 @@
 
   R? visitBinaryExpression(BinaryExpression node);
 
+  R? visitBinaryPattern(BinaryPattern node);
+
   R? visitBlock(Block node);
 
   R? visitBlockFunctionBody(BlockFunctionBody node);
@@ -381,6 +383,10 @@
 
   R? visitCascadeExpression(CascadeExpression node);
 
+  R? visitCaseClause(CaseClause node);
+
+  R? visitCastPattern(CastPattern node);
+
   R? visitCatchClause(CatchClause node);
 
   R? visitCatchClauseParameter(CatchClauseParameter node);
@@ -399,6 +405,8 @@
 
   R? visitConfiguration(Configuration node);
 
+  R? visitConstantPattern(ConstantPattern node);
+
   R? visitConstructorDeclaration(ConstructorDeclaration node);
 
   R? visitConstructorFieldInitializer(ConstructorFieldInitializer node);
@@ -443,6 +451,8 @@
 
   R? visitExtensionOverride(ExtensionOverride node);
 
+  R? visitExtractorPattern(ExtractorPattern node);
+
   R? visitFieldDeclaration(FieldDeclaration node);
 
   R? visitFieldFormalParameter(FieldFormalParameter node);
@@ -451,6 +461,8 @@
 
   R? visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node);
 
+  R? visitForEachPartsWithPattern(ForEachPartsWithPattern node);
+
   R? visitForElement(ForElement node);
 
   R? visitFormalParameterList(FormalParameterList node);
@@ -459,6 +471,8 @@
 
   R? visitForPartsWithExpression(ForPartsWithExpression node);
 
+  R? visitForPartsWithPattern(ForPartsWithPattern node);
+
   R? visitForStatement(ForStatement node);
 
   R? visitFunctionDeclaration(FunctionDeclaration node);
@@ -517,8 +531,14 @@
 
   R? visitListLiteral(ListLiteral node);
 
+  R? visitListPattern(ListPattern node);
+
   R? visitMapLiteralEntry(MapLiteralEntry node);
 
+  R? visitMapPattern(MapPattern node);
+
+  R? visitMapPatternEntry(MapPatternEntry node);
+
   R? visitMethodDeclaration(MethodDeclaration node);
 
   R? visitMethodInvocation(MethodInvocation node);
@@ -539,12 +559,25 @@
 
   R? visitParenthesizedExpression(ParenthesizedExpression node);
 
+  R? visitParenthesizedPattern(ParenthesizedPattern node);
+
   R? visitPartDirective(PartDirective node);
 
   R? visitPartOfDirective(PartOfDirective node);
 
+  R? visitPatternAssignment(PatternAssignment node);
+
+  R? visitPatternAssignmentStatement(PatternAssignmentStatement node);
+
+  R? visitPatternVariableDeclaration(PatternVariableDeclaration node);
+
+  R? visitPatternVariableDeclarationStatement(
+      PatternVariableDeclarationStatement node);
+
   R? visitPostfixExpression(PostfixExpression node);
 
+  R? visitPostfixPattern(PostfixPattern node);
+
   R? visitPrefixedIdentifier(PrefixedIdentifier node);
 
   R? visitPrefixExpression(PrefixExpression node);
@@ -553,6 +586,12 @@
 
   R? visitRecordLiteral(RecordLiteral node);
 
+  R? visitRecordPattern(RecordPattern node);
+
+  R? visitRecordPatternField(RecordPatternField node);
+
+  R? visitRecordPatternFieldName(RecordPatternFieldName node);
+
   R? visitRecordTypeAnnotation(RecordTypeAnnotation node);
 
   R? visitRecordTypeAnnotationNamedField(RecordTypeAnnotationNamedField node);
@@ -565,6 +604,8 @@
   R? visitRedirectingConstructorInvocation(
       RedirectingConstructorInvocation node);
 
+  R? visitRelationalPattern(RelationalPattern node);
+
   R? visitRethrowExpression(RethrowExpression node);
 
   R? visitReturnStatement(ReturnStatement node);
@@ -599,6 +640,14 @@
 
   R? visitSwitchDefault(SwitchDefault node);
 
+  R? visitSwitchExpression(SwitchExpression node);
+
+  R? visitSwitchExpressionCase(SwitchExpressionCase node);
+
+  R? visitSwitchExpressionDefault(SwitchExpressionDefault node);
+
+  R? visitSwitchPatternCase(SwitchPatternCase node);
+
   R? visitSwitchStatement(SwitchStatement node);
 
   R? visitSymbolLiteral(SymbolLiteral node);
@@ -625,6 +674,10 @@
 
   R? visitVariableDeclarationStatement(VariableDeclarationStatement node);
 
+  R? visitVariablePattern(VariablePattern node);
+
+  R? visitWhenClause(WhenClause node);
+
   R? visitWhileStatement(WhileStatement node);
 
   R? visitWithClause(WithClause node);
@@ -643,10 +696,6 @@
   /// The token representing the 'augment' keyword.
   Token get augmentKeyword;
 
-  @Deprecated('Use element2 instead')
-  @override
-  AugmentationImportElement? get element;
-
   @override
   AugmentationImportElement? get element2;
 
@@ -693,6 +742,24 @@
   FunctionType? get staticInvokeType;
 }
 
+/// A binary (infix) pattern.
+///
+///    binaryPattern ::=
+///        [DartPattern] ('|' | '&') [DartPattern]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class BinaryPattern implements DartPattern {
+  /// Return the pattern used to compute the left operand.
+  DartPattern get leftOperand;
+
+  /// Return the binary operator being applied.
+  Token get operator;
+
+  /// Return the pattern used to compute the right operand.
+  DartPattern get rightOperand;
+}
+
 /// A sequence of statements.
 ///
 ///    block ::=
@@ -793,6 +860,42 @@
   Expression get target;
 }
 
+/// The `case` clause that can optionally appear in an `if` statement.
+///
+///    caseClause ::=
+///        'case' [DartPattern] [WhenClause]?
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class CaseClause implements AstNode {
+  /// Return the token representing the 'case' keyword.
+  Token get caseKeyword;
+
+  /// Return the pattern controlling whether the statements will be executed.
+  DartPattern get pattern;
+
+  /// Return the clause controlling whether the statements will be executed.
+  WhenClause? get whenClause;
+}
+
+/// A cast pattern.
+///
+///    castPattern ::=
+///        [DartPattern] 'as' [TypeAnnotation]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class CastPattern implements DartPattern {
+  /// The `as` token.
+  Token get asToken;
+
+  /// The pattern whose matched value will be cast.
+  DartPattern get pattern;
+
+  /// The type that the value being matched is cast to.
+  TypeAnnotation get type;
+}
+
 /// A catch clause within a try statement.
 ///
 ///    onPart ::=
@@ -817,11 +920,6 @@
 
   /// Return the parameter whose value will be the exception that was thrown, or
   /// `null` if there is no 'catch' keyword.
-  @Deprecated('Use exceptionParameter2 instead')
-  SimpleIdentifier? get exceptionParameter;
-
-  /// Return the parameter whose value will be the exception that was thrown, or
-  /// `null` if there is no 'catch' keyword.
   CatchClauseParameter? get exceptionParameter2;
 
   /// Return the type of exceptions caught by this catch clause, or `null` if
@@ -840,11 +938,6 @@
 
   /// Return the parameter whose value will be the stack trace associated with
   /// the exception, or `null` if there is no stack trace parameter.
-  @Deprecated('Use stackTraceParameter2 instead')
-  SimpleIdentifier? get stackTraceParameter;
-
-  /// Return the parameter whose value will be the stack trace associated with
-  /// the exception, or `null` if there is no stack trace parameter.
   CatchClauseParameter? get stackTraceParameter2;
 }
 
@@ -874,6 +967,10 @@
   Token get augmentKeyword;
 
   @override
+  ClassAugmentationElement? get declaredElement;
+
+  @Deprecated('Use declaredElement instead')
+  @override
   ClassAugmentationElement? get declaredElement2;
 }
 
@@ -885,18 +982,11 @@
 ///        '{' [ClassMember]* '}'
 ///
 /// Clients may not extend, implement or mix-in this class.
-//
-// TODO(scheglov) Add `ClassOrAugmentationElement get declaredElement`,
-// when [ClassOrMixinDeclaration] is gone.
-abstract class ClassDeclaration
-    implements
-        ClassOrAugmentationDeclaration,
-        // ignore: deprecated_member_use_from_same_package
-        ClassOrMixinDeclaration {
-  @Deprecated('Use declaredElement2 instead')
+abstract class ClassDeclaration implements ClassOrAugmentationDeclaration {
   @override
   ClassElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   ClassElement? get declaredElement2;
 
@@ -905,10 +995,6 @@
   @override
   ImplementsClause? get implementsClause;
 
-  /// Return `true` if this class is declared to be an abstract class.
-  @Deprecated('Use abstractKeyword instead')
-  bool get isAbstract;
-
   /// Returns the left curly bracket.
   @override
   Token get leftBracket;
@@ -929,14 +1015,6 @@
   /// class/mixin does not have any type parameters.
   @override
   TypeParameterList? get typeParameters;
-
-  /// Return the constructor declared in the class with the given [name], or
-  /// `null` if there is no such constructor.
-  ///
-  /// If the [name] is `null` then the default constructor will be searched
-  /// for.
-  @Deprecated('Filter members instead')
-  ConstructorDeclaration? getConstructor(String? name);
 }
 
 /// A node that declares a name within the scope of a class declarations.
@@ -963,6 +1041,10 @@
   Token get classKeyword;
 
   @override
+  ClassOrAugmentationElement? get declaredElement;
+
+  @Deprecated('Use declaredElement instead')
+  @override
   ClassOrAugmentationElement? get declaredElement2;
 
   /// Returns the `extends` clause for this class, or `null` if the class
@@ -993,48 +1075,6 @@
   WithClause? get withClause;
 }
 
-/// The declaration of a class or mixin.
-///
-/// Clients may not extend, implement or mix-in this class.
-@Deprecated('Use ClassDeclaration or MixinDeclaration directly')
-abstract class ClassOrMixinDeclaration implements NamedCompilationUnitMember {
-  @Deprecated('Use ClassDeclaration or MixinDeclaration directly')
-  @override
-  ClassElement? get declaredElement;
-
-  /// Returns the implements clause for the class/mixin, or `null` if the
-  /// class/mixin does not implement any interfaces.
-  @Deprecated('Use ClassDeclaration or MixinDeclaration directly')
-  ImplementsClause? get implementsClause;
-
-  /// Returns the left curly bracket.
-  @Deprecated('Use ClassDeclaration or MixinDeclaration directly')
-  Token get leftBracket;
-
-  /// Returns the members defined by the class/mixin.
-  @Deprecated('Use ClassDeclaration or MixinDeclaration directly')
-  NodeList<ClassMember> get members;
-
-  /// Returns the right curly bracket.
-  @Deprecated('Use ClassDeclaration or MixinDeclaration directly')
-  Token get rightBracket;
-
-  /// Returns the type parameters for the class/mixin, or `null` if the
-  /// class/mixin does not have any type parameters.
-  @Deprecated('Use ClassDeclaration or MixinDeclaration directly')
-  TypeParameterList? get typeParameters;
-
-  /// Returns the field declared in the class/mixin with the given [name], or
-  /// `null` if there is no such field.
-  @Deprecated('Filter members instead')
-  VariableDeclaration? getField(String name);
-
-  /// Returns the method declared in the class/mixin with the given [name], or
-  /// `null` if there is no such method.
-  @Deprecated('Filter members instead')
-  MethodDeclaration? getMethod(String name);
-}
-
 /// A class type alias.
 ///
 ///    classTypeAlias ::=
@@ -1049,10 +1089,10 @@
   /// defining an abstract class.
   Token? get abstractKeyword;
 
-  @Deprecated('Use declaredElement2 instead')
   @override
   ClassElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   ClassElement? get declaredElement2;
 
@@ -1063,17 +1103,9 @@
   /// implements clause.
   ImplementsClause? get implementsClause;
 
-  /// Return `true` if this class is declared to be an abstract class.
-  @Deprecated('Use abstractKeyword instead')
-  bool get isAbstract;
-
   /// Return the name of the superclass of the class being declared.
   NamedType get superclass;
 
-  /// Return the name of the superclass of the class being declared.
-  @Deprecated('Use superclass instead')
-  NamedType get superclass2;
-
   /// Return the type parameters for the class, or `null` if the class does not
   /// have any type parameters.
   TypeParameterList? get typeParameters;
@@ -1167,10 +1199,6 @@
   /// The comment-referable expression being referenced.
   CommentReferableExpression get expression;
 
-  /// Return the identifier being referenced.
-  @Deprecated('Use expression instead')
-  Identifier get identifier;
-
   /// Return the token representing the 'new' keyword, or `null` if there was no
   /// 'new' keyword.
   Token? get newKeyword;
@@ -1371,15 +1399,44 @@
   /// is true.
   StringLiteral get uri;
 
-  /// Return the source to which the [uri] was resolved.
-  @Deprecated('Use resolvedUri and check for DirectiveUriWithSource instead')
-  Source? get uriSource;
-
   /// Return the value to which the value of the declared variable will be
   /// compared, or `null` if the condition does not include an equality test.
   StringLiteral? get value;
 }
 
+/// A constant expression being used as a pattern.
+///
+/// The only expressions that can be validly used as a pattern are
+/// - `bool` literals
+/// - `double` literals
+/// - `int` literals
+/// - `null` literals
+/// - `String` literals
+/// - references to constant variables
+/// - constant constructor invocations
+/// - constant list literals
+/// - constant set or map literals
+/// - constant expressions wrapped in parentheses and preceeded by the `const`
+///   keyword
+///
+/// This node is also used to recover from cases where a different kind of
+/// expression is used as a pattern, so clients need to handle the case where
+/// the expression is not one of the valid alternatives.
+///
+///    constantPattern ::=
+///        'const'? [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class ConstantPattern implements DartPattern {
+  /// Return the `const` keyword, or `null` if the expression is not preceded by
+  /// the keyword `const`.
+  Token? get constKeyword;
+
+  /// Return the constant expression being used as a pattern.
+  Expression get expression;
+}
+
 /// A constructor declaration.
 ///
 ///    constructorDeclaration ::=
@@ -1409,10 +1466,10 @@
   /// not a const constructor.
   Token? get constKeyword;
 
-  @Deprecated('Use declaredElement2 instead')
   @override
   ConstructorElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   ConstructorElement? get declaredElement2;
 
@@ -1428,11 +1485,11 @@
 
   /// Return the name of the constructor, or `null` if the constructor being
   /// declared is unnamed.
-  @Deprecated('Use name2 instead')
-  SimpleIdentifier? get name;
+  Token? get name;
 
   /// Return the name of the constructor, or `null` if the constructor being
   /// declared is unnamed.
+  @Deprecated('Use name instead')
   Token? get name2;
 
   /// Return the parameters associated with the constructor.
@@ -1512,10 +1569,6 @@
 
   /// Return the name of the type defining the constructor.
   NamedType get type;
-
-  /// Return the name of the type defining the constructor.
-  @Deprecated('Use type instead')
-  NamedType get type2;
 }
 
 /// An expression representing a reference to a constructor, e.g. the expression
@@ -1584,6 +1637,33 @@
   AstNode? get target;
 }
 
+/// A pattern.
+///
+///    pattern ::=
+///        [BinaryPattern]
+///      | [ExpressionPattern]
+///      | [CastPattern]
+///      | [ExtractorPattern]
+///      | [ListPattern]
+///      | [LiteralPattern]
+///      | [MapPattern]
+///      | [RecordPattern]
+///      | [RelationalPattern]
+///      | [ParenthesizedPattern]
+///      | [PostfixPattern]
+///      | [VariablePattern]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class DartPattern implements AstNode {
+  /// Return the precedence of this pattern.
+  ///
+  /// The precedence is a positive integer value that defines how the source
+  /// code is parsed into an AST. For example `a | b & c` is parsed as `a | (b
+  /// & c)` because the precedence of `&` is greater than the precedence of `|`.
+  Precedence get precedence;
+}
+
 /// A node that represents the declaration of one or more names.
 ///
 /// Each declared name is visible within a name scope.
@@ -1593,12 +1673,12 @@
   /// Return the element associated with this declaration, or `null` if either
   /// this node corresponds to a list of declarations or if the AST structure
   /// has not been resolved.
-  @Deprecated('Use declaredElement2 instead')
   Element? get declaredElement;
 
   /// Return the element associated with this declaration, or `null` if either
   /// this node corresponds to a list of declarations or if the AST structure
   /// has not been resolved.
+  @Deprecated('Use declaredElement instead')
   Element? get declaredElement2;
 }
 
@@ -1609,17 +1689,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class DeclaredIdentifier implements Declaration {
-  @Deprecated('Use declaredElement2 instead')
   @override
   LocalVariableElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   LocalVariableElement? get declaredElement2;
 
-  /// Return the name of the variable being declared.
-  @Deprecated('Use name instead')
-  SimpleIdentifier get identifier;
-
   /// Return `true` if this variable was declared with the 'const' modifier.
   bool get isConst;
 
@@ -1677,19 +1753,8 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class Directive implements AnnotatedNode {
   /// Return the element associated with this directive, or `null` if the AST
-  /// structure has not been resolved or if this directive could not be
-  /// resolved.
-  @Deprecated('Use element2 instead')
-  Element? get element;
-
-  /// Return the element associated with this directive, or `null` if the AST
   /// structure has not been resolved.
   Element? get element2;
-
-  /// Return the token representing the keyword that introduces this directive
-  /// ('import', 'export', 'library' or 'part').
-  @Deprecated('Use specific xyzToken instead')
-  Token get keyword;
 }
 
 /// A do statement.
@@ -1810,10 +1875,10 @@
   ConstructorElement? get constructorElement;
 
   /// Return the name of the constant.
-  @Deprecated('Use name2 instead')
-  SimpleIdentifier get name;
+  Token get name;
 
   /// Return the name of the constant.
+  @Deprecated('Use name instead')
   Token get name2;
 }
 
@@ -1829,10 +1894,10 @@
   /// Return the enumeration constants being declared.
   NodeList<EnumConstantDeclaration> get constants;
 
-  @Deprecated('Use declaredElement2 instead')
   @override
-  ClassElement? get declaredElement;
+  EnumElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   EnumElement? get declaredElement2;
 
@@ -1871,10 +1936,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ExportDirective implements NamespaceDirective {
-  @Deprecated('Use element2 instead')
-  @override
-  ExportElement? get element;
-
   /// Return the element associated with this directive, or `null` if the AST
   /// structure has not been resolved.
   @override
@@ -1991,10 +2052,6 @@
 
   /// Return the name of the class that is being extended.
   NamedType get superclass;
-
-  /// Return the name of the class that is being extended.
-  @Deprecated('Use superclass instead')
-  NamedType get superclass2;
 }
 
 /// The declaration of an extension of a type.
@@ -2006,10 +2063,10 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ExtensionDeclaration implements CompilationUnitMember {
-  @Deprecated('Use declaredElement2 instead')
   @override
   ExtensionElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   ExtensionElement? get declaredElement2;
 
@@ -2031,11 +2088,11 @@
 
   /// Return the name of the extension, or `null` if the extension does not have
   /// a name.
-  @Deprecated('Use name2 instead')
-  SimpleIdentifier? get name;
+  Token? get name;
 
   /// Return the name of the extension, or `null` if the extension does not have
   /// a name.
+  @Deprecated('Use name instead')
   Token? get name2;
 
   /// Return the token representing the 'on' keyword.
@@ -2099,6 +2156,31 @@
   List<DartType>? get typeArgumentTypes;
 }
 
+/// An extractor pattern.
+///
+///    extractorPattern ::=
+///        [Identifier] [TypeArgumentList]? '(' [RecordPatternField] ')'
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class ExtractorPattern implements DartPattern {
+  /// Return the patterns matching the properties of the object.
+  NodeList<RecordPatternField> get fields;
+
+  /// Return the left parenthesis.
+  Token get leftParenthesis;
+
+  /// Return the right parenthesis.
+  Token get rightParenthesis;
+
+  /// Return the type arguments associated with this pattern, or `null` if no
+  /// type arguments were declared.
+  TypeArgumentList? get typeArguments;
+
+  /// The name of the type of object from which values will be extracted.
+  Identifier get typeName;
+}
+
 /// The declaration of one or more fields of the same type.
 ///
 ///    fieldDeclaration ::=
@@ -2155,10 +2237,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FieldFormalParameter implements NormalFormalParameter {
-  @Deprecated('Use name instead')
-  @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;
@@ -2228,6 +2306,21 @@
   SimpleIdentifier get identifier;
 }
 
+/// A for-loop part with a pattern.
+///
+///    forEachPartsWithPattern ::=
+///        ( 'final' | 'var' ) [DartPattern] 'in' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class ForEachPartsWithPattern implements ForEachParts {
+  /// Return the `var` or `final` keyword introducing the pattern.
+  Token get keyword;
+
+  /// The pattern that will match the expression.
+  DartPattern get pattern;
+}
+
 /// The basic structure of a for element.
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -2281,12 +2374,6 @@
   /// parameter has not been resolved.
   ParameterElement? get declaredElement;
 
-  /// Return the name of the parameter being declared, or `null` if the
-  /// parameter doesn't have a name, such as when it's part of a generic
-  /// function type.
-  @Deprecated('Use name instead')
-  SimpleIdentifier? get identifier;
-
   /// Return `true` if this parameter was declared with the 'const' modifier.
   bool get isConst;
 
@@ -2453,6 +2540,18 @@
   Expression? get initialization;
 }
 
+/// The parts of a for loop that control the iteration when there is a pattern
+/// declaration as part of the for loop.
+///
+///   forLoopParts ::=
+///       [PatternVariableDeclaration] ';' [Expression]? ';' expressionList?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForPartsWithPattern implements ForParts {
+  /// Return the declaration of the loop variables.
+  PatternVariableDeclaration get variables;
+}
+
 /// A for or for-each statement.
 ///
 ///    forStatement ::=
@@ -2541,7 +2640,10 @@
   bool isPotentiallyMutatedInScope(VariableElement variable);
 }
 
-/// A top-level function declaration.
+/// A function declaration.
+///
+/// Wrapped in a [FunctionDeclarationStatement] to represent a local function
+/// declaration, otherwise a top-level function declaration.
 ///
 ///    functionDeclaration ::=
 ///        'external' functionSignature
@@ -2552,10 +2654,10 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FunctionDeclaration implements NamedCompilationUnitMember {
-  @Deprecated('Use declaredElement2 instead')
   @override
   ExecutableElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   ExecutableElement? get declaredElement2;
 
@@ -2675,10 +2777,10 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FunctionTypeAlias implements TypeAlias {
-  @Deprecated('Use declaredElement2 instead')
   @override
   TypeAliasElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   TypeAliasElement? get declaredElement2;
 
@@ -2702,10 +2804,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FunctionTypedFormalParameter implements NormalFormalParameter {
-  @Deprecated('Use name instead')
-  @override
-  SimpleIdentifier get identifier;
-
   @override
   Token get name;
 
@@ -2852,8 +2950,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class IfElement implements CollectionElement {
+  /// Return the `case` clause used to match a pattern against the [condition].
+  @experimental
+  CaseClause? get caseClause;
+
   /// Return the condition used to determine which of the statements is executed
   /// next.
+  // TODO(brianwilkerson) Deprecate this when the patterns feature is released.
   Expression get condition;
 
   /// Return the statement that is executed if the condition evaluates to
@@ -2864,6 +2967,11 @@
   /// else statement.
   Token? get elseKeyword;
 
+  /// Return the expression used to either determine which of the statements is
+  /// executed next or to compute the value to be matched against the pattern in
+  /// the `case` clause.
+  Expression get expression;
+
   /// Return the token representing the 'if' keyword.
   Token get ifKeyword;
 
@@ -2881,12 +2989,18 @@
 /// An if statement.
 ///
 ///    ifStatement ::=
-///        'if' '(' [Expression] ')' [Statement] ('else' [Statement])?
+///        'if' '(' [Expression] [CaseClause]? ')'[Statement]
+///        ('else' [Statement])?
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class IfStatement implements Statement {
+  /// Return the `case` clause used to match a pattern against the [condition].
+  @experimental
+  CaseClause? get caseClause;
+
   /// Return the condition used to determine which of the statements is executed
   /// next.
+  // TODO(brianwilkerson) Deprecate this when the patterns feature is released.
   Expression get condition;
 
   /// Return the token representing the 'else' keyword, or `null` if there is no
@@ -2897,6 +3011,11 @@
   /// `false`, or `null` if there is no else statement.
   Statement? get elseStatement;
 
+  /// Return the expression used to either determine which of the statements is
+  /// executed next or to compute the value matched against the pattern in the
+  /// `case` clause.
+  Expression get expression;
+
   /// Return the token representing the 'if' keyword.
   Token get ifKeyword;
 
@@ -2923,10 +3042,6 @@
 
   /// Return the list of the interfaces that are being implemented.
   NodeList<NamedType> get interfaces;
-
-  /// Return the list of the interfaces that are being implemented.
-  @Deprecated('Use interfaces instead')
-  NodeList<NamedType> get interfaces2;
 }
 
 /// An expression representing an implicit 'call' method reference.
@@ -2964,113 +3079,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ImportDirective implements NamespaceDirective {
-  @Deprecated('This kind of syntactic equality is rarely useful')
-  static Comparator<ImportDirective> COMPARATOR =
-      (ImportDirective import1, ImportDirective import2) {
-    //
-    // uri
-    //
-    StringLiteral uri1 = import1.uri;
-    StringLiteral uri2 = import2.uri;
-    String? uriStr1 = uri1.stringValue;
-    String? uriStr2 = uri2.stringValue;
-    if (uriStr1 != null || uriStr2 != null) {
-      if (uriStr1 == null) {
-        return -1;
-      } else if (uriStr2 == null) {
-        return 1;
-      } else {
-        int compare = uriStr1.compareTo(uriStr2);
-        if (compare != 0) {
-          return compare;
-        }
-      }
-    }
-    //
-    // as
-    //
-    SimpleIdentifier? prefix1 = import1.prefix;
-    SimpleIdentifier? prefix2 = import2.prefix;
-    String? prefixStr1 = prefix1?.name;
-    String? prefixStr2 = prefix2?.name;
-    if (prefixStr1 != null || prefixStr2 != null) {
-      if (prefixStr1 == null) {
-        return -1;
-      } else if (prefixStr2 == null) {
-        return 1;
-      } else {
-        int compare = prefixStr1.compareTo(prefixStr2);
-        if (compare != 0) {
-          return compare;
-        }
-      }
-    }
-    //
-    // hides and shows
-    //
-    NodeList<Combinator> combinators1 = import1.combinators;
-    List<String> allHides1 = <String>[];
-    List<String> allShows1 = <String>[];
-    int length1 = combinators1.length;
-    for (int i = 0; i < length1; i++) {
-      Combinator combinator = combinators1[i];
-      if (combinator is HideCombinator) {
-        NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
-        int hideLength = hides.length;
-        for (int j = 0; j < hideLength; j++) {
-          SimpleIdentifier simpleIdentifier = hides[j];
-          allHides1.add(simpleIdentifier.name);
-        }
-      } else {
-        NodeList<SimpleIdentifier> shows =
-            (combinator as ShowCombinator).shownNames;
-        int showLength = shows.length;
-        for (int j = 0; j < showLength; j++) {
-          SimpleIdentifier simpleIdentifier = shows[j];
-          allShows1.add(simpleIdentifier.name);
-        }
-      }
-    }
-    NodeList<Combinator> combinators2 = import2.combinators;
-    List<String> allHides2 = <String>[];
-    List<String> allShows2 = <String>[];
-    int length2 = combinators2.length;
-    for (int i = 0; i < length2; i++) {
-      Combinator combinator = combinators2[i];
-      if (combinator is HideCombinator) {
-        NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
-        int hideLength = hides.length;
-        for (int j = 0; j < hideLength; j++) {
-          SimpleIdentifier simpleIdentifier = hides[j];
-          allHides2.add(simpleIdentifier.name);
-        }
-      } else {
-        NodeList<SimpleIdentifier> shows =
-            (combinator as ShowCombinator).shownNames;
-        int showLength = shows.length;
-        for (int j = 0; j < showLength; j++) {
-          SimpleIdentifier simpleIdentifier = shows[j];
-          allShows2.add(simpleIdentifier.name);
-        }
-      }
-    }
-    // test lengths of combinator lists first
-    if (allHides1.length != allHides2.length) {
-      return allHides1.length - allHides2.length;
-    }
-    if (allShows1.length != allShows2.length) {
-      return allShows1.length - allShows2.length;
-    }
-    // next ensure that the lists are equivalent
-    if (!allHides1.toSet().containsAll(allHides2)) {
-      return -1;
-    }
-    if (!allShows1.toSet().containsAll(allShows2)) {
-      return -1;
-    }
-    return 0;
-  };
-
   /// Return the token representing the 'as' keyword, or `null` if the imported
   /// names are not prefixed.
   Token? get asKeyword;
@@ -3079,10 +3087,6 @@
   /// imported URI is not deferred.
   Token? get deferredKeyword;
 
-  @Deprecated('Use element2 instead')
-  @override
-  ImportElement? get element;
-
   /// Return the element associated with this directive, or `null` if the AST
   /// structure has not been resolved.
   @override
@@ -3376,7 +3380,7 @@
 /// A library directive.
 ///
 ///    libraryDirective ::=
-///        [Annotation] 'library' [Identifier] ';'
+///        [Annotation] 'library' [LibraryIdentifier]? ';'
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class LibraryDirective implements Directive {
@@ -3384,8 +3388,12 @@
   Token get libraryKeyword;
 
   /// Return the name of the library being defined.
+  @Deprecated('Use name2')
   LibraryIdentifier get name;
 
+  /// Return the name of the library being defined.
+  LibraryIdentifier? get name2;
+
   /// Return the semicolon terminating the directive.
   Token get semicolon;
 }
@@ -3421,6 +3429,28 @@
   Token get rightBracket;
 }
 
+/// A list pattern.
+///
+///    listPattern ::=
+///        [TypeArgumentList]? '[' [DartPattern] (',' [DartPattern])* ','? ']'
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class ListPattern implements DartPattern {
+  /// Return the elements in this pattern.
+  NodeList<DartPattern> get elements;
+
+  /// Return the left square bracket.
+  Token get leftBracket;
+
+  /// Return the right square bracket.
+  Token get rightBracket;
+
+  /// Return the type arguments associated with this pattern, or `null` if no
+  /// type arguments were declared.
+  TypeArgumentList? get typeArguments;
+}
+
 /// A node that represents a literal expression.
 ///
 ///    literal ::=
@@ -3454,6 +3484,47 @@
   Expression get value;
 }
 
+/// A map pattern.
+///
+///    mapPattern ::=
+///        [TypeArgumentList]? '{' [MapPatternEntry] (',' [MapPatternEntry])*
+///        ','? '}'
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class MapPattern implements DartPattern {
+  /// Return the entries in this pattern.
+  NodeList<MapPatternEntry> get entries;
+
+  /// Return the left curly bracket.
+  Token get leftBracket;
+
+  /// Return the right curly bracket.
+  Token get rightBracket;
+
+  /// Return the type arguments associated with this pattern, or `null` if no
+  /// type arguments were declared.
+  TypeArgumentList? get typeArguments;
+}
+
+/// An entry in a map pattern.
+///
+///    mapPatternEntry ::=
+///        [Expression] ':' [DartPattern]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class MapPatternEntry implements AstNode {
+  /// Return the expression computing the key of the entry to be matched.
+  Expression get key;
+
+  /// Return the colon that separates the key from the value.
+  Token get separator;
+
+  /// Return the pattern used to match the value.
+  DartPattern get value;
+}
+
 /// A method declaration.
 ///
 ///    methodDeclaration ::=
@@ -3476,10 +3547,10 @@
   /// Return the body of the method.
   FunctionBody get body;
 
-  @Deprecated('Use declaredElement2 instead')
   @override
   ExecutableElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   ExecutableElement? get declaredElement2;
 
@@ -3507,10 +3578,10 @@
   Token? get modifierKeyword;
 
   /// Return the name of the method.
-  @Deprecated('Use name2 instead')
-  SimpleIdentifier get name;
+  Token get name;
 
   /// Return the name of the method.
+  @Deprecated('Use name instead')
   Token get name2;
 
   /// Return the token representing the 'operator' keyword, or `null` if this
@@ -3608,6 +3679,10 @@
   Token get augmentKeyword;
 
   @override
+  MixinAugmentationElement? get declaredElement;
+
+  @Deprecated('Use declaredElement instead')
+  @override
   MixinAugmentationElement? get declaredElement2;
 }
 
@@ -3618,15 +3693,11 @@
 ///        [OnClause]? [ImplementsClause]? '{' [ClassMember]* '}'
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class MixinDeclaration
-    implements
-        MixinOrAugmentationDeclaration,
-        // ignore: deprecated_member_use_from_same_package
-        ClassOrMixinDeclaration {
-  @Deprecated('Use declaredElement2 instead')
+abstract class MixinDeclaration implements MixinOrAugmentationDeclaration {
   @override
-  ClassElement? get declaredElement;
+  MixinElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   MixinElement? get declaredElement2;
 
@@ -3661,6 +3732,10 @@
 abstract class MixinOrAugmentationDeclaration
     implements NamedCompilationUnitMember {
   @override
+  MixinOrAugmentationElement? get declaredElement;
+
+  @Deprecated('Use declaredElement instead')
+  @override
   MixinOrAugmentationElement? get declaredElement2;
 
   /// Returns the `implements` clause for the mixin, or `null` if the mixin
@@ -3693,10 +3768,10 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class NamedCompilationUnitMember implements CompilationUnitMember {
   /// Return the name of the member being declared.
-  @Deprecated('Use name2 instead')
-  SimpleIdentifier get name;
+  Token get name;
 
   /// Return the name of the member being declared.
+  @Deprecated('Use name instead')
   Token get name2;
 }
 
@@ -3756,30 +3831,8 @@
   /// loaded at run-time.
   NodeList<Configuration> get configurations;
 
-  /// Return the source that was selected based on the declared variables.
-  ///
-  /// This will be the source from the first configuration whose condition is
-  /// true, or the `[uriSource]` if either there are no configurations or if
-  /// there are no configurations whose condition is true.
-  @Deprecated('Use element2.uri and check for DirectiveUriWithSource instead')
-  Source? get selectedSource;
-
-  /// Return the content of the URI that was selected based on the declared
-  /// variables.
-  ///
-  /// This will be the URI from the first configuration whose condition is
-  /// true, or the `[uriContent]` if either there are no configurations or if
-  /// there are no configurations whose condition is true.
-  @Deprecated(
-      'Use element2.uri and check for DirectiveUriWithRelativeUriString instead')
-  String? get selectedUriContent;
-
   /// Return the semicolon terminating the directive.
   Token get semicolon;
-
-  @Deprecated('Use element2.uri and check for DirectiveUriWithLibrary instead')
-  @override
-  LibraryElement? get uriElement;
 }
 
 /// The "native" clause in an class declaration.
@@ -3829,6 +3882,10 @@
   /// if the list is empty.
   Token? get endToken;
 
+  @Deprecated('NodeList cannot be resized')
+  @override
+  set length(int newLength);
+
   /// Return the node that is the parent of each of the elements in the list.
   AstNode get owner;
 
@@ -3839,6 +3896,26 @@
 
   /// Use the given [visitor] to visit each of the nodes in this list.
   void accept(AstVisitor visitor);
+
+  @Deprecated('NodeList cannot be resized')
+  @override
+  void add(E element);
+
+  @Deprecated('NodeList cannot be resized')
+  @override
+  void addAll(Iterable<E> iterable);
+
+  @Deprecated('NodeList cannot be resized')
+  @override
+  void clear();
+
+  @Deprecated('NodeList cannot be resized')
+  @override
+  void insert(int index, E element);
+
+  @Deprecated('NodeList cannot be resized')
+  @override
+  E removeAt(int index);
 }
 
 /// A formal parameter that is required (is not optional).
@@ -3901,10 +3978,6 @@
 
   /// Return the list of the classes are superclass constraints for the mixin.
   NodeList<NamedType> get superclassConstraints;
-
-  /// Return the list of the classes are superclass constraints for the mixin.
-  @Deprecated('Use superclassConstraints instead')
-  NodeList<NamedType> get superclassConstraints2;
 }
 
 /// A parenthesized expression.
@@ -3924,6 +3997,24 @@
   Token get rightParenthesis;
 }
 
+/// A parenthesized pattern.
+///
+///    parenthesizedPattern ::=
+///        '(' [DartPattern] ')'
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class ParenthesizedPattern implements DartPattern {
+  /// Return the left parenthesis.
+  Token get leftParenthesis;
+
+  /// The pattern within the parentheses.
+  DartPattern get pattern;
+
+  /// Return the right parenthesis.
+  Token get rightParenthesis;
+}
+
 /// A part directive.
 ///
 ///    partDirective ::=
@@ -3967,6 +4058,74 @@
   StringLiteral? get uri;
 }
 
+/// A pattern assignment.
+///
+///    patternAssignment ::=
+///        [DartPattern] '=' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class PatternAssignment implements Expression {
+  /// Return the equal sign separating the pattern from the expression.
+  Token get equals;
+
+  /// The expression that will be matched by the pattern.
+  Expression get expression;
+
+  /// The pattern that will match the expression.
+  DartPattern get pattern;
+}
+
+/// A pattern assignment used as a statement.
+///
+///    patternAssignmentStatement ::=
+///        [PatternAssignment] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class PatternAssignmentStatement implements Statement {
+  /// Return the pattern assignment that comprises the statement.
+  PatternAssignment get assignment;
+
+  /// Return the semicolon terminating the statement.
+  Token get semicolon;
+}
+
+/// A pattern variable declaration.
+///
+///    patternDeclaration ::=
+///        ( 'final' | 'var' ) [DartPattern] '=' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class PatternVariableDeclaration implements AstNode {
+  /// Return the equal sign separating the pattern from the expression.
+  Token get equals;
+
+  /// The expression that will be matched by the pattern.
+  Expression get expression;
+
+  /// Return the `var` or `final` keyword introducing the declaration.
+  Token get keyword;
+
+  /// The pattern that will match the expression.
+  DartPattern get pattern;
+}
+
+/// A pattern variable declaration statement.
+///
+///    patternDeclaration ::=
+///        [PatternVariableDeclaration] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class PatternVariableDeclarationStatement implements Statement {
+  /// The pattern declaration.
+  PatternVariableDeclaration get declaration;
+
+  /// Return the semicolon terminating the statement.
+  Token get semicolon;
+}
+
 /// A postfix unary expression.
 ///
 ///    postfixExpression ::=
@@ -3986,6 +4145,21 @@
   Token get operator;
 }
 
+/// A postfix (unary) pattern.
+///
+///    postfixPattern ::=
+///        [DartPattern] ('?' | '!')
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class PostfixPattern implements DartPattern {
+  /// Return the pattern used to compute the operand.
+  DartPattern get operand;
+
+  /// Return the unary operator being applied.
+  Token get operator;
+}
+
 /// An identifier that is prefixed or an access to an object property where the
 /// target of the property access is a simple identifier.
 ///
@@ -4102,6 +4276,54 @@
   Token get rightParenthesis;
 }
 
+/// A record pattern.
+///
+///    recordPattern ::=
+///        '(' [RecordPatternField] (',' [RecordPatternField])* ')'
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class RecordPattern implements DartPattern {
+  /// Return the fields of the record pattern.
+  NodeList<RecordPatternField> get fields;
+
+  /// Return the left parenthesis.
+  Token get leftParenthesis;
+
+  /// Return the right parenthesis.
+  Token get rightParenthesis;
+}
+
+/// A field in a record pattern.
+///
+///    recordPatternField ::=
+///        [RecordPatternFieldName]? [DartPattern]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class RecordPatternField implements AstNode {
+  /// The name of the field, or `null` if the field is a positional field.
+  RecordPatternFieldName? get fieldName;
+
+  /// The pattern used to match the corresponding record field.
+  DartPattern get pattern;
+}
+
+/// A field name in a record pattern field.
+///
+///    recordPatternField ::=
+///        [Token]? ':'
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class RecordPatternFieldName implements AstNode {
+  /// The colon following the name.
+  Token get colon;
+
+  /// The name of the field.
+  Token? get name;
+}
+
 /// A record type.
 ///
 /// recordType ::=
@@ -4206,6 +4428,21 @@
   Token get thisKeyword;
 }
 
+/// A relational pattern.
+///
+///    relationalPattern ::=
+///        (equalityOperator | relationalOperator) [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class RelationalPattern implements DartPattern {
+  /// Return the expression used to compute the operand.
+  Expression get operand;
+
+  /// Return the relational operator being applied.
+  Token get operator;
+}
+
 /// A rethrow expression.
 ///
 ///    rethrowExpression ::=
@@ -4606,10 +4843,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class SuperFormalParameter implements NormalFormalParameter {
-  @Deprecated('Use name instead')
-  @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;
@@ -4663,11 +4896,102 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class SwitchDefault implements SwitchMember {}
 
+/// A switch expression.
+///
+///    switchExpression ::=
+///        'switch' '(' [Expression] ')' '{' [SwitchExpressionCase]*
+///        [SwitchExpressionDefault]? '}'
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class SwitchExpression implements Expression {
+  /// Return the expression used to determine which of the switch members will
+  /// be selected.
+  Expression get expression;
+
+  /// Return the left curly bracket.
+  Token get leftBracket;
+
+  /// Return the left parenthesis.
+  Token get leftParenthesis;
+
+  /// Return the switch expression members that can be selected by the
+  /// expression.
+  NodeList<SwitchExpressionMember> get members;
+
+  /// Return the right curly bracket.
+  Token get rightBracket;
+
+  /// Return the right parenthesis.
+  Token get rightParenthesis;
+
+  /// Return the token representing the 'switch' keyword.
+  Token get switchKeyword;
+}
+
+/// A case in a switch expression.
+///
+///    switchExpressionCase ::=
+///        'case' [DartPattern] [WhenClause]? '=>' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class SwitchExpressionCase implements SwitchExpressionMember {
+  /// Return the refutable pattern that must match for the [expression] to be executed.
+  DartPattern get pattern;
+
+  /// Return the clause containing the condition that is evaluated when the
+  /// [pattern] matches, that must evaluate to `true` in order for the
+  /// [expression] to be executed.
+  WhenClause? get whenClause;
+}
+
+/// The default case in a switch expression.
+///
+///    switchDefault ::=
+///        'default' '=>' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class SwitchExpressionDefault implements SwitchExpressionMember {}
+
+/// A member within a switch expression.
+///
+///    switchExpressionMember ::=
+///        [SwitchExpressionCase]
+///      | [SwitchExpressionDefault]
+///
+/// Clients may not extend, implement or mix-in this class.
+// TODO(brianwilkerson) Consider renaming `SwitchMember`, `SwitchCase`, and
+//  `SwitchDefault` to start with `SwitchStatement` for consistency.
+@experimental
+abstract class SwitchExpressionMember implements AstNode {
+  /// Return the arrow separating the keyword or the expression from the
+  /// expression.
+  Token get arrow;
+
+  /// Return the expression whose value will be returned from the switch
+  /// expression if this member is selected.
+  Expression get expression;
+
+  /// Return the token representing the 'case' or 'default' keyword.
+  Token get keyword;
+}
+
 /// An element within a switch statement.
 ///
 ///    switchMember ::=
-///        switchCase
-///      | switchDefault
+///        [SwitchCase]
+///      | [SwitchDefault]
+///      | [SwitchPatternCase]
+///
+/// The class [SwitchPatternCase] exists only to support the 'patterns' feature.
+///
+/// Note that when the patterns feature is enabled by default, the class
+/// [SwitchPatternCase] might replace [SwitchCase] entirely. If we do that, then
+/// legacy code (code opted into a version prior to the release of patterns)
+/// will likely wrap the expression in a [ConstantPattern] with synthetic
+/// tokens.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class SwitchMember implements AstNode {
@@ -4686,6 +5010,21 @@
   NodeList<Statement> get statements;
 }
 
+/// A pattern-based case in a switch statement.
+///
+///    switchPatternCase ::=
+///        [Label]* 'case' [DartPattern] [WhenClause]? ':' [Statement]*
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class SwitchPatternCase implements SwitchMember {
+  /// Return the pattern controlling whether the statements will be executed.
+  DartPattern get pattern;
+
+  /// Return the clause controlling whether the statements will be executed.
+  WhenClause? get whenClause;
+}
+
 /// A switch statement.
 ///
 ///    switchStatement ::=
@@ -4911,10 +5250,10 @@
   /// explicit upper bound.
   TypeAnnotation? get bound;
 
-  @Deprecated('Use declaredElement2 instead')
   @override
   TypeParameterElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   TypeParameterElement? get declaredElement2;
 
@@ -4923,10 +5262,10 @@
   Token? get extendsKeyword;
 
   /// Return the name of the type parameter.
-  @Deprecated('Use name2 instead')
-  SimpleIdentifier get name;
+  Token get name;
 
   /// Return the name of the type parameter.
+  @Deprecated('Use name instead')
   Token get name2;
 }
 
@@ -4959,25 +5298,6 @@
 abstract class UriBasedDirective implements Directive {
   /// Return the URI referenced by this directive.
   StringLiteral get uri;
-
-  /// Return the content of the [uri], or `null` if the AST structure has not
-  /// been resolved, or if the [uri] has a string interpolation.
-  @Deprecated(
-      'Use element2.uri and check for DirectiveUriWithRelativeUriString instead')
-  String? get uriContent;
-
-  /// Return the element associated with the [uri] of this directive, or `null`
-  /// if the AST structure has not been resolved or if the URI could not be
-  /// resolved.
-  ///
-  /// Examples of the latter case include a directive that contains an invalid
-  /// URL or a URL that does not exist.
-  @Deprecated('Use element2.uri and check for DirectiveUriWithLibrary instead')
-  Element? get uriElement;
-
-  /// Return the source to which the [uri] was resolved.
-  @Deprecated('Use element2.uri and check for DirectiveUriWithSource instead')
-  Source? get uriSource;
 }
 
 /// An identifier that has an initial value associated with it.
@@ -4994,10 +5314,10 @@
 // Consider changing the class hierarchy so that [VariableDeclaration] does not
 // extend [Declaration].
 abstract class VariableDeclaration implements Declaration {
-  @Deprecated('Use declaredElement2 instead')
   @override
   VariableElement? get declaredElement;
 
+  @Deprecated('Use declaredElement instead')
   @override
   VariableElement? get declaredElement2;
 
@@ -5022,10 +5342,10 @@
   bool get isLate;
 
   /// Return the name of the variable being declared.
-  @Deprecated('Use name2 instead')
-  SimpleIdentifier get name;
+  Token get name;
 
   /// Return the name of the variable being declared.
+  @Deprecated('Use name instead')
   Token get name2;
 }
 
@@ -5089,6 +5409,48 @@
   VariableDeclarationList get variables;
 }
 
+/// A variable pattern.
+///
+///    variablePattern ::=
+///        ( 'var' | 'final' | [TypeAnnotation])? [Identifier]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class VariablePattern implements DartPattern {
+  /// Return the element associated with this declaration, or `null` if either
+  /// the variable name is `_` (in which case no variable is defined) or the AST
+  /// structure has not been resolved.
+  VariablePatternElement? get declaredElement;
+
+  /// The 'var' or 'final' keyword used when there is no [type], or `null` if a
+  /// type is given.
+  Token? get keyword;
+
+  /// The name of the variable being bound.
+  Token get name;
+
+  /// The type that the variable is required to match, or `null` if any type is
+  /// matched.
+  TypeAnnotation? get type;
+}
+
+/// A guard in a pattern-based `case` in a `switch` statement, `switch`
+/// expression, `if` statement, or `if` element.
+///
+///    switchCase ::=
+///        'when' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class WhenClause implements AstNode {
+  /// Return the condition that is evaluated when the [pattern] matches, that
+  /// must evaluate to `true` in order for the [expression] to be executed.
+  Expression get expression;
+
+  /// Return the `when` keyword.
+  Token get whenKeyword;
+}
+
 /// A while statement.
 ///
 ///    whileStatement ::=
@@ -5123,10 +5485,6 @@
   /// Return the names of the mixins that were specified.
   NodeList<NamedType> get mixinTypes;
 
-  /// Return the names of the mixins that were specified.
-  @Deprecated('Use mixinTypes instead')
-  NodeList<NamedType> get mixinTypes2;
-
   /// Return the token representing the 'with' keyword.
   Token get withKeyword;
 }
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index 3862084..2397ad5 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -164,6 +164,9 @@
   R? visitBinaryExpression(BinaryExpression node) => visitExpression(node);
 
   @override
+  R? visitBinaryPattern(BinaryPattern node) => visitDartPattern(node);
+
+  @override
   R? visitBlock(Block node) => visitStatement(node);
 
   @override
@@ -179,6 +182,12 @@
   R? visitCascadeExpression(CascadeExpression node) => visitExpression(node);
 
   @override
+  R? visitCaseClause(CaseClause node) => visitNode(node);
+
+  @override
+  R? visitCastPattern(CastPattern node) => visitDartPattern(node);
+
+  @override
   R? visitCatchClause(CatchClause node) => visitNode(node);
 
   @override
@@ -217,6 +226,9 @@
   R? visitConfiguration(Configuration node) => visitNode(node);
 
   @override
+  R? visitConstantPattern(ConstantPattern node) => visitDartPattern(node);
+
+  @override
   R? visitConstructorDeclaration(ConstructorDeclaration node) =>
       visitClassMember(node);
 
@@ -240,6 +252,8 @@
   @override
   R? visitContinueStatement(ContinueStatement node) => visitStatement(node);
 
+  R? visitDartPattern(DartPattern node) => visitNode(node);
+
   R? visitDeclaration(Declaration node) => visitAnnotatedNode(node);
 
   @override
@@ -301,6 +315,9 @@
   R? visitExtensionOverride(ExtensionOverride node) => visitExpression(node);
 
   @override
+  R? visitExtractorPattern(ExtractorPattern node) => visitDartPattern(node);
+
+  @override
   R? visitFieldDeclaration(FieldDeclaration node) => visitClassMember(node);
 
   @override
@@ -318,6 +335,10 @@
       visitForEachParts(node);
 
   @override
+  R? visitForEachPartsWithPattern(ForEachPartsWithPattern node) =>
+      visitForEachParts(node);
+
+  @override
   R? visitForElement(ForElement node) => visitCollectionElement(node);
 
   R? visitFormalParameter(FormalParameter node) => visitNode(node);
@@ -336,6 +357,9 @@
       visitForParts(node);
 
   @override
+  R? visitForPartsWithPattern(ForPartsWithPattern node) => visitForParts(node);
+
+  @override
   R? visitForStatement(ForStatement node) => visitStatement(node);
 
   R? visitFunctionBody(FunctionBody node) => visitNode(node);
@@ -446,12 +470,21 @@
   @override
   R? visitListLiteral(ListLiteral node) => visitTypedLiteral(node);
 
+  @override
+  R? visitListPattern(ListPattern node) => visitDartPattern(node);
+
   R? visitLiteral(Literal node) => visitExpression(node);
 
   @override
   R? visitMapLiteralEntry(MapLiteralEntry node) => visitCollectionElement(node);
 
   @override
+  R? visitMapPattern(MapPattern node) => visitDartPattern(node);
+
+  @override
+  R? visitMapPatternEntry(MapPatternEntry node) => visitNode(node);
+
+  @override
   R? visitMethodDeclaration(MethodDeclaration node) => visitClassMember(node);
 
   @override
@@ -500,15 +533,38 @@
       visitExpression(node);
 
   @override
+  R? visitParenthesizedPattern(ParenthesizedPattern node) =>
+      visitDartPattern(node);
+
+  @override
   R? visitPartDirective(PartDirective node) => visitUriBasedDirective(node);
 
   @override
   R? visitPartOfDirective(PartOfDirective node) => visitDirective(node);
 
   @override
+  R? visitPatternAssignment(PatternAssignment node) => visitExpression(node);
+
+  @override
+  R? visitPatternAssignmentStatement(PatternAssignmentStatement node) =>
+      visitStatement(node);
+
+  @override
+  R? visitPatternVariableDeclaration(PatternVariableDeclaration node) =>
+      visitNode(node);
+
+  @override
+  R? visitPatternVariableDeclarationStatement(
+          PatternVariableDeclarationStatement node) =>
+      visitStatement(node);
+
+  @override
   R? visitPostfixExpression(PostfixExpression node) => visitExpression(node);
 
   @override
+  R? visitPostfixPattern(PostfixPattern node) => visitDartPattern(node);
+
+  @override
   R? visitPrefixedIdentifier(PrefixedIdentifier node) => visitIdentifier(node);
 
   @override
@@ -521,6 +577,16 @@
   R? visitRecordLiteral(RecordLiteral node) => visitLiteral(node);
 
   @override
+  R? visitRecordPattern(RecordPattern node) => visitDartPattern(node);
+
+  @override
+  R? visitRecordPatternField(RecordPatternField node) => visitNode(node);
+
+  @override
+  R? visitRecordPatternFieldName(RecordPatternFieldName node) =>
+      visitNode(node);
+
+  @override
   R? visitRecordTypeAnnotation(RecordTypeAnnotation node) =>
       visitTypeAnnotation(node);
 
@@ -547,6 +613,9 @@
       visitConstructorInitializer(node);
 
   @override
+  R? visitRelationalPattern(RelationalPattern node) => visitDartPattern(node);
+
+  @override
   R? visitRethrowExpression(RethrowExpression node) => visitExpression(node);
 
   @override
@@ -609,9 +678,26 @@
   @override
   R? visitSwitchDefault(SwitchDefault node) => visitSwitchMember(node);
 
+  @override
+  R? visitSwitchExpression(SwitchExpression node) => visitExpression(node);
+
+  @override
+  R? visitSwitchExpressionCase(SwitchExpressionCase node) =>
+      visitSwitchExpressionMember(node);
+
+  @override
+  R? visitSwitchExpressionDefault(SwitchExpressionDefault node) =>
+      visitSwitchExpressionMember(node);
+
+  R? visitSwitchExpressionMember(SwitchExpressionMember node) =>
+      visitNode(node);
+
   R? visitSwitchMember(SwitchMember node) => visitNode(node);
 
   @override
+  R? visitSwitchPatternCase(SwitchPatternCase node) => visitSwitchMember(node);
+
+  @override
   R? visitSwitchStatement(SwitchStatement node) => visitStatement(node);
 
   @override
@@ -663,6 +749,12 @@
       visitStatement(node);
 
   @override
+  R? visitVariablePattern(VariablePattern node) => visitDartPattern(node);
+
+  @override
+  R? visitWhenClause(WhenClause node) => visitNode(node);
+
+  @override
   R? visitWhileStatement(WhileStatement node) => visitStatement(node);
 
   @override
@@ -747,6 +839,12 @@
   }
 
   @override
+  R? visitBinaryPattern(BinaryPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitBlock(Block node) {
     node.visitChildren(this);
     return null;
@@ -777,6 +875,18 @@
   }
 
   @override
+  R? visitCaseClause(CaseClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitCastPattern(CastPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitCatchClause(CatchClause node) {
     node.visitChildren(this);
     return null;
@@ -831,6 +941,12 @@
   }
 
   @override
+  R? visitConstantPattern(ConstantPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitConstructorDeclaration(ConstructorDeclaration node) {
     node.visitChildren(this);
     return null;
@@ -963,6 +1079,12 @@
   }
 
   @override
+  R? visitExtractorPattern(ExtractorPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitFieldDeclaration(FieldDeclaration node) {
     node.visitChildren(this);
     return null;
@@ -987,6 +1109,12 @@
   }
 
   @override
+  R? visitForEachPartsWithPattern(ForEachPartsWithPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitForElement(ForElement node) {
     node.visitChildren(this);
     return null;
@@ -1011,6 +1139,12 @@
   }
 
   @override
+  R? visitForPartsWithPattern(ForPartsWithPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitForStatement(ForStatement node) {
     node.visitChildren(this);
     return null;
@@ -1185,12 +1319,30 @@
   }
 
   @override
+  R? visitListPattern(ListPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitMapLiteralEntry(MapLiteralEntry node) {
     node.visitChildren(this);
     return null;
   }
 
   @override
+  R? visitMapPattern(MapPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitMapPatternEntry(MapPatternEntry node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitMethodDeclaration(MethodDeclaration node) {
     node.visitChildren(this);
     return null;
@@ -1251,6 +1403,12 @@
   }
 
   @override
+  R? visitParenthesizedPattern(ParenthesizedPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitPartDirective(PartDirective node) {
     node.visitChildren(this);
     return null;
@@ -1263,12 +1421,43 @@
   }
 
   @override
+  R? visitPatternAssignment(PatternAssignment node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitPatternAssignmentStatement(PatternAssignmentStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitPatternVariableDeclaration(PatternVariableDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitPatternVariableDeclarationStatement(
+      PatternVariableDeclarationStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitPostfixExpression(PostfixExpression node) {
     node.visitChildren(this);
     return null;
   }
 
   @override
+  R? visitPostfixPattern(PostfixPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitPrefixedIdentifier(PrefixedIdentifier node) {
     node.visitChildren(this);
     return null;
@@ -1293,6 +1482,24 @@
   }
 
   @override
+  R? visitRecordPattern(RecordPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitRecordPatternField(RecordPatternField node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitRecordPatternFieldName(RecordPatternFieldName node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitRecordTypeAnnotation(RecordTypeAnnotation node) {
     node.visitChildren(this);
     return null;
@@ -1326,6 +1533,12 @@
   }
 
   @override
+  R? visitRelationalPattern(RelationalPattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitRethrowExpression(RethrowExpression node) {
     node.visitChildren(this);
     return null;
@@ -1428,6 +1641,30 @@
   }
 
   @override
+  R? visitSwitchExpression(SwitchExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitSwitchExpressionCase(SwitchExpressionCase node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitSwitchExpressionDefault(SwitchExpressionDefault node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitSwitchPatternCase(SwitchPatternCase node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitSwitchStatement(SwitchStatement node) {
     node.visitChildren(this);
     return null;
@@ -1506,6 +1743,18 @@
   }
 
   @override
+  R? visitVariablePattern(VariablePattern node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R? visitWhenClause(WhenClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitWhileStatement(WhileStatement node) {
     node.visitChildren(this);
     return null;
@@ -1565,6 +1814,9 @@
   R? visitBinaryExpression(BinaryExpression node) => null;
 
   @override
+  R? visitBinaryPattern(BinaryPattern node) => null;
+
+  @override
   R? visitBlock(Block node) => null;
 
   @override
@@ -1580,6 +1832,12 @@
   R? visitCascadeExpression(CascadeExpression node) => null;
 
   @override
+  R? visitCaseClause(CaseClause node) => null;
+
+  @override
+  R? visitCastPattern(CastPattern node) => null;
+
+  @override
   R? visitCatchClause(CatchClause node) => null;
 
   @override
@@ -1607,6 +1865,9 @@
   R? visitConfiguration(Configuration node) => null;
 
   @override
+  R? visitConstantPattern(ConstantPattern node) => null;
+
+  @override
   R? visitConstructorDeclaration(ConstructorDeclaration node) => null;
 
   @override
@@ -1673,6 +1934,9 @@
   R? visitExtensionOverride(ExtensionOverride node) => null;
 
   @override
+  R? visitExtractorPattern(ExtractorPattern node) => null;
+
+  @override
   R? visitFieldDeclaration(FieldDeclaration node) => null;
 
   @override
@@ -1685,6 +1949,9 @@
   R? visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) => null;
 
   @override
+  R? visitForEachPartsWithPattern(ForEachPartsWithPattern node) => null;
+
+  @override
   R? visitForElement(ForElement node) => null;
 
   @override
@@ -1697,6 +1964,9 @@
   R? visitForPartsWithExpression(ForPartsWithExpression node) => null;
 
   @override
+  R? visitForPartsWithPattern(ForPartsWithPattern node) => null;
+
+  @override
   R? visitForStatement(ForStatement node) => null;
 
   @override
@@ -1789,9 +2059,18 @@
   R? visitListLiteral(ListLiteral node) => null;
 
   @override
+  R? visitListPattern(ListPattern node) => null;
+
+  @override
   R? visitMapLiteralEntry(MapLiteralEntry node) => null;
 
   @override
+  R? visitMapPattern(MapPattern node) => null;
+
+  @override
+  R? visitMapPatternEntry(MapPatternEntry node) => null;
+
+  @override
   R? visitMethodDeclaration(MethodDeclaration node) => null;
 
   @override
@@ -1822,15 +2101,35 @@
   R? visitParenthesizedExpression(ParenthesizedExpression node) => null;
 
   @override
+  R? visitParenthesizedPattern(ParenthesizedPattern node) => null;
+
+  @override
   R? visitPartDirective(PartDirective node) => null;
 
   @override
   R? visitPartOfDirective(PartOfDirective node) => null;
 
   @override
+  R? visitPatternAssignment(PatternAssignment node) => null;
+
+  @override
+  R? visitPatternAssignmentStatement(PatternAssignmentStatement node) => null;
+
+  @override
+  R? visitPatternVariableDeclaration(PatternVariableDeclaration node) => null;
+
+  @override
+  R? visitPatternVariableDeclarationStatement(
+          PatternVariableDeclarationStatement node) =>
+      null;
+
+  @override
   R? visitPostfixExpression(PostfixExpression node) => null;
 
   @override
+  R? visitPostfixPattern(PostfixPattern node) => null;
+
+  @override
   R? visitPrefixedIdentifier(PrefixedIdentifier node) => null;
 
   @override
@@ -1843,6 +2142,15 @@
   R? visitRecordLiteral(RecordLiteral node) => null;
 
   @override
+  R? visitRecordPattern(RecordPattern node) => null;
+
+  @override
+  R? visitRecordPatternField(RecordPatternField node) => null;
+
+  @override
+  R? visitRecordPatternFieldName(RecordPatternFieldName node) => null;
+
+  @override
   R? visitRecordTypeAnnotation(RecordTypeAnnotation node) => null;
 
   @override
@@ -1865,6 +2173,9 @@
       null;
 
   @override
+  R? visitRelationalPattern(RelationalPattern node) => null;
+
+  @override
   R? visitRethrowExpression(RethrowExpression node) => null;
 
   @override
@@ -1916,6 +2227,18 @@
   R? visitSwitchDefault(SwitchDefault node) => null;
 
   @override
+  R? visitSwitchExpression(SwitchExpression node) => null;
+
+  @override
+  R? visitSwitchExpressionCase(SwitchExpressionCase node) => null;
+
+  @override
+  R? visitSwitchExpressionDefault(SwitchExpressionDefault node) => null;
+
+  @override
+  R? visitSwitchPatternCase(SwitchPatternCase node) => null;
+
+  @override
   R? visitSwitchStatement(SwitchStatement node) => null;
 
   @override
@@ -1956,6 +2279,12 @@
       null;
 
   @override
+  R? visitVariablePattern(VariablePattern node) => null;
+
+  @override
+  R? visitWhenClause(WhenClause node) => null;
+
+  @override
   R? visitWhileStatement(WhileStatement node) => null;
 
   @override
@@ -2008,6 +2337,9 @@
   R? visitBinaryExpression(BinaryExpression node) => _throw(node);
 
   @override
+  R? visitBinaryPattern(BinaryPattern node) => _throw(node);
+
+  @override
   R? visitBlock(Block node) => _throw(node);
 
   @override
@@ -2023,6 +2355,12 @@
   R? visitCascadeExpression(CascadeExpression node) => _throw(node);
 
   @override
+  R? visitCaseClause(CaseClause node) => _throw(node);
+
+  @override
+  R? visitCastPattern(CastPattern node) => _throw(node);
+
+  @override
   R? visitCatchClause(CatchClause node) => _throw(node);
 
   @override
@@ -2050,6 +2388,9 @@
   R? visitConfiguration(Configuration node) => _throw(node);
 
   @override
+  R? visitConstantPattern(ConstantPattern node) => _throw(node);
+
+  @override
   R? visitConstructorDeclaration(ConstructorDeclaration node) => _throw(node);
 
   @override
@@ -2117,6 +2458,9 @@
   R? visitExtensionOverride(ExtensionOverride node) => _throw(node);
 
   @override
+  R? visitExtractorPattern(ExtractorPattern node) => _throw(node);
+
+  @override
   R? visitFieldDeclaration(FieldDeclaration node) => _throw(node);
 
   @override
@@ -2131,6 +2475,9 @@
       _throw(node);
 
   @override
+  R? visitForEachPartsWithPattern(ForEachPartsWithPattern node) => _throw(node);
+
+  @override
   R? visitForElement(ForElement node) => _throw(node);
 
   @override
@@ -2144,6 +2491,9 @@
   R? visitForPartsWithExpression(ForPartsWithExpression node) => _throw(node);
 
   @override
+  R? visitForPartsWithPattern(ForPartsWithPattern node) => _throw(node);
+
+  @override
   R? visitForStatement(ForStatement node) => _throw(node);
 
   @override
@@ -2237,9 +2587,18 @@
   R? visitListLiteral(ListLiteral node) => _throw(node);
 
   @override
+  R? visitListPattern(ListPattern node) => _throw(node);
+
+  @override
   R? visitMapLiteralEntry(MapLiteralEntry node) => _throw(node);
 
   @override
+  R? visitMapPattern(MapPattern node) => _throw(node);
+
+  @override
+  R? visitMapPatternEntry(MapPatternEntry node) => _throw(node);
+
+  @override
   R? visitMethodDeclaration(MethodDeclaration node) => _throw(node);
 
   @override
@@ -2270,15 +2629,37 @@
   R? visitParenthesizedExpression(ParenthesizedExpression node) => _throw(node);
 
   @override
+  R? visitParenthesizedPattern(ParenthesizedPattern node) => _throw(node);
+
+  @override
   R? visitPartDirective(PartDirective node) => _throw(node);
 
   @override
   R? visitPartOfDirective(PartOfDirective node) => _throw(node);
 
   @override
+  R? visitPatternAssignment(PatternAssignment node) => _throw(node);
+
+  @override
+  R? visitPatternAssignmentStatement(PatternAssignmentStatement node) =>
+      _throw(node);
+
+  @override
+  R? visitPatternVariableDeclaration(PatternVariableDeclaration node) =>
+      _throw(node);
+
+  @override
+  R? visitPatternVariableDeclarationStatement(
+          PatternVariableDeclarationStatement node) =>
+      _throw(node);
+
+  @override
   R? visitPostfixExpression(PostfixExpression node) => _throw(node);
 
   @override
+  R? visitPostfixPattern(PostfixPattern node) => _throw(node);
+
+  @override
   R? visitPrefixedIdentifier(PrefixedIdentifier node) => _throw(node);
 
   @override
@@ -2291,6 +2672,15 @@
   R? visitRecordLiteral(RecordLiteral node) => _throw(node);
 
   @override
+  R? visitRecordPattern(RecordPattern node) => _throw(node);
+
+  @override
+  R? visitRecordPatternField(RecordPatternField node) => _throw(node);
+
+  @override
+  R? visitRecordPatternFieldName(RecordPatternFieldName node) => _throw(node);
+
+  @override
   R? visitRecordTypeAnnotation(RecordTypeAnnotation node) => _throw(node);
 
   @override
@@ -2313,6 +2703,9 @@
       _throw(node);
 
   @override
+  R? visitRelationalPattern(RelationalPattern node) => _throw(node);
+
+  @override
   R? visitRethrowExpression(RethrowExpression node) => _throw(node);
 
   @override
@@ -2365,6 +2758,18 @@
   R? visitSwitchDefault(SwitchDefault node) => _throw(node);
 
   @override
+  R? visitSwitchExpression(SwitchExpression node) => _throw(node);
+
+  @override
+  R? visitSwitchExpressionCase(SwitchExpressionCase node) => _throw(node);
+
+  @override
+  R? visitSwitchExpressionDefault(SwitchExpressionDefault node) => _throw(node);
+
+  @override
+  R? visitSwitchPatternCase(SwitchPatternCase node) => _throw(node);
+
+  @override
   R? visitSwitchStatement(SwitchStatement node) => _throw(node);
 
   @override
@@ -2406,6 +2811,12 @@
       _throw(node);
 
   @override
+  R? visitVariablePattern(VariablePattern node) => _throw(node);
+
+  @override
+  R? visitWhenClause(WhenClause node) => _throw(node);
+
+  @override
   R? visitWhileStatement(WhileStatement node) => _throw(node);
 
   @override
@@ -2515,6 +2926,14 @@
   }
 
   @override
+  T? visitBinaryPattern(BinaryPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitBinaryPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitBlock(Block node) {
     stopwatch.start();
     T? result = _baseVisitor.visitBlock(node);
@@ -2555,6 +2974,22 @@
   }
 
   @override
+  T? visitCaseClause(CaseClause node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitCaseClause(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitCastPattern(CastPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitCastPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitCatchClause(CatchClause node) {
     stopwatch.start();
     T? result = _baseVisitor.visitCatchClause(node);
@@ -2627,6 +3062,14 @@
   }
 
   @override
+  T? visitConstantPattern(ConstantPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitConstantPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitConstructorDeclaration(ConstructorDeclaration node) {
     stopwatch.start();
     T? result = _baseVisitor.visitConstructorDeclaration(node);
@@ -2803,6 +3246,14 @@
   }
 
   @override
+  T? visitExtractorPattern(ExtractorPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitExtractorPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitFieldDeclaration(FieldDeclaration node) {
     stopwatch.start();
     T? result = _baseVisitor.visitFieldDeclaration(node);
@@ -2835,6 +3286,14 @@
   }
 
   @override
+  T? visitForEachPartsWithPattern(ForEachPartsWithPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitForEachPartsWithPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitForElement(ForElement node) {
     stopwatch.start();
     T? result = _baseVisitor.visitForElement(node);
@@ -2867,6 +3326,14 @@
   }
 
   @override
+  T? visitForPartsWithPattern(ForPartsWithPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitForPartsWithPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitForStatement(ForStatement node) {
     stopwatch.start();
     T? result = _baseVisitor.visitForStatement(node);
@@ -3099,6 +3566,14 @@
   }
 
   @override
+  T? visitListPattern(ListPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitListPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitMapLiteralEntry(MapLiteralEntry node) {
     stopwatch.start();
     T? result = _baseVisitor.visitMapLiteralEntry(node);
@@ -3107,6 +3582,22 @@
   }
 
   @override
+  T? visitMapPattern(MapPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitMapPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitMapPatternEntry(MapPatternEntry node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitMapPatternEntry(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitMethodDeclaration(MethodDeclaration node) {
     stopwatch.start();
     T? result = _baseVisitor.visitMethodDeclaration(node);
@@ -3187,6 +3678,14 @@
   }
 
   @override
+  T? visitParenthesizedPattern(ParenthesizedPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitParenthesizedPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitPartDirective(PartDirective node) {
     stopwatch.start();
     T? result = _baseVisitor.visitPartDirective(node);
@@ -3203,6 +3702,39 @@
   }
 
   @override
+  T? visitPatternAssignment(PatternAssignment node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitPatternAssignment(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitPatternAssignmentStatement(PatternAssignmentStatement node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitPatternAssignmentStatement(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitPatternVariableDeclaration(PatternVariableDeclaration node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitPatternVariableDeclaration(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitPatternVariableDeclarationStatement(
+      PatternVariableDeclarationStatement node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitPatternVariableDeclarationStatement(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitPostfixExpression(PostfixExpression node) {
     stopwatch.start();
     T? result = _baseVisitor.visitPostfixExpression(node);
@@ -3211,6 +3743,14 @@
   }
 
   @override
+  T? visitPostfixPattern(PostfixPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitPostfixPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitPrefixedIdentifier(PrefixedIdentifier node) {
     stopwatch.start();
     T? result = _baseVisitor.visitPrefixedIdentifier(node);
@@ -3243,6 +3783,30 @@
   }
 
   @override
+  T? visitRecordPattern(RecordPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitRecordPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitRecordPatternField(RecordPatternField node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitRecordPatternField(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitRecordPatternFieldName(RecordPatternFieldName node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitRecordPatternFieldName(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitRecordTypeAnnotation(RecordTypeAnnotation node) {
     stopwatch.start();
     T? result = _baseVisitor.visitRecordTypeAnnotation(node);
@@ -3286,6 +3850,14 @@
   }
 
   @override
+  T? visitRelationalPattern(RelationalPattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitRelationalPattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitRethrowExpression(RethrowExpression node) {
     stopwatch.start();
     T? result = _baseVisitor.visitRethrowExpression(node);
@@ -3422,6 +3994,38 @@
   }
 
   @override
+  T? visitSwitchExpression(SwitchExpression node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitSwitchExpression(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitSwitchExpressionCase(SwitchExpressionCase node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitSwitchExpressionCase(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitSwitchExpressionDefault(SwitchExpressionDefault node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitSwitchExpressionDefault(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitSwitchPatternCase(SwitchPatternCase node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitSwitchPatternCase(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitSwitchStatement(SwitchStatement node) {
     stopwatch.start();
     T? result = _baseVisitor.visitSwitchStatement(node);
@@ -3526,6 +4130,22 @@
   }
 
   @override
+  T? visitVariablePattern(VariablePattern node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitVariablePattern(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T? visitWhenClause(WhenClause node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitWhenClause(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitWhileStatement(WhileStatement node) {
     stopwatch.start();
     T? result = _baseVisitor.visitWhileStatement(node);
@@ -3597,6 +4217,9 @@
   R? visitBinaryExpression(BinaryExpression node) => visitNode(node);
 
   @override
+  R? visitBinaryPattern(BinaryPattern node) => visitNode(node);
+
+  @override
   R? visitBlock(Block node) => visitNode(node);
 
   @override
@@ -3612,6 +4235,12 @@
   R? visitCascadeExpression(CascadeExpression node) => visitNode(node);
 
   @override
+  R? visitCaseClause(CaseClause node) => visitNode(node);
+
+  @override
+  R? visitCastPattern(CastPattern node) => visitNode(node);
+
+  @override
   R? visitCatchClause(CatchClause node) => visitNode(node);
 
   @override
@@ -3639,6 +4268,9 @@
   R? visitConfiguration(Configuration node) => visitNode(node);
 
   @override
+  R? visitConstantPattern(ConstantPattern node) => visitNode(node);
+
+  @override
   R? visitConstructorDeclaration(ConstructorDeclaration node) =>
       visitNode(node);
 
@@ -3710,6 +4342,9 @@
   R? visitExtensionOverride(ExtensionOverride node) => visitNode(node);
 
   @override
+  R? visitExtractorPattern(ExtractorPattern node) => visitNode(node);
+
+  @override
   R? visitFieldDeclaration(FieldDeclaration node) => visitNode(node);
 
   @override
@@ -3724,6 +4359,10 @@
       visitNode(node);
 
   @override
+  R? visitForEachPartsWithPattern(ForEachPartsWithPattern node) =>
+      visitNode(node);
+
+  @override
   R? visitForElement(ForElement node) => visitNode(node);
 
   @override
@@ -3738,6 +4377,9 @@
       visitNode(node);
 
   @override
+  R? visitForPartsWithPattern(ForPartsWithPattern node) => visitNode(node);
+
+  @override
   R? visitForStatement(ForStatement node) => visitNode(node);
 
   @override
@@ -3832,9 +4474,18 @@
   R? visitListLiteral(ListLiteral node) => visitNode(node);
 
   @override
+  R? visitListPattern(ListPattern node) => visitNode(node);
+
+  @override
   R? visitMapLiteralEntry(MapLiteralEntry node) => visitNode(node);
 
   @override
+  R? visitMapPattern(MapPattern node) => visitNode(node);
+
+  @override
+  R? visitMapPatternEntry(MapPatternEntry node) => visitNode(node);
+
+  @override
   R? visitMethodDeclaration(MethodDeclaration node) => visitNode(node);
 
   @override
@@ -3871,15 +4522,37 @@
       visitNode(node);
 
   @override
+  R? visitParenthesizedPattern(ParenthesizedPattern node) => visitNode(node);
+
+  @override
   R? visitPartDirective(PartDirective node) => visitNode(node);
 
   @override
   R? visitPartOfDirective(PartOfDirective node) => visitNode(node);
 
   @override
+  R? visitPatternAssignment(PatternAssignment node) => visitNode(node);
+
+  @override
+  R? visitPatternAssignmentStatement(PatternAssignmentStatement node) =>
+      visitNode(node);
+
+  @override
+  R? visitPatternVariableDeclaration(PatternVariableDeclaration node) =>
+      visitNode(node);
+
+  @override
+  R? visitPatternVariableDeclarationStatement(
+          PatternVariableDeclarationStatement node) =>
+      visitNode(node);
+
+  @override
   R? visitPostfixExpression(PostfixExpression node) => visitNode(node);
 
   @override
+  R? visitPostfixPattern(PostfixPattern node) => visitNode(node);
+
+  @override
   R? visitPrefixedIdentifier(PrefixedIdentifier node) => visitNode(node);
 
   @override
@@ -3892,6 +4565,16 @@
   R? visitRecordLiteral(RecordLiteral node) => visitNode(node);
 
   @override
+  R? visitRecordPattern(RecordPattern node) => visitNode(node);
+
+  @override
+  R? visitRecordPatternField(RecordPatternField node) => visitNode(node);
+
+  @override
+  R? visitRecordPatternFieldName(RecordPatternFieldName node) =>
+      visitNode(node);
+
+  @override
   R? visitRecordTypeAnnotation(RecordTypeAnnotation node) => visitNode(node);
 
   @override
@@ -3914,6 +4597,9 @@
       visitNode(node);
 
   @override
+  R? visitRelationalPattern(RelationalPattern node) => visitNode(node);
+
+  @override
   R? visitRethrowExpression(RethrowExpression node) => visitNode(node);
 
   @override
@@ -3966,6 +4652,19 @@
   R? visitSwitchDefault(SwitchDefault node) => visitNode(node);
 
   @override
+  R? visitSwitchExpression(SwitchExpression node) => visitNode(node);
+
+  @override
+  R? visitSwitchExpressionCase(SwitchExpressionCase node) => visitNode(node);
+
+  @override
+  R? visitSwitchExpressionDefault(SwitchExpressionDefault node) =>
+      visitNode(node);
+
+  @override
+  R? visitSwitchPatternCase(SwitchPatternCase node) => visitNode(node);
+
+  @override
   R? visitSwitchStatement(SwitchStatement node) => visitNode(node);
 
   @override
@@ -4008,6 +4707,12 @@
       visitNode(node);
 
   @override
+  R? visitVariablePattern(VariablePattern node) => visitNode(node);
+
+  @override
+  R? visitWhenClause(WhenClause node) => visitNode(node);
+
+  @override
   R? visitWhileStatement(WhileStatement node) => visitNode(node);
 
   @override
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index a0014d2..d4cc40d 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -57,14 +57,10 @@
 /// Clients may not extend, implement or mix-in this class.
 @experimental
 abstract class AugmentationImportElement implements _ExistingElement {
-  @Deprecated('Use enclosingElement3 instead')
   @override
   LibraryOrAugmentationElement get enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  LibraryOrAugmentationElement get enclosingElement2;
-
+  @Deprecated('Use enclosingElement instead')
   @override
   LibraryOrAugmentationElement get enclosingElement3;
 
@@ -185,12 +181,56 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ClassElement
-    implements
-        ClassOrAugmentationElement,
-        InterfaceElement,
-        _TmpSharedClassElement {
+    implements ClassOrAugmentationElement, InterfaceElement {
   /// Returns the result of applying augmentations to this class.
   AugmentedClassElement get augmented;
+
+  /// Return `true` if this class or its superclass declares a non-final
+  /// instance field.
+  bool get hasNonFinalField;
+
+  /// Return `true` if this class is abstract. A class is abstract if it has an
+  /// explicit `abstract` modifier. Note, that this definition of
+  /// <i>abstract</i> is different from <i>has unimplemented members</i>.
+  bool get isAbstract;
+
+  /// Return `true` if this class represents the class 'Enum' defined in the
+  /// dart:core library.
+  bool get isDartCoreEnum;
+
+  /// Return `true` if this class represents the class 'Object' defined in the
+  /// dart:core library.
+  bool get isDartCoreObject;
+
+  /// Return `true` if this class is a mixin application.  A class is a mixin
+  /// application if it was declared using the syntax "class A = B with C;".
+  bool get isMixinApplication;
+
+  /// Return `true` if this class can validly be used as a mixin when defining
+  /// another class. For classes defined by a class declaration or a mixin
+  /// application, the behavior of this method is defined by the Dart Language
+  /// Specification in section 9:
+  /// <blockquote>
+  /// It is a compile-time error if a declared or derived mixin refers to super.
+  /// It is a compile-time error if a declared or derived mixin explicitly
+  /// declares a constructor. It is a compile-time error if a mixin is derived
+  /// from a class whose superclass is not Object.
+  /// </blockquote>
+  bool get isValidMixin;
+
+  /// Return a list containing all of the superclass constraints defined for
+  /// this class. The list will be empty if this class does not represent a
+  /// mixin declaration. If this class _does_ represent a mixin declaration but
+  /// the declaration does not have an `on` clause, then the list will contain
+  /// the type for the class `Object`.
+  ///
+  /// <b>Note:</b> Because the element model represents the state of the code,
+  /// it is possible for it to be semantically invalid. In particular, it is not
+  /// safe to assume that the inheritance structure of a class does not contain
+  /// a cycle. Clients that traverse the inheritance structure must explicitly
+  /// guard against infinite loops.
+  @Deprecated('This getter is implemented only for MixinElement')
+  List<InterfaceType> get superclassConstraints;
 }
 
 /// An element that is contained within a [ClassElement].
@@ -200,14 +240,10 @@
   // TODO(brianwilkerson) Either remove this class or rename it to something
   //  more correct.
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   Element get enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  Element get enclosingElement2;
-
+  @Deprecated('Use enclosingElement instead')
   @override
   Element get enclosingElement3;
 
@@ -241,22 +277,14 @@
   /// unit.
   List<ClassElement> get classes;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  LibraryElement get enclosingElement;
-
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  LibraryOrAugmentationElement get enclosingElement2;
-
   /// Return the library, or library augmentation that encloses this unit.
   @override
-  LibraryOrAugmentationElement get enclosingElement3;
+  LibraryOrAugmentationElement get enclosingElement;
 
-  /// Return a list containing all of the enums contained in this compilation
-  /// unit.
-  @Deprecated('Use enums2 instead')
-  List<ClassElement> get enums;
+  /// Return the library, or library augmentation that encloses this unit.
+  @Deprecated('Use enclosingElement instead')
+  @override
+  LibraryOrAugmentationElement get enclosingElement3;
 
   /// Return a list containing all of the enums contained in this compilation
   /// unit.
@@ -275,11 +303,6 @@
 
   /// Return a list containing all of the mixins contained in this compilation
   /// unit.
-  @Deprecated('Use mixins2 instead')
-  List<ClassElement> get mixins;
-
-  /// Return a list containing all of the mixins contained in this compilation
-  /// unit.
   List<MixinElement> get mixins2;
 
   @override
@@ -301,19 +324,7 @@
   /// Return the enum defined in this compilation unit that has the given
   /// [name], or `null` if this compilation unit does not define an enum with
   /// the given name.
-  @Deprecated('Use getEnum2() instead')
-  ClassElement? getEnum(String name);
-
-  /// Return the enum defined in this compilation unit that has the given
-  /// [name], or `null` if this compilation unit does not define an enum with
-  /// the given name.
   EnumElement? getEnum2(String name);
-
-  /// Return the class defined in this compilation unit that has the given
-  /// [name], or `null` if this compilation unit does not define a class with
-  /// the given name.
-  @Deprecated('Use getClass() instead')
-  ClassElement? getType(String name);
 }
 
 /// An element representing a constructor augmentation.
@@ -346,14 +357,10 @@
   @override
   String get displayName;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  ClassElement get enclosingElement;
+  InterfaceElement get enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  ClassElement get enclosingElement2;
-
+  @Deprecated('Use enclosingElement instead')
   @override
   InterfaceElement get enclosingElement3;
 
@@ -500,18 +507,12 @@
   /// Return the element that either physically or logically encloses this
   /// element. This will be `null` if this element is a library because
   /// libraries are the top-level elements in the model.
-  @Deprecated('Use enclosingElement3 instead')
   Element? get enclosingElement;
 
   /// Return the element that either physically or logically encloses this
   /// element. This will be `null` if this element is a library because
   /// libraries are the top-level elements in the model.
-  @Deprecated('Use enclosingElement3 instead')
-  Element? get enclosingElement2;
-
-  /// Return the element that either physically or logically encloses this
-  /// element. This will be `null` if this element is a library because
-  /// libraries are the top-level elements in the model.
+  @Deprecated('Use enclosingElement instead')
   Element? get enclosingElement3;
 
   /// Return `true` if this element has an annotation of the form
@@ -685,16 +686,6 @@
 
   /// Return `true` if this element, assuming that it is within scope, is
   /// accessible to code in the given [library]. This is defined by the Dart
-  /// Language Specification in section 3.2:
-  /// <blockquote>
-  /// A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is
-  /// declared in <i>L</i> or if <i>m</i> is public.
-  /// </blockquote>
-  @Deprecated('Use isAccessibleIn2() instead')
-  bool isAccessibleIn(LibraryElement? library);
-
-  /// Return `true` if this element, assuming that it is within scope, is
-  /// accessible to code in the given [library]. This is defined by the Dart
   /// Language Specification in section 6.2:
   /// <blockquote>
   /// A declaration <i>m</i> is accessible to a library <i>L</i> if <i>m</i> is
@@ -1019,9 +1010,6 @@
 
   R? visitEnumElement(EnumElement element);
 
-  @Deprecated('Override visitLibraryExportElement() instead')
-  R? visitExportElement(ExportElement element);
-
   R? visitExtensionElement(ExtensionElement element);
 
   R? visitFieldElement(FieldElement element);
@@ -1032,9 +1020,6 @@
 
   R? visitGenericFunctionTypeElement(GenericFunctionTypeElement element);
 
-  @Deprecated('Override visitLibraryImportElement() instead')
-  R? visitImportElement(ImportElement element);
-
   R? visitLabelElement(LabelElement element);
 
   R? visitLibraryAugmentationElement(LibraryAugmentationElement element);
@@ -1088,10 +1073,7 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class EnumElement
-    implements
-        EnumOrAugmentationElement,
-        InterfaceElement,
-        _TmpSharedClassElement {
+    implements EnumOrAugmentationElement, InterfaceElement {
   /// Returns the result of applying augmentations to this element.
   AugmentedEnumElement get augmented;
 }
@@ -1119,14 +1101,10 @@
   @override
   String get displayName;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   Element get enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  Element get enclosingElement2;
-
+  @Deprecated('Use enclosingElement instead')
   @override
   Element get enclosingElement3;
 
@@ -1169,20 +1147,6 @@
   String get name;
 }
 
-/// An export directive within a library.
-///
-/// Clients may not extend, implement or mix-in this class.
-@Deprecated('Use LibraryExportElement instead')
-abstract class ExportElement implements UriReferencedElement {
-  /// Return a list containing the combinators that were specified as part of
-  /// the export directive in the order in which they were specified.
-  List<NamespaceCombinator> get combinators;
-
-  /// Return the library that is exported from this library by this export
-  /// directive, or `null` if the URI has invalid syntax or cannot be resolved.
-  LibraryElement? get exportedLibrary;
-}
-
 /// An element that represents an extension.
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -1191,14 +1155,10 @@
   /// declared in this extension.
   List<PropertyAccessorElement> get accessors;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   CompilationUnitElement get enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  CompilationUnitElement get enclosingElement2;
-
+  @Deprecated('Use enclosingElement instead')
   @override
   CompilationUnitElement get enclosingElement3;
 
@@ -1349,30 +1309,6 @@
   List<String> get hiddenNames;
 }
 
-/// A single import directive within a library.
-///
-/// Clients may not extend, implement or mix-in this class.
-@Deprecated('Use LibraryImportElement instead')
-abstract class ImportElement implements UriReferencedElement {
-  /// Return a list containing the combinators that were specified as part of
-  /// the import directive in the order in which they were specified.
-  List<NamespaceCombinator> get combinators;
-
-  /// Return the library that is imported into this library by this import
-  /// directive, or `null` if the URI has invalid syntax or cannot be resolved.
-  LibraryElement? get importedLibrary;
-
-  /// Return `true` if this import is for a deferred library.
-  bool get isDeferred;
-
-  /// The [Namespace] that this directive contributes to the containing library.
-  Namespace get namespace;
-
-  /// Return the prefix that was specified as part of the import directive, or
-  /// `null` if there was no prefix specified.
-  PrefixElement? get prefix;
-}
-
 /// Usage of a [PrefixElement] in an `import` directive.
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -1492,6 +1428,62 @@
   PropertyAccessorElement? lookUpGetter(
       String getterName, LibraryElement library);
 
+  /// Return the element representing the getter that results from looking up
+  /// the given [getterName] in the superclass of this class with respect to the
+  /// given [library], ignoring abstract getters, or `null` if the look up
+  /// fails.  The behavior of this method is defined by the Dart Language
+  /// Specification in section 16.15.2:
+  /// <blockquote>
+  /// The result of looking up getter (respectively setter) <i>m</i> in class
+  /// <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+  /// instance getter (respectively setter) named <i>m</i> that is accessible to
+  /// <i>L</i>, then that getter (respectively setter) is the result of the
+  /// lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+  /// of the lookup is the result of looking up getter (respectively setter)
+  /// <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+  /// lookup has failed.
+  /// </blockquote>
+  /// TODO(scheglov) Deprecate and remove it.
+  PropertyAccessorElement? lookUpInheritedConcreteGetter(
+      String getterName, LibraryElement library);
+
+  /// Return the element representing the method that results from looking up
+  /// the given [methodName] in the superclass of this class with respect to the
+  /// given [library], ignoring abstract methods, or `null` if the look up
+  /// fails.  The behavior of this method is defined by the Dart Language
+  /// Specification in section 16.15.1:
+  /// <blockquote>
+  /// The result of looking up method <i>m</i> in class <i>C</i> with respect to
+  /// library <i>L</i> is:  If <i>C</i> declares an instance method named
+  /// <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+  /// the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+  /// result of the lookup is the result of looking up method <i>m</i> in
+  /// <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+  /// failed.
+  /// </blockquote>
+  /// TODO(scheglov) Deprecate and remove it.
+  MethodElement? lookUpInheritedConcreteMethod(
+      String methodName, LibraryElement library);
+
+  /// Return the element representing the setter that results from looking up
+  /// the given [setterName] in the superclass of this class with respect to the
+  /// given [library], ignoring abstract setters, or `null` if the look up
+  /// fails.  The behavior of this method is defined by the Dart Language
+  /// Specification in section 16.15.2:
+  /// <blockquote>
+  /// The result of looking up getter (respectively setter) <i>m</i> in class
+  /// <i>C</i> with respect to library <i>L</i> is:  If <i>C</i> declares an
+  /// instance getter (respectively setter) named <i>m</i> that is accessible to
+  /// <i>L</i>, then that getter (respectively setter) is the result of the
+  /// lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+  /// of the lookup is the result of looking up getter (respectively setter)
+  /// <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+  /// lookup has failed.
+  /// </blockquote>
+  /// TODO(scheglov) Deprecate and remove it.
+  PropertyAccessorElement? lookUpInheritedConcreteSetter(
+      String setterName, LibraryElement library);
+
   /// Return the element representing the method that results from looking up
   /// the given [methodName] in the superclass of this class with respect to the
   /// given [library], or `null` if the look up fails. The behavior of this
@@ -1561,14 +1553,10 @@
   /// class, as is the case when this element represents an enum or a mixin.
   List<ConstructorElement> get constructors;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   CompilationUnitElement get enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  CompilationUnitElement get enclosingElement2;
-
+  @Deprecated('Use enclosingElement instead')
   @override
   CompilationUnitElement get enclosingElement3;
 
@@ -1610,14 +1598,10 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class LabelElement implements Element {
-  @Deprecated('Use enclosingElement3 instead')
   @override
   ExecutableElement get enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  ExecutableElement get enclosingElement2;
-
+  @Deprecated('Use enclosingElement instead')
   @override
   ExecutableElement get enclosingElement3;
 
@@ -1684,12 +1668,6 @@
   @override
   String get name;
 
-  /// Return a list containing all of the compilation units that are included in
-  /// this library using a `part` directive. This does not include the defining
-  /// compilation unit that contains the `part` directives.
-  @Deprecated('Use parts2 instead')
-  List<CompilationUnitElement> get parts;
-
   /// Returns the list of `part` directives of this library.
   List<PartElement> get parts2;
 
@@ -1710,16 +1688,6 @@
   /// `null` if this library does not define a class with the given name.
   ClassElement? getClass(String name);
 
-  /// Return a list containing all of the imports that share the given [prefix],
-  /// or an empty array if there are no such imports.
-  @Deprecated('Use PrefixElement.imports instead')
-  List<ImportElement> getImportsWithPrefix(PrefixElement prefix);
-
-  /// Return the class defined in this library that has the given [name], or
-  /// `null` if this library does not define a class with the given name.
-  @Deprecated('Use getClass() instead')
-  ClassElement? getType(String className);
-
   /// If a legacy library, return the legacy view on the [element].
   /// Otherwise, return the original element.
   T toLegacyElementIfOptOut<T extends Element>(T element);
@@ -1806,10 +1774,6 @@
   /// Return the compilation unit that defines this library.
   CompilationUnitElement get definingCompilationUnit;
 
-  /// Return a list containing all of the exports defined in this library.
-  @Deprecated('Use libraryExports instead')
-  List<ExportElement> get exports;
-
   /// The set of features available to this library.
   ///
   /// Determined by the combination of the language version for the enclosing
@@ -1817,10 +1781,6 @@
   /// version override comment at the top of the file.
   FeatureSet get featureSet;
 
-  /// Return a list containing all of the imports defined in this library.
-  @Deprecated('Use libraryImports instead')
-  List<ImportElement> get imports;
-
   bool get isNonNullableByDefault;
 
   /// The language version for this library.
@@ -1915,10 +1875,7 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class MixinElement
-    implements
-        MixinOrAugmentationElement,
-        InterfaceElement,
-        _TmpSharedClassElement {
+    implements MixinOrAugmentationElement, InterfaceElement {
   /// Returns the result of applying augmentations to this element.
   AugmentedMixinElement get augmented;
 
@@ -1931,7 +1888,6 @@
   /// safe to assume that the inheritance structure of a class does not contain
   /// a cycle. Clients that traverse the inheritance structure must explicitly
   /// guard against infinite loops.
-  @override
   List<InterfaceType> get superclassConstraints;
 }
 
@@ -2002,18 +1958,6 @@
   /// are considered required.
   bool get isNamed;
 
-  /// Return `true` if this parameter is a required parameter. Required
-  /// parameters are always positional, unless the experiment 'non-nullable' is
-  /// enabled, in which case named parameters can also be required.
-  ///
-  /// Note: regardless of the state of the 'non-nullable' experiment, the
-  /// presence or absence of the `@required` annotation does not change the
-  /// meaning of this getter. The parameter `{@required int x}` will return
-  /// `false` and the parameter `{@required required int x}` will return
-  /// `true`
-  @Deprecated('Use isRequired instead')
-  bool get isNotOptional;
-
   /// Return `true` if this parameter is an optional parameter. Optional
   /// parameters can either be positional or named.  Named parameters that are
   /// annotated with the `@required` annotation are considered optional.  Named
@@ -2095,21 +2039,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class PrefixElement implements _ExistingElement {
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  LibraryElement get enclosingElement;
-
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  LibraryOrAugmentationElement get enclosingElement2;
-
   /// Return the library, or library augmentation that encloses this element.
   @override
-  LibraryOrAugmentationElement get enclosingElement3;
+  LibraryOrAugmentationElement get enclosingElement;
 
-  /// Return the imports that share this prefix.
-  @Deprecated('Use imports2 instead')
-  List<ImportElement> get imports;
+  /// Return the library, or library augmentation that encloses this element.
+  @Deprecated('Use enclosingElement instead')
+  @override
+  LibraryOrAugmentationElement get enclosingElement3;
 
   /// Return the imports that share this prefix.
   List<LibraryImportElement> get imports2;
@@ -2180,14 +2117,10 @@
   @override
   PropertyAccessorElement get declaration;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   Element get enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  Element get enclosingElement2;
-
+  @Deprecated('Use enclosingElement instead')
   @override
   Element get enclosingElement3;
 
@@ -2307,14 +2240,10 @@
   /// a [FunctionType].
   DartType get aliasedType;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   CompilationUnitElement get enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  CompilationUnitElement get enclosingElement2;
-
+  @Deprecated('Use enclosingElement instead')
   @override
   CompilationUnitElement get enclosingElement3;
 
@@ -2459,6 +2388,15 @@
   DartObject? computeConstantValue();
 }
 
+/// A pattern variable.
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class VariablePatternElement implements LocalVariableElement {
+  /// Aliases of this variable in logical-or patterns.
+  List<VariablePatternElement> get aliases;
+}
+
 /// This class exists to provide non-nullable overrides for existing elements,
 /// as opposite to artificial "multiply defined" element.
 abstract class _ExistingElement implements Element {
@@ -2474,127 +2412,3 @@
   @override
   Source get source;
 }
-
-/// Properties that existed in [ClassElement], so we should keep them for
-/// backward compatibility for now. But we want them to be either moved, or
-/// removed.
-abstract class _TmpSharedClassElement {
-  /// Return `true` if this class or its superclass declares a non-final
-  /// instance field.
-  bool get hasNonFinalField;
-
-  /// Return `true` if this class declares a static member.
-  @Deprecated('Not useful for clients')
-  bool get hasStaticMember;
-
-  /// Return `true` if this class is abstract. A class is abstract if it has an
-  /// explicit `abstract` modifier or if it is implicitly abstract, such as a
-  /// class defined by a mixin declaration. Note, that this definition of
-  /// <i>abstract</i> is different from <i>has unimplemented members</i>.
-  /// TODO(scheglov) Deprecate and replace it.
-  bool get isAbstract;
-
-  /// Return `true` if this class represents the class 'Enum' defined in the
-  /// dart:core library.
-  bool get isDartCoreEnum;
-
-  /// Return `true` if this class represents the class 'Object' defined in the
-  /// dart:core library.
-  bool get isDartCoreObject;
-
-  /// Return `true` if this class is defined by an enum declaration.
-  @Deprecated('Use `is EnumElement` instead')
-  bool get isEnum;
-
-  /// Return `true` if this class is defined by a mixin declaration.
-  @Deprecated('Use `is MixinElement` instead')
-  bool get isMixin;
-
-  /// Return `true` if this class is a mixin application.  A class is a mixin
-  /// application if it was declared using the syntax "class A = B with C;".
-  bool get isMixinApplication;
-
-  /// Return `true` if this class can validly be used as a mixin when defining
-  /// another class. For classes defined by a mixin declaration, the result is
-  /// always `true`. For classes defined by a class declaration or a mixin
-  /// application, the behavior of this method is defined by the Dart Language
-  /// Specification in section 9:
-  /// <blockquote>
-  /// It is a compile-time error if a declared or derived mixin refers to super.
-  /// It is a compile-time error if a declared or derived mixin explicitly
-  /// declares a constructor. It is a compile-time error if a mixin is derived
-  /// from a class whose superclass is not Object.
-  /// </blockquote>
-  /// TODO(scheglov) Deprecate and remove it.
-  bool get isValidMixin;
-
-  /// Return a list containing all of the superclass constraints defined for
-  /// this class. The list will be empty if this class does not represent a
-  /// mixin declaration. If this class _does_ represent a mixin declaration but
-  /// the declaration does not have an `on` clause, then the list will contain
-  /// the type for the class `Object`.
-  ///
-  /// <b>Note:</b> Because the element model represents the state of the code,
-  /// it is possible for it to be semantically invalid. In particular, it is not
-  /// safe to assume that the inheritance structure of a class does not contain
-  /// a cycle. Clients that traverse the inheritance structure must explicitly
-  /// guard against infinite loops.
-  /// TODO(scheglov) Deprecate and remove it.
-  List<InterfaceType> get superclassConstraints;
-
-  /// Return the element representing the getter that results from looking up
-  /// the given [getterName] in the superclass of this class with respect to the
-  /// given [library], ignoring abstract getters, or `null` if the look up
-  /// fails.  The behavior of this method is defined by the Dart Language
-  /// Specification in section 16.15.2:
-  /// <blockquote>
-  /// The result of looking up getter (respectively setter) <i>m</i> in class
-  /// <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
-  /// instance getter (respectively setter) named <i>m</i> that is accessible to
-  /// <i>L</i>, then that getter (respectively setter) is the result of the
-  /// lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-  /// of the lookup is the result of looking up getter (respectively setter)
-  /// <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
-  /// lookup has failed.
-  /// </blockquote>
-  /// TODO(scheglov) Deprecate and remove it.
-  PropertyAccessorElement? lookUpInheritedConcreteGetter(
-      String getterName, LibraryElement library);
-
-  /// Return the element representing the method that results from looking up
-  /// the given [methodName] in the superclass of this class with respect to the
-  /// given [library], ignoring abstract methods, or `null` if the look up
-  /// fails.  The behavior of this method is defined by the Dart Language
-  /// Specification in section 16.15.1:
-  /// <blockquote>
-  /// The result of looking up method <i>m</i> in class <i>C</i> with respect to
-  /// library <i>L</i> is:  If <i>C</i> declares an instance method named
-  /// <i>m</i> that is accessible to <i>L</i>, then that method is the result of
-  /// the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
-  /// result of the lookup is the result of looking up method <i>m</i> in
-  /// <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
-  /// failed.
-  /// </blockquote>
-  /// TODO(scheglov) Deprecate and remove it.
-  MethodElement? lookUpInheritedConcreteMethod(
-      String methodName, LibraryElement library);
-
-  /// Return the element representing the setter that results from looking up
-  /// the given [setterName] in the superclass of this class with respect to the
-  /// given [library], ignoring abstract setters, or `null` if the look up
-  /// fails.  The behavior of this method is defined by the Dart Language
-  /// Specification in section 16.15.2:
-  /// <blockquote>
-  /// The result of looking up getter (respectively setter) <i>m</i> in class
-  /// <i>C</i> with respect to library <i>L</i> is:  If <i>C</i> declares an
-  /// instance getter (respectively setter) named <i>m</i> that is accessible to
-  /// <i>L</i>, then that getter (respectively setter) is the result of the
-  /// lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-  /// of the lookup is the result of looking up getter (respectively setter)
-  /// <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
-  /// lookup has failed.
-  /// </blockquote>
-  /// TODO(scheglov) Deprecate and remove it.
-  PropertyAccessorElement? lookUpInheritedConcreteSetter(
-      String setterName, LibraryElement library);
-}
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 5ad3c4c..23038b5 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -33,21 +33,6 @@
   /// Otherwise return `null`.
   InstantiatedTypeAliasElement? get alias;
 
-  /// Return the name of this type as it should appear when presented to users
-  /// in contexts such as error messages.
-  ///
-  /// Clients should not depend on the content of the returned value as it will
-  /// be changed if doing so would improve the UX.
-  @Deprecated('Use getDisplayString instead')
-  String get displayName;
-
-  /// Return the element representing the declaration of this type, or `null` if
-  /// the type has not, or cannot, be associated with an element. The former
-  /// case will occur if the element model is not yet complete; the latter case
-  /// will occur if this object represents an undefined type.
-  @Deprecated('Use element2 instead')
-  Element? get element;
-
   /// Return the element representing the declaration of this type, or `null`
   /// if the type is not associated with an element.
   Element? get element2;
@@ -210,10 +195,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FunctionType implements DartType {
-  @Deprecated('Use element2 instead')
-  @override
-  Null get element;
-
   @override
   Null get element2;
 
@@ -294,10 +275,6 @@
   /// Return a list containing all of the constructors declared in this type.
   List<ConstructorElement> get constructors;
 
-  @Deprecated('Use element2 instead')
-  @override
-  ClassElement get element;
-
   @override
   InterfaceElement get element2;
 
@@ -441,10 +418,6 @@
 /// Clients may not extend, implement or mix-in this class.
 @experimental
 abstract class RecordType implements DartType {
-  @Deprecated('Use element2 instead')
-  @override
-  Null get element;
-
   @override
   Null get element2;
 
@@ -494,10 +467,6 @@
   /// Always consult the bound if that could be relevant.
   ElementLocation get definition;
 
-  @Deprecated('Use element2 instead')
-  @override
-  TypeParameterElement get element;
-
   @override
   TypeParameterElement get element2;
 }
@@ -505,10 +474,6 @@
 /// The special type `void` is used to indicate that the value of an
 /// expression is meaningless, and intended to be discarded.
 abstract class VoidType implements DartType {
-  @Deprecated('Use element2 instead')
-  @override
-  Null get element;
-
   @override
   Null get element2;
 }
diff --git a/pkg/analyzer/lib/dart/element/visitor.dart b/pkg/analyzer/lib/dart/element/visitor.dart
index c5de555..42be774 100644
--- a/pkg/analyzer/lib/dart/element/visitor.dart
+++ b/pkg/analyzer/lib/dart/element/visitor.dart
@@ -107,10 +107,6 @@
 
   R? visitExecutableElement(ExecutableElement element) => visitElement(element);
 
-  @Deprecated('Override visitLibraryExportElement() instead')
-  @override
-  R? visitExportElement(ExportElement element) => visitElement(element);
-
   @override
   R? visitExtensionElement(ExtensionElement element) => visitElement(element);
 
@@ -130,10 +126,6 @@
   R? visitGenericFunctionTypeElement(GenericFunctionTypeElement element) =>
       visitElement(element);
 
-  @Deprecated('Override visitLibraryImportElement() instead')
-  @override
-  R? visitImportElement(ImportElement element) => visitElement(element);
-
   @override
   R? visitLabelElement(LabelElement element) => visitElement(element);
 
@@ -258,13 +250,6 @@
     return null;
   }
 
-  @Deprecated('Override visitLibraryExportElement() instead')
-  @override
-  R? visitExportElement(ExportElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
   @override
   R? visitExtensionElement(ExtensionElement element) {
     element.visitChildren(this);
@@ -295,13 +280,6 @@
     return null;
   }
 
-  @Deprecated('Override visitLibraryImportElement() instead')
-  @override
-  R? visitImportElement(ImportElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
   @override
   R? visitLabelElement(LabelElement element) {
     element.visitChildren(this);
@@ -430,10 +408,6 @@
   @override
   R? visitEnumElement(EnumElement element) => null;
 
-  @Deprecated('Override visitLibraryExportElement() instead')
-  @override
-  R? visitExportElement(ExportElement element) => null;
-
   @override
   R? visitExtensionElement(ExtensionElement element) => null;
 
@@ -451,10 +425,6 @@
   R? visitGenericFunctionTypeElement(GenericFunctionTypeElement element) =>
       null;
 
-  @Deprecated('Override visitLibraryImportElement() instead')
-  @override
-  R? visitImportElement(ImportElement element) => null;
-
   @override
   R? visitLabelElement(LabelElement element) => null;
 
@@ -537,10 +507,6 @@
   @override
   R? visitEnumElement(EnumElement element) => _throw(element);
 
-  @Deprecated('Override visitLibraryExportElement() instead')
-  @override
-  R? visitExportElement(ExportElement element) => _throw(element);
-
   @override
   R? visitExtensionElement(ExtensionElement element) => _throw(element);
 
@@ -558,10 +524,6 @@
   R? visitGenericFunctionTypeElement(GenericFunctionTypeElement element) =>
       _throw(element);
 
-  @Deprecated('Override visitLibraryImportElement() instead')
-  @override
-  R? visitImportElement(ImportElement element) => _throw(element);
-
   @override
   R? visitLabelElement(LabelElement element) => _throw(element);
 
diff --git a/pkg/analyzer/lib/diagnostic/diagnostic.dart b/pkg/analyzer/lib/diagnostic/diagnostic.dart
index 5179104..50ecab8 100644
--- a/pkg/analyzer/lib/diagnostic/diagnostic.dart
+++ b/pkg/analyzer/lib/diagnostic/diagnostic.dart
@@ -37,14 +37,6 @@
   /// The length of the source range associated with this message.
   int get length;
 
-  /// Gets the text of the message.
-  ///
-  /// This getter exists for backwards compatibility with code that was written
-  /// prior to the addition of URLs to diagnostic messages.  New clients should
-  /// use `messageText` instead.
-  @Deprecated('Use messageText(includeUrl: true) instead')
-  String get message;
-
   /// The zero-based offset from the start of the file to the beginning of the
   /// source range associated with this message.
   int get offset;
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index e41e7a1..5b74698 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -48,7 +48,6 @@
   AnalysisOptionsHintCode.PREVIEW_DART_2_SETTING_DEPRECATED,
   AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED,
   AnalysisOptionsHintCode.SUPER_MIXINS_SETTING_DEPRECATED,
-  AnalysisOptionsWarningCode.ANALYSIS_OPTION_DEPRECATED,
   AnalysisOptionsWarningCode.INCLUDE_FILE_NOT_FOUND,
   AnalysisOptionsWarningCode.INCLUDED_FILE_WARNING,
   AnalysisOptionsWarningCode.INVALID_OPTION,
@@ -304,6 +303,7 @@
   CompileTimeErrorCode.MISSING_CONST_IN_SET_LITERAL,
   CompileTimeErrorCode.MISSING_DART_LIBRARY,
   CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER,
+  CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL,
   CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION,
   CompileTimeErrorCode.MISSING_REQUIRED_ARGUMENT,
   CompileTimeErrorCode.MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE,
@@ -747,6 +747,7 @@
   ParserErrorCode.DUPLICATE_PREFIX,
   ParserErrorCode.DUPLICATED_MODIFIER,
   ParserErrorCode.EMPTY_ENUM_BODY,
+  ParserErrorCode.EMPTY_RECORD_TYPE_NAMED_FIELDS_LIST,
   ParserErrorCode.ENUM_IN_CLASS,
   ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND,
   ParserErrorCode.EXPECTED_BODY,
@@ -757,6 +758,10 @@
   ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD,
   ParserErrorCode.EXPECTED_INSTEAD,
   ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL,
+  ParserErrorCode.EXPECTED_NAMED_TYPE_EXTENDS,
+  ParserErrorCode.EXPECTED_NAMED_TYPE_IMPLEMENTS,
+  ParserErrorCode.EXPECTED_NAMED_TYPE_ON,
+  ParserErrorCode.EXPECTED_NAMED_TYPE_WITH,
   ParserErrorCode.EXPECTED_STRING_LITERAL,
   ParserErrorCode.EXPECTED_TOKEN,
   ParserErrorCode.EXPECTED_TYPE_NAME,
@@ -884,6 +889,9 @@
   ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT,
   ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP,
   ParserErrorCode.PREFIX_AFTER_COMBINATOR,
+  ParserErrorCode.RECORD_LITERAL_EMPTY,
+  ParserErrorCode.RECORD_LITERAL_ONE_POSITIONAL_NO_TRAILING_COMMA,
+  ParserErrorCode.RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA,
   ParserErrorCode.REDIRECTING_CONSTRUCTOR_WITH_BODY,
   ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR,
   ParserErrorCode.SETTER_CONSTRUCTOR,
diff --git a/pkg/analyzer/lib/error/listener.dart b/pkg/analyzer/lib/error/listener.dart
index 4dc82be..79ed12f 100644
--- a/pkg/analyzer/lib/error/listener.dart
+++ b/pkg/analyzer/lib/error/listener.dart
@@ -86,10 +86,10 @@
     // TODO(brianwilkerson) Consider extending this method to take any
     //  declaration and compute the correct range for the name of that
     //  declaration. This might make it easier to be consistent.
-    if (constructor.name2 != null) {
+    if (constructor.name != null) {
       var offset = constructor.returnType.offset;
       reportErrorForOffset(
-          code, offset, constructor.name2!.end - offset, arguments);
+          code, offset, constructor.name!.end - offset, arguments);
     } else {
       reportErrorForNode(code, constructor.returnType, arguments);
     }
diff --git a/pkg/analyzer/lib/src/analysis_options/code_style_options.dart b/pkg/analyzer/lib/src/analysis_options/code_style_options.dart
index 283d133..4225b48 100644
--- a/pkg/analyzer/lib/src/analysis_options/code_style_options.dart
+++ b/pkg/analyzer/lib/src/analysis_options/code_style_options.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/analysis/analysis_options.dart';
 import 'package:analyzer/dart/analysis/code_style_options.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 
 /// The concrete implementation of [CodeStyleOptions].
 class CodeStyleOptionsImpl implements CodeStyleOptions {
@@ -23,11 +24,54 @@
   bool get makeLocalsFinal => _isLintEnabled('prefer_final_locals');
 
   @override
+  String get preferredQuoteForStrings => _lintQuote() ?? "'";
+
+  @override
   bool get sortConstructorsFirst => _isLintEnabled('sort_constructors_first');
 
   @override
   bool get useRelativeUris => _isLintEnabled('prefer_relative_imports');
 
+  @override
+  String preferredQuoteForUris(List<NamespaceDirective> directives) {
+    var lintQuote = _lintQuote();
+    if (lintQuote != null) {
+      return lintQuote;
+    }
+    var singleCount = 0;
+    var doubleCount = 0;
+
+    void add(SimpleStringLiteral literal) {
+      var lexeme = literal.literal.lexeme;
+      if (lexeme.startsWith('"')) {
+        doubleCount++;
+      } else {
+        singleCount++;
+      }
+    }
+
+    for (var directive in directives) {
+      var uri = directive.uri;
+      if (uri is SimpleStringLiteral) {
+        add(uri);
+      } else if (uri is AdjacentStrings) {
+        for (var string in uri.strings) {
+          if (string is SimpleStringLiteral) {
+            add(string);
+          }
+        }
+      }
+    }
+    return doubleCount > singleCount ? '"' : "'";
+  }
+
   /// Return `true` if the lint with the given [name] is enabled.
   bool _isLintEnabled(String name) => options.isLintEnabled(name);
+
+  /// Return the preferred lint quote, otherwise `null`.
+  String? _lintQuote() => _isLintEnabled("prefer_single_quotes")
+      ? "'"
+      : _isLintEnabled("prefer_double_quotes")
+          ? '"'
+          : null;
 }
diff --git a/pkg/analyzer/lib/src/analysis_options/error/option_codes.g.dart b/pkg/analyzer/lib/src/analysis_options/error/option_codes.g.dart
index bfcdc4d..925ddcb 100644
--- a/pkg/analyzer/lib/src/analysis_options/error/option_codes.g.dart
+++ b/pkg/analyzer/lib/src/analysis_options/error/option_codes.g.dart
@@ -109,13 +109,6 @@
 }
 
 class AnalysisOptionsWarningCode extends ErrorCode {
-  ///  An error code indicating that the given option is deprecated.
-  static const AnalysisOptionsWarningCode ANALYSIS_OPTION_DEPRECATED =
-      AnalysisOptionsWarningCode(
-    'ANALYSIS_OPTION_DEPRECATED',
-    "The option '{0}' is no longer supported.",
-  );
-
   ///  An error code indicating a specified include file has a warning.
   ///
   ///  Parameters:
@@ -143,6 +136,10 @@
 
   ///  An error code indicating that a plugin is being configured with an invalid
   ///  value for an option and a detail message is provided.
+  ///
+  ///  Parameters:
+  ///  0: the option name
+  ///  1: the detail message
   static const AnalysisOptionsWarningCode INVALID_OPTION =
       AnalysisOptionsWarningCode(
     'INVALID_OPTION',
diff --git a/pkg/analyzer/lib/src/clients/dart_style/rewrite_cascade.dart b/pkg/analyzer/lib/src/clients/dart_style/rewrite_cascade.dart
index d48d2dd..718a838 100644
--- a/pkg/analyzer/lib/src/clients/dart_style/rewrite_cascade.dart
+++ b/pkg/analyzer/lib/src/clients/dart_style/rewrite_cascade.dart
@@ -25,12 +25,12 @@
       ..next = expressionStatement.semicolon,
   );
 
-  return astFactory.expressionStatement(
-    CascadeExpressionImpl(
+  return ExpressionStatementImpl(
+    expression: CascadeExpressionImpl(
       target: newTarget,
       cascadeSections: cascadeExpression.cascadeSections,
     ),
-    expressionStatement.semicolon,
+    semicolon: expressionStatement.semicolon,
   );
 }
 
@@ -73,20 +73,20 @@
       index: expression.index,
       rightBracket: expression.rightBracket,
     );
-  } else if (expression is MethodInvocation) {
+  } else if (expression is MethodInvocationImpl) {
     var expressionTarget = expression.realTarget!;
-    return astFactory.methodInvocation(
-      insertCascadeTargetIntoExpression(
+    return MethodInvocationImpl(
+      target: insertCascadeTargetIntoExpression(
         expression: expressionTarget,
         cascadeTarget: cascadeTarget,
-      ),
+      ) as ExpressionImpl,
       // If we've reached the end, replace the `..` operator with `.`
-      expressionTarget == cascadeTarget
+      operator: expressionTarget == cascadeTarget
           ? _synthesizeToken(TokenType.PERIOD, expression.operator!)
           : expression.operator,
-      expression.methodName,
-      expression.typeArguments,
-      expression.argumentList,
+      methodName: expression.methodName,
+      typeArguments: expression.typeArguments,
+      argumentList: expression.argumentList,
     );
   } else if (expression is PropertyAccess) {
     var expressionTarget = expression.realTarget;
diff --git a/pkg/analyzer/lib/src/dart/analysis/defined_names.dart b/pkg/analyzer/lib/src/dart/analysis/defined_names.dart
index a9295f5..6aeae87 100644
--- a/pkg/analyzer/lib/src/dart/analysis/defined_names.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/defined_names.dart
@@ -18,23 +18,23 @@
 
   void appendClassMemberName(ClassMember member) {
     if (member is MethodDeclaration) {
-      appendName(names.classMemberNames, member.name2);
+      appendName(names.classMemberNames, member.name);
     } else if (member is FieldDeclaration) {
       for (VariableDeclaration field in member.fields.variables) {
-        appendName(names.classMemberNames, field.name2);
+        appendName(names.classMemberNames, field.name);
       }
     }
   }
 
   void appendTopLevelName(CompilationUnitMember member) {
     if (member is NamedCompilationUnitMember) {
-      appendName(names.topLevelNames, member.name2);
+      appendName(names.topLevelNames, member.name);
       if (member is ClassDeclaration) {
         member.members.forEach(appendClassMemberName);
       }
       if (member is EnumDeclaration) {
         for (var constant in member.constants) {
-          appendName(names.classMemberNames, constant.name2);
+          appendName(names.classMemberNames, constant.name);
         }
         member.members.forEach(appendClassMemberName);
       }
@@ -43,7 +43,7 @@
       }
     } else if (member is TopLevelVariableDeclaration) {
       for (VariableDeclaration variable in member.variables.variables) {
-        appendName(names.topLevelNames, variable.name2);
+        appendName(names.topLevelNames, variable.name);
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 961f677..c570aa4 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -85,7 +85,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 = 239;
+  static const int DATA_VERSION = 241;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
@@ -588,13 +588,6 @@
     return _discoverAvailableFilesTask!.completer.future;
   }
 
-  @Deprecated('Use dispose2() instead')
-  @override
-  void dispose() {
-    _scheduler.remove(this);
-    clearLibraryContext();
-  }
-
   @override
   Future<void> dispose2() async {
     final completer = Completer<void>();
@@ -643,18 +636,6 @@
     return completer.future;
   }
 
-  /// Return a [Future] that completes with the [ErrorsResult] for the Dart
-  /// file with the given [path].
-  ///
-  /// The [path] must be absolute and normalized.
-  ///
-  /// This method does not use analysis priorities, and must not be used in
-  /// interactive analysis, such as Analysis Server or its plugins.
-  @Deprecated('Use getErrors() instead')
-  Future<SomeErrorsResult> getErrors2(String path) async {
-    return getErrors(path);
-  }
-
   /// Return a [Future] that completes with the list of added files that
   /// define a class member with the given [name].
   Future<List<String>> getFilesDefiningClassMemberName(String name) {
@@ -695,14 +676,6 @@
     );
   }
 
-  /// Return the [FileResult] for the Dart file with the given [path].
-  ///
-  /// The [path] must be absolute and normalized.
-  @Deprecated('Use getFileSync() instead')
-  SomeFileResult getFileSync2(String path) {
-    return getFileSync(path);
-  }
-
   /// Return a [Future] that completes with the [AnalysisDriverUnitIndex] for
   /// the file with the given [path], or with `null` if the file cannot be
   /// analyzed.
@@ -768,14 +741,6 @@
     );
   }
 
-  /// 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.
-  @Deprecated('Use getLibraryByUri() instead')
-  Future<SomeLibraryElementResult> getLibraryByUri2(String uri) async {
-    return getLibraryByUri(uri);
-  }
-
   /// Return a [ParsedLibraryResult] for the library with the given [path].
   ///
   /// The [path] must be absolute and normalized.
@@ -948,29 +913,6 @@
     return completer.future;
   }
 
-  /// Return a [Future] that completes with a [SomeResolvedUnitResult] for the
-  /// Dart file with the given [path].  If the file cannot be analyzed,
-  /// the [Future] completes with an [InvalidResult].
-  ///
-  /// The [path] must be absolute and normalized.
-  ///
-  /// The [path] can be any file - explicitly or implicitly analyzed, or neither.
-  ///
-  /// If the driver has the cached analysis result for the file, it is returned.
-  /// If [sendCachedToStream] is `true`, then the result is also reported into
-  /// the [results] stream, just as if it were freshly computed.
-  ///
-  /// Otherwise causes the analysis state to transition to "analyzing" (if it is
-  /// not in that state already), the driver will produce the analysis result for
-  /// it, which is consistent with the current file state (including new states
-  /// of the files previously reported using [changeFile]), prior to the next
-  /// time the analysis state transitions to "idle".
-  @Deprecated('Use getResult() instead')
-  Future<SomeResolvedUnitResult> getResult2(String path,
-      {bool sendCachedToStream = false}) {
-    return getResult(path);
-  }
-
   /// Return a [Future] that completes with the [SomeUnitElementResult]
   /// for the file with the given [path].
   Future<SomeUnitElementResult> getUnitElement(String path) {
@@ -994,21 +936,6 @@
     return completer.future;
   }
 
-  /// Return a [Future] that completes with a [ParsedUnitResult] for the file
-  /// with the given [path].
-  ///
-  /// The [path] must be absolute and normalized.
-  ///
-  /// The [path] can be any file - explicitly or implicitly analyzed, or neither.
-  ///
-  /// The parsing is performed in the method itself, and the result is not
-  /// produced through the [results] stream (just because it is not a fully
-  /// resolved unit).
-  @Deprecated('Use parseFileSync() instead')
-  Future<SomeParsedUnitResult> parseFile2(String path) async {
-    return parseFileSync2(path);
-  }
-
   /// Return a [ParsedUnitResult] for the file with the given [path].
   ///
   /// The [path] must be absolute and normalized.
@@ -1040,20 +967,6 @@
     );
   }
 
-  /// Return a [ParsedUnitResult] for the file with the given [path].
-  ///
-  /// The [path] must be absolute and normalized.
-  ///
-  /// The [path] can be any file - explicitly or implicitly analyzed, or neither.
-  ///
-  /// The parsing is performed in the method itself, and the result is not
-  /// produced through the [results] stream (just because it is not a fully
-  /// resolved unit).
-  @Deprecated('Use parseFile() instead')
-  SomeParsedUnitResult parseFileSync2(String path) {
-    return parseFileSync(path);
-  }
-
   @override
   Future<void> performWork() async {
     _discoverDartCore();
@@ -1762,10 +1675,8 @@
 
     var fileContentMap = <String, String>{};
 
-    var fileContent = '';
     try {
       final file = _fsState.getFileForPath(path);
-      fileContent = file.content;
       final fileKind = file.kind;
       final libraryKind = fileKind.library;
       if (libraryKind != null) {
@@ -1791,7 +1702,6 @@
       ExceptionResult(
         filePath: path,
         fileContentMap: fileContentMap,
-        fileContent: fileContent,
         exception: caught,
         contextKey: contextKey,
       ),
@@ -1964,10 +1874,6 @@
   void addFile(String path);
 
   /// Notify the driver that the client is going to stop using it.
-  @Deprecated('Use dispose2() instead')
-  void dispose();
-
-  /// Notify the driver that the client is going to stop using it.
   Future<void> dispose2();
 
   /// Perform a single chunk of work and produce [results].
@@ -2351,10 +2257,6 @@
   /// The content of the library and its parts.
   final Map<String, String> fileContentMap;
 
-  /// The path of the file being analyzed when the [exception] happened.
-  @Deprecated('Use fileContentMap instead')
-  final String fileContent;
-
   /// The exception during analysis of the file with the [filePath].
   final CaughtException exception;
 
@@ -2367,7 +2269,6 @@
   ExceptionResult({
     required this.filePath,
     required this.fileContentMap,
-    required this.fileContent,
     required this.exception,
     required this.contextKey,
   });
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 9d73f80..18513d5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -33,12 +33,14 @@
   EnableString.non_nullable: ExperimentalFeatures.non_nullable,
   EnableString.nonfunction_type_aliases:
       ExperimentalFeatures.nonfunction_type_aliases,
+  EnableString.patterns: ExperimentalFeatures.patterns,
   EnableString.records: ExperimentalFeatures.records,
   EnableString.set_literals: ExperimentalFeatures.set_literals,
   EnableString.spread_collections: ExperimentalFeatures.spread_collections,
   EnableString.super_parameters: ExperimentalFeatures.super_parameters,
   EnableString.test_experiment: ExperimentalFeatures.test_experiment,
   EnableString.triple_shift: ExperimentalFeatures.triple_shift,
+  EnableString.unnamed_libraries: ExperimentalFeatures.unnamed_libraries,
   EnableString.value_class: ExperimentalFeatures.value_class,
   EnableString.variance: ExperimentalFeatures.variance,
 };
@@ -88,6 +90,9 @@
   /// String to enable the experiment "nonfunction-type-aliases"
   static const String nonfunction_type_aliases = 'nonfunction-type-aliases';
 
+  /// String to enable the experiment "patterns"
+  static const String patterns = 'patterns';
+
   /// String to enable the experiment "records"
   static const String records = 'records';
 
@@ -106,6 +111,9 @@
   /// String to enable the experiment "triple-shift"
   static const String triple_shift = 'triple-shift';
 
+  /// String to enable the experiment "unnamed-libraries"
+  static const String unnamed_libraries = 'unnamed-libraries';
+
   /// String to enable the experiment "value-class"
   static const String value_class = 'value-class';
 
@@ -258,8 +266,18 @@
     releaseVersion: Version.parse('2.13.0'),
   );
 
-  static final records = ExperimentalFeature(
+  static final patterns = ExperimentalFeature(
     index: 14,
+    enableString: EnableString.patterns,
+    isEnabledByDefault: IsEnabledByDefault.patterns,
+    isExpired: IsExpired.patterns,
+    documentation: 'Patterns',
+    experimentalReleaseVersion: null,
+    releaseVersion: null,
+  );
+
+  static final records = ExperimentalFeature(
+    index: 15,
     enableString: EnableString.records,
     isEnabledByDefault: IsEnabledByDefault.records,
     isExpired: IsExpired.records,
@@ -269,7 +287,7 @@
   );
 
   static final set_literals = ExperimentalFeature(
-    index: 15,
+    index: 16,
     enableString: EnableString.set_literals,
     isEnabledByDefault: IsEnabledByDefault.set_literals,
     isExpired: IsExpired.set_literals,
@@ -279,7 +297,7 @@
   );
 
   static final spread_collections = ExperimentalFeature(
-    index: 16,
+    index: 17,
     enableString: EnableString.spread_collections,
     isEnabledByDefault: IsEnabledByDefault.spread_collections,
     isExpired: IsExpired.spread_collections,
@@ -289,7 +307,7 @@
   );
 
   static final super_parameters = ExperimentalFeature(
-    index: 17,
+    index: 18,
     enableString: EnableString.super_parameters,
     isEnabledByDefault: IsEnabledByDefault.super_parameters,
     isExpired: IsExpired.super_parameters,
@@ -299,7 +317,7 @@
   );
 
   static final test_experiment = ExperimentalFeature(
-    index: 18,
+    index: 19,
     enableString: EnableString.test_experiment,
     isEnabledByDefault: IsEnabledByDefault.test_experiment,
     isExpired: IsExpired.test_experiment,
@@ -310,7 +328,7 @@
   );
 
   static final triple_shift = ExperimentalFeature(
-    index: 19,
+    index: 20,
     enableString: EnableString.triple_shift,
     isEnabledByDefault: IsEnabledByDefault.triple_shift,
     isExpired: IsExpired.triple_shift,
@@ -319,8 +337,18 @@
     releaseVersion: Version.parse('2.14.0'),
   );
 
+  static final unnamed_libraries = ExperimentalFeature(
+    index: 21,
+    enableString: EnableString.unnamed_libraries,
+    isEnabledByDefault: IsEnabledByDefault.unnamed_libraries,
+    isExpired: IsExpired.unnamed_libraries,
+    documentation: 'Unnamed libraries',
+    experimentalReleaseVersion: null,
+    releaseVersion: null,
+  );
+
   static final value_class = ExperimentalFeature(
-    index: 20,
+    index: 22,
     enableString: EnableString.value_class,
     isEnabledByDefault: IsEnabledByDefault.value_class,
     isExpired: IsExpired.value_class,
@@ -330,7 +358,7 @@
   );
 
   static final variance = ExperimentalFeature(
-    index: 21,
+    index: 23,
     enableString: EnableString.variance,
     isEnabledByDefault: IsEnabledByDefault.variance,
     isExpired: IsExpired.variance,
@@ -385,6 +413,9 @@
   /// Default state of the experiment "nonfunction-type-aliases"
   static const bool nonfunction_type_aliases = true;
 
+  /// Default state of the experiment "patterns"
+  static const bool patterns = false;
+
   /// Default state of the experiment "records"
   static const bool records = false;
 
@@ -403,6 +434,9 @@
   /// Default state of the experiment "triple-shift"
   static const bool triple_shift = true;
 
+  /// Default state of the experiment "unnamed-libraries"
+  static const bool unnamed_libraries = false;
+
   /// Default state of the experiment "value-class"
   static const bool value_class = false;
 
@@ -456,6 +490,9 @@
   /// Expiration status of the experiment "nonfunction-type-aliases"
   static const bool nonfunction_type_aliases = true;
 
+  /// Expiration status of the experiment "patterns"
+  static const bool patterns = false;
+
   /// Expiration status of the experiment "records"
   static const bool records = false;
 
@@ -474,6 +511,9 @@
   /// Expiration status of the experiment "triple-shift"
   static const bool triple_shift = true;
 
+  /// Expiration status of the experiment "unnamed-libraries"
+  static const bool unnamed_libraries = false;
+
   /// Expiration status of the experiment "value-class"
   static const bool value_class = false;
 
@@ -532,6 +572,9 @@
   bool get nonfunction_type_aliases =>
       isEnabled(ExperimentalFeatures.nonfunction_type_aliases);
 
+  /// Current state for the flag "patterns"
+  bool get patterns => isEnabled(ExperimentalFeatures.patterns);
+
   /// Current state for the flag "records"
   bool get records => isEnabled(ExperimentalFeatures.records);
 
@@ -551,6 +594,10 @@
   /// Current state for the flag "triple-shift"
   bool get triple_shift => isEnabled(ExperimentalFeatures.triple_shift);
 
+  /// Current state for the flag "unnamed-libraries"
+  bool get unnamed_libraries =>
+      isEnabled(ExperimentalFeatures.unnamed_libraries);
+
   /// Current state for the flag "value-class"
   bool get value_class => isEnabled(ExperimentalFeatures.value_class);
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 9ca390f..346739d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -460,7 +460,7 @@
   }
 
   File get resource {
-    return _fsState._resourceProvider.getFile(path);
+    return _fsState.resourceProvider.getFile(path);
   }
 
   @visibleForTesting
@@ -872,7 +872,7 @@
         }
       } else if (directive is LibraryDirective) {
         libraryDirective = UnlinkedLibraryDirective(
-          name: directive.name.name,
+          name: directive.name2?.name,
         );
       } else if (directive is PartDirective) {
         parts.add(
@@ -910,13 +910,13 @@
         if (declaration.macroKeyword != null) {
           var constructors = declaration.members
               .whereType<ConstructorDeclaration>()
-              .map((e) => e.name2?.lexeme ?? '')
+              .map((e) => e.name?.lexeme ?? '')
               .where((e) => !e.startsWith('_'))
               .toList();
           if (constructors.isNotEmpty) {
             macroClasses.add(
               MacroClass(
-                name: declaration.name2.lexeme,
+                name: declaration.name.lexeme,
                 constructors: constructors,
               ),
             );
@@ -940,21 +940,21 @@
     final topLevelDeclarations = <String>{};
     for (final declaration in unit.declarations) {
       if (declaration is ClassDeclaration) {
-        topLevelDeclarations.add(declaration.name2.lexeme);
+        topLevelDeclarations.add(declaration.name.lexeme);
       } else if (declaration is EnumDeclaration) {
-        topLevelDeclarations.add(declaration.name2.lexeme);
+        topLevelDeclarations.add(declaration.name.lexeme);
       } else if (declaration is ExtensionDeclaration) {
-        var name = declaration.name2;
+        var name = declaration.name;
         if (name != null) {
           topLevelDeclarations.add(name.lexeme);
         }
       } else if (declaration is FunctionDeclaration) {
-        topLevelDeclarations.add(declaration.name2.lexeme);
+        topLevelDeclarations.add(declaration.name.lexeme);
       } else if (declaration is MixinDeclaration) {
-        topLevelDeclarations.add(declaration.name2.lexeme);
+        topLevelDeclarations.add(declaration.name.lexeme);
       } else if (declaration is TopLevelVariableDeclaration) {
         for (var variable in declaration.variables.variables) {
-          topLevelDeclarations.add(variable.name2.lexeme);
+          topLevelDeclarations.add(variable.name.lexeme);
         }
       }
     }
@@ -1085,7 +1085,7 @@
 /// Information about known file system state.
 class FileSystemState {
   final PerformanceLog _logger;
-  final ResourceProvider _resourceProvider;
+  final ResourceProvider resourceProvider;
   final String contextName;
   final ByteStore _byteStore;
   final SourceFactory _sourceFactory;
@@ -1137,7 +1137,7 @@
   FileSystemState(
     this._logger,
     this._byteStore,
-    this._resourceProvider,
+    this.resourceProvider,
     this.contextName,
     this._sourceFactory,
     this._workspace,
@@ -1153,7 +1153,7 @@
     _testView = FileSystemStateTestView(this);
   }
 
-  package_path.Context get pathContext => _resourceProvider.pathContext;
+  package_path.Context get pathContext => resourceProvider.pathContext;
 
   @visibleForTesting
   FileSystemStateTestView get test => _testView;
@@ -1262,7 +1262,7 @@
   }) {
     var file = _pathToFile[path];
     if (file == null) {
-      File resource = _resourceProvider.getFile(path);
+      File resource = resourceProvider.getFile(path);
       Uri uri = _sourceFactory.pathToUri(path)!;
       file = _newFile(resource, path, uri);
     }
@@ -1305,7 +1305,7 @@
         return Either2.t1(file);
       }
 
-      File resource = _resourceProvider.getFile(path);
+      File resource = resourceProvider.getFile(path);
 
       var rewrittenUri = rewriteToCanonicalUri(_sourceFactory, uri);
       if (rewrittenUri == null) {
@@ -2147,7 +2147,7 @@
   @visibleForTesting
   void discoverLibraries() {
     if (libraries.isEmpty) {
-      var resourceProvider = file._fsState._resourceProvider;
+      var resourceProvider = file._fsState.resourceProvider;
       var pathContext = resourceProvider.pathContext;
 
       var siblings = <Resource>[];
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 4102286..9ccf01c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -19,7 +19,7 @@
   SimpleIdentifier node,
   Element? element,
 ) {
-  if (element == null || element.enclosingElement3 != null) {
+  if (element == null || element.enclosingElement != null) {
     return element;
   }
 
@@ -64,7 +64,7 @@
 /// Return the [CompilationUnitElement] that should be used for [element].
 /// Throw [StateError] if the [element] is not linked into a unit.
 CompilationUnitElement getUnitElement(Element element) {
-  for (Element? e = element; e != null; e = e.enclosingElement3) {
+  for (Element? e = element; e != null; e = e.enclosingElement) {
     if (e is CompilationUnitElement) {
       return e;
     }
@@ -89,21 +89,21 @@
     String? parameterName;
     if (element is ParameterElement) {
       parameterName = element.name;
-      element = element.enclosingElement3!;
+      element = element.enclosingElement!;
     }
 
     String? classMemberName;
-    if (element.enclosingElement3 is ClassElement ||
-        element.enclosingElement3 is ExtensionElement) {
+    if (element.enclosingElement is InterfaceElement ||
+        element.enclosingElement is ExtensionElement) {
       classMemberName = element.name;
-      element = element.enclosingElement3!;
+      element = element.enclosingElement!;
     }
 
     String? unitMemberName;
-    if (element.enclosingElement3 is CompilationUnitElement) {
+    if (element.enclosingElement is CompilationUnitElement) {
       unitMemberName = element.name;
       if (element is ExtensionElement && unitMemberName == null) {
-        var enclosingUnit = element.enclosingElement3;
+        var enclosingUnit = element.enclosingElement;
         var indexOf = enclosingUnit.extensions.indexOf(element);
         unitMemberName = 'extension-$indexOf';
       }
@@ -140,7 +140,7 @@
     } else if (element.isSynthetic) {
       if (elementKind == ElementKind.CONSTRUCTOR) {
         kind = IndexSyntheticElementKind.constructor;
-        element = element.enclosingElement3!;
+        element = element.enclosingElement!;
       } else if (element is FunctionElement &&
           element.name == FunctionElement.LOAD_LIBRARY_NAME) {
         kind = IndexSyntheticElementKind.loadLibrary;
@@ -152,7 +152,7 @@
       } else if (elementKind == ElementKind.GETTER ||
           elementKind == ElementKind.SETTER) {
         var accessor = element as PropertyAccessorElement;
-        Element enclosing = element.enclosingElement3;
+        Element enclosing = element.enclosingElement;
         bool isEnumGetter = enclosing is EnumElement;
         if (isEnumGetter && accessor.name == 'index') {
           kind = IndexSyntheticElementKind.enumIndex;
@@ -167,7 +167,7 @@
           element = accessor.variable;
         }
       } else if (element is MethodElement) {
-        Element enclosing = element.enclosingElement3;
+        Element enclosing = element.enclosingElement;
         bool isEnumMethod = enclosing is EnumElement;
         if (isEnumMethod && element.name == 'toString') {
           kind = IndexSyntheticElementKind.enumToString;
@@ -447,7 +447,7 @@
   _IndexContributor(this.assembler);
 
   void recordIsAncestorOf(InterfaceElement descendant) {
-    _recordIsAncestorOf(descendant, descendant, false, <ClassElement>[]);
+    _recordIsAncestorOf(descendant, descendant, false, <InterfaceElement>[]);
   }
 
   /// Record that the name [node] has a relation of the given [kind].
@@ -492,14 +492,14 @@
         elementKind == ElementKind.TYPE_PARAMETER ||
         elementKind == ElementKind.FUNCTION &&
             element is FunctionElement &&
-            element.enclosingElement3 is ExecutableElement ||
+            element.enclosingElement is ExecutableElement ||
         false) {
       return;
     }
     // Ignore named parameters of synthetic functions, e.g. created for LUB.
     // These functions are not bound to a source, we cannot index them.
     if (elementKind == ElementKind.PARAMETER && element is ParameterElement) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement == null || enclosingElement.isSynthetic) {
         return;
       }
@@ -509,7 +509,7 @@
     // named parameters. Ignore them.
     if (elementKind == ElementKind.PARAMETER &&
         element is ParameterElement &&
-        element.enclosingElement3 is GenericFunctionTypeElement) {
+        element.enclosingElement is GenericFunctionTypeElement) {
       return;
     }
     // Add the relation.
@@ -561,11 +561,11 @@
   @override
   void visitClassDeclaration(ClassDeclaration node) {
     _addSubtypeForClassDeclaration(node);
-    var declaredElement = node.declaredElement2!;
+    var declaredElement = node.declaredElement!;
     if (node.extendsClause == null) {
       final objectElement = declaredElement.supertype?.element2;
       recordRelationOffset(objectElement, IndexRelationKind.IS_EXTENDED_BY,
-          node.name2.offset, 0, true);
+          node.name.offset, 0, true);
     }
     recordIsAncestorOf(declaredElement);
     super.visitClassDeclaration(node);
@@ -574,7 +574,7 @@
   @override
   void visitClassTypeAlias(ClassTypeAlias node) {
     _addSubtypeForClassTypeAlis(node);
-    recordIsAncestorOf(node.declaredElement2!);
+    recordIsAncestorOf(node.declaredElement!);
     super.visitClassTypeAlias(node);
   }
 
@@ -655,7 +655,7 @@
         offset = constructorSelector.period.offset;
         length = constructorSelector.name.end - offset;
       } else {
-        offset = node.name2.end;
+        offset = node.name.end;
         length = 0;
       }
       recordRelationOffset(
@@ -675,13 +675,13 @@
   @override
   void visitEnumDeclaration(EnumDeclaration node) {
     _addSubtype(
-      node.name2.lexeme,
+      node.name.lexeme,
       withClause: node.withClause,
       implementsClause: node.implementsClause,
       memberNodes: node.members,
     );
 
-    var declaredElement = node.declaredElement2!;
+    var declaredElement = node.declaredElement!;
     recordIsAncestorOf(declaredElement);
     super.visitEnumDeclaration(node);
   }
@@ -758,7 +758,7 @@
       recordNameRelation(name, IndexRelationKind.IS_INVOKED_BY, isQualified);
     }
     // element invocation
-    IndexRelationKind kind = element is ClassElement
+    IndexRelationKind kind = element is InterfaceElement
         ? IndexRelationKind.IS_REFERENCED_BY
         : IndexRelationKind.IS_INVOKED_BY;
     recordRelation(element, kind, name, isQualified);
@@ -770,7 +770,7 @@
   @override
   void visitMixinDeclaration(MixinDeclaration node) {
     _addSubtypeForMixinDeclaration(node);
-    recordIsAncestorOf(node.declaredElement2!);
+    recordIsAncestorOf(node.declaredElement!);
     super.visitMixinDeclaration(node);
   }
 
@@ -859,12 +859,6 @@
       }
       recordNameRelation(node, kind, isQualified);
     }
-    // this.field parameter
-    if (element is FieldFormalParameterElement) {
-      IndexRelationKind kind = IndexRelationKind.IS_REFERENCED_BY;
-      recordRelation(element.field, kind, node, true);
-      return;
-    }
     // ignore a local reference to a parameter
     if (element is ParameterElement && node.parent is! Label) {
       return;
@@ -921,15 +915,15 @@
     List<String> supertypes = [];
     List<String> members = [];
 
-    String getClassElementId(ClassElement element) {
+    String getInterfaceElementId(InterfaceElement element) {
       return '${element.library.source.uri};'
           '${element.source.uri};${element.name}';
     }
 
     void addSupertype(NamedType? type) {
       var element = type?.name.staticElement;
-      if (element is ClassElement) {
-        String id = getClassElementId(element);
+      if (element is InterfaceElement) {
+        String id = getInterfaceElementId(element);
         supertypes.add(id);
       }
     }
@@ -948,10 +942,10 @@
 
     for (ClassMember member in memberNodes) {
       if (member is MethodDeclaration && !member.isStatic) {
-        addMemberName(member.name2);
+        addMemberName(member.name);
       } else if (member is FieldDeclaration && !member.isStatic) {
         for (var field in member.fields.variables) {
-          addMemberName(field.name2);
+          addMemberName(field.name);
         }
       }
     }
@@ -964,7 +958,7 @@
 
   /// Record the given class as a subclass of its direct superclasses.
   void _addSubtypeForClassDeclaration(ClassDeclaration node) {
-    _addSubtype(node.name2.lexeme,
+    _addSubtype(node.name.lexeme,
         superclass: node.extendsClause?.superclass,
         withClause: node.withClause,
         implementsClause: node.implementsClause,
@@ -973,7 +967,7 @@
 
   /// Record the given class as a subclass of its direct superclasses.
   void _addSubtypeForClassTypeAlis(ClassTypeAlias node) {
-    _addSubtype(node.name2.lexeme,
+    _addSubtype(node.name.lexeme,
         superclass: node.superclass,
         withClause: node.withClause,
         implementsClause: node.implementsClause,
@@ -982,7 +976,7 @@
 
   /// Record the given mixin as a subclass of its direct superclasses.
   void _addSubtypeForMixinDeclaration(MixinDeclaration node) {
-    _addSubtype(node.name2.lexeme,
+    _addSubtype(node.name.lexeme,
         onClause: node.onClause,
         implementsClause: node.implementsClause,
         memberNodes: node.members);
@@ -995,7 +989,7 @@
       ConstructorElement? constructor) {
     var seenConstructors = <ConstructorElement?>{};
     while (constructor is ConstructorElementImpl && constructor.isSynthetic) {
-      var enclosing = constructor.enclosingElement3;
+      var enclosing = constructor.enclosingElement;
       if (enclosing is ClassElement && enclosing.isMixinApplication) {
         var superInvocation = constructor.constantInitializers
             .whereType<SuperConstructorInvocation>()
@@ -1037,12 +1031,10 @@
           ancestor, IndexRelationKind.IS_ANCESTOR_OF, offset, length, false);
     }
     {
-      if (ancestor is ClassElement) {
-        var superType = ancestor.supertype;
-        if (superType != null) {
-          _recordIsAncestorOf(
-              descendant, superType.element2, true, visitedElements);
-        }
+      var superType = ancestor.supertype;
+      if (superType != null) {
+        _recordIsAncestorOf(
+            descendant, superType.element2, true, visitedElements);
       }
     }
     for (InterfaceType mixinType in ancestor.mixins) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 3481ec5..fdf249d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -160,6 +160,7 @@
         var canResolveNode = resolverVisitor.prepareForResolving(nodeToResolve);
         if (canResolveNode) {
           nodeToResolve.accept(resolverVisitor);
+          resolverVisitor.checkIdle();
           return AnalysisForCompletionResult(
             parsedUnit: parsedUnit,
             resolvedNodes: [nodeToResolve],
@@ -580,14 +581,6 @@
   }) {
     directive.element = element;
 
-    final uriState = state.uri;
-    if (uriState is DirectiveUriWithString) {
-      // ignore: deprecated_member_use_from_same_package
-      directive.uriContent = uriState.relativeUriStr;
-      // ignore: deprecated_member_use_from_same_package
-      directive.uriSource = uriState.source;
-    }
-
     final AugmentationFileKind? importedAugmentationKind;
     if (state is AugmentationImportWithFile) {
       importedAugmentationKind = state.importedAugmentation;
@@ -643,8 +636,6 @@
     units[augmentationFile] = augmentationUnit;
 
     final importedAugmentation = element.importedAugmentation!;
-    // ignore: deprecated_member_use_from_same_package
-    directive.uriSource = importedAugmentation.source;
     augmentationUnit.element = importedAugmentation.definingCompilationUnit;
 
     for (final directive in augmentationUnit.directives) {
@@ -713,7 +704,7 @@
         directive.element = containerElement;
       } else if (directive is LibraryDirectiveImpl) {
         directive.element = containerElement;
-        libraryNameNode = directive.name;
+        libraryNameNode = directive.name2;
       } else if (directive is PartDirectiveImpl) {
         if (containerKind is LibraryFileKind &&
             containerElement is LibraryElementImpl) {
@@ -899,20 +890,6 @@
       final node = configurationNodes[i] as ConfigurationImpl;
       node.resolvedUri = configurationUris[i].asDirectiveUri;
     }
-
-    if (primaryUriState is DirectiveUriWithString) {
-      // ignore: deprecated_member_use_from_same_package
-      directive.uriContent = primaryUriState.relativeUriStr;
-      // ignore: deprecated_member_use_from_same_package
-      directive.uriSource = primaryUriState.source;
-    }
-
-    if (selectedUriState is DirectiveUriWithString) {
-      // ignore: deprecated_member_use_from_same_package
-      directive.selectedUriContent = selectedUriState.relativeUriStr;
-      // ignore: deprecated_member_use_from_same_package
-      directive.selectedSource = selectedUriState.source;
-    }
   }
 
   void _resolvePartDirective({
@@ -926,8 +903,6 @@
   }) {
     StringLiteral partUri = directive.uri;
 
-    // ignore: deprecated_member_use_from_same_package
-    directive.uriSource = partState.includedSource;
     directive.element = partElement;
 
     if (partState is! PartWithUriStr) {
@@ -1012,8 +987,6 @@
     }
 
     final partSource = includedKind.file.source;
-    // ignore: deprecated_member_use_from_same_package
-    directive.uriSource = partSource;
 
     for (final directive in partUnit.directives) {
       if (directive is PartOfDirectiveImpl) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart b/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart
index 5f37b84..83a4f1a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart
@@ -65,7 +65,7 @@
     _LocalNameScope scope = _LocalNameScope(enclosing);
     for (Statement statement in node.statements) {
       if (statement is FunctionDeclarationStatement) {
-        scope.add(statement.functionDeclaration.name2);
+        scope.add(statement.functionDeclaration.name);
       } else if (statement is VariableDeclarationStatement) {
         scope.addVariableNames(statement.variables);
       }
@@ -81,7 +81,7 @@
       if (member is FieldDeclaration) {
         scope.addVariableNames(member.fields);
       } else if (member is MethodDeclaration) {
-        scope.add(member.name2);
+        scope.add(member.name);
       }
     }
     return scope;
@@ -128,7 +128,7 @@
     _LocalNameScope scope = _LocalNameScope(null);
     for (CompilationUnitMember declaration in node.declarations) {
       if (declaration is NamedCompilationUnitMember) {
-        scope.add(declaration.name2);
+        scope.add(declaration.name);
       } else if (declaration is TopLevelVariableDeclaration) {
         scope.addVariableNames(declaration.variables);
       }
@@ -152,13 +152,13 @@
 
   void addTypeParameters(TypeParameterList? typeParameterList) {
     if (typeParameterList != null) {
-      typeParameterList.typeParameters.map((p) => p.name2).forEach(add);
+      typeParameterList.typeParameters.map((p) => p.name).forEach(add);
     }
   }
 
   void addVariableNames(VariableDeclarationList variableList) {
     for (VariableDeclaration variable in variableList.variables) {
-      add(variable.name2);
+      add(variable.name);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/results.dart b/pkg/analyzer/lib/src/dart/analysis/results.dart
index 38e6cc0..5c352da 100644
--- a/pkg/analyzer/lib/src/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/results.dart
@@ -342,28 +342,28 @@
       return;
     }
 
-    if (element is ClassElement) {
+    if (element is InterfaceElement) {
       if (node is ClassDeclaration) {
-        if (_hasOffset2(node.name2)) {
+        if (_hasOffset2(node.name)) {
           result = node;
         }
       } else if (node is ClassTypeAlias) {
-        if (_hasOffset2(node.name2)) {
+        if (_hasOffset2(node.name)) {
           result = node;
         }
       } else if (node is EnumDeclaration) {
-        if (_hasOffset2(node.name2)) {
+        if (_hasOffset2(node.name)) {
           result = node;
         }
       } else if (node is MixinDeclaration) {
-        if (_hasOffset2(node.name2)) {
+        if (_hasOffset2(node.name)) {
           result = node;
         }
       }
     } else if (element is ConstructorElement) {
       if (node is ConstructorDeclaration) {
-        if (node.name2 != null) {
-          if (_hasOffset2(node.name2)) {
+        if (node.name != null) {
+          if (_hasOffset2(node.name)) {
             result = node;
           }
         } else {
@@ -374,30 +374,30 @@
       }
     } else if (element is ExtensionElement) {
       if (node is ExtensionDeclaration) {
-        if (_hasOffset2(node.name2)) {
+        if (_hasOffset2(node.name)) {
           result = node;
         }
       }
     } else if (element is FieldElement) {
       if (node is EnumConstantDeclaration) {
-        if (_hasOffset2(node.name2)) {
+        if (_hasOffset2(node.name)) {
           result = node;
         }
       } else if (node is VariableDeclaration) {
-        if (_hasOffset2(node.name2)) {
+        if (_hasOffset2(node.name)) {
           result = node;
         }
       }
     } else if (element is FunctionElement) {
-      if (node is FunctionDeclaration && _hasOffset2(node.name2)) {
+      if (node is FunctionDeclaration && _hasOffset2(node.name)) {
         result = node;
       }
     } else if (element is LocalVariableElement) {
-      if (node is VariableDeclaration && _hasOffset2(node.name2)) {
+      if (node is VariableDeclaration && _hasOffset2(node.name)) {
         result = node;
       }
     } else if (element is MethodElement) {
-      if (node is MethodDeclaration && _hasOffset2(node.name2)) {
+      if (node is MethodDeclaration && _hasOffset2(node.name)) {
         result = node;
       }
     } else if (element is ParameterElement) {
@@ -406,16 +406,16 @@
       }
     } else if (element is PropertyAccessorElement) {
       if (node is FunctionDeclaration) {
-        if (_hasOffset2(node.name2)) {
+        if (_hasOffset2(node.name)) {
           result = node;
         }
       } else if (node is MethodDeclaration) {
-        if (_hasOffset2(node.name2)) {
+        if (_hasOffset2(node.name)) {
           result = node;
         }
       }
     } else if (element is TopLevelVariableElement) {
-      if (node is VariableDeclaration && _hasOffset2(node.name2)) {
+      if (node is VariableDeclaration && _hasOffset2(node.name)) {
         result = node;
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index d166d04..cdbf4140 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -132,6 +132,38 @@
   VARIABLE
 }
 
+/// Searches through files known to [drivers] for declarations.
+///
+/// If files are known to multiple drivers, they will be searched only within
+/// the context of the first.
+class FindDeclarations {
+  final List<AnalysisDriver> drivers;
+  final WorkspaceSymbols result;
+  final int? maxResults;
+  final RegExp? regExp;
+  final String? onlyForFile;
+
+  FindDeclarations(this.drivers, this.result, this.regExp, this.maxResults,
+      {this.onlyForFile});
+
+  Future<void> compute([CancellationToken? cancellationToken]) async {
+    var searchedFiles = SearchedFiles();
+    await Future.wait(drivers.map((driver) => driver.discoverAvailableFiles()));
+    // Add analyzed files first, so priority is given to drivers that analyze
+    // files over those that just reference them.
+    for (var driver in drivers) {
+      searchedFiles.ownAnalyzed(driver.search);
+    }
+    for (var driver in drivers) {
+      searchedFiles.ownKnown(driver.search);
+    }
+
+    await _FindDeclarations(searchedFiles, result, regExp, maxResults,
+            onlyForFile: onlyForFile)
+        .compute(cancellationToken);
+  }
+}
+
 /// Visitor that adds [SearchResult]s for references to the [importElement].
 class ImportElementReferencesVisitor extends RecursiveAstVisitor<void> {
   final List<SearchResult> results = <SearchResult>[];
@@ -232,15 +264,6 @@
     return elements;
   }
 
-  /// Add matching declarations to the [result].
-  Future<void> declarations(
-      WorkspaceSymbols result, RegExp? regExp, int? maxResults,
-      {String? onlyForFile, CancellationToken? cancellationToken}) async {
-    await _FindDeclarations(_driver, result, regExp, maxResults,
-            onlyForFile: onlyForFile)
-        .compute(cancellationToken);
-  }
-
   /// Returns references to the [element].
   Future<List<SearchResult>> references(
       Element? element, SearchedFiles searchedFiles) async {
@@ -249,8 +272,8 @@
     }
 
     ElementKind kind = element.kind;
-    if (element is ClassElement ||
-        element is ExtensionElement ||
+    if (element is ExtensionElement ||
+        element is InterfaceElement ||
         element is PropertyAccessorElement && element.isSetter ||
         element is TypeAliasElement) {
       return _searchReferences(element, searchedFiles);
@@ -263,7 +286,7 @@
     } else if (element is PropertyInducingElement) {
       return _searchReferences_Field(element, searchedFiles);
     } else if (kind == ElementKind.FUNCTION || kind == ElementKind.METHOD) {
-      if (element.enclosingElement3 is ExecutableElement) {
+      if (element.enclosingElement is ExecutableElement) {
         return _searchReferences_Local(
             element, (n) => n is Block, searchedFiles);
       }
@@ -411,7 +434,7 @@
     // Prepare the element name.
     String name = element.displayName;
     if (element is ConstructorElement) {
-      name = element.enclosingElement3.displayName;
+      name = element.enclosingElement.displayName;
     }
 
     // Prepare the list of files that reference the element name.
@@ -660,7 +683,7 @@
     ));
     if (parameter.isNamed ||
         parameter.isOptionalPositional ||
-        parameter.enclosingElement3 is ConstructorElement) {
+        parameter.enclosingElement is ConstructorElement) {
       results.addAll(await _searchReferences(parameter, searchedFiles));
     }
     return results;
@@ -694,12 +717,18 @@
   final Map<Uri, Search> uriOwners = {};
 
   bool add(String path, Search search) {
-    var file = search._driver.fsState.getFileForPath(path);
+    final fsState = search._driver.fsState;
+    final file = fsState.resourceProvider.getFile(path);
+    final fileState = fsState.getExisting(file);
+    if (fileState == null) {
+      return false;
+    }
+
     var pathOwner = pathOwners[path];
-    var uriOwner = uriOwners[file.uri];
+    var uriOwner = uriOwners[fileState.uri];
     if (pathOwner == null && uriOwner == null) {
       pathOwners[path] = search;
-      uriOwners[file.uri] = search;
+      uriOwners[fileState.uri] = search;
       return true;
     }
     return identical(pathOwner, search) && identical(uriOwner, search);
@@ -712,6 +741,14 @@
       }
     }
   }
+
+  void ownKnown(Search search) {
+    for (var path in search._driver.knownFiles) {
+      if (path.endsWith('.dart')) {
+        add(path, search);
+      }
+    }
+  }
 }
 
 /// A single search result.
@@ -831,96 +868,78 @@
   }
 }
 
-class _FindDeclarations {
-  final AnalysisDriver driver;
+class _FindCompilationUnitDeclarations {
+  final CompilationUnitElement unit;
+  final String filePath;
+  final LineInfo lineInfo;
   final WorkspaceSymbols result;
   final int? maxResults;
   final RegExp? regExp;
-  final String? onlyForFile;
+  final void Function(Declaration) collect;
 
-  _FindDeclarations(this.driver, this.result, this.regExp, this.maxResults,
-      {this.onlyForFile});
+  _FindCompilationUnitDeclarations(
+    this.unit,
+    this.filePath,
+    this.result,
+    this.maxResults,
+    this.regExp,
+    this.collect,
+  ) : lineInfo = unit.lineInfo;
 
-  /// Add matching declarations to the [result].
-  Future<void> compute(CancellationToken? cancellationToken) async {
+  void compute(CancellationToken? cancellationToken) {
     if (result.hasMoreDeclarationsThan(maxResults)) {
       return;
     }
 
-    await driver.discoverAvailableFiles();
-
-    if (cancellationToken != null &&
-        cancellationToken.isCancellationRequested) {
-      result.cancelled = true;
-      return;
-    }
-
-    var knownFiles = driver.fsState.knownFiles.toList();
-    var filesProcessed = 0;
-    try {
-      for (var file in knownFiles) {
-        var elementResult = await driver.getLibraryByUri(file.uriStr);
-        if (elementResult is LibraryElementResult) {
-          _addUnits(file, elementResult.element.units);
-        }
-
-        // Periodically yield and check cancellation token.
-        if (cancellationToken != null && (filesProcessed++) % 20 == 0) {
-          await null; // allow cancellation requests to be processed.
-          if (cancellationToken.isCancellationRequested) {
-            result.cancelled = true;
-            return;
-          }
-        }
-      }
-    } on _MaxNumberOfDeclarationsError {
-      return;
-    }
+    _addAccessors(unit.accessors);
+    _addClasses(unit.classes);
+    _addClasses(unit.enums2);
+    _addClasses(unit.mixins2);
+    _addExtensions(unit.extensions);
+    _addFunctions(unit.functions);
+    _addTypeAliases(unit.typeAliases);
+    _addVariables(unit.topLevelVariables);
   }
 
-  void _addAccessors(FileState file, List<PropertyAccessorElement> elements) {
+  void _addAccessors(List<PropertyAccessorElement> elements) {
     for (var i = 0; i < elements.length; i++) {
       var element = elements[i];
       if (!element.isSynthetic) {
-        _addDeclaration(file, element, element.displayName);
+        _addDeclaration(element, element.displayName);
       }
     }
   }
 
-  void _addClasses(FileState file, List<InterfaceElement> elements) {
+  void _addClasses(List<InterfaceElement> elements) {
     for (var i = 0; i < elements.length; i++) {
       var element = elements[i];
-      _addDeclaration(file, element, element.name);
-      _addAccessors(file, element.accessors);
-      _addConstructors(file, element.constructors);
-      _addFields(file, element.fields);
-      _addMethods(file, element.methods);
+      _addDeclaration(element, element.name);
+      _addAccessors(element.accessors);
+      _addConstructors(element.constructors);
+      _addFields(element.fields);
+      _addMethods(element.methods);
     }
   }
 
-  void _addConstructors(FileState file, List<ConstructorElement> elements) {
+  void _addConstructors(List<ConstructorElement> elements) {
     for (var i = 0; i < elements.length; i++) {
       var element = elements[i];
       if (!element.isSynthetic) {
-        _addDeclaration(file, element, element.name);
+        _addDeclaration(element, element.name);
       }
     }
   }
 
-  void _addDeclaration(FileState file, Element element, String name) {
+  void _addDeclaration(Element element, String name) {
     if (result.hasMoreDeclarationsThan(maxResults)) {
       throw const _MaxNumberOfDeclarationsError();
     }
 
-    if (onlyForFile != null && file.path != onlyForFile) {
-      return;
-    }
-
     if (regExp != null && !regExp!.hasMatch(name)) {
       return;
     }
 
-    var enclosing = element.enclosingElement3;
+    var enclosing = element.enclosingElement;
 
     String? className;
     String? mixinName;
@@ -928,7 +947,7 @@
       // skip
     } else if (enclosing is MixinElement) {
       mixinName = enclosing.name;
-    } else if (enclosing is ClassElement) {
+    } else if (enclosing is InterfaceElement) {
       className = enclosing.name;
     }
 
@@ -948,12 +967,12 @@
 
     element as ElementImpl; // to access codeOffset/codeLength
     var locationOffset = element.nameOffset;
-    var locationStart = file.lineInfo.getLocation(locationOffset);
+    var locationStart = lineInfo.getLocation(locationOffset);
 
-    result.declarations.add(
+    collect(
       Declaration(
-        result._getPathIndex(file.path),
-        file.lineInfo,
+        result._getPathIndex(filePath),
+        lineInfo,
         name,
         kind,
         locationOffset,
@@ -968,73 +987,124 @@
     );
   }
 
-  void _addExtensions(FileState file, List<ExtensionElement> elements) {
+  void _addExtensions(List<ExtensionElement> elements) {
     for (var i = 0; i < elements.length; i++) {
       var element = elements[i];
       var name = element.name;
       if (name != null) {
-        _addDeclaration(file, element, name);
+        _addDeclaration(element, name);
       }
-      _addAccessors(file, element.accessors);
-      _addFields(file, element.fields);
-      _addMethods(file, element.methods);
+      _addAccessors(element.accessors);
+      _addFields(element.fields);
+      _addMethods(element.methods);
     }
   }
 
-  void _addFields(FileState file, List<FieldElement> elements) {
+  void _addFields(List<FieldElement> elements) {
     for (var i = 0; i < elements.length; i++) {
       var element = elements[i];
       if (!element.isSynthetic) {
-        _addDeclaration(file, element, element.name);
+        _addDeclaration(element, element.name);
       }
     }
   }
 
-  void _addFunctions(FileState file, List<FunctionElement> elements) {
+  void _addFunctions(List<FunctionElement> elements) {
     for (var i = 0; i < elements.length; i++) {
       var element = elements[i];
-      _addDeclaration(file, element, element.name);
+      _addDeclaration(element, element.name);
     }
   }
 
-  void _addMethods(FileState file, List<MethodElement> elements) {
+  void _addMethods(List<MethodElement> elements) {
     for (var i = 0; i < elements.length; i++) {
       var element = elements[i];
-      _addDeclaration(file, element, element.name);
+      _addDeclaration(element, element.name);
     }
   }
 
-  void _addTypeAliases(FileState file, List<TypeAliasElement> elements) {
+  void _addTypeAliases(List<TypeAliasElement> elements) {
     for (var i = 0; i < elements.length; i++) {
       var element = elements[i];
-      _addDeclaration(file, element, element.name);
+      _addDeclaration(element, element.name);
     }
   }
 
-  void _addUnits(FileState file, List<CompilationUnitElement> elements) {
-    for (var i = 0; i < elements.length; i++) {
-      var element = elements[i];
-      _addAccessors(file, element.accessors);
-      _addClasses(file, element.classes);
-      _addClasses(file, element.enums2);
-      _addClasses(file, element.mixins2);
-      _addExtensions(file, element.extensions);
-      _addFunctions(file, element.functions);
-      _addTypeAliases(file, element.typeAliases);
-      _addVariables(file, element.topLevelVariables);
-    }
-  }
-
-  void _addVariables(FileState file, List<TopLevelVariableElement> elements) {
+  void _addVariables(List<TopLevelVariableElement> elements) {
     for (var i = 0; i < elements.length; i++) {
       var element = elements[i];
       if (!element.isSynthetic) {
-        _addDeclaration(file, element, element.name);
+        _addDeclaration(element, element.name);
       }
     }
   }
 }
 
+/// Searches through [files] for declarations.
+class _FindDeclarations {
+  final SearchedFiles files;
+  final WorkspaceSymbols result;
+  final int? maxResults;
+  final RegExp? regExp;
+  final String? onlyForFile;
+
+  _FindDeclarations(this.files, this.result, this.regExp, this.maxResults,
+      {this.onlyForFile});
+
+  /// Add matching declarations to the [result].
+  Future<void> compute(CancellationToken? cancellationToken) async {
+    if (result.hasMoreDeclarationsThan(maxResults)) {
+      return;
+    }
+
+    if (cancellationToken != null &&
+        cancellationToken.isCancellationRequested) {
+      result.cancelled = true;
+      return;
+    }
+
+    var filesProcessed = 0;
+    try {
+      for (var entry in files.uriOwners.entries) {
+        var uri = entry.key;
+        var search = entry.value;
+        var elementResult =
+            await search._driver.getLibraryByUri(uri.toString());
+        if (elementResult is LibraryElementResult) {
+          var units = elementResult.element.units;
+          for (var i = 0; i < units.length; i++) {
+            var unit = units[i];
+            var filePath = unit.source.fullName;
+            if (onlyForFile != null && filePath != onlyForFile) {
+              continue;
+            }
+            var finder = _FindCompilationUnitDeclarations(
+              unit,
+              filePath,
+              result,
+              maxResults,
+              regExp,
+              result.declarations.add,
+            );
+            finder.compute(cancellationToken);
+          }
+        }
+
+        // Periodically yield and check cancellation token.
+        if (cancellationToken != null && (filesProcessed++) % 20 == 0) {
+          await null; // allow cancellation requests to be processed.
+          if (cancellationToken.isCancellationRequested) {
+            result.cancelled = true;
+            return;
+          }
+        }
+      }
+    } on _MaxNumberOfDeclarationsError {
+      return;
+    }
+  }
+}
+
 class _IndexRequest {
   final AnalysisDriverUnitIndex index;
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/session_helper.dart b/pkg/analyzer/lib/src/dart/analysis/session_helper.dart
index a7bc83a..5c91570 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session_helper.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session_helper.dart
@@ -41,6 +41,34 @@
     return resolvedLibrary?.getElementDeclaration(element);
   }
 
+  /// Return the [EnumElement] with the given [className] that is exported
+  /// from the library with the given [libraryUri], or `null` if the library
+  /// does not export a class with such name.
+  Future<EnumElement?> getEnum(String libraryUri, String className) async {
+    var libraryResult = await session.getLibraryByUri(libraryUri);
+    if (libraryResult is LibraryElementResult) {
+      var element = libraryResult.element.exportNamespace.get(className);
+      if (element is EnumElement) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  /// Return the [MixinElement] with the given [name] that is exported
+  /// from the library with the given [libraryUri], or `null` if the library
+  /// does not export a class with such name.
+  Future<MixinElement?> getMixin(String libraryUri, String name) async {
+    var libraryResult = await session.getLibraryByUri(libraryUri);
+    if (libraryResult is LibraryElementResult) {
+      var element = libraryResult.element.exportNamespace.get(name);
+      if (element is MixinElement) {
+        return element;
+      }
+    }
+    return null;
+  }
+
   /// Return the resolved unit that declares the given [element].
   Future<ResolvedUnitResult?> getResolvedUnitByElement(Element element) async {
     var libraryPath = element.library!.source.fullName;
diff --git a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
index b32db67..25d679a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
@@ -49,7 +49,7 @@
         var functionExpression = declaration.functionExpression;
         _addTokens(
           declaration.beginToken,
-          functionExpression.parameters?.endToken ?? declaration.name2,
+          functionExpression.parameters?.endToken ?? declaration.name,
         );
         _addFunctionBodyModifiers(functionExpression.body);
       } else if (declaration is MixinDeclaration) {
@@ -140,7 +140,7 @@
     signature.addInt(_kindMethodDeclaration);
     _addTokens(
       node.beginToken,
-      node.parameters?.endToken ?? node.name2,
+      node.parameters?.endToken ?? node.name,
     );
     signature.addBool(node.body is EmptyFunctionBody);
     _addFunctionBodyModifiers(node.body);
@@ -219,7 +219,7 @@
     signature.addInt(variables.length);
 
     for (var variable in variables) {
-      _addToken(variable.name2);
+      _addToken(variable.name);
       signature.addBool(variable.initializer != null);
       if (includeInitializers) {
         _addNode(variable.initializer);
diff --git a/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart b/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
index 8ce40c0..f5c3072 100644
--- a/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
@@ -181,7 +181,7 @@
 }
 
 class UnlinkedLibraryDirective {
-  final String name;
+  final String? name;
 
   UnlinkedLibraryDirective({
     required this.name,
@@ -191,12 +191,12 @@
     SummaryDataReader reader,
   ) {
     return UnlinkedLibraryDirective(
-      name: reader.readStringUtf8(),
+      name: reader.readOptionalStringUtf8(),
     );
   }
 
   void write(BufferedSink sink) {
-    sink.writeStringUtf8(name);
+    sink.writeOptionalStringUtf8(name);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index d35be48..10c5411 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -5,6 +5,8 @@
 import 'dart:collection';
 import 'dart:math' as math;
 
+import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart';
+import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/precedence.dart';
@@ -13,15 +15,14 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/scope.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/ast/to_source_visitor.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/resolver/typed_literal_resolver.dart';
 import 'package:analyzer/src/fasta/token_utils.dart' as util show findPrevious;
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
+import 'package:analyzer/src/generated/source.dart' show LineInfo;
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/utilities/extensions/object.dart';
 import 'package:meta/meta.dart';
 
 /// Two or more string literals that are implicitly concatenated because of
@@ -63,7 +64,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitAdjacentStrings(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitAdjacentStrings(this, contextType: contextType);
   }
 
@@ -485,7 +486,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitAsExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitAsExpression(this, contextType: contextType);
   }
 
@@ -754,7 +755,7 @@
       visitor.visitAssignmentExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitAssignmentExpression(this, contextType: contextType);
   }
 
@@ -915,12 +916,6 @@
     _becomeParentOf(_uri);
   }
 
-  @Deprecated('Use element2 instead')
-  @override
-  AugmentationImportElement? get element {
-    throw StateError('Use element2 instead');
-  }
-
   @override
   AugmentationImportElement? get element2 {
     return super.element2 as AugmentationImportElement?;
@@ -932,16 +927,6 @@
   @override
   Token get firstTokenAfterCommentAndMetadata => importKeyword;
 
-  @Deprecated('Use specific xyzToken instead')
-  @override
-  Token get keyword => importKeyword;
-
-  @Deprecated('Use element2.uri instead')
-  @override
-  LibraryAugmentationElement? get uriElement {
-    return element2?.importedAugmentation;
-  }
-
   @override
   ChildEntities get _childEntities => super._childEntities
     ..addToken('importKeyword', importKeyword)
@@ -1002,7 +987,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitAwaitExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitAwaitExpression(this, contextType: contextType);
   }
 
@@ -1080,7 +1065,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitBinaryExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitBinaryExpression(this, contextType: contextType);
   }
 
@@ -1091,6 +1076,64 @@
   }
 }
 
+/// A binary (infix) pattern.
+///
+///    binaryPattern ::=
+///        [DartPattern] ('|' | '&') [DartPattern]
+@experimental
+class BinaryPatternImpl extends DartPatternImpl implements BinaryPattern {
+  @override
+  final DartPatternImpl leftOperand;
+
+  @override
+  final Token operator;
+
+  @override
+  final DartPatternImpl rightOperand;
+
+  BinaryPatternImpl(
+      {required this.leftOperand,
+      required this.operator,
+      required this.rightOperand}) {
+    _becomeParentOf(leftOperand);
+    _becomeParentOf(rightOperand);
+  }
+
+  @override
+  Token get beginToken => leftOperand.beginToken;
+
+  @override
+  Token get endToken => rightOperand.endToken;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('leftOperand', leftOperand)
+    ..addToken('operator', operator)
+    ..addNode('rightOperand', rightOperand);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitBinaryPattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/50066
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    leftOperand.accept(visitor);
+    rightOperand.accept(visitor);
+  }
+}
+
 /// A function body that consists of a block of statements.
 ///
 ///    blockFunctionBody ::=
@@ -1253,7 +1296,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitBooleanLiteral(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitBooleanLiteral(this, contextType: contextType);
   }
 
@@ -1396,7 +1439,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitCascadeExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitCascadeExpression(this, contextType: contextType);
   }
 
@@ -1412,6 +1455,108 @@
   }
 }
 
+/// The `case` clause that can optionally appear in an `if` statement.
+///
+///    caseClause ::=
+///        'case' [DartPattern] [WhenClause]?
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+class CaseClauseImpl extends AstNodeImpl implements CaseClause {
+  @override
+  final WhenClauseImpl? whenClause;
+
+  @override
+  final Token caseKeyword;
+
+  @override
+  final DartPatternImpl pattern;
+
+  CaseClauseImpl(
+      {required this.caseKeyword,
+      required this.pattern,
+      required this.whenClause});
+
+  @override
+  Token get beginToken => caseKeyword;
+
+  @override
+  Token get endToken => whenClause?.endToken ?? pattern.endToken;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('caseKeyword', caseKeyword)
+    ..addNode('pattern', pattern)
+    ..addNode('whenClause', whenClause);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitCaseClause(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    pattern.accept(visitor);
+    whenClause?.accept(visitor);
+  }
+}
+
+/// A cast pattern.
+///
+///    castPattern ::=
+///        [DartPattern] 'as' [TypeAnnotation]
+@experimental
+class CastPatternImpl extends DartPatternImpl implements CastPattern {
+  @override
+  final Token asToken;
+
+  @override
+  final DartPatternImpl pattern;
+
+  @override
+  final TypeAnnotationImpl type;
+
+  CastPatternImpl(
+      {required this.pattern, required this.asToken, required this.type}) {
+    _becomeParentOf(pattern);
+    _becomeParentOf(type);
+  }
+
+  @override
+  Token get beginToken => pattern.beginToken;
+
+  @override
+  Token get endToken => type.endToken;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('pattern', pattern)
+    ..addToken('asToken', asToken)
+    ..addNode('type', type);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitCastPattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    type.accept(resolverVisitor);
+    resolverVisitor.analyzeCastPattern(
+        matchedType, typeInfos, context, pattern, type.typeOrThrow);
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    pattern.accept(visitor);
+    type.accept(visitor);
+  }
+}
+
 /// A catch clause within a try statement.
 ///
 ///    onPart ::=
@@ -1502,12 +1647,6 @@
   @override
   Token get endToken => _body.endToken;
 
-  @Deprecated('Use exceptionParameter2 instead')
-  @override
-  SimpleIdentifierImpl? get exceptionParameter {
-    return _exceptionParameter?.nameNode;
-  }
-
   @override
   CatchClauseParameterImpl? get exceptionParameter2 {
     return _exceptionParameter;
@@ -1525,12 +1664,6 @@
     _exceptionType = _becomeParentOf(exceptionType as TypeAnnotationImpl?);
   }
 
-  @Deprecated('Use stackTraceParameter2 instead')
-  @override
-  SimpleIdentifierImpl? get stackTraceParameter {
-    return _stackTraceParameter?.nameNode;
-  }
-
   @override
   CatchClauseParameterImpl? get stackTraceParameter2 {
     return _stackTraceParameter;
@@ -1567,17 +1700,15 @@
 
 class CatchClauseParameterImpl extends AstNodeImpl
     implements CatchClauseParameter {
-  /// TODO(scheglov) Eventually replace with [Token].
-  final SimpleIdentifierImpl nameNode;
+  @override
+  final Token name;
 
   @override
   LocalVariableElement? declaredElement;
 
   CatchClauseParameterImpl({
-    required this.nameNode,
-  }) {
-    _becomeParentOf(nameNode);
-  }
+    required this.name,
+  });
 
   @override
   Token get beginToken => name;
@@ -1586,17 +1717,12 @@
   Token get endToken => name;
 
   @override
-  Token get name => nameNode.token;
-
-  @override
   E? accept<E>(AstVisitor<E> visitor) {
     return visitor.visitCatchClauseParameter(this);
   }
 
   @override
-  void visitChildren(AstVisitor visitor) {
-    nameNode.accept(visitor);
-  }
+  void visitChildren(AstVisitor visitor) {}
 }
 
 /// Helper class to allow iteration of child entities of an AST node.
@@ -1684,8 +1810,7 @@
 ///        ([ExtendsClause] [WithClause]?)?
 ///        [ImplementsClause]?
 ///        '{' [ClassMember]* '}'
-// ignore: deprecated_member_use_from_same_package
-class ClassDeclarationImpl extends ClassOrMixinDeclarationImpl
+class ClassDeclarationImpl extends NamedCompilationUnitMemberImpl
     implements ClassDeclaration {
   /// The 'abstract' keyword, or `null` if the keyword was absent.
   @override
@@ -1705,16 +1830,35 @@
   /// any other class.
   ExtendsClauseImpl? _extendsClause;
 
+  /// The type parameters for the class or mixin,
+  /// or `null` if the declaration does not have any type parameters.
+  TypeParameterListImpl? _typeParameters;
+
   /// The with clause for the class, or `null` if the class does not have a with
   /// clause.
   WithClauseImpl? _withClause;
 
+  /// The implements clause for the class or mixin,
+  /// or `null` if the declaration does not implement any interfaces.
+  ImplementsClauseImpl? _implementsClause;
+
   /// The native clause for the class, or `null` if the class does not have a
   /// native clause.
   NativeClauseImpl? _nativeClause;
 
   @override
-  ClassElement? declaredElement2;
+  ClassElement? declaredElement;
+
+  /// The left curly bracket.
+  @override
+  Token leftBracket;
+
+  /// The members defined by the class or mixin.
+  final NodeListImpl<ClassMember> _members = NodeListImpl._();
+
+  /// The right curly bracket.
+  @override
+  Token rightBracket;
 
   /// Initialize a newly created class declaration. Either or both of the
   /// [comment] and [metadata] can be `null` if the class does not have the
@@ -1732,22 +1876,33 @@
     required this.augmentKeyword,
     required this.classKeyword,
     required super.name,
-    required super.typeParameters,
+    required TypeParameterListImpl? typeParameters,
     required ExtendsClauseImpl? extendsClause,
     required WithClauseImpl? withClause,
-    required super.implementsClause,
-    required super.leftBracket,
-    required super.members,
-    required super.rightBracket,
-  })  : _extendsClause = extendsClause,
-        _withClause = withClause {
+    required ImplementsClauseImpl? implementsClause,
+    required NativeClauseImpl? nativeClause,
+    required this.leftBracket,
+    required List<ClassMember> members,
+    required this.rightBracket,
+  })  : _typeParameters = typeParameters,
+        _extendsClause = extendsClause,
+        _withClause = withClause,
+        _implementsClause = implementsClause,
+        _nativeClause = nativeClause {
+    _becomeParentOf(_typeParameters);
     _becomeParentOf(_extendsClause);
     _becomeParentOf(_withClause);
+    _becomeParentOf(_implementsClause);
+    _becomeParentOf(_nativeClause);
+    _members._initialize(this, members);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  ClassElement? get declaredElement => declaredElement2;
+  ClassElement? get declaredElement2 => declaredElement;
+
+  @override
+  Token get endToken => rightBracket;
 
   @override
   ExtendsClauseImpl? get extendsClause => _extendsClause;
@@ -1761,9 +1916,16 @@
     return abstractKeyword ?? macroKeyword ?? augmentKeyword ?? classKeyword;
   }
 
-  @Deprecated('Use abstractKeyword instead')
   @override
-  bool get isAbstract => abstractKeyword != null;
+  ImplementsClauseImpl? get implementsClause => _implementsClause;
+
+  set implementsClause(ImplementsClause? implementsClause) {
+    _implementsClause =
+        _becomeParentOf(implementsClause as ImplementsClauseImpl?);
+  }
+
+  @override
+  NodeListImpl<ClassMember> get members => _members;
 
   @override
   NativeClauseImpl? get nativeClause => _nativeClause;
@@ -1773,6 +1935,13 @@
   }
 
   @override
+  TypeParameterListImpl? get typeParameters => _typeParameters;
+
+  set typeParameters(TypeParameterList? typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters as TypeParameterListImpl?);
+  }
+
+  @override
   WithClauseImpl? get withClause => _withClause;
 
   set withClause(WithClause? withClause) {
@@ -1785,7 +1954,7 @@
     ..addToken('macroKeyword', macroKeyword)
     ..addToken('augmentKeyword', augmentKeyword)
     ..addToken('classKeyword', classKeyword)
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('typeParameters', typeParameters)
     ..addNode('extendsClause', extendsClause)
     ..addNode('withClause', withClause)
@@ -1798,31 +1967,9 @@
   @override
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitClassDeclaration(this);
 
-  @Deprecated('Filter members instead')
-  @override
-  ConstructorDeclaration? getConstructor(String? name) {
-    int length = _members.length;
-    for (int i = 0; i < length; i++) {
-      ClassMember classMember = _members[i];
-      if (classMember is ConstructorDeclaration) {
-        ConstructorDeclaration constructor = classMember;
-        SimpleIdentifier? constructorName = constructor.name;
-        if (name == null && constructorName == null) {
-          return constructor;
-        }
-        if (constructorName != null && constructorName.name == name) {
-          return constructor;
-        }
-      }
-    }
-    return null;
-  }
-
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     _typeParameters?.accept(visitor);
     _extendsClause?.accept(visitor);
     _withClause?.accept(visitor);
@@ -1843,104 +1990,6 @@
   });
 }
 
-@Deprecated('Use ClassDeclaration or MixinDeclaration directly')
-abstract class ClassOrMixinDeclarationImpl
-    extends NamedCompilationUnitMemberImpl implements ClassOrMixinDeclaration {
-  /// The type parameters for the class or mixin,
-  /// or `null` if the declaration does not have any type parameters.
-  TypeParameterListImpl? _typeParameters;
-
-  /// The implements clause for the class or mixin,
-  /// or `null` if the declaration does not implement any interfaces.
-  ImplementsClauseImpl? _implementsClause;
-
-  /// The left curly bracket.
-  @override
-  Token leftBracket;
-
-  /// The members defined by the class or mixin.
-  final NodeListImpl<ClassMember> _members = NodeListImpl._();
-
-  /// The right curly bracket.
-  @override
-  Token rightBracket;
-
-  ClassOrMixinDeclarationImpl({
-    required super.comment,
-    required super.metadata,
-    required super.name,
-    required TypeParameterListImpl? typeParameters,
-    required ImplementsClauseImpl? implementsClause,
-    required this.leftBracket,
-    required List<ClassMember> members,
-    required this.rightBracket,
-  })  : _typeParameters = typeParameters,
-        _implementsClause = implementsClause {
-    _becomeParentOf(_typeParameters);
-    _becomeParentOf(_implementsClause);
-    _members._initialize(this, members);
-  }
-
-  @override
-  Token get endToken => rightBracket;
-
-  @override
-  ImplementsClauseImpl? get implementsClause => _implementsClause;
-
-  set implementsClause(ImplementsClause? implementsClause) {
-    _implementsClause =
-        _becomeParentOf(implementsClause as ImplementsClauseImpl?);
-  }
-
-  @override
-  NodeListImpl<ClassMember> get members => _members;
-
-  @override
-  TypeParameterListImpl? get typeParameters => _typeParameters;
-
-  set typeParameters(TypeParameterList? typeParameters) {
-    _typeParameters = _becomeParentOf(typeParameters as TypeParameterListImpl?);
-  }
-
-  @Deprecated('Filter members instead')
-  @override
-  VariableDeclaration? getField(String name) {
-    int memberLength = _members.length;
-    for (int i = 0; i < memberLength; i++) {
-      ClassMember classMember = _members[i];
-      if (classMember is FieldDeclaration) {
-        FieldDeclaration fieldDeclaration = classMember;
-        NodeList<VariableDeclaration> fields =
-            fieldDeclaration.fields.variables;
-        int fieldLength = fields.length;
-        for (int i = 0; i < fieldLength; i++) {
-          VariableDeclaration field = fields[i];
-          if (name == field.name.name) {
-            return field;
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  @Deprecated('Filter members instead')
-  @override
-  MethodDeclaration? getMethod(String name) {
-    int length = _members.length;
-    for (int i = 0; i < length; i++) {
-      ClassMember classMember = _members[i];
-      if (classMember is MethodDeclaration) {
-        MethodDeclaration method = classMember;
-        if (name == method.name2.lexeme) {
-          return method;
-        }
-      }
-    }
-    return null;
-  }
-}
-
 /// A class type alias.
 ///
 ///    classTypeAlias ::=
@@ -1982,7 +2031,7 @@
   ImplementsClauseImpl? _implementsClause;
 
   @override
-  ClassElement? declaredElement2;
+  ClassElement? declaredElement;
 
   /// Initialize a newly created class type alias. Either or both of the
   /// [comment] and [metadata] can be `null` if the class type alias does not
@@ -2014,9 +2063,9 @@
     _becomeParentOf(_implementsClause);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  ClassElement? get declaredElement => declaredElement2;
+  ClassElement? get declaredElement2 => declaredElement;
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
@@ -2031,10 +2080,6 @@
         _becomeParentOf(implementsClause as ImplementsClauseImpl?);
   }
 
-  @Deprecated('Use abstractKeyword instead')
-  @override
-  bool get isAbstract => abstractKeyword != null;
-
   @override
   NamedTypeImpl get superclass => _superclass;
 
@@ -2042,10 +2087,6 @@
     _superclass = _becomeParentOf(superclass as NamedTypeImpl);
   }
 
-  @Deprecated('Use superclass instead')
-  @override
-  NamedTypeImpl get superclass2 => _superclass;
-
   @override
   TypeParameterListImpl? get typeParameters => _typeParameters;
 
@@ -2063,7 +2104,7 @@
   @override
   ChildEntities get _childEntities => super._childEntities
     ..addToken('typedefKeyword', typedefKeyword)
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('typeParameters', typeParameters)
     ..addToken('equals', equals)
     ..addToken('abstractKeyword', abstractKeyword)
@@ -2080,8 +2121,6 @@
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     _typeParameters?.accept(visitor);
     _superclass.accept(visitor);
     _withClause.accept(visitor);
@@ -2109,7 +2148,9 @@
   Token keyword;
 
   /// Initialize a newly created combinator.
-  CombinatorImpl(this.keyword);
+  CombinatorImpl({
+    required this.keyword,
+  });
 
   @override
   Token get beginToken => keyword;
@@ -2256,15 +2297,6 @@
   }
 
   @override
-  @Deprecated('Use expression instead')
-  IdentifierImpl get identifier => _expression as IdentifierImpl;
-
-  @Deprecated('Use expression= instead')
-  set identifier(Identifier identifier) {
-    _expression = _becomeParentOf(identifier as CommentReferableExpressionImpl);
-  }
-
-  @override
   ChildEntities get _childEntities => ChildEntities()
     ..addToken('newKeyword', newKeyword)
     ..addNode('expression', expression);
@@ -2411,7 +2443,7 @@
   int get offset => 0;
 
   @override
-  ScriptTag? get scriptTag => _scriptTag;
+  ScriptTagImpl? get scriptTag => _scriptTag;
 
   set scriptTag(ScriptTag? scriptTag) {
     _scriptTag = _becomeParentOf(scriptTag as ScriptTagImpl?);
@@ -2581,7 +2613,7 @@
       visitor.visitConditionalExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitConditionalExpression(this, contextType: contextType);
   }
 
@@ -2661,12 +2693,6 @@
     _uri = _becomeParentOf(uri as StringLiteralImpl);
   }
 
-  @Deprecated('Use resolvedUri instead')
-  @override
-  Source? get uriSource {
-    return resolvedUri?.ifTypeOrNull<DirectiveUriWithSource>()?.source;
-  }
-
   @override
   StringLiteralImpl? get value => _value;
 
@@ -2708,6 +2734,63 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
+/// An expression being used as a pattern.
+///
+/// The only expressions that can be validly used as a pattern are `bool`,
+/// `double`, `int`, `null`, and `String` literals and references to constant
+/// variables.
+///
+/// This node is also used to recover from cases where a different kind of
+/// expression is used as a pattern, so clients need to handle the case where
+/// the expression is not one of the valid alternatives.
+///
+///    constantPattern ::=
+///        'const'? [Expression]
+@experimental
+class ConstantPatternImpl extends DartPatternImpl implements ConstantPattern {
+  @override
+  final Token? constKeyword;
+
+  @override
+  ExpressionImpl expression;
+
+  ConstantPatternImpl({required this.constKeyword, required this.expression}) {
+    _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => expression.beginToken;
+
+  @override
+  Token get endToken => expression.endToken;
+
+  @override
+  ChildEntities get _childEntities =>
+      super._childEntities..addNode('expression', expression);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitConstantPattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    resolverVisitor.analyzeExpression(expression, matchedType);
+    expression = resolverVisitor.popRewrite()!;
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    expression.accept(visitor);
+  }
+}
+
 /// A constructor declaration.
 ///
 ///    constructorDeclaration ::=
@@ -2759,7 +2842,8 @@
 
   /// The name of the constructor, or `null` if the constructor being declared
   /// is unnamed.
-  SimpleIdentifierImpl? _name;
+  @override
+  Token? name;
 
   /// The parameters associated with the constructor.
   FormalParameterListImpl _parameters;
@@ -2783,14 +2867,14 @@
   /// structure has not been resolved or if this constructor could not be
   /// resolved.
   @override
-  ConstructorElement? declaredElement2;
+  ConstructorElement? declaredElement;
 
   /// Initialize a newly created constructor declaration. The [externalKeyword]
   /// can be `null` if the constructor is not external. Either or both of the
   /// [comment] and [metadata] can be `null` if the constructor does not have
   /// the corresponding attribute. The [constKeyword] can be `null` if the
   /// constructor cannot be used to create a constant. The [factoryKeyword] can
-  /// be `null` if the constructor is not a factory. The [period] and [name2] can
+  /// be `null` if the constructor is not a factory. The [period] and [name] can
   /// both be `null` if the constructor is not a named constructor. The
   /// [separator] can be `null` if the constructor does not have any
   /// initializers and does not redirect to a different constructor. The list of
@@ -2806,19 +2890,17 @@
     required this.factoryKeyword,
     required IdentifierImpl returnType,
     required this.period,
-    required SimpleIdentifierImpl? name,
+    required this.name,
     required FormalParameterListImpl parameters,
     required this.separator,
     required List<ConstructorInitializer>? initializers,
     required ConstructorNameImpl? redirectedConstructor,
     required FunctionBodyImpl body,
   })  : _returnType = returnType,
-        _name = name,
         _parameters = parameters,
         _redirectedConstructor = redirectedConstructor,
         _body = body {
     _becomeParentOf(_returnType);
-    _becomeParentOf(_name);
     _becomeParentOf(_parameters);
     _initializers._initialize(this, initializers);
     _becomeParentOf(_redirectedConstructor);
@@ -2832,9 +2914,9 @@
     _body = _becomeParentOf(functionBody as FunctionBodyImpl);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  ConstructorElement? get declaredElement => declaredElement2;
+  ConstructorElement? get declaredElement2 => declaredElement;
 
   @override
   Token get endToken {
@@ -2851,19 +2933,9 @@
   @override
   NodeListImpl<ConstructorInitializer> get initializers => _initializers;
 
-  @Deprecated('Use name2 instead')
+  @Deprecated('Use name instead')
   @override
-  SimpleIdentifierImpl? get name {
-    _name?.staticElement = declaredElement;
-    return _name;
-  }
-
-  set name(SimpleIdentifier? name) {
-    _name = _becomeParentOf(name as SimpleIdentifierImpl);
-  }
-
-  @override
-  Token? get name2 => _name?.token;
+  Token? get name2 => name;
 
   @override
   FormalParameterListImpl get parameters => _parameters;
@@ -2894,7 +2966,7 @@
     ..addToken('factoryKeyword', factoryKeyword)
     ..addNode('returnType', returnType)
     ..addToken('period', period)
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('parameters', parameters)
     ..addToken('separator', separator)
     ..addNodeList('initializers', initializers)
@@ -2909,7 +2981,6 @@
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
     _returnType.accept(visitor);
-    _name?.accept(visitor);
     _parameters.accept(visitor);
     _initializers.accept(visitor);
     _redirectedConstructor?.accept(visitor);
@@ -3070,10 +3141,6 @@
     _type = _becomeParentOf(type as NamedTypeImpl);
   }
 
-  @Deprecated('Use type instead')
-  @override
-  NamedTypeImpl get type2 => _type;
-
   @override
   ChildEntities get _childEntities => ChildEntities()
     ..addNode('type', type)
@@ -3131,7 +3198,7 @@
       visitor.visitConstructorReference(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitConstructorReference(this, contextType: contextType);
   }
 
@@ -3239,6 +3306,38 @@
   }
 }
 
+/// A pattern.
+///
+///    pattern ::=
+///        [BinaryPattern]
+///      | [ConstantPattern]
+///      | [CastPattern]
+///      | [ExtractorPattern]
+///      | [ListPattern]
+///      | [LiteralPattern]
+///      | [MapPattern]
+///      | [RecordPattern]
+///      | [RelationalPattern]
+///      | [UnaryPattern]
+///      | [VariablePattern]
+@experimental
+abstract class DartPatternImpl extends AstNodeImpl implements DartPattern {
+  DartPatternImpl();
+
+  @override
+  // TODO(brianwilkerson) Remove this and implement it in subclasses when we
+  //  have constants for pattern-related precedence values.
+  Precedence get precedence => throw UnimplementedError();
+
+  DartType computePatternSchema(ResolverVisitor resolverVisitor);
+
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context);
+}
+
 /// A node that represents the declaration of one or more names. Each declared
 /// name is visible within a name scope.
 abstract class DeclarationImpl extends AnnotatedNodeImpl
@@ -3267,11 +3366,11 @@
   /// does not have a declared type.
   TypeAnnotationImpl? _type;
 
-  /// The name of the variable being declared.
-  SimpleIdentifierImpl _identifier;
+  @override
+  Token name;
 
   @override
-  LocalVariableElement? declaredElement2;
+  LocalVariableElement? declaredElement;
 
   /// Initialize a newly created formal parameter. Either or both of the
   /// [comment] and [metadata] can be `null` if the declaration does not have
@@ -3282,34 +3381,21 @@
     required super.metadata,
     required this.keyword,
     required TypeAnnotationImpl? type,
-    required SimpleIdentifierImpl identifier,
-  })  : _type = type,
-        _identifier = identifier {
+    required this.name,
+  }) : _type = type {
     _becomeParentOf(_type);
-    _becomeParentOf(_identifier);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  LocalVariableElement? get declaredElement => declaredElement2;
+  LocalVariableElement? get declaredElement2 => declaredElement;
 
   @override
-  Token get endToken => _identifier.endToken;
+  Token get endToken => name;
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
-    return keyword ?? _type?.beginToken ?? _identifier.beginToken;
-  }
-
-  @Deprecated('Use name2 instead')
-  @override
-  SimpleIdentifierImpl get identifier {
-    _identifier.staticElement = declaredElement;
-    return _identifier;
-  }
-
-  set identifier(SimpleIdentifier identifier) {
-    _identifier = _becomeParentOf(identifier as SimpleIdentifierImpl);
+    return keyword ?? _type?.beginToken ?? name;
   }
 
   @override
@@ -3319,9 +3405,6 @@
   bool get isFinal => keyword?.keyword == Keyword.FINAL;
 
   @override
-  Token get name => _identifier.token;
-
-  @override
   TypeAnnotationImpl? get type => _type;
 
   set type(TypeAnnotation? type) {
@@ -3341,8 +3424,6 @@
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
     _type?.accept(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    identifier.accept(visitor);
   }
 }
 
@@ -3426,10 +3507,6 @@
     return _parameter.endToken;
   }
 
-  @Deprecated('Use name instead')
-  @override
-  SimpleIdentifierImpl? get identifier => _parameter.identifier;
-
   @override
   bool get isConst => _parameter.isConst;
 
@@ -3494,10 +3571,6 @@
     required super.metadata,
   });
 
-  @Deprecated('Use element2 instead')
-  @override
-  Element? get element => _element;
-
   /// Set the element associated with this directive to be the given [element].
   set element(Element? element) {
     _element = element;
@@ -3668,7 +3741,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitDoubleLiteral(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitDoubleLiteral(this, contextType: contextType);
   }
 
@@ -3804,11 +3877,11 @@
 /// The declaration of an enum constant.
 class EnumConstantDeclarationImpl extends DeclarationImpl
     implements EnumConstantDeclaration {
-  /// The name of the constant.
-  SimpleIdentifierImpl _name;
+  @override
+  final Token name;
 
   @override
-  FieldElement? declaredElement2;
+  FieldElement? declaredElement;
 
   @override
   final EnumConstantArgumentsImpl? arguments;
@@ -3822,40 +3895,29 @@
   EnumConstantDeclarationImpl({
     required super.comment,
     required super.metadata,
-    required SimpleIdentifierImpl name,
+    required this.name,
     required this.arguments,
-  }) : _name = name {
-    _becomeParentOf(_name);
+  }) {
     _becomeParentOf(arguments);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  FieldElement? get declaredElement => declaredElement2;
+  FieldElement? get declaredElement2 => declaredElement;
 
   @override
-  Token get endToken => (arguments ?? _name).endToken;
+  Token get endToken => arguments?.endToken ?? name;
 
   @override
-  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
+  Token get firstTokenAfterCommentAndMetadata => name;
 
-  @Deprecated('Use name2 instead')
+  @Deprecated('Use name instead')
   @override
-  SimpleIdentifierImpl get name {
-    _name.staticElement = declaredElement;
-    return _name;
-  }
-
-  set name(SimpleIdentifier name) {
-    _name = _becomeParentOf(name as SimpleIdentifierImpl);
-  }
-
-  @override
-  Token get name2 => _name.token;
+  Token get name2 => name;
 
   @override
   ChildEntities get _childEntities => super._childEntities
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('arguments', arguments);
 
   @override
@@ -3865,8 +3927,6 @@
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     arguments?.accept(visitor);
   }
 }
@@ -3913,7 +3973,7 @@
   Token rightBracket;
 
   @override
-  EnumElement? declaredElement2;
+  EnumElement? declaredElement;
 
   /// Initialize a newly created enumeration declaration. Either or both of the
   /// [comment] and [metadata] can be `null` if the declaration does not have
@@ -3945,9 +4005,9 @@
   @override
   NodeListImpl<EnumConstantDeclaration> get constants => _constants;
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  ClassElement? get declaredElement => declaredElement2 as ClassElement?;
+  EnumElement? get declaredElement2 => declaredElement;
 
   @override
   Token get endToken => rightBracket;
@@ -3984,7 +4044,7 @@
   // TODO(brianwilkerson) Add commas?
   ChildEntities get _childEntities => super._childEntities
     ..addToken('enumKeyword', enumKeyword)
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('typeParameters', typeParameters)
     ..addNode('withClause', withClause)
     ..addNode('implementsClause', implementsClause)
@@ -4000,8 +4060,6 @@
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     _typeParameters?.accept(visitor);
     _withClause?.accept(visitor);
     _implementsClause?.accept(visitor);
@@ -4010,15 +4068,6 @@
   }
 }
 
-/// Ephemeral identifiers are created as needed to mimic the presence of an
-/// empty identifier.
-class EphemeralIdentifier extends SimpleIdentifierImpl {
-  EphemeralIdentifier(AstNode parent, int location)
-      : super(StringToken(TokenType.IDENTIFIER, "", location)) {
-    (parent as AstNodeImpl)._becomeParentOf(this);
-  }
-}
-
 /// An export directive.
 ///
 ///    exportDirective ::=
@@ -4042,32 +4091,14 @@
     required super.semicolon,
   });
 
-  @Deprecated('Use element2 instead')
   @override
-  ExportElement? get element {
-    final element2 = this.element2;
-    if (element2 is LibraryExportElementImpl) {
-      return ExportElementImpl(element2);
-    }
-    return null;
+  LibraryExportElementImpl? get element2 {
+    return super.element2 as LibraryExportElementImpl?;
   }
 
   @override
-  LibraryExportElement? get element2 => super.element2 as LibraryExportElement?;
-
-  @override
   Token get firstTokenAfterCommentAndMetadata => exportKeyword;
 
-  @Deprecated('Use specific xyzToken instead')
-  @override
-  Token get keyword => exportKeyword;
-
-  @Deprecated('Use element2.uri instead')
-  @override
-  LibraryElement? get uriElement {
-    return element2?.exportedLibrary;
-  }
-
   @override
   ChildEntities get _childEntities => super._childEntities
     ..addToken('exportKeyword', exportKeyword)
@@ -4206,8 +4237,7 @@
         child is MapLiteralEntry ||
         child is SpreadElement ||
         child is IfElement ||
-        child is ForElement ||
-        child is RecordLiteral) {
+        child is ForElement) {
       var parent = child.parent;
       if (parent is ConstantContextForExpressionImpl) {
         return true;
@@ -4223,6 +4253,8 @@
       } else if (parent is Annotation) {
         // Inside an annotation.
         return true;
+      } else if (parent is RecordLiteral && parent.constKeyword != null) {
+        return true;
       } else if (parent is VariableDeclaration) {
         var grandParent = parent.parent;
         // Inside the initializer for a `const` variable declaration.
@@ -4291,7 +4323,7 @@
   /// Note: most code shouldn't call this method directly, but should instead
   /// call [ResolverVisitor.analyzeExpression], which has some special logic for
   /// handling dynamic contexts.
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType);
+  void resolveExpression(ResolverVisitor resolver, DartType contextType);
 }
 
 /// An expression used as a statement.
@@ -4309,7 +4341,10 @@
   Token? semicolon;
 
   /// Initialize a newly created expression statement.
-  ExpressionStatementImpl(this._expression, this.semicolon) {
+  ExpressionStatementImpl({
+    required ExpressionImpl expression,
+    required this.semicolon,
+  }) : _expression = expression {
     _becomeParentOf(_expression);
   }
 
@@ -4362,7 +4397,10 @@
   NamedTypeImpl _superclass;
 
   /// Initialize a newly created extends clause.
-  ExtendsClauseImpl(this.extendsKeyword, this._superclass) {
+  ExtendsClauseImpl({
+    required this.extendsKeyword,
+    required NamedTypeImpl superclass,
+  }) : _superclass = superclass {
     _becomeParentOf(_superclass);
   }
 
@@ -4379,10 +4417,6 @@
     _superclass = _becomeParentOf(name as NamedTypeImpl);
   }
 
-  @Deprecated('Use superclass instead')
-  @override
-  NamedTypeImpl get superclass2 => _superclass;
-
   @override
   ChildEntities get _childEntities => ChildEntities()
     ..addToken('extendsKeyword', extendsKeyword)
@@ -4416,9 +4450,8 @@
   /// hide any elements.
   HideClauseImpl? _hideClause;
 
-  /// The name of the extension, or `null` if the extension does not have a
-  /// name.
-  SimpleIdentifierImpl? _name;
+  @override
+  Token? name;
 
   /// The show clause for the extension or `null` if the declaration does not
   /// show any elements.
@@ -4444,14 +4477,14 @@
   Token rightBracket;
 
   @override
-  ExtensionElement? declaredElement2;
+  ExtensionElement? declaredElement;
 
   ExtensionDeclarationImpl({
     required super.comment,
     required super.metadata,
     required this.extensionKeyword,
     required this.typeKeyword,
-    required SimpleIdentifierImpl? name,
+    required this.name,
     required TypeParameterListImpl? typeParameters,
     required this.onKeyword,
     required TypeAnnotationImpl extendedType,
@@ -4460,20 +4493,18 @@
     required this.leftBracket,
     required List<ClassMember> members,
     required this.rightBracket,
-  })  : _name = name,
-        _typeParameters = typeParameters,
+  })  : _typeParameters = typeParameters,
         _extendedType = extendedType,
         _showClause = showClause,
         _hideClause = hideClause {
-    _becomeParentOf(_name);
     _becomeParentOf(_typeParameters);
     _becomeParentOf(_extendedType);
     _members._initialize(this, members);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  ExtensionElement? get declaredElement => declaredElement2;
+  ExtensionElement? get declaredElement2 => declaredElement;
 
   @override
   Token get endToken => rightBracket;
@@ -4498,19 +4529,9 @@
   @override
   NodeListImpl<ClassMember> get members => _members;
 
-  @Deprecated('Use name2 instead')
+  @Deprecated('Use name instead')
   @override
-  SimpleIdentifierImpl? get name {
-    _name?.staticElement = declaredElement;
-    return _name;
-  }
-
-  set name(SimpleIdentifier? identifier) {
-    _name = _becomeParentOf(identifier as SimpleIdentifierImpl?);
-  }
-
-  @override
-  Token? get name2 => _name?.token;
+  Token? get name2 => name;
 
   @override
   ShowClauseImpl? get showClause => _showClause;
@@ -4529,7 +4550,7 @@
   @override
   ChildEntities get _childEntities => ChildEntities()
     ..addToken('extensionKeyword', extensionKeyword)
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('typeParameters', typeParameters)
     ..addToken('onKeyword', onKeyword)
     ..addNode('extendedType', extendedType)
@@ -4544,8 +4565,6 @@
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name?.accept(visitor);
     _typeParameters?.accept(visitor);
     _extendedType.accept(visitor);
     _members.accept(visitor);
@@ -4637,7 +4656,7 @@
   }
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitExtensionOverride(this, contextType: contextType);
   }
 
@@ -4649,6 +4668,78 @@
   }
 }
 
+/// An extractor pattern.
+///
+///    extractorPattern ::=
+///        [Identifier] [TypeArgumentList]? '(' [RecordPatternField] ')'
+@experimental
+class ExtractorPatternImpl extends DartPatternImpl implements ExtractorPattern {
+  final NodeListImpl<RecordPatternField> _fields = NodeListImpl._();
+
+  @override
+  final Token leftParenthesis;
+
+  @override
+  final Token rightParenthesis;
+
+  @override
+  final TypeArgumentListImpl? typeArguments;
+
+  @override
+  final IdentifierImpl typeName;
+
+  ExtractorPatternImpl(
+      {required this.typeName,
+      required this.typeArguments,
+      required this.leftParenthesis,
+      required List<RecordPatternField> fields,
+      required this.rightParenthesis}) {
+    _becomeParentOf(typeName);
+    _becomeParentOf(typeArguments);
+    _fields._initialize(this, fields);
+  }
+
+  @override
+  Token get beginToken => typeName.beginToken;
+
+  @override
+  Token get endToken => rightParenthesis;
+
+  @override
+  NodeList<RecordPatternField> get fields => _fields;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('typeName', typeName)
+    ..addNode('typeArguments', typeArguments)
+    ..addToken('leftParenthesis', leftParenthesis)
+    ..addNodeList('fields', fields)
+    ..addToken('rightParenthesis', rightParenthesis);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitExtractorPattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/50066
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    typeName.accept(visitor);
+    typeArguments?.accept(visitor);
+    fields.accept(visitor);
+  }
+}
+
 /// The declaration of one or more fields of the same type.
 ///
 ///    fieldDeclaration ::=
@@ -4700,6 +4791,7 @@
   @override
   Element? get declaredElement => null;
 
+  @Deprecated('Use declaredElement instead')
   @override
   Element? get declaredElement2 => null;
 
@@ -4791,12 +4883,11 @@
       this._type,
       this.thisKeyword,
       this.period,
-      SimpleIdentifierImpl identifier,
+      Token name,
       this._typeParameters,
       this._parameters,
       this.question)
-      : super(
-            comment, metadata, covariantKeyword, requiredKeyword, identifier) {
+      : super(comment, metadata, covariantKeyword, requiredKeyword, name) {
     _becomeParentOf(_type);
     _becomeParentOf(_typeParameters);
     _becomeParentOf(_parameters);
@@ -4824,10 +4915,6 @@
     return question ?? _parameters?.endToken ?? name;
   }
 
-  @Deprecated('Use name instead')
-  @override
-  SimpleIdentifierImpl get identifier => super.identifier!;
-
   @override
   bool get isConst => keyword?.keyword == Keyword.CONST;
 
@@ -4878,8 +4965,6 @@
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
     _type?.accept(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    identifier.accept(visitor);
     _typeParameters?.accept(visitor);
     _parameters?.accept(visitor);
   }
@@ -4896,7 +4981,10 @@
   /// Initialize a newly created for-each statement whose loop control variable
   /// is declared internally (in the for-loop part). The [awaitKeyword] can be
   /// `null` if this is not an asynchronous for loop.
-  ForEachPartsImpl(this.inKeyword, this._iterable) {
+  ForEachPartsImpl({
+    required this.inKeyword,
+    required ExpressionImpl iterable,
+  }) : _iterable = iterable {
     _becomeParentOf(_iterable);
   }
 
@@ -4931,9 +5019,11 @@
 
   /// Initialize a newly created for-each statement whose loop control variable
   /// is declared internally (inside the for-loop part).
-  ForEachPartsWithDeclarationImpl(
-      this._loopVariable, Token inKeyword, ExpressionImpl iterator)
-      : super(inKeyword, iterator) {
+  ForEachPartsWithDeclarationImpl({
+    required DeclaredIdentifierImpl loopVariable,
+    required super.inKeyword,
+    required super.iterable,
+  }) : _loopVariable = loopVariable {
     _becomeParentOf(_loopVariable);
   }
 
@@ -4970,9 +5060,11 @@
 
   /// Initialize a newly created for-each statement whose loop control variable
   /// is declared externally (outside the for-loop part).
-  ForEachPartsWithIdentifierImpl(
-      this._identifier, Token inKeyword, ExpressionImpl iterator)
-      : super(inKeyword, iterator) {
+  ForEachPartsWithIdentifierImpl({
+    required SimpleIdentifierImpl identifier,
+    required super.inKeyword,
+    required super.iterable,
+  }) : _identifier = identifier {
     _becomeParentOf(_identifier);
   }
 
@@ -5002,6 +5094,47 @@
   }
 }
 
+/// A for-loop part with a pattern.
+///
+///    forEachPartsWithPattern ::=
+///        ( 'final' | 'var' ) [DartPattern] 'in' [Expression]
+@experimental
+class ForEachPartsWithPatternImpl extends ForEachPartsImpl
+    implements ForEachPartsWithPattern {
+  @override
+  final Token keyword;
+
+  @override
+  final DartPatternImpl pattern;
+
+  ForEachPartsWithPatternImpl({
+    required this.keyword,
+    required this.pattern,
+    required super.inKeyword,
+    required super.iterable,
+  }) {
+    _becomeParentOf(pattern);
+  }
+
+  @override
+  Token get beginToken => keyword;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('keyword', keyword)
+    ..addNode('pattern', pattern);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitForEachPartsWithPattern(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    pattern.accept(visitor);
+    super.visitChildren(visitor);
+  }
+}
+
 class ForElementImpl extends CollectionElementImpl implements ForElement {
   @override
   Token? awaitKeyword;
@@ -5021,8 +5154,15 @@
   CollectionElementImpl _body;
 
   /// Initialize a newly created for element.
-  ForElementImpl(this.awaitKeyword, this.forKeyword, this.leftParenthesis,
-      this._forLoopParts, this.rightParenthesis, this._body) {
+  ForElementImpl({
+    required this.awaitKeyword,
+    required this.forKeyword,
+    required this.leftParenthesis,
+    required ForLoopPartsImpl forLoopParts,
+    required this.rightParenthesis,
+    required CollectionElementImpl body,
+  })  : _forLoopParts = forLoopParts,
+        _body = body {
     _becomeParentOf(_forLoopParts);
     _becomeParentOf(_body);
   }
@@ -5063,6 +5203,7 @@
   void resolveElement(
       ResolverVisitor resolver, CollectionLiteralContext? context) {
     resolver.visitForElement(this, context: context);
+    resolver.pushRewrite(null);
   }
 
   @override
@@ -5084,10 +5225,6 @@
   @override
   ParameterElement? declaredElement;
 
-  @Deprecated('Use name instead')
-  @override
-  SimpleIdentifierImpl? get identifier;
-
   /// TODO(scheglov) I was not able to update 'nnbd_migration' any better.
   SimpleIdentifier? get identifierForMigration {
     final token = name;
@@ -5254,8 +5391,12 @@
   /// [initialization] must be `null`. Either the [condition] and the list of
   /// [updaters] can be `null` if the loop does not have the corresponding
   /// attribute.
-  ForPartsImpl(this.leftSeparator, this._condition, this.rightSeparator,
-      List<Expression>? updaters) {
+  ForPartsImpl({
+    required this.leftSeparator,
+    required ExpressionImpl? condition,
+    required this.rightSeparator,
+    required List<Expression>? updaters,
+  }) : _condition = condition {
     _becomeParentOf(_condition);
     _updaters._initialize(this, updaters);
   }
@@ -5300,13 +5441,13 @@
   /// Initialize a newly created for statement. Both the [condition] and the
   /// list of [updaters] can be `null` if the loop does not have the
   /// corresponding attribute.
-  ForPartsWithDeclarationsImpl(
-      this._variableList,
-      Token leftSeparator,
-      ExpressionImpl? condition,
-      Token rightSeparator,
-      List<Expression>? updaters)
-      : super(leftSeparator, condition, rightSeparator, updaters) {
+  ForPartsWithDeclarationsImpl({
+    required VariableDeclarationListImpl variableList,
+    required super.leftSeparator,
+    required super.condition,
+    required super.rightSeparator,
+    required super.updaters,
+  }) : _variableList = variableList {
     _becomeParentOf(_variableList);
   }
 
@@ -5347,13 +5488,13 @@
   /// Initialize a newly created for statement. Both the [condition] and the
   /// list of [updaters] can be `null` if the loop does not have the
   /// corresponding attribute.
-  ForPartsWithExpressionImpl(
-      this._initialization,
-      Token leftSeparator,
-      ExpressionImpl? condition,
-      Token rightSeparator,
-      List<Expression>? updaters)
-      : super(leftSeparator, condition, rightSeparator, updaters) {
+  ForPartsWithExpressionImpl({
+    required ExpressionImpl? initialization,
+    required super.leftSeparator,
+    required super.condition,
+    required super.rightSeparator,
+    required super.updaters,
+  }) : _initialization = initialization {
     _becomeParentOf(_initialization);
   }
 
@@ -5383,6 +5524,43 @@
   }
 }
 
+/// The parts of a for loop that control the iteration when there is a pattern
+/// declaration as part of the for loop.
+///
+///   forLoopParts ::=
+///       [PatternVariableDeclaration] ';' [Expression]? ';' expressionList?
+class ForPartsWithPatternImpl extends ForPartsImpl
+    implements ForPartsWithPattern {
+  @override
+  final PatternVariableDeclarationImpl variables;
+
+  ForPartsWithPatternImpl({
+    required this.variables,
+    required super.leftSeparator,
+    required super.condition,
+    required super.rightSeparator,
+    required super.updaters,
+  }) {
+    _becomeParentOf(variables);
+  }
+
+  @override
+  Token get beginToken => variables.beginToken;
+
+  @override
+  ChildEntities get _childEntities =>
+      super._childEntities..addNode('variables', variables);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitForPartsWithPattern(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    variables.accept(visitor);
+    super.visitChildren(visitor);
+  }
+}
+
 class ForStatementImpl extends StatementImpl implements ForStatement {
   @override
   Token? awaitKeyword;
@@ -5402,8 +5580,15 @@
   StatementImpl _body;
 
   /// Initialize a newly created for statement.
-  ForStatementImpl(this.awaitKeyword, this.forKeyword, this.leftParenthesis,
-      this._forLoopParts, this.rightParenthesis, this._body) {
+  ForStatementImpl({
+    required this.awaitKeyword,
+    required this.forKeyword,
+    required this.leftParenthesis,
+    required ForLoopPartsImpl forLoopParts,
+    required this.rightParenthesis,
+    required StatementImpl body,
+  })  : _forLoopParts = forLoopParts,
+        _body = body {
     _becomeParentOf(_forLoopParts);
     _becomeParentOf(_body);
   }
@@ -5504,7 +5689,10 @@
   DartType resolve(ResolverVisitor resolver, DartType? imposedType);
 }
 
-/// A top-level declaration.
+/// A function declaration.
+///
+/// Wrapped in a [FunctionDeclarationStatementImpl] to represent a local
+/// function declaration, otherwise a top-level function declaration.
 ///
 ///    functionDeclaration ::=
 ///        'external' functionSignature
@@ -5535,7 +5723,7 @@
   FunctionExpressionImpl _functionExpression;
 
   @override
-  ExecutableElement? declaredElement2;
+  ExecutableElement? declaredElement;
 
   /// Initialize a newly created function declaration. Either or both of the
   /// [comment] and [metadata] can be `null` if the function does not have the
@@ -5558,9 +5746,9 @@
     _becomeParentOf(_functionExpression);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  ExecutableElement? get declaredElement => declaredElement2;
+  ExecutableElement? get declaredElement2 => declaredElement;
 
   @override
   Token get endToken => _functionExpression.endToken;
@@ -5571,7 +5759,7 @@
         externalKeyword ??
         _returnType?.beginToken ??
         propertyKeyword ??
-        _name.beginToken;
+        name;
   }
 
   @override
@@ -5601,7 +5789,7 @@
     ..addToken('externalKeyword', externalKeyword)
     ..addNode('returnType', returnType)
     ..addToken('propertyKeyword', propertyKeyword)
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('functionExpression', functionExpression);
 
   @override
@@ -5611,8 +5799,6 @@
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
     _returnType?.accept(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     _functionExpression.accept(visitor);
   }
 }
@@ -5624,7 +5810,9 @@
   FunctionDeclarationImpl _functionDeclaration;
 
   /// Initialize a newly created function declaration statement.
-  FunctionDeclarationStatementImpl(this._functionDeclaration) {
+  FunctionDeclarationStatementImpl({
+    required FunctionDeclarationImpl functionDeclaration,
+  }) : _functionDeclaration = functionDeclaration {
     _becomeParentOf(_functionDeclaration);
   }
 
@@ -5682,7 +5870,13 @@
   ExecutableElement? declaredElement;
 
   /// Initialize a newly created function declaration.
-  FunctionExpressionImpl(this._typeParameters, this._parameters, this._body) {
+  FunctionExpressionImpl({
+    required TypeParameterListImpl? typeParameters,
+    required FormalParameterListImpl? parameters,
+    required FunctionBodyImpl body,
+  })  : _typeParameters = typeParameters,
+        _parameters = parameters,
+        _body = body {
     _becomeParentOf(_typeParameters);
     _becomeParentOf(_parameters);
     _becomeParentOf(_body);
@@ -5737,7 +5931,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitFunctionExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitFunctionExpression(this, contextType: contextType);
   }
 
@@ -5769,9 +5963,11 @@
   ExecutableElement? staticElement;
 
   /// Initialize a newly created function expression invocation.
-  FunctionExpressionInvocationImpl(this._function,
-      TypeArgumentListImpl? typeArguments, ArgumentListImpl argumentList)
-      : super(typeArguments, argumentList) {
+  FunctionExpressionInvocationImpl({
+    required ExpressionImpl function,
+    required super.typeArguments,
+    required super.argumentList,
+  }) : _function = function {
     _becomeParentOf(_function);
   }
 
@@ -5804,7 +6000,7 @@
       visitor.visitFunctionExpressionInvocation(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitFunctionExpressionInvocation(this, contextType: contextType);
   }
 
@@ -5831,8 +6027,11 @@
   @override
   List<DartType>? typeArgumentTypes;
 
-  FunctionReferenceImpl(this._function, {TypeArgumentListImpl? typeArguments})
-      : _typeArguments = typeArguments {
+  FunctionReferenceImpl({
+    required ExpressionImpl function,
+    required TypeArgumentListImpl? typeArguments,
+  })  : _function = function,
+        _typeArguments = typeArguments {
     _becomeParentOf(_function);
     _becomeParentOf(_typeArguments);
   }
@@ -5870,7 +6069,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitFunctionReference(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitFunctionReference(this, contextType: contextType);
   }
 
@@ -5901,7 +6100,7 @@
   FormalParameterListImpl _parameters;
 
   @override
-  TypeAliasElement? declaredElement2;
+  TypeAliasElement? declaredElement;
 
   /// Initialize a newly created function type alias. Either or both of the
   /// [comment] and [metadata] can be `null` if the function does not have the
@@ -5925,9 +6124,9 @@
     _becomeParentOf(_parameters);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  TypeAliasElement? get declaredElement => declaredElement2;
+  TypeAliasElement? get declaredElement2 => declaredElement;
 
   @override
   FormalParameterListImpl get parameters => _parameters;
@@ -5954,7 +6153,7 @@
   ChildEntities get _childEntities => super._childEntities
     ..addToken('typedefKeyword', typedefKeyword)
     ..addNode('returnType', returnType)
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('typeParameters', typeParameters)
     ..addNode('parameters', parameters)
     ..addToken('semicolon', semicolon);
@@ -5966,8 +6165,6 @@
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
     _returnType?.accept(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     _typeParameters?.accept(visitor);
     _parameters.accept(visitor);
   }
@@ -6004,12 +6201,11 @@
       Token? covariantKeyword,
       Token? requiredKeyword,
       this._returnType,
-      SimpleIdentifierImpl identifier,
+      Token name,
       this._typeParameters,
       this._parameters,
       this.question)
-      : super(
-            comment, metadata, covariantKeyword, requiredKeyword, identifier) {
+      : super(comment, metadata, covariantKeyword, requiredKeyword, name) {
     _becomeParentOf(_returnType);
     _becomeParentOf(_typeParameters);
     _becomeParentOf(_parameters);
@@ -6033,10 +6229,6 @@
   @override
   Token get endToken => question ?? _parameters.endToken;
 
-  @Deprecated('Use name instead')
-  @override
-  SimpleIdentifierImpl get identifier => super.identifier!;
-
   @override
   bool get isConst => false;
 
@@ -6084,8 +6276,6 @@
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
     _returnType?.accept(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    identifier.accept(visitor);
     _typeParameters?.accept(visitor);
     _parameters.accept(visitor);
   }
@@ -6146,9 +6336,15 @@
   GenericFunctionTypeElement? declaredElement;
 
   /// Initialize a newly created generic function type.
-  GenericFunctionTypeImpl(this._returnType, this.functionKeyword,
-      this._typeParameters, this._parameters,
-      {this.question}) {
+  GenericFunctionTypeImpl({
+    required TypeAnnotationImpl? returnType,
+    required this.functionKeyword,
+    required TypeParameterListImpl? typeParameters,
+    required FormalParameterListImpl parameters,
+    required this.question,
+  })  : _returnType = returnType,
+        _typeParameters = typeParameters,
+        _parameters = parameters {
     _becomeParentOf(_returnType);
     _becomeParentOf(_typeParameters);
     _becomeParentOf(_parameters);
@@ -6223,7 +6419,7 @@
   Token equals;
 
   @override
-  Element? declaredElement2;
+  Element? declaredElement;
 
   /// Returns a newly created generic type alias. Either or both of the
   /// [comment] and [metadata] can be `null` if the variable list does not have
@@ -6244,9 +6440,9 @@
     _becomeParentOf(_type);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  Element? get declaredElement => declaredElement2;
+  Element? get declaredElement2 => declaredElement;
 
   /// The type of function being defined by the alias.
   ///
@@ -6282,7 +6478,7 @@
   ChildEntities get _childEntities => ChildEntities()
     ..addNodeList('metadata', metadata)
     ..addToken('typedefKeyword', typedefKeyword)
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('typeParameters', typeParameters)
     ..addToken('equals', equals)
     ..addNode('type', type);
@@ -6295,8 +6491,6 @@
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     _typeParameters?.accept(visitor);
     _type.accept(visitor);
   }
@@ -6315,7 +6509,10 @@
   final NodeListImpl<ShowHideClauseElement> _elements = NodeListImpl._();
 
   /// Initialize a newly created show clause.
-  HideClauseImpl(this.hideKeyword, List<ShowHideClauseElement> elements) {
+  HideClauseImpl({
+    required this.hideKeyword,
+    required List<ShowHideClauseElement> elements,
+  }) {
     _elements._initialize(this, elements);
   }
 
@@ -6352,7 +6549,10 @@
   final NodeListImpl<SimpleIdentifier> _hiddenNames = NodeListImpl._();
 
   /// Initialize a newly created import show combinator.
-  HideCombinatorImpl(super.keyword, List<SimpleIdentifier> hiddenNames) {
+  HideCombinatorImpl({
+    required super.keyword,
+    required List<SimpleIdentifier> hiddenNames,
+  }) {
     _hiddenNames._initialize(this, hiddenNames);
   }
 
@@ -6394,10 +6594,12 @@
   @override
   Token leftParenthesis;
 
-  /// The condition used to determine which of the branches is executed next.
   ExpressionImpl _condition;
 
   @override
+  final CaseClauseImpl? caseClause;
+
+  @override
   Token rightParenthesis;
 
   @override
@@ -6411,15 +6613,20 @@
   CollectionElementImpl? _elseElement;
 
   /// Initialize a newly created for element.
-  IfElementImpl(
-      this.ifKeyword,
-      this.leftParenthesis,
-      this._condition,
-      this.rightParenthesis,
-      this._thenElement,
-      this.elseKeyword,
-      this._elseElement) {
+  IfElementImpl({
+    required this.ifKeyword,
+    required this.leftParenthesis,
+    required ExpressionImpl condition,
+    required this.caseClause,
+    required this.rightParenthesis,
+    required CollectionElementImpl thenElement,
+    required this.elseKeyword,
+    required CollectionElementImpl? elseElement,
+  })  : _condition = condition,
+        _thenElement = thenElement,
+        _elseElement = elseElement {
     _becomeParentOf(_condition);
+    _becomeParentOf(caseClause);
     _becomeParentOf(_thenElement);
     _becomeParentOf(_elseElement);
   }
@@ -6428,7 +6635,7 @@
   Token get beginToken => ifKeyword;
 
   @override
-  ExpressionImpl get condition => _condition;
+  Expression get condition => _condition;
 
   set condition(Expression condition) {
     _condition = _becomeParentOf(condition as ExpressionImpl);
@@ -6445,6 +6652,9 @@
   Token get endToken => _elseElement?.endToken ?? _thenElement.endToken;
 
   @override
+  Expression get expression => _condition;
+
+  @override
   CollectionElementImpl get thenElement => _thenElement;
 
   set thenElement(CollectionElement element) {
@@ -6456,6 +6666,7 @@
     ..addToken('ifKeyword', ifKeyword)
     ..addToken('leftParenthesis', leftParenthesis)
     ..addNode('condition', condition)
+    ..addNode('caseClause', caseClause)
     ..addToken('rightParenthesis', rightParenthesis)
     ..addNode('thenElement', thenElement)
     ..addToken('elseKeyword', elseKeyword)
@@ -6468,11 +6679,13 @@
   void resolveElement(
       ResolverVisitor resolver, CollectionLiteralContext? context) {
     resolver.visitIfElement(this, context: context);
+    resolver.pushRewrite(null);
   }
 
   @override
   void visitChildren(AstVisitor visitor) {
-    _condition.accept(visitor);
+    condition.accept(visitor);
+    caseClause?.accept(visitor);
     _thenElement.accept(visitor);
     _elseElement?.accept(visitor);
   }
@@ -6481,7 +6694,8 @@
 /// An if statement.
 ///
 ///    ifStatement ::=
-///        'if' '(' [Expression] ')' [Statement] ('else' [Statement])?
+///        'if' '(' [Expression] [CaseClause]? ')'[Statement]
+///        ('else' [Statement])?
 class IfStatementImpl extends StatementImpl implements IfStatement {
   @override
   Token ifKeyword;
@@ -6493,6 +6707,9 @@
   ExpressionImpl _condition;
 
   @override
+  final CaseClauseImpl? caseClause;
+
+  @override
   Token rightParenthesis;
 
   @override
@@ -6507,15 +6724,20 @@
 
   /// Initialize a newly created if statement. The [elseKeyword] and
   /// [elseStatement] can be `null` if there is no else clause.
-  IfStatementImpl(
-      this.ifKeyword,
-      this.leftParenthesis,
-      this._condition,
-      this.rightParenthesis,
-      this._thenStatement,
-      this.elseKeyword,
-      this._elseStatement) {
+  IfStatementImpl({
+    required this.ifKeyword,
+    required this.leftParenthesis,
+    required ExpressionImpl condition,
+    required this.caseClause,
+    required this.rightParenthesis,
+    required StatementImpl thenStatement,
+    required this.elseKeyword,
+    required StatementImpl? elseStatement,
+  })  : _condition = condition,
+        _thenStatement = thenStatement,
+        _elseStatement = elseStatement {
     _becomeParentOf(_condition);
+    _becomeParentOf(caseClause);
     _becomeParentOf(_thenStatement);
     _becomeParentOf(_elseStatement);
   }
@@ -6546,6 +6768,9 @@
   }
 
   @override
+  Expression get expression => _condition;
+
+  @override
   StatementImpl get thenStatement => _thenStatement;
 
   set thenStatement(Statement statement) {
@@ -6557,6 +6782,7 @@
     ..addToken('ifKeyword', ifKeyword)
     ..addToken('leftParenthesis', leftParenthesis)
     ..addNode('condition', condition)
+    ..addNode('caseClause', caseClause)
     ..addToken('rightParenthesis', rightParenthesis)
     ..addNode('thenStatement', thenStatement)
     ..addToken('elseKeyword', elseKeyword)
@@ -6568,6 +6794,7 @@
   @override
   void visitChildren(AstVisitor visitor) {
     _condition.accept(visitor);
+    caseClause?.accept(visitor);
     _thenStatement.accept(visitor);
     _elseStatement?.accept(visitor);
   }
@@ -6586,7 +6813,10 @@
   final NodeListImpl<NamedType> _interfaces = NodeListImpl._();
 
   /// Initialize a newly created implements clause.
-  ImplementsClauseImpl(this.implementsKeyword, List<NamedType> interfaces) {
+  ImplementsClauseImpl({
+    required this.implementsKeyword,
+    required List<NamedType> interfaces,
+  }) {
     _interfaces._initialize(this, interfaces);
   }
 
@@ -6594,15 +6824,11 @@
   Token get beginToken => implementsKeyword;
 
   @override
-  Token get endToken => _interfaces.endToken!;
+  Token get endToken => _interfaces.endToken ?? implementsKeyword;
 
   @override
   NodeListImpl<NamedType> get interfaces => _interfaces;
 
-  @Deprecated('Use interfaces instead')
-  @override
-  NodeListImpl<NamedType> get interfaces2 => _interfaces;
-
   @override
   // TODO(paulberry): add commas.
   ChildEntities get _childEntities => ChildEntities()
@@ -6675,7 +6901,7 @@
   }
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitImplicitCallReference(this, contextType: contextType);
   }
 
@@ -6733,26 +6959,12 @@
     _becomeParentOf(_prefix);
   }
 
-  @Deprecated('Use element2 instead')
-  @override
-  ImportElement? get element {
-    final element2 = this.element2;
-    if (element2 is LibraryImportElementImpl) {
-      return ImportElementImpl(element2);
-    }
-    return null;
-  }
-
   @override
   LibraryImportElement? get element2 => super.element2 as LibraryImportElement?;
 
   @override
   Token get firstTokenAfterCommentAndMetadata => importKeyword;
 
-  @Deprecated('Use specific xyzToken instead')
-  @override
-  Token get keyword => importKeyword;
-
   @override
   SimpleIdentifierImpl? get prefix => _prefix;
 
@@ -6760,12 +6972,6 @@
     _prefix = _becomeParentOf(identifier as SimpleIdentifierImpl?);
   }
 
-  @Deprecated('Use element2.uri instead')
-  @override
-  LibraryElement? get uriElement {
-    return element2?.importedLibrary;
-  }
-
   @override
   ChildEntities get _childEntities => super._childEntities
     ..addToken('importKeyword', importKeyword)
@@ -7018,7 +7224,7 @@
   }
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitIndexExpression(this, contextType: contextType);
   }
 
@@ -7132,7 +7338,7 @@
       visitor.visitInstanceCreationExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitInstanceCreationExpression(this, contextType: contextType);
   }
 
@@ -7166,7 +7372,10 @@
   int? value = 0;
 
   /// Initialize a newly created integer literal.
-  IntegerLiteralImpl(this.literal, this.value);
+  IntegerLiteralImpl({
+    required this.literal,
+    required this.value,
+  });
 
   @override
   Token get beginToken => literal;
@@ -7194,7 +7403,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitIntegerLiteral(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitIntegerLiteral(this, contextType: contextType);
   }
 
@@ -7337,7 +7546,10 @@
 
   /// Initialize a newly created string of characters that are part of a string
   /// interpolation.
-  InterpolationStringImpl(this.contents, this.value);
+  InterpolationStringImpl({
+    required this.contents,
+    required this.value,
+  });
 
   @override
   Token get beginToken => contents;
@@ -7389,7 +7601,11 @@
   DartType? staticInvokeType;
 
   /// Initialize a newly created invocation.
-  InvocationExpressionImpl(this._typeArguments, this._argumentList) {
+  InvocationExpressionImpl({
+    required TypeArgumentListImpl? typeArguments,
+    required ArgumentListImpl argumentList,
+  })  : _typeArguments = typeArguments,
+        _argumentList = argumentList {
     _becomeParentOf(_typeArguments);
     _becomeParentOf(_argumentList);
   }
@@ -7470,7 +7686,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitIsExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitIsExpression(this, contextType: contextType);
   }
 
@@ -7550,7 +7766,10 @@
   Token colon;
 
   /// Initialize a newly created label.
-  LabelImpl(this._label, this.colon) {
+  LabelImpl({
+    required SimpleIdentifierImpl label,
+    required this.colon,
+  }) : _label = label {
     _becomeParentOf(_label);
   }
 
@@ -7612,18 +7831,6 @@
   @override
   Token get firstTokenAfterCommentAndMetadata => libraryKeyword;
 
-  @Deprecated('Use specific xyzToken instead')
-  @override
-  Token get keyword => libraryKeyword;
-
-  @Deprecated('Use element2.uri instead')
-  @override
-  LibraryElement? get uriElement {
-    // TODO(scheglov) Implement it.
-    throw UnimplementedError();
-    // return element?.importedLibrary;
-  }
-
   @override
   ChildEntities get _childEntities => super._childEntities
     ..addToken('libraryKeyword', libraryKeyword)
@@ -7647,7 +7854,7 @@
   Token libraryKeyword;
 
   /// The name of the library being defined.
-  LibraryIdentifierImpl _name;
+  LibraryIdentifierImpl? _name;
 
   /// The semicolon terminating the directive.
   @override
@@ -7660,7 +7867,7 @@
     required super.comment,
     required super.metadata,
     required this.libraryKeyword,
-    required LibraryIdentifierImpl name,
+    required LibraryIdentifierImpl? name,
     required this.semicolon,
   }) : _name = name {
     _becomeParentOf(_name);
@@ -7672,21 +7879,21 @@
   @override
   Token get firstTokenAfterCommentAndMetadata => libraryKeyword;
 
-  @Deprecated('Use specific xyzToken instead')
   @override
-  Token get keyword => libraryKeyword;
+  @Deprecated('Use name2')
+  LibraryIdentifierImpl get name => _name!;
 
-  @override
-  LibraryIdentifierImpl get name => _name;
-
-  set name(LibraryIdentifier name) {
-    _name = _becomeParentOf(name as LibraryIdentifierImpl);
+  set name(LibraryIdentifier? name) {
+    _name = _becomeParentOf(name as LibraryIdentifierImpl?);
   }
 
   @override
+  LibraryIdentifierImpl? get name2 => _name;
+
+  @override
   ChildEntities get _childEntities => super._childEntities
     ..addToken('libraryKeyword', libraryKeyword)
-    ..addNode('name', name)
+    ..addNode('name', name2)
     ..addToken('semicolon', semicolon);
 
   @override
@@ -7695,7 +7902,7 @@
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
-    _name.accept(visitor);
+    _name?.accept(visitor);
   }
 }
 
@@ -7754,7 +7961,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitLibraryIdentifier(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitLibraryIdentifier(this, contextType: contextType);
   }
 
@@ -7824,7 +8031,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitListLiteral(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitListLiteral(this, contextType: contextType);
   }
 
@@ -7835,6 +8042,71 @@
   }
 }
 
+/// A list pattern.
+///
+///    listPattern ::=
+///        [TypeArgumentList]? '[' [DartPattern] (',' [DartPattern])* ','? ']'
+@experimental
+class ListPatternImpl extends DartPatternImpl implements ListPattern {
+  final NodeListImpl<DartPattern> _elements = NodeListImpl._();
+
+  @override
+  final Token leftBracket;
+
+  @override
+  final Token rightBracket;
+
+  @override
+  final TypeArgumentListImpl? typeArguments;
+
+  ListPatternImpl(
+      {required this.typeArguments,
+      required this.leftBracket,
+      required List<DartPattern> elements,
+      required this.rightBracket}) {
+    _becomeParentOf(typeArguments);
+    _elements._initialize(this, elements);
+  }
+
+  @override
+  Token get beginToken => typeArguments?.beginToken ?? leftBracket;
+
+  @override
+  NodeList<DartPattern> get elements => _elements;
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('typeArguments', typeArguments)
+    ..addToken('leftBracket', leftBracket)
+    ..addNodeList('elements', elements)
+    ..addToken('rightBracket', rightBracket);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitListPattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/50066
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    typeArguments?.accept(visitor);
+    elements.accept(visitor);
+  }
+}
+
 /// A node that represents a literal expression.
 ///
 ///    literal ::=
@@ -7880,7 +8152,12 @@
   ExpressionImpl _value;
 
   /// Initialize a newly created map literal entry.
-  MapLiteralEntryImpl(this._key, this.separator, this._value) {
+  MapLiteralEntryImpl({
+    required ExpressionImpl key,
+    required this.separator,
+    required ExpressionImpl value,
+  })  : _key = key,
+        _value = value {
     _becomeParentOf(_key);
     _becomeParentOf(_value);
   }
@@ -7918,6 +8195,7 @@
   void resolveElement(
       ResolverVisitor resolver, CollectionLiteralContext? context) {
     resolver.visitMapLiteralEntry(this, context: context);
+    resolver.pushRewrite(null);
   }
 
   @override
@@ -7927,6 +8205,115 @@
   }
 }
 
+/// An entry in a map pattern.
+///
+///    mapPatternEntry ::=
+///        [Expression] ':' [DartPattern]
+@experimental
+class MapPatternEntryImpl extends AstNodeImpl implements MapPatternEntry {
+  @override
+  final ExpressionImpl key;
+
+  @override
+  final Token separator;
+
+  @override
+  final DartPatternImpl value;
+
+  MapPatternEntryImpl(
+      {required this.key, required this.separator, required this.value}) {
+    _becomeParentOf(key);
+    _becomeParentOf(value);
+  }
+
+  @override
+  Token get beginToken => key.beginToken;
+
+  @override
+  Token get endToken => value.endToken;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('key', key)
+    ..addToken('separator', separator)
+    ..addNode('value', value);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitMapPatternEntry(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    key.accept(visitor);
+    value.accept(visitor);
+  }
+}
+
+/// A map pattern.
+///
+///    mapPattern ::=
+///        [TypeArgumentList]? '{' [MapPatternEntry] (',' [MapPatternEntry])*
+///        ','? '}'
+@experimental
+class MapPatternImpl extends DartPatternImpl implements MapPattern {
+  final NodeListImpl<MapPatternEntry> _entries = NodeListImpl._();
+
+  @override
+  final Token leftBracket;
+
+  @override
+  final Token rightBracket;
+
+  @override
+  final TypeArgumentListImpl? typeArguments;
+
+  MapPatternImpl(
+      {required this.typeArguments,
+      required this.leftBracket,
+      required List<MapPatternEntry> entries,
+      required this.rightBracket}) {
+    _becomeParentOf(typeArguments);
+    _entries._initialize(this, entries);
+  }
+
+  @override
+  Token get beginToken => typeArguments?.beginToken ?? leftBracket;
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  NodeList<MapPatternEntry> get entries => _entries;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('typeArguments', typeArguments)
+    ..addToken('leftBracket', leftBracket)
+    ..addNodeList('entries', entries)
+    ..addToken('rightBracket', rightBracket);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitMapPattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/50066
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    typeArguments?.accept(visitor);
+    entries.accept(visitor);
+  }
+}
+
 /// A method declaration.
 ///
 ///    methodDeclaration ::=
@@ -7964,8 +8351,8 @@
   @override
   Token? operatorKeyword;
 
-  /// The name of the method.
-  SimpleIdentifierImpl _name;
+  @override
+  Token name;
 
   /// The type parameters associated with the method, or `null` if the method is
   /// not a generic method.
@@ -7984,7 +8371,7 @@
   /// a [PropertyAccessorElement] if this represents the declaration of either a
   /// getter or a setter.
   @override
-  ExecutableElement? declaredElement2;
+  ExecutableElement? declaredElement;
 
   /// Initialize a newly created method declaration. Either or both of the
   /// [comment] and [metadata] can be `null` if the declaration does not have
@@ -8003,17 +8390,15 @@
     required TypeAnnotationImpl? returnType,
     required this.propertyKeyword,
     required this.operatorKeyword,
-    required SimpleIdentifierImpl name,
+    required this.name,
     required TypeParameterListImpl? typeParameters,
     required FormalParameterListImpl? parameters,
     required FunctionBodyImpl body,
   })  : _returnType = returnType,
-        _name = name,
         _typeParameters = typeParameters,
         _parameters = parameters,
         _body = body {
     _becomeParentOf(_returnType);
-    _becomeParentOf(_name);
     _becomeParentOf(_typeParameters);
     _becomeParentOf(_parameters);
     _becomeParentOf(_body);
@@ -8026,9 +8411,9 @@
     _body = _becomeParentOf(functionBody as FunctionBodyImpl);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  ExecutableElement? get declaredElement => declaredElement2;
+  ExecutableElement? get declaredElement2 => declaredElement;
 
   @override
   Token get endToken => _body.endToken;
@@ -8038,7 +8423,7 @@
     return Token.lexicallyFirst(externalKeyword, modifierKeyword) ??
         _returnType?.beginToken ??
         Token.lexicallyFirst(propertyKeyword, operatorKeyword) ??
-        _name.beginToken;
+        name;
   }
 
   @override
@@ -8060,19 +8445,9 @@
   @override
   bool get isStatic => modifierKeyword?.keyword == Keyword.STATIC;
 
-  @Deprecated('Use name2 instead')
+  @Deprecated('Use name instead')
   @override
-  SimpleIdentifierImpl get name {
-    _name.staticElement = declaredElement;
-    return _name;
-  }
-
-  set name(SimpleIdentifier identifier) {
-    _name = _becomeParentOf(identifier as SimpleIdentifierImpl);
-  }
-
-  @override
-  Token get name2 => _name.token;
+  Token get name2 => name;
 
   @override
   FormalParameterListImpl? get parameters => _parameters;
@@ -8102,7 +8477,7 @@
     ..addNode('returnType', returnType)
     ..addToken('propertyKeyword', propertyKeyword)
     ..addToken('operatorKeyword', operatorKeyword)
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('parameters', parameters)
     ..addNode('body', body);
 
@@ -8113,8 +8488,6 @@
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
     _returnType?.accept(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     _typeParameters?.accept(visitor);
     _parameters?.accept(visitor);
     _body.accept(visitor);
@@ -8152,9 +8525,14 @@
 
   /// Initialize a newly created method invocation. The [target] and [operator]
   /// can be `null` if there is no target.
-  MethodInvocationImpl(this._target, this.operator, this._methodName,
-      TypeArgumentListImpl? typeArguments, ArgumentListImpl argumentList)
-      : super(typeArguments, argumentList) {
+  MethodInvocationImpl({
+    required ExpressionImpl? target,
+    required this.operator,
+    required SimpleIdentifierImpl methodName,
+    required super.typeArguments,
+    required super.argumentList,
+  })  : _target = target,
+        _methodName = methodName {
     _becomeParentOf(_target);
     _becomeParentOf(_methodName);
   }
@@ -8259,7 +8637,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitMethodInvocation(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitMethodInvocation(this, contextType: contextType);
   }
 
@@ -8281,8 +8659,7 @@
 ///    mixinDeclaration ::=
 ///        metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]?
 ///        [RequiresClause]? [ImplementsClause]? '{' [ClassMember]* '}'
-// ignore: deprecated_member_use_from_same_package
-class MixinDeclarationImpl extends ClassOrMixinDeclarationImpl
+class MixinDeclarationImpl extends NamedCompilationUnitMemberImpl
     implements MixinDeclaration {
   /// Return the 'augment' keyword, or `null` if the keyword was absent.
   Token? augmentKeyword;
@@ -8290,12 +8667,31 @@
   @override
   Token mixinKeyword;
 
+  /// The type parameters for the class or mixin,
+  /// or `null` if the declaration does not have any type parameters.
+  TypeParameterListImpl? _typeParameters;
+
   /// The on clause for the mixin, or `null` if the mixin does not have any
   /// super-class constraints.
   OnClauseImpl? _onClause;
 
+  /// The implements clause for the class or mixin,
+  /// or `null` if the declaration does not implement any interfaces.
+  ImplementsClauseImpl? _implementsClause;
+
   @override
-  MixinElement? declaredElement2;
+  MixinElement? declaredElement;
+
+  /// The left curly bracket.
+  @override
+  Token leftBracket;
+
+  /// The members defined by the class or mixin.
+  final NodeListImpl<ClassMember> _members = NodeListImpl._();
+
+  /// The right curly bracket.
+  @override
+  Token rightBracket;
 
   /// Initialize a newly created mixin declaration. Either or both of the
   /// [comment] and [metadata] can be `null` if the mixin does not have the
@@ -8310,19 +8706,27 @@
     required this.augmentKeyword,
     required this.mixinKeyword,
     required super.name,
-    required super.typeParameters,
+    required TypeParameterListImpl? typeParameters,
     required OnClauseImpl? onClause,
-    required super.implementsClause,
-    required super.leftBracket,
-    required super.members,
-    required super.rightBracket,
-  }) : _onClause = onClause {
+    required ImplementsClauseImpl? implementsClause,
+    required this.leftBracket,
+    required List<ClassMember> members,
+    required this.rightBracket,
+  })  : _typeParameters = typeParameters,
+        _onClause = onClause,
+        _implementsClause = implementsClause {
+    _becomeParentOf(_typeParameters);
     _becomeParentOf(_onClause);
+    _becomeParentOf(_implementsClause);
+    _members._initialize(this, members);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  ClassElement? get declaredElement => declaredElement2 as ClassElement?;
+  MixinElement? get declaredElement2 => declaredElement;
+
+  @override
+  Token get endToken => rightBracket;
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
@@ -8332,6 +8736,11 @@
   @override
   ImplementsClauseImpl? get implementsClause => _implementsClause;
 
+  set implementsClause(ImplementsClause? implementsClause) {
+    _implementsClause =
+        _becomeParentOf(implementsClause as ImplementsClauseImpl?);
+  }
+
   @override
   NodeListImpl<ClassMember> get members => _members;
 
@@ -8345,10 +8754,14 @@
   @override
   TypeParameterListImpl? get typeParameters => _typeParameters;
 
+  set typeParameters(TypeParameterList? typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters as TypeParameterListImpl?);
+  }
+
   @override
   ChildEntities get _childEntities => super._childEntities
     ..addToken('mixinKeyword', mixinKeyword)
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addNode('typeParameters', typeParameters)
     ..addNode('onClause', onClause)
     ..addNode('implementsClause', implementsClause)
@@ -8362,8 +8775,6 @@
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     _typeParameters?.accept(visitor);
     _onClause?.accept(visitor);
     _implementsClause?.accept(visitor);
@@ -8375,32 +8786,21 @@
 abstract class NamedCompilationUnitMemberImpl extends CompilationUnitMemberImpl
     implements NamedCompilationUnitMember {
   /// The name of the member being declared.
-  SimpleIdentifierImpl _name;
+  @override
+  Token name;
 
-  /// Initialize a newly created compilation unit member with the given [name2].
+  /// Initialize a newly created compilation unit member with the given [name].
   /// Either or both of the [comment] and [metadata] can be `null` if the member
   /// does not have the corresponding attribute.
   NamedCompilationUnitMemberImpl({
     required super.comment,
     required super.metadata,
-    required SimpleIdentifierImpl name,
-  }) : _name = name {
-    _becomeParentOf(_name);
-  }
+    required this.name,
+  });
 
-  @Deprecated('Use name2 instead')
+  @Deprecated('Use name instead')
   @override
-  SimpleIdentifierImpl get name {
-    _name.staticElement = declaredElement;
-    return _name;
-  }
-
-  set name(SimpleIdentifier identifier) {
-    _name = _becomeParentOf(identifier as SimpleIdentifierImpl);
-  }
-
-  @override
-  Token get name2 => _name.token;
+  Token get name2 => name;
 }
 
 /// An expression that has a name associated with it. They are used in method
@@ -8416,7 +8816,11 @@
   ExpressionImpl _expression;
 
   /// Initialize a newly created named expression..
-  NamedExpressionImpl(this._name, this._expression) {
+  NamedExpressionImpl({
+    required LabelImpl name,
+    required ExpressionImpl expression,
+  })  : _name = name,
+        _expression = expression {
     _becomeParentOf(_name);
     _becomeParentOf(_expression);
   }
@@ -8462,7 +8866,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitNamedExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitNamedExpression(this, contextType: contextType);
   }
 
@@ -8495,7 +8899,12 @@
 
   /// Initialize a newly created type name. The [typeArguments] can be `null` if
   /// there are no type arguments.
-  NamedTypeImpl(this._name, this._typeArguments, {this.question}) {
+  NamedTypeImpl({
+    required IdentifierImpl name,
+    required TypeArgumentListImpl? typeArguments,
+    required this.question,
+  })  : _name = name,
+        _typeArguments = typeArguments {
     _becomeParentOf(_name);
     _becomeParentOf(_typeArguments);
   }
@@ -8566,14 +8975,6 @@
   @override
   Token semicolon;
 
-  @Deprecated('Use element2.uri instead')
-  @override
-  String? selectedUriContent;
-
-  @Deprecated('Use element2.uri instead')
-  @override
-  Source? selectedSource;
-
   /// Initialize a newly created namespace directive. Either or both of the
   /// [comment] and [metadata] can be `null` if the directive does not have the
   /// corresponding attribute. The list of [combinators] can be `null` if there
@@ -8598,10 +8999,6 @@
 
   @override
   Token get endToken => semicolon;
-
-  @Deprecated('Use element2.uri instead')
-  @override
-  LibraryElement? get uriElement;
 }
 
 /// The "native" clause in an class declaration.
@@ -8609,16 +9006,18 @@
 ///    nativeClause ::=
 ///        'native' [StringLiteral]
 class NativeClauseImpl extends AstNodeImpl implements NativeClause {
-  /// The token representing the 'native' keyword.
   @override
-  Token nativeKeyword;
+  final Token nativeKeyword;
 
-  /// The name of the native object that implements the class.
-  StringLiteralImpl? _name;
+  @override
+  final StringLiteralImpl? name;
 
   /// Initialize a newly created native clause.
-  NativeClauseImpl(this.nativeKeyword, this._name) {
-    _becomeParentOf(_name);
+  NativeClauseImpl({
+    required this.nativeKeyword,
+    required this.name,
+  }) {
+    _becomeParentOf(name);
   }
 
   @override
@@ -8626,14 +9025,7 @@
 
   @override
   Token get endToken {
-    return _name?.endToken ?? nativeKeyword;
-  }
-
-  @override
-  StringLiteralImpl? get name => _name;
-
-  set name(StringLiteral? name) {
-    _name = _becomeParentOf(name as StringLiteralImpl?);
+    return name?.endToken ?? nativeKeyword;
   }
 
   @override
@@ -8646,7 +9038,7 @@
 
   @override
   void visitChildren(AstVisitor visitor) {
-    _name?.accept(visitor);
+    name?.accept(visitor);
   }
 }
 
@@ -8714,7 +9106,7 @@
   late final AstNodeImpl _owner;
 
   /// The elements contained in the list.
-  List<E> _elements = <E>[];
+  late final List<E> _elements;
 
   /// Initialize a newly created list of nodes such that all of the nodes that
   /// are added to the list will have their parent set to the given [owner].
@@ -8743,6 +9135,7 @@
   @override
   int get length => _elements.length;
 
+  @Deprecated('NodeList cannot be resized')
   @override
   set length(int newLength) {
     throw UnsupportedError("Cannot resize NodeList.");
@@ -8776,46 +9169,46 @@
     }
   }
 
+  @Deprecated('NodeList cannot be resized')
   @override
   void add(E element) {
-    insert(length, element);
+    throw UnsupportedError("Cannot resize NodeList.");
   }
 
+  @Deprecated('NodeList cannot be resized')
   @override
   void addAll(Iterable<E> iterable) {
-    for (E node in iterable) {
-      _elements.add(node);
-      _owner._becomeParentOf(node as AstNodeImpl);
-    }
+    throw UnsupportedError("Cannot resize NodeList.");
   }
 
+  @Deprecated('NodeList cannot be resized')
   @override
   void clear() {
-    _elements = <E>[];
+    throw UnsupportedError("Cannot resize NodeList.");
   }
 
+  @Deprecated('NodeList cannot be resized')
   @override
   void insert(int index, E element) {
-    _elements.insert(index, element);
-    _owner._becomeParentOf(element as AstNodeImpl);
+    throw UnsupportedError("Cannot resize NodeList.");
   }
 
+  @Deprecated('NodeList cannot be resized')
   @override
   E removeAt(int index) {
-    if (index < 0 || index >= _elements.length) {
-      throw RangeError("Index: $index, Size: ${_elements.length}");
-    }
-    return _elements.removeAt(index);
+    throw UnsupportedError("Cannot resize NodeList.");
   }
 
   /// Set the [owner] of this container, and populate it with [elements].
   void _initialize(AstNodeImpl owner, List<E>? elements) {
     _owner = owner;
-    if (elements != null) {
+    if (elements == null || elements.isEmpty) {
+      _elements = const <Never>[];
+    } else {
+      _elements = elements.toList(growable: false);
       var length = elements.length;
       for (var i = 0; i < length; i++) {
         var node = elements[i];
-        _elements.add(node);
         owner._becomeParentOf(node as AstNodeImpl);
       }
     }
@@ -8845,17 +9238,16 @@
   @override
   Token? requiredKeyword;
 
-  /// The name of the parameter being declared.
-  SimpleIdentifierImpl? _identifier;
+  @override
+  Token? name;
 
   /// 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.
   NormalFormalParameterImpl(this._comment, List<Annotation>? metadata,
-      this.covariantKeyword, this.requiredKeyword, this._identifier) {
+      this.covariantKeyword, this.requiredKeyword, this.name) {
     _becomeParentOf(_comment);
     _metadata._initialize(this, metadata);
-    _becomeParentOf(_identifier);
   }
 
   @override
@@ -8865,17 +9257,6 @@
     _comment = _becomeParentOf(comment as CommentImpl?);
   }
 
-  @Deprecated('Use name2 instead')
-  @override
-  SimpleIdentifierImpl? get identifier {
-    _identifier?.staticElement = declaredElement;
-    return _identifier;
-  }
-
-  set identifier(SimpleIdentifier? identifier) {
-    _identifier = _becomeParentOf(identifier as SimpleIdentifierImpl?);
-  }
-
   @override
   ParameterKind get kind {
     final parent = this.parent;
@@ -8888,14 +9269,6 @@
   @override
   NodeListImpl<Annotation> get metadata => _metadata;
 
-  set metadata(List<Annotation> metadata) {
-    _metadata.clear();
-    _metadata.addAll(metadata);
-  }
-
-  @override
-  Token? get name => _identifier?.token;
-
   @override
   List<AstNode> get sortedCommentAndAnnotations {
     var comment = _comment;
@@ -8949,10 +9322,12 @@
 class NullLiteralImpl extends LiteralImpl implements NullLiteral {
   /// The token representing the literal.
   @override
-  Token literal;
+  final Token literal;
 
   /// Initialize a newly created null literal.
-  NullLiteralImpl(this.literal);
+  NullLiteralImpl({
+    required this.literal,
+  });
 
   @override
   Token get beginToken => literal;
@@ -8968,7 +9343,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitNullLiteral(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitNullLiteral(this, contextType: contextType);
   }
 
@@ -9011,13 +9386,16 @@
 ///        'on' [TypeName] (',' [TypeName])*
 class OnClauseImpl extends AstNodeImpl implements OnClause {
   @override
-  Token onKeyword;
+  final Token onKeyword;
 
   /// The classes are super-class constraints for the mixin.
   final NodeListImpl<NamedType> _superclassConstraints = NodeListImpl._();
 
   /// Initialize a newly created on clause.
-  OnClauseImpl(this.onKeyword, List<NamedType> superclassConstraints) {
+  OnClauseImpl({
+    required this.onKeyword,
+    required List<NamedType> superclassConstraints,
+  }) {
     _superclassConstraints._initialize(this, superclassConstraints);
   }
 
@@ -9025,15 +9403,11 @@
   Token get beginToken => onKeyword;
 
   @override
-  Token get endToken => _superclassConstraints.endToken!;
+  Token get endToken => _superclassConstraints.endToken ?? onKeyword;
 
   @override
   NodeListImpl<NamedType> get superclassConstraints => _superclassConstraints;
 
-  @Deprecated('Use superclassConstraints instead')
-  @override
-  NodeListImpl<NamedType> get superclassConstraints2 => _superclassConstraints;
-
   @override
   // TODO(paulberry): add commas.
   ChildEntities get _childEntities => ChildEntities()
@@ -9110,7 +9484,7 @@
       visitor.visitParenthesizedExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitParenthesizedExpression(this, contextType: contextType);
   }
 
@@ -9120,6 +9494,64 @@
   }
 }
 
+/// A parenthesized pattern.
+///
+///    parenthesizedPattern ::=
+///        '(' [DartPattern] ')'
+@experimental
+class ParenthesizedPatternImpl extends DartPatternImpl
+    implements ParenthesizedPattern {
+  @override
+  final Token leftParenthesis;
+
+  @override
+  final DartPatternImpl pattern;
+
+  @override
+  final Token rightParenthesis;
+
+  ParenthesizedPatternImpl(
+      {required this.leftParenthesis,
+      required this.pattern,
+      required this.rightParenthesis}) {
+    _becomeParentOf(pattern);
+  }
+
+  @override
+  Token get beginToken => leftParenthesis;
+
+  @override
+  Token get endToken => rightParenthesis;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('leftParenthesis', leftParenthesis)
+    ..addNode('pattern', pattern)
+    ..addToken('rightParenthesis', rightParenthesis);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitParenthesizedPattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    resolverVisitor.dispatchPattern(matchedType, typeInfos, context, pattern);
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    pattern.accept(visitor);
+  }
+}
+
 /// A part directive.
 ///
 ///    partDirective ::=
@@ -9155,20 +9587,6 @@
   @override
   Token get firstTokenAfterCommentAndMetadata => partKeyword;
 
-  @Deprecated('Use specific xyzToken instead')
-  @override
-  Token get keyword => partKeyword;
-
-  @Deprecated('Use element2.uri instead')
-  @override
-  CompilationUnitElement? get uriElement {
-    final partElementUri = element2?.uri;
-    if (partElementUri is DirectiveUriWithUnit) {
-      return partElementUri.unit;
-    }
-    return null;
-  }
-
   @override
   ChildEntities get _childEntities => super._childEntities
     ..addToken('partKeyword', partKeyword)
@@ -9227,10 +9645,6 @@
   @override
   Token get firstTokenAfterCommentAndMetadata => partKeyword;
 
-  @Deprecated('Use specific xyzToken instead')
-  @override
-  Token get keyword => partKeyword;
-
   @override
   LibraryIdentifierImpl? get libraryName => _libraryName;
 
@@ -9264,6 +9678,193 @@
   }
 }
 
+/// A pattern assignment.
+///
+///    patternAssignment ::=
+///        [DartPattern] '=' [Expression]
+///
+/// When used as the condition in an `if`, the pattern is always a
+/// [PatternVariable] whose type is not `null`.
+@experimental
+class PatternAssignmentImpl extends ExpressionImpl
+    implements PatternAssignment {
+  @override
+  final Token equals;
+
+  @override
+  final ExpressionImpl expression;
+
+  @override
+  final DartPatternImpl pattern;
+
+  PatternAssignmentImpl(
+      {required this.pattern, required this.equals, required this.expression}) {
+    _becomeParentOf(pattern);
+    _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => pattern.beginToken;
+
+  @override
+  Token get endToken => expression.endToken;
+
+  @override
+  // TODO(brianwilkerson) Create a new precedence constant for pattern
+  //  assignments. The proposal doesn't make the actual value clear.
+  Precedence get precedence => Precedence.assignment;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('pattern', pattern)
+    ..addToken('equals', equals)
+    ..addNode('expression', expression);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitPatternAssignment(this);
+
+  @override
+  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+    // TODO(brianwilkerson) implement resolveExpression
+    throw UnimplementedError();
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    pattern.accept(visitor);
+    expression.accept(visitor);
+  }
+}
+
+/// A pattern assignment used as a statement.
+///
+///    patternAssignmentStatement ::=
+///        [PatternAssignment] ';'
+class PatternAssignmentStatementImpl extends StatementImpl
+    implements PatternAssignmentStatement {
+  @override
+  final PatternAssignmentImpl assignment;
+
+  @override
+  final Token semicolon;
+
+  PatternAssignmentStatementImpl(
+      {required this.assignment, required this.semicolon}) {
+    _becomeParentOf(assignment);
+  }
+
+  @override
+  Token get beginToken => assignment.beginToken;
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('assignment', assignment)
+    ..addToken('semicolon', semicolon);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitPatternAssignmentStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    assignment.accept(visitor);
+  }
+}
+
+/// A pattern variable declaration.
+///
+///    patternDeclaration ::=
+///        ( 'final' | 'var' ) [DartPattern] '=' [Expression]
+@experimental
+class PatternVariableDeclarationImpl extends AstNodeImpl
+    implements PatternVariableDeclaration {
+  @override
+  final Token equals;
+
+  @override
+  final ExpressionImpl expression;
+
+  @override
+  final Token keyword;
+
+  @override
+  final DartPatternImpl pattern;
+
+  PatternVariableDeclarationImpl(
+      {required this.keyword,
+      required this.pattern,
+      required this.equals,
+      required this.expression}) {
+    _becomeParentOf(pattern);
+    _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => keyword;
+
+  @override
+  Token get endToken => expression.endToken;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('keyword', keyword)
+    ..addNode('pattern', pattern)
+    ..addToken('equals', equals)
+    ..addNode('expression', expression);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitPatternVariableDeclaration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    pattern.accept(visitor);
+    expression.accept(visitor);
+  }
+}
+
+/// A pattern variable declaration statement.
+///
+///    patternDeclarationStatement ::=
+///        [PatternVariableDeclaration] ';'
+@experimental
+class PatternVariableDeclarationStatementImpl extends StatementImpl
+    implements PatternVariableDeclarationStatement {
+  @override
+  final PatternVariableDeclarationImpl declaration;
+
+  @override
+  final Token semicolon;
+
+  PatternVariableDeclarationStatementImpl(
+      {required this.declaration, required this.semicolon}) {
+    _becomeParentOf(declaration);
+  }
+
+  @override
+  Token get beginToken => declaration.beginToken;
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('declaration', declaration)
+    ..addToken('semicolon', semicolon);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitPatternVariableDeclarationStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    declaration.accept(visitor);
+  }
+}
+
 /// A postfix unary expression.
 ///
 ///    postfixExpression ::=
@@ -9332,7 +9933,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitPostfixExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitPostfixExpression(this, contextType: contextType);
   }
 
@@ -9346,6 +9947,57 @@
       identical(descendant, operand);
 }
 
+/// A postfix (unary) pattern.
+///
+///    postfixPattern ::=
+///        [DartPattern] ('?' | '!')
+@experimental
+class PostfixPatternImpl extends DartPatternImpl implements PostfixPattern {
+  @override
+  final DartPatternImpl operand;
+
+  @override
+  final Token operator;
+
+  PostfixPatternImpl({required this.operand, required this.operator}) {
+    _becomeParentOf(operand);
+  }
+
+  @override
+  Token get beginToken => operand.beginToken;
+
+  @override
+  Token get endToken => operator;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('operand', operand)
+    ..addToken('operator', operator);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitPostfixPattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    resolverVisitor.analyzeNullCheckOrAssertPattern(
+        matchedType, typeInfos, context, this, operand,
+        isAssert: operator.type == TokenType.BANG);
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    operand.accept(visitor);
+  }
+}
+
 /// An identifier that is prefixed or an access to an object property where the
 /// target of the property access is a simple identifier.
 ///
@@ -9423,7 +10075,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitPrefixedIdentifier(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitPrefixedIdentifier(this, contextType: contextType);
   }
 
@@ -9502,7 +10154,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitPrefixExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitPrefixExpression(this, contextType: contextType);
   }
 
@@ -9621,7 +10273,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitPropertyAccess(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitPropertyAccess(this, contextType: contextType);
   }
 
@@ -9651,7 +10303,7 @@
 
   /// Initialize a newly created record literal.
   RecordLiteralImpl(
-      {this.constKeyword,
+      {required this.constKeyword,
       required this.leftParenthesis,
       required List<Expression> fields,
       required this.rightParenthesis}) {
@@ -9682,7 +10334,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitRecordLiteral(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitRecordLiteral(this, contextType: contextType);
   }
 
@@ -9692,6 +10344,138 @@
   }
 }
 
+/// A field in a record pattern.
+///
+///    recordPatternField ::=
+///        [RecordPatternFieldName]? [DartPattern]
+@experimental
+class RecordPatternFieldImpl extends AstNodeImpl implements RecordPatternField {
+  @override
+  final RecordPatternFieldNameImpl? fieldName;
+
+  @override
+  final DartPatternImpl pattern;
+
+  RecordPatternFieldImpl({required this.fieldName, required this.pattern}) {
+    _becomeParentOf(fieldName);
+    _becomeParentOf(pattern);
+  }
+
+  @override
+  Token get beginToken => fieldName?.beginToken ?? pattern.beginToken;
+
+  @override
+  Token get endToken => pattern.endToken;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNode('fieldName', fieldName)
+    ..addNode('pattern', pattern);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitRecordPatternField(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    fieldName?.accept(visitor);
+    pattern.accept(visitor);
+  }
+}
+
+/// A field name in a record pattern field.
+///
+///    recordPatternField ::=
+///        [Token]? ':'
+@experimental
+class RecordPatternFieldNameImpl extends AstNodeImpl
+    implements RecordPatternFieldName {
+  @override
+  final Token colon;
+
+  @override
+  final Token? name;
+
+  RecordPatternFieldNameImpl({required this.name, required this.colon});
+
+  @override
+  Token get beginToken => name ?? colon;
+
+  @override
+  Token get endToken => colon;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('name', name)
+    ..addToken('colon', colon);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitRecordPatternFieldName(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/// A record pattern.
+///
+///    recordPattern ::=
+///        '(' [RecordPatternField] (',' [RecordPatternField])* ')'
+@experimental
+class RecordPatternImpl extends DartPatternImpl implements RecordPattern {
+  final NodeListImpl<RecordPatternField> _fields = NodeListImpl._();
+
+  @override
+  final Token leftParenthesis;
+
+  @override
+  final Token rightParenthesis;
+
+  RecordPatternImpl(
+      {required this.leftParenthesis,
+      required List<RecordPatternField> fields,
+      required this.rightParenthesis}) {
+    _fields._initialize(this, fields);
+  }
+
+  @override
+  Token get beginToken => leftParenthesis;
+
+  @override
+  Token get endToken => rightParenthesis;
+
+  @override
+  NodeList<RecordPatternField> get fields => _fields;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('leftParenthesis', leftParenthesis)
+    ..addNodeList('fields', fields)
+    ..addToken('rightParenthesis', rightParenthesis);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitRecordPattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/50066
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    fields.accept(visitor);
+  }
+}
+
 abstract class RecordTypeAnnotationFieldImpl extends AstNodeImpl
     implements RecordTypeAnnotationField {
   @override
@@ -9938,6 +10722,56 @@
   }
 }
 
+/// A relational pattern.
+///
+///    relationalPattern ::=
+///        (equalityOperator | relationalOperator) [Expression]
+@experimental
+class RelationalPatternImpl extends DartPatternImpl
+    implements RelationalPattern {
+  @override
+  final ExpressionImpl operand;
+
+  @override
+  final Token operator;
+
+  RelationalPatternImpl({required this.operator, required this.operand}) {
+    _becomeParentOf(operand);
+  }
+
+  @override
+  Token get beginToken => operator;
+
+  @override
+  Token get endToken => operand.endToken;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('operator', operator)
+    ..addNode('operand', operand);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitRelationalPattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/50066
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    operand.accept(visitor);
+  }
+}
+
 /// A rethrow expression.
 ///
 ///    rethrowExpression ::=
@@ -9968,7 +10802,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitRethrowExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitRethrowExpression(this, contextType: contextType);
   }
 
@@ -10148,7 +10982,7 @@
   }
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitSetOrMapLiteral(this, contextType: contextType);
   }
 
@@ -10210,7 +11044,10 @@
   final NodeListImpl<SimpleIdentifier> _shownNames = NodeListImpl._();
 
   /// Initialize a newly created import show combinator.
-  ShowCombinatorImpl(super.keyword, List<SimpleIdentifier> shownNames) {
+  ShowCombinatorImpl({
+    required super.keyword,
+    required List<SimpleIdentifier> shownNames,
+  }) {
     _shownNames._initialize(this, shownNames);
   }
 
@@ -10307,9 +11144,8 @@
       Token? requiredKeyword,
       this.keyword,
       this._type,
-      SimpleIdentifierImpl? identifier)
-      : super(
-            comment, metadata, covariantKeyword, requiredKeyword, identifier) {
+      Token? name)
+      : super(comment, metadata, covariantKeyword, requiredKeyword, name) {
     _becomeParentOf(_type);
   }
 
@@ -10363,8 +11199,6 @@
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
     _type?.accept(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    identifier?.accept(visitor);
   }
 }
 
@@ -10517,9 +11351,6 @@
         return false;
       }
     }
-    if (parent is CatchClauseParameterImpl && parent.nameNode == this) {
-      return false;
-    }
     if (parent is ConstructorFieldInitializer &&
         identical(parent.fieldName, target)) {
       return false;
@@ -10529,18 +11360,6 @@
         return false;
       }
     }
-    if (parent is FieldFormalParameter) {
-      // ignore: deprecated_member_use_from_same_package
-      if (identical(parent.identifier, target)) {
-        return false;
-      }
-    }
-    if (parent is VariableDeclaration) {
-      // ignore: deprecated_member_use_from_same_package
-      if (identical(parent.name, target)) {
-        return false;
-      }
-    }
     return true;
   }
 
@@ -10579,7 +11398,7 @@
   }
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitSimpleIdentifier(this, contextType: contextType);
   }
 
@@ -10658,7 +11477,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitSimpleStringLiteral(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitSimpleStringLiteral(this, contextType: contextType);
   }
 
@@ -10723,6 +11542,7 @@
   void resolveElement(
       ResolverVisitor resolver, CollectionLiteralContext? context) {
     resolver.visitSpreadElement(this, context: context);
+    resolver.pushRewrite(null);
   }
 
   @override
@@ -10835,7 +11655,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitStringInterpolation(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitStringInterpolation(this, contextType: contextType);
   }
 
@@ -11069,7 +11889,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitSuperExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitSuperExpression(this, contextType: contextType);
   }
 
@@ -11131,12 +11951,11 @@
       this._type,
       this.superKeyword,
       this.period,
-      SimpleIdentifierImpl identifier,
+      Token name,
       this._typeParameters,
       this._parameters,
       this.question)
-      : super(
-            comment, metadata, covariantKeyword, requiredKeyword, identifier) {
+      : super(comment, metadata, covariantKeyword, requiredKeyword, name) {
     _becomeParentOf(_type);
     _becomeParentOf(_typeParameters);
     _becomeParentOf(_parameters);
@@ -11164,10 +11983,6 @@
     return question ?? _parameters?.endToken ?? name;
   }
 
-  @Deprecated('Use name instead')
-  @override
-  SimpleIdentifierImpl get identifier => super.identifier!;
-
   @override
   bool get isConst => keyword?.keyword == Keyword.CONST;
 
@@ -11219,8 +12034,6 @@
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
     _type?.accept(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    identifier.accept(visitor);
     _typeParameters?.accept(visitor);
     _parameters?.accept(visitor);
   }
@@ -11294,6 +12107,189 @@
   }
 }
 
+/// A case in a switch expression.
+///
+///    switchExpressionCase ::=
+///        'case' [DartPattern] [WhenClause]? '=>' [Expression]
+@experimental
+class SwitchExpressionCaseImpl extends SwitchExpressionMemberImpl
+    implements SwitchExpressionCase {
+  @override
+  final WhenClauseImpl? whenClause;
+
+  @override
+  final DartPatternImpl pattern;
+
+  SwitchExpressionCaseImpl(
+      {required super.keyword,
+      required this.pattern,
+      required this.whenClause,
+      required super.arrow,
+      required super.expression}) {
+    _becomeParentOf(whenClause);
+    _becomeParentOf(pattern);
+  }
+
+  @override
+  Token get beginToken => keyword;
+
+  @override
+  Token get endToken => expression.endToken;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('keyword', keyword)
+    ..addNode('pattern', pattern)
+    ..addNode('whenClause', whenClause)
+    ..addToken('arrow', arrow)
+    ..addNode('expression', expression);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitSwitchExpressionCase(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    pattern.accept(visitor);
+    whenClause?.accept(visitor);
+    expression.accept(visitor);
+  }
+}
+
+/// The default case in a switch expression.
+///
+///    switchDefault ::=
+///        'default' '=>' [Expression]
+@experimental
+class SwitchExpressionDefaultImpl extends SwitchExpressionMemberImpl
+    implements SwitchExpressionDefault {
+  SwitchExpressionDefaultImpl(
+      {required super.keyword,
+      required super.arrow,
+      required super.expression});
+
+  @override
+  Token get beginToken => keyword;
+
+  @override
+  Token get endToken => expression.endToken;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('keyword', keyword)
+    ..addToken('arrow', arrow)
+    ..addNode('expression', expression);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitSwitchExpressionDefault(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    expression.accept(visitor);
+  }
+}
+
+/// A switch expression.
+///
+///    switchExpression ::=
+///        'switch' '(' [Expression] ')' '{' [SwitchExpressionCase]*
+///        [SwitchExpressionDefault]? '}'
+@experimental
+class SwitchExpressionImpl extends ExpressionImpl implements SwitchExpression {
+  @override
+  final ExpressionImpl expression;
+
+  @override
+  final Token leftBracket;
+
+  @override
+  final Token leftParenthesis;
+
+  final NodeListImpl<SwitchExpressionMember> _members = NodeListImpl._();
+
+  @override
+  final Token rightBracket;
+
+  @override
+  final Token rightParenthesis;
+
+  @override
+  final Token switchKeyword;
+
+  SwitchExpressionImpl(
+      {required this.switchKeyword,
+      required this.leftParenthesis,
+      required this.expression,
+      required this.rightParenthesis,
+      required this.leftBracket,
+      required List<SwitchExpressionMember> members,
+      required this.rightBracket}) {
+    _becomeParentOf(expression);
+    _members._initialize(this, members);
+  }
+
+  @override
+  Token get beginToken => switchKeyword;
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  NodeList<SwitchExpressionMember> get members => _members;
+
+  @override
+  Precedence get precedence => Precedence.primary;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('switchKeyword', switchKeyword)
+    ..addToken('leftParenthesis', leftParenthesis)
+    ..addNode('expression', expression)
+    ..addToken('rightParenthesis', rightParenthesis)
+    ..addToken('leftBracket', leftBracket)
+    ..addNodeList('members', members)
+    ..addToken('rightBracket', rightBracket);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitSwitchExpression(this);
+
+  @override
+  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+    // TODO: implement resolveExpression
+    throw UnimplementedError();
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    expression.accept(visitor);
+    members.accept(visitor);
+  }
+}
+
+/// A member within a switch expression.
+///
+///    switchExpressionMember ::=
+///        [SwitchExpressionCase]
+///      | [SwitchExpressionDefault]
+@experimental
+abstract class SwitchExpressionMemberImpl extends AstNodeImpl
+    implements SwitchExpressionMember {
+  @override
+  final Token arrow;
+
+  @override
+  final ExpressionImpl expression;
+
+  @override
+  final Token keyword;
+
+  SwitchExpressionMemberImpl(
+      {required this.keyword, required this.arrow, required this.expression}) {
+    _becomeParentOf(expression);
+  }
+}
+
 /// An element within a switch statement.
 ///
 ///    switchMember ::=
@@ -11345,6 +12341,52 @@
   NodeListImpl<Statement> get statements => _statements;
 }
 
+/// A pattern-based case in a switch statement.
+///
+///    switchPatternCase ::=
+///        [Label]* 'case' [DartPattern] [WhenClause]? ':' [Statement]*
+@experimental
+class SwitchPatternCaseImpl extends SwitchMemberImpl
+    implements SwitchPatternCase {
+  @override
+  final WhenClauseImpl? whenClause;
+
+  @override
+  final DartPatternImpl pattern;
+
+  SwitchPatternCaseImpl(
+      {required List<Label> labels,
+      required Token keyword,
+      required this.pattern,
+      required this.whenClause,
+      required Token colon,
+      required List<Statement> statements})
+      : super(labels, keyword, colon, statements) {
+    _becomeParentOf(pattern);
+    _becomeParentOf(whenClause);
+  }
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addNodeList('labels', labels)
+    ..addToken('keyword', keyword)
+    ..addNode('pattern', pattern)
+    ..addNode('whenClause', whenClause)
+    ..addToken('colon', colon)
+    ..addNodeList('statements', statements);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitSwitchPatternCase(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    labels.accept(visitor);
+    pattern.accept(visitor);
+    whenClause?.accept(visitor);
+    statements.accept(visitor);
+  }
+}
+
 /// A switch statement.
 ///
 ///    switchStatement ::=
@@ -11459,7 +12501,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitSymbolLiteral(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitSymbolLiteral(this, contextType: contextType);
   }
 
@@ -11498,7 +12540,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitThisExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitThisExpression(this, contextType: contextType);
   }
 
@@ -11552,7 +12594,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitThrowExpression(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitThrowExpression(this, contextType: contextType);
   }
 
@@ -11595,6 +12637,7 @@
   @override
   Element? get declaredElement => null;
 
+  @Deprecated('Use declaredElement instead')
   @override
   Element? get declaredElement2 => null;
 
@@ -11895,7 +12938,7 @@
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitTypeLiteral(this);
 
   @override
-  void resolveExpression(ResolverVisitor resolver, DartType? contextType) {
+  void resolveExpression(ResolverVisitor resolver, DartType contextType) {
     resolver.visitTypeLiteral(this, contextType: contextType);
   }
 
@@ -11912,8 +12955,8 @@
 ///
 ///    typeParameterVariance ::= 'out' | 'inout' | 'in'
 class TypeParameterImpl extends DeclarationImpl implements TypeParameter {
-  /// The name of the type parameter.
-  SimpleIdentifierImpl _name;
+  @override
+  Token name;
 
   /// The token representing the variance modifier keyword, or `null` if
   /// there is no explicit variance modifier, meaning legacy covariance.
@@ -11929,7 +12972,7 @@
   TypeAnnotationImpl? _bound;
 
   @override
-  TypeParameterElement? declaredElement2;
+  TypeParameterElement? declaredElement;
 
   /// Initialize a newly created type parameter. Either or both of the [comment]
   /// and [metadata] can be `null` if the parameter does not have the
@@ -11938,13 +12981,11 @@
   TypeParameterImpl({
     required super.comment,
     required super.metadata,
-    required SimpleIdentifierImpl name,
+    required this.name,
     required this.extendsKeyword,
     required TypeAnnotationImpl? bound,
     this.varianceKeyword,
-  })  : _name = name,
-        _bound = bound {
-    _becomeParentOf(_name);
+  }) : _bound = bound {
     _becomeParentOf(_bound);
   }
 
@@ -11955,35 +12996,28 @@
     _bound = _becomeParentOf(type as TypeAnnotationImpl?);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  TypeParameterElement? get declaredElement => declaredElement2;
+  TypeParameterElement? get declaredElement2 => declaredElement;
 
   @override
   Token get endToken {
     if (_bound == null) {
-      return _name.endToken;
+      return name;
     }
     return _bound!.endToken;
   }
 
   @override
-  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
+  Token get firstTokenAfterCommentAndMetadata => name;
 
-  @Deprecated('Use name2 instead')
+  @Deprecated('Use name instead')
   @override
-  SimpleIdentifierImpl get name => _name;
-
-  set name(SimpleIdentifier identifier) {
-    _name = _becomeParentOf(identifier as SimpleIdentifierImpl);
-  }
-
-  @override
-  Token get name2 => _name.token;
+  Token get name2 => name;
 
   @override
   ChildEntities get _childEntities => super._childEntities
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addToken('extendsKeyword', extendsKeyword)
     ..addNode('bound', bound);
 
@@ -11993,8 +13027,6 @@
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     _bound?.accept(visitor);
   }
 }
@@ -12056,14 +13088,6 @@
   /// The URI referenced by this directive.
   StringLiteralImpl _uri;
 
-  @Deprecated('Use element2.uri instead')
-  @override
-  String? uriContent;
-
-  @Deprecated('Use element2.uri instead')
-  @override
-  Source? uriSource;
-
   /// Initialize a newly create URI-based directive. Either or both of the
   /// [comment] and [metadata] can be `null` if the directive does not have the
   /// corresponding attribute.
@@ -12082,11 +13106,6 @@
     _uri = _becomeParentOf(uri as StringLiteralImpl);
   }
 
-  @Deprecated('Use element2.uri instead')
-  UriValidationCode? validate() {
-    return validateUri(this is ImportDirective, uri, uriContent);
-  }
-
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
@@ -12148,11 +13167,11 @@
 /// extend [Declaration].
 class VariableDeclarationImpl extends DeclarationImpl
     implements VariableDeclaration {
-  /// The name of the variable being declared.
-  SimpleIdentifierImpl _name;
+  @override
+  Token name;
 
   @override
-  VariableElement? declaredElement2;
+  VariableElement? declaredElement;
 
   /// The equal sign separating the variable name from the initial value, or
   /// `null` if the initial value was not specified.
@@ -12172,19 +13191,17 @@
   /// Initialize a newly created variable declaration. The [equals] and
   /// [initializer] can be `null` if there is no initializer.
   VariableDeclarationImpl({
-    required SimpleIdentifierImpl name,
+    required this.name,
     required this.equals,
     required ExpressionImpl? initializer,
-  })  : _name = name,
-        _initializer = initializer,
+  })  : _initializer = initializer,
         super(comment: null, metadata: null) {
-    _becomeParentOf(_name);
     _becomeParentOf(_initializer);
   }
 
-  @Deprecated('Use declaredElement2 instead')
+  @Deprecated('Use declaredElement instead')
   @override
-  VariableElement? get declaredElement => declaredElement2;
+  VariableElement? get declaredElement2 => declaredElement;
 
   /// This overridden implementation of [documentationComment] looks in the
   /// grandparent node for Dartdoc comments if no documentation is specifically
@@ -12206,11 +13223,11 @@
     if (_initializer != null) {
       return _initializer!.endToken;
     }
-    return _name.endToken;
+    return name;
   }
 
   @override
-  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
+  Token get firstTokenAfterCommentAndMetadata => name;
 
   @override
   ExpressionImpl? get initializer => _initializer;
@@ -12237,23 +13254,13 @@
     return parent is VariableDeclarationList && parent.isLate;
   }
 
-  @Deprecated('Use name2 instead')
+  @Deprecated('Use name instead')
   @override
-  SimpleIdentifierImpl get name {
-    _name.staticElement = declaredElement;
-    return _name;
-  }
-
-  set name(SimpleIdentifier identifier) {
-    _name = _becomeParentOf(identifier as SimpleIdentifierImpl);
-  }
-
-  @override
-  Token get name2 => _name.token;
+  Token get name2 => name;
 
   @override
   ChildEntities get _childEntities => super._childEntities
-    ..addToken('name', name2)
+    ..addToken('name', name)
     ..addToken('equals', equals)
     ..addNode('initializer', initializer);
 
@@ -12263,8 +13270,6 @@
   @override
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    name.accept(visitor);
     _initializer?.accept(visitor);
   }
 }
@@ -12410,6 +13415,102 @@
   }
 }
 
+/// A variable pattern.
+///
+///    variablePattern ::=
+///        ( 'var' | 'final' | [TypeAnnotation])? [Identifier]
+@experimental
+class VariablePatternImpl extends DartPatternImpl implements VariablePattern {
+  @override
+  VariablePatternElementImpl? declaredElement;
+
+  @override
+  final Token? keyword;
+
+  @override
+  final Token name;
+
+  @override
+  final TypeAnnotationImpl? type;
+
+  VariablePatternImpl(
+      {required this.name, required this.keyword, required this.type}) {
+    _becomeParentOf(type);
+  }
+
+  @override
+  Token get beginToken => type?.beginToken ?? name;
+
+  @override
+  Token get endToken => name;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('keyword', keyword)
+    ..addNode('type', type)
+    ..addToken('name', name);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitVariablePattern(this);
+
+  @override
+  DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  void resolvePattern(
+      ResolverVisitor resolverVisitor,
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context) {
+    resolverVisitor.analyzeVariablePattern(matchedType, typeInfos, context,
+        this, declaredElement, type?.typeOrThrow,
+        isFinal: keyword?.keyword == Keyword.FINAL);
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    type?.accept(visitor);
+  }
+}
+
+/// A guard in a pattern-based `case` in a `switch` statement or `switch`
+/// expression.
+///
+///    switchCase ::=
+///        'when' [Expression]
+@experimental
+class WhenClauseImpl extends AstNodeImpl implements WhenClause {
+  @override
+  final ExpressionImpl expression;
+
+  @override
+  final Token whenKeyword;
+
+  WhenClauseImpl({required this.whenKeyword, required this.expression}) {
+    _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => whenKeyword;
+
+  @override
+  Token get endToken => expression.endToken;
+
+  @override
+  ChildEntities get _childEntities => super._childEntities
+    ..addToken('whenKeyword', whenKeyword)
+    ..addNode('expression', expression);
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitWhenClause(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    expression.accept(visitor);
+  }
+}
+
 /// A while statement.
 ///
 ///    whileStatement ::=
@@ -12499,15 +13600,11 @@
   Token get beginToken => withKeyword;
 
   @override
-  Token get endToken => _mixinTypes.endToken!;
+  Token get endToken => _mixinTypes.endToken ?? withKeyword;
 
   @override
   NodeListImpl<NamedType> get mixinTypes => _mixinTypes;
 
-  @Deprecated('Use mixinTypes instead')
-  @override
-  NodeListImpl<NamedType> get mixinTypes2 => _mixinTypes;
-
   @override
   // TODO(paulberry): add commas.
   ChildEntities get _childEntities => ChildEntities()
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index acd41d7..cff2f3e 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -40,13 +40,6 @@
   CommentImpl endOfLineComment(List<Token> tokens) =>
       CommentImpl.createEndOfLineComment(tokens);
 
-  ExpressionStatementImpl expressionStatement(
-          Expression expression, Token? semicolon) =>
-      ExpressionStatementImpl(expression as ExpressionImpl, semicolon);
-
-  ExtendsClauseImpl extendsClause(Token extendsKeyword, NamedType superclass) =>
-      ExtendsClauseImpl(extendsKeyword, superclass as NamedTypeImpl);
-
   ExtensionOverrideImpl extensionOverride(
           {required Identifier extensionName,
           TypeArgumentList? typeArguments,
@@ -65,7 +58,7 @@
           TypeAnnotation? type,
           required Token thisKeyword,
           required Token period,
-          required SimpleIdentifier identifier,
+          required Token name,
           TypeParameterList? typeParameters,
           FormalParameterList? parameters,
           Token? question}) =>
@@ -78,40 +71,11 @@
           type as TypeAnnotationImpl?,
           thisKeyword,
           period,
-          identifier as SimpleIdentifierImpl,
+          name,
           typeParameters as TypeParameterListImpl?,
           parameters as FormalParameterListImpl?,
           question);
 
-  ForEachPartsWithDeclarationImpl forEachPartsWithDeclaration(
-          {required DeclaredIdentifier loopVariable,
-          required Token inKeyword,
-          required Expression iterable}) =>
-      ForEachPartsWithDeclarationImpl(loopVariable as DeclaredIdentifierImpl,
-          inKeyword, iterable as ExpressionImpl);
-
-  ForEachPartsWithIdentifierImpl forEachPartsWithIdentifier(
-          {required SimpleIdentifier identifier,
-          required Token inKeyword,
-          required Expression iterable}) =>
-      ForEachPartsWithIdentifierImpl(identifier as SimpleIdentifierImpl,
-          inKeyword, iterable as ExpressionImpl);
-
-  ForElementImpl forElement(
-          {Token? awaitKeyword,
-          required Token forKeyword,
-          required Token leftParenthesis,
-          required ForLoopParts forLoopParts,
-          required Token rightParenthesis,
-          required CollectionElement body}) =>
-      ForElementImpl(
-          awaitKeyword,
-          forKeyword,
-          leftParenthesis,
-          forLoopParts as ForLoopPartsImpl,
-          rightParenthesis,
-          body as CollectionElementImpl);
-
   FormalParameterListImpl formalParameterList(
           Token leftParenthesis,
           List<FormalParameter> parameters,
@@ -121,79 +85,13 @@
       FormalParameterListImpl(leftParenthesis, parameters, leftDelimiter,
           rightDelimiter, rightParenthesis);
 
-  ForPartsWithDeclarationsImpl forPartsWithDeclarations(
-          {required VariableDeclarationList variables,
-          required Token leftSeparator,
-          Expression? condition,
-          required Token rightSeparator,
-          List<Expression>? updaters}) =>
-      ForPartsWithDeclarationsImpl(
-          variables as VariableDeclarationListImpl,
-          leftSeparator,
-          condition as ExpressionImpl?,
-          rightSeparator,
-          updaters);
-
-  ForPartsWithExpressionImpl forPartsWithExpression(
-          {Expression? initialization,
-          required Token leftSeparator,
-          Expression? condition,
-          required Token rightSeparator,
-          List<Expression>? updaters}) =>
-      ForPartsWithExpressionImpl(
-          initialization as ExpressionImpl?,
-          leftSeparator,
-          condition as ExpressionImpl?,
-          rightSeparator,
-          updaters);
-
-  ForStatementImpl forStatement(
-      {Token? awaitKeyword,
-      required Token forKeyword,
-      required Token leftParenthesis,
-      required ForLoopParts forLoopParts,
-      required Token rightParenthesis,
-      required Statement body}) {
-    return ForStatementImpl(
-        awaitKeyword,
-        forKeyword,
-        leftParenthesis,
-        forLoopParts as ForLoopPartsImpl,
-        rightParenthesis,
-        body as StatementImpl);
-  }
-
-  FunctionDeclarationStatementImpl functionDeclarationStatement(
-          FunctionDeclaration functionDeclaration) =>
-      FunctionDeclarationStatementImpl(
-          functionDeclaration as FunctionDeclarationImpl);
-
-  FunctionExpressionImpl functionExpression(TypeParameterList? typeParameters,
-          FormalParameterList? parameters, FunctionBody body) =>
-      FunctionExpressionImpl(typeParameters as TypeParameterListImpl?,
-          parameters as FormalParameterListImpl?, body as FunctionBodyImpl);
-
-  FunctionExpressionInvocationImpl functionExpressionInvocation(
-          Expression function,
-          TypeArgumentList? typeArguments,
-          ArgumentList argumentList) =>
-      FunctionExpressionInvocationImpl(
-          function as ExpressionImpl,
-          typeArguments as TypeArgumentListImpl?,
-          argumentList as ArgumentListImpl);
-
-  FunctionReferenceImpl functionReference(
-          {required Expression function, TypeArgumentList? typeArguments}) =>
-      FunctionReferenceImpl(function as ExpressionImpl,
-          typeArguments: typeArguments as TypeArgumentListImpl?);
-
   FunctionTypedFormalParameterImpl functionTypedFormalParameter2(
           {Comment? comment,
           List<Annotation>? metadata,
           Token? covariantKeyword,
           Token? requiredKeyword,
           TypeAnnotation? returnType,
-          required SimpleIdentifier identifier,
+          required Token name,
           TypeParameterList? typeParameters,
           required FormalParameterList parameters,
           Token? question}) =>
@@ -203,71 +101,11 @@
           covariantKeyword,
           requiredKeyword,
           returnType as TypeAnnotationImpl?,
-          identifier as SimpleIdentifierImpl,
+          name,
           typeParameters as TypeParameterListImpl?,
           parameters as FormalParameterListImpl,
           question);
 
-  GenericFunctionTypeImpl genericFunctionType(
-          TypeAnnotation? returnType,
-          Token functionKeyword,
-          TypeParameterList? typeParameters,
-          FormalParameterList parameters,
-          {Token? question}) =>
-      GenericFunctionTypeImpl(
-          returnType as TypeAnnotationImpl?,
-          functionKeyword,
-          typeParameters as TypeParameterListImpl?,
-          parameters as FormalParameterListImpl,
-          question: question);
-
-  HideClauseImpl hideClause(
-          {required Token hideKeyword,
-          required List<ShowHideClauseElement> elements}) =>
-      HideClauseImpl(hideKeyword, elements);
-
-  HideCombinatorImpl hideCombinator(
-          Token keyword, List<SimpleIdentifier> hiddenNames) =>
-      HideCombinatorImpl(keyword, hiddenNames);
-
-  IfElementImpl ifElement(
-          {required Token ifKeyword,
-          required Token leftParenthesis,
-          required Expression condition,
-          required Token rightParenthesis,
-          required CollectionElement thenElement,
-          Token? elseKeyword,
-          CollectionElement? elseElement}) =>
-      IfElementImpl(
-          ifKeyword,
-          leftParenthesis,
-          condition as ExpressionImpl,
-          rightParenthesis,
-          thenElement as CollectionElementImpl,
-          elseKeyword,
-          elseElement as CollectionElementImpl?);
-
-  IfStatementImpl ifStatement(
-          Token ifKeyword,
-          Token leftParenthesis,
-          Expression condition,
-          Token rightParenthesis,
-          Statement thenStatement,
-          Token? elseKeyword,
-          Statement? elseStatement) =>
-      IfStatementImpl(
-          ifKeyword,
-          leftParenthesis,
-          condition as ExpressionImpl,
-          rightParenthesis,
-          thenStatement as StatementImpl,
-          elseKeyword,
-          elseStatement as StatementImpl?);
-
-  ImplementsClauseImpl implementsClause(
-          Token implementsKeyword, List<NamedType> interfaces) =>
-      ImplementsClauseImpl(implementsKeyword, interfaces);
-
   ImplicitCallReferenceImpl implicitCallReference({
     required Expression expression,
     required MethodElement staticElement,
@@ -306,25 +144,16 @@
           argumentList as ArgumentListImpl,
           typeArguments: typeArguments as TypeArgumentListImpl?);
 
-  IntegerLiteralImpl integerLiteral(Token literal, int? value) =>
-      IntegerLiteralImpl(literal, value);
-
   InterpolationExpressionImpl interpolationExpression(
           Token leftBracket, Expression expression, Token? rightBracket) =>
       InterpolationExpressionImpl(
           leftBracket, expression as ExpressionImpl, rightBracket);
 
-  InterpolationStringImpl interpolationString(Token contents, String value) =>
-      InterpolationStringImpl(contents, value);
-
   IsExpressionImpl isExpression(Expression expression, Token isOperator,
           Token? notOperator, TypeAnnotation type) =>
       IsExpressionImpl(expression as ExpressionImpl, isOperator, notOperator,
           type as TypeAnnotationImpl);
 
-  LabelImpl label(SimpleIdentifier label, Token colon) =>
-      LabelImpl(label as SimpleIdentifierImpl, colon);
-
   LabeledStatementImpl labeledStatement(
           List<Label> labels, Statement statement) =>
       LabeledStatementImpl(labels, statement as StatementImpl);
@@ -354,39 +183,6 @@
         rightBracket);
   }
 
-  MapLiteralEntryImpl mapLiteralEntry(
-          Expression key, Token separator, Expression value) =>
-      MapLiteralEntryImpl(
-          key as ExpressionImpl, separator, value as ExpressionImpl);
-
-  MethodInvocationImpl methodInvocation(
-          Expression? target,
-          Token? operator,
-          SimpleIdentifier methodName,
-          TypeArgumentList? typeArguments,
-          ArgumentList argumentList) =>
-      MethodInvocationImpl(
-          target as ExpressionImpl?,
-          operator,
-          methodName as SimpleIdentifierImpl,
-          typeArguments as TypeArgumentListImpl?,
-          argumentList as ArgumentListImpl);
-
-  NamedExpressionImpl namedExpression(Label name, Expression expression) =>
-      NamedExpressionImpl(name as LabelImpl, expression as ExpressionImpl);
-
-  NamedTypeImpl namedType({
-    required Identifier name,
-    TypeArgumentList? typeArguments,
-    Token? question,
-  }) =>
-      NamedTypeImpl(
-          name as IdentifierImpl, typeArguments as TypeArgumentListImpl?,
-          question: question);
-
-  NativeClauseImpl nativeClause(Token nativeKeyword, StringLiteral? name) =>
-      NativeClauseImpl(nativeKeyword, name as StringLiteralImpl?);
-
   NativeFunctionBodyImpl nativeFunctionBody(
           Token nativeKeyword, StringLiteral? stringLiteral, Token semicolon) =>
       NativeFunctionBodyImpl(
@@ -395,12 +191,6 @@
   NodeListImpl<E> nodeList<E extends AstNode>(AstNode owner) =>
       NodeListImpl<E>(owner as AstNodeImpl);
 
-  NullLiteralImpl nullLiteral(Token literal) => NullLiteralImpl(literal);
-
-  OnClauseImpl onClause(
-          Token onKeyword, List<NamedType> superclassConstraints) =>
-      OnClauseImpl(onKeyword, superclassConstraints);
-
   ParenthesizedExpressionImpl parenthesizedExpression(Token leftParenthesis,
           Expression expression, Token rightParenthesis) =>
       ParenthesizedExpressionImpl(
@@ -457,10 +247,6 @@
           required List<ShowHideClauseElement> elements}) =>
       ShowClauseImpl(showKeyword, elements);
 
-  ShowCombinatorImpl showCombinator(
-          Token keyword, List<SimpleIdentifier> shownNames) =>
-      ShowCombinatorImpl(keyword, shownNames);
-
   ShowHideElementImpl showHideElement(
           {required Token? modifier, required SimpleIdentifier name}) =>
       ShowHideElementImpl(modifier, name);
@@ -472,7 +258,7 @@
           Token? requiredKeyword,
           Token? keyword,
           TypeAnnotation? type,
-          required SimpleIdentifier? identifier}) =>
+          required Token? name}) =>
       SimpleFormalParameterImpl(
           comment as CommentImpl?,
           metadata,
@@ -480,7 +266,7 @@
           requiredKeyword,
           keyword,
           type as TypeAnnotationImpl?,
-          identifier as SimpleIdentifierImpl?);
+          name);
 
   SimpleIdentifierImpl simpleIdentifier(Token token,
       {bool isDeclaration = false}) {
@@ -524,7 +310,7 @@
           TypeAnnotation? type,
           required Token superKeyword,
           required Token period,
-          required SimpleIdentifier identifier,
+          required Token name,
           TypeParameterList? typeParameters,
           FormalParameterList? parameters,
           Token? question}) =>
@@ -537,7 +323,7 @@
           type as TypeAnnotationImpl?,
           superKeyword,
           period,
-          identifier as SimpleIdentifierImpl,
+          name,
           typeParameters as TypeParameterListImpl?,
           parameters as FormalParameterListImpl?,
           question);
diff --git a/pkg/analyzer/lib/src/dart/ast/element_locator.dart b/pkg/analyzer/lib/src/dart/ast/element_locator.dart
index 83dc795..2a5004c 100644
--- a/pkg/analyzer/lib/src/dart/ast/element_locator.dart
+++ b/pkg/analyzer/lib/src/dart/ast/element_locator.dart
@@ -38,7 +38,12 @@
 
   @override
   Element? visitClassDeclaration(ClassDeclaration node) {
-    return node.declaredElement2;
+    return node.declaredElement;
+  }
+
+  @override
+  Element? visitClassTypeAlias(ClassTypeAlias node) {
+    return node.declaredElement;
   }
 
   @override
@@ -48,7 +53,7 @@
 
   @override
   Element? visitConstructorDeclaration(ConstructorDeclaration node) {
-    return node.declaredElement2;
+    return node.declaredElement;
   }
 
   @override
@@ -64,28 +69,43 @@
   }
 
   @override
+  Element? visitDeclaredIdentifier(DeclaredIdentifier node) {
+    return node.declaredElement;
+  }
+
+  @override
+  Element? visitEnumDeclaration(EnumDeclaration node) {
+    return node.declaredElement;
+  }
+
+  @override
   Element? visitExportDirective(ExportDirective node) {
     return node.element2;
   }
 
   @override
+  Element? visitExtensionDeclaration(ExtensionDeclaration node) {
+    return node.declaredElement;
+  }
+
+  @override
   Element? visitFormalParameter(FormalParameter node) {
     return node.declaredElement;
   }
 
   @override
   Element? visitFunctionDeclaration(FunctionDeclaration node) {
-    return node.declaredElement2;
+    return node.declaredElement;
   }
 
   @override
   Element? visitFunctionTypeAlias(FunctionTypeAlias node) {
-    return node.declaredElement2;
+    return node.declaredElement;
   }
 
   @override
   Element? visitGenericTypeAlias(GenericTypeAlias node) {
-    return node.declaredElement2;
+    return node.declaredElement;
   }
 
   @override
@@ -101,16 +121,16 @@
       // Constructor Elements
       var returnType = parent.returnType;
       if (identical(returnType, node)) {
-        var name = parent.name2;
+        var name = parent.name;
         if (name != null) {
-          return parent.declaredElement2;
+          return parent.declaredElement;
         }
         var element = node.staticElement;
-        if (element is ClassElement) {
+        if (element is InterfaceElement) {
           return element.unnamedConstructor;
         }
-      } else if (parent.name2 == node.endToken) {
-        return parent.declaredElement2;
+      } else if (parent.name == node.endToken) {
+        return parent.declaredElement;
       }
     } else if (parent is LibraryIdentifier) {
       var grandParent = parent.parent;
@@ -148,7 +168,7 @@
 
   @override
   Element? visitMethodDeclaration(MethodDeclaration node) {
-    return node.declaredElement2;
+    return node.declaredElement;
   }
 
   @override
@@ -157,6 +177,11 @@
   }
 
   @override
+  Element? visitMixinDeclaration(MixinDeclaration node) {
+    return node.declaredElement;
+  }
+
+  @override
   Element? visitPartOfDirective(PartOfDirective node) {
     return node.element2;
   }
@@ -194,11 +219,11 @@
 
   @override
   Element? visitTypeParameter(TypeParameter node) {
-    return node.declaredElement2;
+    return node.declaredElement;
   }
 
   @override
   Element? visitVariableDeclaration(VariableDeclaration node) {
-    return node.declaredElement2;
+    return node.declaredElement;
   }
 }
diff --git a/pkg/analyzer/lib/src/dart/ast/invokes_super_self.dart b/pkg/analyzer/lib/src/dart/ast/invokes_super_self.dart
index c17d674..8525340 100644
--- a/pkg/analyzer/lib/src/dart/ast/invokes_super_self.dart
+++ b/pkg/analyzer/lib/src/dart/ast/invokes_super_self.dart
@@ -72,7 +72,7 @@
 extension MethodDeclarationExtension on MethodDeclaration {
   bool get invokesSuperSelf {
     var visitor = _SuperVisitor(
-      name2.lexeme,
+      name.lexeme,
       isSetter ? _Usage.writing : _Usage.reading,
     );
     body.accept(visitor);
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 f09dfe3..75bf992 100644
--- a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
@@ -101,6 +101,15 @@
   }
 
   @override
+  void visitBinaryPattern(BinaryPattern node) {
+    _visitNode(node.leftOperand);
+    sink.write(' ');
+    sink.write(node.operator.lexeme);
+    sink.write(' ');
+    _visitNode(node.rightOperand);
+  }
+
+  @override
   void visitBlock(Block node) {
     sink.write('{');
     _visitNodeList(node.statements, separator: ' ');
@@ -139,6 +148,20 @@
   }
 
   @override
+  void visitCaseClause(CaseClause node) {
+    sink.write('case ');
+    _visitNode(node.pattern);
+    _visitNode(node.whenClause, prefix: ' ');
+  }
+
+  @override
+  void visitCastPattern(CastPattern node) {
+    _visitNode(node.pattern);
+    sink.write(' as ');
+    _visitNode(node.type);
+  }
+
+  @override
   void visitCatchClause(CatchClause node) {
     _visitNode(node.exceptionType, prefix: 'on ');
     if (node.catchKeyword != null) {
@@ -167,7 +190,7 @@
     _visitToken(node.macroKeyword, suffix: ' ');
     _visitToken(node.augmentKeyword, suffix: ' ');
     sink.write('class ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.typeParameters);
     _visitNode(node.extendsClause, prefix: ' ');
     _visitNode(node.withClause, prefix: ' ');
@@ -180,13 +203,11 @@
   @override
   void visitClassTypeAlias(covariant ClassTypeAliasImpl node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
-    if (node.abstractKeyword != null) {
-      sink.write('abstract ');
-    }
-    _visitToken(node.macroKeyword, suffix: ' ');
     _visitToken(node.augmentKeyword, suffix: ' ');
+    _visitToken(node.abstractKeyword, suffix: ' ');
+    _visitToken(node.macroKeyword, suffix: ' ');
     sink.write('class ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.typeParameters);
     sink.write(' = ');
     _visitNode(node.superclass);
@@ -231,13 +252,19 @@
   }
 
   @override
+  void visitConstantPattern(ConstantPattern node) {
+    _visitToken(node.constKeyword, suffix: ' ');
+    _visitNode(node.expression);
+  }
+
+  @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
     _visitToken(node.externalKeyword, suffix: ' ');
     _visitToken(node.constKeyword, suffix: ' ');
     _visitToken(node.factoryKeyword, suffix: ' ');
     _visitNode(node.returnType);
-    _visitToken(node.name2, prefix: '.');
+    _visitToken(node.name, prefix: '.');
     _visitNode(node.parameters);
     _visitNodeList(node.initializers, prefix: ' : ', separator: ', ');
     _visitNode(node.redirectedConstructor, prefix: ' = ');
@@ -336,7 +363,7 @@
   @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.arguments);
   }
 
@@ -344,7 +371,7 @@
   void visitEnumDeclaration(EnumDeclaration node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
     sink.write('enum ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.typeParameters);
     _visitNode(node.withClause, prefix: ' ');
     _visitNode(node.implementsClause, prefix: ' ');
@@ -399,7 +426,7 @@
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
     _visitToken(node.extensionKeyword, suffix: ' ');
     _visitToken(node.typeKeyword, suffix: ' ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.typeParameters);
     sink.write(' ');
     _visitToken(node.onKeyword);
@@ -420,6 +447,15 @@
   }
 
   @override
+  void visitExtractorPattern(ExtractorPattern node) {
+    _visitNode(node.typeName);
+    _visitNode(node.typeArguments);
+    sink.write('(');
+    _visitNodeList(node.fields, separator: ', ');
+    sink.write(')');
+  }
+
+  @override
   void visitFieldDeclaration(FieldDeclaration node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
     _visitToken(node.abstractKeyword, suffix: ' ');
@@ -457,6 +493,14 @@
   }
 
   @override
+  void visitForEachPartsWithPattern(ForEachPartsWithPattern node) {
+    sink.write(node.keyword.lexeme);
+    _visitNode(node.pattern);
+    sink.write(' in ');
+    _visitNode(node.iterable);
+  }
+
+  @override
   void visitForElement(ForElement node) {
     _visitToken(node.awaitKeyword, suffix: ' ');
     sink.write('for (');
@@ -512,6 +556,15 @@
   }
 
   @override
+  void visitForPartsWithPattern(ForPartsWithPattern node) {
+    _visitNode(node.variables);
+    sink.write('; ');
+    _visitNode(node.condition);
+    sink.write('; ');
+    _visitNodeList(node.updaters, separator: ', ');
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     if (node.awaitKeyword != null) {
       sink.write('await ');
@@ -528,7 +581,7 @@
     _visitToken(node.externalKeyword, suffix: ' ');
     _visitNode(node.returnType, suffix: ' ');
     _visitToken(node.propertyKeyword, suffix: ' ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.functionExpression);
   }
 
@@ -562,7 +615,7 @@
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
     sink.write('typedef ');
     _visitNode(node.returnType, suffix: ' ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.typeParameters);
     _visitNode(node.parameters);
     sink.write(';');
@@ -597,7 +650,7 @@
   void visitGenericTypeAlias(GenericTypeAlias node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
     sink.write('typedef ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.typeParameters);
     sink.write(' = ');
     _visitNode(node.type);
@@ -620,6 +673,7 @@
   void visitIfElement(IfElement node) {
     sink.write('if (');
     _visitNode(node.condition);
+    _visitNode(node.caseClause, prefix: ' ');
     sink.write(') ');
     _visitNode(node.thenElement);
     _visitNode(node.elseElement, prefix: ' else ');
@@ -629,6 +683,7 @@
   void visitIfStatement(IfStatement node) {
     sink.write('if (');
     _visitNode(node.condition);
+    _visitNode(node.caseClause, prefix: ' ');
     sink.write(') ');
     _visitNode(node.thenStatement);
     _visitNode(node.elseStatement, prefix: ' else ');
@@ -738,7 +793,7 @@
   void visitLibraryDirective(LibraryDirective node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
     sink.write('library ');
-    _visitNode(node.name);
+    _visitNode(node.name2);
     sink.write(';');
   }
 
@@ -757,6 +812,14 @@
   }
 
   @override
+  void visitListPattern(ListPattern node) {
+    _visitNode(node.typeArguments);
+    sink.write('[');
+    _visitNodeList(node.elements, separator: ', ');
+    sink.write(']');
+  }
+
+  @override
   void visitMapLiteralEntry(MapLiteralEntry node) {
     _visitNode(node.key);
     sink.write(' : ');
@@ -764,6 +827,21 @@
   }
 
   @override
+  void visitMapPattern(MapPattern node) {
+    _visitNode(node.typeArguments);
+    sink.write('{');
+    _visitNodeList(node.entries, separator: ', ');
+    sink.write('}');
+  }
+
+  @override
+  void visitMapPatternEntry(MapPatternEntry node) {
+    _visitNode(node.key);
+    sink.write(': ');
+    _visitNode(node.value);
+  }
+
+  @override
   void visitMethodDeclaration(MethodDeclaration node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
     _visitToken(node.externalKeyword, suffix: ' ');
@@ -771,7 +849,7 @@
     _visitNode(node.returnType, suffix: ' ');
     _visitToken(node.propertyKeyword, suffix: ' ');
     _visitToken(node.operatorKeyword, suffix: ' ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     if (!node.isGetter) {
       _visitNode(node.typeParameters);
       _visitNode(node.parameters);
@@ -792,7 +870,7 @@
   void visitMixinDeclaration(MixinDeclaration node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
     sink.write('mixin ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.typeParameters);
     _visitNode(node.onClause, prefix: ' ');
     _visitNode(node.implementsClause, prefix: ' ');
@@ -848,6 +926,13 @@
   }
 
   @override
+  void visitParenthesizedPattern(ParenthesizedPattern node) {
+    sink.write('(');
+    _visitNode(node.pattern);
+    sink.write(')');
+  }
+
+  @override
   void visitPartDirective(PartDirective node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
     sink.write('part ');
@@ -865,12 +950,47 @@
   }
 
   @override
+  void visitPatternAssignment(PatternAssignment node) {
+    _visitNode(node.pattern);
+    sink.write(' = ');
+    _visitNode(node.expression);
+  }
+
+  @override
+  void visitPatternAssignmentStatement(PatternAssignmentStatement node) {
+    _visitNode(node.assignment);
+    sink.write(';');
+  }
+
+  @override
+  void visitPatternVariableDeclaration(PatternVariableDeclaration node) {
+    sink.write(node.keyword.lexeme);
+    sink.write(' ');
+    _visitNode(node.pattern);
+    sink.write(' = ');
+    _visitNode(node.expression);
+  }
+
+  @override
+  void visitPatternVariableDeclarationStatement(
+      PatternVariableDeclarationStatement node) {
+    _visitNode(node.declaration);
+    sink.write(';');
+  }
+
+  @override
   void visitPostfixExpression(PostfixExpression node) {
     _writeOperand(node, node.operand);
     sink.write(node.operator.lexeme);
   }
 
   @override
+  void visitPostfixPattern(PostfixPattern node) {
+    _visitNode(node.operand);
+    sink.write(node.operator.lexeme);
+  }
+
+  @override
   void visitPrefixedIdentifier(PrefixedIdentifier node) {
     _visitNode(node.prefix);
     sink.write('.');
@@ -902,6 +1022,29 @@
   }
 
   @override
+  void visitRecordPattern(RecordPattern node) {
+    var fields = node.fields;
+    sink.write('(');
+    _visitNodeList(fields, separator: ', ');
+    if (fields.length == 1) {
+      sink.write(',');
+    }
+    sink.write(')');
+  }
+
+  @override
+  void visitRecordPatternField(RecordPatternField node) {
+    _visitNode(node.fieldName, suffix: ' ');
+    _visitNode(node.pattern);
+  }
+
+  @override
+  void visitRecordPatternFieldName(RecordPatternFieldName node) {
+    _visitToken(node.name);
+    sink.write(':');
+  }
+
+  @override
   void visitRecordTypeAnnotation(RecordTypeAnnotation node) {
     var positionalFields = node.positionalFields;
     var namedFields = node.namedFields;
@@ -915,6 +1058,9 @@
     }
     _visitNode(namedFields);
     sink.write(')');
+    if (node.question != null) {
+      sink.write('?');
+    }
   }
 
   @override
@@ -952,6 +1098,13 @@
   }
 
   @override
+  void visitRelationalPattern(RelationalPattern node) {
+    sink.write(node.operator.lexeme);
+    sink.write(' ');
+    _visitNode(node.operand);
+  }
+
+  @override
   void visitRethrowExpression(RethrowExpression node) {
     sink.write('rethrow');
   }
@@ -1076,6 +1229,40 @@
   }
 
   @override
+  void visitSwitchExpression(SwitchExpression node) {
+    sink.write('switch (');
+    _visitNode(node.expression);
+    sink.write(') {');
+    _visitNodeList(node.members, separator: ' ');
+    sink.write('}');
+  }
+
+  @override
+  void visitSwitchExpressionCase(SwitchExpressionCase node) {
+    sink.write('case ');
+    _visitNode(node.pattern);
+    _visitNode(node.whenClause, prefix: ' ');
+    sink.write(' => ');
+    _visitNode(node.expression);
+  }
+
+  @override
+  void visitSwitchExpressionDefault(SwitchExpressionDefault node) {
+    sink.write('default => ');
+    _visitNode(node.expression);
+  }
+
+  @override
+  void visitSwitchPatternCase(SwitchPatternCase node) {
+    _visitNodeList(node.labels, separator: ' ', suffix: ' ');
+    sink.write('case ');
+    _visitNode(node.pattern);
+    _visitNode(node.whenClause, prefix: ' ');
+    sink.write(': ');
+    _visitNodeList(node.statements, separator: ' ');
+  }
+
+  @override
   void visitSwitchStatement(SwitchStatement node) {
     sink.write('switch (');
     _visitNode(node.expression);
@@ -1142,7 +1329,7 @@
     if (varianceKeyword != null) {
       sink.write('${varianceKeyword.lexeme} ');
     }
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.bound, prefix: ' extends ');
   }
 
@@ -1156,7 +1343,7 @@
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
     _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
-    _visitToken(node.name2);
+    _visitToken(node.name);
     _visitNode(node.initializer, prefix: ' = ');
   }
 
@@ -1176,6 +1363,19 @@
   }
 
   @override
+  void visitVariablePattern(VariablePattern node) {
+    _visitToken(node.keyword, suffix: ' ');
+    _visitNode(node.type, suffix: ' ');
+    sink.write(node.name.lexeme);
+  }
+
+  @override
+  void visitWhenClause(WhenClause node) {
+    sink.write('when ');
+    _visitNode(node.expression);
+  }
+
+  @override
   void visitWhileStatement(WhileStatement node) {
     sink.write('while (');
     _visitNode(node.condition);
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 30c9ff0..c1b9276 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -186,6 +186,14 @@
   }
 
   @override
+  bool visitBinaryPattern(BinaryPattern node) {
+    var other = _other as BinaryPattern;
+    return isEqualNodes(node.leftOperand, other.leftOperand) &&
+        isEqualTokens(node.operator, other.operator) &&
+        isEqualNodes(node.rightOperand, other.rightOperand);
+  }
+
+  @override
   bool visitBlock(Block node) {
     Block other = _other as Block;
     return isEqualTokens(node.leftBracket, other.leftBracket) &&
@@ -222,6 +230,22 @@
   }
 
   @override
+  bool visitCaseClause(CaseClause node) {
+    var other = _other as CaseClause;
+    return isEqualTokens(node.caseKeyword, other.caseKeyword) &&
+        isEqualNodes(node.pattern, other.pattern) &&
+        isEqualNodes(node.whenClause, other.whenClause);
+  }
+
+  @override
+  bool visitCastPattern(CastPattern node) {
+    var other = _other as CastPattern;
+    return isEqualNodes(node.pattern, other.pattern) &&
+        isEqualTokens(node.asToken, other.asToken) &&
+        isEqualNodes(node.type, other.type);
+  }
+
+  @override
   bool visitCatchClause(CatchClause node) {
     CatchClause other = _other as CatchClause;
     return isEqualTokens(node.onKeyword, other.onKeyword) &&
@@ -249,7 +273,7 @@
         _isEqualNodeLists(node.metadata, other.metadata) &&
         isEqualTokens(node.abstractKeyword, other.abstractKeyword) &&
         isEqualTokens(node.classKeyword, other.classKeyword) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualNodes(node.typeParameters, other.typeParameters) &&
         isEqualNodes(node.extendsClause, other.extendsClause) &&
         isEqualNodes(node.withClause, other.withClause) &&
@@ -266,7 +290,7 @@
             node.documentationComment, other.documentationComment) &&
         _isEqualNodeLists(node.metadata, other.metadata) &&
         isEqualTokens(node.typedefKeyword, other.typedefKeyword) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualNodes(node.typeParameters, other.typeParameters) &&
         isEqualTokens(node.equals, other.equals) &&
         isEqualTokens(node.abstractKeyword, other.abstractKeyword) &&
@@ -322,6 +346,13 @@
   }
 
   @override
+  bool visitConstantPattern(ConstantPattern node) {
+    var other = _other as ConstantPattern;
+    return isEqualTokens(node.constKeyword, other.constKeyword) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
   bool visitConstructorDeclaration(ConstructorDeclaration node) {
     ConstructorDeclaration other = _other as ConstructorDeclaration;
     return isEqualNodes(
@@ -332,7 +363,7 @@
         isEqualTokens(node.factoryKeyword, other.factoryKeyword) &&
         isEqualNodes(node.returnType, other.returnType) &&
         isEqualTokens(node.period, other.period) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualNodes(node.parameters, other.parameters) &&
         isEqualTokens(node.separator, other.separator) &&
         _isEqualNodeLists(node.initializers, other.initializers) &&
@@ -450,7 +481,7 @@
     return isEqualNodes(
             node.documentationComment, other.documentationComment) &&
         _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.name2, other.name2);
+        isEqualTokens(node.name, other.name);
   }
 
   @override
@@ -460,7 +491,7 @@
             node.documentationComment, other.documentationComment) &&
         _isEqualNodeLists(node.metadata, other.metadata) &&
         isEqualTokens(node.enumKeyword, other.enumKeyword) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualTokens(node.leftBracket, other.leftBracket) &&
         _isEqualNodeLists(node.constants, other.constants) &&
         isEqualTokens(node.rightBracket, other.rightBracket);
@@ -507,7 +538,7 @@
             node.documentationComment, other.documentationComment) &&
         _isEqualNodeLists(node.metadata, other.metadata) &&
         isEqualTokens(node.extensionKeyword, other.extensionKeyword) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualNodes(node.typeParameters, other.typeParameters) &&
         isEqualTokens(node.onKeyword, other.onKeyword) &&
         isEqualNodes(node.extendedType, other.extendedType) &&
@@ -525,6 +556,16 @@
   }
 
   @override
+  bool visitExtractorPattern(ExtractorPattern node) {
+    var other = _other as ExtractorPattern;
+    return isEqualNodes(node.typeName, other.typeName) &&
+        isEqualNodes(node.typeArguments, other.typeArguments) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        _isEqualNodeLists(node.fields, other.fields) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis);
+  }
+
+  @override
   bool visitFieldDeclaration(FieldDeclaration node) {
     FieldDeclaration other = _other as FieldDeclaration;
     return isEqualTokens(node.abstractKeyword, other.abstractKeyword) &&
@@ -567,6 +608,15 @@
   }
 
   @override
+  bool visitForEachPartsWithPattern(ForEachPartsWithPattern node) {
+    var other = _other as ForEachPartsWithPattern;
+    return isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.pattern, other.pattern) &&
+        isEqualTokens(node.inKeyword, other.inKeyword) &&
+        isEqualNodes(node.iterable, other.iterable);
+  }
+
+  @override
   bool visitForElement(ForElement node) {
     ForElement other = _other as ForElement;
     return isEqualTokens(node.awaitKeyword, other.awaitKeyword) &&
@@ -608,6 +658,16 @@
   }
 
   @override
+  bool visitForPartsWithPattern(ForPartsWithPattern node) {
+    var other = _other as ForPartsWithPattern;
+    return isEqualNodes(node.variables, other.variables) &&
+        isEqualTokens(node.leftSeparator, other.leftSeparator) &&
+        isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.rightSeparator, other.rightSeparator) &&
+        _isEqualNodeLists(node.updaters, other.updaters);
+  }
+
+  @override
   bool visitForStatement(ForStatement node) {
     ForStatement other = _other as ForStatement;
     return isEqualTokens(node.forKeyword, other.forKeyword) &&
@@ -627,7 +687,7 @@
         isEqualTokens(node.externalKeyword, other.externalKeyword) &&
         isEqualNodes(node.returnType, other.returnType) &&
         isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualNodes(node.functionExpression, other.functionExpression);
   }
 
@@ -666,7 +726,7 @@
         _isEqualNodeLists(node.metadata, other.metadata) &&
         isEqualTokens(node.typedefKeyword, other.typedefKeyword) &&
         isEqualNodes(node.returnType, other.returnType) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualNodes(node.typeParameters, other.typeParameters) &&
         isEqualNodes(node.parameters, other.parameters) &&
         isEqualTokens(node.semicolon, other.semicolon);
@@ -700,7 +760,7 @@
             node.documentationComment, other.documentationComment) &&
         _isEqualNodeLists(node.metadata, other.metadata) &&
         isEqualTokens(node.typedefKeyword, other.typedefKeyword) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualNodes(node.typeParameters, other.typeParameters) &&
         isEqualTokens(node.equals, other.equals) &&
         isEqualNodes(node.type, other.type);
@@ -855,7 +915,7 @@
             node.documentationComment, other.documentationComment) &&
         _isEqualNodeLists(node.metadata, other.metadata) &&
         isEqualTokens(node.libraryKeyword, other.libraryKeyword) &&
-        isEqualNodes(node.name, other.name) &&
+        isEqualNodes(node.name2, other.name2) &&
         isEqualTokens(node.semicolon, other.semicolon);
   }
 
@@ -876,6 +936,15 @@
   }
 
   @override
+  bool visitListPattern(ListPattern node) {
+    var other = _other as ListPattern;
+    return isEqualNodes(node.typeArguments, other.typeArguments) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.elements, other.elements) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
   bool visitMapLiteralEntry(MapLiteralEntry node) {
     MapLiteralEntry other = _other as MapLiteralEntry;
     return isEqualNodes(node.key, other.key) &&
@@ -884,6 +953,23 @@
   }
 
   @override
+  bool visitMapPattern(MapPattern node) {
+    var other = _other as MapPattern;
+    return isEqualNodes(node.typeArguments, other.typeArguments) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.entries, other.entries) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitMapPatternEntry(MapPatternEntry node) {
+    var other = _other as MapPatternEntry;
+    return isEqualNodes(node.key, other.key) &&
+        isEqualTokens(node.separator, other.separator) &&
+        isEqualNodes(node.value, other.value);
+  }
+
+  @override
   bool visitMethodDeclaration(MethodDeclaration node) {
     MethodDeclaration other = _other as MethodDeclaration;
     return isEqualNodes(
@@ -894,7 +980,7 @@
         isEqualNodes(node.returnType, other.returnType) &&
         isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
         isEqualTokens(node.operatorKeyword, other.operatorKeyword) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualNodes(node.parameters, other.parameters) &&
         isEqualNodes(node.body, other.body);
   }
@@ -915,7 +1001,7 @@
             node.documentationComment, other.documentationComment) &&
         _isEqualNodeLists(node.metadata, other.metadata) &&
         isEqualTokens(node.mixinKeyword, other.mixinKeyword) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualNodes(node.typeParameters, other.typeParameters) &&
         isEqualNodes(node.onClause, other.onClause) &&
         isEqualNodes(node.implementsClause, other.implementsClause) &&
@@ -977,6 +1063,14 @@
   }
 
   @override
+  bool visitParenthesizedPattern(ParenthesizedPattern node) {
+    var other = _other as ParenthesizedPattern;
+    return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.pattern, other.pattern) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis);
+  }
+
+  @override
   bool visitPartDirective(PartDirective node) {
     PartDirective other = _other as PartDirective;
     return isEqualNodes(
@@ -1000,6 +1094,38 @@
   }
 
   @override
+  bool visitPatternAssignment(PatternAssignment node) {
+    var other = _other as PatternAssignment;
+    return isEqualNodes(node.pattern, other.pattern) &&
+        isEqualTokens(node.equals, other.equals) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
+  bool visitPatternAssignmentStatement(PatternAssignmentStatement node) {
+    var other = _other as PatternAssignmentStatement;
+    return isEqualNodes(node.assignment, other.assignment) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitPatternVariableDeclaration(PatternVariableDeclaration node) {
+    var other = _other as PatternVariableDeclaration;
+    return isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.pattern, other.pattern) &&
+        isEqualTokens(node.equals, other.equals) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
+  bool visitPatternVariableDeclarationStatement(
+      PatternVariableDeclarationStatement node) {
+    var other = _other as PatternVariableDeclarationStatement;
+    return isEqualNodes(node.declaration, other.declaration) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
   bool visitPostfixExpression(PostfixExpression node) {
     PostfixExpression other = _other as PostfixExpression;
     return isEqualNodes(node.operand, other.operand) &&
@@ -1007,6 +1133,13 @@
   }
 
   @override
+  bool visitPostfixPattern(PostfixPattern node) {
+    var other = _other as PostfixPattern;
+    return isEqualNodes(node.operand, other.operand) &&
+        isEqualTokens(node.operator, other.operator);
+  }
+
+  @override
   bool visitPrefixedIdentifier(PrefixedIdentifier node) {
     PrefixedIdentifier other = _other as PrefixedIdentifier;
     return isEqualNodes(node.prefix, other.prefix) &&
@@ -1038,6 +1171,28 @@
   }
 
   @override
+  bool visitRecordPattern(RecordPattern node) {
+    var other = _other as RecordPattern;
+    return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        _isEqualNodeLists(node.fields, other.fields) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis);
+  }
+
+  @override
+  bool visitRecordPatternField(RecordPatternField node) {
+    var other = _other as RecordPatternField;
+    return isEqualNodes(node.fieldName, other.fieldName) &&
+        isEqualNodes(node.pattern, other.pattern);
+  }
+
+  @override
+  bool visitRecordPatternFieldName(RecordPatternFieldName node) {
+    var other = _other as RecordPatternFieldName;
+    return isEqualTokens(node.name, other.name) &&
+        isEqualTokens(node.colon, other.colon);
+  }
+
+  @override
   bool visitRecordTypeAnnotation(RecordTypeAnnotation node) {
     var other = _other as RecordTypeAnnotation;
     return _isEqualNodeLists(node.positionalFields, other.positionalFields) &&
@@ -1084,6 +1239,13 @@
   }
 
   @override
+  bool visitRelationalPattern(RelationalPattern node) {
+    var other = _other as RelationalPattern;
+    return isEqualTokens(node.operator, other.operator) &&
+        isEqualNodes(node.operand, other.operand);
+  }
+
+  @override
   bool visitRethrowExpression(RethrowExpression node) {
     RethrowExpression other = _other as RethrowExpression;
     return isEqualTokens(node.rethrowKeyword, other.rethrowKeyword);
@@ -1219,6 +1381,47 @@
   }
 
   @override
+  bool visitSwitchExpression(SwitchExpression node) {
+    var other = _other as SwitchExpression;
+    return isEqualTokens(node.switchKeyword, other.switchKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.members, other.members) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitSwitchExpressionCase(SwitchExpressionCase node) {
+    var other = _other as SwitchExpressionCase;
+    return isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.pattern, other.pattern) &&
+        isEqualNodes(node.whenClause, other.whenClause) &&
+        isEqualTokens(node.arrow, other.arrow) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
+  bool visitSwitchExpressionDefault(SwitchExpressionDefault node) {
+    var other = _other as SwitchExpressionDefault;
+    return isEqualTokens(node.keyword, other.keyword) &&
+        isEqualTokens(node.arrow, other.arrow) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
+  bool visitSwitchPatternCase(SwitchPatternCase node) {
+    var other = _other as SwitchPatternCase;
+    return _isEqualNodeLists(node.labels, other.labels) &&
+        isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.pattern, other.pattern) &&
+        isEqualNodes(node.whenClause, other.whenClause) &&
+        isEqualTokens(node.colon, other.colon) &&
+        _isEqualNodeLists(node.statements, other.statements);
+  }
+
+  @override
   bool visitSwitchStatement(SwitchStatement node) {
     SwitchStatement other = _other as SwitchStatement;
     return isEqualTokens(node.switchKeyword, other.switchKeyword) &&
@@ -1293,7 +1496,7 @@
     return isEqualNodes(
             node.documentationComment, other.documentationComment) &&
         _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualTokens((node as TypeParameterImpl).varianceKeyword,
             (other as TypeParameterImpl).varianceKeyword) &&
         isEqualTokens(node.extendsKeyword, other.extendsKeyword) &&
@@ -1314,7 +1517,7 @@
     return isEqualNodes(
             node.documentationComment, other.documentationComment) &&
         _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.name2, other.name2) &&
+        isEqualTokens(node.name, other.name) &&
         isEqualTokens(node.equals, other.equals) &&
         isEqualNodes(node.initializer, other.initializer);
   }
@@ -1338,6 +1541,20 @@
   }
 
   @override
+  bool visitVariablePattern(VariablePattern node) {
+    var other = _other as VariablePattern;
+    return isEqualNodes(node.type, other.type) &&
+        isEqualTokens(node.name, other.name);
+  }
+
+  @override
+  bool visitWhenClause(WhenClause node) {
+    var other = _other as WhenClause;
+    return isEqualTokens(node.whenKeyword, other.whenKeyword) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
   bool visitWhileStatement(WhileStatement node) {
     WhileStatement other = _other as WhileStatement;
     return isEqualTokens(node.whileKeyword, other.whileKeyword) &&
@@ -1470,7 +1687,11 @@
 /// An object used to locate the [AstNode] associated with a source range, given
 /// the AST structure built from the source. More specifically, they will return
 /// the [AstNode] with the shortest length whose source range completely
-/// encompasses the specified range.
+/// encompasses the specified range with some exceptions:
+///
+/// - Offsets that fall between the name and type/formal parameter list of a
+///   declaration will return the declaration node and not the parameter list
+///   node.
 class NodeLocator extends UnifyingAstVisitor<void> {
   /// The start offset of the range used to identify the node.
   final int _startOffset;
@@ -1511,10 +1732,48 @@
               stackTrace));
       return null;
     }
+
     return _foundNode;
   }
 
   @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    // Names do not have AstNodes but offsets at the end should be treated as
+    // part of the decleration (not parameter list).
+    if (_startOffset == _endOffset &&
+        _startOffset == (node.name ?? node.returnType).end) {
+      _foundNode = node;
+      return;
+    }
+
+    super.visitConstructorDeclaration(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    // Names do not have AstNodes but offsets at the end should be treated as
+    // part of the decleration (not parameter list).
+    if (_startOffset == _endOffset && _startOffset == node.name.end) {
+      _foundNode = node;
+      return;
+    }
+
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    // Names do not have AstNodes but offsets at the end should be treated as
+    // part of the decleration (not parameter list).
+    if (_startOffset == _endOffset && _startOffset == node.name.end) {
+      _foundNode = node;
+      return;
+    }
+
+    super.visitMethodDeclaration(node);
+  }
+
+  @override
   void visitNode(AstNode node) {
     // Don't visit a new tree if the result has been already found.
     if (_foundNode != null) {
@@ -1562,7 +1821,11 @@
 
 /// An object used to locate the [AstNode] associated with a source range.
 /// More specifically, they will return the deepest [AstNode] which completely
-/// encompasses the specified range.
+/// encompasses the specified range with some exceptions:
+///
+/// - Offsets that fall between the name and type/formal parameter list of a
+///   declaration will return the declaration node and not the parameter list
+///   node.
 class NodeLocator2 extends UnifyingAstVisitor<void> {
   /// The inclusive start offset of the range used to identify the node.
   final int _startOffset;
@@ -1604,6 +1867,43 @@
   }
 
   @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    // Names do not have AstNodes but offsets at the end should be treated as
+    // part of the decleration (not parameter list).
+    if (_startOffset == _endOffset &&
+        _startOffset == (node.name ?? node.returnType).end) {
+      _foundNode = node;
+      return;
+    }
+
+    super.visitConstructorDeclaration(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    // Names do not have AstNodes but offsets at the end should be treated as
+    // part of the decleration (not parameter list).
+    if (_startOffset == _endOffset && _startOffset == node.name.end) {
+      _foundNode = node;
+      return;
+    }
+
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    // Names do not have AstNodes but offsets at the end should be treated as
+    // part of the decleration (not parameter list).
+    if (_startOffset == _endOffset && _startOffset == node.name.end) {
+      _foundNode = node;
+      return;
+    }
+
+    super.visitMethodDeclaration(node);
+  }
+
+  @override
   void visitNode(AstNode node) {
     // Don't visit a new tree if the result has been already found.
     if (_foundNode != null) {
@@ -1650,7 +1950,7 @@
 }
 
 /// An object that will replace one child node in an AST node with another node.
-class NodeReplacer implements AstVisitor<bool> {
+class NodeReplacer extends ThrowingAstVisitor<bool> {
   /// The node being replaced.
   final AstNode _oldNode;
 
@@ -1659,7 +1959,7 @@
 
   /// Initialize a newly created node locator to replace the [_oldNode] with the
   /// [_newNode].
-  NodeReplacer(this._oldNode, this._newNode);
+  NodeReplacer._(this._oldNode, this._newNode);
 
   @override
   bool visitAdjacentStrings(covariant AdjacentStringsImpl node) {
@@ -2563,7 +2863,7 @@
 
   @override
   bool visitLibraryDirective(covariant LibraryDirectiveImpl node) {
-    if (identical(node.name, _oldNode)) {
+    if (identical(node.name2, _oldNode)) {
       node.name = _newNode as LibraryIdentifier;
       return true;
     }
@@ -2688,15 +2988,6 @@
   }
 
   @override
-  bool visitNativeClause(covariant NativeClauseImpl node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as StringLiteral;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
   bool visitNativeFunctionBody(covariant NativeFunctionBodyImpl node) {
     if (identical(node.stringLiteral, _oldNode)) {
       node.stringLiteral = _newNode as StringLiteral;
@@ -3185,7 +3476,7 @@
     if (parent == null) {
       throw ArgumentError("The old node is not a child of another node");
     }
-    NodeReplacer replacer = NodeReplacer(oldNode, newNode);
+    NodeReplacer replacer = NodeReplacer._(oldNode, newNode);
     return parent.accept(replacer)!;
   }
 }
@@ -3321,7 +3612,7 @@
 
   void _addVariables(NodeList<VariableDeclaration> variables) {
     for (VariableDeclaration variable in variables) {
-      _addToScope(variable.name2);
+      _addToScope(variable.name);
     }
   }
 
@@ -3337,7 +3628,7 @@
         _addVariables(statement.variables.variables);
       } else if (statement is FunctionDeclarationStatement &&
           !_referenceIsWithinLocalFunction) {
-        _addToScope(statement.functionDeclaration.name2);
+        _addToScope(statement.functionDeclaration.name);
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index cdbfcc3..ad6d426 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -133,7 +133,7 @@
       _validateConstantArguments(argumentList);
     }
 
-    var element = node.declaredElement2 as ConstFieldElementImpl;
+    var element = node.declaredElement as ConstFieldElementImpl;
     var result = element.evaluationResult;
     if (result != null) {
       _reportErrors(result.errors, null);
@@ -291,7 +291,7 @@
     super.visitVariableDeclaration(node);
     var initializer = node.initializer;
     if (initializer != null && (node.isConst || node.isFinal)) {
-      var element = node.declaredElement2 as VariableElementImpl;
+      var element = node.declaredElement as VariableElementImpl;
       var result = element.evaluationResult;
       if (result == null) {
         // Variables marked "const" should have had their values computed by
@@ -374,7 +374,7 @@
       // lookup for ==
       var method = element.lookUpConcreteMethod("==", _currentLibrary);
       if (method == null ||
-          (method.enclosingElement3 as ClassElement).isDartCoreObject) {
+          (method.enclosingElement as ClassElement).isDartCoreObject) {
         return false;
       }
       // there is == that we don't like
@@ -578,7 +578,7 @@
         for (VariableDeclaration variableDeclaration
             in member.fields.variables) {
           if (isEnumDeclaration &&
-              variableDeclaration.name2.lexeme == 'values') {
+              variableDeclaration.name.lexeme == 'values') {
             continue;
           }
           var initializer = variableDeclaration.initializer;
@@ -599,7 +599,7 @@
                   CompileTimeErrorCode
                       .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
                   constKeyword,
-                  [variableDeclaration.name2.lexeme]);
+                  [variableDeclaration.name.lexeme]);
             }
           }
         }
@@ -664,7 +664,6 @@
   }
 
   void _validateSwitchStatement_nullSafety(SwitchStatement node) {
-    var switchType = node.expression.typeOrThrow;
     for (var switchMember in node.members) {
       if (switchMember is SwitchCase) {
         Expression expression = switchMember.expression;
@@ -692,15 +691,6 @@
             [expressionType],
           );
         }
-
-        if (!_typeSystem.isSubtypeOf(expressionType, switchType)) {
-          _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode
-                .CASE_EXPRESSION_TYPE_IS_NOT_SWITCH_EXPRESSION_SUBTYPE,
-            expression,
-            [expressionType, switchType],
-          );
-        }
       }
     }
   }
@@ -1091,7 +1081,7 @@
               !declarationListParent.isStatic) {
             var container = declarationListParent.parent;
             if (container is ClassDeclaration) {
-              var enclosingClass = container.declaredElement2;
+              var enclosingClass = container.declaredElement;
               if (enclosingClass != null) {
                 // A field initializer of a class with at least one generative
                 // const constructor does not constitute a constant context, but
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 2526e91..2d40948 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
@@ -214,7 +215,7 @@
   void computeDependencies(
       ConstantEvaluationTarget constant, ReferenceFinderCallback callback) {
     if (constant is ConstFieldElementImpl && constant.isEnumConstant) {
-      var enclosing = constant.enclosingElement3;
+      var enclosing = constant.enclosingElement;
       if (enclosing is EnumElementImpl) {
         if (enclosing.name == 'values') {
           return;
@@ -274,7 +275,7 @@
             }
           }
         }
-        for (FieldElement field in constant.enclosingElement3.fields) {
+        for (FieldElement field in constant.enclosingElement.fields) {
           // Note: non-static const isn't allowed but we handle it anyway so
           // that we won't be confused by incorrect code.
           if ((field.isFinal || field.isConst) &&
@@ -388,7 +389,7 @@
       return null;
     }
     var typeProvider = constructor.library.typeProvider;
-    if (constructor.enclosingElement3 == typeProvider.symbolElement) {
+    if (constructor.enclosingElement == typeProvider.symbolElement) {
       // The dart:core.Symbol has a const factory constructor that redirects
       // to dart:_internal.Symbol.  That in turn redirects to an external
       // const constructor, which we won't be able to evaluate.
@@ -412,7 +413,7 @@
 
   static _EnumConstant? _enumConstant(VariableElementImpl element) {
     if (element is ConstFieldElementImpl && element.isEnumConstant) {
-      var enum_ = element.enclosingElement3;
+      var enum_ = element.enclosingElement;
       if (enum_ is EnumElementImpl) {
         var index = enum_.constants.indexOf(element);
         assert(index >= 0);
@@ -889,7 +890,7 @@
       if (element.name == "identical") {
         NodeList<Expression> arguments = node.argumentList.arguments;
         if (arguments.length == 2) {
-          var enclosingElement = element.enclosingElement3;
+          var enclosingElement = element.enclosingElement;
           if (enclosingElement is CompilationUnitElement) {
             LibraryElement library = enclosingElement.library;
             if (library.isDartCore) {
@@ -958,7 +959,7 @@
     var prefixElement = prefixNode.staticElement;
     // String.length
     if (prefixElement is! PrefixElement &&
-        prefixElement is! ClassElement &&
+        prefixElement is! InterfaceElement &&
         prefixElement is! ExtensionElement) {
       var prefixResult = prefixNode.accept(this);
       if (prefixResult != null &&
@@ -1014,13 +1015,6 @@
 
   @override
   DartObjectImpl? visitRecordLiteral(RecordLiteral node) {
-    if (!node.isConst) {
-      // TODO(brianwilkerson) Merge the error codes into a single error code or
-      //  declare a new error code specific to records.
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL, node);
-      return null;
-    }
     var nodeType = node.staticType;
     if (nodeType == null) {
       return null;
@@ -1360,7 +1354,7 @@
         );
         return _instantiateFunctionTypeForSimpleIdentifier(identifier, rawType);
       }
-    } else if (variableElement is ClassElement) {
+    } else if (variableElement is InterfaceElement) {
       var type = variableElement.instantiate(
         typeArguments: variableElement.typeParameters
             .map((t) => _typeProvider.dynamicType)
@@ -1480,7 +1474,7 @@
       return false;
     }
     return identifier.name == 'length' &&
-        identifier.staticElement?.enclosingElement3 is! ExtensionElement;
+        identifier.staticElement?.enclosingElement is! ExtensionElement;
   }
 
   void _reportNotPotentialConstants(AstNode node) {
@@ -2181,7 +2175,7 @@
     List<Expression> arguments, {
     required bool isNullSafe,
   }) {
-    final definingClass = _constructor.enclosingElement3;
+    final definingClass = _constructor.enclosingElement;
     var argumentCount = arguments.length;
     if (_constructor.name == "fromEnvironment") {
       if (!_checkFromEnvironmentArguments(arguments, definingType)) {
@@ -2192,6 +2186,14 @@
       String? variableName =
           argumentCount < 1 ? null : firstArgument?.toStringValue();
       if (definingClass == typeProvider.boolElement) {
+        // Special case: https://github.com/dart-lang/sdk/issues/50045
+        if (variableName == 'dart.library.js_util') {
+          return DartObjectImpl(
+            typeSystem,
+            typeProvider.boolType,
+            BoolState.UNKNOWN_VALUE,
+          );
+        }
         return FromEnvironmentEvaluator(typeSystem, _declaredVariables)
             .getBool2(variableName, _namedValues, _constructor);
       } else if (definingClass == typeProvider.intElement) {
@@ -2268,14 +2270,14 @@
           superArguments.insert(positionalIndex++, value);
         } else {
           superArguments.add(
-            astFactory.namedExpression(
-              astFactory.label(
-                astFactory.simpleIdentifier(
+            NamedExpressionImpl(
+              name: LabelImpl(
+                label: astFactory.simpleIdentifier(
                   StringToken(TokenType.STRING, parameter.name, -1),
                 )..staticElement = parameter,
-                StringToken(TokenType.COLON, ':', -1),
+                colon: StringToken(TokenType.COLON, ':', -1),
               ),
-              value,
+              expression: value,
             )..staticType = value.typeOrThrow,
           );
         }
@@ -2284,7 +2286,7 @@
   }
 
   void _checkFields() {
-    var fields = _constructor.enclosingElement3.fields;
+    var fields = _constructor.enclosingElement.fields;
     for (var field in fields) {
       if ((field.isFinal || field.isConst) &&
           !field.isStatic &&
@@ -2573,7 +2575,7 @@
   }
 
   void _checkTypeParameters() {
-    var typeParameters = _constructor.enclosingElement3.typeParameters;
+    var typeParameters = _constructor.enclosingElement.typeParameters;
     var typeArguments = _typeArguments;
     if (typeParameters.isNotEmpty &&
         typeArguments != null &&
diff --git a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
index c4e7db3..c988dc5 100644
--- a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
+++ b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
@@ -39,7 +39,7 @@
 
 bool _isConstantTypeName(Identifier name) {
   var element = name.staticElement;
-  if (element is ClassElement || element is TypeAliasElement) {
+  if (element is InterfaceElement || element is TypeAliasElement) {
     if (name is PrefixedIdentifier) {
       if (name.isDeferred) {
         return false;
@@ -102,6 +102,10 @@
       return;
     }
 
+    if (node is RecordLiteral) {
+      return _recordLiteral(node);
+    }
+
     if (node is MethodInvocation) {
       return _methodInvocation(node);
     }
@@ -227,7 +231,7 @@
     }
 
     if (element is ParameterElement) {
-      var enclosing = element.enclosingElement3;
+      var enclosing = element.enclosingElement;
       if (enclosing is ConstructorElement &&
           isConstConstructorElement(enclosing)) {
         if (node.thisOrAncestorOfType<ConstructorInitializer>() != null) {
@@ -309,6 +313,12 @@
     nodes.add(node);
   }
 
+  void _recordLiteral(RecordLiteral node) {
+    for (final field in node.fields) {
+      collect(field);
+    }
+  }
+
   void _typeArgumentList(TypeArgumentList? typeArgumentList) {
     var typeArguments = typeArgumentList?.arguments;
     if (typeArguments != null) {
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 47ceeca..93f130a 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -112,7 +112,7 @@
   @override
   void visitClassDeclaration(ClassDeclaration node) {
     bool prevTreatFinalInstanceVarAsConst = treatFinalInstanceVarAsConst;
-    if (node.declaredElement2!.constructors
+    if (node.declaredElement!.constructors
         .any((ConstructorElement e) => e.isConst)) {
       // Instance vars marked "final" need to be included in the dependency
       // graph, since constant constructors implicitly use the values in their
@@ -130,7 +130,7 @@
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     super.visitConstructorDeclaration(node);
     if (node.constKeyword != null) {
-      var element = node.declaredElement2;
+      var element = node.declaredElement;
       if (element != null) {
         constantsToCompute.add(element);
         constantsToCompute.addAll(element.parameters);
@@ -151,7 +151,7 @@
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
     super.visitEnumConstantDeclaration(node);
 
-    var element = node.declaredElement2 as ConstFieldElementImpl;
+    var element = node.declaredElement as ConstFieldElementImpl;
     constantsToCompute.add(element);
 
     final initializer = element.constantInitializer!;
@@ -165,7 +165,7 @@
   void visitVariableDeclaration(VariableDeclaration node) {
     super.visitVariableDeclaration(node);
     var initializer = node.initializer;
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     if (initializer != null &&
         (node.isConst ||
             treatFinalInstanceVarAsConst &&
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 3a8935e..2ae32bc 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/dart/constant/has_type_parameter_reference.dart';
+import 'package:analyzer/src/dart/element/extensions.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:meta/meta.dart';
@@ -157,18 +158,18 @@
   final DartType type;
 
   /// The state of the object.
-  final InstanceState _state;
+  final InstanceState state;
 
   @override
   final VariableElement? variable;
 
-  /// Initialize a newly created object to have the given [type] and [_state].
-  DartObjectImpl(this._typeSystem, this.type, this._state, {this.variable});
+  /// Initialize a newly created object to have the given [type] and [state].
+  DartObjectImpl(this._typeSystem, this.type, this.state, {this.variable});
 
   /// Creates a duplicate instance of [other], tied to [variable].
   factory DartObjectImpl.forVariable(
       DartObjectImpl other, VariableElement variable) {
-    return DartObjectImpl(other._typeSystem, other.type, other._state,
+    return DartObjectImpl(other._typeSystem, other.type, other.state,
         variable: variable);
   }
 
@@ -189,42 +190,42 @@
     return DartObjectImpl(typeSystem, type, GenericState.UNKNOWN_VALUE);
   }
 
-  Map<String, DartObjectImpl>? get fields => _state.fields;
+  Map<String, DartObjectImpl>? get fields => state.fields;
 
   @override
-  int get hashCode => Object.hash(type, _state);
+  int get hashCode => Object.hash(type, state);
 
   @override
-  bool get hasKnownValue => !_state.isUnknown;
+  bool get hasKnownValue => !state.isUnknown;
 
   /// Return `true` if this object represents an object whose type is 'bool'.
-  bool get isBool => _state.isBool;
+  bool get isBool => state.isBool;
 
   /// Return `true` if this object represents an object whose type is either
   /// 'bool', 'num', 'String', or 'Null'.
-  bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
+  bool get isBoolNumStringOrNull => state.isBoolNumStringOrNull;
 
   /// Return `true` if this object represents an object whose type is 'int'.
-  bool get isInt => _state.isInt;
+  bool get isInt => state.isInt;
 
   @override
-  bool get isNull => _state is NullState;
+  bool get isNull => state is NullState;
 
   /// Return `true` if this object represents an unknown value.
-  bool get isUnknown => _state.isUnknown;
+  bool get isUnknown => state.isUnknown;
 
   /// Return `true` if this object represents an instance of a user-defined
   /// class.
-  bool get isUserDefinedObject => _state is GenericState;
+  bool get isUserDefinedObject => state is GenericState;
 
   @visibleForTesting
-  List<DartType>? get typeArguments => (_state as FunctionState)._typeArguments;
+  List<DartType>? get typeArguments => (state as FunctionState)._typeArguments;
 
   @override
   bool operator ==(Object other) {
     if (other is DartObjectImpl) {
       return _typeSystem.runtimeTypesEqual(type, other.type) &&
-          _state == other._state;
+          state == other.state;
     }
     return false;
   }
@@ -235,7 +236,7 @@
   /// Throws an [EvaluationException] if the operator is not appropriate for an
   /// object of this kind.
   DartObjectImpl add(TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
-    InstanceState result = _state.add(rightOperand._state);
+    InstanceState result = state.add(rightOperand.state);
     if (result is IntState) {
       return DartObjectImpl(
         typeSystem,
@@ -267,7 +268,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.intType,
-      _state.bitNot(),
+      state.bitNot(),
     );
   }
 
@@ -275,7 +276,7 @@
   DartObjectImpl castToType(
       TypeSystemImpl typeSystem, DartObjectImpl castType) {
     _assertType(castType);
-    var resultType = (castType._state as TypeState)._type;
+    var resultType = (castType.state as TypeState)._type;
 
     // If we don't know the type, we cannot prove that the cast will fail.
     if (resultType == null) {
@@ -305,7 +306,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.stringType,
-      _state.concatenate(rightOperand._state),
+      state.concatenate(rightOperand.state),
     );
   }
 
@@ -318,7 +319,7 @@
     if (identical(type, boolType)) {
       return this;
     }
-    return DartObjectImpl(typeSystem, boolType, _state.convertToBool());
+    return DartObjectImpl(typeSystem, boolType, state.convertToBool());
   }
 
   /// Return the result of invoking the '/' operator on this object with the
@@ -328,7 +329,7 @@
   /// an object of this kind.
   DartObjectImpl divide(
       TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
-    InstanceState result = _state.divide(rightOperand._state);
+    InstanceState result = state.divide(rightOperand.state);
     if (result is IntState) {
       return DartObjectImpl(
         typeSystem,
@@ -357,13 +358,13 @@
       return DartObjectImpl(
         typeSystem,
         typeSystem.typeProvider.boolType,
-        _state.logicalAnd(rightOperand._state),
+        state.logicalAnd(rightOperand.state),
       );
     } else if (isInt && rightOperand.isInt) {
       return DartObjectImpl(
         typeSystem,
         typeSystem.typeProvider.intType,
-        _state.bitAnd(rightOperand._state),
+        state.bitAnd(rightOperand.state),
       );
     }
     throw EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT);
@@ -380,13 +381,13 @@
       return DartObjectImpl(
         typeSystem,
         typeSystem.typeProvider.boolType,
-        _state.logicalOr(rightOperand._state),
+        state.logicalOr(rightOperand.state),
       );
     } else if (isInt && rightOperand.isInt) {
       return DartObjectImpl(
         typeSystem,
         typeSystem.typeProvider.intType,
-        _state.bitOr(rightOperand._state),
+        state.bitOr(rightOperand.state),
       );
     }
     throw EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT);
@@ -403,13 +404,13 @@
       return DartObjectImpl(
         typeSystem,
         typeSystem.typeProvider.boolType,
-        _state.logicalXor(rightOperand._state),
+        state.logicalXor(rightOperand.state),
       );
     } else if (isInt && rightOperand.isInt) {
       return DartObjectImpl(
         typeSystem,
         typeSystem.typeProvider.intType,
-        _state.bitXor(rightOperand._state),
+        state.bitXor(rightOperand.state),
       );
     }
     throw EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT);
@@ -435,7 +436,7 @@
       return DartObjectImpl(
         typeSystem,
         typeSystem.typeProvider.boolType,
-        _state.equalEqual(typeSystem, rightOperand._state),
+        state.equalEqual(typeSystem, rightOperand.state),
       );
     }
     throw EvaluationException(
@@ -444,9 +445,11 @@
 
   @override
   DartObject? getField(String name) {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is GenericState) {
       return state.fields[name];
+    } else if (state is RecordState) {
+      return state.getField(name);
     }
     return null;
   }
@@ -454,7 +457,7 @@
   /// Gets the constructor that was called to create this value, if this is a
   /// const constructor invocation. Otherwise returns null.
   ConstructorInvocation? getInvocation() {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is GenericState) {
       return state.invocation;
     }
@@ -471,7 +474,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.boolType,
-      _state.greaterThan(rightOperand._state),
+      state.greaterThan(rightOperand.state),
     );
   }
 
@@ -485,7 +488,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.boolType,
-      _state.greaterThanOrEqual(rightOperand._state),
+      state.greaterThanOrEqual(rightOperand.state),
     );
   }
 
@@ -493,7 +496,7 @@
   /// [testedType].
   DartObjectImpl hasType(TypeSystemImpl typeSystem, DartObjectImpl testedType) {
     _assertType(testedType);
-    var typeType = (testedType._state as TypeState)._type;
+    var typeType = (testedType.state as TypeState)._type;
     BoolState state;
     if (typeType == null) {
       state = BoolState.TRUE_STATE;
@@ -513,7 +516,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.intType,
-      _state.integerDivide(rightOperand._state),
+      state.integerDivide(rightOperand.state),
     );
   }
 
@@ -558,7 +561,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.boolType,
-      _state.isIdentical(typeSystem, rightOperand._state),
+      state.isIdentical(typeSystem, rightOperand.state),
     );
   }
 
@@ -572,7 +575,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.boolType,
-      _state.lazyAnd(() => rightOperandComputer()?._state),
+      state.lazyAnd(() => rightOperandComputer()?.state),
     );
   }
 
@@ -596,7 +599,7 @@
       return DartObjectImpl(
         typeSystem,
         typeSystem.typeProvider.boolType,
-        _state.lazyEqualEqual(typeSystem, rightOperand._state),
+        state.lazyEqualEqual(typeSystem, rightOperand.state),
       );
     }
     throw EvaluationException(
@@ -613,7 +616,7 @@
       DartObjectImpl(
         typeSystem,
         typeSystem.typeProvider.boolType,
-        _state.lazyOr(() => rightOperandComputer()?._state),
+        state.lazyOr(() => rightOperandComputer()?.state),
       );
 
   /// Return the result of invoking the '&lt;' operator on this object with the
@@ -626,7 +629,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.boolType,
-      _state.lessThan(rightOperand._state),
+      state.lessThan(rightOperand.state),
     );
   }
 
@@ -640,7 +643,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.boolType,
-      _state.lessThanOrEqual(rightOperand._state),
+      state.lessThanOrEqual(rightOperand.state),
     );
   }
 
@@ -652,7 +655,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.boolType,
-      _state.logicalNot(),
+      state.logicalNot(),
     );
   }
 
@@ -666,7 +669,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.intType,
-      _state.logicalShiftRight(rightOperand._state),
+      state.logicalShiftRight(rightOperand.state),
     );
   }
 
@@ -676,7 +679,7 @@
   /// Throws an [EvaluationException] if the operator is not appropriate for an
   /// object of this kind.
   DartObjectImpl minus(TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
-    InstanceState result = _state.minus(rightOperand._state);
+    InstanceState result = state.minus(rightOperand.state);
     if (result is IntState) {
       return DartObjectImpl(
         typeSystem,
@@ -699,7 +702,7 @@
   /// Throws an [EvaluationException] if the operator is not appropriate for an
   /// object of this kind.
   DartObjectImpl negated(TypeSystemImpl typeSystem) {
-    InstanceState result = _state.negated();
+    InstanceState result = state.negated();
     if (result is IntState) {
       return DartObjectImpl(
         typeSystem,
@@ -736,7 +739,7 @@
     if (identical(type, stringType)) {
       return this;
     }
-    return DartObjectImpl(typeSystem, stringType, _state.convertToString());
+    return DartObjectImpl(typeSystem, stringType, state.convertToString());
   }
 
   /// Return the result of invoking the '%' operator on this object with the
@@ -746,7 +749,7 @@
   /// object of this kind.
   DartObjectImpl remainder(
       TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
-    InstanceState result = _state.remainder(rightOperand._state);
+    InstanceState result = state.remainder(rightOperand.state);
     if (result is IntState) {
       return DartObjectImpl(
         typeSystem,
@@ -774,7 +777,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.intType,
-      _state.shiftLeft(rightOperand._state),
+      state.shiftLeft(rightOperand.state),
     );
   }
 
@@ -788,7 +791,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.intType,
-      _state.shiftRight(rightOperand._state),
+      state.shiftRight(rightOperand.state),
     );
   }
 
@@ -800,7 +803,7 @@
     return DartObjectImpl(
       typeSystem,
       typeSystem.typeProvider.intType,
-      _state.stringLength(),
+      state.stringLength(),
     );
   }
 
@@ -810,7 +813,7 @@
   /// Throws an [EvaluationException] if the operator is not appropriate for an
   /// object of this kind.
   DartObjectImpl times(TypeSystemImpl typeSystem, DartObjectImpl rightOperand) {
-    InstanceState result = _state.times(rightOperand._state);
+    InstanceState result = state.times(rightOperand.state);
     if (result is IntState) {
       return DartObjectImpl(
         typeSystem,
@@ -830,7 +833,7 @@
 
   @override
   bool? toBoolValue() {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is BoolState) {
       return state.value;
     }
@@ -839,7 +842,7 @@
 
   @override
   double? toDoubleValue() {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is DoubleState) {
       return state.value;
     }
@@ -848,13 +851,13 @@
 
   @override
   ExecutableElement? toFunctionValue() {
-    InstanceState state = _state;
+    final state = this.state;
     return state is FunctionState ? state._element : null;
   }
 
   @override
   int? toIntValue() {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is IntState) {
       return state.value;
     }
@@ -863,7 +866,7 @@
 
   @override
   List<DartObject>? toListValue() {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is ListState) {
       return state._elements;
     }
@@ -872,7 +875,7 @@
 
   @override
   Map<DartObjectImpl, DartObjectImpl>? toMapValue() {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is MapState) {
       return state._entries;
     }
@@ -881,7 +884,7 @@
 
   @override
   Set<DartObject>? toSetValue() {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is SetState) {
       return state._elements;
     }
@@ -890,12 +893,12 @@
 
   @override
   String toString() {
-    return "${type.getDisplayString(withNullability: false)} ($_state)";
+    return "${type.getDisplayString(withNullability: false)} ($state)";
   }
 
   @override
   String? toStringValue() {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is StringState) {
       return state.value;
     }
@@ -904,7 +907,7 @@
 
   @override
   String? toSymbolValue() {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is SymbolState) {
       return state.value;
     }
@@ -913,7 +916,7 @@
 
   @override
   DartType? toTypeValue() {
-    InstanceState state = _state;
+    final state = this.state;
     if (state is TypeState) {
       return state._type;
     }
@@ -928,7 +931,7 @@
     FunctionType type,
     List<DartType> typeArguments,
   ) {
-    var functionState = _state as FunctionState;
+    var functionState = state as FunctionState;
     return DartObjectImpl(
       typeSystem,
       type,
@@ -945,7 +948,7 @@
     required int index,
     required String name,
   }) {
-    var fields = _state.fields!;
+    var fields = state.fields!;
     fields['index'] = DartObjectImpl(
       _typeSystem,
       _typeSystem.typeProvider.intType,
@@ -961,7 +964,7 @@
   /// Throw an exception if the given [object]'s state does not represent a Type
   /// value.
   void _assertType(DartObjectImpl object) {
-    if (object._state is! TypeState) {
+    if (object.state is! TypeState) {
       throw EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_TYPE);
     }
   }
@@ -2556,7 +2559,7 @@
     for (var i = 0; i < positionalCount; i++) {
       var result = positionalFields[i]
           .equalEqual(typeSystem, otherPositionalFields[i])
-          ._state;
+          .state;
       if (result is! BoolState) {
         return BoolState.FALSE_STATE;
       } else if (result != BoolState.TRUE_STATE) {
@@ -2568,7 +2571,7 @@
       if (otherValue == null) {
         return BoolState.FALSE_STATE;
       }
-      var result = entry.value.equalEqual(typeSystem, otherValue)._state;
+      var result = entry.value.equalEqual(typeSystem, otherValue).state;
       if (result is! BoolState) {
         return BoolState.FALSE_STATE;
       } else if (result != BoolState.TRUE_STATE) {
@@ -2578,6 +2581,16 @@
     return BoolState.TRUE_STATE;
   }
 
+  /// Returns the value of the field with the given [name].
+  DartObject? getField(String name) {
+    final index = RecordTypeExtension.positionalFieldIndex(name);
+    if (index != null && index < positionalFields.length) {
+      return positionalFields[index];
+    } else {
+      return namedFields[name];
+    }
+  }
+
   @override
   BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
     var equal = equalEqual(typeSystem, rightOperand);
diff --git a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
index cc2458b..f666d98 100644
--- a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
+++ b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
@@ -19,7 +19,7 @@
     return _getHierarchy(element).interfaces;
   }
 
-  void remove(ClassElement element) {
+  void remove(InterfaceElement element) {
     _map.remove(element);
   }
 
@@ -65,9 +65,7 @@
       }
     }
 
-    if (element is ClassElement) {
-      append(element.supertype);
-    }
+    append(element.supertype);
     if (element is MixinElement) {
       for (var type in element.superclassConstraints) {
         append(type);
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index e3a78c3..d571004 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -48,12 +48,13 @@
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/task/inference_error.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
+import 'package:analyzer/src/utilities/extensions/string.dart';
 import 'package:collection/collection.dart';
 
 /// A concrete implementation of a [ClassElement].
 abstract class AbstractClassElementImpl extends _ExistingElementImpl
     with TypeParameterizedElementMixin, HasCompletionData, MacroTargetElement
-    implements ClassElement {
+    implements InterfaceElement {
   /// The superclass of the class, or `null` for [Object].
   InterfaceType? _supertype;
 
@@ -88,7 +89,6 @@
 
   /// Set the accessors contained in this class to the given [accessors].
   set accessors(List<PropertyAccessorElement> accessors) {
-    assert(!isMixinApplication);
     for (PropertyAccessorElement accessor in accessors) {
       (accessor as PropertyAccessorElementImpl).enclosingElement = this;
     }
@@ -103,26 +103,17 @@
   @override
   String get displayName => name;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   CompilationUnitElementImpl get enclosingElement {
     return _enclosingElement as CompilationUnitElementImpl;
   }
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  CompilationUnitElementImpl get enclosingElement2 {
-    return _enclosingElement as CompilationUnitElementImpl;
-  }
-
-  @override
-  CompilationUnitElementImpl get enclosingElement3 {
-    return _enclosingElement as CompilationUnitElementImpl;
-  }
+  CompilationUnitElementImpl get enclosingElement3 => enclosingElement;
 
   /// Set the fields contained in this class to the given [fields].
   set fields(List<FieldElement> fields) {
-    assert(!isMixinApplication);
     for (FieldElement field in fields) {
       (field as FieldElementImpl).enclosingElement = this;
     }
@@ -141,11 +132,6 @@
     return _interfaces;
   }
 
-  @override
-  bool get isDartCoreEnum {
-    return name == 'Enum' && library.isDartCore;
-  }
-
   /// Return `true` if this class represents the class '_Enum' defined in the
   /// dart:core library.
   bool get isDartCoreEnumImpl {
@@ -159,17 +145,6 @@
   }
 
   @override
-  bool get isDartCoreObject => false;
-
-  @Deprecated('Use `is EnumElement` instead')
-  @override
-  bool get isEnum => false;
-
-  @Deprecated('Use `is MixinElement` instead')
-  @override
-  bool get isMixin => false;
-
-  @override
   List<InterfaceType> get mixins {
     if (mixinInferenceCallback != null) {
       var mixins = mixinInferenceCallback!(this);
@@ -186,9 +161,6 @@
   }
 
   @override
-  List<InterfaceType> get superclassConstraints => const <InterfaceType>[];
-
-  @override
   InterfaceType? get supertype {
     if (_supertype != null) return _supertype!;
 
@@ -240,9 +212,6 @@
   }
 
   @override
-  T? accept<T>(ElementVisitor<T> visitor) => visitor.visitClassElement(this);
-
-  @override
   FieldElement? getField(String name) {
     for (FieldElement fieldElement in fields) {
       if (name == fieldElement.name) {
@@ -328,7 +297,7 @@
               !getter.isAbstract &&
               !getter.isStatic &&
               getter.isAccessibleIn2(library) &&
-              getter.enclosingElement3 != this));
+              getter.enclosingElement != this));
 
   ExecutableElement? lookUpInheritedConcreteMember(
       String name, LibraryElement library) {
@@ -348,7 +317,7 @@
               !method.isAbstract &&
               !method.isStatic &&
               method.isAccessibleIn2(library) &&
-              method.enclosingElement3 != this));
+              method.enclosingElement != this));
 
   @override
   PropertyAccessorElement? lookUpInheritedConcreteSetter(
@@ -358,7 +327,7 @@
               !setter.isAbstract &&
               !setter.isStatic &&
               setter.isAccessibleIn2(library) &&
-              setter.enclosingElement3 != this));
+              setter.enclosingElement != this));
 
   @override
   MethodElement? lookUpInheritedMethod(
@@ -367,7 +336,7 @@
           (MethodElement method) =>
               !method.isStatic &&
               method.isAccessibleIn2(library) &&
-              method.enclosingElement3 != this));
+              method.enclosingElement != this));
 
   @override
   MethodElement? lookUpMethod(String methodName, LibraryElement library) =>
@@ -451,11 +420,7 @@
           yield getter;
         }
       }
-      if (classElement is ClassElement) {
-        classElement = classElement.supertype?.element2;
-      } else {
-        break;
-      }
+      classElement = classElement.supertype?.element2;
     }
   }
 
@@ -484,11 +449,7 @@
           yield method;
         }
       }
-      if (classElement is ClassElement) {
-        classElement = classElement.supertype?.element2;
-      } else {
-        break;
-      }
+      classElement = classElement.supertype?.element2;
     }
   }
 
@@ -518,11 +479,7 @@
           yield setter;
         }
       }
-      if (classElement is ClassElement) {
-        classElement = classElement.supertype?.element2;
-      } else {
-        break;
-      }
+      classElement = classElement.supertype?.element2;
     }
   }
 
@@ -565,21 +522,15 @@
     required this.uri,
   }) : super(null, importKeywordOffset);
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   LibraryOrAugmentationElementImpl get enclosingElement {
-    return super.enclosingElement2 as LibraryOrAugmentationElementImpl;
+    return super.enclosingElement as LibraryOrAugmentationElementImpl;
   }
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  LibraryOrAugmentationElementImpl get enclosingElement2 {
-    return super.enclosingElement2 as LibraryOrAugmentationElementImpl;
-  }
-
+  @Deprecated('Use enclosingElement instead')
   @override
   LibraryOrAugmentationElementImpl get enclosingElement3 {
-    return super.enclosingElement3 as LibraryOrAugmentationElementImpl;
+    return enclosingElement;
   }
 
   @override
@@ -600,39 +551,15 @@
 }
 
 /// An [AbstractClassElementImpl] which is a class.
-class ClassElementImpl extends AbstractClassElementImpl {
-  /// For classes which are not mixin applications, a list containing all of the
-  /// constructors contained in this class, or `null` if the list of
-  /// constructors has not yet been built.
-  ///
-  /// For classes which are mixin applications, the list of constructors is
-  /// computed on the fly by the [constructors] getter, and this field is
-  /// `null`.
-  List<ConstructorElement> _constructors = _Sentinel.constructorElement;
-
-  /// A flag indicating whether the types associated with the instance members
-  /// of this class have been inferred.
-  bool hasBeenInferred = false;
-
-  ElementLinkedData? linkedData;
-
+class ClassElementImpl extends ClassOrMixinElementImpl implements ClassElement {
   /// Initialize a newly created class element to have the given [name] at the
   /// given [offset] in the file that contains the declaration of this element.
   ClassElementImpl(super.name, super.offset);
 
   @override
-  List<PropertyAccessorElement> get accessors {
-    if (!identical(_accessors, _Sentinel.propertyAccessorElement)) {
-      return _accessors;
-    }
-
-    var linkedData = this.linkedData;
-    if (linkedData is ClassElementLinkedData) {
-      linkedData.readMembers(this);
-      return _accessors;
-    }
-
-    return _accessors;
+  set accessors(List<PropertyAccessorElement> accessors) {
+    assert(!isMixinApplication);
+    super.accessors = accessors;
   }
 
   @override
@@ -675,30 +602,16 @@
     return _constructors;
   }
 
-  /// Set the constructors contained in this class to the given [constructors].
-  ///
-  /// Should only be used for class elements that are not mixin applications.
+  @override
   set constructors(List<ConstructorElement> constructors) {
     assert(!isMixinApplication);
-    for (ConstructorElement constructor in constructors) {
-      (constructor as ConstructorElementImpl).enclosingElement = this;
-    }
-    _constructors = constructors;
+    super.constructors = constructors;
   }
 
   @override
-  List<FieldElement> get fields {
-    if (!identical(_fields, _Sentinel.fieldElement)) {
-      return _fields;
-    }
-
-    var linkedData = this.linkedData;
-    if (linkedData is ClassElementLinkedData) {
-      linkedData.readMembers(this);
-      return _fields;
-    }
-
-    return _fields;
+  set fields(List<FieldElement> fields) {
+    assert(!isMixinApplication);
+    super.fields = fields;
   }
 
   @override
@@ -723,11 +636,9 @@
           classesToVisit.add(mixinType.element2);
         }
         // check super
-        if (currentElement is ClassElement) {
-          final supertype = currentElement.supertype;
-          if (supertype != null) {
-            classesToVisit.add(supertype.element2);
-          }
+        final supertype = currentElement.supertype;
+        if (supertype != null) {
+          classesToVisit.add(supertype.element2);
         }
       }
     }
@@ -741,32 +652,10 @@
   bool get hasNoSuchMethod {
     MethodElement? method = lookUpConcreteMethod(
         FunctionElement.NO_SUCH_METHOD_METHOD_NAME, library);
-    var definingClass = method?.enclosingElement3 as ClassElement?;
+    var definingClass = method?.enclosingElement as ClassElement?;
     return definingClass != null && !definingClass.isDartCoreObject;
   }
 
-  @Deprecated('Not useful for clients')
-  @override
-  bool get hasStaticMember {
-    for (MethodElement method in methods) {
-      if (method.isStatic) {
-        return true;
-      }
-    }
-    for (PropertyAccessorElement accessor in accessors) {
-      if (accessor.isStatic) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  List<InterfaceType> get interfacesInternal {
-    linkedData?.read(this);
-    return _interfaces;
-  }
-
   @override
   bool get isAbstract {
     return hasModifier(Modifier.ABSTRACT);
@@ -778,6 +667,11 @@
   }
 
   @override
+  bool get isDartCoreEnum {
+    return name == 'Enum' && library.isDartCore;
+  }
+
+  @override
   bool get isDartCoreObject {
     return name == 'Object' && library.isDartCore;
   }
@@ -838,15 +732,6 @@
   }
 
   @override
-  bool get isSimplyBounded {
-    return hasModifier(Modifier.SIMPLY_BOUNDED);
-  }
-
-  set isSimplyBounded(bool isSimplyBounded) {
-    setModifier(Modifier.SIMPLY_BOUNDED, isSimplyBounded);
-  }
-
-  @override
   bool get isValidMixin {
     final supertype = this.supertype;
     if (supertype != null && !supertype.isDartCoreObject) {
@@ -861,53 +746,13 @@
   }
 
   @override
-  ElementKind get kind => ElementKind.CLASS;
-
-  @override
-  List<ElementAnnotation> get metadata {
-    linkedData?.read(this);
-    return super.metadata;
-  }
-
-  @override
-  List<MethodElement> get methods {
-    if (!identical(_methods, _Sentinel.methodElement)) {
-      return _methods;
-    }
-
-    var linkedData = this.linkedData;
-    if (linkedData is ClassElementLinkedData) {
-      linkedData.readMembers(this);
-      return _methods;
-    }
-
-    return _methods;
-  }
-
-  /// Set the methods contained in this class to the given [methods].
   set methods(List<MethodElement> methods) {
     assert(!isMixinApplication);
-    for (MethodElement method in methods) {
-      (method as MethodElementImpl).enclosingElement = this;
-    }
-    _methods = methods;
+    super.methods = methods;
   }
 
   @override
-  List<InterfaceType> get mixins {
-    linkedData?.read(this);
-    return super.mixins;
-  }
-
-  @override
-  String get name {
-    return super.name!;
-  }
-
-  /// Names of methods, getters, setters, and operators that this mixin
-  /// declaration super-invokes.  For setters this includes the trailing "=".
-  /// The list will be empty if this class is not a mixin declaration.
-  List<String> get superInvokedNames => const <String>[];
+  List<InterfaceType> get superclassConstraints => const [];
 
   @override
   InterfaceType? get supertype {
@@ -916,9 +761,8 @@
   }
 
   @override
-  List<TypeParameterElement> get typeParameters {
-    linkedData?.read(this);
-    return super.typeParameters;
+  T? accept<T>(ElementVisitor<T> visitor) {
+    return visitor.visitClassElement(this);
   }
 
   @override
@@ -926,13 +770,6 @@
     builder.writeClassElement(this);
   }
 
-  void setLinkedData(Reference reference, ElementLinkedData linkedData) {
-    this.reference = reference;
-    reference.element = this;
-
-    this.linkedData = linkedData;
-  }
-
   /// Compute a list of constructors for this class, which is a mixin
   /// application.  If specified, [visitedClasses] is a list of the other mixin
   /// application classes which have been visited on the way to reaching this
@@ -1006,7 +843,8 @@
       implicitConstructor.nameOffset = -1;
 
       var containerRef = reference!.getChild('@constructor');
-      var implicitReference = containerRef.getChild(name);
+      var referenceName = name.ifNotEmptyOrElse('new');
+      var implicitReference = containerRef.getChild(referenceName);
       implicitConstructor.reference = implicitReference;
       implicitReference.element = implicitConstructor;
 
@@ -1081,6 +919,139 @@
   }
 }
 
+abstract class ClassOrMixinElementImpl extends AbstractClassElementImpl {
+  /// For classes which are not mixin applications, a list containing all of the
+  /// constructors contained in this class, or `null` if the list of
+  /// constructors has not yet been built.
+  ///
+  /// For classes which are mixin applications, the list of constructors is
+  /// computed on the fly by the [constructors] getter, and this field is
+  /// `null`.
+  List<ConstructorElement> _constructors = _Sentinel.constructorElement;
+
+  ElementLinkedData? linkedData;
+
+  /// A flag indicating whether the types associated with the instance members
+  /// of this class have been inferred.
+  bool hasBeenInferred = false;
+
+  /// Initialize a newly created class element to have the given [name] at the
+  /// given [offset] in the file that contains the declaration of this element.
+  ClassOrMixinElementImpl(super.name, super.offset);
+
+  @override
+  List<PropertyAccessorElement> get accessors {
+    if (!identical(_accessors, _Sentinel.propertyAccessorElement)) {
+      return _accessors;
+    }
+
+    var linkedData = this.linkedData;
+    if (linkedData is ClassElementLinkedData) {
+      linkedData.readMembers(this);
+      return _accessors;
+    }
+
+    return _accessors;
+  }
+
+  /// Set the constructors contained in this class to the given [constructors].
+  ///
+  /// Should only be used for class elements that are not mixin applications.
+  set constructors(List<ConstructorElement> constructors) {
+    for (ConstructorElement constructor in constructors) {
+      (constructor as ConstructorElementImpl).enclosingElement = this;
+    }
+    _constructors = constructors;
+  }
+
+  @override
+  List<FieldElement> get fields {
+    if (!identical(_fields, _Sentinel.fieldElement)) {
+      return _fields;
+    }
+
+    var linkedData = this.linkedData;
+    if (linkedData is ClassElementLinkedData) {
+      linkedData.readMembers(this);
+      return _fields;
+    }
+
+    return _fields;
+  }
+
+  @override
+  List<InterfaceType> get interfacesInternal {
+    linkedData?.read(this);
+    return _interfaces;
+  }
+
+  @override
+  bool get isSimplyBounded {
+    return hasModifier(Modifier.SIMPLY_BOUNDED);
+  }
+
+  set isSimplyBounded(bool isSimplyBounded) {
+    setModifier(Modifier.SIMPLY_BOUNDED, isSimplyBounded);
+  }
+
+  /// TODO(scheglov) Do we need a separate kind for `MixinElement`?
+  @override
+  ElementKind get kind => ElementKind.CLASS;
+
+  @override
+  List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
+    return super.metadata;
+  }
+
+  @override
+  List<MethodElement> get methods {
+    if (!identical(_methods, _Sentinel.methodElement)) {
+      return _methods;
+    }
+
+    var linkedData = this.linkedData;
+    if (linkedData is ClassElementLinkedData) {
+      linkedData.readMembers(this);
+      return _methods;
+    }
+
+    return _methods;
+  }
+
+  /// Set the methods contained in this class to the given [methods].
+  set methods(List<MethodElement> methods) {
+    for (MethodElement method in methods) {
+      (method as MethodElementImpl).enclosingElement = this;
+    }
+    _methods = methods;
+  }
+
+  @override
+  List<InterfaceType> get mixins {
+    linkedData?.read(this);
+    return super.mixins;
+  }
+
+  @override
+  String get name {
+    return super.name!;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters {
+    linkedData?.read(this);
+    return super.typeParameters;
+  }
+
+  void setLinkedData(Reference reference, ElementLinkedData linkedData) {
+    this.reference = reference;
+    reference.element = this;
+
+    this.linkedData = linkedData;
+  }
+}
+
 /// A concrete implementation of a [CompilationUnitElement].
 class CompilationUnitElementImpl extends UriReferencedElementImpl
     implements CompilationUnitElement, MacroTargetElementContainer {
@@ -1170,31 +1141,19 @@
     _classes = classes;
   }
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  LibraryElement get enclosingElement =>
-      super.enclosingElement2 as LibraryElement;
+  LibraryOrAugmentationElement get enclosingElement =>
+      super.enclosingElement as LibraryOrAugmentationElement;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  LibraryOrAugmentationElement get enclosingElement2 =>
-      super.enclosingElement2 as LibraryOrAugmentationElement;
-
-  @override
-  LibraryOrAugmentationElement get enclosingElement3 =>
-      super.enclosingElement3 as LibraryOrAugmentationElement;
+  LibraryOrAugmentationElement get enclosingElement3 => enclosingElement;
 
   @override
   CompilationUnitElementImpl get enclosingUnit {
     return this;
   }
 
-  @Deprecated('Use enums2 instead')
-  @override
-  List<ClassElement> get enums {
-    return _enums.map((e) => e as ClassElement).toList();
-  }
-
   @override
   List<EnumElement> get enums2 {
     return _enums;
@@ -1251,12 +1210,6 @@
     return super.metadata;
   }
 
-  @Deprecated('Use mixins2 instead')
-  @override
-  List<ClassElement> get mixins {
-    return _mixins.map((e) => e as ClassElement).toList();
-  }
-
   @override
   List<MixinElement> get mixins2 {
     return _mixins;
@@ -1271,7 +1224,7 @@
   }
 
   @override
-  AnalysisSession get session => enclosingElement3.session;
+  AnalysisSession get session => enclosingElement.session;
 
   @override
   List<TopLevelVariableElement> get topLevelVariables {
@@ -1326,17 +1279,6 @@
     return null;
   }
 
-  @Deprecated('Use getEnum2() instead')
-  @override
-  ClassElement? getEnum(String enumName) {
-    for (ClassElement enumDeclaration in enums) {
-      if (enumDeclaration.name == enumName) {
-        return enumDeclaration;
-      }
-    }
-    return null;
-  }
-
   @override
   EnumElement? getEnum2(String name) {
     for (final element in enums2) {
@@ -1347,17 +1289,6 @@
     return null;
   }
 
-  @Deprecated('Use getClass() instead')
-  @override
-  ClassElement? getType(String className) {
-    for (ClassElement class_ in classes) {
-      if (class_.name == className) {
-        return class_;
-      }
-    }
-    return null;
-  }
-
   void setLinkedData(Reference reference, ElementLinkedData linkedData) {
     this.reference = reference;
     reference.element = this;
@@ -1467,7 +1398,7 @@
 
   @override
   String get displayName {
-    var className = enclosingElement3.name;
+    var className = enclosingElement.name;
     var name = this.name;
     if (name.isNotEmpty) {
       return '$className.$name';
@@ -1476,19 +1407,13 @@
     }
   }
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  AbstractClassElementImpl get enclosingElement =>
-      super.enclosingElement2 as AbstractClassElementImpl;
+  InterfaceElement get enclosingElement =>
+      super.enclosingElement as AbstractClassElementImpl;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  AbstractClassElementImpl get enclosingElement2 =>
-      super.enclosingElement2 as AbstractClassElementImpl;
-
-  @override
-  InterfaceElement get enclosingElement3 =>
-      super.enclosingElement3 as AbstractClassElementImpl;
+  InterfaceElement get enclosingElement3 => enclosingElement;
 
   @override
   bool get isConst {
@@ -1525,7 +1450,7 @@
 
   @override
   Element get nonSynthetic {
-    return isSynthetic ? enclosingElement3 : this;
+    return isSynthetic ? enclosingElement : this;
   }
 
   @override
@@ -1550,7 +1475,7 @@
 
   @override
   InterfaceType get returnTypeInternal {
-    return (_returnType ??= enclosingElement3.thisType) as InterfaceType;
+    return (_returnType ??= enclosingElement.thisType) as InterfaceType;
   }
 
   ConstructorElement? get superConstructor {
@@ -1684,7 +1609,7 @@
       if (library == null) {
         throw StateError(
           '[library: null][this: ($runtimeType) $this]'
-          '[enclosingElement: $enclosingElement3]'
+          '[enclosingElement: $enclosingElement]'
           '[reference: $reference]',
         );
       }
@@ -2059,7 +1984,7 @@
     final element = this.element;
     if (element is ConstructorElement) {
       return element.library.isDartCore &&
-          element.enclosingElement3.name == _deprecatedClassName;
+          element.enclosingElement.name == _deprecatedClassName;
     } else if (element is PropertyAccessorElement) {
       return element.library.isDartCore &&
           element.name == _deprecatedVariableName;
@@ -2191,7 +2116,7 @@
   }) {
     final element = this.element;
     return element is ConstructorElement &&
-        element.enclosingElement3.name == className &&
+        element.enclosingElement.name == className &&
         element.library.name == libraryName;
   }
 
@@ -2226,10 +2151,6 @@
   static const _metadataFlag_hasDeprecated = 1 << 1;
   static const _metadataFlag_hasOverride = 1 << 2;
 
-  /// An Unicode right arrow.
-  @deprecated
-  static final String RIGHT_ARROW = " \u2192 ";
-
   static int _NEXT_ID = 0;
 
   @override
@@ -2305,7 +2226,6 @@
     _docComment = doc;
   }
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   Element? get enclosingElement => _enclosingElement;
 
@@ -2314,12 +2234,9 @@
     _enclosingElement = element as ElementImpl?;
   }
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element? get enclosingElement2 => _enclosingElement;
-
-  @override
-  Element? get enclosingElement3 => _enclosingElement;
+  Element? get enclosingElement3 => enclosingElement;
 
   /// Return the enclosing unit element (which might be the same as `this`), or
   /// `null` if this element is not contained in any compilation unit.
@@ -2669,12 +2586,12 @@
 
   @override
   AnalysisSession? get session {
-    return enclosingElement3?.session;
+    return enclosingElement?.session;
   }
 
   @override
   Source? get source {
-    return enclosingElement3?.source;
+    return enclosingElement?.source;
   }
 
   /// Return the context to resolve type parameters in, or `null` if neither
@@ -2742,15 +2659,6 @@
   bool hasModifier(Modifier modifier) =>
       BooleanArray.get(_modifiers, modifier.ordinal);
 
-  @Deprecated('Use isAccessibleIn2() instead')
-  @override
-  bool isAccessibleIn(LibraryElement? library) {
-    if (Identifier.isPrivateName(name!)) {
-      return library == this.library;
-    }
-    return true;
-  }
-
   @override
   bool isAccessibleIn2(LibraryElement library) {
     if (Identifier.isPrivateName(name!)) {
@@ -2759,6 +2667,10 @@
     return true;
   }
 
+  void resetMetadataFlags() {
+    _metadataFlags = 0;
+  }
+
   /// Use the given [visitor] to visit all of the [children] in the given array.
   void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
     for (Element child in children) {
@@ -2784,7 +2696,7 @@
   ) {
     Element? element = this;
     while (element != null && !predicate(element)) {
-      element = element.enclosingElement3;
+      element = element.enclosingElement;
     }
     return element as E?;
   }
@@ -2794,9 +2706,9 @@
     Element? element = this;
     while (element != null && element is! E) {
       if (element is CompilationUnitElement) {
-        element = element.enclosingElement3;
+        element = element.enclosingElement;
       } else {
-        element = element.enclosingElement3;
+        element = element.enclosingElement;
       }
     }
     return element as E?;
@@ -2866,7 +2778,7 @@
     Element? ancestor = element;
     while (ancestor != null) {
       components.insert(0, (ancestor as ElementImpl).identifier);
-      ancestor = ancestor.enclosingElement3;
+      ancestor = ancestor.enclosingElement;
     }
     _components = components;
   }
@@ -3013,23 +2925,6 @@
   }
 
   @override
-  bool get hasNonFinalField => false;
-
-  @Deprecated('Not useful for clients')
-  @override
-  bool get hasStaticMember => true;
-
-  @override
-  bool get isAbstract => false;
-
-  @Deprecated('Use `is EnumElement` instead')
-  @override
-  bool get isEnum => true;
-
-  @override
-  bool get isMixinApplication => false;
-
-  @override
   bool get isSimplyBounded {
     return hasModifier(Modifier.SIMPLY_BOUNDED);
   }
@@ -3039,9 +2934,6 @@
   }
 
   @override
-  bool get isValidMixin => false;
-
-  @override
   ElementKind get kind => ElementKind.ENUM;
 
   @override
@@ -3093,7 +2985,6 @@
 
   @override
   T? accept<T>(ElementVisitor<T> visitor) {
-    visitor.visitClassElement(this);
     return visitor.visitEnumElement(this);
   }
 
@@ -3130,16 +3021,12 @@
   /// [offset].
   ExecutableElementImpl(String super.name, super.offset, {super.reference});
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  Element get enclosingElement => super.enclosingElement2!;
+  Element get enclosingElement => super.enclosingElement!;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element get enclosingElement2 => super.enclosingElement2!;
-
-  @override
-  Element get enclosingElement3 => super.enclosingElement3!;
+  Element get enclosingElement3 => enclosingElement;
 
   @override
   bool get hasImplicitReturnType {
@@ -3316,62 +3203,6 @@
   }
 }
 
-/// A concrete implementation of an [ExportElement].
-@Deprecated('Use LibraryExportElement instead')
-class ExportElementImpl extends ElementImpl
-    with WrapperElementImpl
-    implements ExportElement {
-  @override
-  final LibraryExportElementImpl base;
-
-  ExportElementImpl(this.base) : super(base.name, base.nameOffset);
-
-  @override
-  List<NamespaceCombinator> get combinators => base.combinators;
-
-  @override
-  CompilationUnitElementImpl get enclosingUnit {
-    var enclosingLibrary = enclosingElement as LibraryElementImpl;
-    return enclosingLibrary._definingCompilationUnit;
-  }
-
-  @override
-  LibraryElement? get exportedLibrary {
-    final uri = base.uri;
-    if (uri is DirectiveUriWithLibrary) {
-      return uri.library;
-    }
-    return null;
-  }
-
-  @override
-  String get identifier => 'export@$nameOffset';
-
-  @override
-  ElementKind get kind => ElementKind.EXPORT;
-
-  @override
-  String? get uri {
-    final uri = base.uri;
-    if (uri is DirectiveUriWithRelativeUriString) {
-      return uri.relativeUriString;
-    } else {
-      return null;
-    }
-  }
-
-  @override
-  // TODO: implement uriEnd
-  int get uriEnd => throw UnimplementedError();
-
-  @override
-  // TODO: implement uriOffset
-  int get uriOffset => throw UnimplementedError();
-
-  @override
-  T? accept<T>(ElementVisitor<T> visitor) => visitor.visitExportElement(this);
-}
-
 /// A concrete implementation of an [ExtensionElement].
 class ExtensionElementImpl extends _ExistingElementImpl
     with TypeParameterizedElementMixin, HasCompletionData
@@ -3411,21 +3242,15 @@
   @override
   String get displayName => name ?? '';
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   CompilationUnitElementImpl get enclosingElement {
-    return _enclosingElement as CompilationUnitElementImpl;
+    return super.enclosingElement as CompilationUnitElementImpl;
   }
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  CompilationUnitElementImpl get enclosingElement2 {
-    return super.enclosingElement2 as CompilationUnitElementImpl;
-  }
-
+  @Deprecated('Use enclosingElement instead')
   @override
   CompilationUnitElementImpl get enclosingElement3 {
-    return super.enclosingElement3 as CompilationUnitElementImpl;
+    return enclosingElement;
   }
 
   @override
@@ -3626,7 +3451,7 @@
   ///
   /// Such fields are `index`, `_name`, and `values`.
   bool get isSyntheticEnumField {
-    return enclosingElement3 is EnumElementImpl &&
+    return enclosingElement is EnumElementImpl &&
         isSynthetic &&
         getter?.isSynthetic == true &&
         setter == null;
@@ -3694,7 +3519,7 @@
   @override
   String get identifier {
     String identifier = super.identifier;
-    Element? enclosing = enclosingElement3;
+    Element? enclosing = enclosingElement;
     if (enclosing is ExecutableElement || enclosing is VariableElement) {
       identifier += "@$nameOffset";
     }
@@ -3862,75 +3687,6 @@
   }
 }
 
-/// A concrete implementation of an [ImportElement].
-@Deprecated('Use LibraryImportElement instead')
-class ImportElementImpl extends ElementImpl
-    with WrapperElementImpl
-    implements ImportElement {
-  @override
-  final LibraryImportElementImpl base;
-
-  ImportElementImpl(this.base) : super(base.name, base.nameOffset);
-
-  @override
-  List<NamespaceCombinator> get combinators => base.combinators;
-
-  @override
-  CompilationUnitElementImpl get enclosingUnit {
-    var enclosingLibrary = enclosingElement as LibraryElementImpl;
-    return enclosingLibrary._definingCompilationUnit;
-  }
-
-  @override
-  String get identifier => 'import@$nameOffset';
-
-  @override
-  LibraryElement? get importedLibrary {
-    final uri = base.uri;
-    if (uri is DirectiveUriWithLibrary) {
-      return uri.library;
-    }
-    return null;
-  }
-
-  @override
-  bool get isDeferred => base.prefix is DeferredImportElementPrefix;
-
-  @override
-  Namespace get namespace => base.namespace;
-
-  @override
-  PrefixElement? get prefix => base.prefix?.element;
-
-  @override
-  String? get uri {
-    final uri = base.uri;
-    if (uri is DirectiveUriWithRelativeUriString) {
-      return uri.relativeUriString;
-    } else {
-      return null;
-    }
-  }
-
-  @override
-  // TODO: implement uriEnd
-  int get uriEnd => throw UnimplementedError();
-
-  @override
-  // TODO: implement uriOffset
-  int get uriOffset => throw UnimplementedError();
-
-  @override
-  bool operator ==(Object other) {
-    return identical(this, other);
-  }
-
-  @override
-  T? accept<T>(ElementVisitor<T> visitor) {
-    return visitor.visitImportElement(this);
-  }
-}
-
 class ImportElementPrefixImpl implements ImportElementPrefix {
   @override
   final PrefixElement element;
@@ -3962,19 +3718,13 @@
   @override
   String get displayName => name;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   ExecutableElement get enclosingElement =>
-      super.enclosingElement2 as ExecutableElement;
+      super.enclosingElement as ExecutableElement;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  ExecutableElement get enclosingElement2 =>
-      super.enclosingElement2 as ExecutableElement;
-
-  @override
-  ExecutableElement get enclosingElement3 =>
-      super.enclosingElement3 as ExecutableElement;
+  ExecutableElement get enclosingElement3 => enclosingElement;
 
   /// Return `true` if this label is associated with a `switch` member (`case
   /// ` or`default`).
@@ -4299,12 +4049,6 @@
   @override
   String get name => super.name!;
 
-  @Deprecated('Use parts2 instead')
-  @override
-  List<CompilationUnitElement> get parts {
-    return _partUnits;
-  }
-
   @override
   List<PartElement> get parts2 => _parts2;
 
@@ -4404,24 +4148,6 @@
     return null;
   }
 
-  @Deprecated('Use PrefixElement.imports instead')
-  @override
-  List<ImportElement> getImportsWithPrefix(PrefixElement prefix) {
-    return prefix.imports;
-  }
-
-  @Deprecated('Use getClass() instead')
-  @override
-  ClassElement? getType(String name) {
-    for (final unitElement in units) {
-      final element = unitElement.getType(name);
-      if (element != null) {
-        return element;
-      }
-    }
-    return null;
-  }
-
   /// Indicates whether it is unnecessary to report an undefined identifier
   /// error for an identifier reference with the given [name] and optional
   /// [prefix].
@@ -4731,14 +4457,6 @@
     return _definingCompilationUnit;
   }
 
-  @Deprecated('Use libraryExports instead')
-  @override
-  List<ExportElement> get exports {
-    return libraryExports
-        .map((e) => ExportElementImpl(e as LibraryExportElementImpl))
-        .toList();
-  }
-
   List<LibraryExportElement> get exports_unresolved {
     return _libraryExports;
   }
@@ -4746,14 +4464,6 @@
   @override
   String get identifier => '${_definingCompilationUnit.source.uri}';
 
-  @Deprecated('Use libraryImports instead')
-  @override
-  List<ImportElement> get imports {
-    return libraryImports
-        .map((e) => ImportElementImpl(e as LibraryImportElementImpl))
-        .toList();
-  }
-
   List<LibraryImportElement> get imports_unresolved {
     return _libraryImports;
   }
@@ -4807,11 +4517,7 @@
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
     _definingCompilationUnit.accept(visitor);
-    // ignore: deprecated_member_use_from_same_package
-    safelyVisitChildren(exports, visitor);
     safelyVisitChildren(libraryExports, visitor);
-    // ignore: deprecated_member_use_from_same_package
-    safelyVisitChildren(imports, visitor);
     safelyVisitChildren(libraryImports, visitor);
   }
 
@@ -4936,8 +4642,8 @@
 
   @override
   Element get nonSynthetic {
-    if (isSynthetic && enclosingElement3 is EnumElementImpl) {
-      return enclosingElement3;
+    if (isSynthetic && enclosingElement is EnumElementImpl) {
+      return enclosingElement;
     }
     return this;
   }
@@ -4947,7 +4653,7 @@
 }
 
 /// A [ClassElementImpl] representing a mixin declaration.
-class MixinElementImpl extends ClassElementImpl implements MixinElement {
+class MixinElementImpl extends ClassOrMixinElementImpl implements MixinElement {
   // TODO(brianwilkerson) Consider creating an abstract superclass of
   // ClassElementImpl that contains the portions of the API that this class
   // needs, and make this class extend the new class.
@@ -4956,7 +4662,9 @@
   /// the mixin.
   List<InterfaceType> _superclassConstraints = const [];
 
-  @override
+  /// Names of methods, getters, setters, and operators that this mixin
+  /// declaration super-invokes.  For setters this includes the trailing "=".
+  /// The list will be empty if this class is not a mixin declaration.
   late List<String> superInvokedNames;
 
   /// Initialize a newly created class element to have the given [name] at the
@@ -4976,11 +4684,9 @@
   }
 
   @override
-  bool get isAbstract => true;
-
-  @Deprecated('Use `is MixinElement` instead')
-  @override
-  bool get isMixin => true;
+  List<ConstructorElement> get constructors {
+    return _constructors;
+  }
 
   @override
   List<InterfaceType> get mixins => const <InterfaceType>[];
@@ -5005,7 +4711,6 @@
 
   @override
   T? accept<T>(ElementVisitor<T> visitor) {
-    visitor.visitClassElement(this);
     return visitor.visitMixinElement(this);
   }
 
@@ -5190,14 +4895,10 @@
   @override
   String? get documentationComment => null;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   Element? get enclosingElement => null;
 
-  @Deprecated('Use enclosingElement3 instead')
-  @override
-  Element? get enclosingElement2 => null;
-
+  @Deprecated('Use enclosingElement instead')
   @override
   Element? get enclosingElement3 => null;
 
@@ -5329,17 +5030,6 @@
     return displayName;
   }
 
-  @Deprecated('Use isAccessibleIn2() instead')
-  @override
-  bool isAccessibleIn(LibraryElement? library) {
-    for (Element element in conflictingElements) {
-      if (element.isAccessibleIn(library)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
   @override
   bool isAccessibleIn2(LibraryElement library) {
     for (Element element in conflictingElements) {
@@ -5429,16 +5119,12 @@
   /// [offset].
   NonParameterVariableElementImpl(String super.name, super.offset);
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  Element get enclosingElement => super.enclosingElement2!;
+  Element get enclosingElement => super.enclosingElement!;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element get enclosingElement2 => super.enclosingElement2!;
-
-  @override
-  Element get enclosingElement3 => super.enclosingElement3!;
+  Element get enclosingElement3 => enclosingElement;
 
   bool get hasInitializer {
     return hasModifier(Modifier.HAS_INITIALIZER);
@@ -5650,10 +5336,6 @@
   @override
   bool get isNamed => parameterKind.isNamed;
 
-  @Deprecated('Use isRequired instead')
-  @override
-  bool get isNotOptional => parameterKind.isRequired;
-
   @override
   bool get isOptional => parameterKind.isOptional;
 
@@ -5708,7 +5390,7 @@
 
   @override
   CompilationUnitElementImpl get enclosingUnit {
-    var enclosingLibrary = enclosingElement3 as LibraryElementImpl;
+    var enclosingLibrary = enclosingElement as LibraryElementImpl;
     return enclosingLibrary._definingCompilationUnit;
   }
 
@@ -5739,31 +5421,17 @@
   @override
   String get displayName => name;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  LibraryElement get enclosingElement =>
-      super.enclosingElement2 as LibraryElement;
+  LibraryOrAugmentationElementImpl get enclosingElement =>
+      super.enclosingElement as LibraryOrAugmentationElementImpl;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  LibraryOrAugmentationElementImpl get enclosingElement2 =>
-      super.enclosingElement2 as LibraryOrAugmentationElementImpl;
-
-  @override
-  LibraryOrAugmentationElementImpl get enclosingElement3 =>
-      super.enclosingElement3 as LibraryOrAugmentationElementImpl;
-
-  @Deprecated('Use imports2 instead')
-  @override
-  List<ImportElement> get imports {
-    return enclosingElement2.imports
-        .where((import) => identical(import.prefix, this))
-        .toList();
-  }
+  LibraryOrAugmentationElementImpl get enclosingElement3 => enclosingElement;
 
   @override
   List<LibraryImportElement> get imports2 {
-    return enclosingElement3.libraryImports
+    return enclosingElement.libraryImports
         .where((import) => import.prefix?.element == this)
         .toList();
   }
@@ -5777,7 +5445,7 @@
   }
 
   @override
-  Scope get scope => _scope ??= PrefixScope(enclosingElement3, this);
+  Scope get scope => _scope ??= PrefixScope(enclosingElement, this);
 
   @override
   T? accept<T>(ElementVisitor<T> visitor) => visitor.visitPrefixElement(this);
@@ -5918,16 +5586,12 @@
     reference?.element = this;
   }
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  Element get enclosingElement => variable.enclosingElement2!;
+  Element get enclosingElement => variable.enclosingElement!;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element get enclosingElement2 => variable.enclosingElement2!;
-
-  @override
-  Element get enclosingElement3 => variable.enclosingElement3!;
+  Element get enclosingElement3 => enclosingElement;
 
   @override
   bool get hasImplicitReturnType => variable.hasImplicitType;
@@ -5941,8 +5605,8 @@
     if (!variable.isSynthetic) {
       return variable;
     }
-    assert(enclosingElement3 is EnumElementImpl);
-    return enclosingElement3;
+    assert(enclosingElement is EnumElementImpl);
+    return enclosingElement;
   }
 
   @override
@@ -5987,16 +5651,12 @@
     property.setter = this;
   }
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  Element get enclosingElement => variable.enclosingElement2!;
+  Element get enclosingElement => variable.enclosingElement!;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element get enclosingElement2 => variable.enclosingElement2!;
-
-  @override
-  Element get enclosingElement3 => variable.enclosingElement3!;
+  Element get enclosingElement3 => enclosingElement;
 
   @override
   bool get isSetter => true;
@@ -6094,10 +5754,10 @@
   @override
   Element get nonSynthetic {
     if (isSynthetic) {
-      if (enclosingElement3 is EnumElementImpl) {
+      if (enclosingElement is EnumElementImpl) {
         // TODO(scheglov) remove 'index'?
         if (name == 'index' || name == 'values') {
-          return enclosingElement3;
+          return enclosingElement;
         }
       }
       return (getter ?? setter)!;
@@ -6238,16 +5898,16 @@
 
   @override
   ParameterElement? get superConstructorParameter {
-    final enclosingElement3 = this.enclosingElement3;
-    if (enclosingElement3 is ConstructorElementImpl) {
-      var superConstructor = enclosingElement3.superConstructor;
+    final enclosingElement = this.enclosingElement;
+    if (enclosingElement is ConstructorElementImpl) {
+      var superConstructor = enclosingElement.superConstructor;
       if (superConstructor != null) {
         var superParameters = superConstructor.parameters;
         if (isNamed) {
           return superParameters
               .firstWhereOrNull((e) => e.isNamed && e.name == name);
         } else {
-          var index = indexIn(enclosingElement3);
+          var index = indexIn(enclosingElement);
           var positionalSuperParameters =
               superParameters.where((e) => e.isPositional).toList();
           if (index >= 0 && index < positionalSuperParameters.length) {
@@ -6348,19 +6008,13 @@
   @override
   String get displayName => name;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
   CompilationUnitElement get enclosingElement =>
-      super.enclosingElement2 as CompilationUnitElement;
+      super.enclosingElement as CompilationUnitElement;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  CompilationUnitElement get enclosingElement2 =>
-      super.enclosingElement2 as CompilationUnitElement;
-
-  @override
-  CompilationUnitElement get enclosingElement3 =>
-      super.enclosingElement3 as CompilationUnitElement;
+  CompilationUnitElement get enclosingElement3 => enclosingElement;
 
   /// Returns whether this alias is a "proper rename" of [aliasedClass], as
   /// defined in the constructor-tearoffs specification.
@@ -6515,7 +6169,7 @@
       );
     } else if (type is TypeParameterType) {
       return TypeParameterTypeImpl(
-        element: type.element2,
+        element2: type.element2,
         nullabilitySuffix: resultNullability,
         alias: InstantiatedTypeAliasElementImpl(
           element: this,
@@ -6612,7 +6266,7 @@
       return true;
     }
     if (other is TypeParameterElement) {
-      if (other.enclosingElement3 == null || enclosingElement3 == null) {
+      if (other.enclosingElement == null || enclosingElement == null) {
         return identical(other, this);
       }
       return other.location == location;
@@ -6634,7 +6288,7 @@
     required NullabilitySuffix nullabilitySuffix,
   }) {
     return TypeParameterTypeImpl(
-      element: this,
+      element2: this,
       nullabilitySuffix: nullabilitySuffix,
     );
   }
@@ -6825,175 +6479,12 @@
   DartObject? computeConstantValue() => null;
 }
 
-@Deprecated('Remove it when removing its uses')
-mixin WrapperElementImpl implements ElementImpl {
-  _ExistingElementImpl get base;
-
+class VariablePatternElementImpl extends LocalVariableElementImpl
+    implements VariablePatternElement {
   @override
-  AnalysisContext get context => base.context;
+  final List<VariablePatternElementImpl> aliases = [];
 
-  @override
-  Element get declaration => base.declaration;
-
-  @override
-  String get displayName => base.displayName;
-
-  @override
-  String? get documentationComment => base.documentationComment;
-
-  @override
-  Element? get enclosingElement => base.enclosingElement3;
-
-  @override
-  bool get hasAlwaysThrows => base.hasAlwaysThrows;
-
-  @override
-  bool get hasDeprecated => base.hasDeprecated;
-
-  @override
-  bool get hasDoNotStore => base.hasDoNotStore;
-
-  @override
-  bool get hasFactory => base.hasFactory;
-
-  @override
-  bool get hasInternal => base.hasInternal;
-
-  @override
-  bool get hasIsTest => base.hasIsTest;
-
-  @override
-  bool get hasIsTestGroup => base.hasIsTestGroup;
-
-  @override
-  bool get hasJS => base.hasJS;
-
-  @override
-  bool get hasLiteral => base.hasLiteral;
-
-  @override
-  bool get hasMustCallSuper => base.hasMustCallSuper;
-
-  @override
-  bool get hasNonVirtual => base.hasNonVirtual;
-
-  @override
-  bool get hasOptionalTypeArgs => base.hasOptionalTypeArgs;
-
-  @override
-  bool get hasOverride => base.hasOverride;
-
-  @override
-  bool get hasProtected => base.hasProtected;
-
-  @override
-  bool get hasRequired => base.hasRequired;
-
-  @override
-  bool get hasSealed => base.hasSealed;
-
-  @override
-  bool get hasUseResult => base.hasUseResult;
-
-  @override
-  bool get hasVisibleForOverriding => base.hasVisibleForOverriding;
-
-  @override
-  bool get hasVisibleForTemplate => base.hasVisibleForTemplate;
-
-  @override
-  bool get hasVisibleForTesting => base.hasVisibleForTesting;
-
-  @override
-  int get id => base.id;
-
-  @override
-  bool get isPrivate => base.isPrivate;
-
-  @override
-  bool get isPublic => base.isPublic;
-
-  @override
-  bool get isSynthetic => base.isSynthetic;
-
-  @override
-  ElementKind get kind => base.kind;
-
-  @override
-  LibraryElementImpl get library => base.library;
-
-  @override
-  Source get librarySource => base.librarySource;
-
-  @override
-  ElementLocation get location => base.location;
-
-  @override
-  List<ElementAnnotation> get metadata => base.metadata;
-
-  @override
-  String? get name => base.name;
-
-  @override
-  int get nameLength => base.nameLength;
-
-  @override
-  int get nameOffset => base.nameOffset;
-
-  @override
-  Element get nonSynthetic => this;
-
-  @override
-  AnalysisSession? get session => base.session;
-
-  @override
-  Source get source => base.source;
-
-  @override
-  bool operator ==(Object other) {
-    return identical(this, other);
-  }
-
-  @override
-  String getDisplayString(
-      {required bool withNullability, bool multiline = false}) {
-    return base.getDisplayString(
-      withNullability: withNullability,
-      multiline: multiline,
-    );
-  }
-
-  @override
-  String getExtendedDisplayName(String? shortName) {
-    return base.getExtendedDisplayName(shortName);
-  }
-
-  @Deprecated('Use isAccessibleIn2() instead')
-  @override
-  bool isAccessibleIn(LibraryElement? library) {
-    return base.isAccessibleIn(library);
-  }
-
-  @override
-  bool isAccessibleIn2(LibraryElement library) {
-    return base.isAccessibleIn2(library);
-  }
-
-  @override
-  E? thisOrAncestorMatching<E extends Element>(
-      bool Function(Element p1) predicate) {
-    return base.thisOrAncestorMatching(predicate);
-  }
-
-  @override
-  E? thisOrAncestorOfType<E extends Element>() {
-    return base.thisOrAncestorOfType();
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    base.visitChildren(visitor);
-  }
+  VariablePatternElementImpl(super.name, super.offset);
 }
 
 abstract class _ExistingElementImpl extends ElementImpl with _HasLibraryMixin {
@@ -7008,7 +6499,7 @@
   Source get librarySource => library.source;
 
   @override
-  Source get source => enclosingElement3!.source!;
+  Source get source => enclosingElement!.source!;
 }
 
 /// Instances of [List]s that are used as "not yet computed" values, they
diff --git a/pkg/analyzer/lib/src/dart/element/extensions.dart b/pkg/analyzer/lib/src/dart/element/extensions.dart
index 07b03e2..5122ae1 100644
--- a/pkg/analyzer/lib/src/dart/element/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/element/extensions.dart
@@ -6,6 +6,7 @@
 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:collection/collection.dart';
 import 'package:meta/meta_meta.dart';
 
 extension ElementAnnotationExtensions on ElementAnnotation {
@@ -25,7 +26,7 @@
         }
       }
     } else if (element is ConstructorElement) {
-      interfaceElement = element.enclosingElement3;
+      interfaceElement = element.enclosingElement;
     }
     if (interfaceElement == null) {
       return const <TargetKind>{};
@@ -68,21 +69,21 @@
       return true;
     }
 
-    var ancestor = enclosingElement3;
-    if (ancestor is ClassElement) {
+    var ancestor = enclosingElement;
+    if (ancestor is InterfaceElement) {
       if (ancestor.hasDoNotStore) {
         return true;
       }
-      ancestor = ancestor.enclosingElement3;
+      ancestor = ancestor.enclosingElement;
     } else if (ancestor is ExtensionElement) {
       if (ancestor.hasDoNotStore) {
         return true;
       }
-      ancestor = ancestor.enclosingElement3;
+      ancestor = ancestor.enclosingElement;
     }
 
     return ancestor is CompilationUnitElement &&
-        ancestor.enclosingElement3.hasDoNotStore;
+        ancestor.enclosingElement.hasDoNotStore;
   }
 
   /// Return `true` if this element is an instance member of a class or mixin.
@@ -94,8 +95,8 @@
   /// [PropertyAccessorElement]s.
   bool get isInstanceMember {
     var this_ = this;
-    var enclosing = this_.enclosingElement3;
-    if (enclosing is ClassElement) {
+    var enclosing = this_.enclosingElement;
+    if (enclosing is InterfaceElement) {
       return this_ is MethodElement && !this_.isStatic ||
           this_ is PropertyAccessorElement && !this_.isStatic;
     }
@@ -105,7 +106,17 @@
 
 extension ExecutableElementExtension on ExecutableElement {
   bool get isEnumConstructor {
-    return this is ConstructorElement && enclosingElement3 is EnumElementImpl;
+    return this is ConstructorElement && enclosingElement is EnumElementImpl;
+  }
+}
+
+extension ExecutableElementExtensionQuestion on ExecutableElement? {
+  DartType? get firstParameterType {
+    final self = this;
+    if (self is MethodElement) {
+      return self.parameters.firstOrNull?.type;
+    }
+    return null;
   }
 }
 
@@ -126,6 +137,15 @@
 }
 
 extension RecordTypeExtension on RecordType {
+  /// A regular expression used to match positional field names.
+  static final RegExp _positionalName = RegExp(r'^\$(([0-9])|([1-9][0-9]*))$');
+
+  /// The [name] is either an actual name like `foo` in `({int foo})`, or
+  /// the name of a positional field like `$0` in `(int, String)`.
+  RecordTypeField? fieldByName(String name) {
+    return namedField(name) ?? positionalField(name);
+  }
+
   RecordTypeNamedField? namedField(String name) {
     for (final field in namedFields) {
       if (field.name == name) {
@@ -134,4 +154,24 @@
     }
     return null;
   }
+
+  RecordTypePositionalField? positionalField(String name) {
+    final index = positionalFieldIndex(name);
+    if (index != null && index < positionalFields.length) {
+      return positionalFields[index];
+    }
+    return null;
+  }
+
+  /// Attempt to parse `$0`, `$1`, etc.
+  static int? positionalFieldIndex(String name) {
+    final match = _positionalName.firstMatch(name);
+    if (match != null) {
+      final indexStr = match.group(1);
+      if (indexStr != null) {
+        return int.tryParse(indexStr);
+      }
+    }
+    return null;
+  }
 }
diff --git a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
index dc5f480..84ba313 100644
--- a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
+++ b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
@@ -116,7 +116,7 @@
   /// is a subtype of the [parameterType].
   void constrainArgument(
       DartType argumentType, DartType parameterType, String parameterName,
-      {ClassElement? genericClass}) {
+      {InterfaceElement? genericClass}) {
     var origin = _TypeConstraintFromArgument(
       argumentType,
       parameterType,
@@ -130,7 +130,7 @@
   /// Applies all the argument constraints implied by [parameters] and
   /// [argumentTypes].
   void constrainArguments(
-      {ClassElement? genericClass,
+      {InterfaceElement? genericClass,
       required List<ParameterElement> parameters,
       required List<DartType> argumentTypes}) {
     for (int i = 0; i < argumentTypes.length; i++) {
@@ -729,7 +729,7 @@
   final DartType argumentType;
   final DartType parameterType;
   final String parameterName;
-  final ClassElement? genericClass;
+  final InterfaceElement? genericClass;
 
   _TypeConstraintFromArgument(
       this.argumentType, this.parameterType, this.parameterName,
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index 6ade8c9..12f7996 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -143,7 +143,7 @@
     var result = <Name, ExecutableElement>{};
 
     var substitution = Substitution.fromInterfaceType(type);
-    var rawMap = getInheritedConcreteMap2(type.element);
+    var rawMap = getInheritedConcreteMap2(type.element2);
     for (var rawEntry in rawMap.entries) {
       result[rawEntry.key] = ExecutableMember.from2(
         rawEntry.value,
@@ -171,7 +171,7 @@
     var result = <Name, ExecutableElement>{};
 
     var substitution = Substitution.fromInterfaceType(type);
-    var rawMap = getInheritedMap2(type.element);
+    var rawMap = getInheritedMap2(type.element2);
     for (var rawEntry in rawMap.entries) {
       result[rawEntry.key] = ExecutableMember.from2(
         rawEntry.value,
@@ -293,7 +293,7 @@
   /// if no members would be overridden.
   @Deprecated('Use getOverridden2')
   List<ExecutableElement>? getOverridden(InterfaceType type, Name name) {
-    return getOverridden2(type.element, name);
+    return getOverridden2(type.element2, name);
   }
 
   /// Return all members of mixins, superclasses, and interfaces that a member
@@ -367,7 +367,7 @@
         continue;
       }
 
-      var class_ = executable.enclosingElement3;
+      var class_ = executable.enclosingElement;
       if (class_ is ClassElement && class_.isDartCoreObject) {
         continue;
       }
@@ -454,14 +454,7 @@
     var superImplemented = <Map<Name, ExecutableElement>>[];
     var implemented = <Name, ExecutableElement>{};
 
-    final InterfaceType? superType;
-    if (element is ClassElement) {
-      superType = element.supertype;
-    } else if (element is EnumElement) {
-      superType = element.supertype;
-    } else {
-      throw UnimplementedError('(${element.runtimeType}) $element');
-    }
+    final InterfaceType? superType = element.supertype;
 
     Interface? superTypeInterface;
     if (superType != null) {
@@ -527,7 +520,7 @@
         }
 
         var current = currentList.single;
-        if (candidate.enclosingElement3 == mixinElement) {
+        if (candidate.enclosingElement == mixinElement) {
           namedCandidates[name] = [
             isNonNullableByDefault
                 ? candidate
@@ -723,7 +716,7 @@
     Name name,
     ExecutableElement executable,
   ) {
-    if (executable.enclosingElement3 == class_) {
+    if (executable.enclosingElement == class_) {
       return executable;
     }
 
@@ -913,9 +906,9 @@
   }
 
   static bool _isDeclaredInObject(ExecutableElement element) {
-    var enclosing = element.enclosingElement3;
+    var enclosing = element.enclosingElement;
     // TODO(scheglov) `is! MixinElement` after the separation.
-    return enclosing is ClassElement &&
+    return enclosing is InterfaceElement &&
         enclosing.supertype == null &&
         enclosing is! MixinElement;
   }
diff --git a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
index a07fab4..11caa4d 100644
--- a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
+++ b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
@@ -71,9 +71,6 @@
   /// the class 'Object'.
   InstantiatedClass? get superclass {
     final element = this.element;
-    if (element is! ClassElement) {
-      return null;
-    }
 
     var supertype = element.supertype;
     if (supertype == null) return null;
@@ -710,6 +707,16 @@
       return getLeastUpperBound(T1, _typeSystem.objectNone);
     }
 
+    // UP((...), Record) = Record
+    if (T1 is RecordType && T2.isDartCoreRecord) {
+      return T2;
+    }
+
+    // UP(Record, (...)) = Record
+    if (T1.isDartCoreRecord && T2 is RecordType) {
+      return T1;
+    }
+
     // Record types.
     if (T1 is RecordTypeImpl && T2 is RecordTypeImpl) {
       return _recordType(T1, T2);
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index b0708f0..2ba5a6d 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -43,16 +43,12 @@
   @override
   String get displayName => declaration.displayName;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  ClassElement get enclosingElement => declaration.enclosingElement2;
+  InterfaceElement get enclosingElement => declaration.enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  ClassElement get enclosingElement2 => declaration.enclosingElement2;
-
-  @override
-  InterfaceElement get enclosingElement3 => declaration.enclosingElement3;
+  InterfaceElement get enclosingElement3 => enclosingElement;
 
   @override
   bool get isConst => declaration.isConst;
@@ -352,16 +348,12 @@
   @override
   String get displayName => declaration.displayName;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  Element get enclosingElement => declaration.enclosingElement3;
+  Element get enclosingElement => declaration.enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element get enclosingElement2 => declaration.enclosingElement3;
-
-  @override
-  Element get enclosingElement3 => declaration.enclosingElement3;
+  Element get enclosingElement3 => enclosingElement;
 
   @override
   PropertyAccessorElement? get getter {
@@ -450,16 +442,12 @@
   @override
   FunctionElement get declaration => super.declaration as FunctionElement;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  Element get enclosingElement => declaration.enclosingElement3;
+  Element get enclosingElement => declaration.enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element get enclosingElement2 => declaration.enclosingElement3;
-
-  @override
-  Element get enclosingElement3 => declaration.enclosingElement3;
+  Element get enclosingElement3 => enclosingElement;
 
   @override
   bool get isDartCoreIdentical => declaration.isDartCoreIdentical;
@@ -517,16 +505,12 @@
   @override
   String? get documentationComment => _declaration.documentationComment;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  Element? get enclosingElement => _declaration.enclosingElement3;
+  Element? get enclosingElement => _declaration.enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element? get enclosingElement2 => _declaration.enclosingElement3;
-
-  @override
-  Element? get enclosingElement3 => _declaration.enclosingElement3;
+  Element? get enclosingElement3 => enclosingElement;
 
   @override
   bool get hasAlwaysThrows => _declaration.hasAlwaysThrows;
@@ -660,11 +644,6 @@
   String getExtendedDisplayName(String? shortName) =>
       _declaration.getExtendedDisplayName(shortName);
 
-  @Deprecated('Use isAccessibleIn2() instead')
-  @override
-  bool isAccessibleIn(LibraryElement? library) =>
-      _declaration.isAccessibleIn(library);
-
   @override
   bool isAccessibleIn2(LibraryElement library) =>
       _declaration.isAccessibleIn2(library);
@@ -815,16 +794,12 @@
   @override
   MethodElement get declaration => super.declaration as MethodElement;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  Element get enclosingElement => declaration.enclosingElement3;
+  Element get enclosingElement => declaration.enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element get enclosingElement2 => declaration.enclosingElement3;
-
-  @override
-  Element get enclosingElement3 => declaration.enclosingElement3;
+  Element get enclosingElement3 => enclosingElement;
 
   @override
   String get name => declaration.name;
@@ -907,16 +882,12 @@
   @override
   String? get defaultValueCode => declaration.defaultValueCode;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  Element? get enclosingElement => declaration.enclosingElement3;
+  Element? get enclosingElement => declaration.enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element? get enclosingElement2 => declaration.enclosingElement3;
-
-  @override
-  Element? get enclosingElement3 => declaration.enclosingElement3;
+  Element? get enclosingElement3 => enclosingElement;
 
   @override
   bool get hasDefaultValue => declaration.hasDefaultValue;
@@ -1056,16 +1027,12 @@
   PropertyAccessorElement get declaration =>
       super.declaration as PropertyAccessorElement;
 
-  @Deprecated('Use enclosingElement3 instead')
   @override
-  Element get enclosingElement => declaration.enclosingElement3;
+  Element get enclosingElement => declaration.enclosingElement;
 
-  @Deprecated('Use enclosingElement3 instead')
+  @Deprecated('Use enclosingElement instead')
   @override
-  Element get enclosingElement2 => declaration.enclosingElement3;
-
-  @override
-  Element get enclosingElement3 => declaration.enclosingElement3;
+  Element get enclosingElement3 => enclosingElement;
 
   @override
   bool get isGetter => declaration.isGetter;
diff --git a/pkg/analyzer/lib/src/dart/element/normalize.dart b/pkg/analyzer/lib/src/dart/element/normalize.dart
index 86fd2b8..ed65d5f 100644
--- a/pkg/analyzer/lib/src/dart/element/normalize.dart
+++ b/pkg/analyzer/lib/src/dart/element/normalize.dart
@@ -326,7 +326,7 @@
 
     // * else X & S
     return TypeParameterTypeImpl(
-      element: X.declaration,
+      element2: X.declaration,
       nullabilitySuffix: NullabilitySuffix.none,
       promotedBound: S,
     );
diff --git a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
index 54539c6..3e68fea 100644
--- a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
@@ -105,7 +105,7 @@
     return NamedTypeBuilder(
       type.linker,
       type.typeSystem,
-      type.element,
+      type.element2,
       newTypeArguments ?? type.arguments,
       newNullability ?? type.nullabilitySuffix,
     );
@@ -133,7 +133,7 @@
 
     var promotedBound = (type as TypeParameterTypeImpl).promotedBound;
     return TypeParameterTypeImpl(
-      element: type.element2,
+      element2: type.element2,
       nullabilitySuffix: newNullability ?? type.nullabilitySuffix,
       promotedBound: newPromotedBound ?? promotedBound,
       alias: type.alias,
@@ -149,7 +149,7 @@
     }
 
     return TypeParameterTypeImpl(
-      element: type.element2,
+      element2: type.element2,
       nullabilitySuffix: newNullability,
       alias: type.alias,
     );
@@ -390,8 +390,8 @@
     var newNullability = visitNullability(type);
 
     var parameters = const <TypeParameterElement>[];
-    var element = type.element;
-    if (element is ClassElement) {
+    var element = type.element2;
+    if (element is InterfaceElement) {
       parameters = element.typeParameters;
     } else if (element is TypeAliasElement) {
       parameters = element.typeParameters;
diff --git a/pkg/analyzer/lib/src/dart/element/subtype.dart b/pkg/analyzer/lib/src/dart/element/subtype.dart
index 9dfb25a..aa8e43b 100644
--- a/pkg/analyzer/lib/src/dart/element/subtype.dart
+++ b/pkg/analyzer/lib/src/dart/element/subtype.dart
@@ -195,7 +195,7 @@
       var T1_promotedBound = T1.promotedBound;
       if (T1_promotedBound != null) {
         var X1 = TypeParameterTypeImpl(
-          element: T1.element2,
+          element2: T1.element2,
           nullabilitySuffix: T1.nullabilitySuffix,
         );
         return isSubtypeOf(T0, X1) && isSubtypeOf(T0, T1_promotedBound);
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 508ec19..82bd2da 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -23,20 +23,11 @@
   /// The unique instance of this class.
   static final DynamicTypeImpl instance = DynamicTypeImpl._();
 
+  @override
+  final DynamicElementImpl element2 = DynamicElementImpl();
+
   /// Prevent the creation of instances of this class.
-  DynamicTypeImpl._() : super(DynamicElementImpl());
-
-  @Deprecated('Use element2 instead')
-  @override
-  Element get element {
-    return super.element!;
-  }
-
-  @override
-  DynamicElementImpl get element2 {
-    // ignore: deprecated_member_use_from_same_package
-    return super.element as DynamicElementImpl;
-  }
+  DynamicTypeImpl._();
 
   @override
   int get hashCode => 1;
@@ -98,13 +89,8 @@
     required List<ParameterElement> parameters,
     required this.returnType,
     required this.nullabilitySuffix,
-    InstantiatedTypeAliasElement? alias,
-  })  : parameters = _sortNamedParameters(parameters),
-        super(null, alias: alias);
-
-  @Deprecated('Use element2 instead')
-  @override
-  Null get element => null;
+    super.alias,
+  }) : parameters = _sortNamedParameters(parameters);
 
   @override
   Null get element2 => null;
@@ -467,8 +453,8 @@
     required this.element2,
     required this.typeArguments,
     required this.nullabilitySuffix,
-    InstantiatedTypeAliasElement? alias,
-  }) : super(element2 as ClassElement, alias: alias) {
+    super.alias,
+  }) {
     var typeParameters = element2.typeParameters;
     if (typeArguments.length != typeParameters.length) {
       throw ArgumentError(
@@ -515,10 +501,6 @@
     return _constructors!;
   }
 
-  @Deprecated('Use element2 instead')
-  @override
-  ClassElement get element => super.element as ClassElement;
-
   @override
   int get hashCode {
     return element2.hashCode;
@@ -641,7 +623,7 @@
 
   @Deprecated('Check element, or use getDisplayString()')
   @override
-  String get name => element.name;
+  String get name => element2.name;
 
   @override
   InterfaceType? get superclass {
@@ -931,11 +913,7 @@
   final NullabilitySuffix nullabilitySuffix;
 
   /// Prevent the creation of instances of this class.
-  NeverTypeImpl._(this.nullabilitySuffix) : super(NeverElementImpl.instance);
-
-  @Deprecated('Use element2 instead')
-  @override
-  NeverElementImpl get element => super.element as NeverElementImpl;
+  NeverTypeImpl._(this.nullabilitySuffix);
 
   @override
   int get hashCode => 0;
@@ -1010,13 +988,8 @@
     required this.positionalFields,
     required List<RecordTypeNamedFieldImpl> namedFields,
     required this.nullabilitySuffix,
-    InstantiatedTypeAliasElement? alias,
-  })  : namedFields = _sortNamedFields(namedFields),
-        super(null, alias: alias);
-
-  @Deprecated('Use element2 instead')
-  @override
-  Null get element => null;
+    super.alias,
+  }) : namedFields = _sortNamedFields(namedFields);
 
   @override
   Null get element2 => null;
@@ -1153,25 +1126,8 @@
   @override
   InstantiatedTypeAliasElement? alias;
 
-  /// The element representing the declaration of this type, or `null` if the
-  /// type has not, or cannot, be associated with an element.
-  final Element? _element;
-
-  /// Initialize a newly created type to be declared by the given [element2].
-  TypeImpl(this._element, {this.alias});
-
-  @deprecated
-  @override
-  String get displayName {
-    return getDisplayString(
-      withNullability: false,
-      skipAllDynamicArguments: true,
-    );
-  }
-
-  @Deprecated('Use element2 instead')
-  @override
-  Element? get element => _element;
+  /// Initialize a newly created type.
+  TypeImpl({this.alias});
 
   @override
   bool get isBottom => false;
@@ -1302,6 +1258,9 @@
 /// A concrete implementation of a [TypeParameterType].
 class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
   @override
+  final TypeParameterElement element2;
+
+  @override
   final NullabilitySuffix nullabilitySuffix;
 
   /// An optional promoted bound on the type parameter.
@@ -1313,14 +1272,11 @@
   /// Initialize a newly created type parameter type to be declared by the given
   /// [element] and to have the given name.
   TypeParameterTypeImpl({
-    required TypeParameterElement element,
+    required this.element2,
     required this.nullabilitySuffix,
     this.promotedBound,
-    InstantiatedTypeAliasElement? alias,
-  }) : super(
-          element,
-          alias: alias,
-        );
+    super.alias,
+  });
 
   @override
   DartType get bound =>
@@ -1329,16 +1285,6 @@
   @override
   ElementLocation get definition => element2.location!;
 
-  @Deprecated('Use element2 instead')
-  @override
-  TypeParameterElement get element => super.element as TypeParameterElement;
-
-  @override
-  TypeParameterElement get element2 {
-    // ignore: deprecated_member_use_from_same_package
-    return super.element as TypeParameterElement;
-  }
-
   @override
   int get hashCode => element2.hashCode;
 
@@ -1363,7 +1309,7 @@
 
   @Deprecated('Check element, or use getDisplayString()')
   @override
-  String get name => element.name;
+  String get name => element2.name;
 
   @override
   bool operator ==(Object other) {
@@ -1417,7 +1363,7 @@
       return promotedBound.resolveToBound(objectType);
     }
 
-    var bound = element.bound;
+    var bound = element2.bound;
     if (bound == null) {
       return objectType;
     }
@@ -1441,7 +1387,7 @@
   TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
     if (this.nullabilitySuffix == nullabilitySuffix) return this;
     return TypeParameterTypeImpl(
-      element: element2,
+      element2: element2,
       nullabilitySuffix: nullabilitySuffix,
       promotedBound: promotedBound,
     );
@@ -1454,11 +1400,7 @@
   static final VoidTypeImpl instance = VoidTypeImpl._();
 
   /// Prevent the creation of instances of this class.
-  VoidTypeImpl._() : super(null);
-
-  @Deprecated('Use element2 instead')
-  @override
-  Null get element => null;
+  VoidTypeImpl._();
 
   @override
   Null get element2 => null;
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index a9354ec..3020df7 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -31,7 +31,7 @@
   var map = <TypeParameterElement, DartType>{};
   for (int i = 0; i < typeParameters.length; ++i) {
     map[typeParameters[i]] = TypeParameterTypeImpl(
-      element: freshParameters[i],
+      element2: freshParameters[i],
       nullabilitySuffix: NullabilitySuffix.none,
     );
   }
@@ -320,7 +320,7 @@
   @override
   DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
     return TypeParameterTypeImpl(
-      element: parameter,
+      element2: parameter,
       nullabilitySuffix: NullabilitySuffix.star,
     );
   }
@@ -537,7 +537,7 @@
     return NamedTypeBuilder(
       type.linker,
       type.typeSystem,
-      type.element,
+      type.element2,
       arguments,
       type.nullabilitySuffix,
     );
diff --git a/pkg/analyzer/lib/src/dart/element/type_demotion.dart b/pkg/analyzer/lib/src/dart/element/type_demotion.dart
index 341bfd5..5647d53 100644
--- a/pkg/analyzer/lib/src/dart/element/type_demotion.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_demotion.dart
@@ -36,7 +36,7 @@
       var typeImpl = type as TypeParameterTypeImpl;
       if (typeImpl.promotedBound != null) {
         return TypeParameterTypeImpl(
-          element: type.element2,
+          element2: type.element2,
           nullabilitySuffix: newNullability ?? type.nullabilitySuffix,
           alias: type.alias,
         );
diff --git a/pkg/analyzer/lib/src/dart/element/type_provider.dart b/pkg/analyzer/lib/src/dart/element/type_provider.dart
index 28033ac..5e32f6c 100644
--- a/pkg/analyzer/lib/src/dart/element/type_provider.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_provider.dart
@@ -31,6 +31,7 @@
   'int',
   'Null',
   'num',
+  'Record',
   'String',
 };
 
@@ -552,7 +553,7 @@
     if (typeParameters.isNotEmpty) {
       typeArguments = typeParameters.map((e) {
         return TypeParameterTypeImpl(
-          element: e,
+          element2: e,
           nullabilitySuffix: _nullabilitySuffix,
         );
       }).toList(growable: false);
diff --git a/pkg/analyzer/lib/src/dart/element/type_schema.dart b/pkg/analyzer/lib/src/dart/element/type_schema.dart
index bd5ccb2..cda14dd 100644
--- a/pkg/analyzer/lib/src/dart/element/type_schema.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_schema.dart
@@ -20,7 +20,7 @@
 class UnknownInferredType extends TypeImpl {
   static final UnknownInferredType instance = UnknownInferredType._();
 
-  UnknownInferredType._() : super(null);
+  UnknownInferredType._();
 
   @override
   Element? get element2 => null;
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index 5acb23d..fd97800 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -316,7 +316,7 @@
   }
 
   List<InterfaceType> gatherMixinSupertypeConstraintsForInference(
-      ClassElement mixinElement) {
+      InterfaceElement mixinElement) {
     List<InterfaceType> candidates;
     if (mixinElement is MixinElement) {
       candidates = mixinElement.superclassConstraints;
@@ -327,7 +327,7 @@
       }
       candidates = [supertype];
       candidates.addAll(mixinElement.mixins);
-      if (mixinElement.isMixinApplication) {
+      if (mixinElement is ClassElement && mixinElement.isMixinApplication) {
         candidates.removeLast();
       }
     }
@@ -1319,7 +1319,7 @@
       if (type.promotedBound != null) {
         var promotedBound = promoteToNonNull(type.promotedBound!);
         return TypeParameterTypeImpl(
-          element: element,
+          element2: element,
           nullabilitySuffix: NullabilitySuffix.none,
           promotedBound: promotedBound,
         );
@@ -1333,7 +1333,7 @@
         promotedBound = null;
       }
       return TypeParameterTypeImpl(
-        element: element,
+        element2: element,
         nullabilitySuffix: NullabilitySuffix.none,
         promotedBound: promotedBound,
       );
@@ -1428,7 +1428,7 @@
       freshTypeParameters.add(freshTypeParameter);
       freshTypeParameterTypes.add(
         TypeParameterTypeImpl(
-          element: freshTypeParameter,
+          element2: freshTypeParameter,
           nullabilitySuffix: NullabilitySuffix.none,
         ),
       );
@@ -1594,7 +1594,7 @@
       if (isSubtypeOf(to, from.bound)) {
         var declaration = from.element2.declaration;
         return TypeParameterTypeImpl(
-          element: declaration,
+          element2: declaration,
           nullabilitySuffix: _promotedTypeParameterTypeNullability(
             from.nullabilitySuffix,
             to.nullabilitySuffix,
@@ -1717,7 +1717,7 @@
     // If the method being invoked comes from an extension, don't refine the
     // type because we can only make guarantees about methods defined in the
     // SDK, and the numeric methods we refine are all instance methods.
-    if (methodElement.enclosingElement3 is ExtensionElement) {
+    if (methodElement.enclosingElement is ExtensionElement) {
       return currentType;
     }
 
@@ -1821,7 +1821,7 @@
     // If the method being invoked comes from an extension, don't refine the
     // type because we can only make guarantees about methods defined in the
     // SDK, and the numeric methods we refine are all instance methods.
-    if (methodElement.enclosingElement3 is ExtensionElement) {
+    if (methodElement.enclosingElement is ExtensionElement) {
       return currentType;
     }
 
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 68b9256..6491ba2 100644
--- a/pkg/analyzer/lib/src/dart/error/ffi_code.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/ffi_code.g.dart
@@ -270,8 +270,7 @@
     hasPublishedDocs: true,
   );
 
-  ///  Parameters:
-  ///  0: the type of the field
+  ///  No parameters.
   static const FfiCode MISSING_FIELD_TYPE_IN_STRUCT = FfiCode(
     'MISSING_FIELD_TYPE_IN_STRUCT',
     "Fields in struct classes must have an explicitly declared type of 'int', "
@@ -344,7 +343,8 @@
   );
 
   ///  Parameters:
-  ///  0: the type of the field
+  ///  0: the name of the field
+  ///  1: the type of the field
   static const FfiCode NON_SIZED_TYPE_ARGUMENT = FfiCode(
     'NON_SIZED_TYPE_ARGUMENT',
     "The type '{1}' isn't a valid type argument for '{0}'. The type argument "
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 cada0da..e0b35ac 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
@@ -27,6 +27,9 @@
   );
 
   ///  Users should not assign values marked `@doNotStore`.
+  ///
+  ///  Parameters:
+  ///  0: the name of the field or variable
   static const HintCode ASSIGNMENT_OF_DO_NOT_STORE = HintCode(
     'ASSIGNMENT_OF_DO_NOT_STORE',
     "'{0}' is marked 'doNotStore' and shouldn't be assigned to a field or "
@@ -297,9 +300,10 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
-  ///
   ///  https://github.com/dart-lang/sdk/issues/44063
+  ///
+  ///  Parameters:
+  ///  0: the name of the library
   static const HintCode IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE = HintCode(
     'IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE',
     "The library '{0}' is legacy, and shouldn't be imported into a null safe "
@@ -310,6 +314,9 @@
 
   ///  When "strict-inference" is enabled, collection literal types must be
   ///  inferred via the context type, or have type arguments.
+  ///
+  ///  Parameters:
+  ///  0: the name of the collection
   static const HintCode INFERENCE_FAILURE_ON_COLLECTION_LITERAL = HintCode(
     'INFERENCE_FAILURE_ON_COLLECTION_LITERAL',
     "The type argument(s) of '{0}' can't be inferred.",
@@ -318,6 +325,9 @@
 
   ///  When "strict-inference" is enabled, types in function invocations must be
   ///  inferred via the context type, or have type arguments.
+  ///
+  ///  Parameters:
+  ///  0: the name of the function
   static const HintCode INFERENCE_FAILURE_ON_FUNCTION_INVOCATION = HintCode(
     'INFERENCE_FAILURE_ON_FUNCTION_INVOCATION',
     "The type argument(s) of the function '{0}' can't be inferred.",
@@ -329,6 +339,9 @@
   ///  specify a return type. See the strict-inference resource:
   ///
   ///  https://github.com/dart-lang/language/blob/master/resources/type-system/strict-inference.md
+  ///
+  ///  Parameters:
+  ///  0: the name of the function or method
   static const HintCode INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE = HintCode(
     'INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE',
     "The return type of '{0}' cannot be inferred.",
@@ -337,6 +350,9 @@
 
   ///  When "strict-inference" is enabled, types in function invocations must be
   ///  inferred via the context type, or have type arguments.
+  ///
+  ///  Parameters:
+  ///  0: the name of the type
   static const HintCode INFERENCE_FAILURE_ON_GENERIC_INVOCATION = HintCode(
     'INFERENCE_FAILURE_ON_GENERIC_INVOCATION',
     "The type argument(s) of the generic function type '{0}' can't be "
@@ -347,6 +363,9 @@
   ///  When "strict-inference" is enabled, types in instance creation
   ///  (constructor calls) must be inferred via the context type, or have type
   ///  arguments.
+  ///
+  ///  Parameters:
+  ///  0: the name of the constructor
   static const HintCode INFERENCE_FAILURE_ON_INSTANCE_CREATION = HintCode(
     'INFERENCE_FAILURE_ON_INSTANCE_CREATION',
     "The type argument(s) of the constructor '{0}' can't be inferred.",
@@ -355,6 +374,9 @@
 
   ///  When "strict-inference" in enabled, uninitialized variables must be
   ///  declared with a specific type.
+  ///
+  ///  Parameters:
+  ///  0: the name of the variable
   static const HintCode INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE = HintCode(
     'INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE',
     "The type of {0} can't be inferred without either a type or initializer.",
@@ -363,6 +385,9 @@
 
   ///  When "strict-inference" in enabled, function parameters must be
   ///  declared with a specific type, or inherit a type.
+  ///
+  ///  Parameters:
+  ///  0: the name of the parameter
   static const HintCode INFERENCE_FAILURE_ON_UNTYPED_PARAMETER = HintCode(
     'INFERENCE_FAILURE_ON_UNTYPED_PARAMETER',
     "The type of {0} can't be inferred; a type must be explicitly provided.",
@@ -389,6 +414,7 @@
 
   ///  Parameters:
   ///  0: the name of the element
+  ///  1: ?
   static const HintCode INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY =
       HintCode(
     'INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY',
@@ -459,6 +485,9 @@
     uniqueName: 'INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS',
   );
 
+  ///  Parameters:
+  ///  0: the latest major version
+  ///  1: the latest minor version
   static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER = HintCode(
     'INVALID_LANGUAGE_VERSION_OVERRIDE',
     "The language version override can't specify a version greater than the "
@@ -775,6 +804,9 @@
 
   ///  Generate a hint for classes that inherit from classes annotated with
   ///  `@immutable` but that are not immutable.
+  ///
+  ///  Parameters:
+  ///  0: the name of the class
   static const HintCode MUST_BE_IMMUTABLE = HintCode(
     'MUST_BE_IMMUTABLE',
     "This class (or a class that this class inherits from) is marked as "
@@ -987,7 +1019,8 @@
     uniqueName: 'RETURN_TYPE_INVALID_FOR_CATCH_ERROR',
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the class
   static const HintCode SDK_VERSION_ASYNC_EXPORTED_FROM_CORE = HintCode(
     'SDK_VERSION_ASYNC_EXPORTED_FROM_CORE',
     "The class '{0}' wasn't exported from 'dart:core' until version 2.1, but "
@@ -1007,7 +1040,8 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the operator
   static const HintCode SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT = HintCode(
     'SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT',
     "The use of the operator '{0}' for 'bool' operands in a constant context "
@@ -1112,6 +1146,9 @@
   ///
   ///  A "raw type" is a type name that does not use inference to fill in missing
   ///  type arguments; instead, each type argument is instantiated to its bound.
+  ///
+  ///  Parameters:
+  ///  0: the name of the generic type
   static const HintCode STRICT_RAW_TYPE = HintCode(
     'STRICT_RAW_TYPE',
     "The generic type '{0}' should have explicit type arguments but doesn't.",
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index c1d530d..f44efcc 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -141,6 +141,10 @@
   ParserErrorCode.INVALID_UNICODE_ESCAPE_U_NO_BRACKET,
   ParserErrorCode.INVALID_UNICODE_ESCAPE_U_BRACKET,
   ParserErrorCode.INVALID_UNICODE_ESCAPE_STARTED,
+  ParserErrorCode.RECORD_LITERAL_ONE_POSITIONAL_NO_TRAILING_COMMA,
+  ParserErrorCode.RECORD_LITERAL_EMPTY,
+  ParserErrorCode.EMPTY_RECORD_TYPE_NAMED_FIELDS_LIST,
+  ParserErrorCode.RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA,
 ];
 
 class ParserErrorCode extends ErrorCode {
@@ -431,6 +435,13 @@
     correctionMessage: "Try declaring a constant.",
   );
 
+  static const ParserErrorCode EMPTY_RECORD_TYPE_NAMED_FIELDS_LIST =
+      ParserErrorCode(
+    'EMPTY_RECORD_TYPE_NAMED_FIELDS_LIST',
+    "Record type named fields list can't be empty.",
+    correctionMessage: "Try adding a record type named field to the list.",
+  );
+
   static const ParserErrorCode ENUM_IN_CLASS = ParserErrorCode(
     'ENUM_IN_CLASS',
     "Enums can't be declared inside classes.",
@@ -495,6 +506,36 @@
         "Try inserting a list or map literal, or remove the type arguments.",
   );
 
+  static const ParserErrorCode EXPECTED_NAMED_TYPE_EXTENDS = ParserErrorCode(
+    'EXPECTED_NAMED_TYPE',
+    "Expected a class name.",
+    correctionMessage: "Try using a class name, possibly with type arguments.",
+    uniqueName: 'EXPECTED_NAMED_TYPE_EXTENDS',
+  );
+
+  static const ParserErrorCode EXPECTED_NAMED_TYPE_IMPLEMENTS = ParserErrorCode(
+    'EXPECTED_NAMED_TYPE',
+    "Expected the name of a class or mixin.",
+    correctionMessage:
+        "Try using a class or mixin name, possibly with type arguments.",
+    uniqueName: 'EXPECTED_NAMED_TYPE_IMPLEMENTS',
+  );
+
+  static const ParserErrorCode EXPECTED_NAMED_TYPE_ON = ParserErrorCode(
+    'EXPECTED_NAMED_TYPE',
+    "Expected the name of a class or mixin.",
+    correctionMessage:
+        "Try using a class or mixin name, possibly with type arguments.",
+    uniqueName: 'EXPECTED_NAMED_TYPE_ON',
+  );
+
+  static const ParserErrorCode EXPECTED_NAMED_TYPE_WITH = ParserErrorCode(
+    'EXPECTED_NAMED_TYPE',
+    "Expected a mixin name.",
+    correctionMessage: "Try using a mixin name, possibly with type arguments.",
+    uniqueName: 'EXPECTED_NAMED_TYPE_WITH',
+  );
+
   static const ParserErrorCode EXPECTED_STRING_LITERAL = ParserErrorCode(
     'EXPECTED_STRING_LITERAL',
     "Expected a string literal.",
@@ -1381,6 +1422,26 @@
     correctionMessage: "Try moving the prefix before the combinators.",
   );
 
+  static const ParserErrorCode RECORD_LITERAL_EMPTY = ParserErrorCode(
+    'RECORD_LITERAL_EMPTY',
+    "Record literal can't be empty.",
+    correctionMessage: "Try adding elements or use 'Record.empty()' instead.",
+  );
+
+  static const ParserErrorCode RECORD_LITERAL_ONE_POSITIONAL_NO_TRAILING_COMMA =
+      ParserErrorCode(
+    'RECORD_LITERAL_ONE_POSITIONAL_NO_TRAILING_COMMA',
+    "Record literal with one field requires a trailing comma.",
+    correctionMessage: "Try adding a trailing comma.",
+  );
+
+  static const ParserErrorCode RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA =
+      ParserErrorCode(
+    'RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA',
+    "Record type with one entry requires a trailing comma.",
+    correctionMessage: "Try adding a trailing comma.",
+  );
+
   static const ParserErrorCode REDIRECTING_CONSTRUCTOR_WITH_BODY =
       ParserErrorCode(
     'REDIRECTING_CONSTRUCTOR_WITH_BODY',
diff --git a/pkg/analyzer/lib/src/dart/micro/utils.dart b/pkg/analyzer/lib/src/dart/micro/utils.dart
index 5978e58..708959f 100644
--- a/pkg/analyzer/lib/src/dart/micro/utils.dart
+++ b/pkg/analyzer/lib/src/dart/micro/utils.dart
@@ -47,7 +47,7 @@
     ConstructorElement? constructor) {
   var seenConstructors = <ConstructorElement?>{};
   while (constructor is ConstructorElementImpl && constructor.isSynthetic) {
-    var enclosing = constructor.enclosingElement3;
+    var enclosing = constructor.enclosingElement;
     if (enclosing is ClassElement && enclosing.isMixinApplication) {
       var superInvocation = constructor.constantInitializers
           .whereType<SuperConstructorInvocation>()
@@ -77,7 +77,7 @@
     String prefix,
     Element element,
     Map<LibraryImportElement, Set<Element>> importElementsMap) {
-  if (element.enclosingElement3 is! CompilationUnitElement) {
+  if (element.enclosingElement is! CompilationUnitElement) {
     return null;
   }
   var usedLibrary = element.library;
@@ -277,14 +277,14 @@
 
   @override
   visitConstructorDeclaration(ConstructorDeclaration node) {
-    var e = node.declaredElement2;
+    var e = node.declaredElement;
     if (e == element) {
       if (e!.name.isEmpty) {
         references.add(
             MatchInfo(e.nameOffset + e.nameLength, 0, MatchKind.DECLARATION));
       } else {
         var offset = node.period!.offset;
-        var length = node.name2!.end - offset;
+        var length = node.name!.end - offset;
         references.add(MatchInfo(offset, length, MatchKind.DECLARATION));
       }
     }
@@ -314,7 +314,7 @@
         length = 0;
       }
       references.add(MatchInfo(offset, length, kind));
-    } else if (e != null && e.enclosingElement3 == element) {
+    } else if (e != null && e.enclosingElement == element) {
       kind = MatchKind.REFERENCE;
       offset = node.offset;
       length = element.nameLength;
@@ -333,7 +333,7 @@
         offset = constructorSelector.period.offset;
         length = constructorSelector.name.end - offset;
       } else {
-        offset = node.name2.end;
+        offset = node.name.end;
         length = 0;
       }
       var kind = node.arguments == null
diff --git a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
index 5ff4980..79044b5 100644
--- a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
@@ -62,7 +62,7 @@
 
   void _classGetter(
     AnnotationImpl node,
-    ClassElement classElement,
+    InterfaceElement classElement,
     SimpleIdentifierImpl? getterName,
     List<WhyNotPromotedGetter> whyNotPromotedList,
   ) {
@@ -223,8 +223,8 @@
     }
 
     // Class(args) or Class.CONST
-    if (element1 is ClassElement) {
-      if (argumentList != null) {
+    if (element1 is InterfaceElement) {
+      if (element1 is ClassElement && argumentList != null) {
         _classConstructorInvocation(
             node, element1, name2, argumentList, whyNotPromotedList);
       } else {
@@ -245,8 +245,8 @@
         var element2 = element1.scope.lookup(name2.name).getter;
         name2.staticElement = element2;
         // prefix.Class(args) or prefix.Class.CONST
-        if (element2 is ClassElement) {
-          if (argumentList != null) {
+        if (element2 is InterfaceElement) {
+          if (element2 is ClassElement && argumentList != null) {
             _classConstructorInvocation(
                 node, element2, name3, argumentList, whyNotPromotedList);
           } else {
diff --git a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
index f9b9cc8..12e25af 100644
--- a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
@@ -42,8 +42,10 @@
 
   TypeSystemImpl get _typeSystem => _resolver.typeSystem;
 
-  void resolve(AssignmentExpressionImpl node,
-      {required DartType? contextType}) {
+  void resolve(
+    AssignmentExpressionImpl node, {
+    required DartType? contextType,
+  }) {
     var operator = node.operator.type;
     var hasRead = operator != TokenType.EQ;
     var isIfNull = operator == TokenType.QUESTION_QUESTION_EQ;
@@ -61,6 +63,12 @@
 
     if (hasRead) {
       _resolver.setReadElement(left, readElement);
+      {
+        final recordField = leftResolution.recordField;
+        if (recordField != null) {
+          node.readType = recordField.type;
+        }
+      }
       _resolveOperator(node);
     }
     _resolver.setWriteElement(left, writeElement);
@@ -86,7 +94,7 @@
     }
 
     _resolver.analyzeExpression(right, rhsContext);
-    right = node.rightHandSide;
+    right = _resolver.popRewrite()!;
     var whyNotPromoted = flow?.whyNotPromoted(right);
 
     _resolveTypes(node,
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index 3d5ffca..03f5026 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -40,7 +40,7 @@
   /// and 'name' of `b`). The [InstanceCreationExpression] is rewritten as a
   /// [MethodInvocation] if `a` resolves to a function.
   AstNode instanceCreationExpression(
-      Scope nameScope, InstanceCreationExpression node) {
+      Scope nameScope, InstanceCreationExpressionImpl node) {
     if (node.keyword != null) {
       // Either `new` or `const` has been specified.
       return node;
@@ -58,7 +58,7 @@
         return _toMethodInvocationOfAliasedTypeLiteral(
             node: node, function: typeName, element: element);
       }
-    } else if (typeName is PrefixedIdentifier) {
+    } else if (typeName is PrefixedIdentifierImpl) {
       var prefixElement = nameScope.lookup(typeName.prefix.name).getter;
       if (prefixElement is PrefixElement) {
         var prefixedName = typeName.identifier.name;
@@ -113,7 +113,7 @@
         return node;
       }
       var element = nameScope.lookup(methodName.name).getter;
-      if (element is ClassElement) {
+      if (element is InterfaceElement) {
         return _toInstanceCreation_type(
           node: node,
           typeIdentifier: methodName,
@@ -139,7 +139,7 @@
         // being used.
       }
       var element = nameScope.lookup(target.name).getter;
-      if (element is ClassElement) {
+      if (element is InterfaceElement) {
         // class C { C.named(); }
         // C.named()
         return _toInstanceCreation_type_constructor(
@@ -151,7 +151,7 @@
       } else if (element is PrefixElement) {
         // Possible cases: p.C() or p.C<>()
         var prefixedElement = element.scope.lookup(methodName.name).getter;
-        if (prefixedElement is ClassElement) {
+        if (prefixedElement is InterfaceElement) {
           return _toInstanceCreation_prefix_type(
             node: node,
             prefixIdentifier: target,
@@ -195,7 +195,7 @@
       if (prefixElement is PrefixElement) {
         var prefixedName = target.identifier.name;
         var element = prefixElement.scope.lookup(prefixedName).getter;
-        if (element is ClassElement) {
+        if (element is InterfaceElement) {
           return _instanceCreation_prefix_type_name(
             node: node,
             typeNameIdentifier: target,
@@ -248,7 +248,7 @@
     }
     var prefix = node.prefix;
     var element = nameScope.lookup(prefix.name).getter;
-    if (element is ClassElement) {
+    if (element is InterfaceElement) {
       // Example:
       //     class C { C.named(); }
       //     C.named
@@ -331,7 +331,7 @@
       }
     }
 
-    if (element is ClassElement) {
+    if (element is InterfaceElement) {
       // Example:
       //     class C<T> { C.named(); }
       //     C<int>.named
@@ -393,9 +393,10 @@
           [typeNameIdentifier.toString(), constructorIdentifier.name]);
     }
 
-    var typeName = astFactory.namedType(
+    var typeName = NamedTypeImpl(
       name: typeNameIdentifier,
       typeArguments: typeArguments,
+      question: null,
     );
     var constructorName = ConstructorNameImpl(
       type: typeName,
@@ -420,7 +421,11 @@
       return node;
     }
 
-    var typeName = astFactory.namedType(name: node.prefix);
+    var typeName = NamedTypeImpl(
+      name: node.prefix,
+      typeArguments: null,
+      question: null,
+    );
     var constructorName = ConstructorNameImpl(
       type: typeName,
       period: node.period,
@@ -453,9 +458,10 @@
 
     var operator = node.operator;
 
-    var typeName = astFactory.namedType(
+    var typeName = NamedTypeImpl(
       name: receiver,
       typeArguments: typeArguments,
+      question: null,
     );
     var constructorName = ConstructorNameImpl(
       type: typeName,
@@ -474,13 +480,14 @@
     required SimpleIdentifierImpl prefixIdentifier,
     required SimpleIdentifierImpl typeIdentifier,
   }) {
-    var typeName = astFactory.namedType(
+    var typeName = NamedTypeImpl(
       name: astFactory.prefixedIdentifier(
         prefixIdentifier,
         node.operator!,
         typeIdentifier,
       ),
       typeArguments: node.typeArguments,
+      question: null,
     );
     var constructorName = ConstructorNameImpl(
       type: typeName,
@@ -494,12 +501,13 @@
   }
 
   InstanceCreationExpression _toInstanceCreation_type({
-    required MethodInvocation node,
-    required SimpleIdentifier typeIdentifier,
+    required MethodInvocationImpl node,
+    required SimpleIdentifierImpl typeIdentifier,
   }) {
-    var typeName = astFactory.namedType(
+    var typeName = NamedTypeImpl(
       name: typeIdentifier,
       typeArguments: node.typeArguments,
+      question: null,
     );
     var constructorName = ConstructorNameImpl(
       type: typeName,
@@ -531,7 +539,11 @@
           typeArguments,
           [typeIdentifier.name, constructorIdentifier.name]);
     }
-    var typeName = astFactory.namedType(name: typeIdentifier);
+    var typeName = NamedTypeImpl(
+      name: typeIdentifier,
+      typeArguments: null,
+      question: null,
+    );
     var constructorName = ConstructorNameImpl(
       type: typeName,
       period: node.operator,
@@ -546,32 +558,33 @@
   }
 
   MethodInvocation _toMethodInvocationOfAliasedTypeLiteral({
-    required InstanceCreationExpression node,
+    required InstanceCreationExpressionImpl node,
     required Identifier function,
     required TypeAliasElement element,
   }) {
-    var typeName = astFactory.namedType(
+    var typeName = NamedTypeImpl(
       name: node.constructorName.type.name,
       typeArguments: node.constructorName.type.typeArguments,
+      question: null,
     );
     typeName.type = element.aliasedType;
     typeName.name.staticType = element.aliasedType;
     var typeLiteral = astFactory.typeLiteral(typeName: typeName);
     typeLiteral.staticType = _typeProvider.typeType;
-    var methodInvocation = astFactory.methodInvocation(
-      typeLiteral,
-      node.constructorName.period,
-      node.constructorName.name!,
-      null,
-      node.argumentList,
+    var methodInvocation = MethodInvocationImpl(
+      target: typeLiteral,
+      operator: node.constructorName.period,
+      methodName: node.constructorName.name!,
+      typeArguments: null,
+      argumentList: node.argumentList,
     );
     NodeReplacer.replace(node, methodInvocation);
     return methodInvocation;
   }
 
   AstNode _toMethodInvocationOfFunctionReference({
-    required InstanceCreationExpression node,
-    required Identifier function,
+    required InstanceCreationExpressionImpl node,
+    required IdentifierImpl function,
   }) {
     var period = node.constructorName.period;
     var constructorId = node.constructorName.name;
@@ -579,16 +592,16 @@
       return node;
     }
 
-    var functionReference = astFactory.functionReference(
+    var functionReference = FunctionReferenceImpl(
       function: function,
       typeArguments: node.constructorName.type.typeArguments,
     );
-    var methodInvocation = astFactory.methodInvocation(
-      functionReference,
-      period,
-      constructorId,
-      null,
-      node.argumentList,
+    var methodInvocation = MethodInvocationImpl(
+      target: functionReference,
+      operator: period,
+      methodName: constructorId,
+      typeArguments: null,
+      argumentList: node.argumentList,
     );
     NodeReplacer.replace(node, methodInvocation);
     return methodInvocation;
diff --git a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
index 79d5949..c8b04fa 100644
--- a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
@@ -150,7 +150,7 @@
     }
 
     _resolver.analyzeExpression(left, leftContextType);
-    left = node.leftOperand;
+    left = _resolver.popRewrite()!;
     var leftType = left.typeOrThrow;
 
     var rightContextType = contextType;
@@ -160,7 +160,7 @@
 
     flow?.ifNullExpression_rightBegin(left, leftType);
     _resolver.analyzeExpression(right, rightContextType);
-    right = node.rightOperand;
+    right = _resolver.popRewrite()!;
     flow?.ifNullExpression_end();
 
     var rightType = right.typeOrThrow;
@@ -183,14 +183,14 @@
 
     flow?.logicalBinaryOp_begin();
     _resolver.analyzeExpression(left, _typeProvider.boolType);
-    left = node.leftOperand;
+    left = _resolver.popRewrite()!;
     var leftWhyNotPromoted = _resolver.flowAnalysis.flow?.whyNotPromoted(left);
 
     flow?.logicalBinaryOp_rightBegin(left, node, isAnd: true);
     _resolver.checkUnreachableNode(right);
 
     _resolver.analyzeExpression(right, _typeProvider.boolType);
-    right = node.rightOperand;
+    right = _resolver.popRewrite()!;
     var rightWhyNotPromoted =
         _resolver.flowAnalysis.flow?.whyNotPromoted(right);
 
@@ -212,14 +212,14 @@
 
     flow?.logicalBinaryOp_begin();
     _resolver.analyzeExpression(left, _typeProvider.boolType);
-    left = node.leftOperand;
+    left = _resolver.popRewrite()!;
     var leftWhyNotPromoted = _resolver.flowAnalysis.flow?.whyNotPromoted(left);
 
     flow?.logicalBinaryOp_rightBegin(left, node, isAnd: false);
     _resolver.checkUnreachableNode(right);
 
     _resolver.analyzeExpression(right, _typeProvider.boolType);
-    right = node.rightOperand;
+    right = _resolver.popRewrite()!;
     var rightWhyNotPromoted =
         _resolver.flowAnalysis.flow?.whyNotPromoted(right);
 
@@ -263,7 +263,7 @@
     }
 
     _resolver.analyzeExpression(right, rightContextType);
-    right = node.rightOperand;
+    right = _resolver.popRewrite()!;
     var whyNotPromoted = _resolver.flowAnalysis.flow?.whyNotPromoted(right);
 
     _resolveUserDefinableType(node, contextType: contextType);
diff --git a/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart b/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
index e043a3f..54d18dc 100644
--- a/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
@@ -165,7 +165,7 @@
     return node.getProperty(_key);
   }
 
-  static DartType? _argumentOf(DartType type, ClassElement element) {
+  static DartType? _argumentOf(DartType type, InterfaceElement element) {
     var elementType = type.asInstanceOf(element);
     if (elementType != null) {
       return elementType.typeArguments[0];
diff --git a/pkg/analyzer/lib/src/dart/resolver/comment_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/comment_reference_resolver.dart
index 4fd94f5..fe6a3d7 100644
--- a/pkg/analyzer/lib/src/dart/resolver/comment_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/comment_reference_resolver.dart
@@ -69,7 +69,7 @@
     }
 
     if (!hasNewKeyword) {
-      if (prefixElement is ClassElement) {
+      if (prefixElement is InterfaceElement) {
         name.staticElement = _resolver.inheritance.getMember2(
               prefixElement,
               Name(prefixElement.library.source.uri, name.name),
@@ -85,7 +85,7 @@
       } else {
         // TODO(brianwilkerson) Report this error.
       }
-    } else if (prefixElement is ClassElement) {
+    } else if (prefixElement is InterfaceElement) {
       var constructor = prefixElement.getNamedConstructor(name.name);
       if (constructor == null) {
         // TODO(brianwilkerson) Report this error.
@@ -126,7 +126,7 @@
     name.staticElement = element;
 
     var propertyName = expression.propertyName;
-    if (element is ClassElement) {
+    if (element is InterfaceElement) {
       propertyName.staticElement = element.getMethod(propertyName.name) ??
           element.getGetter(propertyName.name) ??
           element.getSetter(propertyName.name) ??
@@ -191,7 +191,7 @@
     }
     expression.staticElement = element;
     if (hasNewKeyword) {
-      if (element is ClassElement) {
+      if (element is InterfaceElement) {
         var constructor = element.unnamedConstructor;
         if (constructor == null) {
           // TODO(brianwilkerson) Report this error.
diff --git a/pkg/analyzer/lib/src/dart/resolver/constructor_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/constructor_reference_resolver.dart
index 4006686..f6380a7 100644
--- a/pkg/analyzer/lib/src/dart/resolver/constructor_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/constructor_reference_resolver.dart
@@ -30,7 +30,7 @@
     node.constructorName.accept(_resolver);
     var element = node.constructorName.staticElement;
     if (element != null && !element.isFactory) {
-      final enclosingElement = element.enclosingElement3;
+      final enclosingElement = element.enclosingElement;
       if (enclosingElement is ClassElement && enclosingElement.isAbstract) {
         _resolver.errorReporter.reportErrorForNode(
           CompileTimeErrorCode
@@ -60,7 +60,7 @@
       // TODO(srawlins): Handle `enclosingElement` being a function typedef:
       // typedef F<T> = void Function(); var a = F<int>.extensionOnType;`.
       // This is illegal.
-      if (enclosingElement is ClassElement) {
+      if (enclosingElement is InterfaceElement) {
         var method = enclosingElement.getMethod(name.name) ??
             enclosingElement.getGetter(name.name) ??
             enclosingElement.getSetter(name.name);
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index 6493b15..cc11d1b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -61,7 +61,7 @@
 /// be extracted.
 class FlowAnalysisHelper {
   /// The reused instance for creating new [FlowAnalysis] instances.
-  final TypeSystemOperations _typeOperations;
+  final TypeSystemOperations typeOperations;
 
   /// Precomputed sets of potentially assigned variables.
   AssignedVariables<AstNode, PromotableElement>? assignedVariables;
@@ -90,7 +90,7 @@
             respectImplicitlyTypedVarInitializers:
                 featureSet.isEnabled(Feature.constructor_tearoffs));
 
-  FlowAnalysisHelper._(this._typeOperations, this.dataForTesting,
+  FlowAnalysisHelper._(this.typeOperations, this.dataForTesting,
       {required this.isNonNullableByDefault,
       required this.respectImplicitlyTypedVarInitializers});
 
@@ -246,11 +246,11 @@
     }
     flow = isNonNullableByDefault
         ? FlowAnalysis<AstNode, Statement, Expression, PromotableElement,
-                DartType>(_typeOperations, assignedVariables!,
+                DartType>(typeOperations, assignedVariables!,
             respectImplicitlyTypedVarInitializers:
                 respectImplicitlyTypedVarInitializers)
         : FlowAnalysis<AstNode, Statement, Expression, PromotableElement,
-            DartType>.legacy(_typeOperations, assignedVariables!);
+            DartType>.legacy(typeOperations, assignedVariables!);
   }
 
   void topLevelDeclaration_exit() {
@@ -282,7 +282,7 @@
       var variables = node.variables;
       for (var i = 0; i < variables.length; ++i) {
         var variable = variables[i];
-        flow!.declare(variable.declaredElement2 as PromotableElement,
+        flow!.declare(variable.declaredElement as PromotableElement,
             variable.initializer != null);
       }
     }
@@ -378,7 +378,7 @@
 }
 
 class TypeSystemOperations
-    with TypeOperations<DartType>
+    with TypeOperations<DartType>, TypeOperations2<DartType>
     implements Operations<PromotableElement, DartType> {
   final TypeSystemImpl typeSystem;
 
@@ -401,11 +401,27 @@
   }
 
   @override
+  DartType glb(DartType type1, DartType type2) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  bool isAssignableTo(DartType fromType, DartType toType) {
+    return typeSystem.isAssignableTo(fromType, toType);
+  }
+
+  @override
+  bool isDynamic(DartType type) => type.isDynamic;
+
+  @override
   bool isNever(DartType type) {
     return typeSystem.isBottom(type);
   }
 
   @override
+  bool isPropertyPromotable(Object property) => false;
+
+  @override
   bool isSameType(covariant TypeImpl type1, covariant TypeImpl type2) {
     return type1 == type2;
   }
@@ -419,6 +435,21 @@
   bool isTypeParameterType(DartType type) => type is TypeParameterType;
 
   @override
+  DartType lub(DartType type1, DartType type2) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  DartType makeNullable(DartType type) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  DartType? matchListType(DartType type) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
   DartType promoteToNonNull(DartType type) {
     return typeSystem.promoteToNonNull(type);
   }
@@ -631,7 +662,7 @@
         grandParent is FieldDeclaration) {
       throw StateError('Should not visit top level declarations');
     }
-    var declaredElement = node.declaredElement2 as PromotableElement;
+    var declaredElement = node.declaredElement as PromotableElement;
     assignedVariables.declare(declaredElement);
     if (declaredElement.isLate && node.initializer != null) {
       assignedVariables.beginNode();
@@ -682,7 +713,7 @@
           assignedVariables.write(element);
         }
       } else if (forLoopParts is ForEachPartsWithDeclaration) {
-        var variable = forLoopParts.loopVariable.declaredElement2!;
+        var variable = forLoopParts.loopVariable.declaredElement!;
         assignedVariables.declare(variable);
       } else {
         throw StateError('Unrecognized for loop parts');
diff --git a/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
index 3264c28..43dfa86 100644
--- a/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
@@ -29,6 +29,7 @@
     var forLoopParts = node.forLoopParts;
     void visitBody() {
       node.body.resolveElement(_resolver, context);
+      _resolver.popRewrite();
     }
 
     if (forLoopParts is ForPartsImpl) {
@@ -119,7 +120,7 @@
     }
 
     _resolver.analyzeExpression(iterable, targetType);
-    iterable = forEachParts.iterable;
+    iterable = _resolver.popRewrite()!;
 
     _resolver.nullableDereferenceVerifier.expression(
       CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE_AS_ITERATOR,
@@ -132,13 +133,12 @@
         elementType != null &&
         loopVariable.type == null) {
       var loopVariableElement =
-          loopVariable.declaredElement2 as LocalVariableElementImpl;
+          loopVariable.declaredElement as LocalVariableElementImpl;
       loopVariableElement.type = elementType;
     }
 
     if (loopVariable != null) {
-      _resolver.flowAnalysis.flow
-          ?.declare(loopVariable.declaredElement2!, true);
+      _resolver.flowAnalysis.flow?.declare(loopVariable.declaredElement!, true);
     }
 
     _resolver.flowAnalysis.flow?.forEach_bodyBegin(node);
@@ -165,7 +165,7 @@
     var condition = forParts.condition;
     if (condition != null) {
       _resolver.analyzeExpression(condition, _resolver.typeProvider.boolType);
-      condition = forParts.condition!;
+      condition = _resolver.popRewrite()!;
       var whyNotPromoted =
           _resolver.flowAnalysis.flow?.whyNotPromoted(condition);
       _resolver.boolExpressionVerifier
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart
index 2d094c7..cde7754 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart
@@ -162,7 +162,7 @@
     }
 
     return type.instantiate(typeParameters.map((typeParameter) {
-      return typeParameter.declaredElement2!.instantiate(
+      return typeParameter.declaredElement!.instantiate(
         nullabilitySuffix: _resolver.noneOrStarSuffix,
       );
     }).toList());
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 d7f50e4..416c3ce 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -11,7 +11,6 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/error/codes.dart';
@@ -175,7 +174,7 @@
     ExecutableElement element, {
     required bool implicitReceiver,
   }) {
-    var enclosingElement = element.enclosingElement3;
+    var enclosingElement = element.enclosingElement;
     if (implicitReceiver) {
       if (_resolver.enclosingExtension != null) {
         _resolver.errorReporter.reportErrorForNode(
@@ -291,7 +290,7 @@
       typeArguments: node.typeArguments,
       typeArgumentTypes: typeArgumentTypes,
     );
-    NodeReplacer.replace(node, callReference);
+    _resolver.replaceExpression(node, callReference);
     var instantiatedType = callMethodType.instantiate(typeArgumentTypes);
     callReference.staticType = instantiatedType;
   }
@@ -304,8 +303,8 @@
 
   /// Resolves [node] as a [TypeLiteral] referencing an interface type directly
   /// (not through a type alias).
-  void _resolveDirectTypeLiteral(
-      FunctionReferenceImpl node, Identifier name, ClassElement element) {
+  void _resolveDirectTypeLiteral(FunctionReferenceImpl node,
+      IdentifierImpl name, InterfaceElement element) {
     var typeArguments = _checkTypeArguments(
       // `node.typeArguments`, coming from the parser, is never null.
       node.typeArguments!, name.name, element.typeParameters,
@@ -594,14 +593,14 @@
     // Classes and type aliases are checked first so as to include a
     // PropertyAccess parent check, which does not need to be done for
     // functions.
-    if (element is ClassElement || element is TypeAliasElement) {
+    if (element is InterfaceElement || element is TypeAliasElement) {
       // A type-instantiated constructor tearoff like `prefix.C<int>.name` is
       // initially represented as a [PropertyAccess] with a
       // [FunctionReference] 'target'.
       if (node.parent is PropertyAccess) {
         _resolveConstructorReference(node);
         return;
-      } else if (element is ClassElement) {
+      } else if (element is InterfaceElement) {
         node.function.accept(_resolver);
         _resolveDirectTypeLiteral(node, prefix, element);
         return;
@@ -706,7 +705,7 @@
     // Classes and type aliases are checked first so as to include a
     // PropertyAccess parent check, which does not need to be done for
     // functions.
-    if (element is ClassElement || element is TypeAliasElement) {
+    if (element is InterfaceElement || element is TypeAliasElement) {
       // A type-instantiated constructor tearoff like `C<int>.name` or
       // `prefix.C<int>.name` is initially represented as a [PropertyAccess]
       // with a [FunctionReference] target.
@@ -719,7 +718,7 @@
           _resolveConstructorReference(node);
         }
         return;
-      } else if (element is ClassElement) {
+      } else if (element is InterfaceElement) {
         function.staticElement = element;
         _resolveDirectTypeLiteral(node, function, element);
         return;
@@ -794,7 +793,7 @@
   void _resolveTypeAlias({
     required FunctionReferenceImpl node,
     required TypeAliasElement element,
-    required Identifier typeAlias,
+    required IdentifierImpl typeAlias,
   }) {
     var typeArguments = _checkTypeArguments(
       // `node.typeArguments`, coming from the parser, is never null.
@@ -811,21 +810,22 @@
   void _resolveTypeLiteral({
     required FunctionReferenceImpl node,
     required DartType instantiatedType,
-    required Identifier name,
+    required IdentifierImpl name,
   }) {
     // TODO(srawlins): set the static element of [typeName].
     // This involves a fair amount of resolution, as [name] may be a prefixed
     // identifier, etc. [TypeName]s should be resolved in [ResolutionVisitor],
     // and this could be done for nodes like this via [AstRewriter].
-    var typeName = astFactory.namedType(
+    var typeName = NamedTypeImpl(
       name: name,
       typeArguments: node.typeArguments,
+      question: null,
     );
     typeName.type = instantiatedType;
     typeName.name.staticType = instantiatedType;
     var typeLiteral = astFactory.typeLiteral(typeName: typeName);
     typeLiteral.staticType = _typeType;
-    NodeReplacer.replace(node, typeLiteral);
+    _resolver.replaceExpression(node, typeLiteral);
   }
 
   /// Resolves [name] as a property on [receiver].
@@ -839,7 +839,7 @@
   }) {
     if (receiver is Identifier) {
       var receiverElement = receiver.staticElement;
-      if (receiverElement is ClassElement) {
+      if (receiverElement is InterfaceElement) {
         var element = _resolveStaticElement(receiverElement, name);
         name.staticElement = element;
         return element?.referenceType;
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 1c1a643..23f6543 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -87,7 +87,7 @@
 
     var typeName = constructorName.type;
     var typeElement = typeName.name.staticElement;
-    if (typeElement is ClassElement) {
+    if (typeElement is InterfaceElement) {
       typeParameters = typeElement.typeParameters;
       var constructorIdentifier = constructorName.name;
       if (constructorIdentifier == null) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart
index 52a7b37..3d943e2 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart
@@ -461,8 +461,7 @@
       }
       var argument = arguments[deferredArgument.index];
       resolver.analyzeExpression(argument, parameterContextType);
-      // In case of rewrites, we need to grab the argument again.
-      argument = arguments[deferredArgument.index];
+      argument = resolver.popRewrite()!;
       if (flow != null) {
         identicalInfo?[deferredArgument.index] =
             flow.equalityOperand_end(argument, argument.typeOrThrow);
@@ -521,8 +520,7 @@
           parameterContextType = _computeContextForArgument(parameterType);
         }
         resolver.analyzeExpression(argument, parameterContextType);
-        // In case of rewrites, we need to grab the argument again.
-        argument = arguments[i];
+        argument = resolver.popRewrite()!;
         if (flow != null) {
           identicalInfo
               ?.add(flow.equalityOperand_end(argument, argument.typeOrThrow));
diff --git a/pkg/analyzer/lib/src/dart/resolver/legacy_type_asserter.dart b/pkg/analyzer/lib/src/dart/resolver/legacy_type_asserter.dart
index 3e197de..580be8a 100644
--- a/pkg/analyzer/lib/src/dart/resolver/legacy_type_asserter.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/legacy_type_asserter.dart
@@ -50,7 +50,7 @@
 
   @override
   void visitClassMember(ClassMember node) {
-    final element = node.declaredElement2;
+    final element = node.declaredElement;
     if (element is ExecutableElement) {
       _assertLegacyType(element.type);
     }
@@ -66,7 +66,7 @@
 
   @override
   void visitDeclaredIdentifier(DeclaredIdentifier node) {
-    _assertLegacyType(node.declaredElement2?.type);
+    _assertLegacyType(node.declaredElement?.type);
     super.visitDeclaredIdentifier(node);
   }
 
@@ -85,7 +85,7 @@
 
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
-    _assertLegacyType(node.declaredElement2?.type);
+    _assertLegacyType(node.declaredElement?.type);
     super.visitFunctionDeclaration(node);
   }
 
@@ -110,7 +110,7 @@
 
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
-    _assertLegacyType(node.declaredElement2?.type);
+    _assertLegacyType(node.declaredElement?.type);
     super.visitVariableDeclaration(node);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart b/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart
index f0735d6..201311c 100644
--- a/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/scope.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/extensions.dart';
 
 /// Class containing static methods for performing lexical resolution of
@@ -58,5 +59,16 @@
   final Element? requested;
   final Element? recovery;
 
-  LexicalLookupResult({this.requested, this.recovery});
+  /// The [FunctionType] referenced with `call`.
+  final FunctionType? callFunctionType;
+
+  /// The field referenced in a [RecordType].
+  final RecordTypeField? recordField;
+
+  LexicalLookupResult({
+    this.requested,
+    this.recovery,
+    this.callFunctionType,
+    this.recordField,
+  });
 }
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 78dbe74..ee8890ef5 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -134,7 +133,7 @@
 
     if (receiver is IdentifierImpl) {
       var element = receiver.staticElement;
-      if (element is ClassElement) {
+      if (element is InterfaceElement) {
         _resolveReceiverTypeLiteral(
             node, element, nameNode, name, whyNotPromotedList,
             contextType: contextType);
@@ -175,13 +174,6 @@
       receiverType = _typeSystem.promoteToNonNull(receiverType);
     }
 
-    if (_typeSystem.isFunctionBounded(receiverType)) {
-      _resolveReceiverFunctionBounded(
-          node, receiver, receiverType, nameNode, name, whyNotPromotedList,
-          contextType: contextType);
-      return;
-    }
-
     if (receiver is TypeLiteralImpl &&
         receiver.type.typeArguments != null &&
         receiver.type.type is FunctionType) {
@@ -220,7 +212,7 @@
     ExecutableElement element,
     bool nullReceiver,
   ) {
-    var enclosingElement = element.enclosingElement3;
+    var enclosingElement = element.enclosingElement;
     if (nullReceiver) {
       if (_resolver.enclosingExtension != null) {
         _resolver.errorReporter.reportErrorForNode(
@@ -487,36 +479,6 @@
         .resolveInvocation(rawType: rawType);
   }
 
-  void _resolveReceiverFunctionBounded(
-      MethodInvocationImpl node,
-      Expression receiver,
-      DartType receiverType,
-      SimpleIdentifierImpl nameNode,
-      String name,
-      List<WhyNotPromotedGetter> whyNotPromotedList,
-      {required DartType? contextType}) {
-    if (name == FunctionElement.CALL_METHOD_NAME) {
-      _setResolution(node, receiverType, whyNotPromotedList,
-          contextType: contextType);
-      // TODO(scheglov) Replace this with using FunctionType directly.
-      // Here was erase resolution that _setResolution() sets.
-      nameNode.staticElement = null;
-      nameNode.staticType = _dynamicType;
-      return;
-    }
-
-    _resolveReceiverType(
-      node: node,
-      receiver: receiver,
-      receiverType: receiverType,
-      nameNode: nameNode,
-      name: name,
-      receiverErrorNode: nameNode,
-      whyNotPromotedList: whyNotPromotedList,
-      contextType: contextType,
-    );
-  }
-
   void _resolveReceiverNever(MethodInvocationImpl node, Expression receiver,
       DartType receiverType, List<WhyNotPromotedGetter> whyNotPromotedList,
       {required DartType? contextType}) {
@@ -790,6 +752,24 @@
       nameErrorEntity: nameNode,
     );
 
+    final callFunctionType = result.callFunctionType;
+    if (callFunctionType != null) {
+      assert(name == FunctionElement.CALL_METHOD_NAME);
+      _setResolution(node, callFunctionType, whyNotPromotedList,
+          contextType: contextType);
+      // TODO(scheglov) Replace this with using FunctionType directly.
+      // Here was erase resolution that _setResolution() sets.
+      nameNode.staticElement = null;
+      nameNode.staticType = _dynamicType;
+      return;
+    }
+
+    final recordField = result.recordField;
+    if (recordField != null) {
+      return _rewriteAsFunctionExpressionInvocation(node, recordField.type,
+          contextType: contextType);
+    }
+
     var target = result.getter;
     if (target != null) {
       nameNode.staticElement = target;
@@ -926,12 +906,12 @@
       functionExpression.staticType = targetType;
     }
 
-    var invocation = astFactory.functionExpressionInvocation(
-      functionExpression,
-      node.typeArguments,
-      node.argumentList,
+    var invocation = FunctionExpressionInvocationImpl(
+      function: functionExpression,
+      typeArguments: node.typeArguments,
+      argumentList: node.argumentList,
     );
-    NodeReplacer.replace(node, invocation);
+    _resolver.replaceExpression(node, invocation);
     node.setProperty(_rewriteResultKey, invocation);
     _resolver.flowAnalysis.transferTestData(node, invocation);
   }
@@ -1011,10 +991,10 @@
   /// Checks whether the given [expression] is a reference to a class. If it is
   /// then the element representing the class is returned, otherwise `null` is
   /// returned.
-  static ClassElement? getTypeReference(Expression expression) {
+  static InterfaceElement? getTypeReference(Expression expression) {
     if (expression is Identifier) {
       var staticElement = expression.staticElement;
-      if (staticElement is ClassElement) {
+      if (staticElement is InterfaceElement) {
         return staticElement;
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
index c4e1b9b..0465c72 100644
--- a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
@@ -36,7 +36,7 @@
 
   /// If not `null`, the element of the [ClassDeclaration], or the
   /// [ClassTypeAlias] being resolved.
-  ClassElement? enclosingClass;
+  InterfaceElement? enclosingClass;
 
   /// If not `null`, a direct child of an [ExtendsClause], [WithClause],
   /// or [ImplementsClause].
@@ -93,7 +93,8 @@
         return;
       }
 
-      if (prefixElement is ClassElement || prefixElement is TypeAliasElement) {
+      if (prefixElement is InterfaceElement ||
+          prefixElement is TypeAliasElement) {
         _rewriteToConstructorName(node, typeIdentifier);
         return;
       }
@@ -164,7 +165,7 @@
 
   /// We are resolving the [NamedType] in a redirecting constructor of the
   /// [enclosingClass].
-  InterfaceType _inferRedirectedConstructor(ClassElement element) {
+  InterfaceType _inferRedirectedConstructor(InterfaceElement element) {
     if (element == enclosingClass) {
       return element.thisType;
     } else {
@@ -192,7 +193,7 @@
 
     var argumentList = node.typeArguments;
     if (argumentList != null) {
-      if (element is ClassElement) {
+      if (element is InterfaceElement) {
         var typeArguments = _buildTypeArguments(
           node,
           argumentList,
@@ -243,8 +244,7 @@
         }
       }
 
-      if (element is ClassElement &&
-          identical(node, redirectedConstructor_namedType)) {
+      if (identical(node, redirectedConstructor_namedType)) {
         return _inferRedirectedConstructor(element);
       }
 
@@ -569,7 +569,7 @@
 
     if (element is LocalVariableElement ||
         (element is FunctionElement &&
-            element.enclosingElement3 is ExecutableElement)) {
+            element.enclosingElement is ExecutableElement)) {
       errorReporter.reportError(
         DiagnosticFactory().referencedBeforeDeclaration(
           errorReporter.source,
diff --git a/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
index 9667c37f..05afade 100644
--- a/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
@@ -208,7 +208,7 @@
     }
 
     _resolver.analyzeExpression(operand, contextType);
-    operand = node.operand;
+    operand = _resolver.popRewrite()!;
 
     var operandType = operand.typeOrThrow;
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
index fc71e4f..07b3969 100644
--- a/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
@@ -74,6 +74,7 @@
         innerContextType = contextType;
       }
       _resolver.analyzeExpression(operand, innerContextType);
+      _resolver.popRewrite();
     }
 
     _resolve1(node);
@@ -226,7 +227,7 @@
     var operand = node.operand;
 
     _resolver.analyzeExpression(operand, _typeProvider.boolType);
-    operand = node.operand;
+    operand = _resolver.popRewrite()!;
     var whyNotPromoted = _resolver.flowAnalysis.flow?.whyNotPromoted(operand);
 
     _resolver.boolExpressionVerifier.checkForNonBoolNegationExpression(operand,
diff --git a/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart
index 1672216..9693f8e 100644
--- a/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart
@@ -6,7 +6,6 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
@@ -34,14 +33,18 @@
     if (prefixElement is! PrefixElement) {
       final prefixType = node.prefix.staticType;
       // TODO(scheglov) It would be nice to rewrite all such cases.
-      if (prefixType is RecordType) {
-        final propertyAccess = PropertyAccessImpl(
-          node.prefix,
-          node.period,
-          node.identifier,
-        );
-        NodeReplacer.replace(node, propertyAccess);
-        return propertyAccess;
+      if (prefixType != null) {
+        final prefixTypeResolved =
+            _resolver.typeSystem.resolveToBound(prefixType);
+        if (prefixTypeResolved is RecordType) {
+          final propertyAccess = PropertyAccessImpl(
+            node.prefix,
+            node.period,
+            node.identifier,
+          );
+          _resolver.replaceExpression(node, propertyAccess);
+          return propertyAccess;
+        }
       }
     }
 
@@ -75,7 +78,7 @@
         result.readElementRecovery != null) {
       // Since the element came from error recovery logic, its type isn't
       // trustworthy; leave it as `dynamic`.
-    } else if (element is ClassElement) {
+    } else if (element is InterfaceElement) {
       if (_isExpressionIdentifier(node)) {
         var type = _typeProvider.typeType;
         node.staticType = type;
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 6ae4651..e113b09 100644
--- a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
+import 'package:analyzer/src/dart/element/extensions.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
@@ -20,12 +21,8 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scope_helpers.dart';
 import 'package:analyzer/src/generated/super_context.dart';
-import 'package:collection/collection.dart';
 
 class PropertyElementResolver with ScopeHelpers {
-  /// A regular expression used to match positional field names.
-  static final RegExp _recordPositionalFieldName = RegExp(r'^\$([0-9]+)$');
-
   final ResolverVisitor _resolver;
 
   PropertyElementResolver(this._resolver);
@@ -70,7 +67,11 @@
         );
       }
 
-      return _toIndexResult(result);
+      return _toIndexResult(
+        result,
+        hasRead: hasRead,
+        hasWrite: hasWrite,
+      );
     }
 
     var targetType = target.typeOrThrow;
@@ -130,7 +131,11 @@
       );
     }
 
-    return _toIndexResult(result);
+    return _toIndexResult(
+      result,
+      hasRead: hasRead,
+      hasWrite: hasWrite,
+    );
   }
 
   PropertyElementResolverResult resolvePrefixedIdentifier({
@@ -233,6 +238,21 @@
     if (hasRead) {
       var readLookup = LexicalLookup.resolveGetter(scopeLookupResult) ??
           _resolver.thisLookupGetter(node);
+
+      final callFunctionType = readLookup?.callFunctionType;
+      if (callFunctionType != null) {
+        return PropertyElementResolverResult(
+          functionTypeCallType: callFunctionType,
+        );
+      }
+
+      final recordField = readLookup?.recordField;
+      if (recordField != null) {
+        return PropertyElementResolverResult(
+          recordField: recordField,
+        );
+      }
+
       readElementRequested = _resolver.toLegacyElement(readLookup?.requested);
       if (readElementRequested is PropertyAccessorElement &&
           !readElementRequested.isStatic) {
@@ -295,7 +315,7 @@
           propertyName,
         );
       } else {
-        var enclosingElement = element.enclosingElement3;
+        var enclosingElement = element.enclosingElement;
         if (enclosingElement is ExtensionElement &&
             enclosingElement.name == null) {
           _resolver.errorReporter.reportErrorForNode(
@@ -325,20 +345,6 @@
     }
   }
 
-  DartType? _computeIndexContextType({
-    required ExecutableElement? readElement,
-    required ExecutableElement? writeElement,
-  }) {
-    var method = writeElement ?? readElement;
-    var parameters = method is MethodElement ? method.parameters : null;
-
-    if (parameters != null && parameters.isNotEmpty) {
-      return parameters[0].type;
-    }
-
-    return null;
-  }
-
   bool _isAccessible(ExecutableElement element) {
     return element.isAccessibleIn2(_definingLibrary);
   }
@@ -373,7 +379,7 @@
     //
     if (target is Identifier) {
       var targetElement = target.staticElement;
-      if (targetElement is ClassElement) {
+      if (targetElement is InterfaceElement) {
         return _resolveTargetInterfaceElement(
           typeReference: targetElement,
           isCascaded: isCascaded,
@@ -453,16 +459,6 @@
       return PropertyElementResolverResult();
     }
 
-    if (targetType is RecordType) {
-      final result = _resolveTargetRecordType(
-        targetType: targetType,
-        propertyName: propertyName,
-      );
-      if (result != null) {
-        return result;
-      }
-    }
-
     var result = _resolver.typePropertyResolver.resolve(
       receiver: target,
       receiverType: targetType,
@@ -506,6 +502,7 @@
       readElementRecovery: result.setter,
       writeElementRequested: result.setter,
       writeElementRecovery: result.getter,
+      recordField: result.recordField,
     );
   }
 
@@ -750,32 +747,6 @@
     );
   }
 
-  PropertyElementResolverResult? _resolveTargetRecordType({
-    required RecordType targetType,
-    required SimpleIdentifier propertyName,
-  }) {
-    final namedField = targetType.namedFields.firstWhereOrNull(
-      (field) => field.name == propertyName.name,
-    );
-    if (namedField != null) {
-      return PropertyElementResolverResult(
-        recordField: namedField,
-      );
-    }
-
-    final match = _recordPositionalFieldName.firstMatch(propertyName.name);
-    if (match != null) {
-      final index = int.tryParse(match.group(1)!);
-      if (index != null && index < targetType.positionalFields.length) {
-        return PropertyElementResolverResult(
-          recordField: targetType.positionalFields[index],
-        );
-      }
-    }
-
-    return null;
-  }
-
   PropertyElementResolverResult _resolveTargetSuperExpression({
     required Expression node,
     required SuperExpression target,
@@ -871,17 +842,22 @@
     );
   }
 
-  PropertyElementResolverResult _toIndexResult(ResolutionResult result) {
+  PropertyElementResolverResult _toIndexResult(
+    ResolutionResult result, {
+    required bool hasRead,
+    required bool hasWrite,
+  }) {
     var readElement = result.getter;
     var writeElement = result.setter;
 
+    final contextType = hasRead
+        ? readElement.firstParameterType
+        : writeElement.firstParameterType;
+
     return PropertyElementResolverResult(
       readElementRequested: readElement,
       writeElementRequested: writeElement,
-      indexContextType: _computeIndexContextType(
-        readElement: readElement,
-        writeElement: writeElement,
-      ),
+      indexContextType: contextType,
     );
   }
 }
diff --git a/pkg/analyzer/lib/src/dart/resolver/record_literal_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/record_literal_resolver.dart
index 0de4113..f22a407 100644
--- a/pkg/analyzer/lib/src/dart/resolver/record_literal_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/record_literal_resolver.dart
@@ -16,9 +16,6 @@
 
 /// Helper for resolving [RecordLiteral]s.
 class RecordLiteralResolver {
-  /// A regular expression used to match positional field names.
-  static final RegExp positionalFieldName = RegExp(r'^\$[0-9]+$');
-
   final ResolverVisitor _resolver;
 
   RecordLiteralResolver({
@@ -49,6 +46,12 @@
   /// Report any fields in the record literal [node] that use an invalid name.
   void reportInvalidFieldNames(RecordLiteralImpl node) {
     var fields = node.fields;
+    var positionalCount = 0;
+    for (var field in fields) {
+      if (field is! NamedExpression) {
+        positionalCount++;
+      }
+    }
     for (var field in fields) {
       if (field is NamedExpression) {
         var nameNode = field.name.label;
@@ -56,15 +59,21 @@
         if (name.startsWith('_')) {
           errorReporter.reportErrorForNode(
               CompileTimeErrorCode.INVALID_FIELD_NAME_PRIVATE, nameNode);
-        } else if (positionalFieldName.hasMatch(name)) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.INVALID_FIELD_NAME_POSITIONAL, nameNode);
         } else {
-          var objectElement = _resolver.typeProvider.objectElement;
-          if (objectElement.getGetter(name) != null ||
-              objectElement.getMethod(name) != null) {
-            errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.INVALID_FIELD_NAME_FROM_OBJECT, nameNode);
+          final index = RecordTypeExtension.positionalFieldIndex(name);
+          if (index != null) {
+            if (index < positionalCount) {
+              errorReporter.reportErrorForNode(
+                  CompileTimeErrorCode.INVALID_FIELD_NAME_POSITIONAL, nameNode);
+            }
+          } else {
+            var objectElement = _resolver.typeProvider.objectElement;
+            if (objectElement.getGetter(name) != null ||
+                objectElement.getMethod(name) != null) {
+              errorReporter.reportErrorForNode(
+                  CompileTimeErrorCode.INVALID_FIELD_NAME_FROM_OBJECT,
+                  nameNode);
+            }
           }
         }
       }
@@ -116,6 +125,7 @@
 
   void _resolveField(Expression field, DartType? contextType) {
     _resolver.analyzeExpression(field, contextType);
+    _resolver.popRewrite();
   }
 
   void _resolveFields(RecordLiteralImpl node, DartType? contextType) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/record_type_annotation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/record_type_annotation_resolver.dart
index fbf4079..a3e41ab 100644
--- a/pkg/analyzer/lib/src/dart/resolver/record_type_annotation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/record_type_annotation_resolver.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
+import 'package:analyzer/src/dart/element/extensions.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
@@ -14,9 +15,6 @@
 
 /// Helper for resolving [RecordTypeAnnotation]s.
 class RecordTypeAnnotationResolver {
-  /// A regular expression used to match positional field names.
-  static final RegExp positionalFieldName = RegExp(r'^\$[0-9]+$');
-
   final TypeProviderImpl typeProvider;
   final ErrorReporter errorReporter;
 
@@ -46,6 +44,8 @@
 
   /// Report any fields in the record type [node] that use an invalid name.
   void reportInvalidFieldNames(RecordTypeAnnotationImpl node) {
+    var positionalFields = node.positionalFields;
+    var positionalCount = positionalFields.length;
     for (var field in node.fields) {
       var nameToken = field.name;
       if (nameToken != null) {
@@ -53,15 +53,23 @@
         if (name.startsWith('_')) {
           errorReporter.reportErrorForToken(
               CompileTimeErrorCode.INVALID_FIELD_NAME_PRIVATE, nameToken);
-        } else if (positionalFieldName.hasMatch(name)) {
-          errorReporter.reportErrorForToken(
-              CompileTimeErrorCode.INVALID_FIELD_NAME_POSITIONAL, nameToken);
         } else {
-          var objectElement = typeProvider.objectElement;
-          if (objectElement.getGetter(name) != null ||
-              objectElement.getMethod(name) != null) {
-            errorReporter.reportErrorForToken(
-                CompileTimeErrorCode.INVALID_FIELD_NAME_FROM_OBJECT, nameToken);
+          final index = RecordTypeExtension.positionalFieldIndex(name);
+          if (index != null) {
+            if (index < positionalCount &&
+                positionalFields.indexOf(field) != index) {
+              errorReporter.reportErrorForToken(
+                  CompileTimeErrorCode.INVALID_FIELD_NAME_POSITIONAL,
+                  nameToken);
+            }
+          } else {
+            var objectElement = typeProvider.objectElement;
+            if (objectElement.getGetter(name) != null ||
+                objectElement.getMethod(name) != null) {
+              errorReporter.reportErrorForToken(
+                  CompileTimeErrorCode.INVALID_FIELD_NAME_FROM_OBJECT,
+                  nameToken);
+            }
           }
         }
       }
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart
index 130268c..7c7cdc7 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 
 /// The result of attempting to resolve an identifier to elements.
 class ResolutionResult {
@@ -43,6 +44,12 @@
   /// when `dynamicTarget.foo`).
   final bool needsSetterError;
 
+  /// The [FunctionType] referenced with `call`.
+  final FunctionType? callFunctionType;
+
+  /// The field referenced in a [RecordType].
+  final RecordTypeField? recordField;
+
   /// Initialize a newly created result to represent resolving a single
   /// reading and / or writing result.
   ResolutionResult({
@@ -50,6 +57,8 @@
     this.needsGetterError = true,
     this.setter,
     this.needsSetterError = true,
+    this.callFunctionType,
+    this.recordField,
   }) : state = _ResolutionResultState.single;
 
   /// Initialize a newly created result with no elements and the given [state].
@@ -57,7 +66,9 @@
       : getter = null,
         needsGetterError = true,
         setter = null,
-        needsSetterError = true;
+        needsSetterError = true,
+        callFunctionType = null,
+        recordField = null;
 
   /// Return `true` if this result represents the case where multiple ambiguous
   /// elements were found.
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 4818b5d..4e36cf7 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -200,7 +201,6 @@
         _define(element);
 
         exceptionNode.declaredElement = element;
-        exceptionNode.nameNode.staticElement = element;
 
         element.isFinal = true;
         if (exceptionTypeNode == null) {
@@ -208,10 +208,8 @@
           var type =
               _isNonNullableByDefault ? _typeProvider.objectType : _dynamicType;
           element.type = type;
-          exceptionNode.nameNode.staticType = type;
         } else {
           element.type = exceptionTypeNode.typeOrThrow;
-          exceptionNode.nameNode.staticType = exceptionTypeNode.type;
         }
 
         element.setCodeRange(
@@ -230,11 +228,9 @@
         _define(element);
 
         stackTraceNode.declaredElement = element;
-        stackTraceNode.nameNode.staticElement = element;
 
         element.isFinal = true;
         element.type = _typeProvider.stackTraceType;
-        stackTraceNode.nameNode.staticType = _typeProvider.stackTraceType;
 
         element.setCodeRange(
           stackTraceNode.name.offset,
@@ -249,7 +245,7 @@
   @override
   void visitClassDeclaration(covariant ClassDeclarationImpl node) {
     ClassElementImpl element = _elementWalker!.getClass();
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _namedTypeResolver.enclosingClass = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
@@ -284,7 +280,7 @@
   @override
   void visitClassTypeAlias(covariant ClassTypeAliasImpl node) {
     ClassElementImpl element = _elementWalker!.getClass();
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _namedTypeResolver.enclosingClass = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
@@ -311,8 +307,8 @@
   @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     ConstructorElementImpl element = _elementWalker!.getConstructor();
-    (node as ConstructorDeclarationImpl).declaredElement2 = element;
-    node.declaredElement2 = element;
+    (node as ConstructorDeclarationImpl).declaredElement = element;
+    node.declaredElement = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
 
@@ -342,7 +338,7 @@
     var nameToken = node.name;
     var element = LocalVariableElementImpl(nameToken.lexeme, nameToken.offset);
     _elementHolder.enclose(element);
-    node.declaredElement2 = element;
+    node.declaredElement = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
 
@@ -417,7 +413,7 @@
   void visitEnumConstantDeclaration(
       covariant EnumConstantDeclarationImpl node) {
     var element = _elementWalker!.getVariable() as ConstFieldElementImpl;
-    node.declaredElement2 = element;
+    node.declaredElement = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
 
@@ -434,12 +430,12 @@
   @override
   void visitEnumDeclaration(covariant EnumDeclarationImpl node) {
     EnumElementImpl element = _elementWalker!.getEnum();
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _namedTypeResolver.enclosingClass = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
 
-    _withElementWalker(ElementWalker.forClass(element), () {
+    _withElementWalker(ElementWalker.forEnum(element), () {
       _withNameScope(() {
         _buildTypeParameterElements(node.typeParameters);
         node.typeParameters?.accept(this);
@@ -472,8 +468,8 @@
   @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     var element = _elementWalker!.getExtension();
-    (node as ExtensionDeclarationImpl).declaredElement2 = element;
-    node.declaredElement2 = element;
+    (node as ExtensionDeclarationImpl).declaredElement = element;
+    node.declaredElement = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
 
@@ -555,9 +551,9 @@
       element = node.isGetter || node.isSetter
           ? _elementWalker!.getAccessor()
           : _elementWalker!.getFunction();
-      node.declaredElement2 = element;
+      node.declaredElement = element;
     } else {
-      element = node.declaredElement2 as ExecutableElementImpl;
+      element = node.declaredElement as ExecutableElementImpl;
 
       _setCodeRange(element, node);
       setElementDocumentationComment(element, node);
@@ -655,7 +651,7 @@
   @override
   void visitFunctionTypeAlias(covariant FunctionTypeAliasImpl node) {
     var element = _elementWalker!.getTypedef();
-    node.declaredElement2 = element;
+    node.declaredElement = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
 
@@ -769,7 +765,7 @@
   @override
   void visitGenericTypeAlias(covariant GenericTypeAliasImpl node) {
     var element = _elementWalker!.getTypedef();
-    node.declaredElement2 = element;
+    node.declaredElement = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
 
@@ -795,7 +791,9 @@
   }
 
   @override
-  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+  void visitInstanceCreationExpression(
+    covariant InstanceCreationExpressionImpl node,
+  ) {
     var newNode = _astRewriter.instanceCreationExpression(_nameScope, node);
     if (newNode != node) {
       if (node.constructorName.type.typeArguments != null &&
@@ -871,7 +869,7 @@
     ExecutableElementImpl element = node.isGetter || node.isSetter
         ? _elementWalker!.getAccessor()
         : _elementWalker!.getFunction();
-    node.declaredElement2 = element;
+    node.declaredElement = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
 
@@ -906,11 +904,11 @@
   @override
   void visitMixinDeclaration(covariant MixinDeclarationImpl node) {
     var element = _elementWalker!.getMixin();
-    node.declaredElement2 = element as MixinElementImpl;
+    node.declaredElement = element;
 
     _setOrCreateMetadataElements(element, node.metadata);
 
-    _withElementWalker(ElementWalker.forClass(element), () {
+    _withElementWalker(ElementWalker.forMixin(element), () {
       _withNameScope(() {
         _buildTypeParameterElements(node.typeParameters);
         node.typeParameters?.accept(this);
@@ -978,7 +976,10 @@
 
   @override
   void visitRecordTypeAnnotation(covariant RecordTypeAnnotationImpl node) {
-    node.visitChildren(this);
+    _withElementWalker(null, () {
+      node.visitChildren(this);
+    });
+
     _recordTypeResolver.resolve(node);
   }
 
@@ -1104,7 +1105,7 @@
 
   @override
   void visitTypeParameter(TypeParameter node) {
-    var element = node.declaredElement2 as TypeParameterElementImpl;
+    var element = node.declaredElement as TypeParameterElementImpl;
 
     _setOrCreateMetadataElements(element, node.metadata);
 
@@ -1124,9 +1125,9 @@
     VariableElementImpl element;
     if (_elementWalker != null) {
       element = _elementWalker!.getVariable();
-      node.declaredElement2 = element;
+      node.declaredElement = element;
     } else {
-      var localElement = node.declaredElement2 as LocalVariableElementImpl;
+      var localElement = node.declaredElement as LocalVariableElementImpl;
       element = localElement;
 
       var varList = node.parent as VariableDeclarationList;
@@ -1168,7 +1169,7 @@
     var variables = node.variables;
     for (var i = 0; i < variables.length; i++) {
       var variable = variables[i];
-      var element = variable.declaredElement2 as ElementImpl;
+      var element = variable.declaredElement as ElementImpl;
       _setOrCreateMetadataElements(element, annotations, visitNodes: false);
 
       var offset = (i == 0 ? node.parent! : variable).offset;
@@ -1177,6 +1178,22 @@
     }
   }
 
+  @override
+  void visitVariablePattern(covariant VariablePatternImpl node) {
+    node.type?.accept(this);
+
+    if (node.name.lexeme != '_') {
+      final element = VariablePatternElementImpl(
+        node.name.lexeme,
+        node.name.offset,
+      );
+      node.declaredElement = element;
+      _elementHolder.enclose(element);
+      element.isFinal = node.keyword?.keyword == Keyword.FINAL;
+      element.hasImplicitType = node.type == null;
+    }
+  }
+
   /// Builds the label elements associated with [labels] and stores them in the
   /// element holder.
   void _buildLabelElements(
@@ -1208,9 +1225,9 @@
   void _buildLocalFunctionElement(
       covariant FunctionDeclarationStatementImpl statement) {
     var node = statement.functionDeclaration;
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var element = FunctionElementImpl(nameToken.lexeme, nameToken.offset);
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _define(element);
     _elementHolder.enclose(element);
   }
@@ -1221,7 +1238,7 @@
     var isLate = variableList.isLate;
     for (var variable in variableList.variables) {
       variable as VariableDeclarationImpl;
-      var nameToken = variable.name2;
+      var nameToken = variable.name;
 
       LocalVariableElementImpl element;
       if (isConst && variable.initializer != null) {
@@ -1235,7 +1252,7 @@
           nameToken.offset,
         );
       }
-      variable.declaredElement2 = element;
+      variable.declaredElement = element;
       _elementHolder.enclose(element);
       _define(element);
 
@@ -1253,7 +1270,7 @@
 
     for (var typeParameter in typeParameterList.typeParameters) {
       typeParameter as TypeParameterImpl;
-      var name = typeParameter.name2;
+      var name = typeParameter.name;
 
       TypeParameterElementImpl element;
       if (_elementWalker != null) {
@@ -1264,9 +1281,7 @@
 
         _setCodeRange(element, typeParameter);
       }
-      typeParameter.declaredElement2 = element;
-      // ignore: deprecated_member_use_from_same_package
-      typeParameter.name.staticElement = element;
+      typeParameter.declaredElement = element;
       _define(element);
       _setOrCreateMetadataElements(element, typeParameter.metadata);
     }
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index 0d700ea..30cf781 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -27,10 +27,10 @@
         NodeList<VariableDeclaration> variables = statement.variables.variables;
         int variableCount = variables.length;
         for (int j = 0; j < variableCount; j++) {
-          yield variables[j].declaredElement2!;
+          yield variables[j].declaredElement!;
         }
       } else if (statement is FunctionDeclarationStatement) {
-        yield statement.functionDeclaration.declaredElement2!;
+        yield statement.functionDeclaration.declaredElement!;
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/resolver/shared_type_analyzer.dart b/pkg/analyzer/lib/src/dart/resolver/shared_type_analyzer.dart
new file mode 100644
index 0000000..8dff60d
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/shared_type_analyzer.dart
@@ -0,0 +1,105 @@
+// Copyright (c) 2022, 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/type_inference/type_analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:collection/collection.dart';
+
+/// Implementation of [TypeAnalyzerErrors] that reports errors using the
+/// analyzer's [ErrorReporter] class.
+class SharedTypeAnalyzerErrors
+    implements
+        TypeAnalyzerErrors<AstNode, Statement, Expression, PromotableElement,
+            DartType> {
+  final ErrorReporter _errorReporter;
+
+  SharedTypeAnalyzerErrors(this._errorReporter);
+
+  @override
+  void assertInErrorRecovery() {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  void caseExpressionTypeMismatch(
+      {required Expression scrutinee,
+      required Expression caseExpression,
+      required scrutineeType,
+      required caseExpressionType,
+      required bool nullSafetyEnabled}) {
+    if (nullSafetyEnabled) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode
+              .CASE_EXPRESSION_TYPE_IS_NOT_SWITCH_EXPRESSION_SUBTYPE,
+          caseExpression,
+          [caseExpressionType, scrutineeType]);
+    } else {
+      // We only report the error if it occurs on the first case; otherwise
+      // separate logic will report that different cases have different types.
+      var switchStatement = scrutinee.parent as SwitchStatement;
+      if (identical(
+          switchStatement.members
+              .whereType<SwitchCase>()
+              .firstOrNull
+              ?.expression,
+          caseExpression)) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
+            scrutinee,
+            [scrutineeType, caseExpressionType]);
+      }
+    }
+  }
+
+  @override
+  void inconsistentMatchVar(
+      {required AstNode pattern,
+      required DartType type,
+      required AstNode previousPattern,
+      required DartType previousType}) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  void inconsistentMatchVarExplicitness(
+      {required AstNode pattern, required AstNode previousPattern}) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  void nonBooleanCondition(Expression node) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  void patternDoesNotAllowLate(AstNode pattern) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  void patternTypeMismatchInIrrefutableContext(
+      {required AstNode pattern,
+      required AstNode context,
+      required DartType matchedType,
+      required DartType requiredType}) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  void refutablePatternInIrrefutableContext(AstNode pattern, AstNode context) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  void switchCaseCompletesNormally(
+      covariant SwitchStatement node, int caseIndex, int numHeads) {
+    _errorReporter.reportErrorForToken(
+        CompileTimeErrorCode.SWITCH_CASE_COMPLETES_NORMALLY,
+        node.members[caseIndex + numHeads - 1].keyword);
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
index 97dbd16..2136d81 100644
--- a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
@@ -22,6 +22,8 @@
 
   final InvocationInferenceHelper _inferenceHelper;
 
+  var _currentAlreadyResolved = false;
+
   SimpleIdentifierResolver(this._resolver)
       : _inferenceHelper = _resolver.inferenceHelper;
 
@@ -41,7 +43,7 @@
 
     _reportDeprecatedExportUse(node);
 
-    _resolve1(node);
+    _resolve1(node, contextType: contextType);
     _resolve2(node, contextType: contextType);
   }
 
@@ -117,7 +119,9 @@
     }
   }
 
-  void _resolve1(SimpleIdentifierImpl node) {
+  void _resolve1(SimpleIdentifierImpl node, {required DartType? contextType}) {
+    _currentAlreadyResolved = false;
+
     //
     // Synthetic identifiers have been already reported during parsing.
     //
@@ -167,6 +171,24 @@
       hasWrite: hasWrite,
     );
 
+    final callFunctionType = result.functionTypeCallType;
+    if (callFunctionType != null) {
+      final staticType = _resolver.inferenceHelper
+          .inferTearOff(node, node, callFunctionType, contextType: contextType);
+      _inferenceHelper.recordStaticType(node, staticType,
+          contextType: contextType);
+      _currentAlreadyResolved = true;
+      return;
+    }
+
+    final recordField = result.recordField;
+    if (recordField != null) {
+      _inferenceHelper.recordStaticType(node, recordField.type,
+          contextType: contextType);
+      _currentAlreadyResolved = true;
+      return;
+    }
+
     var element = hasRead ? result.readElement : result.writeElement;
 
     var enclosingClass = _resolver.enclosingClass;
@@ -204,6 +226,10 @@
   }
 
   void _resolve2(SimpleIdentifierImpl node, {required DartType? contextType}) {
+    if (_currentAlreadyResolved) {
+      return;
+    }
+
     var element = node.staticElement;
 
     if (element is ExtensionElement) {
@@ -212,7 +238,7 @@
     }
 
     DartType staticType = DynamicTypeImpl.instance;
-    if (element is ClassElement) {
+    if (element is InterfaceElement) {
       if (_isExpressionIdentifier(node)) {
         node.staticType = _typeProvider.typeType;
       }
diff --git a/pkg/analyzer/lib/src/dart/resolver/this_lookup.dart b/pkg/analyzer/lib/src/dart/resolver/this_lookup.dart
index d274eb8..8b79e08 100644
--- a/pkg/analyzer/lib/src/dart/resolver/this_lookup.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/this_lookup.dart
@@ -33,6 +33,20 @@
       nameErrorEntity: node,
     );
 
+    final callFunctionType = propertyResult.callFunctionType;
+    if (callFunctionType != null) {
+      return LexicalLookupResult(
+        callFunctionType: callFunctionType,
+      );
+    }
+
+    final recordField = propertyResult.recordField;
+    if (recordField != null) {
+      return LexicalLookupResult(
+        recordField: recordField,
+      );
+    }
+
     var getterElement = propertyResult.getter;
     if (getterElement != null) {
       return LexicalLookupResult(requested: getterElement);
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
index b88be0e..f220df5 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/extensions.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
@@ -186,7 +187,13 @@
 
       if (receiverTypeResolved is FunctionType &&
           _name == FunctionElement.CALL_METHOD_NAME) {
-        return _toResult();
+        return ResolutionResult(
+          getter: null,
+          needsGetterError: false,
+          setter: null,
+          needsSetterError: false,
+          callFunctionType: receiverTypeResolved,
+        );
       }
 
       if (receiverTypeResolved is NeverType) {
@@ -196,6 +203,18 @@
         return _toResult();
       }
 
+      if (receiverTypeResolved is RecordType) {
+        final field = receiverTypeResolved.fieldByName(name);
+        if (field != null) {
+          return ResolutionResult(
+            recordField: field,
+            needsGetterError: false,
+          );
+        }
+        _needsGetterError = true;
+        _needsSetterError = true;
+      }
+
       _lookupExtension(receiverType);
       if (_hasGetterOrSetter) {
         return _toResult();
diff --git a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
index 31b7308..7440121 100644
--- a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/src/dart/element/generic_inferrer.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -52,8 +53,6 @@
   final MigratableAstInfoProvider _migratableAstInfoProvider;
 
   final bool _strictInference;
-  final bool _uiAsCodeEnabled;
-
   final bool _isNonNullableByDefault;
 
   factory TypedLiteralResolver(ResolverVisitor resolver, FeatureSet featureSet,
@@ -69,8 +68,6 @@
         typeProvider,
         resolver.errorReporter,
         analysisOptionsImpl.strictInference,
-        featureSet.isEnabled(Feature.control_flow_collections) ||
-            featureSet.isEnabled(Feature.spread_collections),
         featureSet.isEnabled(Feature.non_nullable),
         migratableAstInfoProvider);
   }
@@ -81,7 +78,6 @@
       this._typeProvider,
       this._errorReporter,
       this._strictInference,
-      this._uiAsCodeEnabled,
       this._isNonNullableByDefault,
       this._migratableAstInfoProvider);
 
@@ -97,7 +93,7 @@
   }
 
   void resolveListLiteral(ListLiteralImpl node,
-      {required DartType? contextType}) {
+      {required DartType contextType}) {
     InterfaceType? listType;
     GenericInferrer? inferrer;
 
@@ -111,7 +107,7 @@
       }
     } else {
       inferrer = _inferListTypeDownwards(node, contextType: contextType);
-      if (contextType != null) {
+      if (contextType is! UnknownInferredType) {
         var typeArguments = inferrer.partialInfer();
         listType = _typeProvider.listElement.instantiate(
             typeArguments: typeArguments, nullabilitySuffix: _noneOrStarSuffix);
@@ -131,7 +127,7 @@
   }
 
   void resolveSetOrMapLiteral(SetOrMapLiteral node,
-      {required DartType? contextType}) {
+      {required DartType contextType}) {
     (node as SetOrMapLiteralImpl).becomeUnresolved();
     var typeArguments = node.typeArguments?.arguments;
 
@@ -170,7 +166,6 @@
       assert(literalResolution.kind == _LiteralResolutionKind.ambiguous);
       literalType = null;
     }
-    var elements = _getSetOrMapElements(node);
     CollectionLiteralContext? context;
     if (literalType is InterfaceType) {
       List<DartType> typeArguments = literalType.typeArguments;
@@ -179,13 +174,6 @@
         DartType iterableType = _typeProvider.iterableType(elementType);
         context = CollectionLiteralContext(
             elementType: elementType, iterableType: iterableType);
-        if (!_uiAsCodeEnabled &&
-            elements.isEmpty &&
-            node.typeArguments == null &&
-            node.isMap) {
-          // The node is really an empty set literal with no type arguments.
-          node.becomeMap();
-        }
       } else if (typeArguments.length == 2) {
         DartType keyType = typeArguments[0];
         DartType valueType = typeArguments[1];
@@ -485,7 +473,7 @@
 
   InterfaceType? _inferListTypeUpwards(
       GenericInferrer inferrer, ListLiteral node,
-      {required DartType? contextType}) {
+      {required DartType contextType}) {
     var element = _typeProvider.listElement;
     var typeParameters = element.typeParameters;
     var genericElementType = typeParameters[0].instantiate(
@@ -499,7 +487,9 @@
         'element', genericElementType, ParameterKind.POSITIONAL);
     List<ParameterElement> parameters =
         List.filled(elementTypes.length, syntheticParameter);
-    if (_strictInference && parameters.isEmpty && contextType == null) {
+    if (_strictInference &&
+        parameters.isEmpty &&
+        contextType is UnknownInferredType) {
       // We cannot infer the type of a collection literal with no elements, and
       // no context type. If there are any elements, inference has not failed,
       // as the types of those elements are considered resolved.
@@ -619,11 +609,12 @@
       List<CollectionElement> elements, CollectionLiteralContext? context) {
     for (var element in elements) {
       (element as CollectionElementImpl).resolveElement(_resolver, context);
+      _resolver.popRewrite();
     }
   }
 
   void _resolveListLiteral2(GenericInferrer? inferrer, ListLiteralImpl node,
-      {required DartType? contextType}) {
+      {required DartType contextType}) {
     var typeArguments = node.typeArguments?.arguments;
 
     // If we have explicit arguments, use them.
@@ -658,7 +649,7 @@
 
   void _resolveSetOrMapLiteral2(GenericInferrer? inferrer,
       _LiteralResolution literalResolution, SetOrMapLiteralImpl node,
-      {required DartType? contextType}) {
+      {required DartType contextType}) {
     var typeArguments = node.typeArguments?.arguments;
 
     // If we have type arguments, use them.
@@ -701,7 +692,7 @@
     }
     if (_strictInference &&
         _getSetOrMapElements(node).isEmpty &&
-        contextType == null) {
+        contextType is UnknownInferredType) {
       // We cannot infer the type of a collection literal with no elements, and
       // no context type. If there are any elements, inference has not failed,
       // as the types of those elements are considered resolved.
diff --git a/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart
index 3387200..b7d3f31 100644
--- a/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart
@@ -33,13 +33,13 @@
         _resolver.errorReporter.reportErrorForNode(
           HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE,
           node,
-          [node.name2.lexeme],
+          [node.name.lexeme],
         );
       }
       return;
     }
 
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     var isTopLevel =
         element is FieldElement || element is TopLevelVariableElement;
 
@@ -50,7 +50,7 @@
     }
 
     _resolver.analyzeExpression(initializer, element.type);
-    initializer = node.initializer!;
+    initializer = _resolver.popRewrite()!;
     var whyNotPromoted =
         _resolver.flowAnalysis.flow?.whyNotPromoted(initializer);
 
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 c8c5504..f147134 100644
--- a/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
@@ -157,6 +157,7 @@
   ) {
     _resolver.analyzeExpression(
         node.expression, _computeContextType(bodyContext, node));
+    _resolver.popRewrite();
 
     if (node.star != null) {
       _resolver.nullableDereferenceVerifier.expression(
diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic.dart
index 39a6b98..bd11d71 100644
--- a/pkg/analyzer/lib/src/diagnostic/diagnostic.dart
+++ b/pkg/analyzer/lib/src/diagnostic/diagnostic.dart
@@ -32,9 +32,6 @@
       : _message = message;
 
   @override
-  String get message => messageText(includeUrl: true);
-
-  @override
   String messageText({required bool includeUrl}) {
     if (includeUrl && url != null) {
       var result = StringBuffer(_message);
diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
index 2e1fa8c..c96b840 100644
--- a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
+++ b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
@@ -180,9 +180,9 @@
     return AnalysisError(
         source, errorNode.offset, errorNode.length, errorCode, [
       member.name,
-      member.enclosingElement3.name!,
+      member.enclosingElement.name!,
       member.type,
-      superMember.enclosingElement3.name!,
+      superMember.enclosingElement.name!,
       superMember.type,
     ], [
       // Only include the context location for INVALID_OVERRIDE because for
diff --git a/pkg/analyzer/lib/src/error/assignment_verifier.dart b/pkg/analyzer/lib/src/error/assignment_verifier.dart
index 9cef247..db6259f 100644
--- a/pkg/analyzer/lib/src/error/assignment_verifier.dart
+++ b/pkg/analyzer/lib/src/error/assignment_verifier.dart
@@ -56,8 +56,8 @@
       return;
     }
 
-    if (recovery is ClassElement ||
-        recovery is DynamicElementImpl ||
+    if (recovery is DynamicElementImpl ||
+        recovery is InterfaceElement ||
         recovery is TypeAliasElement ||
         recovery is TypeParameterElement) {
       _errorReporter.reportErrorForNode(
@@ -91,7 +91,7 @@
         _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
           node,
-          [variable.name, variable.enclosingElement3.displayName],
+          [variable.name, variable.enclosingElement.displayName],
         );
       } 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 93f77a9..0154c4e 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -45,7 +45,7 @@
 
   /// The class containing the AST nodes being visited, or `null` if we are not
   /// in the scope of a class.
-  ClassElementImpl? _enclosingClass;
+  InterfaceElement? _enclosingClass;
 
   /// A flag indicating whether a surrounding member is annotated as
   /// `@doNotStore`.
@@ -155,11 +155,10 @@
             HintCode.INVALID_IMMUTABLE_ANNOTATION, node, []);
       }
     } else if (element.isInternal) {
-      var parentElement =
-          parent is Declaration ? parent.declaredElement2 : null;
+      var parentElement = parent is Declaration ? parent.declaredElement : null;
       if (parent is TopLevelVariableDeclaration) {
         for (VariableDeclaration variable in parent.variables.variables) {
-          var element = variable.declaredElement2 as TopLevelVariableElement;
+          var element = variable.declaredElement as TopLevelVariableElement;
           if (Identifier.isPrivateName(element.name)) {
             _errorReporter.reportErrorForNode(
                 HintCode.INVALID_INTERNAL_ANNOTATION, variable, []);
@@ -167,14 +166,14 @@
         }
       } else if (parent is FieldDeclaration) {
         for (VariableDeclaration variable in parent.fields.variables) {
-          var element = variable.declaredElement2 as FieldElement;
+          var element = variable.declaredElement as FieldElement;
           if (Identifier.isPrivateName(element.name)) {
             _errorReporter.reportErrorForNode(
                 HintCode.INVALID_INTERNAL_ANNOTATION, variable, []);
           }
         }
       } else if (parent is ConstructorDeclaration) {
-        var class_ = parent.declaredElement2!.enclosingElement3;
+        var class_ = parent.declaredElement!.enclosingElement;
         if (class_.isPrivate || (parentElement?.isPrivate ?? false)) {
           _errorReporter.reportErrorForNode(
               HintCode.INVALID_INTERNAL_ANNOTATION, node, []);
@@ -256,7 +255,7 @@
         if (parent is TopLevelVariableDeclaration) {
           for (VariableDeclaration variable in parent.variables.variables) {
             var variableElement =
-                variable.declaredElement2 as TopLevelVariableElement;
+                variable.declaredElement as TopLevelVariableElement;
 
             if (Identifier.isPrivateName(variableElement.name)) {
               reportInvalidAnnotation(variableElement);
@@ -269,7 +268,7 @@
           }
         } else if (parent is FieldDeclaration) {
           for (VariableDeclaration variable in parent.fields.variables) {
-            var fieldElement = variable.declaredElement2 as FieldElement;
+            var fieldElement = variable.declaredElement as FieldElement;
             if (parent.isStatic && element.isVisibleForOverriding == true) {
               reportInvalidVisibleForOverriding(fieldElement);
             }
@@ -278,8 +277,8 @@
               reportInvalidAnnotation(fieldElement);
             }
           }
-        } else if (parent.declaredElement2 != null) {
-          final declaredElement = parent.declaredElement2!;
+        } else if (parent.declaredElement != null) {
+          final declaredElement = parent.declaredElement!;
           if (element.isVisibleForOverriding &&
               !declaredElement.isInstanceMember) {
             reportInvalidVisibleForOverriding(declaredElement);
@@ -304,9 +303,9 @@
       if (undefinedParam != null) {
         String? name;
         if (parent is FunctionDeclaration) {
-          name = parent.name2.lexeme;
+          name = parent.name.lexeme;
         } else if (parent is MethodDeclaration) {
-          name = parent.name2.lexeme;
+          name = parent.name.lexeme;
         }
         if (name != null) {
           var paramName = undefinedParam is SimpleStringLiteral
@@ -326,7 +325,7 @@
         var invokedElement = element.element!;
         var name = invokedElement.name;
         if (invokedElement is ConstructorElement) {
-          var className = invokedElement.enclosingElement3.name;
+          var className = invokedElement.enclosingElement.name;
           if (name!.isEmpty) {
             name = className;
           } else {
@@ -386,7 +385,7 @@
 
   @override
   void visitClassDeclaration(ClassDeclaration node) {
-    var element = node.declaredElement2 as ClassElementImpl;
+    var element = node.declaredElement as ClassElementImpl;
     _enclosingClass = element;
     _invalidAccessVerifier._enclosingClass = element;
 
@@ -430,7 +429,7 @@
 
   @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
-    var element = node.declaredElement2 as ConstructorElementImpl;
+    var element = node.declaredElement as ConstructorElementImpl;
     if (!_isNonNullableByDefault && element.isFactory) {
       if (node.body is BlockFunctionBody) {
         // Check the block for a return statement, if not, create the hint.
@@ -479,11 +478,11 @@
       super.visitFieldDeclaration(node);
       for (var field in node.fields.variables) {
         ExecutableElement? getOverriddenPropertyAccessor() {
-          final element = field.declaredElement2;
+          final element = field.declaredElement;
           if (element is PropertyAccessorElement || element is FieldElement) {
             Name name = Name(_currentLibrary.source.uri, element!.name);
-            Element enclosingElement = element.enclosingElement3!;
-            if (enclosingElement is ClassElement) {
+            Element enclosingElement = element.enclosingElement!;
+            if (enclosingElement is InterfaceElement) {
               var overridden = _inheritanceManager
                   .getMember2(enclosingElement, name, forSuper: true);
               // Check for a setter.
@@ -506,9 +505,9 @@
           // always named, so we can safely assume
           // `overriddenElement.enclosingElement3.name` is non-`null`.
           _errorReporter.reportErrorForToken(
-              HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER, field.name2, [
-            field.name2.lexeme,
-            overriddenElement.enclosingElement3.displayName
+              HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER, field.name, [
+            field.name.lexeme,
+            overriddenElement.enclosingElement.displayName
           ]);
         }
         if (!_invalidAccessVerifier._inTestDirectory) {
@@ -535,7 +534,7 @@
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     bool wasInDoNotStoreMember = _inDoNotStoreMember;
-    ExecutableElement element = node.declaredElement2!;
+    ExecutableElement element = node.declaredElement!;
     _deprecatedVerifier.pushInDeprecatedValue(element.hasDeprecated);
     if (element.hasDoNotStore) {
       _inDoNotStoreMember = true;
@@ -546,7 +545,7 @@
       // Return types are inferred only on non-recursive local functions.
       if (node.parent is CompilationUnit && !node.isSetter) {
         _checkStrictInferenceReturnType(
-            node.returnType, node, node.name2.lexeme);
+            node.returnType, node, node.name.lexeme);
       }
       _checkStrictInferenceInParameters(node.functionExpression.parameters,
           body: node.functionExpression.body);
@@ -583,7 +582,7 @@
 
   @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    _checkStrictInferenceReturnType(node.returnType, node, node.name2.lexeme);
+    _checkStrictInferenceReturnType(node.returnType, node, node.name.lexeme);
     _checkStrictInferenceInParameters(node.parameters);
     super.visitFunctionTypeAlias(node);
   }
@@ -609,7 +608,7 @@
   void visitGenericTypeAlias(GenericTypeAlias node) {
     if (node.functionType != null) {
       _checkStrictInferenceReturnType(
-          node.functionType!.returnType, node, node.name2.lexeme);
+          node.functionType!.returnType, node, node.name.lexeme);
     }
     super.visitGenericTypeAlias(node);
   }
@@ -650,21 +649,21 @@
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
     bool wasInDoNotStoreMember = _inDoNotStoreMember;
-    var element = node.declaredElement2!;
-    var enclosingElement = element.enclosingElement3;
+    var element = node.declaredElement!;
+    var enclosingElement = element.enclosingElement;
 
     Name name = Name(_currentLibrary.source.uri, element.name);
 
     ExecutableElement? getConcreteOverriddenElement() =>
-        element is ClassMemberElement && enclosingElement is ClassElement
+        element is ClassMemberElement && enclosingElement is InterfaceElement
             ? _inheritanceManager.getMember2(enclosingElement, name,
                 forSuper: true)
             : null;
-    ExecutableElement? getOverriddenPropertyAccessor() =>
-        element is PropertyAccessorElement && enclosingElement is ClassElement
-            ? _inheritanceManager.getMember2(enclosingElement, name,
-                forSuper: true)
-            : null;
+    ExecutableElement? getOverriddenPropertyAccessor() => element
+                is PropertyAccessorElement &&
+            enclosingElement is InterfaceElement
+        ? _inheritanceManager.getMember2(enclosingElement, name, forSuper: true)
+        : null;
 
     _deprecatedVerifier.pushInDeprecatedValue(element.hasDeprecated);
     if (element.hasDoNotStore) {
@@ -678,13 +677,13 @@
       _checkForUnnecessaryNoSuchMethod(node);
 
       var elementIsOverride = element is ClassMemberElement &&
-              enclosingElement is ClassElement
+              enclosingElement is InterfaceElement
           ? _inheritanceManager.getOverridden2(enclosingElement, name) != null
           : false;
 
       if (!node.isSetter && !elementIsOverride) {
         _checkStrictInferenceReturnType(
-            node.returnType, node, node.name2.lexeme);
+            node.returnType, node, node.name.lexeme);
       }
       if (!elementIsOverride) {
         _checkStrictInferenceInParameters(node.parameters, body: node.body);
@@ -701,10 +700,9 @@
         // always named, so we can safely assume
         // `overriddenElement.enclosingElement3.name` is non-`null`.
         _errorReporter.reportErrorForToken(
-            HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER, node.name2, [
-          node.name2.lexeme,
-          overriddenElement.enclosingElement3.displayName
-        ]);
+            HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER,
+            node.name,
+            [node.name.lexeme, overriddenElement.enclosingElement.displayName]);
       }
 
       super.visitMethodDeclaration(node);
@@ -725,7 +723,7 @@
 
   @override
   void visitMixinDeclaration(MixinDeclaration node) {
-    var element = node.declaredElement2 as ClassElementImpl;
+    var element = node.declaredElement as MixinElementImpl;
     _enclosingClass = element;
     _invalidAccessVerifier._enclosingClass = _enclosingClass;
 
@@ -1058,14 +1056,14 @@
       return nonFinalFields;
     }
 
-    var element = node.declaredElement2 as ClassElement;
-    if (isOrInheritsImmutable(element, HashSet<ClassElement>())) {
+    var element = node.declaredElement as InterfaceElement;
+    if (isOrInheritsImmutable(element, HashSet<InterfaceElement>())) {
       Iterable<String> nonFinalFields =
           definedOrInheritedNonFinalInstanceFields(
-              element, HashSet<ClassElement>());
+              element, HashSet<InterfaceElement>());
       if (nonFinalFields.isNotEmpty) {
-        _errorReporter.reportErrorForToken(HintCode.MUST_BE_IMMUTABLE,
-            node.name2, [nonFinalFields.join(', ')]);
+        _errorReporter.reportErrorForToken(
+            HintCode.MUST_BE_IMMUTABLE, node.name, [nonFinalFields.join(', ')]);
       }
     }
   }
@@ -1137,8 +1135,8 @@
     // Note that null return types are expected to be flagged by other analyses.
     var returnType = decl.returnType?.type;
     if (returnType is VoidType) {
-      _errorReporter.reportErrorForToken(HintCode.INVALID_FACTORY_METHOD_DECL,
-          decl.name2, [decl.name2.lexeme]);
+      _errorReporter.reportErrorForToken(
+          HintCode.INVALID_FACTORY_METHOD_DECL, decl.name, [decl.name.lexeme]);
       return;
     }
 
@@ -1167,7 +1165,7 @@
     }
 
     _errorReporter.reportErrorForToken(
-        HintCode.INVALID_FACTORY_METHOD_IMPL, decl.name2, [decl.name2.lexeme]);
+        HintCode.INVALID_FACTORY_METHOD_IMPL, decl.name, [decl.name.lexeme]);
   }
 
   void _checkForInvalidSealedSuperclass(NamedCompilationUnitMember node) {
@@ -1179,14 +1177,15 @@
     // ClassElement, but [_checkForInvalidSealedSuperclass] should only be
     // called with a [ClassOrMixinDeclaration], or a [ClassTypeAlias]. The
     // `declaredElement` of these specific classes is a [ClassElement].
-    var element = node.declaredElement2 as ClassElement;
+    var element = node.declaredElement as InterfaceElement;
     // TODO(srawlins): Perhaps replace this with a getter on Element, like
     // `Element.hasOrInheritsSealed`?
     for (InterfaceType supertype in element.allSupertypes) {
       final superclass = supertype.element2;
       if (superclass.hasSealed) {
         if (!currentPackageContains(superclass)) {
-          if (element.superclassConstraints.contains(supertype)) {
+          if (element is MixinElement &&
+              element.superclassConstraints.contains(supertype)) {
             // This is a special violation of the sealed class contract,
             // requiring specific messaging.
             _errorReporter.reportErrorForNode(HintCode.MIXIN_ON_SEALED_CLASS,
@@ -1330,13 +1329,13 @@
     if (functionNode is FunctionDeclaration) {
       _errorReporter.reportErrorForToken(
         HintCode.MISSING_RETURN,
-        functionNode.name2,
+        functionNode.name,
         [returnType],
       );
     } else if (functionNode is MethodDeclaration) {
       _errorReporter.reportErrorForToken(
         HintCode.MISSING_RETURN,
-        functionNode.name2,
+        functionNode.name,
         [returnType],
       );
     } else {
@@ -1460,7 +1459,7 @@
         _errorReporter.reportErrorForNode(
           HintCode.RETURN_OF_DO_NOT_STORE,
           entry.key,
-          [entry.value.name!, parent.declaredElement2!.displayName],
+          [entry.value.name!, parent.declaredElement!.displayName],
         );
       }
     }
@@ -1471,7 +1470,7 @@
   ///
   /// Return `true` if and only if a hint code is generated on the passed node.
   bool _checkForUnnecessaryNoSuchMethod(MethodDeclaration node) {
-    if (node.name2.lexeme != FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
+    if (node.name.lexeme != FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
       return false;
     }
     bool isNonObjectNoSuchMethodInvocation(Expression? invocation) {
@@ -1481,7 +1480,7 @@
         SimpleIdentifier name = invocation.methodName;
         if (name.name == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
           var methodElement = name.staticElement;
-          var classElement = methodElement?.enclosingElement3;
+          var classElement = methodElement?.enclosingElement;
           return methodElement is MethodElement &&
               classElement is ClassElement &&
               !classElement.isDartCoreObject;
@@ -1494,7 +1493,7 @@
     if (body is ExpressionFunctionBody) {
       if (isNonObjectNoSuchMethodInvocation(body.expression)) {
         _errorReporter.reportErrorForToken(
-            HintCode.UNNECESSARY_NO_SUCH_METHOD, node.name2);
+            HintCode.UNNECESSARY_NO_SUCH_METHOD, node.name);
         return true;
       }
     } else if (body is BlockFunctionBody) {
@@ -1504,7 +1503,7 @@
         if (returnStatement is ReturnStatement &&
             isNonObjectNoSuchMethodInvocation(returnStatement.expression)) {
           _errorReporter.reportErrorForToken(
-              HintCode.UNNECESSARY_NO_SUCH_METHOD, node.name2);
+              HintCode.UNNECESSARY_NO_SUCH_METHOD, node.name);
           return true;
         }
       }
@@ -1864,7 +1863,7 @@
   final bool _inTemplateSource;
   late final bool _inTestDirectory;
 
-  ClassElement? _enclosingClass;
+  InterfaceElement? _enclosingClass;
 
   _InvalidAccessVerifier(
       this._errorReporter, this._library, this._workspacePackage)
@@ -1920,7 +1919,7 @@
 
       if (node.leftOperand is SuperExpression) {
         var methodDeclaration = node.thisOrAncestorOfType<MethodDeclaration>();
-        if (methodDeclaration?.name2.lexeme == operator.lexeme) {
+        if (methodDeclaration?.name.lexeme == operator.lexeme) {
           return;
         }
       }
@@ -1984,7 +1983,7 @@
       SimpleIdentifier identifier, Element element) {
     bool hasProtected = _hasProtected(element);
     if (hasProtected) {
-      var definingClass = element.enclosingElement3 as ClassElement;
+      var definingClass = element.enclosingElement as InterfaceElement;
       if (_hasTypeOrSuperType(_enclosingClass, definingClass)) {
         return;
       }
@@ -2023,7 +2022,7 @@
       node = identifier;
     }
 
-    var definingClass = element.enclosingElement3;
+    var definingClass = element.enclosingElement;
     if (hasProtected) {
       _errorReporter.reportErrorForNode(
           HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
@@ -2051,7 +2050,7 @@
           parent is PropertyAccess && parent.target is SuperExpression) {
         var methodDeclaration =
             grandparent?.thisOrAncestorOfType<MethodDeclaration>();
-        if (methodDeclaration?.name2.lexeme == identifier.name) {
+        if (methodDeclaration?.name.lexeme == identifier.name) {
           validOverride = true;
         }
       }
@@ -2079,19 +2078,22 @@
 
   bool _hasProtected(Element element) {
     if (element is PropertyAccessorElement &&
-        element.enclosingElement3 is ClassElement &&
+        element.enclosingElement is InterfaceElement &&
         (element.hasProtected || element.variable.hasProtected)) {
       return true;
     }
     if (element is MethodElement &&
-        element.enclosingElement3 is ClassElement &&
+        element.enclosingElement is InterfaceElement &&
         element.hasProtected) {
       return true;
     }
     return false;
   }
 
-  bool _hasTypeOrSuperType(ClassElement? element, ClassElement superElement) {
+  bool _hasTypeOrSuperType(
+    InterfaceElement? element,
+    InterfaceElement superElement,
+  ) {
     if (element == null) {
       return false;
     }
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index c42f140..ad19e26 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -75,8 +75,7 @@
 
   ///  Parameters:
   ///  0: the name of the ambiguous type
-  ///  1: the name of the first library that the type is found
-  ///  2: the name of the second library that the type is found
+  ///  1: the names of the libraries that the type is found
   static const CompileTimeErrorCode AMBIGUOUS_IMPORT = CompileTimeErrorCode(
     'AMBIGUOUS_IMPORT',
     "The name '{0}' is defined in the libraries {1}.",
@@ -149,7 +148,8 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the variable
   static const CompileTimeErrorCode ASSIGNMENT_TO_FINAL_LOCAL =
       CompileTimeErrorCode(
     'ASSIGNMENT_TO_FINAL_LOCAL',
@@ -158,7 +158,9 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the reference
+  ///  1: the name of the class
   static const CompileTimeErrorCode ASSIGNMENT_TO_FINAL_NO_SETTER =
       CompileTimeErrorCode(
     'ASSIGNMENT_TO_FINAL_NO_SETTER',
@@ -225,7 +227,8 @@
         "Try marking the function body with either 'async' or 'async*'.",
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the return type
   static const CompileTimeErrorCode BODY_MIGHT_COMPLETE_NORMALLY =
       CompileTimeErrorCode(
     'BODY_MIGHT_COMPLETE_NORMALLY',
@@ -340,7 +343,8 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the type
   static const CompileTimeErrorCode CAST_TO_NON_TYPE = CompileTimeErrorCode(
     'CAST_TO_NON_TYPE',
     "The name '{0}' isn't a type, so it can't be used in an 'as' expression.",
@@ -374,7 +378,8 @@
   );
 
   ///  Parameters:
-  ///  0: the name of the member
+  ///  0: the name of the class
+  ///  1: the name of the member
   static const CompileTimeErrorCode
       CLASS_INSTANTIATION_ACCESS_TO_UNKNOWN_MEMBER = CompileTimeErrorCode(
     'CLASS_INSTANTIATION_ACCESS_TO_MEMBER',
@@ -617,6 +622,11 @@
 
   ///  16.12.2 Const: It is a compile-time error if evaluation of a constant
   ///  object results in an uncaught exception being thrown.
+  ///
+  ///  Parameters:
+  ///  0: the type of the runtime value of the argument
+  ///  1: the name of the field
+  ///  2: the type of the field
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH =
       CompileTimeErrorCode(
     'CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH',
@@ -1322,8 +1332,7 @@
     uniqueName: 'EXTENDS_DISALLOWED_CLASS',
   );
 
-  ///  Parameters:
-  ///  0: the name in the extends clause
+  ///  No parameters.
   static const CompileTimeErrorCode EXTENDS_NON_CLASS = CompileTimeErrorCode(
     'EXTENDS_NON_CLASS',
     "Classes can only extend other classes.",
@@ -1785,6 +1794,8 @@
     uniqueName: 'ILLEGAL_ENUM_VALUES_INHERITANCE',
   );
 
+  ///  Parameters:
+  ///  0: the required language version
   static const CompileTimeErrorCode ILLEGAL_LANGUAGE_VERSION_OVERRIDE =
       CompileTimeErrorCode(
     'ILLEGAL_LANGUAGE_VERSION_OVERRIDE',
@@ -1830,8 +1841,7 @@
     uniqueName: 'IMPLEMENTS_DISALLOWED_CLASS',
   );
 
-  ///  Parameters:
-  ///  0: the name of the interface that was not found
+  ///  No parameters.
   static const CompileTimeErrorCode IMPLEMENTS_NON_CLASS = CompileTimeErrorCode(
     'IMPLEMENTS_NON_CLASS',
     "Classes and mixins can only implement other classes and mixins.",
@@ -2090,6 +2100,7 @@
 
   ///  Parameters:
   ///  0: the lexeme of the integer
+  ///  1: the closest valid double
   static const CompileTimeErrorCode INTEGER_LITERAL_IMPRECISE_AS_DOUBLE =
       CompileTimeErrorCode(
     'INTEGER_LITERAL_IMPRECISE_AS_DOUBLE',
@@ -2101,7 +2112,8 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the value of the literal
   static const CompileTimeErrorCode INTEGER_LITERAL_OUT_OF_RANGE =
       CompileTimeErrorCode(
     'INTEGER_LITERAL_OUT_OF_RANGE',
@@ -2156,8 +2168,9 @@
   );
 
   ///  Parameters:
-  ///  0: the type of the function
-  ///  1: the expected function type
+  ///  0: the name of the function
+  ///  1: the type of the function
+  ///  2: the expected function type
   ///
   ///  This error is only reported in libraries which are not null safe.
   static const CompileTimeErrorCode INVALID_CAST_FUNCTION =
@@ -2181,8 +2194,9 @@
   );
 
   ///  Parameters:
-  ///  0: the type of the literal
-  ///  1: the expected type
+  ///  0: the lexeme of the literal
+  ///  1: the type of the literal
+  ///  2: the expected type
   ///
   ///  This error is only reported in libraries which are not null safe.
   static const CompileTimeErrorCode INVALID_CAST_LITERAL = CompileTimeErrorCode(
@@ -2230,8 +2244,9 @@
   );
 
   ///  Parameters:
-  ///  0: the type of the torn-off method
-  ///  1: the expected function type
+  ///  0: the name of the torn-off method
+  ///  1: the type of the torn-off method
+  ///  2: the expected function type
   ///
   ///  This error is only reported in libraries which are not null safe.
   static const CompileTimeErrorCode INVALID_CAST_METHOD = CompileTimeErrorCode(
@@ -2294,8 +2309,8 @@
   static const CompileTimeErrorCode INVALID_FIELD_NAME_POSITIONAL =
       CompileTimeErrorCode(
     'INVALID_FIELD_NAME',
-    "Record field names can't be a dollar sign followed by digits because "
-        "those are used to access positional fields.",
+    "Record field names can't be a dollar sign followed by an integer when "
+        "the\ninteger is the index of a positional field.",
     correctionMessage: "Try using a different name for the field.",
     uniqueName: 'INVALID_FIELD_NAME_POSITIONAL',
   );
@@ -2313,8 +2328,8 @@
   ///  0: the name of the declared member that is not a valid override.
   ///  1: the name of the interface that declares the member.
   ///  2: the type of the declared member in the interface.
-  ///  3. the name of the interface with the overridden member.
-  ///  4. the type of the overridden member.
+  ///  3: the name of the interface with the overridden member.
+  ///  4: the type of the overridden member.
   ///
   ///  These parameters must be kept in sync with those of
   ///  [CompileTimeErrorCode.INVALID_OVERRIDE].
@@ -2348,8 +2363,7 @@
     hasPublishedDocs: true,
   );
 
-  ///  Parameters:
-  ///  0: the invalid modifier
+  ///  No parameters.
   static const CompileTimeErrorCode INVALID_MODIFIER_ON_SETTER =
       CompileTimeErrorCode(
     'INVALID_MODIFIER_ON_SETTER',
@@ -2362,8 +2376,8 @@
   ///  0: the name of the declared member that is not a valid override.
   ///  1: the name of the interface that declares the member.
   ///  2: the type of the declared member in the interface.
-  ///  3. the name of the interface with the overridden member.
-  ///  4. the type of the overridden member.
+  ///  3: the name of the interface with the overridden member.
+  ///  4: the type of the overridden member.
   static const CompileTimeErrorCode INVALID_OVERRIDE = CompileTimeErrorCode(
     'INVALID_OVERRIDE',
     "'{1}.{0}' ('{2}') isn't a valid override of '{3}.{0}' ('{4}').",
@@ -2386,8 +2400,7 @@
     hasPublishedDocs: true,
   );
 
-  ///  Parameters:
-  ///  0: the super modifier
+  ///  No parameters.
   static const CompileTimeErrorCode INVALID_SUPER_FORMAL_PARAMETER_LOCATION =
       CompileTimeErrorCode(
     'INVALID_SUPER_FORMAL_PARAMETER_LOCATION',
@@ -2655,7 +2668,8 @@
     "Seeing this message constitutes a bug. Please report it.",
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the library
   static const CompileTimeErrorCode MISSING_DART_LIBRARY = CompileTimeErrorCode(
     'MISSING_DART_LIBRARY',
     "Required library '{0}' is missing.",
@@ -2663,7 +2677,8 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the parameter
   static const CompileTimeErrorCode MISSING_DEFAULT_VALUE_FOR_PARAMETER =
       CompileTimeErrorCode(
     'MISSING_DEFAULT_VALUE_FOR_PARAMETER',
@@ -2675,6 +2690,18 @@
     hasPublishedDocs: true,
   );
 
+  ///  Parameters:
+  ///  0: the name of the parameter
+  static const CompileTimeErrorCode
+      MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL = CompileTimeErrorCode(
+    'MISSING_DEFAULT_VALUE_FOR_PARAMETER',
+    "The parameter '{0}' can't have a value of 'null' because of its type, but "
+        "the implicit default value is 'null'.",
+    correctionMessage: "Try adding an explicit non-'null' default value.",
+    hasPublishedDocs: true,
+    uniqueName: 'MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL',
+  );
+
   ///  No parameters.
   static const CompileTimeErrorCode
       MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION =
@@ -2832,7 +2859,7 @@
   static const CompileTimeErrorCode
       MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS = CompileTimeErrorCode(
     'SUBTYPE_OF_DISALLOWED_TYPE',
-    "''{0}' can't be used as a superclass constraint.",
+    "'{0}' can't be used as a superclass constraint.",
     correctionMessage:
         "Try specifying a different super-class constraint, or remove the 'on' "
         "clause.",
@@ -2896,6 +2923,10 @@
   ///  x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>:
   ///  a<sub>n+kM/sub>)</i> it is a static warning if the type <i>T</i> does not
   ///  declare a constructor with the same name as the declaration of <i>T</i>.
+  ///
+  ///  Parameters:
+  ///  0: the name of the class being instantiated
+  ///  1: the name of the constructor
   static const CompileTimeErrorCode NEW_WITH_UNDEFINED_CONSTRUCTOR =
       CompileTimeErrorCode(
     'NEW_WITH_UNDEFINED_CONSTRUCTOR',
@@ -3221,7 +3252,7 @@
   static const CompileTimeErrorCode NON_TYPE_AS_TYPE_ARGUMENT =
       CompileTimeErrorCode(
     'NON_TYPE_AS_TYPE_ARGUMENT',
-    "The name '{0}' isn't a type so it can't be used as a type argument.",
+    "The name '{0}' isn't a type, so it can't be used as a type argument.",
     correctionMessage:
         "Try correcting the name to an existing type, or defining a type named "
         "'{0}'.",
@@ -3517,8 +3548,7 @@
   );
 
   ///  Parameters:
-  ///  0: the URI of the expected library
-  ///  1: the non-matching actual library name from the "part of" declaration
+  ///  0: the non-matching actual library name from the "part of" declaration
   static const CompileTimeErrorCode PART_OF_UNNAMED_LIBRARY =
       CompileTimeErrorCode(
     'PART_OF_UNNAMED_LIBRARY',
@@ -3600,6 +3630,8 @@
     hasPublishedDocs: true,
   );
 
+  ///  Parameters:
+  ///  0: the name of the setter
   static const CompileTimeErrorCode PRIVATE_SETTER = CompileTimeErrorCode(
     'PRIVATE_SETTER',
     "The setter '{0}' is private and can't be accessed outside the library "
@@ -3608,6 +3640,8 @@
     hasPublishedDocs: true,
   );
 
+  ///  Parameters:
+  ///  0: the name of the variable
   static const CompileTimeErrorCode READ_POTENTIALLY_UNASSIGNED_FINAL =
       CompileTimeErrorCode(
     'READ_POTENTIALLY_UNASSIGNED_FINAL',
@@ -3730,7 +3764,9 @@
     uniqueName: 'RECURSIVE_INTERFACE_INHERITANCE_WITH',
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the constructor
+  ///  1: the name of the class
   static const CompileTimeErrorCode REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR =
       CompileTimeErrorCode(
     'REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR',
@@ -3829,7 +3865,8 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the variable
   static const CompileTimeErrorCode REFERENCED_BEFORE_DECLARATION =
       CompileTimeErrorCode(
     'REFERENCED_BEFORE_DECLARATION',
@@ -4182,7 +4219,8 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the type
   static const CompileTimeErrorCode TYPE_TEST_WITH_NON_TYPE =
       CompileTimeErrorCode(
     'TYPE_TEST_WITH_NON_TYPE',
@@ -4191,7 +4229,8 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the type
   static const CompileTimeErrorCode TYPE_TEST_WITH_UNDEFINED_NAME =
       CompileTimeErrorCode(
     'TYPE_TEST_WITH_UNDEFINED_NAME',
@@ -4211,6 +4250,8 @@
     uniqueName: 'UNCHECKED_INVOCATION_OF_NULLABLE_VALUE',
   );
 
+  ///  Parameters:
+  ///  0: the name of the method
   static const CompileTimeErrorCode
       UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE = CompileTimeErrorCode(
     'UNCHECKED_USE_OF_NULLABLE_VALUE',
@@ -4223,6 +4264,8 @@
     uniqueName: 'UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE',
   );
 
+  ///  Parameters:
+  ///  0: the name of the operator
   static const CompileTimeErrorCode
       UNCHECKED_OPERATOR_INVOCATION_OF_NULLABLE_VALUE = CompileTimeErrorCode(
     'UNCHECKED_USE_OF_NULLABLE_VALUE',
@@ -4233,6 +4276,8 @@
     uniqueName: 'UNCHECKED_OPERATOR_INVOCATION_OF_NULLABLE_VALUE',
   );
 
+  ///  Parameters:
+  ///  0: the name of the property
   static const CompileTimeErrorCode
       UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE = CompileTimeErrorCode(
     'UNCHECKED_USE_OF_NULLABLE_VALUE',
@@ -4289,7 +4334,8 @@
     uniqueName: 'UNCHECKED_USE_OF_NULLABLE_VALUE_IN_YIELD_EACH',
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the annotation
   static const CompileTimeErrorCode UNDEFINED_ANNOTATION = CompileTimeErrorCode(
     'UNDEFINED_ANNOTATION',
     "Undefined name '{0}' used as an annotation.",
@@ -4548,7 +4594,9 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the reference
+  ///  1: the name of the prefix
   static const CompileTimeErrorCode UNDEFINED_PREFIXED_NAME =
       CompileTimeErrorCode(
     'UNDEFINED_PREFIXED_NAME',
@@ -4892,6 +4940,10 @@
   ///  Let `C` be a generic class that declares a formal type parameter `X`, and
   ///  assume that `T` is a direct superinterface of `C`. It is a compile-time
   ///  error if `X` occurs contravariantly or invariantly in `T`.
+  ///
+  ///  Parameters:
+  ///  0: the name of the type parameter
+  ///  1: the name of the super interface
   static const CompileTimeErrorCode
       WRONG_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE = CompileTimeErrorCode(
     'WRONG_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE',
@@ -4998,6 +5050,8 @@
 }
 
 class LanguageCode extends ErrorCode {
+  ///  Parameters:
+  ///  0: the name of the field
   static const LanguageCode IMPLICIT_DYNAMIC_FIELD = LanguageCode(
     'IMPLICIT_DYNAMIC_FIELD',
     "Missing field type for '{0}'.",
@@ -5006,6 +5060,9 @@
         "analysis options file.",
   );
 
+  ///  Parameters:
+  ///  0: the name of the function
+  ///  1: the names of the type arguments
   static const LanguageCode IMPLICIT_DYNAMIC_FUNCTION = LanguageCode(
     'IMPLICIT_DYNAMIC_FUNCTION',
     "Missing type arguments for generic function '{0}<{1}>'.",
@@ -5014,6 +5071,8 @@
         "analysis options file.",
   );
 
+  ///  Parameters:
+  ///  0: the name of type
   static const LanguageCode IMPLICIT_DYNAMIC_INVOKE = LanguageCode(
     'IMPLICIT_DYNAMIC_INVOKE',
     "Missing type arguments for calling generic function type '{0}'.",
@@ -5038,6 +5097,9 @@
         "analysis options file.",
   );
 
+  ///  Parameters:
+  ///  0: the name of the function
+  ///  1: the names of the type arguments
   static const LanguageCode IMPLICIT_DYNAMIC_METHOD = LanguageCode(
     'IMPLICIT_DYNAMIC_METHOD',
     "Missing type arguments for generic method '{0}<{1}>'.",
@@ -5046,6 +5108,8 @@
         "analysis options file.",
   );
 
+  ///  Parameters:
+  ///  0: the name of the parameter
   static const LanguageCode IMPLICIT_DYNAMIC_PARAMETER = LanguageCode(
     'IMPLICIT_DYNAMIC_PARAMETER',
     "Missing parameter type for '{0}'.",
@@ -5054,6 +5118,8 @@
         "analysis options file.",
   );
 
+  ///  Parameters:
+  ///  0: the name of the function or method
   static const LanguageCode IMPLICIT_DYNAMIC_RETURN = LanguageCode(
     'IMPLICIT_DYNAMIC_RETURN',
     "Missing return type for '{0}'.",
@@ -5062,6 +5128,8 @@
         "analysis options file.",
   );
 
+  ///  Parameters:
+  ///  0: the name of the type
   static const LanguageCode IMPLICIT_DYNAMIC_TYPE = LanguageCode(
     'IMPLICIT_DYNAMIC_TYPE',
     "Missing type arguments for generic type '{0}'.",
@@ -5070,6 +5138,8 @@
         "analysis options file.",
   );
 
+  ///  Parameters:
+  ///  0: the name of the variable
   static const LanguageCode IMPLICIT_DYNAMIC_VARIABLE = LanguageCode(
     'IMPLICIT_DYNAMIC_VARIABLE',
     "Missing variable type for '{0}'.",
@@ -5138,6 +5208,11 @@
   ///  <i>m2</i> explicitly specifies a default value for a formal parameter
   ///  <i>p</i> and the signature of <i>m1</i> specifies a different default value
   ///  for <i>p</i>.
+  ///
+  ///  Parameters:
+  ///  0: the name of the super class
+  ///  1: the name of the super method
+  ///  2: the name of the overriding method
   static const StaticWarningCode
       INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED = StaticWarningCode(
     'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED',
@@ -5151,6 +5226,9 @@
   ///  <i>m2</i> explicitly specifies a default value for a formal parameter
   ///  <i>p</i> and the signature of <i>m1</i> specifies a different default value
   ///  for <i>p</i>.
+  ///  Parameters:
+  ///  0: the name of the super class
+  ///  1: the name of the super method
   static const StaticWarningCode
       INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL = StaticWarningCode(
     'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL',
diff --git a/pkg/analyzer/lib/src/error/correct_override.dart b/pkg/analyzer/lib/src/error/correct_override.dart
index 9a3e4c1..cd2c317 100644
--- a/pkg/analyzer/lib/src/error/correct_override.dart
+++ b/pkg/analyzer/lib/src/error/correct_override.dart
@@ -131,9 +131,9 @@
             errorNode.length,
             [
               _thisMember.name,
-              _thisMember.enclosingElement3.name!,
+              _thisMember.enclosingElement.name!,
               _thisMember.type,
-              superMember.enclosingElement3.name!,
+              superMember.enclosingElement.name!,
               superMember.type,
             ],
           );
@@ -144,7 +144,7 @@
 
   List<_SuperMember> _superMembers() {
     var classHierarchy = _session.classHierarchy;
-    var classElement = _thisMember.enclosingElement3 as ClassElement;
+    var classElement = _thisMember.enclosingElement as InterfaceElement;
     var interfaces = classHierarchy.implementedInterfaces(classElement);
 
     var superMembers = <_SuperMember>[];
@@ -272,6 +272,5 @@
 
   _SuperParameter(this.element, this.type);
 
-  ExecutableElement get member =>
-      element.enclosingElement3 as ExecutableElement;
+  ExecutableElement get member => element.enclosingElement as ExecutableElement;
 }
diff --git a/pkg/analyzer/lib/src/error/deprecated_member_use_verifier.dart b/pkg/analyzer/lib/src/error/deprecated_member_use_verifier.dart
index 7191646..e518276 100644
--- a/pkg/analyzer/lib/src/error/deprecated_member_use_verifier.dart
+++ b/pkg/analyzer/lib/src/error/deprecated_member_use_verifier.dart
@@ -10,16 +10,11 @@
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:collection/collection.dart';
 
-class DeprecatedMemberUseVerifier {
-  final WorkspacePackage? _workspacePackage;
-  final ErrorReporter _errorReporter;
-
+abstract class BaseDeprecatedMemberUseVerifier {
   /// We push a new value every time when we enter into a scope which
   /// can be marked as deprecated - a class, a method, fields (multiple).
   final List<bool> _inDeprecatedMemberStack = [false];
 
-  DeprecatedMemberUseVerifier(this._workspacePackage, this._errorReporter);
-
   void assignmentExpression(AssignmentExpression node) {
     _checkForDeprecated(node.readElement, node.leftHandSide);
     _checkForDeprecated(node.writeElement, node.leftHandSide);
@@ -99,6 +94,9 @@
     _invocationArguments(node.staticElement, node.argumentList);
   }
 
+  void reportError(
+      AstNode errorNode, Element element, String displayName, String? message);
+
   void simpleIdentifier(SimpleIdentifier node) {
     // Don't report declared identifiers.
     if (node.inDeclarationContext()) {
@@ -169,7 +167,7 @@
       // TODO(jwren) We should modify ConstructorElement.getDisplayName(),
       // or have the logic centralized elsewhere, instead of doing this logic
       // here.
-      displayName = element.enclosingElement3.displayName;
+      displayName = element.enclosingElement.displayName;
       if (element.displayName.isNotEmpty) {
         displayName = "$displayName.${element.displayName}";
       }
@@ -181,25 +179,8 @@
       var invokeClass = invokeType.element2;
       displayName = "${invokeClass.name}.${element.displayName}";
     }
-    var library = element is LibraryElement ? element : element.library;
     var message = _deprecatedMessage(element);
-    if (message == null || message.isEmpty) {
-      _errorReporter.reportErrorForNode(
-        _isLibraryInWorkspacePackage(library)
-            ? HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE
-            : HintCode.DEPRECATED_MEMBER_USE,
-        errorNode,
-        [displayName],
-      );
-    } else {
-      _errorReporter.reportErrorForNode(
-        _isLibraryInWorkspacePackage(library)
-            ? HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE
-            : HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE,
-        errorNode,
-        [displayName, message],
-      );
-    }
+    reportError(errorNode, element, displayName, message);
   }
 
   void _invocationArguments(Element? element, ArgumentList arguments) {
@@ -213,15 +194,6 @@
     }
   }
 
-  bool _isLibraryInWorkspacePackage(LibraryElement? library) {
-    // Better to not make a big claim that they _are_ in the same package,
-    // if we were unable to determine what package [_currentLibrary] is in.
-    if (_workspacePackage == null || library == null) {
-      return false;
-    }
-    return _workspacePackage!.contains(library.source);
-  }
-
   void _simpleIdentifier(SimpleIdentifier identifier) {
     _checkForDeprecated(identifier.staticElement, identifier);
   }
@@ -268,11 +240,11 @@
   /// Return `true` if [element] is a [ParameterElement] declared in [node].
   static bool _isLocalParameter(Element? element, AstNode? node) {
     if (element is ParameterElement) {
-      var definingFunction = element.enclosingElement3 as ExecutableElement;
+      var definingFunction = element.enclosingElement as ExecutableElement;
 
       for (; node != null; node = node.parent) {
         if (node is ConstructorDeclaration) {
-          if (node.declaredElement2 == definingFunction) {
+          if (node.declaredElement == definingFunction) {
             return true;
           }
         } else if (node is FunctionExpression) {
@@ -280,7 +252,7 @@
             return true;
           }
         } else if (node is MethodDeclaration) {
-          if (node.declaredElement2 == definingFunction) {
+          if (node.declaredElement == definingFunction) {
             return true;
           }
         }
@@ -323,3 +295,43 @@
     }
   }
 }
+
+class DeprecatedMemberUseVerifier extends BaseDeprecatedMemberUseVerifier {
+  final WorkspacePackage? _workspacePackage;
+  final ErrorReporter _errorReporter;
+
+  DeprecatedMemberUseVerifier(this._workspacePackage, this._errorReporter);
+
+  @override
+  void reportError(
+      AstNode errorNode, Element element, String displayName, String? message) {
+    var library = element is LibraryElement ? element : element.library;
+
+    if (message == null || message.isEmpty) {
+      _errorReporter.reportErrorForNode(
+        _isLibraryInWorkspacePackage(library)
+            ? HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE
+            : HintCode.DEPRECATED_MEMBER_USE,
+        errorNode,
+        [displayName],
+      );
+    } else {
+      _errorReporter.reportErrorForNode(
+        _isLibraryInWorkspacePackage(library)
+            ? HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE
+            : HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE,
+        errorNode,
+        [displayName, message],
+      );
+    }
+  }
+
+  bool _isLibraryInWorkspacePackage(LibraryElement? library) {
+    // Better to not make a big claim that they _are_ in the same package,
+    // if we were unable to determine what package [_currentLibrary] is in.
+    if (_workspacePackage == null || library == null) {
+      return false;
+    }
+    return _workspacePackage!.contains(library.source);
+  }
+}
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index 163872a..dd5b5de 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -45,12 +45,12 @@
   }
 
   void checkClass(ClassDeclaration node) {
-    _checkClassMembers(node.declaredElement2!, node.members);
+    _checkClassMembers(node.declaredElement!, node.members);
   }
 
   /// Check that there are no members with the same name.
   void checkEnum(EnumDeclaration node) {
-    var enumElement = node.declaredElement2!;
+    var enumElement = node.declaredElement!;
     var enumName = enumElement.name;
 
     var constructorNames = <String>{};
@@ -60,15 +60,15 @@
     var staticSetters = <String, Element>{};
 
     for (EnumConstantDeclaration constant in node.constants) {
-      _checkDuplicateIdentifier(staticGetters, constant.name2,
-          element: constant.declaredElement2!);
-      _checkValuesDeclarationInEnum(constant.name2);
+      _checkDuplicateIdentifier(staticGetters, constant.name,
+          element: constant.declaredElement!);
+      _checkValuesDeclarationInEnum(constant.name);
     }
 
     for (var member in node.members) {
       if (member is ConstructorDeclaration) {
         if (member.returnType.name == enumElement.name) {
-          var name = member.declaredElement2!.name;
+          var name = member.declaredElement!.name;
           if (!constructorNames.add(name)) {
             if (name.isEmpty) {
               _errorReporter.reportErrorForName(
@@ -86,11 +86,11 @@
         }
       } else if (member is FieldDeclaration) {
         for (var field in member.fields.variables) {
-          var identifier = field.name2;
+          var identifier = field.name;
           _checkDuplicateIdentifier(
             member.isStatic ? staticGetters : instanceGetters,
             identifier,
-            element: field.declaredElement2!,
+            element: field.declaredElement!,
             setterScope: member.isStatic ? staticSetters : instanceSetters,
           );
           _checkValuesDeclarationInEnum(identifier);
@@ -98,12 +98,12 @@
       } else if (member is MethodDeclaration) {
         _checkDuplicateIdentifier(
           member.isStatic ? staticGetters : instanceGetters,
-          member.name2,
-          element: member.declaredElement2!,
+          member.name,
+          element: member.declaredElement!,
           setterScope: member.isStatic ? staticSetters : instanceSetters,
         );
         if (!(member.isStatic && member.isSetter)) {
-          _checkValuesDeclarationInEnum2(member.name2);
+          _checkValuesDeclarationInEnum2(member.name);
         }
       }
     }
@@ -111,15 +111,15 @@
     if (enumName == 'values') {
       _errorReporter.reportErrorForToken(
         CompileTimeErrorCode.ENUM_WITH_NAME_VALUES,
-        node.name2,
+        node.name,
       );
     }
 
     for (var constant in node.constants) {
-      if (constant.name2.lexeme == enumName) {
+      if (constant.name.lexeme == enumName) {
         _errorReporter.reportErrorForToken(
           CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
-          constant.name2,
+          constant.name,
         );
       }
     }
@@ -150,7 +150,7 @@
             [
               enumElement.displayName,
               baseName,
-              inherited.enclosingElement3.displayName,
+              inherited.enclosingElement.displayName,
             ],
           );
         }
@@ -177,7 +177,7 @@
             [
               enumElement.displayName,
               baseName,
-              inherited.enclosingElement3.displayName,
+              inherited.enclosingElement.displayName,
             ],
           );
         }
@@ -195,19 +195,19 @@
     for (var member in node.members) {
       if (member is FieldDeclaration) {
         for (var field in member.fields.variables) {
-          var identifier = field.name2;
+          var identifier = field.name;
           _checkDuplicateIdentifier(
             member.isStatic ? staticGetters : instanceGetters,
             identifier,
-            element: field.declaredElement2!,
+            element: field.declaredElement!,
             setterScope: member.isStatic ? staticSetters : instanceSetters,
           );
         }
       } else if (member is MethodDeclaration) {
         _checkDuplicateIdentifier(
           member.isStatic ? staticGetters : instanceGetters,
-          member.name2,
-          element: member.declaredElement2!,
+          member.name,
+          element: member.declaredElement!,
           setterScope: member.isStatic ? staticSetters : instanceSetters,
         );
       }
@@ -218,7 +218,7 @@
       if (member is FieldDeclaration) {
         if (member.isStatic) {
           for (var field in member.fields.variables) {
-            var identifier = field.name2;
+            var identifier = field.name;
             var name = identifier.lexeme;
             if (instanceGetters.containsKey(name) ||
                 instanceSetters.containsKey(name)) {
@@ -232,7 +232,7 @@
         }
       } else if (member is MethodDeclaration) {
         if (member.isStatic) {
-          var identifier = member.name2;
+          var identifier = member.name;
           var name = identifier.lexeme;
           if (instanceGetters.containsKey(name) ||
               instanceSetters.containsKey(name)) {
@@ -252,13 +252,13 @@
   void checkForVariables(VariableDeclarationList node) {
     Map<String, Element> definedNames = HashMap<String, Element>();
     for (VariableDeclaration variable in node.variables) {
-      _checkDuplicateIdentifier(definedNames, variable.name2,
-          element: variable.declaredElement2!);
+      _checkDuplicateIdentifier(definedNames, variable.name,
+          element: variable.declaredElement!);
     }
   }
 
   void checkMixin(MixinDeclaration node) {
-    _checkClassMembers(node.declaredElement2!, node.members);
+    _checkClassMembers(node.declaredElement!, node.members);
   }
 
   /// Check that all of the parameters have unique names.
@@ -281,14 +281,14 @@
     for (Statement statement in statements) {
       if (statement is VariableDeclarationStatement) {
         for (VariableDeclaration variable in statement.variables.variables) {
-          _checkDuplicateIdentifier(definedNames, variable.name2,
-              element: variable.declaredElement2!);
+          _checkDuplicateIdentifier(definedNames, variable.name,
+              element: variable.declaredElement!);
         }
       } else if (statement is FunctionDeclarationStatement) {
         _checkDuplicateIdentifier(
           definedNames,
-          statement.functionDeclaration.name2,
-          element: statement.functionDeclaration.declaredElement2!,
+          statement.functionDeclaration.name,
+          element: statement.functionDeclaration.declaredElement!,
         );
       }
     }
@@ -298,8 +298,8 @@
   void checkTypeParameters(TypeParameterList node) {
     Map<String, Element> definedNames = HashMap<String, Element>();
     for (TypeParameter parameter in node.typeParameters) {
-      _checkDuplicateIdentifier(definedNames, parameter.name2,
-          element: parameter.declaredElement2!);
+      _checkDuplicateIdentifier(definedNames, parameter.name,
+          element: parameter.declaredElement!);
     }
   }
 
@@ -354,18 +354,18 @@
     }
     for (CompilationUnitMember member in node.declarations) {
       if (member is ExtensionDeclaration) {
-        var identifier = member.name2;
+        var identifier = member.name;
         if (identifier != null) {
           _checkDuplicateIdentifier(definedGetters, identifier,
-              element: member.declaredElement2!, setterScope: definedSetters);
+              element: member.declaredElement!, setterScope: definedSetters);
         }
       } else if (member is NamedCompilationUnitMember) {
-        _checkDuplicateIdentifier(definedGetters, member.name2,
-            element: member.declaredElement2!, setterScope: definedSetters);
+        _checkDuplicateIdentifier(definedGetters, member.name,
+            element: member.declaredElement!, setterScope: definedSetters);
       } else if (member is TopLevelVariableDeclaration) {
         for (VariableDeclaration variable in member.variables.variables) {
-          _checkDuplicateIdentifier(definedGetters, variable.name2,
-              element: variable.declaredElement2!, setterScope: definedSetters);
+          _checkDuplicateIdentifier(definedGetters, variable.name,
+              element: variable.declaredElement!, setterScope: definedSetters);
         }
       }
     }
@@ -385,7 +385,7 @@
           // [member] is erroneous; do not count it as a possible duplicate.
           continue;
         }
-        var name = member.name2?.lexeme ?? '';
+        var name = member.name?.lexeme ?? '';
         if (name == 'new') {
           name = '';
         }
@@ -403,16 +403,16 @@
         for (VariableDeclaration field in member.fields.variables) {
           _checkDuplicateIdentifier(
             member.isStatic ? staticGetters : instanceGetters,
-            field.name2,
-            element: field.declaredElement2!,
+            field.name,
+            element: field.declaredElement!,
             setterScope: member.isStatic ? staticSetters : instanceSetters,
           );
         }
       } else if (member is MethodDeclaration) {
         _checkDuplicateIdentifier(
           member.isStatic ? staticGetters : instanceGetters,
-          member.name2,
-          element: member.declaredElement2!,
+          member.name,
+          element: member.declaredElement!,
           setterScope: member.isStatic ? staticSetters : instanceSetters,
         );
       }
@@ -431,7 +431,7 @@
       if (member is FieldDeclaration) {
         if (member.isStatic) {
           for (VariableDeclaration field in member.fields.variables) {
-            final identifier = field.name2;
+            final identifier = field.name;
             String name = identifier.lexeme;
             if (instanceGetters.containsKey(name) ||
                 instanceSetters.containsKey(name)) {
@@ -445,7 +445,7 @@
         }
       } else if (member is MethodDeclaration) {
         if (member.isStatic) {
-          final identifier = member.name2;
+          final identifier = member.name;
           String name = identifier.lexeme;
           if (instanceGetters.containsKey(name) ||
               instanceSetters.containsKey(name)) {
diff --git a/pkg/analyzer/lib/src/error/getter_setter_types_verifier.dart b/pkg/analyzer/lib/src/error/getter_setter_types_verifier.dart
index cb76e1b..0f51c27 100644
--- a/pkg/analyzer/lib/src/error/getter_setter_types_verifier.dart
+++ b/pkg/analyzer/lib/src/error/getter_setter_types_verifier.dart
@@ -53,23 +53,23 @@
           var setterType = setter.parameters[0].type;
           if (!_match(getterType, setterType)) {
             Element errorElement;
-            if (getter.enclosingElement3 == element) {
+            if (getter.enclosingElement == element) {
               errorElement = getter;
-            } else if (setter.enclosingElement3 == element) {
+            } else if (setter.enclosingElement == element) {
               errorElement = setter;
             } else {
               errorElement = element;
             }
 
             var getterName = getter.displayName;
-            if (getter.enclosingElement3 != element) {
-              var getterClassName = getter.enclosingElement3.displayName;
+            if (getter.enclosingElement != element) {
+              var getterClassName = getter.enclosingElement.displayName;
               getterName = '$getterClassName.$getterName';
             }
 
             var setterName = setter.displayName;
-            if (setter.enclosingElement3 != element) {
-              var setterClassName = setter.enclosingElement3.displayName;
+            if (setter.enclosingElement != element) {
+              var setterClassName = setter.enclosingElement.displayName;
               setterName = '$setterClassName.$setterName';
             }
 
diff --git a/pkg/analyzer/lib/src/error/imports_verifier.dart b/pkg/analyzer/lib/src/error/imports_verifier.dart
index 7574408..c45bf62 100644
--- a/pkg/analyzer/lib/src/error/imports_verifier.dart
+++ b/pkg/analyzer/lib/src/error/imports_verifier.dart
@@ -94,7 +94,7 @@
 
   void _recordIfExtensionMember(Element? element) {
     if (element != null) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement is ExtensionElement) {
         _recordUsedExtension(enclosingElement);
       }
@@ -165,7 +165,7 @@
     if (_recordPrefixMap(identifier, element)) {
       return;
     }
-    var enclosingElement = element.enclosingElement3;
+    var enclosingElement = element.enclosingElement;
     if (enclosingElement is CompilationUnitElement) {
       _recordUsedElement(element);
     } else if (enclosingElement is ExtensionElement) {
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index e17c257..6e1b65c 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -45,8 +45,8 @@
           reporter: _reporter,
           featureSet: unit.featureSet,
           library: library,
-          classNameToken: declaration.name2,
-          classElement: declaration.declaredElement2!,
+          classNameToken: declaration.name,
+          classElement: declaration.declaredElement!,
           implementsClause: declaration.implementsClause,
           members: declaration.members,
           superclass: declaration.extendsClause?.superclass,
@@ -60,8 +60,8 @@
           reporter: _reporter,
           featureSet: unit.featureSet,
           library: library,
-          classNameToken: declaration.name2,
-          classElement: declaration.declaredElement2!,
+          classNameToken: declaration.name,
+          classElement: declaration.declaredElement!,
           implementsClause: declaration.implementsClause,
           superclass: declaration.superclass,
           withClause: declaration.withClause,
@@ -74,8 +74,8 @@
           reporter: _reporter,
           featureSet: unit.featureSet,
           library: library,
-          classNameToken: declaration.name2,
-          classElement: declaration.declaredElement2!,
+          classNameToken: declaration.name,
+          classElement: declaration.declaredElement!,
           implementsClause: declaration.implementsClause,
           members: declaration.members,
           withClause: declaration.withClause,
@@ -88,8 +88,8 @@
           reporter: _reporter,
           featureSet: unit.featureSet,
           library: library,
-          classNameToken: declaration.name2,
-          classElement: declaration.declaredElement2!,
+          classNameToken: declaration.name,
+          classElement: declaration.declaredElement!,
           implementsClause: declaration.implementsClause,
           members: declaration.members,
           onClause: declaration.onClause,
@@ -109,7 +109,7 @@
   /// Returns [ExecutableElement] members that are in the interface of the
   /// given class, but don't have concrete implementations.
   static List<ExecutableElement> missingOverrides(ClassDeclaration node) {
-    return _missingOverrides[node.name2] ?? const [];
+    return _missingOverrides[node.name] ?? const [];
   }
 }
 
@@ -215,14 +215,14 @@
       if (member is FieldDeclaration) {
         var fieldList = member.fields;
         for (var field in fieldList.variables) {
-          var fieldElement = field.declaredElement2 as FieldElement;
-          _checkDeclaredMember(field.name2, libraryUri, fieldElement.getter);
-          _checkDeclaredMember(field.name2, libraryUri, fieldElement.setter);
+          var fieldElement = field.declaredElement as FieldElement;
+          _checkDeclaredMember(field.name, libraryUri, fieldElement.getter);
+          _checkDeclaredMember(field.name, libraryUri, fieldElement.setter);
           if (!member.isStatic && classElement is! EnumElement) {
-            _checkIllegalEnumValuesDeclaration(field.name2);
+            _checkIllegalEnumValuesDeclaration(field.name);
           }
           if (!member.isStatic) {
-            _checkIllegalConcreteEnumMemberDeclaration(field.name2);
+            _checkIllegalConcreteEnumMemberDeclaration(field.name);
           }
         }
       } else if (member is MethodDeclaration) {
@@ -231,13 +231,13 @@
           continue;
         }
 
-        _checkDeclaredMember(member.name2, libraryUri, member.declaredElement2,
+        _checkDeclaredMember(member.name, libraryUri, member.declaredElement,
             methodParameterNodes: member.parameters?.parameters);
         if (!(member.isStatic || member.isAbstract || member.isSetter)) {
-          _checkIllegalConcreteEnumMemberDeclaration(member.name2);
+          _checkIllegalConcreteEnumMemberDeclaration(member.name);
         }
         if (!member.isStatic && classElement is! EnumElement) {
-          _checkIllegalEnumValuesDeclaration(member.name2);
+          _checkIllegalEnumValuesDeclaration(member.name);
         }
       }
     }
@@ -250,7 +250,8 @@
       errorReporter: reporter,
     ).checkInterface(classElement, interface);
 
-    if (!(classElement as ClassElement).isAbstract) {
+    if (classElement is ClassElement && !classElement.isAbstract ||
+        classElement is EnumElement) {
       List<ExecutableElement>? inheritedAbstract;
 
       for (var name in interface.map.keys) {
@@ -413,7 +414,8 @@
         typeElement.isDartCoreEnum &&
         library.featureSet.isEnabled(Feature.enhanced_enums)) {
       if (classElement is ClassElement && classElement.isAbstract ||
-          classElement is EnumElement) {
+          classElement is EnumElement ||
+          classElement is MixinElement) {
         return false;
       }
       reporter.reportErrorForNode(
@@ -555,7 +557,7 @@
                     .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
                 derivedOptionalNodes[i],
                 [
-                  baseExecutable.enclosingElement3.displayName,
+                  baseExecutable.enclosingElement.displayName,
                   baseExecutable.displayName,
                   name
                 ],
@@ -584,7 +586,7 @@
                   .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
               derivedOptionalNodes[i],
               [
-                baseExecutable.enclosingElement3.displayName,
+                baseExecutable.enclosingElement.displayName,
                 baseExecutable.displayName
               ],
             );
@@ -644,12 +646,10 @@
     path.add(element);
 
     // n-case
-    if (element is ClassElement) {
-      var supertype = element.supertype;
-      if (supertype != null &&
-          _checkForRecursiveInterfaceInheritance(supertype.element2, path)) {
-        return true;
-      }
+    final supertype = element.supertype;
+    if (supertype != null &&
+        _checkForRecursiveInterfaceInheritance(supertype.element2, path)) {
+      return true;
     }
 
     for (InterfaceType type in element.mixins) {
@@ -681,7 +681,8 @@
       final classElement = this.classElement;
       if (classElement is ClassElementImpl &&
               !classElement.isDartCoreEnumImpl ||
-          classElement is EnumElementImpl) {
+          classElement is EnumElementImpl ||
+          classElement is MixinElementImpl) {
         if (const {'index', 'hashCode', '=='}.contains(name.lexeme)) {
           reporter.reportErrorForToken(
             CompileTimeErrorCode.ILLEGAL_CONCRETE_ENUM_MEMBER_DECLARATION,
@@ -710,8 +711,8 @@
       ) {
         var member = concreteMap[Name(libraryUri, memberName)];
         if (member != null) {
-          var enclosingClass = member.enclosingElement3;
-          if (enclosingClass is ClassElement && filter(enclosingClass)) {
+          var enclosingClass = member.enclosingElement as InterfaceElement;
+          if (enclosingClass is! ClassElement || filter(enclosingClass)) {
             reporter.reportErrorForToken(
               CompileTimeErrorCode.ILLEGAL_CONCRETE_ENUM_MEMBER_INHERITANCE,
               classNameToken,
@@ -751,7 +752,7 @@
         reporter.reportErrorForToken(
           CompileTimeErrorCode.ILLEGAL_ENUM_VALUES_INHERITANCE,
           classNameToken,
-          [inherited.enclosingElement3.name!],
+          [inherited.enclosingElement.name!],
         );
       }
     }
@@ -760,10 +761,8 @@
   /// Return the error code that should be used when the given class [element]
   /// references itself directly.
   ErrorCode _getRecursiveErrorCode(InterfaceElement element) {
-    if (element is ClassElement) {
-      if (element.supertype?.element2 == classElement) {
-        return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS;
-      }
+    if (element.supertype?.element2 == classElement) {
+      return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS;
     }
 
     if (element is MixinElement) {
@@ -806,15 +805,15 @@
 
     for (var member in members) {
       if (member is MethodDeclaration) {
-        var displayName = member.name2.lexeme;
-        var name2 = displayName;
+        var displayName = member.name.lexeme;
+        var name = displayName;
         if (member.isSetter) {
-          name2 += '=';
+          name += '=';
         }
-        if (checkMemberNameCombo(member, name2, displayName)) return true;
+        if (checkMemberNameCombo(member, name, displayName)) return true;
       } else if (member is FieldDeclaration) {
         for (var variableDeclaration in member.fields.variables) {
-          var name = variableDeclaration.name2.lexeme;
+          var name = variableDeclaration.name.lexeme;
           if (checkMemberNameCombo(member, name, name)) return true;
           if (!variableDeclaration.isFinal) {
             if (checkMemberNameCombo(member, '$name=', name)) return true;
@@ -838,13 +837,13 @@
         token,
         [
           name.name,
-          conflict.getter.enclosingElement3.name!,
-          conflict.method.enclosingElement3.name!
+          conflict.getter.enclosingElement.name!,
+          conflict.method.enclosingElement.name!
         ],
       );
     } else if (conflict is CandidatesConflict) {
       var candidatesStr = conflict.candidates.map((candidate) {
-        var className = candidate.enclosingElement3.name;
+        var className = candidate.enclosingElement.name;
         var typeStr = candidate.type.getDisplayString(
           withNullability: _isNonNullableByDefault,
         );
@@ -880,7 +879,7 @@
       }
 
       var elementName = element.displayName;
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       var enclosingName = enclosingElement.displayName;
       var description = "$prefix$enclosingName.$elementName";
 
@@ -929,14 +928,14 @@
   }
 
   bool _reportNoCombinedSuperSignature(MethodDeclaration node) {
-    var element = node.declaredElement2;
+    var element = node.declaredElement;
     if (element is MethodElementImpl) {
       var inferenceError = element.typeInferenceError;
       if (inferenceError?.kind ==
           TopLevelInferenceErrorKind.overrideNoCombinedSuperSignature) {
         reporter.reportErrorForToken(
           CompileTimeErrorCode.NO_COMBINED_SUPER_SIGNATURE,
-          node.name2,
+          node.name,
           [
             classElement.name,
             inferenceError!.arguments[0],
diff --git a/pkg/analyzer/lib/src/error/must_call_super_verifier.dart b/pkg/analyzer/lib/src/error/must_call_super_verifier.dart
index c473cbf..7bbe7f8 100644
--- a/pkg/analyzer/lib/src/error/must_call_super_verifier.dart
+++ b/pkg/analyzer/lib/src/error/must_call_super_verifier.dart
@@ -20,7 +20,7 @@
     if (node.isStatic || node.isAbstract) {
       return;
     }
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     var overridden = _findOverriddenMemberWithMustCallSuper(element);
     if (overridden == null) {
       return;
@@ -28,17 +28,21 @@
 
     if (element is MethodElement && _hasConcreteSuperMethod(element)) {
       _verifySuperIsCalled(
-          node, overridden.name, overridden.enclosingElement3.name);
+          node, overridden.name, overridden.enclosingElement.name);
       return;
     }
 
-    var enclosingElement = element.enclosingElement3 as ClassElement;
+    var enclosingElement = element.enclosingElement;
+    if (enclosingElement is! ClassElement) {
+      return;
+    }
+
     if (element is PropertyAccessorElement && element.isGetter) {
       var inheritedConcreteGetter = enclosingElement
           .lookUpInheritedConcreteGetter(element.name, element.library);
       if (inheritedConcreteGetter != null) {
         _verifySuperIsCalled(
-            node, overridden.name, overridden.enclosingElement3.name);
+            node, overridden.name, overridden.enclosingElement.name);
       }
       return;
     }
@@ -53,7 +57,7 @@
         if (name.endsWith('=')) {
           name = name.substring(0, name.length - 1);
         }
-        _verifySuperIsCalled(node, name, overridden.enclosingElement3.name);
+        _verifySuperIsCalled(node, name, overridden.enclosingElement.name);
       }
     }
   }
@@ -69,10 +73,10 @@
   ExecutableElement? _findOverriddenMemberWithMustCallSuper(
       ExecutableElement element) {
     //Element member = node.declaredElement;
-    if (element.enclosingElement3 is! ClassElement) {
+    if (element.enclosingElement is! InterfaceElement) {
       return null;
     }
-    var classElement = element.enclosingElement3 as InterfaceElement;
+    var classElement = element.enclosingElement as InterfaceElement;
     String name = element.name;
 
     // Walk up the type hierarchy from [classElement], ignoring direct
@@ -81,9 +85,7 @@
 
     void addToQueue(InterfaceElement element) {
       superclasses.addAll(element.mixins.map((i) => i.element2));
-      if (element is ClassElement) {
-        superclasses.add(element.supertype?.element2);
-      }
+      superclasses.add(element.supertype?.element2);
       if (element is MixinElement) {
         superclasses
             .addAll(element.superclassConstraints.map((i) => i.element2));
@@ -116,7 +118,7 @@
 
   /// Returns whether [node] overrides a concrete method.
   bool _hasConcreteSuperMethod(ExecutableElement element) {
-    var classElement = element.enclosingElement3 as ClassElement;
+    var classElement = element.enclosingElement as InterfaceElement;
     String name = element.name;
 
     if (classElement.supertype.isConcrete(name)) {
@@ -127,7 +129,8 @@
       return true;
     }
 
-    if (classElement.superclassConstraints.any((c) => c.isConcrete(name))) {
+    if (classElement is MixinElement &&
+        classElement.superclassConstraints.any((c) => c.isConcrete(name))) {
       return true;
     }
 
@@ -136,12 +139,12 @@
 
   void _verifySuperIsCalled(MethodDeclaration node, String methodName,
       String? overriddenEnclosingName) {
-    var declaredElement = node.declaredElement2 as ExecutableElementImpl;
+    var declaredElement = node.declaredElement as ExecutableElementImpl;
     if (!declaredElement.invokesSuperSelf) {
       // Overridable elements are always enclosed in named elements, so it is
       // safe to assume [overriddenEnclosingName] is non-`null`.
       _errorReporter.reportErrorForToken(
-          HintCode.MUST_CALL_SUPER, node.name2, [overriddenEnclosingName!]);
+          HintCode.MUST_CALL_SUPER, node.name, [overriddenEnclosingName!]);
     }
     return;
   }
diff --git a/pkg/analyzer/lib/src/error/override_verifier.dart b/pkg/analyzer/lib/src/error/override_verifier.dart
index 5a50cf48..dc2004a 100644
--- a/pkg/analyzer/lib/src/error/override_verifier.dart
+++ b/pkg/analyzer/lib/src/error/override_verifier.dart
@@ -31,14 +31,14 @@
 
   @override
   void visitClassDeclaration(ClassDeclaration node) {
-    _currentClass = node.declaredElement2;
+    _currentClass = node.declaredElement;
     super.visitClassDeclaration(node);
     _currentClass = null;
   }
 
   @override
   void visitEnumDeclaration(EnumDeclaration node) {
-    _currentClass = node.declaredElement2;
+    _currentClass = node.declaredElement;
     super.visitEnumDeclaration(node);
     _currentClass = null;
   }
@@ -46,7 +46,7 @@
   @override
   void visitFieldDeclaration(FieldDeclaration node) {
     for (VariableDeclaration field in node.fields.variables) {
-      var fieldElement = field.declaredElement2 as FieldElement;
+      var fieldElement = field.declaredElement as FieldElement;
       if (fieldElement.hasOverride) {
         var getter = fieldElement.getter;
         if (getter != null && _isOverride(getter)) continue;
@@ -56,7 +56,7 @@
 
         _errorReporter.reportErrorForToken(
           HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD,
-          field.name2,
+          field.name,
         );
       }
     }
@@ -64,23 +64,23 @@
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     if (element.hasOverride && !_isOverride(element)) {
       if (element is MethodElement) {
         _errorReporter.reportErrorForToken(
           HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD,
-          node.name2,
+          node.name,
         );
       } else if (element is PropertyAccessorElement) {
         if (element.isGetter) {
           _errorReporter.reportErrorForToken(
             HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER,
-            node.name2,
+            node.name,
           );
         } else {
           _errorReporter.reportErrorForToken(
             HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER,
-            node.name2,
+            node.name,
           );
         }
       }
@@ -89,7 +89,7 @@
 
   @override
   void visitMixinDeclaration(MixinDeclaration node) {
-    _currentClass = node.declaredElement2;
+    _currentClass = node.declaredElement;
     super.visitMixinDeclaration(node);
     _currentClass = null;
   }
diff --git a/pkg/analyzer/lib/src/error/required_parameters_verifier.dart b/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
index 51cc6f1..8dbae46 100644
--- a/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
+++ b/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
@@ -39,7 +39,7 @@
     _check(
       parameters: node.constructorElement?.parameters,
       arguments: node.arguments?.argumentList.arguments ?? <Expression>[],
-      errorNode: node.name2,
+      errorNode: node.name,
     );
   }
 
@@ -259,7 +259,7 @@
   }
 
   static SimpleIdentifier? _ifClassElement(SimpleIdentifier? node) {
-    return node?.staticElement is ClassElement ? node : null;
+    return node?.staticElement is InterfaceElement ? node : null;
   }
 
   static SimpleIdentifier? _ifConstructorElement(SimpleIdentifier? node) {
diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
index 3d4b8bd..56b58ed 100644
--- a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
+++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
@@ -37,7 +37,7 @@
     List<TypeParameterElement> typeParameters;
     if (classElement is TypeAliasElement) {
       typeParameters = classElement.typeParameters;
-    } else if (classElement is ClassElement) {
+    } else if (classElement is InterfaceElement) {
       typeParameters = classElement.typeParameters;
     } else {
       return;
@@ -97,7 +97,7 @@
       return;
     }
 
-    var enumElement = constructorElement.enclosingElement3;
+    var enumElement = constructorElement.enclosingElement;
     var typeParameters = enumElement.typeParameters;
 
     var typeArgumentList = node.arguments?.typeArguments;
@@ -131,7 +131,7 @@
       bound = substitution.substituteType(bound);
 
       if (!_typeSystem.isSubtypeOf(typeArgument, bound)) {
-        final errorTarget = typeArgumentNodes?[i] ?? node.name2;
+        final errorTarget = typeArgumentNodes?[i] ?? node.name;
         _errorReporter.reportErrorForOffset(
           CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
           errorTarget.offset,
diff --git a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
index 140b81d..fcbbb32 100644
--- a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
+++ b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
@@ -23,7 +23,7 @@
   final UsedLocalElements usedElements = UsedLocalElements();
 
   final LibraryElement _enclosingLibrary;
-  ClassElement? _enclosingClass;
+  InterfaceElement? _enclosingClass;
   ExecutableElement? _enclosingExec;
 
   /// Non-null when the visitor is inside an [IsExpression]'s type.
@@ -72,7 +72,7 @@
   void visitClassDeclaration(ClassDeclaration node) {
     var enclosingClassOld = _enclosingClass;
     try {
-      _enclosingClass = node.declaredElement2;
+      _enclosingClass = node.declaredElement;
       super.visitClassDeclaration(node);
     } finally {
       _enclosingClass = enclosingClassOld;
@@ -81,7 +81,7 @@
 
   @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     var redirectedConstructor = node.redirectedConstructor;
     if (redirectedConstructor != null) {
       var redirectedElement = redirectedConstructor.staticElement;
@@ -126,7 +126,7 @@
   void visitFunctionDeclaration(FunctionDeclaration node) {
     var enclosingExecOld = _enclosingExec;
     try {
-      _enclosingExec = node.declaredElement2;
+      _enclosingExec = node.declaredElement;
       super.visitFunctionDeclaration(node);
     } finally {
       _enclosingExec = enclosingExecOld;
@@ -176,7 +176,7 @@
   void visitMethodDeclaration(MethodDeclaration node) {
     var enclosingExecOld = _enclosingExec;
     try {
-      _enclosingExec = node.declaredElement2;
+      _enclosingExec = node.declaredElement;
       super.visitMethodDeclaration(node);
     } finally {
       _enclosingExec = enclosingExecOld;
@@ -247,7 +247,7 @@
                   parent is ConstructorName &&
                   grandparent is InstanceCreationExpression) ||
               // unnamed constructor
-              (element is ClassElement &&
+              (element is InterfaceElement &&
                   grandparent is ConstructorName &&
                   grandparent.parent is InstanceCreationExpression);
       if (element is ExecutableElement &&
@@ -257,7 +257,7 @@
           usedElements.addElement(parameter);
         }
       }
-      var enclosingElement = element?.enclosingElement3;
+      var enclosingElement = element?.enclosingElement;
       if (element == null) {
         if (isIdentifierRead) {
           usedElements.unresolvedReadMembers.add(node.name);
@@ -270,7 +270,7 @@
             usedElements.readMembers.add(field.getter!);
           }
         }
-      } else if ((enclosingElement is ClassElement ||
+      } else if ((enclosingElement is InterfaceElement ||
               enclosingElement is ExtensionElement) &&
           !identical(element, _enclosingExec)) {
         usedElements.members.add(element);
@@ -334,7 +334,7 @@
     }
     // Ignore places where the element is not actually used.
     if (parent is NamedType) {
-      if (element is ClassElement) {
+      if (element is InterfaceElement) {
         var enclosingVariableDeclaration = _enclosingVariableDeclaration;
         if (enclosingVariableDeclaration != null) {
           // If it's a field's type, it still counts as used.
@@ -455,8 +455,14 @@
       : _libraryUri = library.source.uri;
 
   @override
+  void visitCatchClauseParameter(CatchClauseParameter node) {
+    _visitLocalVariableElement(node.declaredElement!);
+    super.visitCatchClauseParameter(node);
+  }
+
+  @override
   void visitClassDeclaration(ClassDeclaration node) {
-    final declaredElement = node.declaredElement2!;
+    final declaredElement = node.declaredElement!;
     _visitClassElement(declaredElement);
 
     super.visitClassDeclaration(node);
@@ -464,8 +470,8 @@
 
   @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
-    if (node.name2 != null) {
-      final declaredElement = node.declaredElement2!;
+    if (node.name != null) {
+      final declaredElement = node.declaredElement!;
       _visitConstructorElement(declaredElement);
     }
 
@@ -473,8 +479,14 @@
   }
 
   @override
+  void visitDeclaredIdentifier(DeclaredIdentifier node) {
+    _visitLocalVariableElement(node.declaredElement!);
+    super.visitDeclaredIdentifier(node);
+  }
+
+  @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    final declaredElement = node.declaredElement2 as FieldElement;
+    final declaredElement = node.declaredElement as FieldElement;
     _visitFieldElement(declaredElement);
 
     super.visitEnumConstantDeclaration(node);
@@ -482,13 +494,24 @@
 
   @override
   void visitEnumDeclaration(EnumDeclaration node) {
-    final declaredElement = node.declaredElement2!;
+    final declaredElement = node.declaredElement!;
     _visitClassElement(declaredElement);
 
     super.visitEnumDeclaration(node);
   }
 
   @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    for (final field in node.fields.variables) {
+      _visitFieldElement(
+        field.declaredElement as FieldElement,
+      );
+    }
+
+    super.visitFieldDeclaration(node);
+  }
+
+  @override
   void visitFormalParameterList(FormalParameterList node) {
     for (var element in node.parameterElements) {
       if (!_isUsedElement(element!)) {
@@ -500,8 +523,19 @@
   }
 
   @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    for (final variable in node.variables.variables) {
+      _visitLocalVariableElement(
+        variable.declaredElement as LocalVariableElement,
+      );
+    }
+
+    super.visitForPartsWithDeclarations(node);
+  }
+
+  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
-    final declaredElement = node.declaredElement2;
+    final declaredElement = node.declaredElement;
     if (declaredElement is FunctionElement) {
       _visitFunctionElement(declaredElement);
     } else if (declaredElement is PropertyAccessorElement) {
@@ -513,7 +547,7 @@
 
   @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    final declaredElement = node.declaredElement2!;
+    final declaredElement = node.declaredElement!;
     _visitTypeAliasElement(declaredElement);
 
     super.visitFunctionTypeAlias(node);
@@ -521,7 +555,7 @@
 
   @override
   void visitGenericTypeAlias(GenericTypeAlias node) {
-    final declaredElement = node.declaredElement2 as TypeAliasElement;
+    final declaredElement = node.declaredElement as TypeAliasElement;
     _visitTypeAliasElement(declaredElement);
 
     super.visitGenericTypeAlias(node);
@@ -529,7 +563,7 @@
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
-    final declaredElement = node.declaredElement2;
+    final declaredElement = node.declaredElement;
     if (declaredElement is MethodElement) {
       _visitMethodElement(declaredElement);
     } else if (declaredElement is PropertyAccessorElement) {
@@ -541,7 +575,7 @@
 
   @override
   void visitMixinDeclaration(MixinDeclaration node) {
-    final declaredElement = node.declaredElement2!;
+    final declaredElement = node.declaredElement!;
     _visitClassElement(declaredElement);
 
     super.visitMixinDeclaration(node);
@@ -551,14 +585,14 @@
   void visitSimpleIdentifier(SimpleIdentifier node) {
     if (node.inDeclarationContext()) {
       var element = node.staticElement;
-      if (element is ClassElement) {
-        _visitClassElement(element);
-      } else if (element is ConstructorElement) {
+      if (element is ConstructorElement) {
         _visitConstructorElement(element);
       } else if (element is FieldElement) {
         _visitFieldElement(element);
       } else if (element is FunctionElement) {
         _visitFunctionElement(element);
+      } else if (element is InterfaceElement) {
+        _visitClassElement(element);
       } else if (element is LocalVariableElement) {
         _visitLocalVariableElement(element);
       } else if (element is MethodElement) {
@@ -573,6 +607,28 @@
     }
   }
 
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    for (final variable in node.variables.variables) {
+      _visitTopLevelVariableElement(
+        variable.declaredElement as TopLevelVariableElement,
+      );
+    }
+
+    super.visitTopLevelVariableDeclaration(node);
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    for (final variable in node.variables.variables) {
+      _visitLocalVariableElement(
+        variable.declaredElement as LocalVariableElement,
+      );
+    }
+
+    super.visitVariableDeclarationStatement(node);
+  }
+
   /// Returns whether the name of [element] consists only of underscore
   /// characters.
   bool _isNamedUnderscore(LocalVariableElement element) {
@@ -587,7 +643,7 @@
   }
 
   bool _isPrivateClassOrExtension(Element element) =>
-      (element is ClassElement || element is ExtensionElement) &&
+      (element is InterfaceElement || element is ExtensionElement) &&
       element.isPrivate;
 
   /// Returns whether [element] is accessible outside of the library in which
@@ -596,14 +652,14 @@
     if (element.isPrivate) {
       return false;
     }
-    var enclosingElement = element.enclosingElement3;
+    var enclosingElement = element.enclosingElement;
 
     if (enclosingElement is EnumElement) {
       if (element is ConstructorElement && element.isGenerative) {
         return false;
       }
     }
-    if (enclosingElement is ClassElement) {
+    if (enclosingElement is InterfaceElement) {
       if (enclosingElement.isPrivate) {
         if (element.isStatic || element is ConstructorElement) {
           return false;
@@ -624,7 +680,7 @@
     bool elementIsStaticVariable =
         element is VariableElement && element.isStatic;
     if (element.isPublic) {
-      if (_isPrivateClassOrExtension(element.enclosingElement3!) &&
+      if (_isPrivateClassOrExtension(element.enclosingElement!) &&
           elementIsStaticVariable) {
         // Public static fields of private classes, mixins, and extensions are
         // inaccessible from outside the library in which they are declared.
@@ -661,7 +717,7 @@
         element is FunctionElement && !element.isStatic) {
       // local variable or function
     } else if (element is ParameterElement) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       // Only report unused parameters of constructors, methods, and functions.
       if (enclosingElement is! ConstructorElement &&
           enclosingElement is! FunctionElement &&
@@ -673,7 +729,7 @@
         return true;
       }
       if (enclosingElement is ConstructorElement &&
-          enclosingElement.enclosingElement3.typeParameters.isNotEmpty) {
+          enclosingElement.enclosingElement.typeParameters.isNotEmpty) {
         // There is an issue matching arguments of instance creation
         // expressions for generic classes with parameters, so for now,
         // consider every parameter of a constructor of a generic class
@@ -727,8 +783,8 @@
   }
 
   Iterable<ExecutableElement> _overriddenElements(Element element) {
-    var enclosingElement = element.enclosingElement3;
-    if (enclosingElement is ClassElement) {
+    var enclosingElement = element.enclosingElement;
+    if (enclosingElement is InterfaceElement) {
       Name name = Name(_libraryUri, element.name!);
       var overridden =
           _inheritanceManager.getOverridden2(enclosingElement, name);
@@ -809,7 +865,7 @@
     // constructor in the class. A single unused, private constructor may serve
     // the purpose of preventing the class from being extended. In serving this
     // purpose, the constructor is "used."
-    if (element.enclosingElement3.constructors.length > 1 &&
+    if (element.enclosingElement.constructors.length > 1 &&
         !_isUsedMember(element)) {
       _reportErrorForElement(
           HintCode.UNUSED_ELEMENT, element, [element.displayName]);
diff --git a/pkg/analyzer/lib/src/error/use_result_verifier.dart b/pkg/analyzer/lib/src/error/use_result_verifier.dart
index 52a5118..c9571b8 100644
--- a/pkg/analyzer/lib/src/error/use_result_verifier.dart
+++ b/pkg/analyzer/lib/src/error/use_result_verifier.dart
@@ -199,6 +199,7 @@
         parent is ForElement ||
         parent is IfElement ||
         parent is ParenthesizedExpression ||
+        parent is PrefixExpression ||
         parent is SpreadElement) {
       return _isUsed(parent);
     }
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index c16f660..f851f4b 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -29,12 +29,10 @@
         messageOperatorWithTypeParameters,
         messagePositionalAfterNamedArgument,
         templateDuplicateLabelInSwitchStatement,
-        templateExpectedButGot,
         templateExpectedIdentifier,
         templateExperimentNotEnabled,
         templateExtraneousModifier,
-        templateInternalProblemUnhandled,
-        templateUnexpectedToken;
+        templateInternalProblemUnhandled;
 import 'package:_fe_analyzer_shared/src/parser/parser.dart'
     show
         Assert,
@@ -53,24 +51,24 @@
     show translateErrorToken;
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart';
 import 'package:_fe_analyzer_shared/src/scanner/token.dart'
-    show KeywordToken, StringToken, SyntheticStringToken, SyntheticToken;
+    show KeywordToken, StringToken, SyntheticToken;
 import 'package:_fe_analyzer_shared/src/scanner/token_constants.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
+import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/fasta/error_converter.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
 import 'package:collection/collection.dart';
 import 'package:pub_semver/pub_semver.dart';
 
-const _invalidCollectionElement = _InvalidCollectionElement._();
-
 /// A parser listener that builds the analyzer's AST structure.
 class AstBuilder extends StackListener {
   final AstFactoryImpl ast = astFactory;
@@ -88,17 +86,8 @@
   /// `native` support.
   late Parser parser;
 
-  /// The class currently being parsed, or `null` if no class is being parsed.
-  ClassDeclarationImpl? classDeclaration;
-
-  /// The mixin currently being parsed, or `null` if no mixin is being parsed.
-  MixinDeclarationImpl? mixinDeclaration;
-
-  /// The extension currently being parsed, or `null` if none.
-  ExtensionDeclarationImpl? extensionDeclaration;
-
-  /// The enum currently being parsed, or `null` if none.
-  EnumDeclarationImpl? enumDeclaration;
+  /// The class like declaration being parsed.
+  _ClassLikeDeclarationBuilder? _classLikeBuilder;
 
   /// If true, this is building a full AST. Otherwise, only create method
   /// bodies.
@@ -115,19 +104,13 @@
   // * The current library has an import that uses the scheme "dart-ext".
   bool allowNativeClause = false;
 
-  StringLiteral? nativeName;
+  StringLiteralImpl? nativeName;
 
   bool parseFunctionBodies = true;
 
   /// `true` if non-nullable behavior is enabled.
   final bool enableNonNullable;
 
-  /// `true` if spread-collections behavior is enabled
-  final bool enableSpreadCollections;
-
-  /// `true` if control-flow-collections behavior is enabled
-  final bool enableControlFlowCollections;
-
   /// `true` if triple-shift behavior is enabled
   final bool enableTripleShift;
 
@@ -158,6 +141,9 @@
   /// `true` if records are enabled
   final bool enableRecords;
 
+  /// `true` if unnamed-library behavior is enabled
+  final bool enableUnnamedLibraries;
+
   final FeatureSet _featureSet;
 
   final LineInfo _lineInfo;
@@ -167,10 +153,6 @@
       [Uri? uri])
       : errorReporter = FastaErrorReporter(errorReporter),
         enableNonNullable = _featureSet.isEnabled(Feature.non_nullable),
-        enableSpreadCollections =
-            _featureSet.isEnabled(Feature.spread_collections),
-        enableControlFlowCollections =
-            _featureSet.isEnabled(Feature.control_flow_collections),
         enableTripleShift = _featureSet.isEnabled(Feature.triple_shift),
         enableNonFunctionTypeAliases =
             _featureSet.isEnabled(Feature.nonfunction_type_aliases),
@@ -184,32 +166,10 @@
         enableEnhancedEnums = _featureSet.isEnabled(Feature.enhanced_enums),
         enableMacros = _featureSet.isEnabled(Feature.macros),
         enableRecords = _featureSet.isEnabled(Feature.records),
+        enableUnnamedLibraries =
+            _featureSet.isEnabled(Feature.unnamedLibraries),
         uri = uri ?? fileUri;
 
-  NodeList<ClassMember> get currentDeclarationMembers {
-    if (classDeclaration != null) {
-      return classDeclaration!.members;
-    } else if (mixinDeclaration != null) {
-      return mixinDeclaration!.members;
-    } else if (extensionDeclaration != null) {
-      return extensionDeclaration!.members;
-    } else {
-      return enumDeclaration!.members;
-    }
-  }
-
-  Token? get currentDeclarationName {
-    if (classDeclaration != null) {
-      return classDeclaration!.name2;
-    } else if (mixinDeclaration != null) {
-      return mixinDeclaration!.name2;
-    } else if (extensionDeclaration != null) {
-      return extensionDeclaration!.name2;
-    } else {
-      return enumDeclaration!.name2;
-    }
-  }
-
   @override
   Uri get importUri => uri;
 
@@ -251,9 +211,7 @@
   @override
   void beginClassDeclaration(Token begin, Token? abstractToken,
       Token? macroToken, Token? augmentToken, Token name) {
-    assert(classDeclaration == null &&
-        mixinDeclaration == null &&
-        extensionDeclaration == null);
+    assert(_classLikeBuilder == null);
     push(_Modifiers()..abstractKeyword = abstractToken);
     if (!enableMacros) {
       if (macroToken != null) {
@@ -280,9 +238,7 @@
   @override
   void beginExtensionDeclaration(Token extensionKeyword, Token? nameToken) {
     assert(optional('extension', extensionKeyword));
-    assert(classDeclaration == null &&
-        mixinDeclaration == null &&
-        extensionDeclaration == null);
+    assert(_classLikeBuilder == null);
     debugEvent("ExtensionHeader");
 
     var typeParameters = pop() as TypeParameterListImpl?;
@@ -294,25 +250,15 @@
       name = ast.simpleIdentifier(nameToken, isDeclaration: true);
     }
 
-    extensionDeclaration = ExtensionDeclarationImpl(
+    _classLikeBuilder = _ExtensionDeclarationBuilder(
       comment: comment,
       metadata: metadata,
       extensionKeyword: extensionKeyword,
-      typeKeyword: null,
-      name: name,
+      name: name?.token,
       typeParameters: typeParameters,
-      onKeyword: Tokens.on_(),
-      extendedType: ast.namedType(
-        name: _tmpSimpleIdentifier(),
-      ), // extendedType is set in [endExtensionDeclaration]
-      showClause: null,
-      hideClause: null,
       leftBracket: Tokens.openCurlyBracket(),
       rightBracket: Tokens.closeCurlyBracket(),
-      members: [],
     );
-
-    declarations.add(extensionDeclaration!);
   }
 
   @override
@@ -380,8 +326,10 @@
     }
     if (staticToken != null) {
       assert(staticToken.isModifier);
-      String? className = currentDeclarationName?.lexeme;
-      if (name.lexeme != className || getOrSet != null) {
+      final builder = _classLikeBuilder;
+      if (builder is! _ClassDeclarationBuilder ||
+          builder.name.lexeme != name.lexeme ||
+          getOrSet != null) {
         modifiers.staticKeyword = staticToken;
       }
     }
@@ -399,9 +347,7 @@
   @override
   void beginMixinDeclaration(
       Token? augmentToken, Token mixinKeyword, Token name) {
-    assert(classDeclaration == null &&
-        mixinDeclaration == null &&
-        extensionDeclaration == null);
+    assert(_classLikeBuilder == null);
     push(augmentToken ?? NullValue.Token);
   }
 
@@ -441,7 +387,7 @@
     var typeParameter = TypeParameterImpl(
       comment: comment,
       metadata: metadata,
-      name: name,
+      name: name.token,
       extendsKeyword: null,
       bound: null,
     );
@@ -598,6 +544,28 @@
     }
   }
 
+  /// TODO(scheglov) We should not do this.
+  /// Ideally, we should not test parsing pieces of class, and instead parse
+  /// the whole unit, and extract pieces that we need to validate.
+  _ClassDeclarationBuilder createFakeClassDeclarationBuilder(String className) {
+    return _classLikeBuilder = _ClassDeclarationBuilder(
+      comment: null,
+      metadata: null,
+      abstractKeyword: null,
+      macroKeyword: null,
+      augmentKeyword: null,
+      classKeyword: Token(Keyword.CLASS, 0),
+      name: StringToken(TokenType.STRING, className, -1),
+      typeParameters: null,
+      extendsClause: null,
+      withClause: null,
+      implementsClause: null,
+      nativeClause: null,
+      leftBracket: Tokens.openCurlyBracket(),
+      rightBracket: Tokens.closeCurlyBracket(),
+    );
+  }
+
   @override
   void debugEvent(String name) {
     // printEvent('AstBuilder: $name');
@@ -632,8 +600,8 @@
   }
 
   void doInvocation(
-      TypeArgumentList? typeArguments, MethodInvocationImpl arguments) {
-    var receiver = pop() as Expression;
+      TypeArgumentListImpl? typeArguments, MethodInvocationImpl arguments) {
+    var receiver = pop() as ExpressionImpl;
     if (receiver is SimpleIdentifierImpl) {
       arguments.methodName = receiver;
       if (typeArguments != null) {
@@ -641,8 +609,13 @@
       }
       push(arguments);
     } else {
-      push(ast.functionExpressionInvocation(
-          receiver, typeArguments, arguments.argumentList));
+      push(
+        FunctionExpressionInvocationImpl(
+          function: receiver,
+          typeArguments: typeArguments,
+          argumentList: arguments.argumentList,
+        ),
+      );
     }
   }
 
@@ -655,7 +628,7 @@
     debugEvent("Arguments");
 
     var expressions = popTypedList2<Expression>(count);
-    ArgumentList arguments = ArgumentListImpl(
+    final arguments = ArgumentListImpl(
       leftParenthesis: leftParenthesis,
       arguments: expressions,
       rightParenthesis: rightParenthesis,
@@ -674,8 +647,15 @@
       }
     }
 
-    push(ast.methodInvocation(
-        null, null, _tmpSimpleIdentifier(), null, arguments));
+    push(
+      MethodInvocationImpl(
+        target: null,
+        operator: null,
+        methodName: _tmpSimpleIdentifier(),
+        typeArguments: null,
+        argumentList: arguments,
+      ),
+    );
   }
 
   @override
@@ -703,10 +683,10 @@
           arguments.add(message);
         }
         push(
-          ast.functionExpressionInvocation(
-            ast.simpleIdentifier(assertKeyword),
-            null,
-            ArgumentListImpl(
+          FunctionExpressionInvocationImpl(
+            function: ast.simpleIdentifier(assertKeyword),
+            typeArguments: null,
+            argumentList: ArgumentListImpl(
               leftParenthesis: leftParenthesis,
               arguments: arguments,
               rightParenthesis: leftParenthesis.endGroup!,
@@ -793,6 +773,19 @@
   }
 
   @override
+  void endBinaryPattern(Token operatorToken) {
+    assert(operatorToken.isOperator);
+    debugEvent("BinaryPattern");
+
+    var right = pop() as DartPatternImpl;
+    var left = pop() as DartPatternImpl;
+    push(
+      BinaryPatternImpl(
+          leftOperand: left, operator: operatorToken, rightOperand: right),
+    );
+  }
+
+  @override
   void endBlock(
       int count, Token leftBracket, Token rightBracket, BlockKind blockKind) {
     assert(optional('{', leftBracket));
@@ -849,10 +842,17 @@
     debugEvent("Cascade");
 
     var expression = pop() as Expression;
-    var receiver = pop() as CascadeExpression;
+    var cascade = pop() as CascadeExpressionImpl;
     pop(); // Token.
-    receiver.cascadeSections.add(expression);
-    push(receiver);
+    push(
+      CascadeExpressionImpl(
+        target: cascade.target,
+        cascadeSections: <Expression>[
+          ...cascade.cascadeSections,
+          expression,
+        ],
+      ),
+    );
   }
 
   @override
@@ -929,15 +929,16 @@
       factoryKeyword: null,
       returnType: ast.simpleIdentifier(prefixOrName.token),
       period: period,
-      name: nameOrNull,
+      name: nameOrNull?.token,
       parameters: parameters,
       separator: separator,
       initializers: initializers,
       redirectedConstructor: redirectedConstructor,
       body: body,
     );
-    currentDeclarationMembers.add(constructor);
-    if (mixinDeclaration != null) {
+
+    _classLikeBuilder?.members.add(constructor);
+    if (_classLikeBuilder is MixinDeclaration) {
       // TODO (danrubel): Report an error if this is a mixin declaration.
     }
   }
@@ -945,7 +946,12 @@
   @override
   void endClassDeclaration(Token beginToken, Token endToken) {
     debugEvent("ClassDeclaration");
-    classDeclaration = null;
+
+    final builder = _classLikeBuilder as _ClassDeclarationBuilder;
+    declarations.add(
+      builder.build(),
+    );
+    _classLikeBuilder = null;
   }
 
   @override
@@ -1005,7 +1011,7 @@
       throw UnimplementedError();
     }
 
-    currentDeclarationMembers.add(
+    _classLikeBuilder?.members.add(
       ConstructorDeclarationImpl(
         comment: comment,
         metadata: metadata,
@@ -1014,7 +1020,7 @@
         factoryKeyword: factoryKeyword,
         returnType: ast.simpleIdentifier(returnType.token),
         period: period,
-        name: name,
+        name: name?.token,
         parameters: parameters,
         separator: separator,
         initializers: null,
@@ -1077,7 +1083,7 @@
     var covariantKeyword = covariantToken;
     var metadata = pop() as List<Annotation>?;
     var comment = _findComment(metadata, beginToken);
-    currentDeclarationMembers.add(
+    _classLikeBuilder?.members.add(
       FieldDeclarationImpl(
         comment: comment,
         metadata: metadata,
@@ -1145,7 +1151,7 @@
     }
 
     checkFieldFormalParameters(parameters);
-    currentDeclarationMembers.add(
+    _classLikeBuilder?.members.add(
       MethodDeclarationImpl(
         comment: comment,
         metadata: metadata,
@@ -1154,7 +1160,7 @@
         returnType: returnType,
         propertyKeyword: getOrSet,
         operatorKeyword: operatorKeyword,
-        name: nameId,
+        name: nameId.token,
         typeParameters: typeParameters,
         parameters: parameters,
         body: body,
@@ -1171,16 +1177,9 @@
     assert(optional('}', rightBracket));
     debugEvent("ClassOrMixinBody");
 
-    if (classDeclaration != null) {
-      classDeclaration!
-        ..leftBracket = leftBracket
-        ..rightBracket = rightBracket;
-    } else if (mixinDeclaration != null) {
-      mixinDeclaration!
-        ..leftBracket = leftBracket
-        ..rightBracket = rightBracket;
-    } else {
-      extensionDeclaration!
+    final builder = _classLikeBuilder;
+    if (builder != null) {
+      builder
         ..leftBracket = leftBracket
         ..rightBracket = rightBracket;
     }
@@ -1296,9 +1295,10 @@
     var typeNameIdentifier = pop() as IdentifierImpl;
     push(
       ConstructorNameImpl(
-        type: ast.namedType(
+        type: NamedTypeImpl(
           name: typeNameIdentifier,
           typeArguments: typeArguments,
+          question: null,
         ),
         period: periodBeforeName,
         name: constructorName,
@@ -1314,7 +1314,7 @@
     assert(optional(';', semicolon));
     debugEvent("DoWhileStatement");
 
-    var condition = pop() as ParenthesizedExpressionImpl;
+    var condition = pop() as _ParenthesizedCondition;
     var body = pop() as StatementImpl;
     push(
       DoStatementImpl(
@@ -1344,6 +1344,12 @@
     assert(optional('enum', enumKeyword));
     assert(optional('{', leftBrace));
     debugEvent("Enum");
+
+    final builder = _classLikeBuilder as _EnumDeclarationBuilder;
+    declarations.add(
+      builder.build(),
+    );
+    _classLikeBuilder = null;
   }
 
   @override
@@ -1400,6 +1406,8 @@
   @override
   void endExtensionDeclaration(Token extensionKeyword, Token? typeKeyword,
       Token onKeyword, Token? showKeyword, Token? hideKeyword, Token token) {
+    final builder = _classLikeBuilder as _ExtensionDeclarationBuilder;
+
     if (typeKeyword != null && !enableExtensionTypes) {
       _reportFeatureNotEnabled(
         feature: ExperimentalFeatures.extension_types,
@@ -1415,18 +1423,22 @@
       );
     }
 
-    ShowClause? showClause = pop(NullValue.ShowClause) as ShowClause?;
-    HideClause? hideClause = pop(NullValue.HideClause) as HideClause?;
+    final showClause = pop(NullValue.ShowClause) as ShowClauseImpl?;
+    final hideClause = pop(NullValue.HideClause) as HideClauseImpl?;
 
-    var type = pop() as TypeAnnotation;
+    final type = pop() as TypeAnnotationImpl;
 
-    extensionDeclaration!
-      ..extendedType = type
-      ..onKeyword = onKeyword
-      ..typeKeyword = typeKeyword
-      ..showClause = showClause
-      ..hideClause = hideClause;
-    extensionDeclaration = null;
+    declarations.add(
+      builder.build(
+        extendedType: type,
+        onKeyword: onKeyword,
+        typeKeyword: typeKeyword,
+        showClause: showClause,
+        hideClause: hideClause,
+      ),
+    );
+
+    _classLikeBuilder = null;
   }
 
   @override
@@ -1473,7 +1485,7 @@
       // don't bother adding this declaration to the AST.
       return;
     }
-    currentDeclarationMembers.add(
+    _classLikeBuilder?.members.add(
       MethodDeclarationImpl(
         comment: comment,
         metadata: metadata,
@@ -1482,7 +1494,7 @@
         returnType: null,
         propertyKeyword: null,
         operatorKeyword: null,
-        name: methodName,
+        name: methodName.token,
         typeParameters: typeParameters,
         parameters: parameters,
         body: body,
@@ -1530,16 +1542,16 @@
   }
 
   @override
-  void endFieldInitializer(Token assignment, Token token) {
-    assert(optional('=', assignment));
+  void endFieldInitializer(Token equals, Token token) {
+    assert(optional('=', equals));
     debugEvent("FieldInitializer");
 
     var initializer = pop() as ExpressionImpl;
     var name = pop() as SimpleIdentifierImpl;
     push(
-      _makeVariableDeclaration(
-        name: name,
-        equals: assignment,
+      VariableDeclarationImpl(
+        name: name.token,
+        equals: equals,
         initializer: initializer,
       ),
     );
@@ -1548,32 +1560,43 @@
   @override
   void endForControlFlow(Token token) {
     debugEvent("endForControlFlow");
-    var entry = pop() as Object;
-    var forLoopParts = pop() as ForParts;
-    var leftParen = pop() as Token;
+    var body = pop() as CollectionElementImpl;
+    var forLoopParts = pop() as ForPartsImpl;
+    var leftParenthesis = pop() as Token;
     var forToken = pop() as Token;
 
-    pushForControlFlowInfo(null, forToken, leftParen, forLoopParts, entry);
+    push(
+      ForElementImpl(
+        awaitKeyword: null,
+        forKeyword: forToken,
+        leftParenthesis: leftParenthesis,
+        forLoopParts: forLoopParts,
+        rightParenthesis: leftParenthesis.endGroup!,
+        body: body,
+      ),
+    );
   }
 
   @override
   void endForIn(Token endToken) {
     debugEvent("ForInExpression");
 
-    var body = pop() as Statement;
-    var forLoopParts = pop() as ForEachParts;
+    var body = pop() as StatementImpl;
+    var forLoopParts = pop() as ForEachPartsImpl;
     var leftParenthesis = pop() as Token;
     var forToken = pop() as Token;
     var awaitToken = pop(NullValue.AwaitToken) as Token?;
 
-    push(ast.forStatement(
-      awaitKeyword: awaitToken,
-      forKeyword: forToken,
-      leftParenthesis: leftParenthesis,
-      forLoopParts: forLoopParts,
-      rightParenthesis: leftParenthesis.endGroup!,
-      body: body,
-    ));
+    push(
+      ForStatementImpl(
+        awaitKeyword: awaitToken,
+        forKeyword: forToken,
+        leftParenthesis: leftParenthesis,
+        forLoopParts: forLoopParts,
+        rightParenthesis: leftParenthesis.endGroup!,
+        body: body,
+      ),
+    );
   }
 
   @override
@@ -1585,14 +1608,22 @@
   void endForInControlFlow(Token token) {
     debugEvent("endForInControlFlow");
 
-    var entry = pop() as Object;
-    var forLoopParts = pop() as ForEachParts;
+    var body = pop() as CollectionElementImpl;
+    var forLoopParts = pop() as ForEachPartsImpl;
     var leftParenthesis = pop() as Token;
     var forToken = pop() as Token;
     var awaitToken = pop(NullValue.AwaitToken) as Token?;
 
-    pushForControlFlowInfo(
-        awaitToken, forToken, leftParenthesis, forLoopParts, entry);
+    push(
+      ForElementImpl(
+        awaitKeyword: awaitToken,
+        forKeyword: forToken,
+        leftParenthesis: leftParenthesis,
+        forLoopParts: forLoopParts,
+        rightParenthesis: leftParenthesis.endGroup!,
+        body: body,
+      ),
+    );
   }
 
   @override
@@ -1650,7 +1681,7 @@
         assert(thisKeyword == null,
             "Can't have both 'this' and 'super' in a parameter.");
         node = ast.superFormalParameter(
-            identifier: name!,
+            name: name!.token,
             comment: comment,
             metadata: metadata,
             covariantKeyword: covariantKeyword,
@@ -1665,7 +1696,7 @@
         assert(superKeyword == null,
             "Can't have both 'this' and 'super' in a parameter.");
         node = ast.fieldFormalParameter2(
-            identifier: name!,
+            name: name!.token,
             comment: comment,
             metadata: metadata,
             covariantKeyword: covariantKeyword,
@@ -1678,7 +1709,7 @@
             question: typeOrFunctionTypedParameter.question);
       } else {
         node = ast.functionTypedFormalParameter2(
-            identifier: name!,
+            name: name!.token,
             comment: comment,
             metadata: metadata,
             covariantKeyword: covariantKeyword,
@@ -1709,7 +1740,7 @@
             type: type,
             superKeyword: superKeyword,
             period: periodAfterThisOrSuper!,
-            identifier: name!);
+            name: name!.token);
       } else if (thisKeyword != null) {
         assert(superKeyword == null,
             "Can't have both 'this' and 'super' in a parameter.");
@@ -1722,7 +1753,7 @@
             type: type,
             thisKeyword: thisKeyword,
             period: thisKeyword.next!,
-            identifier: name!);
+            name: name!.token);
       } else {
         node = ast.simpleFormalParameter2(
             comment: comment,
@@ -1731,7 +1762,7 @@
             requiredKeyword: requiredKeyword,
             keyword: keyword,
             type: type,
-            identifier: name);
+            name: name?.token);
       }
     }
 
@@ -1789,18 +1820,21 @@
   @override
   void endForStatement(Token endToken) {
     debugEvent("ForStatement");
-    var body = pop() as Statement;
-    var forLoopParts = pop() as ForParts;
+    var body = pop() as StatementImpl;
+    var forLoopParts = pop() as ForPartsImpl;
     var leftParen = pop() as Token;
     var forToken = pop() as Token;
 
-    push(ast.forStatement(
-      forKeyword: forToken,
-      leftParenthesis: leftParen,
-      forLoopParts: forLoopParts,
-      rightParenthesis: leftParen.endGroup!,
-      body: body,
-    ));
+    push(
+      ForStatementImpl(
+        awaitKeyword: null,
+        forKeyword: forToken,
+        leftParenthesis: leftParen,
+        forLoopParts: forLoopParts,
+        rightParenthesis: leftParen.endGroup!,
+        body: body,
+      ),
+    );
   }
 
   @override
@@ -1816,10 +1850,16 @@
     // as possible.
     debugEvent("FunctionExpression");
 
-    var body = pop() as FunctionBody;
-    var parameters = pop() as FormalParameterList?;
-    var typeParameters = pop() as TypeParameterList?;
-    push(ast.functionExpression(typeParameters, parameters, body));
+    var body = pop() as FunctionBodyImpl;
+    var parameters = pop() as FormalParameterListImpl?;
+    var typeParameters = pop() as TypeParameterListImpl?;
+    push(
+      FunctionExpressionImpl(
+        typeParameters: typeParameters,
+        parameters: parameters,
+        body: body,
+      ),
+    );
   }
 
   @override
@@ -1835,12 +1875,18 @@
       reportErrorIfNullableType(questionMark);
     }
 
-    var parameters = pop() as FormalParameterList;
-    var returnType = pop() as TypeAnnotation?;
-    var typeParameters = pop() as TypeParameterList?;
-    push(ast.genericFunctionType(
-        returnType, functionToken, typeParameters, parameters,
-        question: questionMark));
+    var parameters = pop() as FormalParameterListImpl;
+    var returnType = pop() as TypeAnnotationImpl?;
+    var typeParameters = pop() as TypeParameterListImpl?;
+    push(
+      GenericFunctionTypeImpl(
+        returnType: returnType,
+        functionKeyword: functionToken,
+        typeParameters: typeParameters,
+        parameters: parameters,
+        question: questionMark,
+      ),
+    );
   }
 
   @override
@@ -1857,9 +1903,7 @@
     // Create a temporary formal parameter that will be dissected later in
     // [endFormalParameter].
     push(ast.functionTypedFormalParameter2(
-        identifier: ast.simpleIdentifier(
-          StringToken(TokenType.IDENTIFIER, '', 0),
-        ),
+        name: StringToken(TokenType.IDENTIFIER, '', 0),
         returnType: returnType,
         typeParameters: typeParameters,
         parameters: formalParameters,
@@ -1872,26 +1916,52 @@
     debugEvent("Hide");
 
     var hiddenNames = pop() as List<SimpleIdentifier>;
-    push(ast.hideCombinator(hideKeyword, hiddenNames));
+    push(
+      HideCombinatorImpl(
+        keyword: hideKeyword,
+        hiddenNames: hiddenNames,
+      ),
+    );
   }
 
   @override
   void endIfControlFlow(Token token) {
-    var thenElement = pop() as CollectionElement;
-    var condition = pop() as ParenthesizedExpression;
+    var thenElement = pop() as CollectionElementImpl;
+    var condition = pop() as _ParenthesizedCondition;
     var ifToken = pop() as Token;
-    pushIfControlFlowInfo(ifToken, condition, thenElement, null, null);
+    push(
+      IfElementImpl(
+        ifKeyword: ifToken,
+        leftParenthesis: condition.leftParenthesis,
+        condition: condition.expression,
+        caseClause: null,
+        rightParenthesis: condition.rightParenthesis,
+        thenElement: thenElement,
+        elseKeyword: null,
+        elseElement: null,
+      ),
+    );
   }
 
   @override
   void endIfElseControlFlow(Token token) {
-    var elseElement = pop() as CollectionElement;
+    var elseElement = pop() as CollectionElementImpl;
     var elseToken = pop() as Token;
-    var thenElement = pop() as CollectionElement;
-    var condition = pop() as ParenthesizedExpression;
+    var thenElement = pop() as CollectionElementImpl;
+    var condition = pop() as _ParenthesizedCondition;
     var ifToken = pop() as Token;
-    pushIfControlFlowInfo(
-        ifToken, condition, thenElement, elseToken, elseElement);
+    push(
+      IfElementImpl(
+        ifKeyword: ifToken,
+        leftParenthesis: condition.leftParenthesis,
+        condition: condition.expression,
+        caseClause: null,
+        rightParenthesis: condition.rightParenthesis,
+        thenElement: thenElement,
+        elseKeyword: elseToken,
+        elseElement: elseElement,
+      ),
+    );
   }
 
   @override
@@ -1899,17 +1969,21 @@
     assert(optional('if', ifToken));
     assert(optionalOrNull('else', elseToken));
 
-    var elsePart = popIfNotNull(elseToken) as Statement?;
-    var thenPart = pop() as Statement;
-    var condition = pop() as ParenthesizedExpression;
-    push(ast.ifStatement(
-        ifToken,
-        condition.leftParenthesis,
-        condition.expression,
-        condition.rightParenthesis,
-        thenPart,
-        elseToken,
-        elsePart));
+    var elsePart = popIfNotNull(elseToken) as StatementImpl?;
+    var thenPart = pop() as StatementImpl;
+    var condition = pop() as _ParenthesizedCondition;
+    push(
+      IfStatementImpl(
+        ifKeyword: ifToken,
+        leftParenthesis: condition.leftParenthesis,
+        condition: condition.expression,
+        caseClause: condition.caseClause,
+        rightParenthesis: condition.rightParenthesis,
+        thenStatement: thenPart,
+        elseKeyword: elseToken,
+        elseStatement: elsePart,
+      ),
+    );
   }
 
   @override
@@ -1987,8 +2061,8 @@
     if (node is VariableDeclaration) {
       variable = node;
     } else if (node is SimpleIdentifierImpl) {
-      variable = _makeVariableDeclaration(
-        name: node,
+      variable = VariableDeclarationImpl(
+        name: node.token,
         equals: null,
         initializer: null,
       );
@@ -2075,13 +2149,20 @@
   }
 
   @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
     assert(optional('library', libraryKeyword));
     assert(optional(';', semicolon));
     debugEvent("LibraryName");
 
-    var libraryName = pop() as List<SimpleIdentifier>;
-    var name = ast.libraryIdentifier(libraryName);
+    var libraryName = hasName ? pop() as List<SimpleIdentifier>? : null;
+
+    if (!hasName && !enableUnnamedLibraries) {
+      _reportFeatureNotEnabled(
+        feature: ExperimentalFeatures.unnamed_libraries,
+        startToken: libraryKeyword,
+      );
+    }
+    var name = libraryName == null ? null : ast.libraryIdentifier(libraryName);
     var metadata = pop() as List<Annotation>?;
     var comment = _findComment(metadata, libraryKeyword);
     directives.add(
@@ -2109,13 +2190,21 @@
       var last = parts.last as Token;
       Quote quote = analyzeQuote(first.lexeme);
       List<InterpolationElement> elements = <InterpolationElement>[];
-      elements.add(ast.interpolationString(
-          first, unescapeFirstStringPart(first.lexeme, quote, first, this)));
+      elements.add(
+        InterpolationStringImpl(
+          contents: first,
+          value: unescapeFirstStringPart(first.lexeme, quote, first, this),
+        ),
+      );
       for (int i = 1; i < parts.length - 1; i++) {
         var part = parts[i];
         if (part is Token) {
-          elements.add(ast.interpolationString(
-              part, unescape(part.lexeme, quote, part, this)));
+          elements.add(
+            InterpolationStringImpl(
+              contents: part,
+              value: unescape(part.lexeme, quote, part, this),
+            ),
+          );
         } else if (part is InterpolationExpression) {
           elements.add(part);
         } else {
@@ -2126,10 +2215,13 @@
               uri);
         }
       }
-      elements.add(ast.interpolationString(
-          last,
-          unescapeLastStringPart(
-              last.lexeme, quote, last, last.isSynthetic, this)));
+      elements.add(
+        InterpolationStringImpl(
+          contents: last,
+          value: unescapeLastStringPart(
+              last.lexeme, quote, last, last.isSynthetic, this),
+        ),
+      );
       push(ast.stringInterpolation(elements));
     }
   }
@@ -2146,19 +2238,22 @@
   @override
   void endLocalFunctionDeclaration(Token token) {
     debugEvent("LocalFunctionDeclaration");
-    var body = pop() as FunctionBody;
+    var body = pop() as FunctionBodyImpl;
     if (isFullAst) {
       pop(); // constructor initializers
       pop(); // separator before constructor initializers
     }
-    var parameters = pop() as FormalParameterList;
+    var parameters = pop() as FormalParameterListImpl;
     checkFieldFormalParameters(parameters);
     var name = pop() as SimpleIdentifierImpl;
     var returnType = pop() as TypeAnnotationImpl?;
-    var typeParameters = pop() as TypeParameterList?;
+    var typeParameters = pop() as TypeParameterListImpl?;
     var metadata = pop(NullValue.Metadata) as List<Annotation>?;
-    final functionExpression =
-        ast.functionExpression(typeParameters, parameters, body);
+    final functionExpression = FunctionExpressionImpl(
+      typeParameters: typeParameters,
+      parameters: parameters,
+      body: body,
+    );
     var functionDeclaration = FunctionDeclarationImpl(
       comment: null,
       metadata: metadata,
@@ -2166,10 +2261,14 @@
       externalKeyword: null,
       returnType: returnType,
       propertyKeyword: null,
-      name: name,
+      name: name.token,
       functionExpression: functionExpression,
     );
-    push(ast.functionDeclarationStatement(functionDeclaration));
+    push(
+      FunctionDeclarationStatementImpl(
+        functionDeclaration: functionDeclaration,
+      ),
+    );
   }
 
   @override
@@ -2229,7 +2328,12 @@
   @override
   void endMixinDeclaration(Token mixinKeyword, Token endToken) {
     debugEvent("MixinDeclaration");
-    mixinDeclaration = null;
+
+    final builder = _classLikeBuilder as _MixinDeclarationBuilder;
+    declarations.add(
+      builder.build(),
+    );
+    _classLikeBuilder = null;
   }
 
   @override
@@ -2275,16 +2379,22 @@
   @override
   void endNamedFunctionExpression(Token endToken) {
     debugEvent("NamedFunctionExpression");
-    var body = pop() as FunctionBody;
+    var body = pop() as FunctionBodyImpl;
     if (isFullAst) {
       pop(); // constructor initializers
       pop(); // separator before constructor initializers
     }
-    var parameters = pop() as FormalParameterList;
+    var parameters = pop() as FormalParameterListImpl;
     pop(); // name
     pop(); // returnType
-    var typeParameters = pop() as TypeParameterList?;
-    push(ast.functionExpression(typeParameters, parameters, body));
+    var typeParameters = pop() as TypeParameterListImpl?;
+    push(
+      FunctionExpressionImpl(
+        typeParameters: typeParameters,
+        parameters: parameters,
+        body: body,
+      ),
+    );
   }
 
   @override
@@ -2298,8 +2408,13 @@
 
     ImplementsClauseImpl? implementsClause;
     if (implementsKeyword != null) {
-      var interfaces = popTypeList();
-      implementsClause = ast.implementsClause(implementsKeyword, interfaces);
+      var interfaces = _popNamedTypeList(
+        errorCode: ParserErrorCode.EXPECTED_NAMED_TYPE_IMPLEMENTS,
+      );
+      implementsClause = ImplementsClauseImpl(
+        implementsKeyword: implementsKeyword,
+        interfaces: interfaces,
+      );
     }
     var withClause = pop(NullValue.WithClause) as WithClauseImpl;
     var superclass = pop() as NamedTypeImpl;
@@ -2316,7 +2431,7 @@
         comment: comment,
         metadata: metadata,
         typedefKeyword: classKeyword,
-        name: name,
+        name: name.token,
         typeParameters: typeParameters,
         equals: equalsToken,
         abstractKeyword: abstractKeyword,
@@ -2410,7 +2525,7 @@
   }
 
   @override
-  void endRecordLiteral(Token token, int count) {
+  void endRecordLiteral(Token token, int count, Token? constKeyword) {
     debugEvent("RecordLiteral");
 
     if (!enableRecords) {
@@ -2427,6 +2542,7 @@
     }
 
     push(RecordLiteralImpl(
+      constKeyword: constKeyword,
       leftParenthesis: token,
       fields: expressions,
       rightParenthesis: token.endGroup!,
@@ -2519,9 +2635,14 @@
     assert(optional(';', semicolon));
     debugEvent("RethrowStatement");
 
-    RethrowExpression expression = ast.rethrowExpression(rethrowToken);
+    final expression = ast.rethrowExpression(rethrowToken);
     // TODO(scheglov) According to the specification, 'rethrow' is a statement.
-    push(ast.expressionStatement(expression, semicolon));
+    push(
+      ExpressionStatementImpl(
+        expression: expression,
+        semicolon: semicolon,
+      ),
+    );
   }
 
   @override
@@ -2541,7 +2662,12 @@
     debugEvent("Show");
 
     var shownNames = pop() as List<SimpleIdentifier>;
-    push(ast.showCombinator(showKeyword, shownNames));
+    push(
+      ShowCombinatorImpl(
+        keyword: showKeyword,
+        shownNames: shownNames,
+      ),
+    );
   }
 
   @override
@@ -2590,18 +2716,58 @@
     var statements = popTypedList2<Statement>(statementCount);
     List<SwitchMember?> members;
 
+    List<LabelImpl> popLabels() {
+      final labels = <LabelImpl>[];
+      while (peek() is LabelImpl) {
+        labels.insert(0, pop() as LabelImpl);
+        --labelCount;
+      }
+      return labels;
+    }
+
+    SwitchMemberImpl updateSwitchMember({
+      required SwitchMember member,
+      List<Label>? labels,
+      List<Statement>? statements,
+    }) {
+      if (member is SwitchCaseImpl) {
+        return SwitchCaseImpl(
+          labels ?? member.labels,
+          member.keyword,
+          member.expression,
+          member.colon,
+          statements ?? member.statements,
+        );
+      } else if (member is SwitchDefaultImpl) {
+        return SwitchDefaultImpl(
+          labels ?? member.labels,
+          member.keyword,
+          member.colon,
+          statements ?? member.statements,
+        );
+      } else if (member is SwitchPatternCaseImpl) {
+        return SwitchPatternCaseImpl(
+          labels: labels ?? member.labels,
+          keyword: member.keyword,
+          pattern: member.pattern,
+          whenClause: member.whenClause,
+          colon: member.colon,
+          statements: statements ?? member.statements,
+        );
+      } else {
+        throw UnimplementedError('(${member.runtimeType}) $member');
+      }
+    }
+
     if (labelCount == 0 && defaultKeyword == null) {
       // Common situation: case with no default and no labels.
       members = popTypedList2<SwitchMember>(expressionCount);
     } else {
       // Labels and case statements may be intertwined
       if (defaultKeyword != null) {
-        SwitchDefault member = ast.switchDefault(
-            <Label>[], defaultKeyword, colonAfterDefault!, <Statement>[]);
-        while (peek() is Label) {
-          member.labels.insert(0, pop() as Label);
-          --labelCount;
-        }
+        final labels = popLabels();
+        final member = ast.switchDefault(
+            labels, defaultKeyword, colonAfterDefault!, <Statement>[]);
         members = List<SwitchMember?>.filled(expressionCount + 1, null);
         members[expressionCount] = member;
       } else {
@@ -2609,17 +2775,23 @@
       }
       for (int index = expressionCount - 1; index >= 0; --index) {
         var member = pop() as SwitchMember;
-        while (peek() is Label) {
-          member.labels.insert(0, pop() as Label);
-          --labelCount;
-        }
-        members[index] = member;
+        final labels = popLabels();
+        members[index] = updateSwitchMember(
+          member: member,
+          labels: labels,
+          statements: null,
+        );
       }
       assert(labelCount == 0);
     }
+
     var members2 = members.whereNotNull().toList();
     if (members2.isNotEmpty) {
-      members2.last.statements.addAll(statements);
+      members2.last = updateSwitchMember(
+        member: members2.last,
+        labels: null,
+        statements: statements,
+      );
     }
     push(members2);
   }
@@ -2632,12 +2804,12 @@
     var rightBracket = pop() as Token;
     var members = pop() as List<SwitchMember>;
     var leftBracket = pop() as Token;
-    var expression = pop() as ParenthesizedExpression;
+    var condition = pop() as _ParenthesizedCondition;
     push(ast.switchStatement(
         switchKeyword,
-        expression.leftParenthesis,
-        expression.expression,
-        expression.rightParenthesis,
+        condition.leftParenthesis,
+        condition.expression,
+        condition.rightParenthesis,
         leftBracket,
         members,
         rightBracket));
@@ -2708,9 +2880,9 @@
         optional('set', getOrSet));
     debugEvent("TopLevelMethod");
 
-    var body = pop() as FunctionBody;
-    var parameters = pop() as FormalParameterList?;
-    var typeParameters = pop() as TypeParameterList?;
+    var body = pop() as FunctionBodyImpl;
+    var parameters = pop() as FormalParameterListImpl?;
+    var typeParameters = pop() as TypeParameterListImpl?;
     var name = pop() as SimpleIdentifierImpl;
     var returnType = pop() as TypeAnnotationImpl?;
     var modifiers = pop() as _Modifiers?;
@@ -2726,9 +2898,12 @@
         externalKeyword: externalKeyword,
         returnType: returnType,
         propertyKeyword: getOrSet,
-        name: name,
-        functionExpression:
-            ast.functionExpression(typeParameters, parameters, body),
+        name: name.token,
+        functionExpression: FunctionExpressionImpl(
+          typeParameters: typeParameters,
+          parameters: parameters,
+          body: body,
+        ),
       ),
     );
   }
@@ -2777,7 +2952,7 @@
           metadata: metadata,
           typedefKeyword: typedefKeyword,
           returnType: returnType,
-          name: name,
+          name: name.token,
           typeParameters: typeParameters,
           parameters: parameters,
           semicolon: semicolon,
@@ -2800,7 +2975,7 @@
           comment: comment,
           metadata: metadata,
           typedefKeyword: typedefKeyword,
-          name: name,
+          name: name.token,
           typeParameters: templateParameters,
           equals: equals,
           type: type,
@@ -2857,17 +3032,17 @@
   }
 
   @override
-  void endVariableInitializer(Token assignmentOperator) {
-    assert(optionalOrNull('=', assignmentOperator));
+  void endVariableInitializer(Token equals) {
+    assert(optionalOrNull('=', equals));
     debugEvent("VariableInitializer");
 
     var initializer = pop() as ExpressionImpl;
     var identifier = pop() as SimpleIdentifierImpl;
     // TODO(ahe): Don't push initializers, instead install them.
     push(
-      _makeVariableDeclaration(
-        name: identifier,
-        equals: assignmentOperator,
+      VariableDeclarationImpl(
+        name: identifier.token,
+        equals: equals,
         initializer: initializer,
       ),
     );
@@ -2907,7 +3082,7 @@
     debugEvent("WhileStatement");
 
     var body = pop() as Statement;
-    var condition = pop() as ParenthesizedExpression;
+    var condition = pop() as _ParenthesizedCondition;
     push(ast.whileStatement(whileKeyword, condition.leftParenthesis,
         condition.expression, condition.rightParenthesis, body));
   }
@@ -3015,9 +3190,30 @@
     assert(optional(':', colon));
     debugEvent("CaseMatch");
 
-    var expression = pop() as Expression;
-    push(ast.switchCase(
-        <Label>[], caseKeyword, expression, colon, <Statement>[]));
+    if (_featureSet.isEnabled(Feature.patterns)) {
+      var pattern = pop() as DartPatternImpl;
+      push(SwitchPatternCaseImpl(
+          labels: <Label>[],
+          keyword: caseKeyword,
+          pattern: pattern,
+          whenClause: null,
+          colon: colon,
+          statements: <Statement>[]));
+    } else {
+      var expression = pop() as Expression;
+      push(ast.switchCase(
+          <Label>[], caseKeyword, expression, colon, <Statement>[]));
+    }
+  }
+
+  @override
+  void handleCastPattern(Token asOperator) {
+    assert(optional('as', asOperator));
+    debugEvent("CastPattern");
+
+    var type = pop() as TypeAnnotationImpl;
+    var pattern = pop() as DartPatternImpl;
+    push(CastPatternImpl(pattern: pattern, asToken: asOperator, type: type));
   }
 
   @override
@@ -3030,17 +3226,15 @@
     var body = pop() as Block;
     var catchParameterList = popIfNotNull(catchKeyword) as FormalParameterList?;
     var type = popIfNotNull(onKeyword) as TypeAnnotation?;
-    SimpleIdentifier? exception;
-    SimpleIdentifier? stackTrace;
+    Token? exception;
+    Token? stackTrace;
     if (catchParameterList != null) {
       List<FormalParameter> catchParameters = catchParameterList.parameters;
       if (catchParameters.isNotEmpty) {
-        // ignore: deprecated_member_use_from_same_package
-        exception = catchParameters[0].identifier;
+        exception = catchParameters[0].name;
       }
       if (catchParameters.length > 1) {
-        // ignore: deprecated_member_use_from_same_package
-        stackTrace = catchParameters[1].identifier;
+        stackTrace = catchParameters[1].name;
       }
     }
     push(
@@ -3051,13 +3245,13 @@
         leftParenthesis: catchParameterList?.leftParenthesis,
         exceptionParameter: exception != null
             ? CatchClauseParameterImpl(
-                nameNode: exception as SimpleIdentifierImpl,
+                name: exception,
               )
             : null,
         comma: comma,
         stackTraceParameter: stackTrace != null
             ? CatchClauseParameterImpl(
-                nameNode: stackTrace as SimpleIdentifierImpl,
+                name: stackTrace,
               )
             : null,
         rightParenthesis: catchParameterList?.rightParenthesis,
@@ -3077,16 +3271,25 @@
       pop();
       typeCount--;
     }
-    var supertype = pop() as TypeAnnotation?;
-    if (supertype is NamedType) {
-      push(ast.extendsClause(extendsKeyword!, supertype));
+    var supertype = pop() as TypeAnnotationImpl?;
+    if (supertype is NamedTypeImpl) {
+      push(
+        ExtendsClauseImpl(
+          extendsKeyword: extendsKeyword!,
+          superclass: supertype,
+        ),
+      );
     } else {
-      // TODO(brianwilkerson) Produce a diagnostic indicating that the type
-      //  annotation is either missing or an invalid kind. Also, consider
-      //  (a) extending `ExtendsClause` to accept any type annotation for
-      //  recovery purposes, and (b) extending the parser to parse a generic
-      //  function type at this location.
       push(NullValue.ExtendsClause);
+      // TODO(brianwilkerson) Consider (a) extending `ExtendsClause` to accept
+      //  any type annotation for recovery purposes, and (b) extending the
+      //  parser to parse a generic function type at this location.
+      if (supertype != null) {
+        errorReporter.errorReporter?.reportErrorForNode(
+          ParserErrorCode.EXPECTED_NAMED_TYPE_EXTENDS,
+          supertype,
+        );
+      }
     }
   }
 
@@ -3094,12 +3297,15 @@
   void handleClassHeader(Token begin, Token classKeyword, Token? nativeToken) {
     assert(optional('class', classKeyword));
     assert(optionalOrNull('native', nativeToken));
-    assert(classDeclaration == null && mixinDeclaration == null);
+    assert(_classLikeBuilder == null);
     debugEvent("ClassHeader");
 
-    NativeClause? nativeClause;
+    NativeClauseImpl? nativeClause;
     if (nativeToken != null) {
-      nativeClause = ast.nativeClause(nativeToken, nativeName);
+      nativeClause = NativeClauseImpl(
+        nativeKeyword: nativeToken,
+        name: nativeName,
+      );
     }
     var implementsClause =
         pop(NullValue.IdentifierList) as ImplementsClauseImpl?;
@@ -3115,25 +3321,22 @@
     var comment = _findComment(metadata, begin);
     // leftBracket, members, and rightBracket
     // are set in [endClassOrMixinBody].
-    classDeclaration = ClassDeclarationImpl(
+    _classLikeBuilder = _ClassDeclarationBuilder(
       comment: comment,
       metadata: metadata,
       abstractKeyword: abstractKeyword,
       macroKeyword: macroKeyword,
       augmentKeyword: augmentKeyword,
       classKeyword: classKeyword,
-      name: name,
+      name: name.token,
       typeParameters: typeParameters,
       extendsClause: extendsClause,
       withClause: withClause,
       implementsClause: implementsClause,
+      nativeClause: nativeClause,
       leftBracket: Tokens.openCurlyBracket(),
-      members: <ClassMember>[],
       rightBracket: Tokens.closeCurlyBracket(),
     );
-
-    classDeclaration!.nativeClause = nativeClause;
-    declarations.add(classDeclaration!);
   }
 
   @override
@@ -3144,7 +3347,9 @@
   @override
   void handleClassWithClause(Token withKeyword) {
     assert(optional('with', withKeyword));
-    var mixinTypes = popTypeList();
+    var mixinTypes = _popNamedTypeList(
+      errorCode: ParserErrorCode.EXPECTED_NAMED_TYPE_WITH,
+    );
     push(ast.withClause(withKeyword, mixinTypes));
   }
 
@@ -3194,6 +3399,12 @@
   }
 
   @override
+  void handleConstantPattern(Token? constKeyword) {
+    push(ConstantPatternImpl(
+        constKeyword: constKeyword, expression: pop() as ExpressionImpl));
+  }
+
+  @override
   void handleConstFactory(Token constKeyword) {
     debugEvent("ConstFactory");
     // TODO(kallentu): Removal of const factory error for const function feature
@@ -3304,7 +3515,6 @@
       constant = EnumConstantDeclarationImpl(
         comment: constant.documentationComment,
         metadata: constant.metadata,
-        // ignore: deprecated_member_use_from_same_package
         name: constant.name,
         arguments: EnumConstantArgumentsImpl(
           typeArguments: typeArguments,
@@ -3320,12 +3530,13 @@
   @override
   void handleEnumElements(Token elementsEndToken, int elementsCount) {
     debugEvent("EnumElements");
+    final builder = _classLikeBuilder as _EnumDeclarationBuilder;
 
     var constants = popTypedList2<EnumConstantDeclaration>(elementsCount);
-    enumDeclaration!.constants.addAll(constants);
+    builder.constants.addAll(constants);
 
     if (optional(';', elementsEndToken)) {
-      enumDeclaration!.semicolon = elementsEndToken;
+      builder.semicolon = elementsEndToken;
     }
 
     if (!enableEnhancedEnums && optional(';', elementsEndToken)) {
@@ -3365,21 +3576,17 @@
       );
     }
 
-    declarations.add(
-      enumDeclaration = EnumDeclarationImpl(
-        comment: comment,
-        metadata: metadata,
-        enumKeyword: enumKeyword,
-        name: name,
-        typeParameters: typeParameters,
-        withClause: withClause,
-        implementsClause: implementsClause,
-        leftBracket: leftBrace,
-        constants: [],
-        semicolon: null,
-        members: [],
-        rightBracket: leftBrace.endGroup!,
-      ),
+    _classLikeBuilder = _EnumDeclarationBuilder(
+      comment: comment,
+      metadata: metadata,
+      enumKeyword: enumKeyword,
+      name: name.token,
+      typeParameters: typeParameters,
+      withClause: withClause,
+      implementsClause: implementsClause,
+      leftBracket: leftBrace,
+      semicolon: null,
+      rightBracket: leftBrace.endGroup!,
     );
   }
 
@@ -3391,7 +3598,9 @@
   @override
   void handleEnumWithClause(Token withKeyword) {
     assert(optional('with', withKeyword));
-    var mixinTypes = popTypeList();
+    var mixinTypes = _popNamedTypeList(
+      errorCode: ParserErrorCode.EXPECTED_NAMED_TYPE_WITH,
+    );
     push(ast.withClause(withKeyword, mixinTypes));
   }
 
@@ -3430,15 +3639,15 @@
   void handleExpressionStatement(Token semicolon) {
     assert(optional(';', semicolon));
     debugEvent("ExpressionStatement");
-    var expression = pop() as Expression;
+    var expression = pop() as ExpressionImpl;
     reportErrorIfSuper(expression);
-    if (expression is SimpleIdentifier &&
+    if (expression is SimpleIdentifierImpl &&
         expression.token.keyword?.isBuiltInOrPseudo == false) {
       // This error is also reported by the body builder.
       handleRecoverableError(
           messageExpectedStatement, expression.beginToken, expression.endToken);
     }
-    if (expression is AssignmentExpression) {
+    if (expression is AssignmentExpressionImpl) {
       if (!expression.leftHandSide.isAssignable) {
         // This error is also reported by the body builder.
         handleRecoverableError(
@@ -3447,7 +3656,12 @@
             expression.leftHandSide.endToken);
       }
     }
-    push(ast.expressionStatement(expression, semicolon));
+    push(
+      ExpressionStatementImpl(
+        expression: expression,
+        semicolon: semicolon,
+      ),
+    );
   }
 
   @override
@@ -3460,7 +3674,10 @@
     HideClause? hideClause;
     if (hideKeyword != null) {
       var elements = popTypedList2<ShowHideClauseElement>(hideElementCount);
-      hideClause = ast.hideClause(hideKeyword: hideKeyword, elements: elements);
+      hideClause = HideClauseImpl(
+        hideKeyword: hideKeyword,
+        elements: elements,
+      );
     }
 
     ShowClause? showClause;
@@ -3474,6 +3691,34 @@
   }
 
   @override
+  void handleExtractorPattern(
+      Token firstIdentifierToken, Token? dot, Token? secondIdentifierToken) {
+    debugEvent("ExtractorPattern");
+
+    var arguments = pop() as _ExtractorPatternFields;
+    var typeArguments = pop() as TypeArgumentListImpl?;
+    var firstIdentifier = SimpleIdentifierImpl(firstIdentifierToken);
+    var typeName = dot == null
+        ? firstIdentifier
+        : PrefixedIdentifierImpl(
+            firstIdentifier, dot, SimpleIdentifierImpl(secondIdentifierToken!));
+    push(ExtractorPatternImpl(
+        typeName: typeName,
+        typeArguments: typeArguments,
+        leftParenthesis: arguments.leftParenthesis,
+        fields: arguments.fields,
+        rightParenthesis: arguments.rightParenthesis));
+  }
+
+  @override
+  void handleExtractorPatternFields(
+      int count, Token beginToken, Token endToken) {
+    debugEvent("ExtractorPatternFields");
+    var fields = popTypedList2<RecordPatternField>(count);
+    push(_ExtractorPatternFields(beginToken, endToken, fields));
+  }
+
+  @override
   void handleFinallyBlock(Token finallyKeyword) {
     debugEvent("FinallyBlock");
     // The finally block is popped in "endTryStatement".
@@ -3503,36 +3748,35 @@
     assert(optional('(', leftParenthesis));
     assert(optional('in', inKeyword) || optional(':', inKeyword));
 
-    var iterator = pop() as Expression;
+    var iterable = pop() as ExpressionImpl;
     var variableOrDeclaration = pop()!;
 
     ForEachParts forLoopParts;
     if (variableOrDeclaration is VariableDeclarationStatement) {
       VariableDeclarationList variableList = variableOrDeclaration.variables;
-      forLoopParts = ast.forEachPartsWithDeclaration(
+      forLoopParts = ForEachPartsWithDeclarationImpl(
         loopVariable: DeclaredIdentifierImpl(
           comment: variableList.documentationComment as CommentImpl?,
           metadata: variableList.metadata,
           keyword: variableList.keyword,
           type: variableList.type as TypeAnnotationImpl?,
-          // ignore: deprecated_member_use_from_same_package
-          identifier: variableList.variables.first.name as SimpleIdentifierImpl,
+          name: variableList.variables.first.name,
         ),
         inKeyword: inKeyword,
-        iterable: iterator,
+        iterable: iterable,
       );
     } else {
-      if (variableOrDeclaration is! SimpleIdentifier) {
+      if (variableOrDeclaration is! SimpleIdentifierImpl) {
         // Parser has already reported the error.
         if (!leftParenthesis.next!.isIdentifier) {
           parser.rewriter.insertSyntheticIdentifier(leftParenthesis);
         }
         variableOrDeclaration = ast.simpleIdentifier(leftParenthesis.next!);
       }
-      forLoopParts = ast.forEachPartsWithIdentifier(
+      forLoopParts = ForEachPartsWithIdentifierImpl(
         identifier: variableOrDeclaration,
         inKeyword: inKeyword,
-        iterable: iterator,
+        iterable: iterable,
       );
     }
 
@@ -3554,9 +3798,9 @@
     var conditionStatement = pop() as Statement;
     var initializerPart = pop();
 
-    Expression? condition;
+    ExpressionImpl? condition;
     Token rightSeparator;
-    if (conditionStatement is ExpressionStatement) {
+    if (conditionStatement is ExpressionStatementImpl) {
       condition = conditionStatement.expression;
       rightSeparator = conditionStatement.semicolon!;
     } else {
@@ -3564,17 +3808,17 @@
     }
 
     ForParts forLoopParts;
-    if (initializerPart is VariableDeclarationStatement) {
-      forLoopParts = ast.forPartsWithDeclarations(
-        variables: initializerPart.variables,
+    if (initializerPart is VariableDeclarationStatementImpl) {
+      forLoopParts = ForPartsWithDeclarationsImpl(
+        variableList: initializerPart.variables,
         leftSeparator: leftSeparator,
         condition: condition,
         rightSeparator: rightSeparator,
         updaters: updates,
       );
     } else {
-      forLoopParts = ast.forPartsWithExpression(
-        initialization: initializerPart as Expression?,
+      forLoopParts = ForPartsWithExpressionImpl(
+        initialization: initializerPart as ExpressionImpl?,
         leftSeparator: leftSeparator,
         condition: condition,
         rightSeparator: rightSeparator,
@@ -3619,7 +3863,7 @@
         EnumConstantDeclarationImpl(
           comment: comment,
           metadata: metadata,
-          name: identifier,
+          name: token,
           arguments: null,
         ),
       );
@@ -3641,10 +3885,16 @@
     debugEvent("Implements");
 
     if (implementsKeyword != null) {
-      var types = popTypedList2<TypeAnnotation>(interfacesCount);
-      // TODO(brianwilkerson) Report diagnostics for any type that's filtered out.
-      var interfaces = types.whereType<NamedType>().toList();
-      push(ast.implementsClause(implementsKeyword, interfaces));
+      endTypeList(interfacesCount);
+      final interfaces = _popNamedTypeList(
+        errorCode: ParserErrorCode.EXPECTED_NAMED_TYPE_IMPLEMENTS,
+      );
+      push(
+        ImplementsClauseImpl(
+          implementsKeyword: implementsKeyword,
+          interfaces: interfaces,
+        ),
+      );
     } else {
       push(NullValue.IdentifierList);
     }
@@ -3795,8 +4045,28 @@
     assert(optionalOrNull(':', colon));
     debugEvent("Label");
 
-    var name = pop() as SimpleIdentifier;
-    push(ast.label(name, colon));
+    var name = pop() as SimpleIdentifierImpl;
+    push(
+      LabelImpl(
+        label: name,
+        colon: colon,
+      ),
+    );
+  }
+
+  @override
+  void handleListPattern(int count, Token leftBracket, Token rightBracket) {
+    assert(optional('[', leftBracket));
+    assert(optional(']', rightBracket));
+    debugEvent("ListPattern");
+
+    var elements = popTypedList2<DartPattern>(count);
+    var typeArguments = pop() as TypeArgumentListImpl?;
+    push(ListPatternImpl(
+        typeArguments: typeArguments,
+        leftBracket: leftBracket,
+        elements: elements,
+        rightBracket: rightBracket));
   }
 
   @override
@@ -3832,7 +4102,12 @@
         identical(token.kind, HEXADECIMAL_TOKEN));
     debugEvent("LiteralInt");
 
-    push(ast.integerLiteral(token, int.tryParse(token.lexeme)));
+    push(
+      IntegerLiteralImpl(
+        literal: token,
+        value: int.tryParse(token.lexeme),
+      ),
+    );
   }
 
   @override
@@ -3843,28 +4118,11 @@
     assert(optional(']', rightBracket));
     debugEvent("LiteralList");
 
-    if (enableControlFlowCollections || enableSpreadCollections) {
-      List<CollectionElement> elements = popCollectionElements(count);
-      var typeArguments = pop() as TypeArgumentList?;
+    List<CollectionElement> elements = popCollectionElements(count);
+    var typeArguments = pop() as TypeArgumentList?;
 
-      // TODO(danrubel): Remove this and _InvalidCollectionElement
-      // once control flow and spread collection support is enabled by default
-      elements.removeWhere((e) => e == _invalidCollectionElement);
-
-      push(ast.listLiteral(
-          constKeyword, typeArguments, leftBracket, elements, rightBracket));
-    } else {
-      var elements = popTypedList<Expression>(count) ?? const [];
-      var typeArguments = pop() as TypeArgumentList?;
-
-      List<Expression> expressions = <Expression>[];
-      for (var elem in elements) {
-        expressions.add(elem);
-      }
-
-      push(ast.listLiteral(
-          constKeyword, typeArguments, leftBracket, expressions, rightBracket));
-    }
+    push(ast.listLiteral(
+        constKeyword, typeArguments, leftBracket, elements, rightBracket));
   }
 
   @override
@@ -3872,9 +4130,15 @@
     assert(optional(':', colon));
     debugEvent("LiteralMapEntry");
 
-    var value = pop() as Expression;
-    var key = pop() as Expression;
-    push(ast.mapLiteralEntry(key, colon, value));
+    var value = pop() as ExpressionImpl;
+    var key = pop() as ExpressionImpl;
+    push(
+      MapLiteralEntryImpl(
+        key: key,
+        separator: colon,
+        value: value,
+      ),
+    );
   }
 
   @override
@@ -3882,7 +4146,11 @@
     assert(optional('null', token));
     debugEvent("LiteralNull");
 
-    push(ast.nullLiteral(token));
+    push(
+      NullLiteralImpl(
+        literal: token,
+      ),
+    );
   }
 
   @override
@@ -3895,98 +4163,45 @@
     // behavior and will be removed once unified collection has been enabled
     bool hasSetEntry,
   ) {
-    if (enableControlFlowCollections || enableSpreadCollections) {
-      List<CollectionElement> elements = popCollectionElements(count);
+    List<CollectionElement> elements = popCollectionElements(count);
 
-      // TODO(danrubel): Remove this and _InvalidCollectionElement
-      // once control flow and spread collection support is enabled by default
-      elements.removeWhere((e) => e == _invalidCollectionElement);
+    var typeArguments = pop() as TypeArgumentList?;
+    push(ast.setOrMapLiteral(
+      constKeyword: constKeyword,
+      typeArguments: typeArguments,
+      leftBracket: leftBrace,
+      elements: elements,
+      rightBracket: rightBrace,
+    ));
+  }
 
-      var typeArguments = pop() as TypeArgumentList?;
-      push(ast.setOrMapLiteral(
-        constKeyword: constKeyword,
+  @override
+  void handleMapPattern(int count, Token leftBrace, Token rightBrace) {
+    debugEvent('MapPattern');
+
+    var entries = popTypedList2<MapPatternEntry>(count);
+    var typeArguments = pop() as TypeArgumentListImpl?;
+    push(MapPatternImpl(
         typeArguments: typeArguments,
         leftBracket: leftBrace,
-        elements: elements,
-        rightBracket: rightBrace,
-      ));
-    } else {
-      var elements = popTypedList(count);
-      var typeArguments = pop() as TypeArgumentList?;
+        entries: entries,
+        rightBracket: rightBrace));
+  }
 
-      // Replicate existing behavior that has been removed from the parser.
-      // This will be removed once control flow collections
-      // and spread collections are enabled by default.
+  @override
+  void handleMapPatternEntry(Token colon, Token endToken) {
+    assert(optional(':', colon));
+    debugEvent("MapPatternEntry");
 
-      // Determine if this is a set or map based on type args and content
-      final typeArgCount = typeArguments?.arguments.length;
-      bool? isSet = typeArgCount == 1
-          ? true
-          : typeArgCount != null
-              ? false
-              : null;
-      isSet ??= hasSetEntry;
-
-      // Build the set or map
-      if (isSet) {
-        final setEntries = <Expression>[];
-        if (elements != null) {
-          for (var elem in elements) {
-            if (elem is MapLiteralEntry) {
-              setEntries.add(elem.key);
-              handleRecoverableError(
-                  templateUnexpectedToken.withArguments(elem.separator),
-                  elem.separator,
-                  elem.separator);
-            } else if (elem is Expression) {
-              setEntries.add(elem);
-            }
-          }
-        }
-        push(ast.setOrMapLiteral(
-          constKeyword: constKeyword,
-          typeArguments: typeArguments,
-          leftBracket: leftBrace,
-          elements: setEntries,
-          rightBracket: rightBrace,
-        ));
-      } else {
-        final mapEntries = <MapLiteralEntry>[];
-        if (elements != null) {
-          for (var elem in elements) {
-            if (elem is MapLiteralEntry) {
-              mapEntries.add(elem);
-            } else if (elem is Expression) {
-              Token next = elem.endToken.next!;
-              int offset = next.offset;
-              handleRecoverableError(
-                  templateExpectedButGot.withArguments(':'), next, next);
-              handleRecoverableError(
-                  templateExpectedIdentifier.withArguments(next), next, next);
-              Token separator = SyntheticToken(TokenType.COLON, offset);
-              Expression value = ast.simpleIdentifier(
-                  SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
-              mapEntries.add(ast.mapLiteralEntry(elem, separator, value));
-            }
-          }
-        }
-        push(ast.setOrMapLiteral(
-          constKeyword: constKeyword,
-          typeArguments: typeArguments,
-          leftBracket: leftBrace,
-          elements: mapEntries,
-          rightBracket: rightBrace,
-        ));
-      }
-    }
+    var value = pop() as DartPatternImpl;
+    var key = pop() as ExpressionImpl;
+    push(MapPatternEntryImpl(key: key, separator: colon, value: value));
   }
 
   @override
   void handleMixinHeader(Token mixinKeyword) {
     assert(optional('mixin', mixinKeyword));
-    assert(classDeclaration == null &&
-        mixinDeclaration == null &&
-        extensionDeclaration == null);
+    assert(_classLikeBuilder == null);
     debugEvent("MixinHeader");
 
     var implementsClause =
@@ -3998,20 +4213,18 @@
     var metadata = pop() as List<Annotation>?;
     var comment = _findComment(metadata, mixinKeyword);
 
-    mixinDeclaration = MixinDeclarationImpl(
+    _classLikeBuilder = _MixinDeclarationBuilder(
       comment: comment,
       metadata: metadata,
       augmentKeyword: augmentKeyword,
       mixinKeyword: mixinKeyword,
-      name: name,
+      name: name.token,
       typeParameters: typeParameters,
       onClause: onClause,
       implementsClause: implementsClause,
       leftBracket: Tokens.openCurlyBracket(),
-      members: <ClassMember>[],
       rightBracket: Tokens.closeCurlyBracket(),
     );
-    declarations.add(mixinDeclaration!);
   }
 
   @override
@@ -4020,10 +4233,16 @@
     debugEvent("MixinOn");
 
     if (onKeyword != null) {
-      var types = popTypedList2<TypeAnnotation>(typeCount);
-      // TODO(brianwilkerson) Report diagnostics for any type that's filtered out.
-      var onTypes = types.whereType<NamedType>().toList();
-      push(ast.onClause(onKeyword, onTypes));
+      endTypeList(typeCount);
+      final onTypes = _popNamedTypeList(
+        errorCode: ParserErrorCode.EXPECTED_NAMED_TYPE_ON,
+      );
+      push(
+        OnClauseImpl(
+          onKeyword: onKeyword,
+          superclassConstraints: onTypes,
+        ),
+      );
     } else {
       push(NullValue.IdentifierList);
     }
@@ -4034,15 +4253,25 @@
     assert(optional(':', colon));
     debugEvent("NamedArgument");
 
-    var expression = pop() as Expression;
-    var name = pop() as SimpleIdentifier;
-    push(ast.namedExpression(ast.label(name, colon), expression));
+    var expression = pop() as ExpressionImpl;
+    var name = pop() as SimpleIdentifierImpl;
+    push(
+      NamedExpressionImpl(
+        name: LabelImpl(
+          label: name,
+          colon: colon,
+        ),
+        expression: expression,
+      ),
+    );
   }
 
   @override
   void handleNamedMixinApplicationWithClause(Token withKeyword) {
     assert(optionalOrNull('with', withKeyword));
-    var mixinTypes = popTypeList();
+    var mixinTypes = _popNamedTypeList(
+      errorCode: ParserErrorCode.EXPECTED_NAMED_TYPE_WITH,
+    );
     push(ast.withClause(withKeyword, mixinTypes));
   }
 
@@ -4054,7 +4283,7 @@
     debugEvent("NativeClause");
 
     if (hasName) {
-      nativeName = pop() as StringLiteral; // StringLiteral
+      nativeName = pop() as StringLiteralImpl;
     } else {
       nativeName = null;
     }
@@ -4095,8 +4324,8 @@
 
     var name = pop() as SimpleIdentifierImpl;
     push(
-      _makeVariableDeclaration(
-        name: name,
+      VariableDeclarationImpl(
+        name: name.token,
         equals: null,
         initializer: null,
       ),
@@ -4128,9 +4357,9 @@
   @override
   void handleNoTypeNameInConstructorReference(Token token) {
     debugEvent("NoTypeNameInConstructorReference");
-    assert(enumDeclaration != null);
+    final builder = _classLikeBuilder as _EnumDeclarationBuilder;
 
-    push(ast.simpleIdentifier(enumDeclaration!.name2));
+    push(ast.simpleIdentifier(builder.name));
   }
 
   @override
@@ -4139,6 +4368,23 @@
   }
 
   @override
+  void handleNullAssertPattern(Token bang) {
+    debugEvent("NullAssertPattern");
+    push(PostfixPatternImpl(operand: pop() as DartPatternImpl, operator: bang));
+  }
+
+  @override
+  void handleNullCheckPattern(Token question) {
+    debugEvent('NullCheckPattern');
+    if (!_featureSet.isEnabled(Feature.patterns)) {
+      // TODO(paulberry): report the appropriate error
+      throw UnimplementedError('Patterns not enabled');
+    }
+    push(PostfixPatternImpl(
+        operand: pop() as DartPatternImpl, operator: question));
+  }
+
+  @override
   void handleOperator(Token operatorToken) {
     assert(operatorToken.isUserDefinableOperator);
     debugEvent("Operator");
@@ -4157,9 +4403,42 @@
   }
 
   @override
-  void handleParenthesizedCondition(Token leftParenthesis) {
-    // TODO(danrubel): Implement rather than forwarding.
-    endParenthesizedExpression(leftParenthesis);
+  void handleParenthesizedCondition(Token leftParenthesis, Token? case_) {
+    ExpressionImpl condition;
+    CaseClauseImpl? caseClause;
+    if (case_ != null) {
+      // TODO(paulberry): what about a guard?
+      var pattern = pop() as DartPatternImpl;
+      caseClause = CaseClauseImpl(
+          caseKeyword: case_, pattern: pattern, whenClause: null);
+    }
+    condition = pop() as ExpressionImpl;
+    push(_ParenthesizedCondition(leftParenthesis, condition, caseClause));
+  }
+
+  @override
+  void handleParenthesizedPattern(Token leftParenthesis) {
+    assert(optional('(', leftParenthesis));
+    debugEvent("ParenthesizedPattern");
+
+    var pattern = pop() as DartPatternImpl;
+    push(ParenthesizedPatternImpl(
+        leftParenthesis: leftParenthesis,
+        pattern: pattern,
+        rightParenthesis: leftParenthesis.endGroup!));
+  }
+
+  @override
+  void handlePatternField(Token? colon) {
+    debugEvent("PatternField");
+
+    var pattern = pop() as DartPatternImpl;
+    RecordPatternFieldNameImpl? fieldName;
+    if (colon != null) {
+      var name = (pop() as SimpleIdentifier?)?.token;
+      fieldName = RecordPatternFieldNameImpl(name: name, colon: colon);
+    }
+    push(RecordPatternFieldImpl(fieldName: fieldName, pattern: pattern));
   }
 
   @override
@@ -4183,6 +4462,17 @@
   }
 
   @override
+  void handleRecordPattern(Token token, int count) {
+    debugEvent("RecordPattern");
+
+    var fields = popTypedList2<RecordPatternField>(count);
+    push(RecordPatternImpl(
+        leftParenthesis: token,
+        fields: fields,
+        rightParenthesis: token.endGroup!));
+  }
+
+  @override
   void handleRecoverableError(
       Message message, Token startToken, Token endToken) {
     /// TODO(danrubel): Ignore this error until we deprecate `native` support.
@@ -4207,28 +4497,42 @@
   void handleRecoverClassHeader() {
     debugEvent("RecoverClassHeader");
 
-    var implementsClause = pop(NullValue.IdentifierList) as ImplementsClause?;
-    var withClause = pop(NullValue.WithClause) as WithClause?;
-    var extendsClause = pop(NullValue.ExtendsClause) as ExtendsClause?;
-    var declaration = declarations.last as ClassDeclarationImpl;
+    var implementsClause =
+        pop(NullValue.IdentifierList) as ImplementsClauseImpl?;
+    var withClause = pop(NullValue.WithClause) as WithClauseImpl?;
+    var extendsClause = pop(NullValue.ExtendsClause) as ExtendsClauseImpl?;
+    var declaration = _classLikeBuilder as _ClassDeclarationBuilder;
     if (extendsClause != null) {
       if (declaration.extendsClause?.superclass == null) {
         declaration.extendsClause = extendsClause;
       }
     }
     if (withClause != null) {
-      if (declaration.withClause == null) {
+      final existingClause = declaration.withClause;
+      if (existingClause == null) {
         declaration.withClause = withClause;
       } else {
-        declaration.withClause!.mixinTypes.addAll(withClause.mixinTypes);
+        declaration.withClause = WithClauseImpl(
+          existingClause.withKeyword,
+          [
+            ...existingClause.mixinTypes,
+            ...withClause.mixinTypes,
+          ],
+        );
       }
     }
     if (implementsClause != null) {
-      if (declaration.implementsClause == null) {
+      final existingClause = declaration.implementsClause;
+      if (existingClause == null) {
         declaration.implementsClause = implementsClause;
       } else {
-        declaration.implementsClause!.interfaces
-            .addAll(implementsClause.interfaces);
+        declaration.implementsClause = ImplementsClauseImpl(
+          implementsKeyword: existingClause.implementsKeyword,
+          interfaces: [
+            ...existingClause.interfaces,
+            ...implementsClause.interfaces,
+          ],
+        );
       }
     }
   }
@@ -4241,50 +4545,84 @@
     var combinators = pop() as List<Combinator>?;
     var deferredKeyword = pop(NullValue.Deferred) as Token?;
     var asKeyword = pop(NullValue.As) as Token?;
-    var prefix = pop(NullValue.Prefix) as SimpleIdentifier?;
+    var prefix = pop(NullValue.Prefix) as SimpleIdentifierImpl?;
     var configurations = pop() as List<Configuration>?;
 
-    var directive = directives.last as ImportDirectiveImpl;
-    if (combinators != null) {
-      directive.combinators.addAll(combinators);
-    }
-    directive.deferredKeyword ??= deferredKeyword;
+    final directive = directives.last as ImportDirectiveImpl;
+
+    // TODO(scheglov) This code would be easier if we used one object.
+    var mergedAsKeyword = directive.asKeyword;
+    var mergedPrefix = directive.prefix;
     if (directive.asKeyword == null && asKeyword != null) {
-      directive.asKeyword = asKeyword;
-      directive.prefix = prefix;
+      mergedAsKeyword = asKeyword;
+      mergedPrefix = prefix;
     }
-    if (configurations != null) {
-      directive.configurations.addAll(configurations);
-    }
-    if (semicolon != null) {
-      directive.semicolon = semicolon;
-    }
+
+    directives.last = ImportDirectiveImpl(
+      comment: directive.documentationComment,
+      metadata: directive.metadata,
+      importKeyword: directive.importKeyword,
+      uri: directive.uri,
+      configurations: [
+        ...directive.configurations,
+        ...?configurations,
+      ],
+      deferredKeyword: directive.deferredKeyword ?? deferredKeyword,
+      asKeyword: mergedAsKeyword,
+      prefix: mergedPrefix,
+      combinators: [
+        ...directive.combinators,
+        ...?combinators,
+      ],
+      semicolon: semicolon ?? directive.semicolon,
+    );
   }
 
   @override
   void handleRecoverMixinHeader() {
-    var implementsClause = pop(NullValue.IdentifierList) as ImplementsClause?;
-    var onClause = pop(NullValue.IdentifierList) as OnClause?;
+    final builder = _classLikeBuilder as _MixinDeclarationBuilder;
+    var implementsClause =
+        pop(NullValue.IdentifierList) as ImplementsClauseImpl?;
+    var onClause = pop(NullValue.IdentifierList) as OnClauseImpl?;
 
     if (onClause != null) {
-      if (mixinDeclaration!.onClause == null) {
-        mixinDeclaration!.onClause = onClause;
+      final existingClause = builder.onClause;
+      if (existingClause == null) {
+        builder.onClause = onClause;
       } else {
-        mixinDeclaration!.onClause!.superclassConstraints
-            .addAll(onClause.superclassConstraints);
+        builder.onClause = OnClauseImpl(
+          onKeyword: existingClause.onKeyword,
+          superclassConstraints: [
+            ...existingClause.superclassConstraints,
+            ...onClause.superclassConstraints,
+          ],
+        );
       }
     }
     if (implementsClause != null) {
-      if (mixinDeclaration!.implementsClause == null) {
-        mixinDeclaration!.implementsClause = implementsClause;
+      final existingClause = builder.implementsClause;
+      if (existingClause == null) {
+        builder.implementsClause = implementsClause;
       } else {
-        mixinDeclaration!.implementsClause!.interfaces
-            .addAll(implementsClause.interfaces);
+        builder.implementsClause = ImplementsClauseImpl(
+          implementsKeyword: implementsClause.implementsKeyword,
+          interfaces: [
+            ...existingClause.interfaces,
+            ...implementsClause.interfaces,
+          ],
+        );
       }
     }
   }
 
   @override
+  void handleRelationalPattern(Token token) {
+    debugEvent("RelationalPattern");
+    push(RelationalPatternImpl(
+        operator: token, operand: pop() as ExpressionImpl));
+  }
+
+  @override
   void handleScript(Token token) {
     assert(identical(token.type, TokenType.SCRIPT_TAG));
     debugEvent("Script");
@@ -4324,16 +4662,12 @@
   @override
   void handleSpreadExpression(Token spreadToken) {
     var expression = pop() as Expression;
-    if (enableSpreadCollections) {
-      push(ast.spreadElement(
-          spreadOperator: spreadToken, expression: expression));
-    } else {
-      _reportFeatureNotEnabled(
-        feature: ExperimentalFeatures.spread_collections,
-        startToken: spreadToken,
-      );
-      push(_invalidCollectionElement);
-    }
+    push(
+      ast.spreadElement(
+        spreadOperator: spreadToken,
+        expression: expression,
+      ),
+    );
   }
 
   @override
@@ -4390,10 +4724,10 @@
       reportErrorIfNullableType(questionMark);
     }
 
-    var arguments = pop() as TypeArgumentList?;
-    var name = pop() as Identifier;
+    var arguments = pop() as TypeArgumentListImpl?;
+    var name = pop() as IdentifierImpl;
     push(
-      ast.namedType(
+      NamedTypeImpl(
         name: name,
         typeArguments: arguments,
         question: questionMark,
@@ -4403,8 +4737,8 @@
 
   @override
   void handleTypeArgumentApplication(Token openAngleBracket) {
-    var typeArguments = pop() as TypeArgumentList;
-    var receiver = pop() as Expression;
+    var typeArguments = pop() as TypeArgumentListImpl;
+    var receiver = pop() as ExpressionImpl;
     if (!enableConstructorTearoffs) {
       _reportFeatureNotEnabled(
         feature: ExperimentalFeatures.constructor_tearoffs,
@@ -4412,8 +4746,12 @@
         endToken: typeArguments.rightBracket,
       );
     }
-    push(ast.functionReference(
-        function: receiver, typeArguments: typeArguments));
+    push(
+      FunctionReferenceImpl(
+        function: receiver,
+        typeArguments: typeArguments,
+      ),
+    );
   }
 
   @override
@@ -4469,6 +4807,17 @@
   }
 
   @override
+  void handleVariablePattern(Token? keyword, Token variable) {
+    debugEvent('VariablePattern');
+    if (!_featureSet.isEnabled(Feature.patterns)) {
+      // TODO(paulberry): report the appropriate error
+      throw UnimplementedError('Patterns not enabled');
+    }
+    var type = pop() as TypeAnnotationImpl?;
+    push(VariablePatternImpl(keyword: keyword, type: type, name: variable));
+  }
+
+  @override
   void handleVoidKeyword(Token voidKeyword) {
     assert(optional('void', voidKeyword));
     debugEvent("VoidKeyword");
@@ -4562,71 +4911,6 @@
     return result.reversed.toList();
   }
 
-  // List<T?>? popTypedList<T>(int count, [List<T>? list]) {
-  //   if (count == 0) return null;
-  //   assert(stack.length >= count);
-  //
-  //   final tailList = list ?? List<T?>.filled(count, null, growable: true);
-  //   stack.popList(count, tailList, null);
-  //   return tailList;
-  // }
-
-  List<NamedType> popTypeList() {
-    var types = pop() as List<TypeAnnotation>;
-    // TODO(brianwilkerson) Report diagnostics for any type that's filtered out.
-    return types.whereType<NamedType>().toList();
-  }
-
-  void pushForControlFlowInfo(Token? awaitToken, Token forToken,
-      Token leftParenthesis, ForLoopParts forLoopParts, Object entry) {
-    if (entry == _invalidCollectionElement) {
-      push(_invalidCollectionElement);
-    } else if (enableControlFlowCollections) {
-      push(ast.forElement(
-        awaitKeyword: awaitToken,
-        forKeyword: forToken,
-        leftParenthesis: leftParenthesis,
-        forLoopParts: forLoopParts,
-        rightParenthesis: leftParenthesis.endGroup!,
-        body: entry as CollectionElement,
-      ));
-    } else {
-      _reportFeatureNotEnabled(
-        feature: ExperimentalFeatures.control_flow_collections,
-        startToken: forToken,
-      );
-      push(_invalidCollectionElement);
-    }
-  }
-
-  void pushIfControlFlowInfo(
-      Token ifToken,
-      ParenthesizedExpression condition,
-      CollectionElement thenElement,
-      Token? elseToken,
-      CollectionElement? elseElement) {
-    if (thenElement == _invalidCollectionElement ||
-        elseElement == _invalidCollectionElement) {
-      push(_invalidCollectionElement);
-    } else if (enableControlFlowCollections) {
-      push(ast.ifElement(
-        ifKeyword: ifToken,
-        leftParenthesis: condition.leftParenthesis,
-        condition: condition.expression,
-        rightParenthesis: condition.rightParenthesis,
-        thenElement: thenElement,
-        elseKeyword: elseToken,
-        elseElement: elseElement,
-      ));
-    } else {
-      _reportFeatureNotEnabled(
-        feature: ExperimentalFeatures.control_flow_collections,
-        startToken: ifToken,
-      );
-      push(_invalidCollectionElement);
-    }
-  }
-
   void reportErrorIfNullableType(Token? questionMark) {
     if (questionMark != null) {
       assert(optional('?', questionMark));
@@ -4697,16 +4981,19 @@
         typeArguments: typeArguments));
   }
 
-  VariableDeclaration _makeVariableDeclaration({
-    required SimpleIdentifierImpl name,
-    required Token? equals,
-    required ExpressionImpl? initializer,
+  List<NamedType> _popNamedTypeList({
+    required ErrorCode errorCode,
   }) {
-    return VariableDeclarationImpl(
-      name: name,
-      equals: equals,
-      initializer: initializer,
-    );
+    final types = pop() as List<TypeAnnotation>;
+    final namedTypes = <NamedType>[];
+    for (final type in types) {
+      if (type is NamedType) {
+        namedTypes.add(type);
+      } else {
+        errorReporter.errorReporter?.reportErrorForNode(errorCode, type);
+      }
+    }
+    return namedTypes;
   }
 
   void _reportFeatureNotEnabled({
@@ -4739,7 +5026,7 @@
     );
   }
 
-  SimpleIdentifier _tmpSimpleIdentifier() {
+  SimpleIdentifierImpl _tmpSimpleIdentifier() {
     return ast.simpleIdentifier(
       StringToken(TokenType.STRING, '__tmp', -1),
     );
@@ -4763,6 +5050,73 @@
   }
 }
 
+class _ClassDeclarationBuilder extends _ClassLikeDeclarationBuilder {
+  final Token? abstractKeyword;
+  final Token? macroKeyword;
+  final Token? augmentKeyword;
+  final Token classKeyword;
+  final Token name;
+  ExtendsClauseImpl? extendsClause;
+  WithClauseImpl? withClause;
+  ImplementsClauseImpl? implementsClause;
+  final NativeClauseImpl? nativeClause;
+
+  _ClassDeclarationBuilder({
+    required super.comment,
+    required super.metadata,
+    required super.typeParameters,
+    required super.leftBracket,
+    required super.rightBracket,
+    required this.abstractKeyword,
+    required this.macroKeyword,
+    required this.augmentKeyword,
+    required this.classKeyword,
+    required this.name,
+    required this.extendsClause,
+    required this.withClause,
+    required this.implementsClause,
+    required this.nativeClause,
+  });
+
+  ClassDeclarationImpl build() {
+    return ClassDeclarationImpl(
+      comment: comment,
+      metadata: metadata,
+      abstractKeyword: abstractKeyword,
+      macroKeyword: macroKeyword,
+      augmentKeyword: augmentKeyword,
+      classKeyword: classKeyword,
+      name: name,
+      typeParameters: typeParameters,
+      extendsClause: extendsClause,
+      withClause: withClause,
+      implementsClause: implementsClause,
+      nativeClause: nativeClause,
+      leftBracket: leftBracket,
+      members: members,
+      rightBracket: rightBracket,
+    );
+  }
+}
+
+class _ClassLikeDeclarationBuilder {
+  final CommentImpl? comment;
+  final List<Annotation>? metadata;
+  final TypeParameterListImpl? typeParameters;
+
+  Token leftBracket;
+  final List<ClassMember> members = [];
+  Token rightBracket;
+
+  _ClassLikeDeclarationBuilder({
+    required this.comment,
+    required this.metadata,
+    required this.typeParameters,
+    required this.leftBracket,
+    required this.rightBracket,
+  });
+}
+
 class _ConstructorNameWithInvalidTypeArgs {
   final ConstructorName name;
   final TypeArgumentList invalidTypeArgs;
@@ -4770,17 +5124,130 @@
   _ConstructorNameWithInvalidTypeArgs(this.name, this.invalidTypeArgs);
 }
 
-/// When [enableSpreadCollections] and/or [enableControlFlowCollections]
-/// are false, this class is pushed on the stack when a disabled
-/// [CollectionElement] has been parsed.
-class _InvalidCollectionElement implements CollectionElement {
-  // TODO(danrubel): Remove this once control flow and spread collections
-  // have been enabled by default.
+class _EnumDeclarationBuilder extends _ClassLikeDeclarationBuilder {
+  final Token enumKeyword;
+  final Token name;
+  final WithClauseImpl? withClause;
+  final ImplementsClauseImpl? implementsClause;
+  final List<EnumConstantDeclaration> constants = [];
+  Token? semicolon;
 
-  const _InvalidCollectionElement._();
+  _EnumDeclarationBuilder({
+    required super.comment,
+    required super.metadata,
+    required super.typeParameters,
+    required super.leftBracket,
+    required super.rightBracket,
+    required this.enumKeyword,
+    required this.name,
+    required this.withClause,
+    required this.implementsClause,
+    required this.semicolon,
+  });
 
-  @override
-  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+  EnumDeclarationImpl build() {
+    return EnumDeclarationImpl(
+      comment: comment,
+      metadata: metadata,
+      enumKeyword: enumKeyword,
+      name: name,
+      typeParameters: typeParameters,
+      withClause: withClause,
+      implementsClause: implementsClause,
+      leftBracket: leftBracket,
+      constants: constants,
+      semicolon: semicolon,
+      members: members,
+      rightBracket: rightBracket,
+    );
+  }
+}
+
+class _ExtensionDeclarationBuilder extends _ClassLikeDeclarationBuilder {
+  final Token extensionKeyword;
+  final Token? name;
+
+  _ExtensionDeclarationBuilder({
+    required super.comment,
+    required super.metadata,
+    required super.typeParameters,
+    required super.leftBracket,
+    required super.rightBracket,
+    required this.extensionKeyword,
+    required this.name,
+  });
+
+  ExtensionDeclarationImpl build({
+    required Token? typeKeyword,
+    required HideClauseImpl? hideClause,
+    required ShowClauseImpl? showClause,
+    required Token onKeyword,
+    required TypeAnnotationImpl extendedType,
+  }) {
+    return ExtensionDeclarationImpl(
+      comment: comment,
+      metadata: metadata,
+      extensionKeyword: extensionKeyword,
+      typeKeyword: typeKeyword,
+      name: name,
+      typeParameters: typeParameters,
+      onKeyword: onKeyword,
+      extendedType: extendedType,
+      showClause: showClause,
+      hideClause: hideClause,
+      leftBracket: leftBracket,
+      members: members,
+      rightBracket: rightBracket,
+    );
+  }
+}
+
+/// Temporary representation of the fields of an extractor used internally by
+/// the [AstBuilder].
+class _ExtractorPatternFields {
+  final Token leftParenthesis;
+  final Token rightParenthesis;
+  final List<RecordPatternField> fields;
+
+  _ExtractorPatternFields(
+      this.leftParenthesis, this.rightParenthesis, this.fields);
+}
+
+class _MixinDeclarationBuilder extends _ClassLikeDeclarationBuilder {
+  final Token? augmentKeyword;
+  final Token mixinKeyword;
+  final Token name;
+  OnClauseImpl? onClause;
+  ImplementsClauseImpl? implementsClause;
+
+  _MixinDeclarationBuilder({
+    required super.comment,
+    required super.metadata,
+    required super.typeParameters,
+    required super.leftBracket,
+    required super.rightBracket,
+    required this.augmentKeyword,
+    required this.mixinKeyword,
+    required this.name,
+    required this.onClause,
+    required this.implementsClause,
+  });
+
+  MixinDeclarationImpl build() {
+    return MixinDeclarationImpl(
+      comment: comment,
+      metadata: metadata,
+      augmentKeyword: augmentKeyword,
+      mixinKeyword: mixinKeyword,
+      name: name,
+      typeParameters: typeParameters,
+      onClause: onClause,
+      implementsClause: implementsClause,
+      leftBracket: leftBracket,
+      members: members,
+      rightBracket: rightBracket,
+    );
+  }
 }
 
 /// Data structure placed on the stack to represent a non-empty sequence
@@ -4854,6 +5321,20 @@
   _ParameterDefaultValue(this.separator, this.value);
 }
 
+/// Data structure placed on the stack to represent the parenthesized condition
+/// part of an if-statement, if-control-flow, switch-statement, while-statement,
+/// or do-while-statement.
+class _ParenthesizedCondition {
+  final Token leftParenthesis;
+  final ExpressionImpl expression;
+  final CaseClauseImpl? caseClause;
+
+  _ParenthesizedCondition(
+      this.leftParenthesis, this.expression, this.caseClause);
+
+  Token get rightParenthesis => leftParenthesis.endGroup!;
+}
+
 /// Data structure placed on stack to represent the redirected constructor.
 class _RedirectingFactoryBody {
   final Token? asyncKeyword;
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 4b487ca..ce43c70 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -128,7 +128,7 @@
   }
 
   void visitConstructorDeclaration(ConstructorDeclaration node) {
-    ConstructorElement element = node.declaredElement2!;
+    ConstructorElement element = node.declaredElement!;
     if (element is ConstructorElementImpl) {
       var redirectedNode = node.redirectedConstructor;
       if (redirectedNode != null) {
@@ -299,10 +299,22 @@
     _resolveAnnotations(node.metadata);
   }
 
+  void visitRecordTypeAnnotationNamedField(
+    RecordTypeAnnotationNamedField node,
+  ) {
+    _resolveAnnotations(node.metadata);
+  }
+
+  void visitRecordTypeAnnotationPositionalField(
+    RecordTypeAnnotationPositionalField node,
+  ) {
+    _resolveAnnotations(node.metadata);
+  }
+
   void visitRedirectingConstructorInvocation(
       covariant RedirectingConstructorInvocationImpl node) {
     var enclosingClass = _resolver.enclosingClass;
-    if (enclosingClass is! ClassElement) {
+    if (enclosingClass is! InterfaceElement) {
       // TODO(brianwilkerson) Report this error.
       return;
     }
@@ -336,7 +348,7 @@
   void visitSuperConstructorInvocation(
       covariant SuperConstructorInvocationImpl node) {
     var enclosingClass = _resolver.enclosingClass;
-    if (enclosingClass is! ClassElement) {
+    if (enclosingClass is! InterfaceElement) {
       // TODO(brianwilkerson) Report this error.
       return;
     }
@@ -365,7 +377,7 @@
     } else {
       if (element.isFactory &&
           // Check if we've reported [NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS].
-          !element.enclosingElement3.constructors
+          !element.enclosingElement.constructors
               .every((constructor) => constructor.isFactory)) {
         _errorReporter.reportErrorForNode(
             CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]);
@@ -488,7 +500,7 @@
   static InterfaceElement? getTypeReference(Expression expression) {
     if (expression is Identifier) {
       var element = expression.staticElement;
-      if (element is ClassElement) {
+      if (element is InterfaceElement) {
         return element;
       } else if (element is TypeAliasElement) {
         var aliasedType = element.aliasedType;
diff --git a/pkg/analyzer/lib/src/generated/element_walker.dart b/pkg/analyzer/lib/src/generated/element_walker.dart
index 35f4f3a..ae5784e 100644
--- a/pkg/analyzer/lib/src/generated/element_walker.dart
+++ b/pkg/analyzer/lib/src/generated/element_walker.dart
@@ -60,6 +60,15 @@
         _typedefs = element.typeAliases,
         _variables = element.topLevelVariables.where(_isNotSynthetic).toList();
 
+  /// Creates an [ElementWalker] which walks the child elements of a enum
+  /// element.
+  ElementWalker.forEnum(EnumElement this.element)
+      : _accessors = element.accessors.where(_isNotSynthetic).toList(),
+        _constructors = element.constructors.where(_isNotSynthetic).toList(),
+        _functions = element.methods,
+        _typeParameters = element.typeParameters,
+        _variables = element.fields.where(_isNotSynthetic).toList();
+
   /// Creates an [ElementWalker] which walks the child elements of a compilation
   /// unit element.
   ElementWalker.forExecutable(ExecutableElement this.element)
@@ -86,6 +95,15 @@
   ElementWalker.forGenericTypeAlias(TypeAliasElement this.element)
       : _typeParameters = element.typeParameters;
 
+  /// Creates an [ElementWalker] which walks the child elements of a mixin
+  /// element.
+  ElementWalker.forMixin(MixinElement this.element)
+      : _accessors = element.accessors.where(_isNotSynthetic).toList(),
+        _constructors = element.constructors.where(_isNotSynthetic).toList(),
+        _functions = element.methods,
+        _typeParameters = element.typeParameters,
+        _variables = element.fields.where(_isNotSynthetic).toList();
+
   /// Creates an [ElementWalker] which walks the child elements of a parameter
   /// element.
   ElementWalker.forParameter(ParameterElement this.element)
@@ -165,7 +183,7 @@
 
   /// Returns the next non-synthetic child of [element] which is a mixin; throws
   /// an [IndexError] if there are no more.
-  ClassElementImpl getMixin() => _mixins![_mixinIndex++] as ClassElementImpl;
+  MixinElementImpl getMixin() => _mixins![_mixinIndex++] as MixinElementImpl;
 
   /// Returns the next non-synthetic child of [element] which is a parameter;
   /// throws an [IndexError] if there are no more.
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index a2e3851..a7397ce 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -48,7 +48,6 @@
 import 'package:analyzer/src/summary2/macro_application_error.dart';
 import 'package:analyzer/src/utilities/extensions/object.dart';
 import 'package:analyzer/src/utilities/extensions/string.dart';
-import 'package:collection/collection.dart';
 
 class EnclosingExecutableContext {
   final ExecutableElement? element;
@@ -117,7 +116,7 @@
   }
 
   static bool _inFactoryConstructor(Element? element) {
-    var enclosing = element?.enclosingElement3;
+    var enclosing = element?.enclosingElement;
     if (enclosing == null) {
       return false;
     }
@@ -128,11 +127,11 @@
   }
 
   static bool _inStaticMethod(Element? element) {
-    var enclosing = element?.enclosingElement3;
+    var enclosing = element?.enclosingElement;
     if (enclosing == null) {
       return false;
     }
-    if (enclosing is ClassElement || enclosing is ExtensionElement) {
+    if (enclosing is InterfaceElement || enclosing is ExtensionElement) {
       if (element is ExecutableElement) {
         return element.isStatic;
       }
@@ -421,7 +420,7 @@
   void visitClassDeclaration(ClassDeclaration node) {
     var outerClass = _enclosingClass;
     try {
-      var element = node.declaredElement2 as ClassElementImpl;
+      var element = node.declaredElement as ClassElementImpl;
       _isInNativeClass = node.nativeClause != null;
       _enclosingClass = element;
 
@@ -429,7 +428,7 @@
       _duplicateDefinitionVerifier.checkClass(node);
       if (!element.isDartCoreFunctionImpl) {
         _checkForBuiltInIdentifierAsName(
-            node.name2, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
+            node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
       }
       _checkForConflictingClassTypeVariableErrorCodes();
       var superclass = node.extendsClause?.superclass;
@@ -448,7 +447,7 @@
       _checkForFinalNotInitializedInClass(members);
       _checkForBadFunctionUse(node);
       _checkForWrongTypeParameterVarianceInSuperinterfaces();
-      _checkForMainFunction1(node.name2, node.declaredElement2!);
+      _checkForMainFunction1(node.name, node.declaredElement!);
       _reportMacroApplicationErrors(
         annotations: node.metadata,
         macroErrors: element.macroApplicationErrors,
@@ -470,13 +469,13 @@
   @override
   void visitClassTypeAlias(ClassTypeAlias node) {
     _checkForBuiltInIdentifierAsName(
-        node.name2, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
+        node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
     var outerClassElement = _enclosingClass;
     try {
-      _enclosingClass = node.declaredElement2 as ClassElementImpl;
+      _enclosingClass = node.declaredElement as ClassElementImpl;
       _checkClassInheritance(
           node, node.superclass, node.withClause, node.implementsClause);
-      _checkForMainFunction1(node.name2, node.declaredElement2!);
+      _checkForMainFunction1(node.name, node.declaredElement!);
       _checkForWrongTypeParameterVarianceInSuperinterfaces();
     } finally {
       _enclosingClass = outerClassElement;
@@ -513,7 +512,7 @@
 
   @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     _withEnclosingExecutable(element, () {
       _checkForNonConstGenerativeEnumConstructor(node);
       _checkForInvalidModifierOnBody(
@@ -596,12 +595,12 @@
   void visitEnumDeclaration(EnumDeclaration node) {
     var outerClass = _enclosingClass;
     try {
-      var element = node.declaredElement2 as EnumElementImpl;
+      var element = node.declaredElement as EnumElementImpl;
       _enclosingClass = element;
       _duplicateDefinitionVerifier.checkEnum(node);
 
       _checkForBuiltInIdentifierAsName(
-          node.name2, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
+          node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
       _checkForConflictingEnumTypeVariableErrorCodes(element);
       var implementsClause = node.implementsClause;
       var withClause = node.withClause;
@@ -613,7 +612,7 @@
       _constructorFieldsVerifier.enterEnum(node, element);
       _checkForFinalNotInitializedInClass(node.members);
       _checkForWrongTypeParameterVarianceInSuperinterfaces();
-      _checkForMainFunction1(node.name2, node.declaredElement2!);
+      _checkForMainFunction1(node.name, node.declaredElement!);
       _checkForEnumInstantiatedToBoundsIsNotWellBounded(node, element);
 
       GetterSetterTypesVerifier(
@@ -653,7 +652,7 @@
 
   @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     _enclosingExtension = element;
     _duplicateDefinitionVerifier.checkExtension(node);
     _checkForConflictingExtensionTypeVariableErrorCodes();
@@ -664,7 +663,7 @@
       errorReporter: errorReporter,
     ).checkExtension(element);
 
-    final name = node.name2;
+    final name = node.name;
     if (name != null) {
       _checkForBuiltInIdentifierAsName(
           name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME);
@@ -719,7 +718,7 @@
   @override
   void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
     DeclaredIdentifier loopVariable = node.loopVariable;
-    if (_checkForEachParts(node, loopVariable.declaredElement2)) {
+    if (_checkForEachParts(node, loopVariable.declaredElement)) {
       if (loopVariable.isConst) {
         errorReporter.reportErrorForToken(
             CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE,
@@ -754,8 +753,8 @@
 
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
-    ExecutableElement functionElement = node.declaredElement2!;
-    if (functionElement.enclosingElement3 is! CompilationUnitElement) {
+    ExecutableElement functionElement = node.declaredElement!;
+    if (functionElement.enclosingElement is! CompilationUnitElement) {
       _hiddenElements!.declare(functionElement);
     }
 
@@ -764,13 +763,13 @@
       if (node.isSetter) {
         FunctionExpression functionExpression = node.functionExpression;
         _checkForWrongNumberOfParametersForSetter(
-            node.name2, functionExpression.parameters);
+            node.name, functionExpression.parameters);
         _checkForNonVoidReturnTypeForSetter(returnType);
       }
       _checkForTypeAnnotationDeferredClass(returnType);
       _returnTypeVerifier.verifyReturnType(returnType);
-      _checkForImplicitDynamicReturn(node.name2, node.declaredElement2!);
-      _checkForMainFunction1(node.name2, node.declaredElement2!);
+      _checkForImplicitDynamicReturn(node.name, node.declaredElement!);
+      _checkForMainFunction1(node.name, node.declaredElement!);
       _checkForMainFunction2(node);
       super.visitFunctionDeclaration(node);
     });
@@ -816,10 +815,10 @@
   @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     _checkForBuiltInIdentifierAsName(
-        node.name2, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
-    _checkForMainFunction1(node.name2, node.declaredElement2!);
+        node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
+    _checkForMainFunction1(node.name, node.declaredElement!);
     _checkForTypeAliasCannotReferenceItself(
-        node.name2, node.declaredElement2 as TypeAliasElementImpl);
+        node.name, node.declaredElement as TypeAliasElementImpl);
     super.visitFunctionTypeAlias(node);
   }
 
@@ -853,10 +852,10 @@
   @override
   void visitGenericTypeAlias(GenericTypeAlias node) {
     _checkForBuiltInIdentifierAsName(
-        node.name2, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
-    _checkForMainFunction1(node.name2, node.declaredElement2!);
+        node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
+    _checkForMainFunction1(node.name, node.declaredElement!);
     _checkForTypeAliasCannotReferenceItself(
-        node.name2, node.declaredElement2 as TypeAliasElementImpl);
+        node.name, node.declaredElement as TypeAliasElementImpl);
     super.visitGenericTypeAlias(node);
   }
 
@@ -947,10 +946,10 @@
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
-    _withEnclosingExecutable(node.declaredElement2!, () {
+    _withEnclosingExecutable(node.declaredElement!, () {
       var returnType = node.returnType;
       if (node.isSetter) {
-        _checkForWrongNumberOfParametersForSetter(node.name2, node.parameters);
+        _checkForWrongNumberOfParametersForSetter(node.name, node.parameters);
         _checkForNonVoidReturnTypeForSetter(returnType);
       } else if (node.isOperator) {
         var hasWrongNumberOfParameters =
@@ -965,7 +964,7 @@
       _checkForExtensionDeclaresMemberOfObject(node);
       _checkForTypeAnnotationDeferredClass(returnType);
       _returnTypeVerifier.verifyReturnType(returnType);
-      _checkForImplicitDynamicReturn(node.name2, node.declaredElement2!);
+      _checkForImplicitDynamicReturn(node.name, node.declaredElement!);
       _checkForWrongTypeParameterVarianceInMethod(node);
       super.visitMethodDeclaration(node);
     });
@@ -995,12 +994,12 @@
     // TODO(scheglov) Verify for all mixin errors.
     var outerClass = _enclosingClass;
     try {
-      _enclosingClass = node.declaredElement2!;
+      _enclosingClass = node.declaredElement!;
 
       List<ClassMember> members = node.members;
       _duplicateDefinitionVerifier.checkMixin(node);
       _checkForBuiltInIdentifierAsName(
-          node.name2, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
+          node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
       _checkForConflictingClassTypeVariableErrorCodes();
 
       var onClause = node.onClause;
@@ -1013,7 +1012,7 @@
 
       _checkForConflictingClassMembers();
       _checkForFinalNotInitializedInClass(members);
-      _checkForMainFunction1(node.name2, node.declaredElement2!);
+      _checkForMainFunction1(node.name, node.declaredElement!);
       _checkForWrongTypeParameterVarianceInSuperinterfaces();
       //      _checkForBadFunctionUse(node);
       super.visitMixinDeclaration(node);
@@ -1274,7 +1273,7 @@
     _checkForNotInitializedNonNullableVariable(node.variables, true);
 
     for (var variable in node.variables.variables) {
-      _checkForMainFunction1(variable.name2, variable.declaredElement2!);
+      _checkForMainFunction1(variable.name, variable.declaredElement!);
     }
 
     super.visitTopLevelVariableDeclaration(node);
@@ -1291,7 +1290,7 @@
 
   @override
   void visitTypeParameter(TypeParameter node) {
-    _checkForBuiltInIdentifierAsName(node.name2,
+    _checkForBuiltInIdentifierAsName(node.name,
         CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME);
     _checkForTypeAnnotationDeferredClass(node.bound);
     _checkForImplicitDynamicType(node.bound);
@@ -1309,11 +1308,11 @@
 
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
-    final nameToken = node.name2;
+    final nameToken = node.name;
     var initializerNode = node.initializer;
     // do checks
     _checkForImplicitDynamicIdentifier(node, nameToken,
-        variable: node.declaredElement2!);
+        variable: node.declaredElement!);
     _checkForAbstractOrExternalVariableInitializer(node);
     // visit initializer
     String name = nameToken.lexeme;
@@ -1329,7 +1328,7 @@
     AstNode grandparent = node.parent!.parent!;
     if (grandparent is! TopLevelVariableDeclaration &&
         grandparent is! FieldDeclaration) {
-      VariableElement element = node.declaredElement2!;
+      VariableElement element = node.declaredElement!;
       // There is no hidden elements if we are outside of a function body,
       // which will happen for variables declared in control flow elements.
       _hiddenElements?.declare(element);
@@ -1419,21 +1418,21 @@
 
   void _checkForAbstractOrExternalVariableInitializer(
       VariableDeclaration node) {
-    var declaredElement = node.declaredElement2;
+    var declaredElement = node.declaredElement;
     if (node.initializer != null) {
       if (declaredElement is FieldElement) {
         if (declaredElement.isAbstract) {
           errorReporter.reportErrorForToken(
-              CompileTimeErrorCode.ABSTRACT_FIELD_INITIALIZER, node.name2);
+              CompileTimeErrorCode.ABSTRACT_FIELD_INITIALIZER, node.name);
         }
         if (declaredElement.isExternal) {
           errorReporter.reportErrorForToken(
-              CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, node.name2);
+              CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, node.name);
         }
       } else if (declaredElement is TopLevelVariableElement) {
         if (declaredElement.isExternal) {
           errorReporter.reportErrorForToken(
-              CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, node.name2);
+              CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, node.name);
         }
       }
     }
@@ -1521,7 +1520,7 @@
     DartType redirectedReturnType = redirectedType.returnType;
 
     // Report specific problem when return type is incompatible
-    FunctionType constructorType = declaration.declaredElement2!.type;
+    FunctionType constructorType = declaration.declaredElement!.type;
     DartType constructorReturnType = constructorType.returnType;
     if (!typeSystem.isAssignableTo(
         redirectedReturnType, constructorReturnType)) {
@@ -1637,7 +1636,7 @@
         errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
           highlightedNode,
-          [variable.name, variable.enclosingElement3.displayName],
+          [variable.name, variable.enclosingElement.displayName],
         );
       } else {
         errorReporter.reportErrorForNode(
@@ -1652,7 +1651,7 @@
     } else if (element is MethodElement) {
       errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_METHOD, expression);
-    } else if (element is ClassElement ||
+    } else if (element is InterfaceElement ||
         element is DynamicElementImpl ||
         element is TypeParameterElement) {
       errorReporter.reportErrorForNode(
@@ -1807,14 +1806,14 @@
             CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, method, [
           _enclosingClass!.displayName,
           name,
-          inherited.enclosingElement3.displayName,
+          inherited.enclosingElement.displayName,
         ]);
       } else if (inherited is PropertyAccessorElement) {
         errorReporter.reportErrorForElement(
             CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD, method, [
           _enclosingClass!.displayName,
           name,
-          inherited.enclosingElement3.displayName
+          inherited.enclosingElement.displayName
         ]);
       }
     }
@@ -1834,14 +1833,14 @@
             CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, accessor, [
           _enclosingClass!.displayName,
           name,
-          inherited.enclosingElement3.displayName,
+          inherited.enclosingElement.displayName,
         ]);
       } else if (inherited is MethodElement) {
         errorReporter.reportErrorForElement(
             CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD, accessor, [
           _enclosingClass!.displayName,
           name,
-          inherited.enclosingElement3.displayName
+          inherited.enclosingElement.displayName
         ]);
       }
     }
@@ -1926,7 +1925,7 @@
   }
 
   void _checkForConflictingGenerics(NamedCompilationUnitMember node) {
-    var element = node.declaredElement2 as InterfaceElement;
+    var element = node.declaredElement as InterfaceElement;
 
     var analysisSession = _currentLibrary.session;
     var errors = analysisSession.classHierarchy.errors(element);
@@ -1935,7 +1934,7 @@
       if (error is IncompatibleInterfacesClassHierarchyError) {
         errorReporter.reportErrorForToken(
           CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
-          node.name2,
+          node.name,
           [
             _enclosingClass!.name,
             error.first.getDisplayString(withNullability: true),
@@ -1993,7 +1992,7 @@
         // [declaration] is a redirecting constructor via a redirecting
         // initializer.
         _checkForRedirectToNonConstConstructor(
-          declaration.declaredElement2!,
+          declaration.declaredElement!,
           initializer.staticElement,
           initializer.constructorName ?? initializer.thisKeyword,
         );
@@ -2099,11 +2098,11 @@
       errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
           constructor.returnType,
-          ["'${field.enclosingElement3.name}.${field.name}'"]);
+          ["'${field.enclosingElement.name}.${field.name}'"]);
       return true;
     } else if (instanceFields.length > 1) {
       var fieldNames = instanceFields
-          .map((field) => "'${field.enclosingElement3.name}.${field.name}'")
+          .map((field) => "'${field.enclosingElement.name}.${field.name}'")
           .join(', ');
       errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS,
@@ -2127,7 +2126,7 @@
         errorReporter.reportErrorForNode(
             CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
             initializer,
-            [element.enclosingElement3.displayName]);
+            [element.enclosingElement.displayName]);
         return true;
       }
     }
@@ -2165,8 +2164,8 @@
       return;
     }
     // check if there is non-final field
-    final classElement = constructorElement.enclosingElement3;
-    if (classElement is ClassElement && !classElement.hasNonFinalField) {
+    final classElement = constructorElement.enclosingElement;
+    if (classElement is! ClassElement || !classElement.hasNonFinalField) {
       return;
     }
     errorReporter.reportErrorForName(
@@ -2498,7 +2497,7 @@
       if (isWellBounded is NotWellBoundedTypeResult) {
         errorReporter.reportErrorForToken(
           CompileTimeErrorCode.ENUM_INSTANTIATED_TO_BOUNDS_IS_NOT_WELL_BOUNDED,
-          node.name2,
+          node.name,
         );
       }
     }
@@ -2641,7 +2640,7 @@
   void _checkForExtensionDeclaresMemberOfObject(MethodDeclaration node) {
     if (_enclosingExtension == null) return;
 
-    var name = node.name2.lexeme;
+    var name = node.name.lexeme;
     if (name == '==' ||
         name == 'hashCode' ||
         name == 'toString' ||
@@ -2649,7 +2648,7 @@
         name == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
       errorReporter.reportErrorForToken(
         CompileTimeErrorCode.EXTENSION_DECLARES_MEMBER_OF_OBJECT,
-        node.name2,
+        node.name,
       );
     }
   }
@@ -2718,10 +2717,10 @@
         if (isConst) {
           errorReporter.reportErrorForToken(
               CompileTimeErrorCode.CONST_NOT_INITIALIZED,
-              variable.name2,
-              [variable.name2.lexeme]);
+              variable.name,
+              [variable.name.lexeme]);
         } else {
-          var variableElement = variable.declaredElement2;
+          var variableElement = variable.declaredElement;
           if (variableElement is FieldElement &&
               (variableElement.isAbstract || variableElement.isExternal)) {
             // Abstract and external fields can't be initialized, so no error.
@@ -2731,8 +2730,8 @@
           } else if (!_isNonNullableByDefault || !variable.isLate) {
             errorReporter.reportErrorForToken(
                 CompileTimeErrorCode.FINAL_NOT_INITIALIZED,
-                variable.name2,
-                [variable.name2.lexeme]);
+                variable.name,
+                [variable.name.lexeme]);
           }
         }
       }
@@ -2936,7 +2935,7 @@
         // OK, instance member
         return;
       }
-      Element enclosingElement = element.enclosingElement3;
+      Element enclosingElement = element.enclosingElement;
       if (enclosingElement is ExtensionElement) {
         if (target is ExtensionOverride) {
           // OK, target is an extension override
@@ -2953,7 +2952,7 @@
           // OK, target is a type
           return;
         }
-        if (enclosingElement is! ClassElement) {
+        if (enclosingElement is! InterfaceElement) {
           // OK, top-level element
           return;
         }
@@ -3018,7 +3017,7 @@
     var constructorElement = node.staticElement;
     if (constructorElement != null &&
         constructorElement.isGenerative &&
-        constructorElement.enclosingElement3 is EnumElement) {
+        constructorElement.enclosingElement is EnumElement) {
       if (_currentLibrary.featureSet.isEnabled(Feature.enhanced_enums)) {
         errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR,
@@ -3061,8 +3060,8 @@
       return;
     }
     // not a class member
-    Element enclosingElement = element.enclosingElement3;
-    if (enclosingElement is! ClassElement &&
+    Element enclosingElement = element.enclosingElement;
+    if (enclosingElement is! InterfaceElement &&
         enclosingElement is! ExtensionElement) {
       return;
     }
@@ -3195,7 +3194,7 @@
     }
 
     // We should only check exported declarations, i.e. top-level.
-    if (declaredElement.enclosingElement3 is! CompilationUnitElement) {
+    if (declaredElement.enclosingElement is! CompilationUnitElement) {
       return;
     }
 
@@ -3216,7 +3215,7 @@
       return;
     }
 
-    if (functionDeclaration.name2.lexeme != 'main') {
+    if (functionDeclaration.name.lexeme != 'main') {
       return;
     }
 
@@ -3237,14 +3236,14 @@
     if (requiredPositional.length > 2) {
       errorReporter.reportErrorForToken(
         CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS,
-        functionDeclaration.name2,
+        functionDeclaration.name,
       );
     }
 
     if (parameters.any((e) => e.isRequiredNamed)) {
       errorReporter.reportErrorForToken(
         CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS,
-        functionDeclaration.name2,
+        functionDeclaration.name,
       );
     }
 
@@ -3443,7 +3442,7 @@
   /// implementations of all the super-invoked members of the [mixinElement].
   bool _checkForMixinSuperInvokedMembers(int mixinIndex, NamedType mixinName,
       InterfaceElement mixinElement, InterfaceType mixinType) {
-    var mixinElementImpl = mixinElement as ClassElementImpl;
+    var mixinElementImpl = mixinElement as MixinElementImpl;
     if (mixinElementImpl.superInvokedNames.isEmpty) {
       return false;
     }
@@ -3535,7 +3534,7 @@
               namedType, [
             name,
             namedType.name.name,
-            inheritedMember.enclosingElement3.name!
+            inheritedMember.enclosingElement.name!
           ]);
           return true;
         }
@@ -3647,7 +3646,7 @@
       if (superUnnamedConstructor.isFactory) {
         errorReporter.reportErrorForToken(
             CompileTimeErrorCode.NON_GENERATIVE_IMPLICIT_CONSTRUCTOR,
-            declaration.name2, [
+            declaration.name, [
           superElement.name,
           _enclosingClass!.name,
           superUnnamedConstructor
@@ -3664,7 +3663,7 @@
       // real problem was already reported.
       errorReporter.reportErrorForToken(
           CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
-          declaration.name2,
+          declaration.name,
           [superType, _enclosingClass!.displayName]);
     }
   }
@@ -3752,7 +3751,7 @@
 
     errorReporter.reportErrorForToken(
       CompileTimeErrorCode.NON_FINAL_FIELD_IN_ENUM,
-      variableList.variables.first.name2,
+      variableList.variables.first.name,
     );
   }
 
@@ -3762,7 +3761,7 @@
   /// See [CompileTimeErrorCode.NON_VOID_RETURN_FOR_OPERATOR].
   void _checkForNonVoidReturnTypeForOperator(MethodDeclaration declaration) {
     // check that []= operator
-    if (declaration.name2.lexeme != "[]=") {
+    if (declaration.name.lexeme != "[]=") {
       return;
     }
     // check return type
@@ -3805,7 +3804,7 @@
     if (_isEnclosingClassFfiUnion) return;
 
     for (var field in fields.variables) {
-      var fieldElement = field.declaredElement2 as FieldElement;
+      var fieldElement = field.declaredElement as FieldElement;
       if (fieldElement.isAbstract || fieldElement.isExternal) continue;
       if (field.initializer != null) continue;
 
@@ -3815,7 +3814,7 @@
       errorReporter.reportErrorForNode(
         CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD,
         field,
-        [field.name2.lexeme],
+        [field.name.lexeme],
       );
     }
   }
@@ -3868,8 +3867,8 @@
       if (variable.initializer == null) {
         errorReporter.reportErrorForToken(
           CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_VARIABLE,
-          variable.name2,
-          [variable.name2.lexeme],
+          variable.name,
+          [variable.name.lexeme],
         );
       }
     }
@@ -4059,19 +4058,19 @@
     }
     var redirectedElement = redirectedConstructor.staticElement;
     _checkForRedirectToNonConstConstructor(
-      declaration.declaredElement2!,
+      declaration.declaredElement!,
       redirectedElement,
       redirectedConstructor,
     );
-    var redirectedClass = redirectedElement?.enclosingElement3;
+    var redirectedClass = redirectedElement?.enclosingElement;
     if (redirectedClass is ClassElement &&
         redirectedClass.isAbstract &&
         redirectedElement != null &&
         !redirectedElement.isFactory) {
       String enclosingNamedType = _enclosingClass!.displayName;
       String constructorStrName = enclosingNamedType;
-      if (declaration.name2 != null) {
-        constructorStrName += ".${declaration.name2!.lexeme}";
+      if (declaration.name != null) {
+        constructorStrName += ".${declaration.name!.lexeme}";
       }
       errorReporter.reportErrorForNode(
           CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
@@ -4243,30 +4242,7 @@
       return;
     }
 
-    Expression expression = statement.expression;
-    if (checkForUseOfVoidResult(expression)) {
-      return;
-    }
-
-    // prepare 'switch' expression type
-    DartType expressionType = expression.typeOrThrow;
-
-    // compare with type of the first non-default 'case'
-    var switchCase = statement.members.whereType<SwitchCase>().firstOrNull;
-    if (switchCase == null) {
-      return;
-    }
-
-    Expression caseExpression = switchCase.expression;
-    DartType caseType = caseExpression.typeOrThrow;
-
-    // check types
-    if (!typeSystem.isAssignableTo(expressionType, caseType)) {
-      errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
-          expression,
-          [expressionType, caseType]);
-    }
+    checkForUseOfVoidResult(statement.expression);
   }
 
   void _checkForThrowOfInvalidType(ThrowExpression node) {
@@ -4322,7 +4298,7 @@
         if (elementToNode == null) {
           elementToNode = {};
           for (var parameter in parameters) {
-            elementToNode[parameter.declaredElement2!] = parameter;
+            elementToNode[parameter.declaredElement!] = parameter;
           }
         }
 
@@ -4335,12 +4311,12 @@
             current = null;
           }
           if (step == parameters.length) {
-            var element = parameter.declaredElement2!;
+            var element = parameter.declaredElement!;
             // This error can only occur if there is a bound, so we can saefly
             // assume `element.bound` is non-`null`.
             errorReporter.reportErrorForToken(
               CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
-              parameter.name2,
+              parameter.name,
               [element.displayName, element.bound!],
             );
             break;
@@ -4354,7 +4330,7 @@
     if (_enclosingExecutable.inStaticMethod || _isInStaticVariableDeclaration) {
       var element = identifier.staticElement;
       if (element is TypeParameterElement &&
-          element.enclosingElement3 is ClassElement) {
+          element.enclosingElement is InterfaceElement) {
         // The class's type parameters are not in scope for static methods.
         // However all other type parameters are legal (e.g. the static method's
         // type parameters, or a local function's type parameters).
@@ -4445,7 +4421,7 @@
 
     void reportError(ErrorCode errorCode, List<Object> arguments) {
       Identifier returnType = constructor.returnType;
-      var name = constructor.name2;
+      var name = constructor.name;
       int offset = returnType.offset;
       int length = (name != null ? name.end : returnType.end) - offset;
       errorReporter.reportErrorForOffset(errorCode, offset, length, arguments);
@@ -4548,7 +4524,7 @@
     } else if (targetType == null) {
       if (target is Identifier) {
         final targetElement = target.staticElement;
-        if (targetElement is ClassElement ||
+        if (targetElement is InterfaceElement ||
             targetElement is ExtensionElement ||
             targetElement is TypeAliasElement) {
           errorReporter.reportErrorForOffset(
@@ -4596,11 +4572,11 @@
     if (element == null || element is TypeParameterElement) {
       return;
     }
-    var enclosingElement = element.enclosingElement3;
+    var enclosingElement = element.enclosingElement;
     if (identical(enclosingElement, _enclosingClass)) {
       return;
     }
-    if (enclosingElement is! ClassElement) {
+    if (enclosingElement is! InterfaceElement) {
       return;
     }
     if (element is ExecutableElement && !element.isStatic) {
@@ -4697,7 +4673,7 @@
     }
     int numParameters = parameterList.parameters.length;
     // prepare operator name
-    final nameToken = declaration.name2;
+    final nameToken = declaration.name;
     final name = nameToken.lexeme;
     // check for exact number of parameters
     int expected = -1;
@@ -4769,8 +4745,8 @@
         // variance is added to the interface.
         if (!(typeParameter as TypeParameterElementImpl).isLegacyCovariant) {
           var fields = node.fields;
-          var fieldElement = fields.variables.first.declaredElement2!;
-          var fieldName = fields.variables.first.name2;
+          var fieldElement = fields.variables.first.declaredElement!;
+          var fieldName = fields.variables.first.name;
           Variance fieldVariance = Variance(typeParameter, fieldElement.type);
 
           _checkForWrongVariancePosition(
@@ -5090,21 +5066,21 @@
             if (typeSystem.isPotentiallyNonNullable(type)) {
               final parameterName = _parameterName(parameter);
               final errorTarget = parameterName ?? parameter;
+
+              List<Object>? arguments;
+              ErrorCode errorCode;
               if (parameterElement.hasRequired) {
-                errorReporter.reportErrorForOffset(
-                  CompileTimeErrorCode
-                      .MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION,
-                  errorTarget.offset,
-                  errorTarget.length,
-                );
+                errorCode = CompileTimeErrorCode
+                    .MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION;
               } else {
-                errorReporter.reportErrorForOffset(
-                  CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER,
-                  errorTarget.offset,
-                  errorTarget.length,
-                  [parameterName?.lexeme ?? '?'],
-                );
+                errorCode = parameterElement.isPositional
+                    ? CompileTimeErrorCode
+                        .MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL
+                    : CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER;
+                arguments = [parameterName?.lexeme ?? '?'];
               }
+              errorReporter.reportErrorForOffset(
+                  errorCode, errorTarget.offset, errorTarget.length, arguments);
             }
           }
         }
@@ -5288,7 +5264,7 @@
       if (fieldDeclaration is FieldDeclaration) {
         for (VariableDeclaration field in fieldDeclaration.fields.variables) {
           if (field.initializer == null) {
-            fields.add(field.declaredElement2 as FieldElement);
+            fields.add(field.declaredElement as FieldElement);
           }
         }
       }
diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
index 90e93ad..6ab5842 100644
--- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
@@ -86,9 +86,9 @@
         if (className == _structClassName || className == _unionClassName) {
           inCompound = true;
           compound = node;
-          if (node.declaredElement2!.isEmptyStruct) {
-            _errorReporter.reportErrorForToken(FfiCode.EMPTY_STRUCT, node.name2,
-                [node.name2.lexeme, className]);
+          if (node.declaredElement!.isEmptyStruct) {
+            _errorReporter.reportErrorForToken(
+                FfiCode.EMPTY_STRUCT, node.name, [node.name.lexeme, className]);
           }
           if (className == _structClassName) {
             _validatePackedAnnotation(node.metadata);
@@ -96,21 +96,21 @@
         } else if (className == _abiSpecificIntegerClassName) {
           _validateAbiSpecificIntegerAnnotation(node);
           _validateAbiSpecificIntegerMappingAnnotation(
-              node.name2, node.metadata);
+              node.name, node.metadata);
         } else if (className != _allocatorClassName &&
             className != _opaqueClassName &&
             className != _abiSpecificIntegerClassName) {
           _errorReporter.reportErrorForNode(
               FfiCode.SUBTYPE_OF_FFI_CLASS_IN_EXTENDS,
               superclass.name,
-              [node.name2.lexeme, superclass.name.name]);
+              [node.name.lexeme, superclass.name.name]);
         }
       } else if (superclass.isCompoundSubtype ||
           superclass.isAbiSpecificIntegerSubtype) {
         _errorReporter.reportErrorForNode(
             FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS,
             superclass,
-            [node.name2.lexeme, superclass.name.name]);
+            [node.name.lexeme, superclass.name.name]);
       }
     }
 
@@ -124,11 +124,11 @@
       }
       if (typename.ffiClass != null) {
         _errorReporter.reportErrorForNode(subtypeOfFfiCode, typename,
-            [node.name2.lexeme, typename.name.toSource()]);
+            [node.name.lexeme, typename.name.toSource()]);
       } else if (typename.isCompoundSubtype ||
           typename.isAbiSpecificIntegerSubtype) {
         _errorReporter.reportErrorForNode(subtypeOfStructCode, typename,
-            [node.name2.lexeme, typename.name.toSource()]);
+            [node.name.lexeme, typename.name.toSource()]);
       }
     }
 
@@ -148,13 +148,13 @@
     }
 
     if (inCompound) {
-      if (node.declaredElement2!.typeParameters.isNotEmpty) {
+      if (node.declaredElement!.typeParameters.isNotEmpty) {
         _errorReporter.reportErrorForToken(
-            FfiCode.GENERIC_STRUCT_SUBCLASS, node.name2, [node.name2.lexeme]);
+            FfiCode.GENERIC_STRUCT_SUBCLASS, node.name, [node.name.lexeme]);
       }
       final implementsClause = node.implementsClause;
       if (implementsClause != null) {
-        final compoundType = node.declaredElement2!.thisType;
+        final compoundType = node.declaredElement!.thisType;
         final structType = compoundType.superclass!;
         final ffiLibrary = structType.element2.library;
         final finalizableElement = ffiLibrary.getClass(_finalizableClassName)!;
@@ -162,8 +162,8 @@
         if (typeSystem.isSubtypeOf(compoundType, finalizableType)) {
           _errorReporter.reportErrorForToken(
               FfiCode.COMPOUND_IMPLEMENTS_FINALIZABLE,
-              node.name2,
-              [node.name2.lexeme]);
+              node.name,
+              [node.name.lexeme]);
         }
       }
     }
@@ -194,7 +194,7 @@
     _checkFfiNative(
       errorNode: node,
       annotations: node.metadata,
-      declarationElement: node.declaredElement2!,
+      declarationElement: node.declaredElement!,
       formalParameterList: node.functionExpression.parameters,
     );
     super.visitFunctionDeclaration(node);
@@ -204,7 +204,7 @@
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     var element = node.staticElement;
     if (element is MethodElement) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement.isAllocatorExtension &&
           element.name == _allocateExtensionMethodName) {
         _validateAllocate(node);
@@ -217,7 +217,7 @@
   void visitIndexExpression(IndexExpression node) {
     var element = node.staticElement;
     if (element is MethodElement) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement.isNativeStructPointerExtension ||
           enclosingElement.isNativeStructArrayExtension) {
         if (element.name == '[]') {
@@ -230,7 +230,7 @@
   @override
   void visitInstanceCreationExpression(InstanceCreationExpression node) {
     var constructor = node.constructorName.staticElement;
-    var class_ = constructor?.enclosingElement3;
+    var class_ = constructor?.enclosingElement;
     if (class_.isStructSubclass || class_.isUnionSubclass) {
       _errorReporter.reportErrorForNode(
         FfiCode.CREATION_OF_STRUCT_OR_UNION,
@@ -246,7 +246,7 @@
     _checkFfiNative(
         errorNode: node,
         annotations: node.metadata,
-        declarationElement: node.declaredElement2!,
+        declarationElement: node.declaredElement!,
         formalParameterList: node.parameters);
     super.visitMethodDeclaration(node);
   }
@@ -255,7 +255,7 @@
   void visitMethodInvocation(MethodInvocation node) {
     var element = node.methodName.staticElement;
     if (element is MethodElement) {
-      Element enclosingElement = element.enclosingElement3;
+      Element enclosingElement = element.enclosingElement;
       if (enclosingElement.isPointer) {
         if (element.name == 'fromFunction') {
           _validateFromFunction(node, element);
@@ -272,7 +272,7 @@
         }
       }
     } else if (element is FunctionElement) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement is CompilationUnitElement) {
         if (element.library.name == 'dart.ffi') {
           if (element.name == 'sizeOf') {
@@ -288,7 +288,7 @@
   void visitPrefixedIdentifier(PrefixedIdentifier node) {
     var element = node.staticElement;
     if (element != null) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement.isNativeStructPointerExtension) {
         if (element.name == 'ref') {
           _validateRefPrefixedIdentifier(node);
@@ -302,7 +302,7 @@
   void visitPropertyAccess(PropertyAccess node) {
     var element = node.propertyName.staticElement;
     if (element != null) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement.isNativeStructPointerExtension) {
         if (element.name == 'ref') {
           _validateRefPropertyAccess(node);
@@ -361,7 +361,7 @@
         // Receiver can only be Pointer if the class extends
         // NativeFieldWrapperClass1.
         if (ffiSignature.normalParameterTypes[0].isPointer) {
-          final cls = declarationElement.enclosingElement3 as ClassElement;
+          final cls = declarationElement.enclosingElement as InterfaceElement;
           if (!_extendsNativeFieldWrapperClass1(cls.thisType)) {
             _errorReporter.reportErrorForNode(
                 FfiCode
@@ -385,11 +385,12 @@
       }
 
       // Arguments can only be Pointer if the class extends
-      // NativeFieldWrapperClass1.
+      // Pointer or NativeFieldWrapperClass1.
       for (var i = 0; i < formalParameters.length; i++) {
         if (ffiParameterTypes[i].isPointer) {
-          final type = formalParameters[i].declaredElement!.type;
-          if (!_extendsNativeFieldWrapperClass1(type as InterfaceType)) {
+          final type =
+              formalParameters[i].declaredElement!.type as InterfaceType;
+          if (!type.isPointer && !_extendsNativeFieldWrapperClass1(type)) {
             _errorReporter.reportErrorForNode(
                 FfiCode
                     .FFI_NATIVE_ONLY_CLASSES_EXTENDING_NATIVEFIELDWRAPPERCLASS1_CAN_BE_POINTER,
@@ -428,11 +429,7 @@
         return true;
       }
       final element = type.element2;
-      if (element is ClassElement) {
-        type = element.supertype;
-      } else {
-        break;
-      }
+      type = element.supertype;
     }
     return false;
   }
@@ -617,7 +614,7 @@
   _PrimitiveDartType _typeForAnnotation(Annotation annotation) {
     var element = annotation.element;
     if (element is ConstructorElement) {
-      String name = element.enclosingElement3.name;
+      String name = element.enclosingElement.name;
       if (_primitiveIntegerNativeTypes.contains(name)) {
         return _PrimitiveDartType.int;
       } else if (_primitiveDoubleNativeTypes.contains(name)) {
@@ -638,7 +635,7 @@
         node.members.single is! ConstructorDeclaration ||
         (node.members.single as ConstructorDeclaration).constKeyword == null) {
       _errorReporter.reportErrorForToken(
-          FfiCode.ABI_SPECIFIC_INTEGER_INVALID, node.name2);
+          FfiCode.ABI_SPECIFIC_INTEGER_INVALID, node.name);
     }
   }
 
@@ -736,7 +733,7 @@
     List<Annotation> extraAnnotations = [];
     for (Annotation annotation in annotations) {
       if (annotation.element.ffiClass != null ||
-          annotation.element?.enclosingElement3.isAbiSpecificIntegerSubclass ==
+          annotation.element?.enclosingElement.isAbiSpecificIntegerSubclass ==
               true) {
         if (requiredFound) {
           extraAnnotations.add(annotation);
@@ -977,7 +974,7 @@
       if (node.externalKeyword == null) {
         _errorReporter.reportErrorForToken(
           FfiCode.FIELD_MUST_BE_EXTERNAL_IN_STRUCT,
-          fields.variables[0].name2,
+          fields.variables[0].name,
         );
       }
     }
@@ -985,7 +982,7 @@
     var fieldType = fields.type;
     if (fieldType == null) {
       _errorReporter.reportErrorForToken(
-          FfiCode.MISSING_FIELD_TYPE_IN_STRUCT, fields.variables[0].name2);
+          FfiCode.MISSING_FIELD_TYPE_IN_STRUCT, fields.variables[0].name);
     } else {
       DartType declaredType = fieldType.typeOrThrow;
       if (declaredType.isDartCoreInt) {
@@ -1013,7 +1010,7 @@
         _validateSizeOfAnnotation(fieldType, annotations, arrayDimensions);
       } else if (declaredType.isCompoundSubtype) {
         final clazz = (declaredType as InterfaceType).element2;
-        if (clazz is ClassElement && clazz.isEmptyStruct) {
+        if (clazz.isEmptyStruct) {
           _errorReporter.reportErrorForNode(FfiCode.EMPTY_STRUCT, node, [
             clazz.name,
             clazz.supertype!.getDisplayString(withNullability: false)
@@ -1030,7 +1027,7 @@
         if (field.initializer != null) {
           _errorReporter.reportErrorForToken(
             FfiCode.FIELD_IN_STRUCT_WITH_INITIALIZER,
-            field.name2,
+            field.name,
           );
         }
       }
@@ -1311,7 +1308,7 @@
     final element = this.element;
     return element is ConstructorElement &&
         element.ffiClass != null &&
-        element.enclosingElement3.name ==
+        element.enclosingElement.name ==
             FfiVerifier._abiSpecificIntegerMappingClassName;
   }
 
@@ -1319,21 +1316,21 @@
     final element = this.element;
     return element is ConstructorElement &&
         element.ffiClass != null &&
-        element.enclosingElement3.name == 'Array';
+        element.enclosingElement.name == 'Array';
   }
 
   bool get isFfiNative {
     final element = this.element;
     return element is ConstructorElement &&
         element.ffiClass != null &&
-        element.enclosingElement3.name == 'FfiNative';
+        element.enclosingElement.name == 'FfiNative';
   }
 
   bool get isPacked {
     final element = this.element;
     return element is ConstructorElement &&
         element.ffiClass != null &&
-        element.enclosingElement3.name == 'Packed';
+        element.enclosingElement.name == 'Packed';
   }
 }
 
@@ -1377,7 +1374,7 @@
     final element = this.element;
     return element is ConstructorElement &&
         element.ffiClass != null &&
-        element.enclosingElement3.name == 'Array';
+        element.enclosingElement.name == 'Array';
     // Note: this is 'Array' instead of '_ArraySize' because it finds the
     // forwarding factory instead of the forwarded constructor.
   }
@@ -1386,7 +1383,7 @@
     final element = this.element;
     return element is ConstructorElement &&
         element.ffiClass != null &&
-        element.enclosingElement3.name == 'Packed';
+        element.enclosingElement.name == 'Packed';
   }
 
   int? get packedMemberAlignment {
@@ -1401,7 +1398,7 @@
   ClassElement? get ffiClass {
     var element = this;
     if (element is ConstructorElement) {
-      element = element.enclosingElement3;
+      element = element.enclosingElement;
     }
     if (element is ClassElement && element.isFfiClass) {
       return element;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 1d7b7a3..23a1b21 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -44,7 +44,8 @@
           featureSet,
           lineInfo,
         ) {
-    fastaParser = fasta.Parser(astBuilder);
+    fastaParser = fasta.Parser(astBuilder,
+        allowPatterns: featureSet.isEnabled(Feature.patterns));
     astBuilder.parser = fastaParser;
     astBuilder.allowNativeClause = allowNativeClause;
   }
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index d3a6c6a..5e7a527 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -5,6 +5,9 @@
 import 'dart:collection';
 
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
+import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart';
+import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer.dart';
+import 'package:_fe_analyzer_shared/src/type_inference/type_operations.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/syntactic_entity.dart';
@@ -29,6 +32,7 @@
 import 'package:analyzer/src/dart/element/scope.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/dart/resolver/annotation_resolver.dart';
 import 'package:analyzer/src/dart/resolver/assignment_expression_resolver.dart';
@@ -52,6 +56,7 @@
 import 'package:analyzer/src/dart/resolver/property_element_resolver.dart';
 import 'package:analyzer/src/dart/resolver/record_literal_resolver.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/dart/resolver/shared_type_analyzer.dart';
 import 'package:analyzer/src/dart/resolver/simple_identifier_resolver.dart';
 import 'package:analyzer/src/dart/resolver/this_lookup.dart';
 import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
@@ -129,10 +134,31 @@
 /// Instances of the class `ResolverVisitor` are used to resolve the nodes
 /// within a single compilation unit.
 class ResolverVisitor extends ThrowingAstVisitor<void>
-    with ErrorDetectionHelpers {
+    with
+        ErrorDetectionHelpers,
+        TypeAnalyzer<AstNode, Statement, Expression, PromotableElement,
+            DartType> {
+  /// Debug-only: if `true`, manipulations of [_rewriteStack] performed by
+  /// [popRewrite], [pushRewrite], and [replaceExpression] will be printed.
+  static const bool _debugRewriteStack = false;
+
   /// The element for the library containing the compilation unit being visited.
   final LibraryElementImpl definingLibrary;
 
+  /// If the resolver visitor is visiting a switch statement, the tracker that
+  /// determines whether the switch is exhaustive.
+  ///
+  /// TODO(paulberry): move exhaustiveness computation into the shared
+  /// [TypeAnalyzer].
+  SwitchExhaustiveness? switchExhaustiveness;
+
+  @override
+  final TypeAnalyzerOptions options;
+
+  @override
+  late final SharedTypeAnalyzerErrors errors =
+      SharedTypeAnalyzerErrors(errorReporter);
+
   /// The source representing the compilation unit being visited.
   final Source source;
 
@@ -226,10 +252,6 @@
   /// be built and the comment resolved.
   bool resolveOnlyCommentInFunctionBody = false;
 
-  /// The type of the expression of the immediately enclosing [SwitchStatement],
-  /// or `null` if not in a [SwitchStatement].
-  DartType? _enclosingSwitchStatementExpressionType;
-
   /// Stack of expressions which we have not yet finished visiting, that should
   /// terminate a null-shorting expression.
   ///
@@ -256,6 +278,22 @@
 
   final bool genericMetadataIsEnabled;
 
+  /// Stack for obtaining rewritten expressions.  Prior to visiting an
+  /// expression, a caller may push the expression on this stack; if
+  /// [replaceExpression] is later called, it will update the top of the stack
+  /// to point to the rewritten expression.
+  ///
+  /// The stack sometimes contains `null`s.  These account for situations where
+  /// it's necessary to push a value onto the stack to balance a later pop, but
+  /// there is no suitable expression to push.
+  final List<ExpressionImpl?> _rewriteStack = [];
+
+  /// Debug-only expando mapping AST nodes to the nodes they were replaced with
+  /// by [replaceExpression].  This is used by [dispatchExpression] as a sanity
+  /// check to make sure the expression it pops off the [_rewriteStack] is
+  /// actually correct.
+  late final Expando<AstNode> _replacements = Expando();
+
   /// Initialize a newly created visitor to resolve the nodes in an AST node.
   ///
   /// The [definingLibrary] is the element for the library containing the node
@@ -306,7 +344,11 @@
         ),
         _featureSet = featureSet,
         genericMetadataIsEnabled =
-            definingLibrary.featureSet.isEnabled(Feature.generic_metadata) {
+            definingLibrary.featureSet.isEnabled(Feature.generic_metadata),
+        options = TypeAnalyzerOptions(
+            nullSafetyEnabled: definingLibrary.isNonNullableByDefault,
+            patternsEnabled:
+                definingLibrary.featureSet.isEnabled(Feature.patterns)) {
     var analysisOptions =
         definingLibrary.context.analysisOptions as AnalysisOptionsImpl;
 
@@ -375,12 +417,28 @@
         FunctionReferenceResolver(this, _isNonNullableByDefault);
   }
 
+  @override
+  DartType get boolType => throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  DartType get doubleType => throw UnimplementedError('TODO(paulberry)');
+
+  @override
+  DartType get dynamicType => throw UnimplementedError('TODO(paulberry)');
+
   /// Return the element representing the function containing the current node,
   /// or `null` if the current node is not contained in a function.
   ///
   /// @return the element representing the function containing the current node
   ExecutableElement? get enclosingFunction => _enclosingFunction;
 
+  @override
+  FlowAnalysis<AstNode, Statement, Expression, PromotableElement, DartType>?
+      get flow => flowAnalysis.flow;
+
+  @override
+  DartType get intType => throw UnimplementedError('TODO(paulberry)');
+
   bool get isConstructorTearoffsEnabled =>
       _featureSet.isEnabled(Feature.constructor_tearoffs);
 
@@ -398,6 +456,14 @@
         : NullabilitySuffix.star;
   }
 
+  @override
+  DartType get objectQuestionType =>
+      throw UnimplementedError('TODO(paulberry)');
+
+  /// Gets the current depth of the [_rewriteStack].  This may be used in
+  /// assertions to verify that pushes and pops are properly balanced.
+  int get rewriteStackDepth => _rewriteStack.length;
+
   /// If a class, or mixin, is being resolved, the type of the class.
   ///
   /// If an extension is being resolved, the type of `this`, the declared
@@ -408,17 +474,16 @@
     return _thisType;
   }
 
+  @override
+  TypeOperations2<DartType> get typeOperations => flowAnalysis.typeOperations;
+
+  @override
+  DartType get unknownType => UnknownInferredType.instance;
+
   /// Return `true` if NNBD is enabled for this compilation unit.
   bool get _isNonNullableByDefault =>
       _featureSet.isEnabled(Feature.non_nullable);
 
-  void analyzeExpression(Expression expression, DartType? contextType) {
-    if (contextType != null && contextType.isDynamic) {
-      contextType = null;
-    }
-    (expression as ExpressionImpl).resolveExpression(this, contextType);
-  }
-
   /// Verify that the arguments in the given [argumentList] can be assigned to
   /// their corresponding parameters.
   ///
@@ -513,6 +578,13 @@
     }
   }
 
+  /// The client of the resolver should call this method after asking the
+  /// resolver to visit an AST node.  This performs assertions to make sure that
+  /// temporary resolver state has been properly cleaned up.
+  void checkIdle() {
+    assert(_rewriteStack.isEmpty);
+  }
+
   void checkReadOfNotAssignedLocalVariable(
     SimpleIdentifier node,
     Element? element,
@@ -609,6 +681,67 @@
     return messages;
   }
 
+  @override
+  ExpressionTypeAnalysisResult<DartType> dispatchExpression(
+      covariant ExpressionImpl expression, DartType context) {
+    int? stackDepth;
+    assert(() {
+      stackDepth = rewriteStackDepth;
+      return true;
+    }());
+    // TODO(paulberry): implement null shorting
+    // Stack: ()
+    pushRewrite(expression);
+    // Stack: (Expression)
+    expression.resolveExpression(this, context);
+    assert(rewriteStackDepth == stackDepth! + 1);
+    var replacementExpression = peekRewrite()!;
+    assert(identical(
+        _replacements[expression] ?? expression, replacementExpression));
+    var staticType = replacementExpression.staticType;
+    if (staticType == null) {
+      assert(replacementExpression is ExtensionOverride);
+      staticType = unknownType;
+    }
+    return SimpleTypeAnalysisResult<DartType>(type: staticType);
+  }
+
+  @override
+  void dispatchPattern(
+      DartType matchedType,
+      Map<PromotableElement, VariableTypeInfo<AstNode, DartType>> typeInfos,
+      MatchContext<AstNode, Expression> context,
+      AstNode node) {
+    if (node is DartPatternImpl) {
+      node.resolvePattern(this, matchedType, typeInfos, context);
+    } else {
+      // This can occur inside conventional switch statements, since
+      // [SwitchCase] points directly to an [Expression] rather than to a
+      // [ConstantPattern].  So we mimic what
+      // [ConstantPatternImpl.resolvePattern] would do.
+      analyzeConstantPattern(
+          matchedType, typeInfos, context, node, node as Expression);
+      // Stack: (Expression)
+      popRewrite();
+      // Stack: ()
+    }
+  }
+
+  @override
+  DartType dispatchPatternSchema(covariant DartPatternImpl node) {
+    return node.computePatternSchema(this);
+  }
+
+  @override
+  void dispatchStatement(Statement statement) {
+    statement.accept(this);
+  }
+
+  @override
+  void finishExpressionCase(Expression node, int caseIndex) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
   /// Return the static element associated with the given expression whose type
   /// can be overridden, or `null` if there is no element whose type can be
   /// overridden.
@@ -630,6 +763,73 @@
     return null;
   }
 
+  @override
+  SwitchExpressionMemberInfo<AstNode, Expression> getSwitchExpressionMemberInfo(
+      Expression node, int index) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
+  SwitchStatementMemberInfo<AstNode, Statement, Expression>
+      getSwitchStatementMemberInfo(covariant SwitchStatement node, int index) {
+    var member = node.members[index];
+    AstNode? pattern;
+    if (member is SwitchCase) {
+      pattern = member.expression;
+    } else if (member is SwitchPatternCase) {
+      pattern = member.pattern;
+    }
+    return SwitchStatementMemberInfo(
+        [CaseHeadOrDefaultInfo(pattern: pattern)], member.statements,
+        labels: member.labels);
+  }
+
+  @override
+  void handleCase_afterCaseHeads(AstNode node, int caseIndex, int numHeads) {}
+
+  @override
+  void handleCaseHead(
+      // TODO(paulberry): once we support switch expressions this type will
+      // need to change.
+      covariant SwitchStatement node,
+      {required int caseIndex,
+      required int subIndex}) {
+    // Stack: (Expression)
+    popRewrite(); // "when" expression
+    // Stack: ()
+    switchExhaustiveness!.visitSwitchMember(node.members[caseIndex]);
+  }
+
+  @override
+  void handleDefault(covariant SwitchStatement node, int caseIndex) {
+    switchExhaustiveness!.visitSwitchMember(node.members[caseIndex]);
+  }
+
+  @override
+  void handleMergedStatementCase(covariant SwitchStatement node,
+      {required int caseIndex,
+      required int executionPathIndex,
+      required int numStatements}) {
+    nullSafetyDeadCodeVerifier.flowEnd(node.members[caseIndex]);
+  }
+
+  @override
+  void handleNoGuard(AstNode node, int caseIndex) {
+    // Stack: ()
+    // We can push `null` here because there is no actual expression associated
+    // with the lack of a guard, so there's nothing that will need rewriting.
+    pushRewrite(null);
+    // Stack: (Expression)
+  }
+
+  @override
+  void handleNoStatement(Statement node) {}
+
+  @override
+  void handleSwitchScrutinee(DartType type) {
+    switchExhaustiveness = SwitchExhaustiveness(type);
+  }
+
   /// If generic function instantiation should be performed on `expression`,
   /// inserts a [FunctionReference] node which wraps [expression].
   ///
@@ -674,12 +874,11 @@
     }
 
     var parent = expression.parent;
-    var genericFunctionInstantiation = astFactory.functionReference(
+    var genericFunctionInstantiation = FunctionReferenceImpl(
       function: expression,
       typeArguments: null,
     );
-    NodeReplacer.replace(expression, genericFunctionInstantiation,
-        parent: parent);
+    replaceExpression(expression, genericFunctionInstantiation, parent: parent);
 
     genericFunctionInstantiation.typeArgumentTypes = typeArgumentTypes;
     genericFunctionInstantiation.staticType = staticType;
@@ -687,6 +886,18 @@
     return genericFunctionInstantiation;
   }
 
+  @override
+  bool isSwitchExhaustive(AstNode node, DartType expressionType) =>
+      switchExhaustiveness!.isExhaustive;
+
+  @override
+  bool isVariablePattern(AstNode pattern) => pattern is VariablePattern;
+
+  @override
+  DartType listType(DartType elementType) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
   /// If we reached a null-shorting termination, and the [node] has null
   /// shorting, make the type of the [node] nullable.
   void nullShortingTermination(ExpressionImpl node,
@@ -718,6 +929,18 @@
     // TODO(brianwilkerson) Remove this method.
   }
 
+  /// Examines the top entry of [_rewriteStack] but does not pop it.
+  ExpressionImpl? peekRewrite() => _rewriteStack.last;
+
+  /// Pops the top entry off of [_rewriteStack].
+  ExpressionImpl? popRewrite() {
+    var expression = _rewriteStack.removeLast();
+    if (_debugRewriteStack) {
+      assert(_debugPrint('POP ${expression.runtimeType} $expression'));
+    }
+    return expression;
+  }
+
   /// Set information about enclosing declarations.
   void prepareEnclosingDeclarations({
     InterfaceElement? enclosingClassElement,
@@ -750,23 +973,53 @@
     }
 
     if (parent is ClassDeclaration) {
-      forClassElement(parent.declaredElement2!);
+      forClassElement(parent.declaredElement!);
       return true;
     }
 
     if (parent is ExtensionDeclaration) {
-      enclosingExtension = parent.declaredElement2!;
+      enclosingExtension = parent.declaredElement!;
       return true;
     }
 
     if (parent is MixinDeclaration) {
-      forClassElement(parent.declaredElement2!);
+      forClassElement(parent.declaredElement!);
       return true;
     }
 
     return false;
   }
 
+  /// Pushes an entry onto [_rewriteStack].
+  void pushRewrite(ExpressionImpl? expression) {
+    if (_debugRewriteStack) {
+      assert(_debugPrint('PUSH ${expression.runtimeType} $expression'));
+    }
+    _rewriteStack.add(expression);
+  }
+
+  /// Replaces the expression [oldNode] with [newNode], updating the node's
+  /// parent as appropriate.
+  ///
+  /// If [newNode] is the parent of [oldNode] already (because [newNode] became
+  /// the parent of [oldNode] in its constructor), this action will loop
+  /// infinitely; pass [oldNode]'s previous parent as [parent] to avoid this.
+  void replaceExpression(Expression oldNode, ExpressionImpl newNode,
+      {AstNode? parent}) {
+    assert(() {
+      assert(_replacements[oldNode] == null);
+      _replacements[oldNode] = newNode;
+      return true;
+    }());
+    if (_rewriteStack.isNotEmpty && identical(peekRewrite(), oldNode)) {
+      if (_debugRewriteStack) {
+        assert(_debugPrint('REPLACE ${newNode.runtimeType} $newNode'));
+      }
+      _rewriteStack.last = newNode;
+    }
+    NodeReplacer.replace(oldNode, newNode, parent: parent);
+  }
+
   /// Resolve LHS [node] of an assignment, an explicit [AssignmentExpression],
   /// or implicit [PrefixExpression] or [PostfixExpression].
   PropertyElementResolverResult resolveForWrite({
@@ -784,17 +1037,33 @@
       );
 
       analyzeExpression(node.index, result.indexContextType);
+      popRewrite();
       var whyNotPromoted = flowAnalysis.flow?.whyNotPromoted(node.index);
       checkIndexExpressionIndex(
         node.index,
-        readElement: result.readElement as ExecutableElement?,
+        readElement: hasRead ? result.readElement as ExecutableElement? : null,
         writeElement: result.writeElement as ExecutableElement?,
         whyNotPromoted: whyNotPromoted,
       );
 
       return result;
-    } else if (node is PrefixedIdentifier) {
-      node.prefix.accept(this);
+    } else if (node is PrefixedIdentifierImpl) {
+      final prefix = node.prefix;
+      prefix.accept(this);
+
+      // TODO(scheglov) It would be nice to rewrite all such cases.
+      if (prefix.staticType is RecordType) {
+        final propertyAccess = PropertyAccessImpl(
+          prefix,
+          node.period,
+          node.identifier,
+        );
+        NodeReplacer.replace(node, propertyAccess);
+        return resolveForWrite(
+          node: propertyAccess,
+          hasRead: hasRead,
+        );
+      }
 
       return _propertyElementResolver.resolvePrefixedIdentifier(
         node: node,
@@ -869,6 +1138,15 @@
     _thisType = thisType;
   }
 
+  @override
+  void setVariableType(PromotableElement variable, DartType type) {
+    if (variable is LocalVariableElementImpl) {
+      variable.type = type;
+    } else {
+      throw UnimplementedError('TODO(paulberry)');
+    }
+  }
+
   void setWriteElement(Expression node, Element? element) {
     DartType writeType = DynamicTypeImpl.instance;
     if (node is IndexExpression) {
@@ -927,7 +1205,7 @@
       if (flow != null) {
         var target = node.target;
         if (target is SimpleIdentifier &&
-            target.staticElement is ClassElement) {
+            target.staticElement is InterfaceElement) {
           // `?.` to access static methods is equivalent to `.`, so do nothing.
         } else {
           flow.nullAwareAccess_rightBegin(
@@ -966,6 +1244,12 @@
   }
 
   @override
+  DartType variableTypeFromInitializerType(DartType type) {
+    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/50078
+    return type;
+  }
+
+  @override
   void visitAdjacentStrings(AdjacentStrings node, {DartType? contextType}) {
     checkUnreachableNode(node);
     node.visitChildren(this);
@@ -999,6 +1283,7 @@
   void visitAssertInitializer(AssertInitializer node) {
     flowAnalysis.flow?.assert_begin();
     analyzeExpression(node.condition, typeProvider.boolType);
+    popRewrite();
     boolExpressionVerifier.checkForNonBoolExpression(
       node.condition,
       errorCode: CompileTimeErrorCode.NON_BOOL_EXPRESSION,
@@ -1013,6 +1298,7 @@
   void visitAssertStatement(AssertStatement node) {
     flowAnalysis.flow?.assert_begin();
     analyzeExpression(node.condition, typeProvider.boolType);
+    popRewrite();
     boolExpressionVerifier.checkForNonBoolExpression(
       node.condition,
       errorCode: CompileTimeErrorCode.NON_BOOL_EXPRESSION,
@@ -1049,6 +1335,7 @@
     }
     checkUnreachableNode(node);
     analyzeExpression(node.expression, futureUnion);
+    popRewrite();
     typeAnalyzer.visitAwaitExpression(node as AwaitExpressionImpl,
         contextType: contextType);
     _insertImplicitCallReference(
@@ -1113,6 +1400,7 @@
   void visitCascadeExpression(covariant CascadeExpressionImpl node,
       {DartType? contextType}) {
     analyzeExpression(node.target, contextType);
+    popRewrite();
 
     if (node.isNullAware) {
       flowAnalysis.flow!.nullAwareAccess_rightBegin(
@@ -1146,7 +1434,7 @@
     //
     var outerType = enclosingClass;
     try {
-      enclosingClass = node.declaredElement2;
+      enclosingClass = node.declaredElement;
       checkUnreachableNode(node);
       node.visitChildren(this);
       elementResolver.visitClassDeclaration(node);
@@ -1189,6 +1477,7 @@
     for (int i = 0; i < declarationCount; i++) {
       declarations[i].accept(this);
     }
+    checkIdle();
   }
 
   @override
@@ -1200,7 +1489,7 @@
 
     // TODO(scheglov) Do we need these checks for null?
     analyzeExpression(node.condition, typeProvider.boolType);
-    condition = node.condition;
+    condition = popRewrite()!;
     var whyNotPromoted = flowAnalysis.flow?.whyNotPromoted(condition);
     boolExpressionVerifier.checkForNonBoolCondition(condition,
         whyNotPromoted: whyNotPromoted);
@@ -1210,6 +1499,7 @@
       checkUnreachableNode(node.thenExpression);
     }
     analyzeExpression(node.thenExpression, contextType);
+    popRewrite();
     nullSafetyDeadCodeVerifier.flowEnd(node.thenExpression);
 
     Expression elseExpression = node.elseExpression;
@@ -1223,7 +1513,7 @@
     } else {
       analyzeExpression(elseExpression, contextType);
     }
-    elseExpression = node.elseExpression;
+    elseExpression = popRewrite()!;
 
     typeAnalyzer.visitConditionalExpression(node as ConditionalExpressionImpl,
         contextType: contextType);
@@ -1242,11 +1532,11 @@
     flowAnalysis.executableDeclaration_enter(node, node.parameters,
         isClosure: false);
 
-    var returnType = node.declaredElement2!.type.returnType;
+    var returnType = node.declaredElement!.type.returnType;
 
     var outerFunction = _enclosingFunction;
     try {
-      _enclosingFunction = node.declaredElement2;
+      _enclosingFunction = node.declaredElement;
       assert(_thisType == null);
       _setupThisType();
       checkUnreachableNode(node);
@@ -1284,7 +1574,7 @@
     var fieldType = fieldElement?.type;
     var expression = node.expression;
     analyzeExpression(expression, fieldType);
-    expression = node.expression;
+    expression = popRewrite()!;
     var whyNotPromoted = flowAnalysis.flow?.whyNotPromoted(expression);
     elementResolver.visitConstructorFieldInitializer(
         node as ConstructorFieldInitializerImpl);
@@ -1339,6 +1629,7 @@
     var defaultValue = node.defaultValue;
     if (defaultValue != null) {
       analyzeExpression(defaultValue, node.declaredElement?.type);
+      popRewrite();
     }
     ParameterElement element = node.declaredElement!;
 
@@ -1358,7 +1649,7 @@
 
     flowAnalysis.flow?.doStatement_conditionBegin();
     analyzeExpression(condition, typeProvider.boolType);
-    condition = node.condition;
+    condition = popRewrite()!;
     var whyNotPromoted = flowAnalysis.flow?.whyNotPromoted(condition);
     boolExpressionVerifier.checkForNonBoolCondition(condition,
         whyNotPromoted: whyNotPromoted);
@@ -1404,7 +1695,7 @@
     node.metadata.accept(this);
     checkUnreachableNode(node);
 
-    var element = node.declaredElement2 as ConstFieldElementImpl;
+    var element = node.declaredElement as ConstFieldElementImpl;
     var initializer = element.constantInitializer;
     if (initializer is InstanceCreationExpression) {
       var constructorName = initializer.constructorName;
@@ -1413,7 +1704,7 @@
         node.constructorElement = constructorElement;
         if (!constructorElement.isConst && constructorElement.isFactory) {
           final errorTarget =
-              node.arguments?.constructorSelector?.name ?? node.name2;
+              node.arguments?.constructorSelector?.name ?? node.name;
           errorReporter.reportErrorForOffset(
             CompileTimeErrorCode.ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR,
             errorTarget.offset,
@@ -1433,7 +1724,7 @@
           } else {
             errorReporter.reportErrorForToken(
               CompileTimeErrorCode.UNDEFINED_ENUM_CONSTRUCTOR_UNNAMED,
-              node.name2,
+              node.name,
             );
           }
         }
@@ -1450,6 +1741,7 @@
           );
           for (var argument in argumentList.arguments) {
             analyzeExpression(argument, argument.staticParameterElement?.type);
+            popRewrite();
           }
           arguments.typeArguments?.accept(this);
 
@@ -1465,7 +1757,7 @@
           if (requiredParameterCount != 0) {
             errorReporter.reportErrorForToken(
               CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS,
-              node.name2,
+              node.name,
               [requiredParameterCount, 0],
             );
           }
@@ -1483,7 +1775,7 @@
     //
     var outerType = enclosingClass;
     try {
-      enclosingClass = node.declaredElement2;
+      enclosingClass = node.declaredElement;
       checkUnreachableNode(node);
       node.visitChildren(this);
       elementResolver.visitEnumDeclaration(node);
@@ -1515,6 +1807,7 @@
         node.expression,
         inferenceContext.bodyContext!.contextType,
       );
+      popRewrite();
 
       flowAnalysis.flow?.handleExit();
 
@@ -1542,7 +1835,7 @@
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     var outerExtension = enclosingExtension;
     try {
-      enclosingExtension = node.declaredElement2!;
+      enclosingExtension = node.declaredElement!;
       checkUnreachableNode(node);
       node.visitChildren(this);
       elementResolver.visitExtensionDeclaration(node);
@@ -1636,16 +1929,17 @@
       isClosure: isLocal,
     );
 
-    var functionType = node.declaredElement2!.type;
+    var functionType = node.declaredElement!.type;
 
     var outerFunction = _enclosingFunction;
     try {
-      _enclosingFunction = node.declaredElement2;
+      _enclosingFunction = node.declaredElement;
       checkUnreachableNode(node);
       node.documentationComment?.accept(this);
       node.metadata.accept(this);
       node.returnType?.accept(this);
       analyzeExpression(node.functionExpression, functionType);
+      popRewrite();
       elementResolver.visitFunctionDeclaration(node);
     } finally {
       _enclosingFunction = outerFunction;
@@ -1654,7 +1948,7 @@
     if (!node.isSetter) {
       checkForBodyMayCompleteNormally(
         body: node.functionExpression.body,
-        errorNode: node.name2,
+        errorNode: node.name,
       );
     }
     flowAnalysis.executableDeclaration_exit(
@@ -1743,7 +2037,7 @@
     flowAnalysis.flow?.ifStatement_conditionBegin();
     Expression condition = node.condition;
     analyzeExpression(condition, typeProvider.boolType);
-    condition = node.condition;
+    condition = popRewrite()!;
     var whyNotPromoted = flowAnalysis.flow?.whyNotPromoted(condition);
 
     boolExpressionVerifier.checkForNonBoolCondition(condition,
@@ -1751,12 +2045,14 @@
 
     flowAnalysis.flow?.ifStatement_thenBegin(condition, node);
     (node.thenElement as CollectionElementImpl).resolveElement(this, context);
+    popRewrite();
     nullSafetyDeadCodeVerifier.flowEnd(node.thenElement);
 
     var elseElement = node.elseElement;
     if (elseElement != null) {
       flowAnalysis.flow?.ifStatement_elseBegin();
       (elseElement as CollectionElementImpl).resolveElement(this, context);
+      popRewrite();
       nullSafetyDeadCodeVerifier.flowEnd(elseElement);
     }
 
@@ -1764,31 +2060,47 @@
   }
 
   @override
-  void visitIfStatement(IfStatement node) {
+  void visitIfStatement(covariant IfStatementImpl node) {
     checkUnreachableNode(node);
-    flowAnalysis.flow?.ifStatement_conditionBegin();
 
-    Expression condition = node.condition;
+    final caseClause = node.caseClause;
+    if (caseClause != null) {
+      analyzeIfCaseStatement(
+        node,
+        node.expression,
+        caseClause.pattern,
+        caseClause.whenClause?.expression,
+        node.thenStatement,
+        node.elseStatement,
+      );
+      // Stack: (Expression, Guard)
+      popRewrite(); // guard
+      popRewrite()!; // expression
+    } else {
+      flowAnalysis.flow?.ifStatement_conditionBegin();
 
-    analyzeExpression(condition, typeProvider.boolType);
-    condition = node.condition;
-    var whyNotPromoted = flowAnalysis.flow?.whyNotPromoted(condition);
+      Expression condition = node.condition;
 
-    boolExpressionVerifier.checkForNonBoolCondition(condition,
-        whyNotPromoted: whyNotPromoted);
+      analyzeExpression(condition, typeProvider.boolType);
+      condition = popRewrite()!;
+      var whyNotPromoted = flowAnalysis.flow?.whyNotPromoted(condition);
 
-    flowAnalysis.flow?.ifStatement_thenBegin(condition, node);
-    node.thenStatement.accept(this);
-    nullSafetyDeadCodeVerifier.flowEnd(node.thenStatement);
+      boolExpressionVerifier.checkForNonBoolCondition(condition,
+          whyNotPromoted: whyNotPromoted);
 
-    var elseStatement = node.elseStatement;
-    if (elseStatement != null) {
-      flowAnalysis.flow?.ifStatement_elseBegin();
-      elseStatement.accept(this);
-      nullSafetyDeadCodeVerifier.flowEnd(elseStatement);
+      flowAnalysis.flow?.ifStatement_thenBegin(condition, node);
+      node.thenStatement.accept(this);
+      nullSafetyDeadCodeVerifier.flowEnd(node.thenStatement);
+
+      var elseStatement = node.elseStatement;
+      if (elseStatement != null) {
+        flowAnalysis.flow?.ifStatement_elseBegin();
+        elseStatement.accept(this);
+        nullSafetyDeadCodeVerifier.flowEnd(elseStatement);
+      }
+
+      flowAnalysis.flow?.ifStatement_end(elseStatement != null);
     }
-
-    flowAnalysis.flow?.ifStatement_end(elseStatement != null);
   }
 
   @override
@@ -1802,6 +2114,7 @@
       {DartType? contextType}) {
     checkUnreachableNode(node);
     analyzeExpression(node.expression, null);
+    popRewrite();
     node.typeArguments?.accept(this);
   }
 
@@ -1828,6 +2141,7 @@
     node.staticElement = element as MethodElement?;
 
     analyzeExpression(node.index, result.indexContextType);
+    popRewrite();
     var whyNotPromoted = flowAnalysis.flow?.whyNotPromoted(node.index);
     checkIndexExpressionIndex(
       node.index,
@@ -1922,7 +2236,8 @@
   void visitListLiteral(covariant ListLiteralImpl node,
       {DartType? contextType}) {
     checkUnreachableNode(node);
-    _typedLiteralResolver.resolveListLiteral(node, contextType: contextType);
+    _typedLiteralResolver.resolveListLiteral(node,
+        contextType: contextType ?? UnknownInferredType.instance);
   }
 
   @override
@@ -1930,7 +2245,9 @@
       {CollectionLiteralContext? context}) {
     checkUnreachableNode(node);
     analyzeExpression(node.key, context?.keyType);
+    popRewrite();
     analyzeExpression(node.value, context?.valueType);
+    popRewrite();
   }
 
   @override
@@ -1939,11 +2256,11 @@
     flowAnalysis.executableDeclaration_enter(node, node.parameters,
         isClosure: false);
 
-    DartType returnType = node.declaredElement2!.returnType;
+    DartType returnType = node.declaredElement!.returnType;
 
     var outerFunction = _enclosingFunction;
     try {
-      _enclosingFunction = node.declaredElement2;
+      _enclosingFunction = node.declaredElement;
       assert(_thisType == null);
       _setupThisType();
       checkUnreachableNode(node);
@@ -1962,7 +2279,7 @@
     if (!node.isSetter) {
       checkForBodyMayCompleteNormally(
         body: node.body,
-        errorNode: node.name2,
+        errorNode: node.name,
       );
     }
     flowAnalysis.executableDeclaration_exit(node.body, false);
@@ -1982,7 +2299,7 @@
       var flow = flowAnalysis.flow;
       if (flow != null) {
         if (target is SimpleIdentifierImpl &&
-            target.staticElement is ClassElement) {
+            target.staticElement is InterfaceElement) {
           // `?.` to access static methods is equivalent to `.`, so do nothing.
         } else {
           flow.nullAwareAccess_rightBegin(
@@ -2019,7 +2336,7 @@
     //
     var outerType = enclosingClass;
     try {
-      enclosingClass = node.declaredElement2!;
+      enclosingClass = node.declaredElement!;
       checkUnreachableNode(node);
       node.visitChildren(this);
       elementResolver.visitMixinDeclaration(node);
@@ -2033,6 +2350,7 @@
     checkUnreachableNode(node);
     node.name.accept(this);
     analyzeExpression(node.expression, contextType);
+    popRewrite();
     typeAnalyzer.visitNamedExpression(node as NamedExpressionImpl,
         contextType: contextType);
     // Any "why not promoted" information that flow analysis had associated with
@@ -2084,6 +2402,7 @@
       {DartType? contextType}) {
     checkUnreachableNode(node);
     analyzeExpression(node.expression, contextType);
+    popRewrite();
     typeAnalyzer.visitParenthesizedExpression(
         node as ParenthesizedExpressionImpl,
         contextType: contextType);
@@ -2209,6 +2528,7 @@
     RecordTypeAnnotationNamedField node,
   ) {
     node.visitChildren(this);
+    elementResolver.visitRecordTypeAnnotationNamedField(node);
   }
 
   @override
@@ -2223,6 +2543,7 @@
     RecordTypeAnnotationPositionalField node,
   ) {
     node.visitChildren(this);
+    elementResolver.visitRecordTypeAnnotationPositionalField(node);
   }
 
   @override
@@ -2266,7 +2587,7 @@
         inferenceContext.bodyContext?.contextType,
       );
       // Pick up the expression again in case it was rewritten.
-      expression = node.expression;
+      expression = popRewrite();
     }
 
     inferenceContext.bodyContext?.addReturnExpression(expression);
@@ -2277,7 +2598,7 @@
   void visitSetOrMapLiteral(SetOrMapLiteral node, {DartType? contextType}) {
     checkUnreachableNode(node);
     _typedLiteralResolver.resolveSetOrMapLiteral(node,
-        contextType: contextType);
+        contextType: contextType ?? UnknownInferredType.instance);
   }
 
   @override
@@ -2317,6 +2638,7 @@
     }
     checkUnreachableNode(node);
     analyzeExpression(node.expression, iterableType);
+    popRewrite();
 
     if (!node.isNullAware) {
       nullableDereferenceVerifier.expression(
@@ -2372,67 +2694,16 @@
   }
 
   @override
-  void visitSwitchCase(SwitchCase node) {
-    checkUnreachableNode(node);
-
-    checkUnreachableNode(node);
-    node.labels.accept(this);
-    analyzeExpression(node.expression, _enclosingSwitchStatementExpressionType);
-    node.statements.accept(this);
-
-    var flow = flowAnalysis.flow;
-    if (flow != null && flow.isReachable && _isNonNullableByDefault) {
-      var switchStatement = node.parent as SwitchStatement;
-      if (switchStatement.members.last != node && node.statements.isNotEmpty) {
-        errorReporter.reportErrorForToken(
-          CompileTimeErrorCode.SWITCH_CASE_COMPLETES_NORMALLY,
-          node.keyword,
-        );
-      }
-    }
-
-    nullSafetyDeadCodeVerifier.flowEnd(node);
-  }
-
-  @override
-  void visitSwitchDefault(SwitchDefault node) {
-    checkUnreachableNode(node);
-    node.visitChildren(this);
-    nullSafetyDeadCodeVerifier.flowEnd(node);
-  }
-
-  @override
   void visitSwitchStatement(SwitchStatement node) {
+    // Stack: ()
     checkUnreachableNode(node);
 
-    var previousExpressionType = _enclosingSwitchStatementExpressionType;
-    try {
-      var expression = node.expression;
-      expression.accept(this);
-      expression = node.expression;
-
-      _enclosingSwitchStatementExpressionType = expression.typeOrThrow;
-
-      var flow = flowAnalysis.flow!;
-
-      flow.switchStatement_expressionEnd(node);
-
-      var exhaustiveness = _SwitchExhaustiveness(
-        _enclosingSwitchStatementExpressionType!,
-      );
-
-      var members = node.members;
-      for (var member in members) {
-        flow.switchStatement_beginCase(member.labels.isNotEmpty, node);
-        member.accept(this);
-
-        exhaustiveness.visitSwitchMember(member);
-      }
-
-      flow.switchStatement_end(exhaustiveness.isExhaustive);
-    } finally {
-      _enclosingSwitchStatementExpressionType = previousExpressionType;
-    }
+    var previousExhaustiveness = switchExhaustiveness;
+    analyzeSwitchStatement(node, node.expression, node.members.length);
+    // Stack: (Expression)
+    popRewrite();
+    // Stack: ()
+    switchExhaustiveness = previousExhaustiveness;
   }
 
   @override
@@ -2544,7 +2815,7 @@
   void visitVariableDeclaration(VariableDeclaration node) {
     _variableDeclarationResolver.resolve(node as VariableDeclarationImpl);
 
-    var declaredElement = node.declaredElement2!;
+    var declaredElement = node.declaredElement!;
 
     var initializer = node.initializer;
     var parent = node.parent as VariableDeclarationList;
@@ -2582,7 +2853,7 @@
 
     flowAnalysis.flow?.whileStatement_conditionBegin(node);
     analyzeExpression(condition, typeProvider.boolType);
-    condition = node.condition;
+    condition = popRewrite()!;
     var whyNotPromoted = flowAnalysis.flow?.whyNotPromoted(condition);
 
     boolExpressionVerifier.checkForNonBoolCondition(node.condition,
@@ -2608,7 +2879,7 @@
   }
 
   void _checkTopLevelCycle(VariableDeclaration node) {
-    var element = node.declaredElement2;
+    var element = node.declaredElement;
     if (element is! PropertyInducingElementImpl) {
       return;
     }
@@ -2624,7 +2895,7 @@
     if (error.kind == TopLevelInferenceErrorKind.dependencyCycle) {
       var argumentsText = error.arguments.join(', ');
       errorReporter.reportErrorForToken(CompileTimeErrorCode.TOP_LEVEL_CYCLE,
-          node.name2, [node.name2.lexeme, argumentsText]);
+          node.name, [node.name.lexeme, argumentsText]);
     }
   }
 
@@ -2637,6 +2908,14 @@
     return typeProvider.futureOrType(type);
   }
 
+  /// Helper function used to print information to the console in debug mode.
+  /// This method returns `true` so that it can be conveniently called inside of
+  /// an `assert` statement.
+  bool _debugPrint(String s) {
+    print(s);
+    return true;
+  }
+
   /// If `expression` should be treated as `expression.call`, inserts an
   /// [ImplicitCallReference] node which wraps [expression].
   void _insertImplicitCallReference(ExpressionImpl expression,
@@ -2689,7 +2968,7 @@
       typeArguments: null,
       typeArgumentTypes: typeArgumentTypes,
     );
-    NodeReplacer.replace(expression, callReference, parent: parent);
+    replaceExpression(expression, callReference, parent: parent);
 
     callReference.staticType = callMethodType;
   }
@@ -2711,7 +2990,8 @@
         _migratableAstInfoProvider.isPropertyAccessNullAware(function) &&
         _isNonNullableByDefault) {
       var target = function.target;
-      if (target is SimpleIdentifier && target.staticElement is ClassElement) {
+      if (target is SimpleIdentifier &&
+          target.staticElement is InterfaceElement) {
         // `?.` to access static methods is equivalent to `.`, so do nothing.
       } else {
         flowAnalysis.flow!.nullAwareAccess_rightBegin(function,
@@ -2936,12 +3216,13 @@
       var element = conditionalKnownValue ? node.thenElement : node.elseElement;
       if (element != null) {
         (element as CollectionElementImpl).resolveElement(this, context);
+        popRewrite();
       }
     }
   }
 
   @override
-  void visitIfStatement(IfStatement node) {
+  void visitIfStatement(covariant IfStatementImpl node) {
     var conditionalKnownValue =
         _migrationResolutionHooks.getConditionalKnownValue(node);
     if (conditionalKnownValue == null) {
@@ -3068,7 +3349,7 @@
   void visitClassDeclaration(ClassDeclaration node) {
     Scope outerScope = nameScope;
     try {
-      ClassElement element = node.declaredElement2!;
+      ClassElement element = node.declaredElement!;
       node.metadata.accept(this);
 
       nameScope = TypeParameterScope(
@@ -3103,7 +3384,7 @@
     node.metadata.accept(this);
     Scope outerScope = nameScope;
     try {
-      ClassElement element = node.declaredElement2!;
+      ClassElement element = node.declaredElement!;
       nameScope = InterfaceScope(
         TypeParameterScope(nameScope, element.typeParameters),
         element,
@@ -3136,7 +3417,7 @@
     (node.body as FunctionBodyImpl).localVariableInfo = _localVariableInfo;
     Scope outerScope = nameScope;
     try {
-      ConstructorElement element = node.declaredElement2!;
+      ConstructorElement element = node.declaredElement!;
 
       node.metadata.accept(this);
       node.returnType.accept(this);
@@ -3176,7 +3457,7 @@
 
   @override
   void visitDeclaredIdentifier(DeclaredIdentifier node) {
-    _define(node.declaredElement2!);
+    _define(node.declaredElement!);
     super.visitDeclaredIdentifier(node);
   }
 
@@ -3200,7 +3481,7 @@
   void visitEnumDeclaration(EnumDeclaration node) {
     Scope outerScope = nameScope;
     try {
-      final element = node.declaredElement2!;
+      final element = node.declaredElement!;
       node.metadata.accept(this);
 
       nameScope = TypeParameterScope(
@@ -3239,7 +3520,7 @@
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     Scope outerScope = nameScope;
     try {
-      ExtensionElement element = node.declaredElement2!;
+      ExtensionElement element = node.declaredElement!;
       node.metadata.accept(this);
 
       nameScope = TypeParameterScope(
@@ -3312,7 +3593,7 @@
         parent.declaredElement!.parameters,
       );
     } else if (parent is FunctionTypeAlias) {
-      var aliasedElement = parent.declaredElement2!.aliasedElement;
+      var aliasedElement = parent.declaredElement!.aliasedElement;
       var functionElement = aliasedElement as GenericFunctionTypeElement;
       nameScope = FormalParameterScope(
         nameScope,
@@ -3321,7 +3602,7 @@
     } else if (parent is MethodDeclaration) {
       nameScope = FormalParameterScope(
         nameScope,
-        parent.declaredElement2!.parameters,
+        parent.declaredElement!.parameters,
       );
     }
   }
@@ -3359,10 +3640,10 @@
     Scope outerScope = nameScope;
     try {
       _enclosingClosure = node.parent is FunctionDeclarationStatement
-          ? node.declaredElement2
+          ? node.declaredElement
           : null;
       node.metadata.accept(this);
-      var element = node.declaredElement2!;
+      var element = node.declaredElement!;
       nameScope = TypeParameterScope(
         nameScope,
         element.typeParameters,
@@ -3416,7 +3697,7 @@
     node.metadata.accept(this);
     Scope outerScope = nameScope;
     try {
-      var element = node.declaredElement2!;
+      var element = node.declaredElement!;
       nameScope = TypeParameterScope(nameScope, element.typeParameters);
       visitFunctionTypeAliasInScope(node);
     } finally {
@@ -3490,7 +3771,7 @@
     node.metadata.accept(this);
     Scope outerScope = nameScope;
     try {
-      var element = node.declaredElement2 as TypeAliasElement;
+      var element = node.declaredElement as TypeAliasElement;
       nameScope = TypeParameterScope(nameScope, element.typeParameters);
       _setNodeNameScope(node, nameScope);
       visitGenericTypeAliasInScope(node);
@@ -3518,6 +3799,7 @@
   @override
   void visitIfStatement(IfStatement node) {
     node.condition.accept(this);
+    node.caseClause?.accept(this);
     visitStatementInScope(node.thenStatement);
     visitStatementInScope(node.elseStatement);
   }
@@ -3538,7 +3820,7 @@
     node.metadata.accept(this);
     Scope outerScope = nameScope;
     try {
-      ExecutableElement element = node.declaredElement2!;
+      ExecutableElement element = node.declaredElement!;
       nameScope = TypeParameterScope(
         nameScope,
         element.typeParameters,
@@ -3580,7 +3862,7 @@
   void visitMixinDeclaration(MixinDeclaration node) {
     Scope outerScope = nameScope;
     try {
-      final element = node.declaredElement2!;
+      final element = node.declaredElement!;
       node.metadata.accept(this);
 
       nameScope = TypeParameterScope(nameScope, element.typeParameters);
@@ -3664,7 +3946,7 @@
       if (node.inSetterContext()) {
         _localVariableInfo.potentiallyMutatedInScope.add(element);
         if (_enclosingClosure != null &&
-            element.enclosingElement3 != _enclosingClosure) {
+            element.enclosingElement != _enclosingClosure) {
           _localVariableInfo.potentiallyMutatedInClosure.add(element);
         }
       }
@@ -3738,7 +4020,7 @@
     super.visitVariableDeclaration(node);
 
     if (node.parent!.parent is ForParts) {
-      _define(node.declaredElement2!);
+      _define(node.declaredElement!);
     }
   }
 
@@ -3850,7 +4132,7 @@
 
 /// Tracker for whether a `switch` statement has `default` or is on an
 /// enumeration, and all the enum constants are covered.
-class _SwitchExhaustiveness {
+class SwitchExhaustiveness {
   /// If the switch is on an enumeration, the set of enum constants to cover.
   /// Otherwise `null`.
   final Set<FieldElement>? _enumConstants;
@@ -3862,20 +4144,20 @@
 
   bool isExhaustive = false;
 
-  factory _SwitchExhaustiveness(DartType expressionType) {
+  factory SwitchExhaustiveness(DartType expressionType) {
     if (expressionType is InterfaceType) {
       var enum_ = expressionType.element2;
       if (enum_ is EnumElementImpl) {
-        return _SwitchExhaustiveness._(
+        return SwitchExhaustiveness._(
           enum_.constants.toSet(),
           expressionType.nullabilitySuffix == NullabilitySuffix.none,
         );
       }
     }
-    return _SwitchExhaustiveness._(null, false);
+    return SwitchExhaustiveness._(null, false);
   }
 
-  _SwitchExhaustiveness._(this._enumConstants, this._isNullEnumValueCovered);
+  SwitchExhaustiveness._(this._enumConstants, this._isNullEnumValueCovered);
 
   void visitSwitchMember(SwitchMember node) {
     if (_enumConstants != null && node is SwitchCase) {
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 e564a7a..54a9b3f 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -5,12 +5,9 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
-import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:meta/meta.dart';
 
@@ -54,15 +51,6 @@
           rightBracket:
               TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET));
 
-  static MethodInvocationImpl cascadedMethodInvocation(String methodName,
-          [List<Expression> arguments = const []]) =>
-      astFactory.methodInvocation(
-          null,
-          TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD),
-          identifier3(methodName),
-          null,
-          argumentList(arguments));
-
   static PropertyAccessImpl cascadedPropertyAccess(String propertyName) =>
       astFactory.propertyAccess(
           null,
@@ -89,44 +77,17 @@
           augmentKeyword:
               isAugmentation ? TokenFactory.tokenFromString('augment') : null,
           classKeyword: TokenFactory.tokenFromKeyword(Keyword.CLASS),
-          name: identifier3(name),
+          name: TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, name),
           typeParameters: typeParameters as TypeParameterListImpl?,
           extendsClause: extendsClause as ExtendsClauseImpl?,
           withClause: withClause as WithClauseImpl?,
           implementsClause: implementsClause as ImplementsClauseImpl?,
+          nativeClause: null,
           leftBracket: TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET),
           members: members,
           rightBracket:
               TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
 
-  static ClassTypeAliasImpl classTypeAlias(
-          String name,
-          TypeParameterList? typeParameters,
-          Keyword? abstractKeyword,
-          NamedType superclass,
-          WithClause withClause,
-          ImplementsClause? implementsClause,
-          {bool isMacro = false,
-          bool isAugmentation = false}) =>
-      ClassTypeAliasImpl(
-        comment: null,
-        metadata: null,
-        typedefKeyword: TokenFactory.tokenFromKeyword(Keyword.CLASS),
-        name: identifier3(name),
-        typeParameters: typeParameters as TypeParameterListImpl?,
-        equals: TokenFactory.tokenFromType(TokenType.EQ),
-        abstractKeyword: abstractKeyword == null
-            ? null
-            : TokenFactory.tokenFromKeyword(abstractKeyword),
-        macroKeyword: isMacro ? TokenFactory.tokenFromString('macro') : null,
-        augmentKeyword:
-            isAugmentation ? TokenFactory.tokenFromString('augment') : null,
-        superclass: superclass as NamedTypeImpl,
-        withClause: withClause as WithClauseImpl,
-        implementsClause: implementsClause as ImplementsClauseImpl?,
-        semicolon: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-      );
-
   static CompilationUnitImpl compilationUnit() =>
       compilationUnit8(null, [], []);
 
@@ -195,7 +156,7 @@
         returnType: returnType as IdentifierImpl,
         period:
             name == null ? null : TokenFactory.tokenFromType(TokenType.PERIOD),
-        name: name == null ? null : identifier3(name),
+        name: name == null ? null : identifier3(name).token,
         parameters: parameters as FormalParameterListImpl,
         separator: initializers.isEmpty
             ? null
@@ -207,59 +168,6 @@
         ),
       );
 
-  static ConstructorDeclarationImpl constructorDeclaration2(
-          Keyword? constKeyword,
-          Keyword? factoryKeyword,
-          Identifier returnType,
-          String? name,
-          FormalParameterList parameters,
-          List<ConstructorInitializer> initializers,
-          FunctionBody body) =>
-      ConstructorDeclarationImpl(
-        comment: null,
-        metadata: null,
-        externalKeyword: null,
-        constKeyword: constKeyword == null
-            ? null
-            : TokenFactory.tokenFromKeyword(constKeyword),
-        factoryKeyword: factoryKeyword == null
-            ? null
-            : TokenFactory.tokenFromKeyword(factoryKeyword),
-        returnType: returnType as IdentifierImpl,
-        period:
-            name == null ? null : TokenFactory.tokenFromType(TokenType.PERIOD),
-        name: name == null ? null : identifier3(name),
-        parameters: parameters as FormalParameterListImpl,
-        separator: initializers.isEmpty
-            ? null
-            : TokenFactory.tokenFromType(TokenType.PERIOD),
-        initializers: initializers,
-        redirectedConstructor: null,
-        body: body as FunctionBodyImpl,
-      );
-
-  static DeclaredIdentifierImpl declaredIdentifier(
-          Keyword keyword, String identifier) =>
-      declaredIdentifier2(keyword, null, identifier);
-
-  static DeclaredIdentifierImpl declaredIdentifier2(
-          Keyword? keyword, TypeAnnotation? type, String identifier) =>
-      DeclaredIdentifierImpl(
-        comment: null,
-        metadata: null,
-        keyword:
-            keyword == null ? null : TokenFactory.tokenFromKeyword(keyword),
-        type: type as TypeAnnotationImpl?,
-        identifier: identifier3(identifier),
-      );
-
-  static DeclaredIdentifierImpl declaredIdentifier3(String identifier) =>
-      declaredIdentifier2(Keyword.VAR, null, identifier);
-
-  static DeclaredIdentifierImpl declaredIdentifier4(
-          TypeAnnotation type, String identifier) =>
-      declaredIdentifier2(null, type, identifier);
-
   static CommentImpl documentationComment(
       List<Token> tokens, List<CommentReference> references) {
     return astFactory.documentationComment(tokens, references);
@@ -282,13 +190,6 @@
           [List<Combinator> combinators = const []]) =>
       exportDirective([], uri, combinators);
 
-  static ExpressionStatementImpl expressionStatement(Expression expression) =>
-      astFactory.expressionStatement(
-          expression, TokenFactory.tokenFromType(TokenType.SEMICOLON));
-
-  static ExtendsClauseImpl extendsClause(NamedType type) => astFactory
-      .extendsClause(TokenFactory.tokenFromKeyword(Keyword.EXTENDS), type);
-
   static ExtensionDeclarationImpl extensionDeclaration(
           {required String name,
           required bool isExtensionTypeDeclaration,
@@ -304,7 +205,7 @@
         typeKeyword: isExtensionTypeDeclaration
             ? TokenFactory.tokenFromString('type')
             : null,
-        name: identifier3(name),
+        name: identifier3(name).token,
         typeParameters: typeParameters as TypeParameterListImpl?,
         onKeyword: TokenFactory.tokenFromKeyword(Keyword.ON),
         extendedType: extendedType as TypeAnnotationImpl,
@@ -355,38 +256,12 @@
           type: type,
           thisKeyword: TokenFactory.tokenFromKeyword(Keyword.THIS),
           period: TokenFactory.tokenFromType(TokenType.PERIOD),
-          identifier: identifier3(identifier),
+          name: identifier3(identifier).token,
           parameters: parameterList);
 
   static FieldFormalParameterImpl fieldFormalParameter2(String identifier) =>
       fieldFormalParameter(null, null, identifier);
 
-  static ForEachPartsWithDeclarationImpl forEachPartsWithDeclaration(
-          DeclaredIdentifier loopVariable, Expression iterable) =>
-      astFactory.forEachPartsWithDeclaration(
-          loopVariable: loopVariable,
-          inKeyword: TokenFactory.tokenFromKeyword(Keyword.IN),
-          iterable: iterable);
-
-  static ForEachPartsWithIdentifierImpl forEachPartsWithIdentifier(
-          SimpleIdentifier identifier, Expression iterable) =>
-      astFactory.forEachPartsWithIdentifier(
-          identifier: identifier,
-          inKeyword: TokenFactory.tokenFromKeyword(Keyword.IN),
-          iterable: iterable);
-
-  static ForElementImpl forElement(
-          ForLoopParts forLoopParts, CollectionElement body,
-          {bool hasAwait = false}) =>
-      astFactory.forElement(
-          awaitKeyword:
-              hasAwait ? TokenFactory.tokenFromKeyword(Keyword.AWAIT) : null,
-          forKeyword: TokenFactory.tokenFromKeyword(Keyword.FOR),
-          leftParenthesis: TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-          forLoopParts: forLoopParts,
-          rightParenthesis: TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-          body: body);
-
   static FormalParameterListImpl formalParameterList(
           [List<FormalParameter> parameters = const []]) =>
       astFactory.formalParameterList(
@@ -396,127 +271,14 @@
           null,
           TokenFactory.tokenFromType(TokenType.CLOSE_PAREN));
 
-  static ForPartsWithDeclarationsImpl forPartsWithDeclarations(
-          VariableDeclarationList variables,
-          Expression? condition,
-          List<Expression>? updaters) =>
-      astFactory.forPartsWithDeclarations(
-          variables: variables,
-          leftSeparator: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-          condition: condition,
-          rightSeparator: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-          updaters: updaters);
-
-  static ForPartsWithExpressionImpl forPartsWithExpression(
-          Expression? initialization,
-          Expression? condition,
-          List<Expression>? updaters) =>
-      astFactory.forPartsWithExpression(
-          initialization: initialization,
-          leftSeparator: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-          condition: condition,
-          rightSeparator: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-          updaters: updaters);
-
-  static ForStatementImpl forStatement(
-          ForLoopParts forLoopParts, Statement body) =>
-      astFactory.forStatement(
-          forKeyword: TokenFactory.tokenFromKeyword(Keyword.FOR),
-          leftParenthesis: TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-          forLoopParts: forLoopParts,
-          rightParenthesis: TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-          body: body);
-
-  static FunctionDeclarationImpl functionDeclaration(
-          TypeAnnotation? type,
-          Keyword? keyword,
-          String name,
-          FunctionExpression functionExpression) =>
-      FunctionDeclarationImpl(
-        comment: null,
-        metadata: null,
-        augmentKeyword: null,
-        externalKeyword: null,
-        returnType: type as TypeAnnotationImpl?,
-        propertyKeyword:
-            keyword == null ? null : TokenFactory.tokenFromKeyword(keyword),
-        name: identifier3(name),
-        functionExpression: functionExpression as FunctionExpressionImpl,
-      );
-
-  static FunctionDeclarationStatementImpl functionDeclarationStatement(
-          TypeAnnotation? type,
-          Keyword? keyword,
-          String name,
-          FunctionExpression functionExpression) =>
-      astFactory.functionDeclarationStatement(
-          functionDeclaration(type, keyword, name, functionExpression));
-
-  static FunctionExpressionImpl functionExpression2(
-          FormalParameterList parameters, FunctionBody body) =>
-      astFactory.functionExpression(null, parameters, body);
-
-  static FunctionExpressionImpl functionExpression3(
-          TypeParameterList typeParameters,
-          FormalParameterList parameters,
-          FunctionBody body) =>
-      astFactory.functionExpression(typeParameters, parameters, body);
-
-  static FunctionExpressionInvocationImpl functionExpressionInvocation(
-          Expression function,
-          [List<Expression> arguments = const []]) =>
-      functionExpressionInvocation2(function, null, arguments);
-
-  static FunctionExpressionInvocationImpl functionExpressionInvocation2(
-          Expression function,
-          [TypeArgumentList? typeArguments,
-          List<Expression> arguments = const []]) =>
-      astFactory.functionExpressionInvocation(
-          function, typeArguments, argumentList(arguments));
-
   static FunctionTypedFormalParameterImpl functionTypedFormalParameter(
           TypeAnnotation? returnType, String identifier,
           [List<FormalParameter> parameters = const []]) =>
       astFactory.functionTypedFormalParameter2(
           returnType: returnType,
-          identifier: identifier3(identifier),
+          name: identifier3(identifier).token,
           parameters: formalParameterList(parameters));
 
-  static GenericFunctionTypeImpl genericFunctionType(TypeAnnotation returnType,
-          TypeParameterList typeParameters, FormalParameterList parameters,
-          {bool question = false}) =>
-      astFactory.genericFunctionType(returnType,
-          TokenFactory.tokenFromString("Function"), typeParameters, parameters,
-          question:
-              question ? TokenFactory.tokenFromType(TokenType.QUESTION) : null);
-
-  static GenericTypeAliasImpl genericTypeAlias(String name,
-          TypeParameterList typeParameters, GenericFunctionType functionType) =>
-      GenericTypeAliasImpl(
-        comment: null,
-        metadata: null,
-        typedefKeyword: TokenFactory.tokenFromKeyword(Keyword.TYPEDEF),
-        name: identifier3(name),
-        typeParameters: typeParameters as TypeParameterListImpl,
-        equals: TokenFactory.tokenFromType(TokenType.EQ),
-        type: functionType as GenericFunctionTypeImpl,
-        semicolon: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-      );
-
-  static HideClauseImpl hideClause(List<ShowHideClauseElement> elements) =>
-      astFactory.hideClause(
-          hideKeyword: TokenFactory.tokenFromString("hide"),
-          elements: elements);
-
-  static HideCombinatorImpl hideCombinator(
-          List<SimpleIdentifier> identifiers) =>
-      astFactory.hideCombinator(
-          TokenFactory.tokenFromString("hide"), identifiers);
-
-  static HideCombinatorImpl hideCombinator2(List<String> identifiers) =>
-      astFactory.hideCombinator(
-          TokenFactory.tokenFromString("hide"), identifierList(identifiers));
-
   static PrefixedIdentifierImpl identifier(
           SimpleIdentifier prefix, SimpleIdentifier identifier) =>
       astFactory.prefixedIdentifier(
@@ -543,41 +305,6 @@
         .toList();
   }
 
-  static IfElementImpl ifElement(
-          Expression condition, CollectionElement thenElement,
-          [CollectionElement? elseElement]) =>
-      astFactory.ifElement(
-          ifKeyword: TokenFactory.tokenFromKeyword(Keyword.IF),
-          leftParenthesis: TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-          condition: condition,
-          rightParenthesis: TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-          thenElement: thenElement,
-          elseKeyword: elseElement == null
-              ? null
-              : TokenFactory.tokenFromKeyword(Keyword.ELSE),
-          elseElement: elseElement);
-
-  static IfStatementImpl ifStatement(
-          Expression condition, Statement thenStatement) =>
-      ifStatement2(condition, thenStatement, null);
-
-  static IfStatementImpl ifStatement2(Expression condition,
-          Statement thenStatement, Statement? elseStatement) =>
-      astFactory.ifStatement(
-          TokenFactory.tokenFromKeyword(Keyword.IF),
-          TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-          condition,
-          TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-          thenStatement,
-          elseStatement == null
-              ? null
-              : TokenFactory.tokenFromKeyword(Keyword.ELSE),
-          elseStatement);
-
-  static ImplementsClauseImpl implementsClause(List<NamedType> types) =>
-      astFactory.implementsClause(
-          TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS), types);
-
   static ImportDirectiveImpl importDirective(List<Annotation> metadata,
           String uri, bool isDeferred, String? prefix,
           [List<Combinator> combinators = const []]) =>
@@ -645,10 +372,6 @@
           name,
           argumentList(arguments));
 
-  static IntegerLiteralImpl integer(int value) => astFactory.integerLiteral(
-      TokenFactory.tokenFromTypeAndString(TokenType.INT, value.toString()),
-      value);
-
   static InterpolationExpressionImpl interpolationExpression(
           Expression expression) =>
       astFactory.interpolationExpression(
@@ -663,11 +386,6 @@
           identifier3(identifier),
           null);
 
-  static InterpolationStringImpl interpolationString(
-          String contents, String value) =>
-      astFactory.interpolationString(
-          TokenFactory.tokenFromString(contents), value);
-
   static IsExpressionImpl isExpression(
           Expression expression, bool negated, TypeAnnotation type) =>
       astFactory.isExpression(
@@ -676,28 +394,25 @@
           negated ? TokenFactory.tokenFromType(TokenType.BANG) : null,
           type);
 
-  static LabelImpl label(SimpleIdentifier label) =>
-      astFactory.label(label, TokenFactory.tokenFromType(TokenType.COLON));
-
-  static LabelImpl label2(String label) =>
-      AstTestFactory.label(identifier3(label));
-
   static LabeledStatementImpl labeledStatement(
           List<Label> labels, Statement statement) =>
       astFactory.labeledStatement(labels, statement);
 
   static LibraryDirectiveImpl libraryDirective(
-          List<Annotation> metadata, LibraryIdentifier libraryName) =>
+          List<Annotation> metadata, LibraryIdentifier? libraryName) =>
       LibraryDirectiveImpl(
         comment: null,
         metadata: metadata,
         libraryKeyword: TokenFactory.tokenFromKeyword(Keyword.LIBRARY),
-        name: libraryName as LibraryIdentifierImpl,
+        name: libraryName as LibraryIdentifierImpl?,
         semicolon: TokenFactory.tokenFromType(TokenType.SEMICOLON),
       );
 
-  static LibraryDirectiveImpl libraryDirective2(String libraryName) =>
-      libraryDirective(<Annotation>[], libraryIdentifier2([libraryName]));
+  static LibraryDirectiveImpl libraryDirective2(String? libraryName) =>
+      libraryDirective(
+        <Annotation>[],
+        libraryName == null ? null : libraryIdentifier2([libraryName]),
+      );
 
   static LibraryIdentifierImpl libraryIdentifier(
           List<SimpleIdentifier> components) =>
@@ -724,19 +439,6 @@
           elements,
           TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET));
 
-  static MapLiteralEntryImpl mapLiteralEntry(String key, Expression value) =>
-      astFactory.mapLiteralEntry(
-          string2(key), TokenFactory.tokenFromType(TokenType.COLON), value);
-
-  static MapLiteralEntryImpl mapLiteralEntry2(
-          Expression key, Expression value) =>
-      astFactory.mapLiteralEntry(
-          key, TokenFactory.tokenFromType(TokenType.COLON), value);
-
-  static MapLiteralEntryImpl mapLiteralEntry3(String key, String value) =>
-      astFactory.mapLiteralEntry(string2(key),
-          TokenFactory.tokenFromType(TokenType.COLON), string2(value));
-
   static MethodDeclarationImpl methodDeclaration(
           Keyword? modifier,
           TypeAnnotation? returnType,
@@ -755,7 +457,7 @@
             property == null ? null : TokenFactory.tokenFromKeyword(property),
         operatorKeyword:
             operator == null ? null : TokenFactory.tokenFromKeyword(operator),
-        name: name as SimpleIdentifierImpl,
+        name: name.token,
         typeParameters: null,
         parameters: parameters as FormalParameterListImpl?,
         body: EmptyFunctionBodyImpl(
@@ -763,167 +465,12 @@
         ),
       );
 
-  static MethodDeclarationImpl methodDeclaration2(
-          Keyword? modifier,
-          TypeAnnotation? returnType,
-          Keyword? property,
-          Keyword? operator,
-          SimpleIdentifier name,
-          FormalParameterList? parameters,
-          FunctionBody body) =>
-      MethodDeclarationImpl(
-        comment: null,
-        metadata: null,
-        externalKeyword: null,
-        modifierKeyword:
-            modifier == null ? null : TokenFactory.tokenFromKeyword(modifier),
-        returnType: returnType as TypeAnnotationImpl?,
-        propertyKeyword:
-            property == null ? null : TokenFactory.tokenFromKeyword(property),
-        operatorKeyword:
-            operator == null ? null : TokenFactory.tokenFromKeyword(operator),
-        name: name as SimpleIdentifierImpl,
-        typeParameters: null,
-        parameters: parameters as FormalParameterListImpl?,
-        body: body as FunctionBodyImpl,
-      );
-
-  static MethodDeclarationImpl methodDeclaration3(
-          Keyword? modifier,
-          TypeAnnotation? returnType,
-          Keyword? property,
-          Keyword? operator,
-          SimpleIdentifier name,
-          TypeParameterList? typeParameters,
-          FormalParameterList? parameters,
-          FunctionBody body) =>
-      MethodDeclarationImpl(
-        comment: null,
-        metadata: null,
-        externalKeyword: null,
-        modifierKeyword:
-            modifier == null ? null : TokenFactory.tokenFromKeyword(modifier),
-        returnType: returnType as TypeAnnotationImpl?,
-        propertyKeyword:
-            property == null ? null : TokenFactory.tokenFromKeyword(property),
-        operatorKeyword:
-            operator == null ? null : TokenFactory.tokenFromKeyword(operator),
-        name: name as SimpleIdentifierImpl,
-        typeParameters: typeParameters as TypeParameterListImpl?,
-        parameters: parameters as FormalParameterListImpl?,
-        body: body as FunctionBodyImpl,
-      );
-
-  static MethodDeclarationImpl methodDeclaration4(
-          {bool external = false,
-          Keyword? modifier,
-          TypeAnnotation? returnType,
-          Keyword? property,
-          bool operator = false,
-          required String name,
-          FormalParameterList? parameters,
-          required FunctionBody body}) =>
-      MethodDeclarationImpl(
-        comment: null,
-        metadata: null,
-        externalKeyword:
-            external ? TokenFactory.tokenFromKeyword(Keyword.EXTERNAL) : null,
-        modifierKeyword:
-            modifier == null ? null : TokenFactory.tokenFromKeyword(modifier),
-        returnType: returnType as TypeAnnotationImpl?,
-        propertyKeyword:
-            property == null ? null : TokenFactory.tokenFromKeyword(property),
-        operatorKeyword:
-            operator ? TokenFactory.tokenFromKeyword(Keyword.OPERATOR) : null,
-        name: identifier3(name),
-        typeParameters: null,
-        parameters: parameters as FormalParameterListImpl?,
-        body: body as FunctionBodyImpl,
-      );
-
-  static MethodInvocationImpl methodInvocation(
-          Expression? target, String methodName,
-          [List<Expression> arguments = const [],
-          TokenType operator = TokenType.PERIOD]) =>
-      astFactory.methodInvocation(
-          target,
-          target == null ? null : TokenFactory.tokenFromType(operator),
-          identifier3(methodName),
-          null,
-          argumentList(arguments));
-
-  static MethodInvocationImpl methodInvocation2(String methodName,
-          [List<Expression> arguments = const []]) =>
-      methodInvocation(null, methodName, arguments);
-
-  static MethodInvocationImpl methodInvocation3(Expression? target,
-          String methodName, TypeArgumentList? typeArguments,
-          [List<Expression> arguments = const [],
-          TokenType operator = TokenType.PERIOD]) =>
-      astFactory.methodInvocation(
-          target,
-          target == null ? null : TokenFactory.tokenFromType(operator),
-          identifier3(methodName),
-          typeArguments,
-          argumentList(arguments));
-
-  static NamedExpressionImpl namedExpression(
-          Label label, Expression expression) =>
-      astFactory.namedExpression(label, expression);
-
-  static NamedExpressionImpl namedExpression2(
-          String label, Expression expression) =>
-      namedExpression(label2(label), 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));
-
   static NativeFunctionBodyImpl nativeFunctionBody(String nativeMethodName) =>
       astFactory.nativeFunctionBody(
           TokenFactory.tokenFromString("native"),
           string2(nativeMethodName),
           TokenFactory.tokenFromType(TokenType.SEMICOLON));
 
-  static NullLiteralImpl nullLiteral() =>
-      astFactory.nullLiteral(TokenFactory.tokenFromKeyword(Keyword.NULL));
-
   static ParenthesizedExpressionImpl parenthesizedExpression(
           Expression expression) =>
       astFactory.parenthesizedExpression(
@@ -1024,15 +571,6 @@
           showKeyword: TokenFactory.tokenFromString("show"),
           elements: elements);
 
-  static ShowCombinatorImpl showCombinator(
-          List<SimpleIdentifier> identifiers) =>
-      astFactory.showCombinator(
-          TokenFactory.tokenFromString("show"), identifiers);
-
-  static ShowCombinatorImpl showCombinator2(List<String> identifiers) =>
-      astFactory.showCombinator(
-          TokenFactory.tokenFromString("show"), identifierList(identifiers));
-
   static ShowHideElementImpl showHideElement(String name) =>
       astFactory.showHideElement(modifier: null, name: identifier3(name));
 
@@ -1061,8 +599,8 @@
           keyword:
               keyword == null ? null : TokenFactory.tokenFromKeyword(keyword),
           type: type,
-          identifier:
-              parameterName == null ? null : identifier3(parameterName));
+          name:
+              parameterName == null ? null : identifier3(parameterName).token);
 
   static SimpleFormalParameterImpl simpleFormalParameter3(
           String parameterName) =>
@@ -1110,7 +648,7 @@
           type: type,
           superKeyword: TokenFactory.tokenFromKeyword(Keyword.SUPER),
           period: TokenFactory.tokenFromType(TokenType.PERIOD),
-          identifier: identifier3(identifier),
+          name: identifier3(identifier).token,
           parameters: parameterList);
 
   static SuperFormalParameterImpl superFormalParameter2(String identifier) =>
@@ -1206,19 +744,6 @@
               : TokenFactory.tokenFromKeyword(Keyword.FINALLY),
           finallyClause);
 
-  static FunctionTypeAliasImpl typeAlias(TypeAnnotation returnType, String name,
-          TypeParameterList? typeParameters, FormalParameterList parameters) =>
-      FunctionTypeAliasImpl(
-        comment: null,
-        metadata: null,
-        typedefKeyword: TokenFactory.tokenFromKeyword(Keyword.TYPEDEF),
-        returnType: returnType as TypeAnnotationImpl,
-        name: identifier3(name),
-        typeParameters: typeParameters as TypeParameterListImpl?,
-        parameters: parameters as FormalParameterListImpl,
-        semicolon: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-      );
-
   static TypeArgumentList? typeArgumentList(List<TypeAnnotation>? types) {
     if (types == null || types.isEmpty) {
       return null;
@@ -1234,27 +759,18 @@
   static TypeParameterImpl typeParameter(String name) => TypeParameterImpl(
         comment: null,
         metadata: null,
-        name: identifier3(name),
+        name: identifier3(name).token,
         extendsKeyword: null,
         bound: null,
       );
 
-  static TypeParameterImpl typeParameter2(String name, TypeAnnotation bound) =>
-      TypeParameterImpl(
-        comment: null,
-        metadata: null,
-        name: identifier3(name),
-        extendsKeyword: TokenFactory.tokenFromKeyword(Keyword.EXTENDS),
-        bound: bound as TypeAnnotationImpl,
-      );
-
   static TypeParameterImpl typeParameter3(String name, String varianceLexeme) =>
       // TODO (kallentu) : Clean up AstFactoryImpl casting once variance is
       // added to the interface.
       TypeParameterImpl(
         comment: null,
         metadata: null,
-        name: identifier3(name),
+        name: identifier3(name).token,
         extendsKeyword: null,
         bound: null,
         varianceKeyword: TokenFactory.tokenFromString(varianceLexeme),
@@ -1281,7 +797,7 @@
 
   static VariableDeclarationImpl variableDeclaration(String name) =>
       VariableDeclarationImpl(
-        name: identifier3(name),
+        name: identifier3(name).token,
         equals: null,
         initializer: null,
       );
@@ -1289,7 +805,7 @@
   static VariableDeclarationImpl variableDeclaration2(
           String name, Expression initializer) =>
       VariableDeclarationImpl(
-        name: identifier3(name),
+        name: identifier3(name).token,
         equals: TokenFactory.tokenFromType(TokenType.EQ),
         initializer: initializer as ExpressionImpl,
       );
diff --git a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
index 9f8721f..9ccbffa 100644
--- a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
+++ b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
@@ -225,9 +225,9 @@
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
-    if (checkTripleShift && node.isOperator && node.name2.lexeme == '>>>') {
+    if (checkTripleShift && node.isOperator && node.name.lexeme == '>>>') {
       _errorReporter.reportErrorForToken(
-          HintCode.SDK_VERSION_GT_GT_GT_OPERATOR, node.name2);
+          HintCode.SDK_VERSION_GT_GT_GT_OPERATOR, node.name);
     }
     super.visitMethodDeclaration(node);
   }
@@ -255,7 +255,7 @@
     }
     var element = node.staticElement;
     if (checkFutureAndStream &&
-        element is ClassElement &&
+        element is InterfaceElement &&
         (element == _typeProvider.futureElement ||
             element == _typeProvider.streamElement)) {
       for (LibraryElement importedLibrary
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index d5f45ba..04a56bd 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -336,9 +336,9 @@
 
   @override
   bool canBeConstConstructor(covariant ConstructorDeclarationImpl node) {
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
 
-    final classElement = element.enclosingElement3;
+    final classElement = element.enclosingElement;
     if (classElement is ClassElement && classElement.hasNonFinalField) {
       return false;
     }
diff --git a/pkg/analyzer/lib/src/lint/linter_visitor.dart b/pkg/analyzer/lib/src/lint/linter_visitor.dart
index 2847322..8c1642e 100644
--- a/pkg/analyzer/lib/src/lint/linter_visitor.dart
+++ b/pkg/analyzer/lib/src/lint/linter_visitor.dart
@@ -84,6 +84,12 @@
   }
 
   @override
+  void visitBinaryPattern(BinaryPattern node) {
+    _runSubscriptions(node, registry._forBinaryPattern);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitBlock(Block node) {
     _runSubscriptions(node, registry._forBlock);
     node.visitChildren(this);
@@ -114,6 +120,18 @@
   }
 
   @override
+  void visitCaseClause(CaseClause node) {
+    _runSubscriptions(node, registry._forCaseClause);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitCastPattern(CastPattern node) {
+    _runSubscriptions(node, registry._forCastPattern);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitCatchClause(CatchClause node) {
     _runSubscriptions(node, registry._forCatchClause);
     node.visitChildren(this);
@@ -168,6 +186,12 @@
   }
 
   @override
+  void visitConstantPattern(ConstantPattern node) {
+    _runSubscriptions(node, registry._forConstantPattern);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     _runSubscriptions(node, registry._forConstructorDeclaration);
     node.visitChildren(this);
@@ -300,6 +324,12 @@
   }
 
   @override
+  void visitExtractorPattern(ExtractorPattern node) {
+    _runSubscriptions(node, registry._forExtractorPattern);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitFieldDeclaration(FieldDeclaration node) {
     _runSubscriptions(node, registry._forFieldDeclaration);
     node.visitChildren(this);
@@ -324,6 +354,12 @@
   }
 
   @override
+  void visitForEachPartsWithPattern(ForEachPartsWithPattern node) {
+    _runSubscriptions(node, registry._forForEachPartsWithPattern);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitForElement(ForElement node) {
     _runSubscriptions(node, registry._forForElement);
     node.visitChildren(this);
@@ -348,6 +384,12 @@
   }
 
   @override
+  void visitForPartsWithPattern(ForPartsWithPattern node) {
+    _runSubscriptions(node, registry._forForPartsWithPattern);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     _runSubscriptions(node, registry._forForStatement);
     node.visitChildren(this);
@@ -522,12 +564,30 @@
   }
 
   @override
+  void visitListPattern(ListPattern node) {
+    _runSubscriptions(node, registry._forListPattern);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitMapLiteralEntry(MapLiteralEntry node) {
     _runSubscriptions(node, registry._forMapLiteralEntry);
     node.visitChildren(this);
   }
 
   @override
+  void visitMapPattern(MapPattern node) {
+    _runSubscriptions(node, registry._forMapPattern);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitMapPatternEntry(MapPatternEntry node) {
+    _runSubscriptions(node, registry._forMapPatternEntry);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitMethodDeclaration(MethodDeclaration node) {
     _runSubscriptions(node, registry._forMethodDeclaration);
     node.visitChildren(this);
@@ -588,6 +648,12 @@
   }
 
   @override
+  void visitParenthesizedPattern(ParenthesizedPattern node) {
+    _runSubscriptions(node, registry._forParenthesizedPattern);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitPartDirective(PartDirective node) {
     _runSubscriptions(node, registry._forPartDirective);
     node.visitChildren(this);
@@ -600,12 +666,43 @@
   }
 
   @override
+  void visitPatternAssignment(PatternAssignment node) {
+    _runSubscriptions(node, registry._forPatternAssignment);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitPatternAssignmentStatement(PatternAssignmentStatement node) {
+    _runSubscriptions(node, registry._forPatternAssignmentStatement);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitPatternVariableDeclaration(PatternVariableDeclaration node) {
+    _runSubscriptions(node, registry._forPatternVariableDeclaration);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitPatternVariableDeclarationStatement(
+      PatternVariableDeclarationStatement node) {
+    _runSubscriptions(node, registry._forPatternVariableDeclarationStatement);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitPostfixExpression(PostfixExpression node) {
     _runSubscriptions(node, registry._forPostfixExpression);
     node.visitChildren(this);
   }
 
   @override
+  void visitPostfixPattern(PostfixPattern node) {
+    _runSubscriptions(node, registry._forPostfixPattern);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitPrefixedIdentifier(PrefixedIdentifier node) {
     _runSubscriptions(node, registry._forPrefixedIdentifier);
     node.visitChildren(this);
@@ -630,6 +727,24 @@
   }
 
   @override
+  void visitRecordPattern(RecordPattern node) {
+    _runSubscriptions(node, registry._forRecordPattern);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitRecordPatternField(RecordPatternField node) {
+    _runSubscriptions(node, registry._forRecordPatternField);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitRecordPatternFieldName(RecordPatternFieldName node) {
+    _runSubscriptions(node, registry._forRecordPatternFieldName);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitRecordTypeAnnotation(RecordTypeAnnotation node) {
     _runSubscriptions(node, registry._forRecordTypeAnnotation);
     node.visitChildren(this);
@@ -664,6 +779,12 @@
   }
 
   @override
+  void visitRelationalPattern(RelationalPattern node) {
+    _runSubscriptions(node, registry._forRelationalPattern);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitRethrowExpression(RethrowExpression node) {
     _runSubscriptions(node, registry._forRethrowExpression);
     node.visitChildren(this);
@@ -766,6 +887,30 @@
   }
 
   @override
+  void visitSwitchExpression(SwitchExpression node) {
+    _runSubscriptions(node, registry._forSwitchExpression);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitSwitchExpressionCase(SwitchExpressionCase node) {
+    _runSubscriptions(node, registry._forSwitchExpressionCase);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitSwitchExpressionDefault(SwitchExpressionDefault node) {
+    _runSubscriptions(node, registry._forSwitchExpressionDefault);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitSwitchPatternCase(SwitchPatternCase node) {
+    _runSubscriptions(node, registry._forSwitchPatternCase);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitSwitchStatement(SwitchStatement node) {
     _runSubscriptions(node, registry._forSwitchStatement);
     node.visitChildren(this);
@@ -844,6 +989,18 @@
   }
 
   @override
+  void visitVariablePattern(VariablePattern node) {
+    _runSubscriptions(node, registry._forVariablePattern);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitWhenClause(WhenClause node) {
+    _runSubscriptions(node, registry._forWhenClause);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitWhileStatement(WhileStatement node) {
     _runSubscriptions(node, registry._forWhileStatement);
     node.visitChildren(this);
@@ -894,11 +1051,14 @@
       _forAugmentationImportDirective = [];
   final List<_Subscription<AwaitExpression>> _forAwaitExpression = [];
   final List<_Subscription<BinaryExpression>> _forBinaryExpression = [];
+  final List<_Subscription<BinaryPattern>> _forBinaryPattern = [];
   final List<_Subscription<Block>> _forBlock = [];
   final List<_Subscription<BlockFunctionBody>> _forBlockFunctionBody = [];
   final List<_Subscription<BooleanLiteral>> _forBooleanLiteral = [];
   final List<_Subscription<BreakStatement>> _forBreakStatement = [];
   final List<_Subscription<CascadeExpression>> _forCascadeExpression = [];
+  final List<_Subscription<CaseClause>> _forCaseClause = [];
+  final List<_Subscription<CastPattern>> _forCastPattern = [];
   final List<_Subscription<CatchClause>> _forCatchClause = [];
   final List<_Subscription<CatchClauseParameter>> _forCatchClauseParameter = [];
   final List<_Subscription<ClassDeclaration>> _forClassDeclaration = [];
@@ -909,6 +1069,7 @@
   final List<_Subscription<ConditionalExpression>> _forConditionalExpression =
       [];
   final List<_Subscription<Configuration>> _forConfiguration = [];
+  final List<_Subscription<ConstantPattern>> _forConstantPattern = [];
   final List<_Subscription<ConstructorDeclaration>> _forConstructorDeclaration =
       [];
   final List<_Subscription<ConstructorFieldInitializer>>
@@ -937,18 +1098,22 @@
   final List<_Subscription<ExtendsClause>> _forExtendsClause = [];
   final List<_Subscription<ExtensionDeclaration>> _forExtensionDeclaration = [];
   final List<_Subscription<ExtensionOverride>> _forExtensionOverride = [];
+  final List<_Subscription<ExtractorPattern>> _forExtractorPattern = [];
   final List<_Subscription<FieldDeclaration>> _forFieldDeclaration = [];
   final List<_Subscription<FieldFormalParameter>> _forFieldFormalParameter = [];
   final List<_Subscription<ForEachPartsWithDeclaration>>
       _forForEachPartsWithDeclaration = [];
   final List<_Subscription<ForEachPartsWithIdentifier>>
       _forForEachPartsWithIdentifier = [];
+  final List<_Subscription<ForEachPartsWithPattern>>
+      _forForEachPartsWithPattern = [];
   final List<_Subscription<ForElement>> _forForElement = [];
   final List<_Subscription<FormalParameterList>> _forFormalParameterList = [];
   final List<_Subscription<ForPartsWithDeclarations>>
       _forForPartsWithDeclarations = [];
   final List<_Subscription<ForPartsWithExpression>> _forForPartsWithExpression =
       [];
+  final List<_Subscription<ForPartsWithPattern>> _forForPartsWithPattern = [];
   final List<_Subscription<ForStatement>> _forForStatement = [];
   final List<_Subscription<FunctionDeclaration>> _forFunctionDeclaration = [];
   final List<_Subscription<FunctionDeclarationStatement>>
@@ -985,7 +1150,10 @@
   final List<_Subscription<LibraryDirective>> _forLibraryDirective = [];
   final List<_Subscription<LibraryIdentifier>> _forLibraryIdentifier = [];
   final List<_Subscription<ListLiteral>> _forListLiteral = [];
+  final List<_Subscription<ListPattern>> _forListPattern = [];
   final List<_Subscription<MapLiteralEntry>> _forMapLiteralEntry = [];
+  final List<_Subscription<MapPatternEntry>> _forMapPatternEntry = [];
+  final List<_Subscription<MapPattern>> _forMapPattern = [];
   final List<_Subscription<MethodDeclaration>> _forMethodDeclaration = [];
   final List<_Subscription<MethodInvocation>> _forMethodInvocation = [];
   final List<_Subscription<MixinDeclaration>> _forMixinDeclaration = [];
@@ -997,13 +1165,26 @@
   final List<_Subscription<OnClause>> _forOnClause = [];
   final List<_Subscription<ParenthesizedExpression>>
       _forParenthesizedExpression = [];
+  final List<_Subscription<ParenthesizedPattern>> _forParenthesizedPattern = [];
   final List<_Subscription<PartDirective>> _forPartDirective = [];
   final List<_Subscription<PartOfDirective>> _forPartOfDirective = [];
+  final List<_Subscription<PatternAssignment>> _forPatternAssignment = [];
+  final List<_Subscription<PatternAssignmentStatement>>
+      _forPatternAssignmentStatement = [];
+  final List<_Subscription<PatternVariableDeclaration>>
+      _forPatternVariableDeclaration = [];
+  final List<_Subscription<PatternVariableDeclarationStatement>>
+      _forPatternVariableDeclarationStatement = [];
   final List<_Subscription<PostfixExpression>> _forPostfixExpression = [];
+  final List<_Subscription<PostfixPattern>> _forPostfixPattern = [];
   final List<_Subscription<PrefixedIdentifier>> _forPrefixedIdentifier = [];
   final List<_Subscription<PrefixExpression>> _forPrefixExpression = [];
   final List<_Subscription<PropertyAccess>> _forPropertyAccess = [];
   final List<_Subscription<RecordLiteral>> _forRecordLiterals = [];
+  final List<_Subscription<RecordPatternField>> _forRecordPatternField = [];
+  final List<_Subscription<RecordPatternFieldName>> _forRecordPatternFieldName =
+      [];
+  final List<_Subscription<RecordPattern>> _forRecordPattern = [];
   final List<_Subscription<RecordTypeAnnotation>> _forRecordTypeAnnotation = [];
   final List<_Subscription<RecordTypeAnnotationNamedField>>
       _forRecordTypeAnnotationNamedField = [];
@@ -1013,6 +1194,7 @@
       _forRecordTypeAnnotationPositionalField = [];
   final List<_Subscription<RedirectingConstructorInvocation>>
       _forRedirectingConstructorInvocation = [];
+  final List<_Subscription<RelationalPattern>> _forRelationalPattern = [];
   final List<_Subscription<RethrowExpression>> _forRethrowExpression = [];
   final List<_Subscription<ReturnStatement>> _forReturnStatement = [];
   final List<_Subscription<ScriptTag>> _forScriptTag = [];
@@ -1032,6 +1214,11 @@
   final List<_Subscription<SuperFormalParameter>> _forSuperFormalParameter = [];
   final List<_Subscription<SwitchCase>> _forSwitchCase = [];
   final List<_Subscription<SwitchDefault>> _forSwitchDefault = [];
+  final List<_Subscription<SwitchExpressionCase>> _forSwitchExpressionCase = [];
+  final List<_Subscription<SwitchExpressionDefault>>
+      _forSwitchExpressionDefault = [];
+  final List<_Subscription<SwitchExpression>> _forSwitchExpression = [];
+  final List<_Subscription<SwitchPatternCase>> _forSwitchPatternCase = [];
   final List<_Subscription<SwitchStatement>> _forSwitchStatement = [];
   final List<_Subscription<SymbolLiteral>> _forSymbolLiteral = [];
   final List<_Subscription<ThisExpression>> _forThisExpression = [];
@@ -1048,6 +1235,8 @@
       _forVariableDeclarationList = [];
   final List<_Subscription<VariableDeclarationStatement>>
       _forVariableDeclarationStatement = [];
+  final List<_Subscription<VariablePattern>> _forVariablePattern = [];
+  final List<_Subscription<WhenClause>> _forWhenClause = [];
   final List<_Subscription<WhileStatement>> _forWhileStatement = [];
   final List<_Subscription<WithClause>> _forWithClause = [];
   final List<_Subscription<YieldStatement>> _forYieldStatement = [];
@@ -1097,6 +1286,10 @@
     _forBinaryExpression.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addBinaryPattern(LintRule linter, AstVisitor visitor) {
+    _forBinaryPattern.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addBlock(LintRule linter, AstVisitor visitor) {
     _forBlock.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
@@ -1119,6 +1312,14 @@
         .add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addCaseClause(LintRule linter, AstVisitor visitor) {
+    _forCaseClause.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addCastPattern(LintRule linter, AstVisitor visitor) {
+    _forCastPattern.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addCatchClause(LintRule linter, AstVisitor visitor) {
     _forCatchClause.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
@@ -1157,6 +1358,10 @@
     _forConfiguration.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addConstantPattern(LintRule linter, AstVisitor visitor) {
+    _forConstantPattern.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addConstructorDeclaration(LintRule linter, AstVisitor visitor) {
     _forConstructorDeclaration
         .add(_Subscription(linter, visitor, _getTimer(linter)));
@@ -1259,6 +1464,10 @@
         .add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addExtractorPattern(LintRule linter, AstVisitor visitor) {
+    _forExtractorPattern.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addFieldDeclaration(LintRule linter, AstVisitor visitor) {
     _forFieldDeclaration.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
@@ -1278,6 +1487,11 @@
         .add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addForEachPartsWithPattern(LintRule linter, AstVisitor visitor) {
+    _forForEachPartsWithPattern
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addForElement(LintRule linter, AstVisitor visitor) {
     _forForElement.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
@@ -1297,6 +1511,11 @@
         .add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addForPartsWithPattern(LintRule linter, AstVisitor visitor) {
+    _forForPartsWithPattern
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addForStatement(LintRule linter, AstVisitor visitor) {
     _forForStatement.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
@@ -1427,10 +1646,22 @@
     _forListLiteral.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addListPattern(LintRule linter, AstVisitor visitor) {
+    _forListPattern.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addMapLiteralEntry(LintRule linter, AstVisitor visitor) {
     _forMapLiteralEntry.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addMapPattern(LintRule linter, AstVisitor visitor) {
+    _forMapPattern.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addMapPatternEntry(LintRule linter, AstVisitor visitor) {
+    _forMapPatternEntry.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addMethodDeclaration(LintRule linter, AstVisitor visitor) {
     _forMethodDeclaration
         .add(_Subscription(linter, visitor, _getTimer(linter)));
@@ -1474,6 +1705,11 @@
         .add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addParenthesizedPattern(LintRule linter, AstVisitor visitor) {
+    _forParenthesizedPattern
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addPartDirective(LintRule linter, AstVisitor visitor) {
     _forPartDirective.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
@@ -1482,11 +1718,36 @@
     _forPartOfDirective.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addPatternAssignment(LintRule linter, AstVisitor visitor) {
+    _forPatternAssignment
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addPatternAssignmentStatement(LintRule linter, AstVisitor visitor) {
+    _forPatternAssignmentStatement
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addPatternVariableDeclaration(LintRule linter, AstVisitor visitor) {
+    _forPatternVariableDeclaration
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addPatternVariableDeclarationStatement(
+      LintRule linter, AstVisitor visitor) {
+    _forPatternVariableDeclarationStatement
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addPostfixExpression(LintRule linter, AstVisitor visitor) {
     _forPostfixExpression
         .add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addPostfixPattern(LintRule linter, AstVisitor visitor) {
+    _forPostfixPattern.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addPrefixedIdentifier(LintRule linter, AstVisitor visitor) {
     _forPrefixedIdentifier
         .add(_Subscription(linter, visitor, _getTimer(linter)));
@@ -1504,12 +1765,36 @@
     _forRecordLiterals.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addRecordPattern(LintRule linter, AstVisitor visitor) {
+    _forRecordPattern.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addRecordPatternField(LintRule linter, AstVisitor visitor) {
+    _forRecordPatternField
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addRecordPatternFieldName(LintRule linter, AstVisitor visitor) {
+    _forRecordPatternFieldName
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addRecordTypeAnnotation(LintRule linter, AstVisitor visitor) {
+    _forRecordTypeAnnotation
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addRedirectingConstructorInvocation(
       LintRule linter, AstVisitor visitor) {
     _forRedirectingConstructorInvocation
         .add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addRelationalPattern(LintRule linter, AstVisitor visitor) {
+    _forRelationalPattern
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addRethrowExpression(LintRule linter, AstVisitor visitor) {
     _forRethrowExpression
         .add(_Subscription(linter, visitor, _getTimer(linter)));
@@ -1584,6 +1869,25 @@
     _forSwitchDefault.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addSwitchExpression(LintRule linter, AstVisitor visitor) {
+    _forSwitchExpression.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addSwitchExpressionCase(LintRule linter, AstVisitor visitor) {
+    _forSwitchExpressionCase
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addSwitchExpressionDefault(LintRule linter, AstVisitor visitor) {
+    _forSwitchExpressionDefault
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addSwitchPatternCase(LintRule linter, AstVisitor visitor) {
+    _forSwitchPatternCase
+        .add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addSwitchStatement(LintRule linter, AstVisitor visitor) {
     _forSwitchStatement.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
@@ -1646,6 +1950,14 @@
         .add(_Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addVariablePattern(LintRule linter, AstVisitor visitor) {
+    _forVariablePattern.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addWhenClause(LintRule linter, AstVisitor visitor) {
+    _forWhenClause.add(_Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addWhileStatement(LintRule linter, AstVisitor visitor) {
     _forWhileStatement.add(_Subscription(linter, visitor, _getTimer(linter)));
   }
diff --git a/pkg/analyzer/lib/src/lint/options_rule_validator.dart b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
index df08b4b..d36b5f6 100644
--- a/pkg/analyzer/lib/src/lint/options_rule_validator.dart
+++ b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
@@ -71,47 +71,55 @@
     var node = options.valueAt(linter);
     if (node is YamlMap) {
       var rules = node.valueAt(rulesKey);
-      validateRules(rules, reporter);
+      _validateRules(rules, reporter);
     }
     return errors;
   }
 
-  void validateRules(YamlNode? rules, ErrorReporter reporter) {
-    if (rules is YamlList) {
-      final seenRules = <String>{};
+  void _validateRules(YamlNode? rules, ErrorReporter reporter) {
+    final seenRules = <String>{};
 
-      String? findIncompatibleRule(LintRule rule) {
-        for (var incompatibleRule in rule.incompatibleRules) {
-          if (seenRules.contains(incompatibleRule)) {
-            return incompatibleRule;
-          }
+    String? findIncompatibleRule(LintRule rule) {
+      for (var incompatibleRule in rule.incompatibleRules) {
+        if (seenRules.contains(incompatibleRule)) {
+          return incompatibleRule;
         }
-        return null;
+      }
+      return null;
+    }
+
+    void validateRule(YamlNode node, bool enabled) {
+      var value = node.value;
+      if (value == null) return;
+
+      final rule = getRegisteredLint(value);
+      if (rule == null) {
+        reporter.reportErrorForSpan(UNDEFINED_LINT_WARNING, node.span, [value]);
+        return;
       }
 
-      for (var ruleNode in rules.nodes) {
-        final value = ruleNode.value;
-        if (value != null) {
-          final rule = getRegisteredLint(value);
-          if (rule == null) {
-            reporter.reportErrorForSpan(
-                UNDEFINED_LINT_WARNING, ruleNode.span, [value]);
-            continue;
-          }
-
-          final incompatibleRule = findIncompatibleRule(rule);
-          if (incompatibleRule != null) {
-            reporter.reportErrorForSpan(INCOMPATIBLE_LINT_WARNING,
-                ruleNode.span, [value, incompatibleRule]);
-          } else if (!seenRules.add(rule.name)) {
-            reporter.reportErrorForSpan(
-                DUPLICATE_RULE_HINT, ruleNode.span, [value]);
-          } else if (rule.maturity == Maturity.deprecated) {
-            reporter.reportErrorForSpan(
-                DEPRECATED_LINT_HINT, ruleNode.span, [value]);
-          }
+      if (enabled) {
+        final incompatibleRule = findIncompatibleRule(rule);
+        if (incompatibleRule != null) {
+          reporter.reportErrorForSpan(
+              INCOMPATIBLE_LINT_WARNING, node.span, [value, incompatibleRule]);
+        } else if (!seenRules.add(rule.name)) {
+          reporter.reportErrorForSpan(DUPLICATE_RULE_HINT, node.span, [value]);
         }
       }
+      if (rule.maturity == Maturity.deprecated) {
+        reporter.reportErrorForSpan(DEPRECATED_LINT_HINT, node.span, [value]);
+      }
+    }
+
+    if (rules is YamlList) {
+      for (var ruleNode in rules.nodes) {
+        validateRule(ruleNode, true);
+      }
+    } else if (rules is YamlMap) {
+      for (var ruleEntry in rules.nodeMap.entries) {
+        validateRule(ruleEntry.key, ruleEntry.value.value);
+      }
     }
   }
 }
diff --git a/pkg/analyzer/lib/src/lint/util.dart b/pkg/analyzer/lib/src/lint/util.dart
index 476ee13..328971b 100644
--- a/pkg/analyzer/lib/src/lint/util.dart
+++ b/pkg/analyzer/lib/src/lint/util.dart
@@ -42,17 +42,40 @@
 /// Returns `true` if this [fileName] is a Pubspec file.
 bool isPubspecFileName(String fileName) => _pubspec.hasMatch(fileName);
 
-class Spelunker {
+class FileSpelunker extends _AbstractSpelunker {
   final String path;
+  FileSpelunker(this.path, {super.sink, super.featureSet});
+  @override
+  String getSource() => File(path).readAsStringSync();
+}
+
+@Deprecated('Prefer FileSpelunker')
+class Spelunker extends _AbstractSpelunker {
+  final String path;
+  Spelunker(this.path, {super.sink, super.featureSet});
+  @override
+  String getSource() => File(path).readAsStringSync();
+}
+
+class StringSpelunker extends _AbstractSpelunker {
+  final String source;
+  StringSpelunker(this.source, {super.sink, super.featureSet});
+  @override
+  String getSource() => source;
+}
+
+abstract class _AbstractSpelunker {
   final IOSink sink;
   FeatureSet featureSet;
 
-  Spelunker(this.path, {IOSink? sink, FeatureSet? featureSet})
+  _AbstractSpelunker({IOSink? sink, FeatureSet? featureSet})
       : sink = sink ?? stdout,
         featureSet = featureSet ?? FeatureSet.latestLanguageVersion();
 
+  String getSource();
+
   void spelunk() {
-    var contents = File(path).readAsStringSync();
+    var contents = getSource();
 
     var parseResult = parseString(
       content: contents,
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 a712b1b..62fccec 100644
--- a/pkg/analyzer/lib/src/manifest/manifest_warning_code.g.dart
+++ b/pkg/analyzer/lib/src/manifest/manifest_warning_code.g.dart
@@ -52,6 +52,9 @@
 
   ///  A code indicating that a specified permission is not supported on Chrome
   ///  OS.
+  ///
+  ///  Parameters:
+  ///  0: the name of the feature tag
   static const ManifestWarningCode PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE =
       ManifestWarningCode(
     'PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE',
@@ -74,6 +77,9 @@
   );
 
   ///  A code indicating that a specified feature is not supported on Chrome OS.
+  ///
+  ///  Parameters:
+  ///  0: the name of the feature
   static const ManifestWarningCode UNSUPPORTED_CHROME_OS_FEATURE =
       ManifestWarningCode(
     'UNSUPPORTED_CHROME_OS_FEATURE',
@@ -85,6 +91,9 @@
 
   ///  A code indicating that a specified hardware feature is not supported on
   ///  Chrome OS.
+  ///
+  ///  Parameters:
+  ///  0: the name of the feature
   static const ManifestWarningCode UNSUPPORTED_CHROME_OS_HARDWARE =
       ManifestWarningCode(
     'UNSUPPORTED_CHROME_OS_HARDWARE',
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 0717a4a..529c20e 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.g.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.g.dart
@@ -52,7 +52,8 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the field
   static const PubspecWarningCode DEPENDENCIES_FIELD_NOT_MAP =
       PubspecWarningCode(
     'DEPENDENCIES_FIELD_NOT_MAP',
@@ -61,7 +62,8 @@
     hasPublishedDocs: true,
   );
 
-  ///  No parameters.
+  ///  Parameters:
+  ///  0: the name of the field
   static const PubspecWarningCode DEPRECATED_FIELD = PubspecWarningCode(
     'DEPRECATED_FIELD',
     "The '{0}' field is no longer used and can be removed.",
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index b146553..382747d 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -1472,7 +1472,7 @@
             var defaultArguments = _computeDefaultArguments(parameters);
             var isConst = classMember.constKeyword != null;
 
-            var constructorName = classMember.name2;
+            var constructorName = classMember.name;
             constructorName ??= StringToken(
               TokenType.IDENTIFIER,
               '',
@@ -1513,7 +1513,7 @@
                 isFinal: isFinal,
                 isStatic: isStatic,
                 kind: DeclarationKind.FIELD,
-                name: field.name2,
+                name: field.name,
                 parent: parent,
                 relevanceTags: [
                   'ElementKind.FIELD',
@@ -1531,7 +1531,7 @@
                 isDeprecated: isDeprecated,
                 isStatic: isStatic,
                 kind: DeclarationKind.GETTER,
-                name: classMember.name2,
+                name: classMember.name,
                 parent: parent,
                 relevanceTags: ['ElementKind.FIELD'],
                 returnType: _getTypeAnnotationString(classMember.returnType),
@@ -1541,7 +1541,7 @@
                 isDeprecated: isDeprecated,
                 isStatic: isStatic,
                 kind: DeclarationKind.SETTER,
-                name: classMember.name2,
+                name: classMember.name,
                 parameters: parameters.toSource(),
                 parameterNames: _getFormalParameterNames(parameters),
                 parameterTypes: _getFormalParameterTypes(parameters),
@@ -1558,7 +1558,7 @@
                 isDeprecated: isDeprecated,
                 isStatic: isStatic,
                 kind: DeclarationKind.METHOD,
-                name: classMember.name2,
+                name: classMember.name,
                 parameters: parameters.toSource(),
                 parameterNames: _getFormalParameterNames(parameters),
                 parameterTypes: _getFormalParameterTypes(parameters),
@@ -1579,7 +1579,7 @@
           isAbstract: node.abstractKeyword != null,
           isDeprecated: isDeprecated,
           kind: DeclarationKind.CLASS,
-          name: node.name2,
+          name: node.name,
           relevanceTags: ['ElementKind.CLASS'],
         );
         if (classDeclaration == null) continue;
@@ -1614,7 +1614,7 @@
             parent: classDeclaration,
             relevanceTagsInFile: ['ElementKind.CONSTRUCTOR'],
             requiredParameterCount: 0,
-            returnType: node.name2.lexeme,
+            returnType: node.name.lexeme,
             typeParameters: null,
           ));
         }
@@ -1622,14 +1622,14 @@
         addDeclaration(
           isDeprecated: isDeprecated,
           kind: DeclarationKind.CLASS_TYPE_ALIAS,
-          name: node.name2,
+          name: node.name,
           relevanceTags: ['ElementKind.CLASS'],
         );
       } else if (node is EnumDeclaration) {
         var enumDeclaration = addDeclaration(
           isDeprecated: isDeprecated,
           kind: DeclarationKind.ENUM,
-          name: node.name2,
+          name: node.name,
           relevanceTags: ['ElementKind.ENUM'],
         );
         if (enumDeclaration == null) continue;
@@ -1640,7 +1640,7 @@
           addDeclaration(
             isDeprecated: isDeprecated,
             kind: DeclarationKind.ENUM_CONSTANT,
-            name: constant.name2,
+            name: constant.name,
             parent: enumDeclaration,
             relevanceTags: [
               'ElementKind.ENUM_CONSTANT',
@@ -1649,7 +1649,7 @@
           );
         }
       } else if (node is ExtensionDeclaration) {
-        var name = node.name2;
+        var name = node.name;
         if (name != null) {
           addDeclaration(
             isDeprecated: isDeprecated,
@@ -1667,7 +1667,7 @@
           addDeclaration(
             isDeprecated: isDeprecated,
             kind: DeclarationKind.GETTER,
-            name: node.name2,
+            name: node.name,
             relevanceTags: ['ElementKind.FUNCTION'],
             returnType: _getTypeAnnotationString(node.returnType),
           );
@@ -1675,7 +1675,7 @@
           addDeclaration(
             isDeprecated: isDeprecated,
             kind: DeclarationKind.SETTER,
-            name: node.name2,
+            name: node.name,
             parameters: parameters.toSource(),
             parameterNames: _getFormalParameterNames(parameters),
             parameterTypes: _getFormalParameterTypes(parameters),
@@ -1690,7 +1690,7 @@
             defaultArgumentListTextRanges: defaultArguments?.ranges,
             isDeprecated: isDeprecated,
             kind: DeclarationKind.FUNCTION,
-            name: node.name2,
+            name: node.name,
             parameters: parameters.toSource(),
             parameterNames: _getFormalParameterNames(parameters),
             parameterTypes: _getFormalParameterTypes(parameters),
@@ -1709,7 +1709,7 @@
           addDeclaration(
             isDeprecated: isDeprecated,
             kind: DeclarationKind.FUNCTION_TYPE_ALIAS,
-            name: node.name2,
+            name: node.name,
             parameters: parameters.toSource(),
             parameterNames: _getFormalParameterNames(parameters),
             parameterTypes: _getFormalParameterTypes(parameters),
@@ -1723,7 +1723,7 @@
           addDeclaration(
             isDeprecated: isDeprecated,
             kind: DeclarationKind.TYPE_ALIAS,
-            name: node.name2,
+            name: node.name,
             relevanceTags: ['ElementKind.TYPE_ALIAS'],
           );
         }
@@ -1732,7 +1732,7 @@
         addDeclaration(
           isDeprecated: isDeprecated,
           kind: DeclarationKind.FUNCTION_TYPE_ALIAS,
-          name: node.name2,
+          name: node.name,
           parameters: parameters.toSource(),
           parameterNames: _getFormalParameterNames(parameters),
           parameterTypes: _getFormalParameterTypes(parameters),
@@ -1745,7 +1745,7 @@
         var mixinDeclaration = addDeclaration(
           isDeprecated: isDeprecated,
           kind: DeclarationKind.MIXIN,
-          name: node.name2,
+          name: node.name,
           relevanceTags: ['ElementKind.MIXIN'],
         );
         if (mixinDeclaration == null) continue;
@@ -1760,7 +1760,7 @@
             isDeprecated: isDeprecated,
             isFinal: isFinal,
             kind: DeclarationKind.VARIABLE,
-            name: variable.name2,
+            name: variable.name,
             relevanceTags: [
               'ElementKind.TOP_LEVEL_VARIABLE',
               if (isConst) 'ElementKind.TOP_LEVEL_VARIABLE+const',
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index a3cc55b..65b8ce1 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -118,8 +118,6 @@
         return _readListLiteral();
       case Tag.MapLiteralEntry:
         return _readMapLiteralEntry();
-      case Tag.MixinDeclaration:
-        return _readMixinDeclaration();
       case Tag.MethodInvocation:
         return _readMethodInvocation();
       case Tag.NamedExpression:
@@ -184,9 +182,9 @@
   }
 
   IntegerLiteral _createIntegerLiteral(String lexeme, int value) {
-    var node = astFactory.integerLiteral(
-      TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
-      value,
+    var node = IntegerLiteralImpl(
+      literal: TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
+      value: value,
     );
     _readExpressionResolution(node);
     return node;
@@ -368,17 +366,15 @@
     return node;
   }
 
-  SimpleIdentifierImpl _readDeclarationName() {
+  Token _readDeclarationName() {
     var name = _reader.readStringReference();
-    return astFactory.simpleIdentifier(
-      StringToken(TokenType.STRING, name, -1),
-    );
+    return StringToken(TokenType.STRING, name, -1);
   }
 
   DeclaredIdentifier _readDeclaredIdentifier() {
     var flags = _readByte();
     var type = _readOptionalNode() as TypeAnnotationImpl?;
-    var identifier = _readDeclarationName();
+    var name = _readDeclarationName();
     var metadata = _readNodeList<Annotation>();
     return DeclaredIdentifierImpl(
       comment: null,
@@ -392,7 +388,7 @@
         Tokens.var_(),
       ),
       type: type,
-      identifier: identifier,
+      name: name,
     );
   }
 
@@ -474,9 +470,9 @@
     var formalParameters = _readOptionalNode() as FormalParameterList?;
     var flags = _readByte();
     var metadata = _readNodeList<Annotation>();
-    var identifier = readNode() as SimpleIdentifier;
+    var name = _readDeclarationName();
     var node = astFactory.fieldFormalParameter2(
-      identifier: identifier,
+      name: name,
       period: Tokens.period(),
       thisKeyword: Tokens.this_(),
       covariantKeyword:
@@ -502,9 +498,9 @@
   }
 
   ForEachPartsWithDeclaration _readForEachPartsWithDeclaration() {
-    var loopVariable = readNode() as DeclaredIdentifier;
-    var iterable = readNode() as Expression;
-    return astFactory.forEachPartsWithDeclaration(
+    var loopVariable = readNode() as DeclaredIdentifierImpl;
+    var iterable = readNode() as ExpressionImpl;
+    return ForEachPartsWithDeclarationImpl(
       inKeyword: Tokens.in_(),
       iterable: iterable,
       loopVariable: loopVariable,
@@ -513,9 +509,9 @@
 
   ForElement _readForElement() {
     var flags = _readByte();
-    var forLoopParts = readNode() as ForLoopParts;
-    var body = readNode() as CollectionElement;
-    return astFactory.forElement(
+    var forLoopParts = readNode() as ForLoopPartsImpl;
+    var body = readNode() as CollectionElementImpl;
+    return ForElementImpl(
       awaitKeyword: AstBinaryFlags.hasAwait(flags) ? Tokens.await_() : null,
       body: body,
       forKeyword: Tokens.for_(),
@@ -549,23 +545,23 @@
   }
 
   ForPartsWithDeclarations _readForPartsWithDeclarations() {
-    var variables = readNode() as VariableDeclarationList;
-    var condition = _readOptionalNode() as Expression?;
+    var variables = readNode() as VariableDeclarationListImpl;
+    var condition = _readOptionalNode() as ExpressionImpl?;
     var updaters = _readNodeList<Expression>();
-    return astFactory.forPartsWithDeclarations(
+    return ForPartsWithDeclarationsImpl(
       condition: condition,
       leftSeparator: Tokens.semicolon(),
       rightSeparator: Tokens.semicolon(),
       updaters: updaters,
-      variables: variables,
+      variableList: variables,
     );
   }
 
   ForPartsWithExpression _readForPartsWithExpression() {
-    var initialization = _readOptionalNode() as Expression?;
-    var condition = _readOptionalNode() as Expression?;
+    var initialization = _readOptionalNode() as ExpressionImpl?;
+    var condition = _readOptionalNode() as ExpressionImpl?;
     var updaters = _readNodeList<Expression>();
-    return astFactory.forPartsWithExpression(
+    return ForPartsWithExpressionImpl(
       condition: condition,
       initialization: initialization,
       leftSeparator: Tokens.semicolon(),
@@ -579,23 +575,23 @@
   }
 
   FunctionExpressionInvocation _readFunctionExpressionInvocation() {
-    var function = readNode() as Expression;
-    var typeArguments = _readOptionalNode() as TypeArgumentList?;
-    var arguments = readNode() as ArgumentList;
-    var node = astFactory.functionExpressionInvocation(
-      function,
-      typeArguments,
-      arguments,
+    var function = readNode() as ExpressionImpl;
+    var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
+    var arguments = readNode() as ArgumentListImpl;
+    var node = FunctionExpressionInvocationImpl(
+      function: function,
+      typeArguments: typeArguments,
+      argumentList: arguments,
     );
     _readInvocationExpression(node);
     return node;
   }
 
   FunctionReference _readFunctionReference() {
-    var function = readNode() as Expression;
-    var typeArguments = _readOptionalNode() as TypeArgumentList?;
+    var function = readNode() as ExpressionImpl;
+    var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
 
-    var node = astFactory.functionReference(
+    var node = FunctionReferenceImpl(
       function: function,
       typeArguments: typeArguments,
     );
@@ -610,12 +606,12 @@
     var formalParameters = readNode() as FormalParameterList;
     var flags = _readByte();
     var metadata = _readNodeList<Annotation>();
-    var identifier = readNode() as SimpleIdentifier;
+    var name = _readDeclarationName();
     var node = astFactory.functionTypedFormalParameter2(
       comment: null,
       covariantKeyword:
           AstBinaryFlags.isCovariant(flags) ? Tokens.covariant_() : null,
-      identifier: identifier,
+      name: name,
       metadata: metadata,
       parameters: formalParameters,
       requiredKeyword:
@@ -629,14 +625,14 @@
   GenericFunctionType _readGenericFunctionType() {
     var flags = _readByte();
     // TODO(scheglov) add type parameters to locals
-    var typeParameters = _readOptionalNode() as TypeParameterList?;
-    var returnType = _readOptionalNode() as TypeAnnotation?;
-    var formalParameters = readNode() as FormalParameterList;
-    var node = astFactory.genericFunctionType(
-      returnType,
-      Tokens.function(),
-      typeParameters,
-      formalParameters,
+    var typeParameters = _readOptionalNode() as TypeParameterListImpl?;
+    var returnType = _readOptionalNode() as TypeAnnotationImpl?;
+    var formalParameters = readNode() as FormalParameterListImpl;
+    var node = GenericFunctionTypeImpl(
+      returnType: returnType,
+      functionKeyword: Tokens.function(),
+      typeParameters: typeParameters,
+      parameters: formalParameters,
       question: AstBinaryFlags.hasQuestion(flags) ? Tokens.question() : null,
     );
     var type = _reader.readRequiredType() as FunctionType;
@@ -654,11 +650,12 @@
   }
 
   IfElement _readIfElement() {
-    var condition = readNode() as Expression;
-    var thenElement = readNode() as CollectionElement;
-    var elseElement = _readOptionalNode() as CollectionElement?;
-    return astFactory.ifElement(
+    var condition = readNode() as ExpressionImpl;
+    var thenElement = readNode() as CollectionElementImpl;
+    var elseElement = _readOptionalNode() as CollectionElementImpl?;
+    return IfElementImpl(
       condition: condition,
+      caseClause: null,
       elseElement: elseElement,
       elseKeyword: elseElement != null ? Tokens.else_() : null,
       ifKeyword: Tokens.if_(),
@@ -751,9 +748,9 @@
 
   IntegerLiteral _readIntegerLiteralNull() {
     var lexeme = _readStringReference();
-    var node = astFactory.integerLiteral(
-      TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
-      null,
+    var node = IntegerLiteralImpl(
+      literal: TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
+      value: null,
     );
     _readExpressionResolution(node);
     return node;
@@ -787,9 +784,9 @@
   InterpolationString _readInterpolationString() {
     var lexeme = _readStringReference();
     var value = _readStringReference();
-    return astFactory.interpolationString(
-      TokenFactory.tokenFromString(lexeme),
-      value,
+    return InterpolationStringImpl(
+      contents: TokenFactory.tokenFromString(lexeme),
+      value: value,
     );
   }
 
@@ -830,17 +827,21 @@
   }
 
   MapLiteralEntry _readMapLiteralEntry() {
-    var key = readNode() as Expression;
-    var value = readNode() as Expression;
-    return astFactory.mapLiteralEntry(key, Tokens.colon(), value);
+    var key = readNode() as ExpressionImpl;
+    var value = readNode() as ExpressionImpl;
+    return MapLiteralEntryImpl(
+      key: key,
+      separator: Tokens.colon(),
+      value: value,
+    );
   }
 
   MethodInvocation _readMethodInvocation() {
     var flags = _readByte();
-    var target = _readOptionalNode() as Expression?;
-    var methodName = readNode() as SimpleIdentifier;
-    var typeArguments = _readOptionalNode() as TypeArgumentList?;
-    var arguments = readNode() as ArgumentList;
+    var target = _readOptionalNode() as ExpressionImpl?;
+    var methodName = readNode() as SimpleIdentifierImpl;
+    var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
+    var arguments = readNode() as ArgumentListImpl;
 
     Token? operator;
     if (AstBinaryFlags.hasQuestion(flags)) {
@@ -853,61 +854,40 @@
       operator = Tokens.periodPeriod();
     }
 
-    var node = astFactory.methodInvocation(
-      target,
-      operator,
-      methodName,
-      typeArguments,
-      arguments,
+    var node = MethodInvocationImpl(
+      target: target,
+      operator: operator,
+      methodName: methodName,
+      typeArguments: typeArguments,
+      argumentList: arguments,
     );
     _readInvocationExpression(node);
     return node;
   }
 
-  MixinDeclaration _readMixinDeclaration() {
-    var typeParameters = _readOptionalNode() as TypeParameterListImpl?;
-    var onClause = _readOptionalNode() as OnClauseImpl?;
-    var implementsClause = _readOptionalNode() as ImplementsClauseImpl?;
-    var name = readNode() as SimpleIdentifierImpl;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = MixinDeclarationImpl(
-      comment: null,
-      metadata: metadata,
-      augmentKeyword: null,
-      mixinKeyword: Tokens.mixin_(),
-      name: name,
-      typeParameters: typeParameters,
-      onClause: onClause,
-      implementsClause: implementsClause,
-      leftBracket: Tokens.openCurlyBracket(),
-      members: const <ClassMember>[],
-      rightBracket: Tokens.closeCurlyBracket(),
-    );
-
-    return node;
-  }
-
   NamedExpression _readNamedExpression() {
     var name = _readStringReference();
-    var nameNode = astFactory.label(
-      astFactory.simpleIdentifier(
+    var nameNode = LabelImpl(
+      label: astFactory.simpleIdentifier(
         StringToken(TokenType.STRING, name, -1),
       ),
-      Tokens.colon(),
+      colon: Tokens.colon(),
     );
-    var expression = readNode() as Expression;
-    var node = astFactory.namedExpression(nameNode, expression);
+    var expression = readNode() as ExpressionImpl;
+    var node = NamedExpressionImpl(
+      name: nameNode,
+      expression: expression,
+    );
     node.staticType = expression.staticType;
     return node;
   }
 
   NamedType _readNamedType() {
     var flags = _readByte();
-    var name = readNode() as Identifier;
-    var typeArguments = _readOptionalNode() as TypeArgumentList?;
+    var name = readNode() as IdentifierImpl;
+    var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
 
-    var node = astFactory.namedType(
+    var node = NamedTypeImpl(
       name: name,
       typeArguments: typeArguments,
       question: AstBinaryFlags.hasQuestion(flags) ? Tokens.question() : null,
@@ -922,8 +902,8 @@
   }
 
   NullLiteral _readNullLiteral() {
-    var node = astFactory.nullLiteral(
-      Tokens.null_(),
+    final node = NullLiteralImpl(
+      literal: Tokens.null_(),
     );
     _readExpressionResolution(node);
     return node;
@@ -1084,11 +1064,10 @@
     var type = _readOptionalNode() as TypeAnnotation?;
     var flags = _readByte();
     var metadata = _readNodeList<Annotation>();
-    var identifier =
-        AstBinaryFlags.hasName(flags) ? _readDeclarationName() : null;
+    var name = AstBinaryFlags.hasName(flags) ? _readDeclarationName() : null;
 
     var node = astFactory.simpleFormalParameter2(
-      identifier: identifier,
+      name: name,
       type: type,
       covariantKeyword:
           AstBinaryFlags.isCovariant(flags) ? Tokens.covariant_() : null,
@@ -1109,13 +1088,12 @@
     _reader.readByte(); // TODO(scheglov) inherits covariant
 
     var element = ParameterElementImpl(
-      name: identifier?.name ?? '',
+      name: name?.lexeme ?? '',
       nameOffset: -1,
       parameterKind: node.kind,
     );
     element.type = actualType;
     node.declaredElement = element;
-    identifier?.staticElement = element;
 
     return node;
   }
@@ -1251,7 +1229,7 @@
 
   VariableDeclaration _readVariableDeclaration() {
     var flags = _readByte();
-    var name = readNode() as SimpleIdentifierImpl;
+    var name = _readDeclarationName();
     var initializer = _readOptionalNode() as ExpressionImpl?;
 
     var node = VariableDeclarationImpl(
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
index 2daf44d..d2e1959 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -77,7 +77,6 @@
   static const int MethodDeclaration_getter = 85;
   static const int MethodDeclaration_setter = 86;
   static const int MethodInvocation = 59;
-  static const int MixinDeclaration = 67;
   static const int NamedExpression = 60;
   static const int NamedType = 39;
   static const int NullLiteral = 49;
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 69cc493..9ddc455 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -776,7 +776,7 @@
   @override
   void visitTypeParameter(TypeParameter node) {
     _writeByte(Tag.TypeParameter);
-    _writeDeclarationName(node.name2);
+    _writeDeclarationName(node.name);
     _writeOptionalNode(node.bound);
     _storeDeclaration(node);
   }
@@ -870,7 +870,7 @@
       f();
     } else {
       var elements = node.typeParameters
-          .map((typeParameter) => typeParameter.declaredElement2!)
+          .map((typeParameter) => typeParameter.declaredElement!)
           .toList();
       _sink.localElements.withElements(elements, () {
         f();
diff --git a/pkg/analyzer/lib/src/summary2/ast_resolver.dart b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
index a2a72d3..6bf2173 100644
--- a/pkg/analyzer/lib/src/summary2/ast_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
@@ -64,6 +64,7 @@
     _prepareEnclosingDeclarations();
     _flowAnalysis.topLevelDeclaration_enter(node, null);
     node.accept(_resolverVisitor);
+    _resolverVisitor.checkIdle();
     _flowAnalysis.topLevelDeclaration_exit();
   }
 
@@ -83,6 +84,7 @@
     _flowAnalysis.topLevelDeclaration_enter(node, node.parameters,
         visit: visit);
     visit(_resolverVisitor);
+    _resolverVisitor.checkIdle();
     _flowAnalysis.topLevelDeclaration_exit();
   }
 
@@ -98,6 +100,8 @@
     _prepareEnclosingDeclarations();
     _flowAnalysis.topLevelDeclaration_enter(node.parent!, null);
     _resolverVisitor.analyzeExpression(node, contextType);
+    _resolverVisitor.popRewrite();
+    _resolverVisitor.checkIdle();
     _flowAnalysis.topLevelDeclaration_exit();
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/ast_text_printer.dart b/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
index c1c63e0..a1b0394 100644
--- a/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
@@ -152,7 +152,7 @@
     _token(node.abstractKeyword);
     _token(node.macroKeyword);
     _token(node.classKeyword);
-    _token(node.name2);
+    _token(node.name);
     node.typeParameters?.accept(this);
     node.extendsClause?.accept(this);
     node.withClause?.accept(this);
@@ -169,7 +169,7 @@
     _token(node.abstractKeyword);
     _token(node.macroKeyword);
     _token(node.typedefKeyword);
-    _token(node.name2);
+    _token(node.name);
     node.typeParameters?.accept(this);
     _token(node.equals);
     node.superclass.accept(this);
@@ -217,7 +217,7 @@
     _token(node.factoryKeyword);
     node.returnType.accept(this);
     _token(node.period);
-    _token(node.name2);
+    _token(node.name);
     node.parameters.accept(this);
     _token(node.separator);
     _nodeList(node.initializers, node.body.beginToken);
@@ -316,7 +316,7 @@
   @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
     _declaration(node);
-    _token(node.name2);
+    _token(node.name);
     node.arguments?.accept(this);
   }
 
@@ -324,7 +324,7 @@
   void visitEnumDeclaration(EnumDeclaration node) {
     _compilationUnitMember(node);
     _token(node.enumKeyword);
-    _token(node.name2);
+    _token(node.name);
     node.typeParameters?.accept(this);
     node.withClause?.accept(this);
     node.implementsClause?.accept(this);
@@ -370,7 +370,7 @@
     _compilationUnitMember(node);
     _token(node.extensionKeyword);
     _token(node.typeKeyword);
-    _token(node.name2);
+    _token(node.name);
     node.typeParameters?.accept(this);
     _token(node.onKeyword);
     node.extendedType.accept(this);
@@ -495,7 +495,7 @@
     _token(node.externalKeyword);
     node.returnType?.accept(this);
     _token(node.propertyKeyword);
-    _token(node.name2);
+    _token(node.name);
     node.functionExpression.accept(this);
   }
 
@@ -529,7 +529,7 @@
     _compilationUnitMember(node);
     _token(node.typedefKeyword);
     node.returnType?.accept(this);
-    _token(node.name2);
+    _token(node.name);
     node.typeParameters?.accept(this);
     node.parameters.accept(this);
     _token(node.semicolon);
@@ -558,7 +558,7 @@
   void visitGenericTypeAlias(GenericTypeAlias node) {
     _compilationUnitMember(node);
     _token(node.typedefKeyword);
-    _token(node.name2);
+    _token(node.name);
     node.typeParameters?.accept(this);
     _token(node.equals);
     node.type.accept(this);
@@ -670,7 +670,7 @@
   void visitLibraryDirective(LibraryDirective node) {
     _directive(node);
     _token(node.libraryKeyword);
-    node.name.accept(this);
+    node.name2?.accept(this);
     _token(node.semicolon);
   }
 
@@ -702,7 +702,7 @@
     node.returnType?.accept(this);
     _token(node.propertyKeyword);
     _token(node.operatorKeyword);
-    _token(node.name2);
+    _token(node.name);
     node.typeParameters?.accept(this);
     node.parameters?.accept(this);
     node.body.accept(this);
@@ -721,7 +721,7 @@
   void visitMixinDeclaration(MixinDeclaration node) {
     _compilationUnitMember(node);
     _token(node.mixinKeyword);
-    _token(node.name2);
+    _token(node.name);
     node.typeParameters?.accept(this);
     node.onClause?.accept(this);
     node.implementsClause?.accept(this);
@@ -994,7 +994,7 @@
     // TODO (kallentu) : Clean up TypeParameterImpl casting once variance is
     // added to the interface.
     _token((node as TypeParameterImpl).varianceKeyword);
-    _token(node.name2);
+    _token(node.name);
     _token(node.extendsKeyword);
     node.bound?.accept(this);
   }
@@ -1009,7 +1009,7 @@
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
     _annotatedNode(node);
-    _token(node.name2);
+    _token(node.name);
     _token(node.equals);
     node.initializer?.accept(this);
   }
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index 817004b..da908c4 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -28,6 +28,7 @@
 import 'package:analyzer/src/summary2/macro_application_error.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/task/inference_error.dart';
+import 'package:analyzer/src/utilities/extensions/string.dart';
 import 'package:pub_semver/pub_semver.dart';
 
 class BundleReader {
@@ -98,8 +99,8 @@
   /// as well access them through their [Reference]s. For a class declaration
   /// this means reading them, for a named mixin application this means
   /// computing constructors.
-  void readMembers(ClassElementImpl element) {
-    if (element.isMixinApplication) {
+  void readMembers(ClassOrMixinElementImpl element) {
+    if (element is ClassElementImpl && element.isMixinApplication) {
       element.constructors;
     } else {
       _readMembers?.call();
@@ -200,13 +201,17 @@
     ResolutionReader reader,
     ElementImpl element,
   ) {
-    var enclosing = element.enclosingElement3;
-    if (enclosing is ClassElement) {
+    var enclosing = element.enclosingElement;
+    if (enclosing is InterfaceElement) {
       reader._addTypeParameters(enclosing.typeParameters);
     } else if (enclosing is CompilationUnitElement) {
       // Nothing.
+    } else if (enclosing is EnumElement) {
+      reader._addTypeParameters(enclosing.typeParameters);
     } else if (enclosing is ExtensionElement) {
       reader._addTypeParameters(enclosing.typeParameters);
+    } else if (enclosing is MixinElement) {
+      reader._addTypeParameters(enclosing.typeParameters);
     } else {
       throw UnimplementedError('${enclosing.runtimeType}');
     }
@@ -268,7 +273,7 @@
   @override
   void _read(element, reader) {
     element.metadata = reader._readAnnotationList(
-      unitElement: element.enclosingElement3,
+      unitElement: element.enclosingElement,
     );
     _readTypeParameters(reader, element.typeParameters);
     element.supertype = reader._readOptionalInterfaceType();
@@ -292,7 +297,7 @@
   @override
   void _read(element, reader) {
     element.metadata = reader._readAnnotationList(
-      unitElement: element.enclosingElement3,
+      unitElement: element.enclosingElement,
     );
     _readTypeParameters(reader, element.typeParameters);
     element.extendedType = reader.readRequiredType();
@@ -656,7 +661,8 @@
     return List.generate(length, (_) {
       var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
       var name = _reader.readStringReference();
-      var reference = containerRef.getChild(name);
+      var referenceName = name.ifNotEmptyOrElse('new');
+      var reference = containerRef.getChild(referenceName);
       var element = ConstructorElementImpl(name, -1);
       var linkedData = ConstructorElementLinkedData(
         reference: reference,
@@ -1552,7 +1558,7 @@
   @override
   void _read(element, reader) {
     element.metadata = reader._readAnnotationList(
-      unitElement: element.enclosingElement3,
+      unitElement: element.enclosingElement,
     );
     _readTypeParameters(reader, element.typeParameters);
     element.superclassConstraints = reader._readInterfaceTypeList();
@@ -1636,7 +1642,7 @@
       // TODO(scheglov) why to check for empty? If we have this flags.
       if (arguments.isNotEmpty) {
         var typeParameters =
-            (element.enclosingElement3 as TypeParameterizedElement)
+            (element.enclosingElement as TypeParameterizedElement)
                 .typeParameters;
         var substitution = Substitution.fromPairs(typeParameters, arguments);
         element =
@@ -1735,7 +1741,7 @@
       var element = readElement() as TypeParameterElement;
       var nullability = _readNullability();
       var type = TypeParameterTypeImpl(
-        element: element,
+        element2: element,
         nullabilitySuffix: nullability,
       );
       return _readAliasElementArguments(type);
@@ -1838,7 +1844,7 @@
         );
       } else if (type is TypeParameterType) {
         return TypeParameterTypeImpl(
-          element: type.element2,
+          element2: type.element2,
           nullabilitySuffix: type.nullabilitySuffix,
           alias: InstantiatedTypeAliasElementImpl(
             element: aliasElement,
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 6a0d6eb..93ea875 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -866,9 +866,9 @@
       return const [];
     }
 
-    var enclosing = declaration.enclosingElement3;
+    var enclosing = declaration.enclosingElement;
     if (enclosing is TypeParameterizedElement) {
-      if (enclosing is! ClassElement && enclosing is! ExtensionElement) {
+      if (enclosing is! InterfaceElement && enclosing is! ExtensionElement) {
         return const <DartType>[];
       }
 
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index 7609d8d..6e5caf2 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -25,32 +25,32 @@
   void build(List<AstNode> nodes) {
     for (var node in nodes) {
       if (node is ClassDeclaration) {
-        var element = node.declaredElement2!;
+        var element = node.declaredElement!;
         _breakSelfCycles(node.typeParameters);
         _breakRawTypeCycles(element, node.typeParameters);
         _computeBounds(element, node.typeParameters);
       } else if (node is ClassTypeAlias) {
-        var element = node.declaredElement2!;
+        var element = node.declaredElement!;
         _breakSelfCycles(node.typeParameters);
         _breakRawTypeCycles(element, node.typeParameters);
         _computeBounds(element, node.typeParameters);
       } else if (node is EnumDeclaration) {
-        var element = node.declaredElement2!;
+        var element = node.declaredElement!;
         _breakSelfCycles(node.typeParameters);
         _breakRawTypeCycles(element, node.typeParameters);
         _computeBounds(element, node.typeParameters);
       } else if (node is FunctionTypeAlias) {
-        var element = node.declaredElement2!;
+        var element = node.declaredElement!;
         _breakSelfCycles(node.typeParameters);
         _breakRawTypeCycles(element, node.typeParameters);
         _computeBounds(element, node.typeParameters);
       } else if (node is GenericTypeAlias) {
-        var element = node.declaredElement2!;
+        var element = node.declaredElement!;
         _breakSelfCycles(node.typeParameters);
         _breakRawTypeCycles(element, node.typeParameters);
         _computeBounds(element, node.typeParameters);
       } else if (node is MixinDeclaration) {
-        var element = node.declaredElement2!;
+        var element = node.declaredElement!;
         _breakSelfCycles(node.typeParameters);
         _breakRawTypeCycles(element, node.typeParameters);
         _computeBounds(element, node.typeParameters);
@@ -119,7 +119,7 @@
         if (typeParametersByName == null) {
           typeParametersByName = {};
           for (var parameterNode in typeParameters) {
-            var name = parameterNode.name2.lexeme;
+            var name = parameterNode.name.lexeme;
             typeParametersByName[name] = parameterNode;
           }
         }
@@ -152,7 +152,7 @@
     if (parameterList == null) return;
 
     for (var parameter in parameterList.typeParameters) {
-      var element = parameter.declaredElement2 as TypeParameterElementImpl;
+      var element = parameter.declaredElement as TypeParameterElementImpl;
       var defaultType = element.defaultType;
       if (defaultType is TypeBuilder) {
         var builtType = defaultType.build();
@@ -182,7 +182,7 @@
     var bounds = <DartType>[];
     for (int i = 0; i < length; i++) {
       var node = nodes[i];
-      elements.add(node.declaredElement2 as TypeParameterElementImpl);
+      elements.add(node.declaredElement as TypeParameterElementImpl);
       bounds.add(node.bound?.type ?? dynamicType);
     }
 
@@ -228,7 +228,7 @@
 
     // Set computed TypeBuilder(s) as default types.
     for (var i = 0; i < length; i++) {
-      var element = nodes[i].declaredElement2 as TypeParameterElementImpl;
+      var element = nodes[i].declaredElement as TypeParameterElementImpl;
       element.defaultType = bounds[i];
     }
   }
@@ -243,13 +243,13 @@
   ) {
     var paths = <List<_CycleElement>>[];
     if (startType is NamedTypeBuilder) {
-      var declaration = startType.element;
+      var declaration = startType.element2;
       if (startType.arguments.isEmpty) {
-        if (startType.element == end) {
+        if (startType.element2 == end) {
           paths.add([
             _CycleElement(startParameter, startType),
           ]);
-        } else if (visited.add(startType.element)) {
+        } else if (visited.add(startType.element2)) {
           void recurseParameters(List<TypeParameterElement> parameters) {
             for (var parameter in parameters) {
               var parameterNode = _linker.getLinkingNode(parameter);
@@ -273,12 +273,12 @@
             }
           }
 
-          if (declaration is ClassElement) {
+          if (declaration is InterfaceElement) {
             recurseParameters(declaration.typeParameters);
           } else if (declaration is TypeAliasElement) {
             recurseParameters(declaration.typeParameters);
           }
-          visited.remove(startType.element);
+          visited.remove(startType.element2);
         }
       } else {
         for (var argument in startType.arguments) {
diff --git a/pkg/analyzer/lib/src/summary2/detach_nodes.dart b/pkg/analyzer/lib/src/summary2/detach_nodes.dart
index 7f375e4..a74d668 100644
--- a/pkg/analyzer/lib/src/summary2/detach_nodes.dart
+++ b/pkg/analyzer/lib/src/summary2/detach_nodes.dart
@@ -46,6 +46,14 @@
   }
 
   @override
+  void visitMixinElement(MixinElement element) {
+    if (element is MixinElementImpl) {
+      element.mixinInferenceCallback = null;
+    }
+    super.visitMixinElement(element);
+  }
+
+  @override
   void visitParameterElement(ParameterElement element) {
     _detachConstVariable(element);
     super.visitParameterElement(element);
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 1b77bf2..3397614 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -17,6 +17,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/utilities/extensions/string.dart';
 import 'package:collection/collection.dart';
 
 class ElementBuilder extends ThrowingAstVisitor<void> {
@@ -88,7 +89,7 @@
 
   @override
   void visitClassDeclaration(covariant ClassDeclarationImpl node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
 
     var element = ClassElementImpl(name, nameToken.offset);
@@ -98,7 +99,7 @@
     _setCodeRange(element, node);
     _setDocumentation(element, node);
 
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addClass(name, element);
@@ -121,7 +122,7 @@
 
   @override
   void visitClassTypeAlias(covariant ClassTypeAliasImpl node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
 
     var element = ClassElementImpl(name, nameToken.offset);
@@ -132,7 +133,7 @@
     _setCodeRange(element, node);
     _setDocumentation(element, node);
 
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addClass(name, element);
@@ -156,8 +157,8 @@
   void visitConstructorDeclaration(
     covariant ConstructorDeclarationImpl node,
   ) {
-    var nameNode = node.name2 ?? node.returnType;
-    var name = node.name2?.lexeme ?? '';
+    var nameNode = node.name ?? node.returnType;
+    var name = node.name?.lexeme ?? '';
     if (name == 'new') {
       // A constructor declared as `C.new` is unnamed, and is modeled as such.
       name = '';
@@ -178,7 +179,7 @@
       element.constantInitializers = node.initializers;
     }
 
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addConstructor(element);
@@ -196,7 +197,7 @@
 
   @override
   void visitEnumDeclaration(covariant EnumDeclarationImpl node) {
-    var nameNode = node.name2;
+    var nameNode = node.name;
     var name = nameNode.lexeme;
     var nameOffset = nameNode.offset;
 
@@ -205,7 +206,7 @@
     _setCodeRange(element, node);
     _setDocumentation(element, node);
 
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addEnum(name, element);
@@ -221,9 +222,9 @@
     var constants = node.constants;
     var valuesElements = <Expression>[];
     for (var i = 0; i < constants.length; ++i) {
-      var constant = constants[i];
-      var name = constant.name2.lexeme;
-      var field = ConstFieldElementImpl(name, constant.name2.offset)
+      var constant = constants[i] as EnumConstantDeclarationImpl;
+      var name = constant.name.lexeme;
+      var field = ConstFieldElementImpl(name, constant.name.offset)
         ..hasImplicitType = true
         ..hasInitializer = true
         ..isConst = true
@@ -243,11 +244,12 @@
       var initializer = astFactory.instanceCreationExpression(
         null,
         ConstructorNameImpl(
-          type: astFactory.namedType(
+          type: NamedTypeImpl(
             name: astFactory.simpleIdentifier(
               StringToken(TokenType.STRING, element.name, -1),
             ),
             typeArguments: constant.arguments?.typeArguments,
+            question: null,
           ),
           period: constructorName != null ? Tokens.period() : null,
           name: constructorName != null
@@ -266,9 +268,7 @@
       );
 
       var variableDeclaration = VariableDeclarationImpl(
-        name: astFactory.simpleIdentifier(
-          StringToken(TokenType.STRING, name, -1),
-        ),
+        name: StringToken(TokenType.STRING, name, -1),
         equals: Tokens.eq(),
         initializer: initializer,
       );
@@ -309,27 +309,28 @@
       valuesField.constantInitializer = initializer;
 
       var variableDeclaration = VariableDeclarationImpl(
-        name: astFactory.simpleIdentifier(
-          StringToken(TokenType.STRING, 'values', -1),
-        ),
+        name: StringToken(TokenType.STRING, 'values', -1),
         equals: Tokens.eq(),
         initializer: initializer,
       );
-      valuesTypeNode = astFactory.namedType(
+      valuesTypeNode = NamedTypeImpl(
         name: astFactory.simpleIdentifier(
           StringToken(TokenType.STRING, 'List', -1),
         ),
         typeArguments: astFactory.typeArgumentList(
           Tokens.lt(),
           [
-            astFactory.namedType(
+            NamedTypeImpl(
               name: astFactory.simpleIdentifier(
                 StringToken(TokenType.STRING, element.name, -1),
               )..staticElement = element,
+              typeArguments: null,
+              question: null,
             )
           ],
           Tokens.gt(),
         ),
+        question: null,
       );
       VariableDeclarationListImpl(
         comment: null,
@@ -397,7 +398,7 @@
 
   @override
   void visitExtensionDeclaration(covariant ExtensionDeclarationImpl node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken?.lexeme;
     var nameOffset = nameToken?.offset ?? -1;
 
@@ -406,7 +407,7 @@
     _setCodeRange(element, node);
     _setDocumentation(element, node);
 
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _linker.elementNodes[element] = node;
 
     var refName = name ?? '${_nextUnnamedExtensionId++}';
@@ -446,7 +447,7 @@
     var metadata = _buildAnnotations(node.metadata);
     for (var variable in node.fields.variables) {
       variable as VariableDeclarationImpl;
-      var nameToken = variable.name2;
+      var nameToken = variable.name;
       var name = nameToken.lexeme;
       var nameOffset = nameToken.offset;
 
@@ -478,7 +479,7 @@
       _enclosingContext.addNonSyntheticField(element);
 
       _linker.elementNodes[element] = variable;
-      variable.declaredElement2 = element;
+      variable.declaredElement = element;
     }
     _buildType(node.fields.type);
   }
@@ -543,7 +544,7 @@
 
   @override
   void visitFunctionDeclaration(covariant FunctionDeclarationImpl node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
     var nameOffset = nameToken.offset;
 
@@ -585,7 +586,7 @@
     _setCodeRange(executableElement, node);
     _setDocumentation(executableElement, node);
 
-    node.declaredElement2 = executableElement;
+    node.declaredElement = executableElement;
     _linker.elementNodes[executableElement] = node;
 
     _buildExecutableElementChildren(
@@ -606,7 +607,7 @@
 
   @override
   void visitFunctionTypeAlias(covariant FunctionTypeAliasImpl node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
 
     var element = TypeAliasElementImpl(name, nameToken.offset);
@@ -615,7 +616,7 @@
     _setCodeRange(element, node);
     _setDocumentation(element, node);
 
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addTypeAlias(name, element);
@@ -715,7 +716,7 @@
 
   @override
   void visitGenericTypeAlias(covariant GenericTypeAliasImpl node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
 
     var element = TypeAliasElementImpl(name, nameToken.offset);
@@ -723,7 +724,7 @@
     _setCodeRange(element, node);
     _setDocumentation(element, node);
 
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addTypeAlias(name, element);
@@ -777,7 +778,7 @@
 
   @override
   void visitMethodDeclaration(covariant MethodDeclarationImpl node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
     var nameOffset = nameToken.offset;
 
@@ -836,7 +837,7 @@
     _setCodeRange(executableElement, node);
     _setDocumentation(executableElement, node);
 
-    node.declaredElement2 = executableElement;
+    node.declaredElement = executableElement;
     _linker.elementNodes[executableElement] = node;
 
     _buildExecutableElementChildren(
@@ -851,7 +852,7 @@
 
   @override
   void visitMixinDeclaration(covariant MixinDeclarationImpl node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
 
     var element = MixinElementImpl(name, nameToken.offset);
@@ -859,7 +860,7 @@
     _setCodeRange(element, node);
     _setDocumentation(element, node);
 
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addMixin(name, element);
@@ -1036,7 +1037,7 @@
     var metadata = _buildAnnotations(node.metadata);
     for (var variable in node.variables.variables) {
       variable as VariableDeclarationImpl;
-      var nameToken = variable.name2;
+      var nameToken = variable.name;
       var name = nameToken.lexeme;
       var nameOffset = nameToken.offset;
 
@@ -1065,7 +1066,7 @@
 
       _linker.elementNodes[element] = variable;
       _enclosingContext.addTopLevelVariable(name, element);
-      variable.declaredElement2 = element;
+      variable.declaredElement = element;
 
       var getter = element.getter;
       if (getter is PropertyAccessorElementImpl) {
@@ -1090,14 +1091,14 @@
 
   @override
   void visitTypeParameter(covariant TypeParameterImpl node) {
-    var nameToken = node.name2;
+    var nameToken = node.name;
     var name = nameToken.lexeme;
 
     var element = TypeParameterElementImpl(name, nameToken.offset);
     element.metadata = _buildAnnotations(node.metadata);
     _setCodeRange(element, node);
 
-    node.declaredElement2 = element;
+    node.declaredElement = element;
     _linker.elementNodes[element] = node;
     _enclosingContext.addTypeParameter(name, element);
 
@@ -1119,7 +1120,7 @@
   }
 
   void _buildClass(ClassDeclaration node) {
-    var element = node.declaredElement2 as ClassElementImpl;
+    var element = node.declaredElement as ClassElementImpl;
     var hasConstConstructor = node.members.any((e) {
       return e is ConstructorDeclaration && e.constKeyword != null;
     });
@@ -1164,7 +1165,7 @@
   }
 
   void _buildMixin(MixinDeclaration node) {
-    var element = node.declaredElement2 as MixinElementImpl;
+    var element = node.declaredElement as MixinElementImpl;
     var hasConstConstructor = node.members.any((e) {
       return e is ConstructorDeclaration && e.constKeyword != null;
     });
@@ -1359,7 +1360,9 @@
 
   Reference addConstructor(ConstructorElementImpl element) {
     constructors.add(element);
-    return _bindReference('@constructor', element.name, element);
+
+    final referenceName = element.name.ifNotEmptyOrElse('new');
+    return _bindReference('@constructor', referenceName, element);
   }
 
   Reference addEnum(String name, EnumElementImpl element) {
diff --git a/pkg/analyzer/lib/src/summary2/function_type_builder.dart b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
index 0a07a1c..e81d0d8 100644
--- a/pkg/analyzer/lib/src/summary2/function_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
@@ -61,7 +61,7 @@
   }
 
   @override
-  Element? get element => null;
+  Element? get element2 => null;
 
   @override
   R accept<R>(TypeVisitor<R> visitor) {
@@ -208,6 +208,6 @@
     TypeParameterList? node,
   ) {
     if (node == null) return const [];
-    return node.typeParameters.map((n) => n.declaredElement2!).toList();
+    return node.typeParameters.map((n) => n.declaredElement!).toList();
   }
 }
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
index b273460..2b92778 100644
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -78,7 +78,7 @@
         var unitReader = SummaryDataReader(unitInfoBytes);
         var unitInfo = _InfoUnit(unitReader);
 
-        final enclosing = unitElement.enclosingElement3;
+        final enclosing = unitElement.enclosingElement;
         if (enclosing is LibraryElementImpl) {
           if (identical(enclosing.definingCompilationUnit, unitElement)) {
             _applyToLibrary(enclosing, unitInfo);
@@ -1116,7 +1116,7 @@
     sink.writeList2<ClassDeclaration>(unit.declarations, (node) {
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
-      sink.writeUInt30(node.name2.offset);
+      sink.writeUInt30(node.name.offset);
       _writeDocumentationComment(node);
       _writeTypeParameters(node.typeParameters);
       _writeConstructors(node.members);
@@ -1132,7 +1132,7 @@
     sink.writeList2<ClassTypeAlias>(unit.declarations, (node) {
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
-      sink.writeUInt30(node.name2.offset);
+      sink.writeUInt30(node.name.offset);
       _writeDocumentationComment(node);
       _writeTypeParameters(node.typeParameters);
       _writeOffsets(
@@ -1144,7 +1144,7 @@
     sink.writeList2<EnumDeclaration>(unit.declarations, (node) {
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
-      sink.writeUInt30(node.name2.offset);
+      sink.writeUInt30(node.name.offset);
       _writeDocumentationComment(node);
       _writeTypeParameters(node.typeParameters);
       _writeConstructors(node.members);
@@ -1161,7 +1161,7 @@
     sink.writeList2<ExtensionDeclaration>(unit.declarations, (node) {
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
-      sink.writeUInt30(1 + (node.name2?.offset ?? -1));
+      sink.writeUInt30(1 + (node.name?.offset ?? -1));
       _writeDocumentationComment(node);
       _writeTypeParameters(node.typeParameters);
       _writeConstructors(node.members);
@@ -1182,7 +1182,7 @@
       (node) {
         sink.writeUInt30(node.offset);
         sink.writeUInt30(node.length);
-        sink.writeUInt30(node.name2.offset);
+        sink.writeUInt30(node.name.offset);
         _writeDocumentationComment(node);
         _writeTypeParameters(node.functionExpression.typeParameters);
         _writeFormalParameters(node.functionExpression.parameters);
@@ -1201,7 +1201,7 @@
             .toList(), (node) {
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
-      sink.writeUInt30(node.name2.offset);
+      sink.writeUInt30(node.name.offset);
       _writeDocumentationComment(node);
       _writeTypeParameters(node.functionExpression.typeParameters);
       _writeFormalParameters(node.functionExpression.parameters);
@@ -1215,7 +1215,7 @@
     sink.writeList2<FunctionTypeAlias>(unit.declarations, (node) {
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
-      sink.writeUInt30(node.name2.offset);
+      sink.writeUInt30(node.name.offset);
       _writeDocumentationComment(node);
       _writeTypeParameters(node.typeParameters);
       _writeFormalParameters(node.parameters);
@@ -1230,7 +1230,7 @@
       var aliasedType = node.type;
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
-      sink.writeUInt30(node.name2.offset);
+      sink.writeUInt30(node.name.offset);
       _writeDocumentationComment(node);
       _writeTypeParameters(node.typeParameters);
       if (aliasedType is GenericFunctionType) {
@@ -1250,7 +1250,7 @@
     sink.writeList2<MixinDeclaration>(unit.declarations, (node) {
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
-      sink.writeUInt30(node.name2.offset);
+      sink.writeUInt30(node.name.offset);
       _writeDocumentationComment(node);
       _writeTypeParameters(node.typeParameters);
       _writeConstructors(node.members);
@@ -1293,7 +1293,7 @@
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
       sink.writeOptionalUInt30(node.period?.offset);
-      var nameNode = node.name2 ?? node.returnType;
+      var nameNode = node.name ?? node.returnType;
       sink.writeUInt30(nameNode.offset);
       sink.writeUInt30(nameNode.end);
       _writeDocumentationComment(node);
@@ -1331,7 +1331,7 @@
       var codeOffset = node.offset;
       sink.writeUInt30(codeOffset);
       sink.writeUInt30(node.end - codeOffset);
-      sink.writeUInt30(node.name2.offset);
+      sink.writeUInt30(node.name.offset);
       _writeDocumentationComment(node);
       _writeOffsets(
         metadata: node.metadata,
@@ -1348,7 +1348,7 @@
     var codeOffset = _codeOffsetForVariable(node);
     sink.writeUInt30(codeOffset);
     sink.writeUInt30(node.end - codeOffset);
-    sink.writeUInt30(node.name2.offset);
+    sink.writeUInt30(node.name.offset);
     _writeDocumentationComment(node);
 
     // TODO(scheglov) Replace with some kind of double-iterating list.
@@ -1403,7 +1403,7 @@
       (node) {
         sink.writeUInt30(node.offset);
         sink.writeUInt30(node.length);
-        sink.writeUInt30(node.name2.offset);
+        sink.writeUInt30(node.name.offset);
         _writeDocumentationComment(node);
         _writeTypeParameters(node.typeParameters);
         _writeFormalParameters(node.parameters);
@@ -1423,8 +1423,11 @@
     for (var directive in unit.directives) {
       firstDirective ??= directive;
       if (directive is LibraryDirective) {
-        nameOffset = directive.name.offset;
-        nameLength = directive.name.length;
+        final libraryName = directive.name2;
+        if (libraryName != null) {
+          nameOffset = libraryName.offset;
+          nameLength = libraryName.length;
+        }
         break;
       }
     }
@@ -1449,7 +1452,7 @@
       (node) {
         sink.writeUInt30(node.offset);
         sink.writeUInt30(node.length);
-        sink.writeUInt30(node.name2.offset);
+        sink.writeUInt30(node.name.offset);
         _writeDocumentationComment(node);
         _writeTypeParameters(node.typeParameters);
         _writeFormalParameters(node.parameters);
@@ -1537,7 +1540,7 @@
     var codeOffset = _codeOffsetForVariable(node);
     sink.writeUInt30(codeOffset);
     sink.writeUInt30(node.end - codeOffset);
-    sink.writeUInt30(node.name2.offset);
+    sink.writeUInt30(node.name.offset);
     _writeDocumentationComment(node);
 
     // TODO(scheglov) Replace with some kind of double-iterating list.
@@ -1554,7 +1557,7 @@
     sink.writeList<TypeParameter>(parameters, (node) {
       sink.writeUInt30(node.offset);
       sink.writeUInt30(node.length);
-      sink.writeUInt30(node.name2.offset);
+      sink.writeUInt30(node.name.offset);
     });
   }
 }
@@ -2022,6 +2025,7 @@
 
   @override
   void visitRecordLiteral(RecordLiteral node) {
+    _tokenOrNull(node.constKeyword);
     _tokenOrNull(node.leftParenthesis);
     _tokenOrNull(node.rightParenthesis);
     super.visitRecordLiteral(node);
@@ -2046,6 +2050,7 @@
   @override
   void visitSimpleFormalParameter(SimpleFormalParameter node) {
     _tokenOrNull(node.requiredKeyword);
+    _tokenOrNull(node.name);
     super.visitSimpleFormalParameter(node);
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 242be88..818acd8 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -212,7 +212,7 @@
               executable.body.accept(collector);
             }
           }
-          var element = declaration.declaredElement2 as MixinElementImpl;
+          var element = declaration.declaredElement as MixinElementImpl;
           element.superInvokedNames = names.toList();
         }
       }
@@ -760,9 +760,12 @@
     var nameLength = 0;
     for (final directive in libraryUnitNode.directives) {
       if (directive is ast.LibraryDirective) {
-        name = directive.name.components.map((e) => e.name).join('.');
-        nameOffset = directive.name.offset;
-        nameLength = directive.name.length;
+        final nameIdentifier = directive.name2;
+        if (nameIdentifier != null) {
+          name = nameIdentifier.components.map((e) => e.name).join('.');
+          nameOffset = nameIdentifier.offset;
+          nameLength = nameIdentifier.length;
+        }
         break;
       }
     }
diff --git a/pkg/analyzer/lib/src/summary2/macro_declarations.dart b/pkg/analyzer/lib/src/summary2/macro_declarations.dart
index ed16196..a8c9cd8 100644
--- a/pkg/analyzer/lib/src/summary2/macro_declarations.dart
+++ b/pkg/analyzer/lib/src/summary2/macro_declarations.dart
@@ -52,7 +52,7 @@
     }
 
     for (final entry in fromNode._classMap.entries) {
-      final element = entry.key.declaredElement2!;
+      final element = entry.key.declaredElement!;
       final declaration = entry.value;
       declaration.element = element;
       fromElement._classMap[element] = declaration;
@@ -116,7 +116,7 @@
 
   FieldDeclarationImpl _fieldElement(FieldElement element) {
     assert(!_fieldMap.containsKey(element));
-    final enclosingClass = element.enclosingElement3 as ClassElement;
+    final enclosingClass = element.enclosingElement as ClassElement;
     return FieldDeclarationImpl(
       id: macro.RemoteInstance.uniqueId,
       identifier: identifier(element),
@@ -214,7 +214,7 @@
     assert(!_classMap.containsKey(node));
     return IntrospectableClassDeclarationImpl._(
       id: macro.RemoteInstance.uniqueId,
-      identifier: _declaredIdentifier(node.name2, node.declaredElement2!),
+      identifier: _declaredIdentifier(node.name, node.declaredElement!),
       typeParameters: _typeParameters(node.typeParameters),
       interfaces: _typeAnnotations(node.implementsClause?.interfaces),
       isAbstract: node.abstractKeyword != null,
@@ -290,7 +290,7 @@
   ) {
     return macro.TypeParameterDeclarationImpl(
       id: macro.RemoteInstance.uniqueId,
-      identifier: _declaredIdentifier(node.name2, node.declaredElement2!),
+      identifier: _declaredIdentifier(node.name, node.declaredElement!),
       bound: node.bound.mapOrNull(_typeAnnotation),
     );
   }
diff --git a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
index 1dc9caa..ccf3d51 100644
--- a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
@@ -96,8 +96,12 @@
   }
 
   @override
-  void visitExportDirective(ExportDirective node) {
+  void visitExportDirective(covariant ExportDirectiveImpl node) {
     node.metadata.accept(this);
+    // We might have already accessed metadata flags, e.g. `hasDeprecated`,
+    // before we finished metadata resolution, during `PrefixScope` building.
+    // So, these flags are not accurate anymore, and we need to reset them.
+    node.element2!.resetMetadataFlags();
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index 507f59a..28836a0 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -30,7 +30,7 @@
   final TypeSystemImpl typeSystem;
 
   @override
-  final Element element;
+  final Element element2;
 
   final List<DartType> arguments;
 
@@ -48,7 +48,7 @@
   /// and set for the [node].
   DartType? _type;
 
-  NamedTypeBuilder(this.linker, this.typeSystem, this.element, this.arguments,
+  NamedTypeBuilder(this.linker, this.typeSystem, this.element2, this.arguments,
       this.nullabilitySuffix,
       {this.node});
 
@@ -74,7 +74,7 @@
 
   /// TODO(scheglov) Only when enabled both in the element, and target?
   bool get _isNonFunctionTypeAliasesEnabled {
-    return element.library!.featureSet.isEnabled(
+    return element2.library!.featureSet.isEnabled(
       Feature.nonfunction_type_aliases,
     );
   }
@@ -95,8 +95,9 @@
       return _type!;
     }
 
-    final element = this.element;
-    if (element is ClassElement) {
+    // ignore: unnecessary_this
+    final element = this.element2;
+    if (element is InterfaceElement) {
       var parameters = element.typeParameters;
       var arguments = _buildArguments(parameters);
       var type = element.instantiate(
@@ -124,7 +125,7 @@
       }
     } else if (element is TypeParameterElement) {
       _type = TypeParameterTypeImpl(
-        element: element,
+        element2: element,
         nullabilitySuffix: nullabilitySuffix,
       );
     } else {
@@ -138,7 +139,7 @@
   @override
   String toString() {
     var buffer = StringBuffer();
-    buffer.write(element.displayName);
+    buffer.write(element2.displayName);
     if (arguments.isNotEmpty) {
       buffer.write('<');
       buffer.write(arguments.join(', '));
@@ -154,7 +155,7 @@
     }
 
     return NamedTypeBuilder(
-        linker, typeSystem, element, arguments, nullabilitySuffix,
+        linker, typeSystem, element2, arguments, nullabilitySuffix,
         node: node);
   }
 
@@ -319,7 +320,7 @@
   static List<TypeParameterElement> _typeParameters(TypeParameterList? node) {
     if (node != null) {
       return node.typeParameters
-          .map<TypeParameterElement>((p) => p.declaredElement2!)
+          .map<TypeParameterElement>((p) => p.declaredElement!)
           .toList();
     } else {
       return const <TypeParameterElement>[];
diff --git a/pkg/analyzer/lib/src/summary2/not_serializable_nodes.dart b/pkg/analyzer/lib/src/summary2/not_serializable_nodes.dart
index 4c20261..d697cc5 100644
--- a/pkg/analyzer/lib/src/summary2/not_serializable_nodes.dart
+++ b/pkg/analyzer/lib/src/summary2/not_serializable_nodes.dart
@@ -10,16 +10,16 @@
 import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
 
 FunctionExpressionImpl emptyFunctionExpression() {
-  return astFactory.functionExpression(
-    null,
-    astFactory.formalParameterList(
+  return FunctionExpressionImpl(
+    typeParameters: null,
+    parameters: astFactory.formalParameterList(
       Tokens.openParenthesis(),
       [],
       null,
       null,
       Tokens.closeParenthesis(),
     ),
-    BlockFunctionBodyImpl(
+    body: BlockFunctionBodyImpl(
       keyword: null,
       star: null,
       block: BlockImpl(
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 98de463..b8333bb 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -53,7 +53,7 @@
   void visitClassDeclaration(ClassDeclaration node) {
     var outerScope = scope;
 
-    var element = node.declaredElement2 as ClassElementImpl;
+    var element = node.declaredElement as ClassElementImpl;
 
     scope = TypeParameterScope(scope, element.typeParameters);
 
@@ -75,7 +75,7 @@
   void visitClassTypeAlias(ClassTypeAlias node) {
     var outerScope = scope;
 
-    var element = node.declaredElement2 as ClassElementImpl;
+    var element = node.declaredElement as ClassElementImpl;
 
     scope = TypeParameterScope(scope, element.typeParameters);
     LinkingNodeContext(node, scope);
@@ -99,7 +99,7 @@
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     var outerScope = scope;
 
-    var element = node.declaredElement2 as ConstructorElementImpl;
+    var element = node.declaredElement as ConstructorElementImpl;
 
     scope = TypeParameterScope(scope, element.typeParameters);
     LinkingNodeContext(node, scope);
@@ -118,7 +118,7 @@
   void visitEnumDeclaration(EnumDeclaration node) {
     var outerScope = scope;
 
-    var element = node.declaredElement2 as EnumElementImpl;
+    var element = node.declaredElement as EnumElementImpl;
 
     scope = TypeParameterScope(scope, element.typeParameters);
 
@@ -147,7 +147,7 @@
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     var outerScope = scope;
 
-    var element = node.declaredElement2 as ExtensionElementImpl;
+    var element = node.declaredElement as ExtensionElementImpl;
 
     scope = TypeParameterScope(scope, element.typeParameters);
 
@@ -193,7 +193,7 @@
   void visitFunctionDeclaration(FunctionDeclaration node) {
     var outerScope = scope;
 
-    var element = node.declaredElement2 as ExecutableElementImpl;
+    var element = node.declaredElement as ExecutableElementImpl;
 
     scope = TypeParameterScope(outerScope, element.typeParameters);
     LinkingNodeContext(node, scope);
@@ -215,7 +215,7 @@
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     var outerScope = scope;
 
-    var element = node.declaredElement2 as TypeAliasElementImpl;
+    var element = node.declaredElement as TypeAliasElementImpl;
 
     scope = TypeParameterScope(outerScope, element.typeParameters);
 
@@ -268,7 +268,7 @@
   void visitGenericTypeAlias(GenericTypeAlias node) {
     var outerScope = scope;
 
-    var element = node.declaredElement2 as TypeAliasElementImpl;
+    var element = node.declaredElement as TypeAliasElementImpl;
 
     scope = TypeParameterScope(outerScope, element.typeParameters);
 
@@ -295,7 +295,7 @@
   void visitMethodDeclaration(MethodDeclaration node) {
     var outerScope = scope;
 
-    var element = node.declaredElement2 as ExecutableElementImpl;
+    var element = node.declaredElement as ExecutableElementImpl;
 
     scope = TypeParameterScope(scope, element.typeParameters);
     LinkingNodeContext(node, scope);
@@ -312,7 +312,7 @@
   void visitMixinDeclaration(MixinDeclaration node) {
     var outerScope = scope;
 
-    var element = node.declaredElement2 as MixinElementImpl;
+    var element = node.declaredElement as MixinElementImpl;
 
     scope = TypeParameterScope(scope, element.typeParameters);
 
@@ -367,7 +367,7 @@
       node.type = DynamicTypeImpl.instance;
     } else if (element is TypeParameterElement) {
       node.type = TypeParameterTypeImpl(
-        element: element,
+        element2: element,
         nullabilitySuffix: nullabilitySuffix,
       );
     } else {
@@ -456,7 +456,7 @@
     var bound = node.bound;
     if (bound != null) {
       bound.accept(this);
-      var element = node.declaredElement2 as TypeParameterElementImpl;
+      var element = node.declaredElement as TypeParameterElementImpl;
       element.bound = bound.type;
     }
   }
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index 32a9af8..6519104 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -41,22 +41,22 @@
     walker.walk(node);
     var node2 = node._node;
     if (node2 is ClassDeclaration) {
-      var element = node2.declaredElement2 as ClassElementImpl;
+      var element = node2.declaredElement as ClassElementImpl;
       element.isSimplyBounded = node.isSimplyBounded;
     } else if (node2 is ClassTypeAlias) {
-      var element = node2.declaredElement2 as ClassElementImpl;
+      var element = node2.declaredElement as ClassElementImpl;
       element.isSimplyBounded = node.isSimplyBounded;
     } else if (node2 is EnumDeclaration) {
-      var element = node2.declaredElement2 as EnumElementImpl;
+      var element = node2.declaredElement as EnumElementImpl;
       element.isSimplyBounded = node.isSimplyBounded;
     } else if (node2 is GenericTypeAlias) {
-      var element = node2.declaredElement2 as TypeAliasElementImpl;
+      var element = node2.declaredElement as TypeAliasElementImpl;
       element.isSimplyBounded = node.isSimplyBounded;
     } else if (node2 is FunctionTypeAlias) {
-      var element = node2.declaredElement2 as TypeAliasElementImpl;
+      var element = node2.declaredElement as TypeAliasElementImpl;
       element.isSimplyBounded = node.isSimplyBounded;
     } else if (node2 is MixinDeclaration) {
-      var element = node2.declaredElement2 as MixinElementImpl;
+      var element = node2.declaredElement as MixinElementImpl;
       element.isSimplyBounded = node.isSimplyBounded;
     } else {
       throw UnimplementedError('${node2.runtimeType}');
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index de81111..f40a23c 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -47,7 +47,7 @@
         unit.extensions.forEach(_resolveExtensionFields);
         unit.mixins2.forEach(_resolveInterfaceFields);
 
-        _scope = unit.enclosingElement3.scope;
+        _scope = unit.enclosingElement.scope;
         unit.topLevelVariables.forEach(_resolveVariable);
       }
     }
@@ -174,7 +174,7 @@
       }
     }
 
-    var classElement = _constructor.enclosingElement3;
+    var classElement = _constructor.enclosingElement;
     if (classElement is ClassElement && classElement.isMixinApplication) {
       var superType = classElement.supertype;
       if (superType != null) {
@@ -285,7 +285,7 @@
 
     _set.add(element);
 
-    if (element.enclosingElement3.typeParameters.isNotEmpty) {
+    if (element.enclosingElement.typeParameters.isNotEmpty) {
       node.argumentList.accept(this);
     }
   }
@@ -356,7 +356,7 @@
         unit.extensions.forEach(_addExtensionElementFields);
         unit.mixins2.forEach(_addClassElementFields);
 
-        _scope = unit.enclosingElement3.scope;
+        _scope = unit.enclosingElement.scope;
         for (var element in unit.topLevelVariables) {
           _addVariableNode(element);
         }
@@ -455,7 +455,7 @@
 
   @override
   String get displayName {
-    return _node.name2.lexeme;
+    return _node.name.lexeme;
   }
 
   @override
@@ -526,9 +526,9 @@
   }
 
   void _resolveInitializer({required bool forDependencies}) {
-    var enclosingElement = _element.enclosingElement3;
+    var enclosingElement = _element.enclosingElement;
     var enclosingClassElement =
-        enclosingElement is ClassElement ? enclosingElement : null;
+        enclosingElement is InterfaceElement ? enclosingElement : null;
     var astResolver = AstResolver(_walker._linker, _unitElement, _scope,
         enclosingClassElement: enclosingClassElement);
     astResolver.resolveExpression(() => _node.initializer!,
diff --git a/pkg/analyzer/lib/src/summary2/type_alias.dart b/pkg/analyzer/lib/src/summary2/type_alias.dart
index 51f1819..a935662 100644
--- a/pkg/analyzer/lib/src/summary2/type_alias.dart
+++ b/pkg/analyzer/lib/src/summary2/type_alias.dart
@@ -16,12 +16,12 @@
           if (node is FunctionTypeAlias) {
             var finder = _Finder(linker, node);
             finder.functionTypeAlias(node);
-            var element = node.declaredElement2 as TypeAliasElementImpl;
+            var element = node.declaredElement as TypeAliasElementImpl;
             element.hasSelfReference = finder.hasSelfReference;
           } else if (node is GenericTypeAlias) {
             var finder = _Finder(linker, node);
             finder.genericTypeAlias(node);
-            var element = node.declaredElement2 as TypeAliasElementImpl;
+            var element = node.declaredElement as TypeAliasElementImpl;
             element.hasSelfReference = finder.hasSelfReference;
           }
         }
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index b573cf4..db708c2 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -117,7 +117,7 @@
   }
 
   void _classDeclaration(ClassDeclaration node) {
-    var element = node.declaredElement2 as ClassElementImpl;
+    var element = node.declaredElement as ClassElementImpl;
 
     var extendsClause = node.extendsClause;
     if (extendsClause != null) {
@@ -143,7 +143,7 @@
   }
 
   void _classTypeAlias(ClassTypeAlias node) {
-    var element = node.declaredElement2 as ClassElementImpl;
+    var element = node.declaredElement as ClassElementImpl;
 
     var superType = node.superclass.type;
     if (superType is InterfaceType && _isInterfaceTypeInterface(superType)) {
@@ -181,7 +181,7 @@
           returnType = _dynamicType;
         }
       }
-      var element = node.declaredElement2 as ExecutableElementImpl;
+      var element = node.declaredElement as ExecutableElementImpl;
       element.returnType = returnType;
     } else if (node is FunctionTypeAlias) {
       _functionTypeAlias(node);
@@ -194,13 +194,13 @@
       if (returnType == null) {
         if (node.isSetter) {
           returnType = _voidType;
-        } else if (node.isOperator && node.name2.lexeme == '[]=') {
+        } else if (node.isOperator && node.name.lexeme == '[]=') {
           returnType = _voidType;
         } else {
           returnType = _dynamicType;
         }
       }
-      var element = node.declaredElement2 as ExecutableElementImpl;
+      var element = node.declaredElement as ExecutableElementImpl;
       element.returnType = returnType;
     } else if (node is MixinDeclaration) {
       _mixinDeclaration(node);
@@ -213,7 +213,7 @@
       var type = node.type?.type;
       if (type != null) {
         for (var variable in node.variables) {
-          (variable.declaredElement2 as VariableElementImpl).type = type;
+          (variable.declaredElement as VariableElementImpl).type = type;
         }
       }
     } else {
@@ -222,7 +222,7 @@
   }
 
   void _enumDeclaration(EnumDeclaration node) {
-    var element = node.declaredElement2 as EnumElementImpl;
+    var element = node.declaredElement as EnumElementImpl;
 
     element.mixins = _toInterfaceTypeList(
       node.withClause?.mixinTypes,
@@ -234,7 +234,7 @@
   }
 
   void _extensionDeclaration(ExtensionDeclaration node) {
-    var element = node.declaredElement2 as ExtensionElementImpl;
+    var element = node.declaredElement as ExtensionElementImpl;
     element.extendedType = node.extendedType.typeOrThrow;
   }
 
@@ -261,7 +261,7 @@
   }
 
   void _functionTypeAlias(FunctionTypeAlias node) {
-    var element = node.declaredElement2 as TypeAliasElementImpl;
+    var element = node.declaredElement as TypeAliasElementImpl;
     var function = element.aliasedElement as GenericFunctionTypeElementImpl;
     function.returnType = node.returnType?.type ?? _dynamicType;
     element.aliasedType = function.type;
@@ -279,7 +279,7 @@
   }
 
   void _genericTypeAlias(GenericTypeAlias node) {
-    var element = node.declaredElement2 as TypeAliasElementImpl;
+    var element = node.declaredElement as TypeAliasElementImpl;
     var featureSet = element.library.featureSet;
 
     var typeNode = node.type;
@@ -298,7 +298,7 @@
   }
 
   void _mixinDeclaration(MixinDeclaration node) {
-    var element = node.declaredElement2 as MixinElementImpl;
+    var element = node.declaredElement as MixinElementImpl;
 
     var constraints = _toInterfaceTypeList(
       node.onClause?.superclassConstraints,
@@ -347,7 +347,7 @@
     }
 
     return node.typeParameters
-        .map<TypeParameterElement>((p) => p.declaredElement2!)
+        .map<TypeParameterElement>((p) => p.declaredElement!)
         .toList();
   }
 
@@ -362,7 +362,7 @@
     );
   }
 
-  static InterfaceType _objectType(ClassElementImpl element) {
+  static InterfaceType _objectType(AbstractClassElementImpl element) {
     return element.library.typeProvider.objectType;
   }
 }
@@ -434,7 +434,7 @@
     List<InterfaceType>? supertypeConstraints;
     InterfaceType Function(List<DartType> typeArguments)? instantiate;
     final mixinElement = mixinNode.name.staticElement;
-    if (mixinElement is ClassElement) {
+    if (mixinElement is InterfaceElement) {
       typeParameters = mixinElement.typeParameters;
       if (typeParameters.isNotEmpty) {
         supertypeConstraints = typeSystem
@@ -518,8 +518,7 @@
   void perform(List<AstNode> declarations) {
     for (var node in declarations) {
       if (node is ClassDeclaration || node is ClassTypeAlias) {
-        var element =
-            (node as Declaration).declaredElement2 as ClassElementImpl;
+        var element = (node as Declaration).declaredElement as ClassElementImpl;
         element.mixinInferenceCallback = _callbackWhenRecursion;
       }
     }
@@ -569,13 +568,13 @@
 
   void _inferDeclaration(AstNode node) {
     if (node is ClassDeclaration) {
-      var element = node.declaredElement2 as ClassElementImpl;
+      var element = node.declaredElement as ClassElementImpl;
       _infer(element, node.withClause);
     } else if (node is ClassTypeAlias) {
-      var element = node.declaredElement2 as ClassElementImpl;
+      var element = node.declaredElement as ClassElementImpl;
       _infer(element, node.withClause);
     } else if (node is EnumDeclaration) {
-      var element = node.declaredElement2 as EnumElementImpl;
+      var element = node.declaredElement as EnumElementImpl;
       _infer(element, node.withClause);
     }
   }
@@ -587,10 +586,10 @@
   void _resetHierarchies(List<AstNode> declarations) {
     for (var declaration in declarations) {
       if (declaration is ClassDeclaration) {
-        var element = declaration.declaredElement2 as ClassElementImpl;
+        var element = declaration.declaredElement as ClassElementImpl;
         element.library.session.classHierarchy.remove(element);
       } else if (declaration is MixinDeclaration) {
-        var element = declaration.declaredElement2 as MixinElementImpl;
+        var element = declaration.declaredElement as MixinElementImpl;
         element.library.session.classHierarchy.remove(element);
       }
     }
diff --git a/pkg/analyzer/lib/src/summary2/variance_builder.dart b/pkg/analyzer/lib/src/summary2/variance_builder.dart
index e2abb85..4bed065 100644
--- a/pkg/analyzer/lib/src/summary2/variance_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/variance_builder.dart
@@ -63,9 +63,9 @@
         return Variance.unrelated;
       }
     } else if (type is NamedTypeBuilder) {
-      var element = type.element;
+      var element = type.element2;
       var arguments = type.arguments;
-      if (element is ClassElement) {
+      if (element is InterfaceElement) {
         var result = Variance.unrelated;
         if (arguments.isNotEmpty) {
           var parameters = element.typeParameters;
@@ -174,7 +174,7 @@
     try {
       for (var parameter in parameterList.typeParameters) {
         var variance = _computeFunctionType(
-          parameter.declaredElement2!,
+          parameter.declaredElement!,
           returnType: node.returnType?.type,
           typeFormals: null,
           parameters: FunctionTypeBuilder.getParameters(
@@ -220,7 +220,7 @@
     _visit.add(node);
     try {
       for (var parameter in parameterList.typeParameters) {
-        var variance = _compute(parameter.declaredElement2!, type);
+        var variance = _compute(parameter.declaredElement!, type);
         _setVariance(parameter, variance);
       }
     } finally {
@@ -257,7 +257,7 @@
   }
 
   static void _setVariance(TypeParameter node, Variance variance) {
-    var element = node.declaredElement2 as TypeParameterElementImpl;
+    var element = node.declaredElement as TypeParameterElementImpl;
     element.variance = variance;
   }
 }
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index c35ff4d..b6ef279 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -660,12 +660,7 @@
             key = k.value?.toString();
             if (!AnalyzerOptions.strongModeOptions.contains(key)) {
               _builder.reportError(reporter, AnalyzerOptions.strongMode, k);
-            } else if (key == AnalyzerOptions.declarationCasts) {
-              reporter.reportErrorForSpan(
-                  AnalysisOptionsWarningCode.ANALYSIS_OPTION_DEPRECATED,
-                  k.span,
-                  [AnalyzerOptions.declarationCasts]);
-            } else {
+            } else if (key != AnalyzerOptions.declarationCasts) {
               // If we have a valid key, go on and check the value.
               validKey = true;
             }
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index d01f62f..47e2661 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -16,6 +16,7 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/error/codes.dart' show CompileTimeErrorCode;
+import 'package:collection/collection.dart';
 
 Element? _getKnownElement(SyntacticEntity expression) {
   if (expression is ParenthesizedExpression) {
@@ -203,7 +204,7 @@
     _visitForEachParts(
       node,
       node.loopVariable.name,
-      node.loopVariable.declaredElement2,
+      node.loopVariable.declaredElement,
     );
     node.visitChildren(this);
   }
@@ -411,9 +412,7 @@
       assert(methodElement.isOperator);
       var functionType = methodElement.type;
       var paramTypes = functionType.normalParameterTypes;
-      assert(paramTypes.length == 1);
-      assert(functionType.namedParameterTypes.isEmpty);
-      assert(functionType.optionalParameterTypes.isEmpty);
+      var paramType = paramTypes.firstOrNull ?? _typeProvider.dynamicType;
 
       // Refine the return type.
       var rhsType = expr.rightHandSide.typeOrThrow;
@@ -426,7 +425,7 @@
       );
 
       // Check the argument for an implicit cast.
-      _checkImplicitCast(expr.rightHandSide, to: paramTypes[0], from: rhsType);
+      _checkImplicitCast(expr.rightHandSide, to: paramType, from: rhsType);
 
       // Check the return type for an implicit cast.
       //
@@ -564,7 +563,7 @@
     FunctionType functionType;
     var parent = body.parent;
     if (parent is Declaration) {
-      functionType = _elementType(parent.declaredElement2!) as FunctionType;
+      functionType = _elementType(parent.declaredElement!) as FunctionType;
     } else {
       assert(parent is FunctionExpression);
       functionType = (parent as FunctionExpression).staticType as FunctionType;
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index e69f550..93f68d9 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -2,8 +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 'dart:collection';
-
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -18,11 +16,11 @@
 /// instance methods within a single compilation unit.
 class InstanceMemberInferrer {
   final InheritanceManager3 inheritance;
-  final Set<ClassElement> elementsBeingInferred = HashSet<ClassElement>();
+  final Set<InterfaceElement> elementsBeingInferred = {};
 
   late TypeSystemImpl typeSystem;
   late bool isNonNullableByDefault;
-  late ClassElement currentClassElement;
+  late InterfaceElement currentInterfaceElement;
 
   /// Initialize a newly create inferrer.
   InstanceMemberInferrer(this.inheritance);
@@ -112,7 +110,7 @@
 
     var getterName = Name(elementLibraryUri, elementName);
     var overriddenGetters = inheritance.getOverridden2(
-      currentClassElement,
+      currentInterfaceElement,
       getterName,
     );
     if (overriddenGetters != null) {
@@ -125,14 +123,14 @@
 
     var setterName = Name(elementLibraryUri, '$elementName=');
     var overriddenSetters = inheritance.getOverridden2(
-      currentClassElement,
+      currentInterfaceElement,
       setterName,
     );
     overriddenSetters ??= const [];
 
     DartType combinedGetterType() {
       var combinedGetter = inheritance.combineSignatures(
-        targetClass: currentClassElement,
+        targetClass: currentInterfaceElement,
         candidates: overriddenGetters!,
         doTopMerge: true,
         name: getterName,
@@ -146,7 +144,7 @@
 
     DartType combinedSetterType() {
       var combinedSetter = inheritance.combineSignatures(
-        targetClass: currentClassElement,
+        targetClass: currentInterfaceElement,
         candidates: overriddenSetters!,
         doTopMerge: true,
         name: setterName,
@@ -309,7 +307,7 @@
   /// Infer type information for all of the instance members in the given
   /// [classElement].
   void _inferClass(InterfaceElement classElement) {
-    if (classElement is ClassElementImpl) {
+    if (classElement is ClassOrMixinElementImpl) {
       if (classElement.hasBeenInferred) {
         return;
       }
@@ -329,11 +327,10 @@
         _inferType(classElement.supertype);
         classElement.mixins.forEach(_inferType);
         classElement.interfaces.forEach(_inferType);
-        classElement.superclassConstraints.forEach(_inferType);
         //
         // Then infer the types for the members.
         //
-        currentClassElement = classElement;
+        currentInterfaceElement = classElement;
         for (var field in classElement.fields) {
           _inferAccessorOrField(
             field: field as FieldElementImpl,
@@ -392,7 +389,7 @@
 
     var name = Name(element.library.source.uri, element.name);
     var overriddenElements = inheritance.getOverridden2(
-      currentClassElement,
+      currentInterfaceElement,
       name,
     );
     if (overriddenElements == null ||
@@ -406,7 +403,7 @@
     if (hasImplicitType) {
       var conflicts = <Conflict>[];
       var combinedSignature = inheritance.combineSignatures(
-        targetClass: currentClassElement,
+        targetClass: currentInterfaceElement,
         candidates: overriddenElements,
         doTopMerge: true,
         name: name,
@@ -424,7 +421,7 @@
           var conflict = conflicts.single;
           if (conflict is CandidatesConflict) {
             conflictExplanation = conflict.candidates.map((candidate) {
-              var className = candidate.enclosingElement3.name;
+              var className = candidate.enclosingElement.name;
               var typeStr = candidate.type.getDisplayString(
                 withNullability: typeSystem.isNonNullableByDefault,
               );
@@ -540,7 +537,7 @@
       overridden = overridden.declaration;
 
       // Skip Object itself.
-      var enclosingElement = overridden.enclosingElement3;
+      var enclosingElement = overridden.enclosingElement;
       if (enclosingElement is ClassElement &&
           enclosingElement.isDartCoreObject) {
         continue;
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element.dart b/pkg/analyzer/lib/src/test_utilities/find_element.dart
index 15100c6..4ec5dec 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_element.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_element.dart
@@ -104,7 +104,7 @@
 
     unit.accept(FunctionAstVisitor(
       functionDeclarationStatement: (node) {
-        var element = node.functionDeclaration.declaredElement2;
+        var element = node.functionDeclaration.declaredElement;
         if (element is FunctionElement && element.name == name) {
           if (result != null) {
             throw StateError('Not unique: $name');
@@ -137,10 +137,10 @@
         updateResult(node.declaredElement!);
       },
       declaredIdentifier: (node) {
-        updateResult(node.declaredElement2!);
+        updateResult(node.declaredElement!);
       },
       variableDeclaration: (node) {
-        updateResult(node.declaredElement2!);
+        updateResult(node.declaredElement!);
       },
     ));
 
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index 6df4a53..b9f53cc 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -67,6 +67,10 @@
     return _node(search, (n) => n is BinaryExpression);
   }
 
+  BinaryPattern binaryPattern(String search) {
+    return _node(search, (n) => n is BinaryPattern);
+  }
+
   Block block(String search) {
     return _node(search, (n) => n is Block);
   }
@@ -87,6 +91,14 @@
     return _node(search, (n) => n is CascadeExpression);
   }
 
+  CaseClause caseClause(String search) {
+    return _node(search, (n) => n is CaseClause);
+  }
+
+  CastPattern castPattern(String search) {
+    return _node(search, (n) => n is CastPattern);
+  }
+
   CatchClause catchClause(String search) {
     return _node(search, (n) => n is CatchClause);
   }
@@ -123,6 +135,10 @@
     return _node(search, (n) => n is Configuration);
   }
 
+  ConstantPattern constantPattern(String search) {
+    return _node(search, (n) => n is ConstantPattern);
+  }
+
   ConstructorDeclaration constructor(String search) {
     return _node(search, (n) => n is ConstructorDeclaration);
   }
@@ -207,6 +223,10 @@
     return _node(search, (n) => n is ExtensionOverride);
   }
 
+  ExtractorPattern extractorPattern(String search) {
+    return _node(search, (n) => n is ExtractorPattern);
+  }
+
   FieldDeclaration fieldDeclaration(String search) {
     return _node(search, (n) => n is FieldDeclaration);
   }
@@ -223,8 +243,20 @@
     return _node(search, (n) => n is ForEachPartsWithIdentifier);
   }
 
+  ForEachPartsWithPattern forEachPartsWithPattern(String search) {
+    return _node(search, (n) => n is ForEachPartsWithPattern);
+  }
+
+  ForElement forElement(String search) {
+    return _node(search, (n) => n is ForElement);
+  }
+
   FormalParameterList formalParameterList(String search) {
-    return _node(search, (n) => n is FormalParameterList);
+    // If the search starts with `(` then NodeLocator will locate the definition
+    // before it, so offset the search to within the parameter list.
+    final locateOffset = search.startsWith('(') ? 1 : 0;
+    return _node(search, (n) => n is FormalParameterList,
+        locateOffset: locateOffset);
   }
 
   ForPartsWithDeclarations forPartsWithDeclarations(String search) {
@@ -235,6 +267,10 @@
     return _node(search, (n) => n is ForPartsWithExpression);
   }
 
+  ForPartsWithPattern forPartsWithPattern(String search) {
+    return _node(search, (n) => n is ForPartsWithPattern);
+  }
+
   ForStatement forStatement(String search) {
     return _node(search, (n) => n is ForStatement);
   }
@@ -319,6 +355,10 @@
     return _node(search, (n) => n is InterpolationExpression);
   }
 
+  InterpolationString interpolationString(String search) {
+    return _node(search, (n) => n is InterpolationString);
+  }
+
   IsExpression isExpression(String search) {
     return _node(search, (n) => n is IsExpression);
   }
@@ -347,10 +387,22 @@
     return _node(search, (n) => n is ListLiteral);
   }
 
+  ListPattern listPattern(String search) {
+    return _node(search, (n) => n is ListPattern);
+  }
+
   MapLiteralEntry mapLiteralEntry(String search) {
     return _node(search, (n) => n is MapLiteralEntry);
   }
 
+  MapPattern mapPattern(String search) {
+    return _node(search, (n) => n is MapPattern);
+  }
+
+  MapPatternEntry mapPatternEntry(String search) {
+    return _node(search, (n) => n is MapPatternEntry);
+  }
+
   MethodDeclaration methodDeclaration(String search) {
     return _node(search, (n) => n is MethodDeclaration);
   }
@@ -404,6 +456,10 @@
     return _node(search, (n) => n is ParenthesizedExpression);
   }
 
+  ParenthesizedPattern parenthesizedPattern(String search) {
+    return _node(search, (n) => n is ParenthesizedPattern);
+  }
+
   PartDirective part(String search) {
     return _node(search, (n) => n is PartDirective);
   }
@@ -412,10 +468,31 @@
     return _node(search, (n) => n is PartOfDirective);
   }
 
+  PatternAssignment patternAssignment(String search) {
+    return _node(search, (n) => n is PatternAssignment);
+  }
+
+  PatternAssignmentStatement patternAssignmentStatement(String search) {
+    return _node(search, (n) => n is PatternAssignmentStatement);
+  }
+
+  PatternVariableDeclaration patternVariableDeclaration(String search) {
+    return _node(search, (n) => n is PatternVariableDeclaration);
+  }
+
+  PatternVariableDeclarationStatement patternVariableDeclarationStatement(
+      String search) {
+    return _node(search, (n) => n is PatternVariableDeclarationStatement);
+  }
+
   PostfixExpression postfix(String search) {
     return _node(search, (n) => n is PostfixExpression);
   }
 
+  PostfixPattern postfixPattern(String search) {
+    return _node(search, (n) => n is PostfixPattern);
+  }
+
   PrefixExpression prefix(String search) {
     return _node(search, (n) => n is PrefixExpression);
   }
@@ -432,6 +509,18 @@
     return _node(search, (n) => n is RecordLiteral);
   }
 
+  RecordPattern recordPattern(String search) {
+    return _node(search, (n) => n is RecordPattern);
+  }
+
+  RecordPatternField recordPatternField(String search) {
+    return _node(search, (n) => n is RecordPatternField);
+  }
+
+  RecordPatternFieldName recordPatternFieldName(String search) {
+    return _node(search, (n) => n is RecordPatternFieldName);
+  }
+
   RecordTypeAnnotation recordTypeAnnotation(String search) {
     return _node(search, (n) => n is RecordTypeAnnotation);
   }
@@ -441,6 +530,10 @@
     return _node(search, (n) => n is RedirectingConstructorInvocation);
   }
 
+  RelationalPattern relationalPattern(String search) {
+    return _node(search, (n) => n is RelationalPattern);
+  }
+
   RethrowExpression rethrow_(String search) {
     return _node(search, (n) => n is RethrowExpression);
   }
@@ -469,6 +562,14 @@
     return _node(search, (n) => n is SimpleFormalParameter);
   }
 
+  SimpleStringLiteral simpleStringLiteral(String search) {
+    return _node(search, (n) => n is SimpleStringLiteral);
+  }
+
+  SpreadElement spreadElement(String search) {
+    return _node(search, (n) => n is SpreadElement);
+  }
+
   Statement statement(String search) {
     return _node(search, (n) => n is Statement);
   }
@@ -501,6 +602,22 @@
     return _node(search, (n) => n is SwitchDefault);
   }
 
+  SwitchExpression switchExpression(String search) {
+    return _node(search, (n) => n is SwitchExpression);
+  }
+
+  SwitchExpressionCase switchExpressionCase(String search) {
+    return _node(search, (n) => n is SwitchExpressionCase);
+  }
+
+  SwitchExpressionDefault switchExpressionDefault(String search) {
+    return _node(search, (n) => n is SwitchExpressionDefault);
+  }
+
+  SwitchPatternCase switchPatternCase(String search) {
+    return _node(search, (n) => n is SwitchPatternCase);
+  }
+
   SwitchStatement switchStatement(String search) {
     return _node(search, (n) => n is SwitchStatement);
   }
@@ -525,7 +642,7 @@
     for (var declaration in unit.declarations) {
       if (declaration is TopLevelVariableDeclaration) {
         for (var variable in declaration.variables.variables) {
-          if (variable.name2.lexeme == name) {
+          if (variable.name.lexeme == name) {
             return variable;
           }
         }
@@ -574,6 +691,14 @@
     return _node(search, (n) => n is VariableDeclarationStatement);
   }
 
+  VariablePattern variablePattern(String search) {
+    return _node(search, (n) => n is VariablePattern);
+  }
+
+  WhenClause whenClause(String search) {
+    return _node(search, (n) => n is WhenClause);
+  }
+
   WhileStatement whileStatement(String search) {
     return _node(search, (n) => n is WhileStatement);
   }
@@ -586,8 +711,14 @@
     return _node(search, (n) => n is YieldStatement);
   }
 
-  T _node<T>(String search, bool Function(AstNode) predicate) {
-    int offset = this.offset(search);
+  /// Locates a node at the offset of [search] and returns the first ancestor
+  /// matching [predicate].
+  ///
+  /// If [locateOffset] is provided, its value is added to the offset of
+  /// [search] before locating the node.
+  T _node<T>(String search, bool Function(AstNode) predicate,
+      {int? locateOffset}) {
+    int offset = this.offset(search) + (locateOffset ?? 0);
 
     var node = NodeLocator2(offset).searchWithin(unit);
     if (node == null) {
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 924d688..7c245f0 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -218,6 +218,10 @@
 abstract class MapMixin<K, V> implements Map<K, V> { }
 
 abstract class SetMixin<E> implements Set<E> { }
+
+abstract class Queue<E> implements Iterable<E> {
+  bool remove(Object? value);
+}
 ''',
   )
 ]);
@@ -499,8 +503,10 @@
   void addAll(Map<K, V> other);
   Map<RK, RV> cast<RK, RV>();
   bool containsKey(Object? key);
+  bool containsValue(Object? value);
   void forEach(void action(K key, V value));
   V putIfAbsent(K key, V ifAbsent());
+  V? remove(Object? key);
 }
 
 class Null extends Object {
@@ -595,8 +601,13 @@
 
   bool add(E value);
   void addAll(Iterable<E> elements);
-  bool remove(Object? value);
+  bool containsAll(Iterable<Object?> other);
+  Set<E> difference(Set<Object?> other);
+  Set<E> intersection(Set<Object?> other);
   E? lookup(Object? object);
+  bool remove(Object? value);
+  void removeAll(Iterable<Object?> elements);
+  void retainAll(Iterable<Object?> elements);
 
   static Set<T> castFrom<S, T>(Set<S> source, {Set<R> Function<R>()? newSet}) =>
       throw '';
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
index a415ac94..5a10a24 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
@@ -1151,7 +1151,7 @@
 
   TypeParameterType _typeParameterType(TypeParameterElement element) {
     return TypeParameterTypeImpl(
-      element: element,
+      element2: element,
       nullabilitySuffix: NullabilitySuffix.none,
     );
   }
diff --git a/pkg/analyzer/lib/src/util/ast_data_extractor.dart b/pkg/analyzer/lib/src/util/ast_data_extractor.dart
index 46ac78b..ff0650a 100644
--- a/pkg/analyzer/lib/src/util/ast_data_extractor.dart
+++ b/pkg/analyzer/lib/src/util/ast_data_extractor.dart
@@ -8,14 +8,14 @@
 import 'package:analyzer/dart/element/element.dart';
 
 MemberId computeMemberId(Element element) {
-  var enclosingElement = element.enclosingElement3;
+  var enclosingElement = element.enclosingElement;
   if (enclosingElement is CompilationUnitElement) {
     var memberName = element.name!;
     if (element is PropertyAccessorElement && element.isSetter) {
       memberName += '=';
     }
     return MemberId.internal(memberName);
-  } else if (enclosingElement is ClassElement) {
+  } else if (enclosingElement is InterfaceElement) {
     var memberName = element.name!;
     var className = enclosingElement.name;
     return MemberId.internal(memberName, className: className);
@@ -95,7 +95,7 @@
   T? computeNodeValue(Id id, AstNode node);
 
   Id createClassId(Declaration node) {
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     return ClassId(element.name!);
   }
 
@@ -109,7 +109,7 @@
   }
 
   Id createMemberId(Declaration node) {
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     return computeMemberId(element);
   }
 
diff --git a/pkg/analyzer/lib/src/utilities/extensions/string.dart b/pkg/analyzer/lib/src/utilities/extensions/string.dart
index a6ad2d8..8cb7877 100644
--- a/pkg/analyzer/lib/src/utilities/extensions/string.dart
+++ b/pkg/analyzer/lib/src/utilities/extensions/string.dart
@@ -75,3 +75,9 @@
     }
   }
 }
+
+extension StringExtension on String {
+  String ifNotEmptyOrElse(String orElse) {
+    return isNotEmpty ? this : orElse;
+  }
+}
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index c098220..9c2d6d1 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -71,9 +71,6 @@
       An error code indicating that the enablePreviewDart2 setting is
       deprecated.
 AnalysisOptionsWarningCode:
-  ANALYSIS_OPTION_DEPRECATED:
-    problemMessage: "The option '{0}' is no longer supported."
-    comment: An error code indicating that the given option is deprecated.
   INCLUDED_FILE_WARNING:
     problemMessage: "Warning in the included options file {0}({1}..{2}): {3}"
     comment: |-
@@ -98,6 +95,10 @@
     comment: |-
       An error code indicating that a plugin is being configured with an invalid
       value for an option and a detail message is provided.
+      
+      Parameters:
+      0: the option name
+      1: the detail message
   INVALID_SECTION_FORMAT:
     problemMessage: "Invalid format for the '{0}' section."
     comment: |-
@@ -374,8 +375,7 @@
     comment: |-
       Parameters:
       0: the name of the ambiguous type
-      1: the name of the first library that the type is found
-      2: the name of the second library that the type is found
+      1: the names of the libraries that the type is found
     documentation: |-
       #### Description
 
@@ -773,7 +773,9 @@
     problemMessage: "The final variable '{0}' can only be set once."
     correctionMessage: "Try making '{0}' non-final."
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the variable
     documentation: |-
       #### Description
 
@@ -809,7 +811,10 @@
     problemMessage: "There isn’t a setter named '{0}' in class '{1}'."
     correctionMessage: Try correcting the name to reference an existing setter, or declare the setter.
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the reference
+      1: the name of the class
     documentation: |-
       #### Description
 
@@ -1085,7 +1090,9 @@
     problemMessage: "The body might complete normally, causing 'null' to be returned, but the return type, '{0}', is a potentially non-nullable type."
     correctionMessage: Try adding either a return or a throw statement at the end.
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the return type
     documentation: |-
       #### Description
 
@@ -1505,7 +1512,9 @@
     problemMessage: "The name '{0}' isn't a type, so it can't be used in an 'as' expression."
     correctionMessage: "Try changing the name to the name of an existing type, or creating a type with the name '{0}'."
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the type
     documentation: |-
       #### Description
 
@@ -1543,7 +1552,8 @@
     correctionMessage: "Try invoking a different constructor, or defining a constructor named '{1}'."
     comment: |-
       Parameters:
-      0: the name of the member
+      0: the name of the class
+      1: the name of the member
   CLASS_INSTANTIATION_ACCESS_TO_STATIC_MEMBER:
     sharedName: CLASS_INSTANTIATION_ACCESS_TO_MEMBER
     problemMessage: "The static member '{0}' can't be accessed on a class instantiation."
@@ -2023,6 +2033,11 @@
     comment: |-
       16.12.2 Const: It is a compile-time error if evaluation of a constant
       object results in an uncaught exception being thrown.
+
+      Parameters:
+      0: the type of the runtime value of the argument
+      1: the name of the field
+      2: the type of the field
   CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH:
     problemMessage: "A value of type '{0}' can't be assigned to a parameter of type '{1}' in a const constructor."
     correctionMessage: "Try using a subtype, or removing the keyword 'const'."
@@ -3323,7 +3338,7 @@
       ```
 
       If there are multiple named constructors and all except one of them are
-      unneeded, then remove the constructorsthat aren't needed:
+      unneeded, then remove the constructors that aren't needed:
 
       ```dart
       class C {
@@ -3365,8 +3380,8 @@
     problemMessage: The field name '{0}' is already used in this record.
     correctionMessage: Try renaming the field.
     comment: |-
-       Parameters:
-       0: the duplicated name
+      Parameters:
+      0: the duplicated name
   DUPLICATE_FIELD_FORMAL_PARAMETER:
     problemMessage: "The field '{0}' can't be initialized by multiple parameters in the same constructor."
     correctionMessage: Try removing one of the parameters, or using different fields.
@@ -3999,9 +4014,7 @@
     correctionMessage: Try specifying a different superclass, or removing the extends clause.
     isUnresolvedIdentifier: true
     hasPublishedDocs: true
-    comment: |-
-      Parameters:
-      0: the name in the extends clause
+    comment: No parameters.
     documentation: |-
       #### Description
 
@@ -5485,6 +5498,9 @@
   ILLEGAL_LANGUAGE_VERSION_OVERRIDE:
     problemMessage: The language version must be {0}.
     correctionMessage: Try removing the language version override and migrating the code.
+    comment: |-
+      Parameters:
+      0: the required language version
   ILLEGAL_CONCRETE_ENUM_MEMBER_DECLARATION:
     sharedName: ILLEGAL_CONCRETE_ENUM_MEMBER
     problemMessage: A concrete instance member named '{0}' can't be declared in a class that implements 'Enum'.
@@ -5605,9 +5621,7 @@
     problemMessage: Classes and mixins can only implement other classes and mixins.
     correctionMessage: Try specifying a class or mixin, or remove the name from the list.
     hasPublishedDocs: true
-    comment: |-
-      Parameters:
-      0: the name of the interface that was not found
+    comment: No parameters.
     documentation: |-
       #### Description
 
@@ -6512,6 +6526,7 @@
     comment: |-
       Parameters:
       0: the lexeme of the integer
+      1: the closest valid double
     documentation: |-
       #### Description
 
@@ -6548,7 +6563,9 @@
     problemMessage: "The integer literal {0} can't be represented in 64 bits."
     correctionMessage: "Try using the 'BigInt' class if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808."
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the value of the literal
     documentation: |-
       #### Description
 
@@ -6794,8 +6811,9 @@
     problemMessage: "The function '{0}' has type '{1}' that isn't of expected type '{2}'. This means its parameter or return type doesn't match what is expected."
     comment: |-
       Parameters:
-      0: the type of the function
-      1: the expected function type
+      0: the name of the function
+      1: the type of the function
+      2: the expected function type
 
       This error is only reported in libraries which are not null safe.
   INVALID_CAST_FUNCTION_EXPR:
@@ -6810,8 +6828,9 @@
     problemMessage: "The literal '{0}' with type '{1}' isn't of expected type '{2}'."
     comment: |-
       Parameters:
-      0: the type of the literal
-      1: the expected type
+      0: the lexeme of the literal
+      1: the type of the literal
+      2: the expected type
 
       This error is only reported in libraries which are not null safe.
   INVALID_CAST_LITERAL_LIST:
@@ -6842,8 +6861,9 @@
     problemMessage: "The method tear-off '{0}' has type '{1}' that isn't of expected type '{2}'. This means its parameter or return type doesn't match what is expected."
     comment: |-
       Parameters:
-      0: the type of the torn-off method
-      1: the expected function type
+      0: the name of the torn-off method
+      1: the type of the torn-off method
+      2: the expected function type
 
       This error is only reported in libraries which are not null safe.
   INVALID_CAST_NEW_EXPR:
@@ -6985,7 +7005,9 @@
     comment: No parameters.
   INVALID_FIELD_NAME_POSITIONAL:
     sharedName: INVALID_FIELD_NAME
-    problemMessage: Record field names can't be a dollar sign followed by digits because those are used to access positional fields.
+    problemMessage: |-
+      Record field names can't be a dollar sign followed by an integer when the
+      integer is the index of a positional field.
     correctionMessage: Try using a different name for the field.
     comment: No parameters.
   INVALID_IMPLEMENTATION_OVERRIDE:
@@ -6996,8 +7018,8 @@
       0: the name of the declared member that is not a valid override.
       1: the name of the interface that declares the member.
       2: the type of the declared member in the interface.
-      3. the name of the interface with the overridden member.
-      4. the type of the overridden member.
+      3: the name of the interface with the overridden member.
+      4: the type of the overridden member.
 
       These parameters must be kept in sync with those of
       [CompileTimeErrorCode.INVALID_OVERRIDE].
@@ -7161,9 +7183,7 @@
     problemMessage: "Setters can't use 'async', 'async*', or 'sync*'."
     correctionMessage: Try removing the modifier.
     hasPublishedDocs: true
-    comment: |-
-      Parameters:
-      0: the invalid modifier
+    comment: No parameters.
     documentation: |-
       #### Description
 
@@ -7208,8 +7228,8 @@
       0: the name of the declared member that is not a valid override.
       1: the name of the interface that declares the member.
       2: the type of the declared member in the interface.
-      3. the name of the interface with the overridden member.
-      4. the type of the overridden member.
+      3: the name of the interface with the overridden member.
+      4: the type of the overridden member.
     documentation: |-
       #### Description
 
@@ -7360,9 +7380,7 @@
     problemMessage: Super parameters can only be used in non-redirecting generative constructors.
     correctionMessage: Try removing the 'super' modifier, or changing the constructor to be non-redirecting and generative.
     hasPublishedDocs: true
-    comment: |-
-      Parameters:
-      0: the super modifier
+    comment: No parameters.
     documentation: |-
       #### Description
       
@@ -8238,7 +8256,9 @@
     problemMessage: "Required library '{0}' is missing."
     correctionMessage: Re-install the Dart or Flutter SDK.
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the library
     documentation: |-
       #### Description
 
@@ -8253,7 +8273,9 @@
     problemMessage: "The parameter '{0}' can't have a value of 'null' because of its type, but the implicit default value is 'null'."
     correctionMessage: "Try adding either an explicit non-'null' default value or the 'required' modifier."
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the parameter
     documentation: |-
       #### Description
 
@@ -8302,6 +8324,14 @@
       void f(int x) {}
       void g({required int x}) {}
       ```
+  MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL:
+    sharedName: MISSING_DEFAULT_VALUE_FOR_PARAMETER
+    problemMessage: "The parameter '{0}' can't have a value of 'null' because of its type, but the implicit default value is 'null'."
+    correctionMessage: "Try adding an explicit non-'null' default value."
+    hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the name of the parameter
   MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION:
     sharedName: MISSING_DEFAULT_VALUE_FOR_PARAMETER
     problemMessage: "With null safety, use the 'required' keyword, not the '@required' annotation."
@@ -8952,6 +8982,10 @@
       x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>:
       a<sub>n+kM/sub>)</i> it is a static warning if the type <i>T</i> does not
       declare a constructor with the same name as the declaration of <i>T</i>.
+
+      Parameters:
+      0: the name of the class being instantiated
+      1: the name of the constructor
   NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT:
     problemMessage: "The class '{0}' doesn't have an unnamed constructor."
     correctionMessage: "Try using one of the named constructors defined in '{0}'."
@@ -9920,7 +9954,7 @@
       }
       ```
   NON_TYPE_AS_TYPE_ARGUMENT:
-    problemMessage: "The name '{0}' isn't a type so it can't be used as a type argument."
+    problemMessage: "The name '{0}' isn't a type, so it can't be used as a type argument."
     correctionMessage: "Try correcting the name to an existing type, or defining a type named '{0}'."
     isUnresolvedIdentifier: true
     hasPublishedDocs: true
@@ -10980,8 +11014,7 @@
     hasPublishedDocs: true
     comment: |-
       Parameters:
-      0: the URI of the expected library
-      1: the non-matching actual library name from the "part of" declaration
+      0: the non-matching actual library name from the "part of" declaration
     documentation: |-
       #### Description
 
@@ -11305,6 +11338,9 @@
     problemMessage: "The setter '{0}' is private and can't be accessed outside the library that declares it."
     correctionMessage: Try making it public.
     hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the name of the setter
     documentation: |-
       #### Description
 
@@ -11350,6 +11386,9 @@
     problemMessage: "The final variable '{0}' can't be read because it's potentially unassigned at this point."
     correctionMessage: Ensure that it is assigned on necessary execution paths.
     hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the name of the variable
     documentation: |-
       #### Description
 
@@ -11604,7 +11643,10 @@
     problemMessage: "The constructor '{0}' couldn't be found in '{1}'."
     correctionMessage: "Try redirecting to a different constructor, or defining the constructor named '{0}'."
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the constructor
+      1: the name of the class
     documentation: |-
       #### Description
 
@@ -12052,7 +12094,9 @@
     problemMessage: "Local variable '{0}' can't be referenced before it is declared."
     correctionMessage: "Try moving the declaration to before the first use, or renaming the local variable so that it doesn't hide a name from an enclosing scope."
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the variable
     documentation: |-
       #### Description
 
@@ -12867,7 +12911,7 @@
       0: the name of the disallowed type
   MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS:
     sharedName: SUBTYPE_OF_DISALLOWED_TYPE
-    problemMessage: "''{0}' can't be used as a superclass constraint."
+    problemMessage: "'{0}' can't be used as a superclass constraint."
     correctionMessage: "Try specifying a different super-class constraint, or remove the 'on' clause."
     hasPublishedDocs: true
     comment: |-
@@ -13517,7 +13561,9 @@
     problemMessage: "The name '{0}' isn't a type and can't be used in an 'is' expression."
     correctionMessage: Try correcting the name to match an existing type.
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the type
     documentation: |-
       #### Description
 
@@ -13569,7 +13615,9 @@
     problemMessage: "The name '{0}' isn't defined, so it can't be used in an 'is' expression."
     correctionMessage: "Try changing the name to the name of an existing type, or creating a type with the name '{0}'."
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the type
     documentation: |-
       #### Description
 
@@ -13615,11 +13663,17 @@
     problemMessage: "The method '{0}' can't be unconditionally invoked because the receiver can be 'null'."
     correctionMessage: "Try making the call conditional (using '?.') or adding a null check to the target ('!')."
     hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the name of the method
   UNCHECKED_OPERATOR_INVOCATION_OF_NULLABLE_VALUE:
     sharedName: UNCHECKED_USE_OF_NULLABLE_VALUE
     problemMessage: "The operator '{0}' can't be unconditionally invoked because the receiver can be 'null'."
     correctionMessage: "Try adding a null check to the target ('!')."
     hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the name of the operator
   UNCHECKED_USE_OF_NULLABLE_VALUE_IN_YIELD_EACH:
     sharedName: UNCHECKED_USE_OF_NULLABLE_VALUE
     problemMessage: "A nullable expression can't be used in a yield-each statement."
@@ -13696,12 +13750,17 @@
     problemMessage: "The property '{0}' can't be unconditionally accessed because the receiver can be 'null'."
     correctionMessage: "Try making the access conditional (using '?.') or adding a null check to the target ('!')."
     hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the name of the property
   UNDEFINED_ANNOTATION:
     problemMessage: "Undefined name '{0}' used as an annotation."
     correctionMessage: Try defining the name or importing it from another library.
     isUnresolvedIdentifier: true
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the annotation
     documentation: |-
       #### Description
 
@@ -14657,7 +14716,10 @@
     problemMessage: "The name '{0}' is being referenced through the prefix '{1}', but it isn't defined in any of the libraries imported using that prefix."
     correctionMessage: "Try correcting the prefix or importing the library that defines '{0}'."
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the reference
+      1: the name of the prefix
     documentation: |-
       #### Description
 
@@ -15541,6 +15603,10 @@
       Let `C` be a generic class that declares a formal type parameter `X`, and
       assume that `T` is a direct superinterface of `C`. It is a compile-time
       error if `X` occurs contravariantly or invariantly in `T`.
+
+      Parameters:
+      0: the name of the type parameter
+      1: the name of the super interface
   WRONG_TYPE_PARAMETER_VARIANCE_POSITION:
     problemMessage: "The '{0}' type parameter '{1}' can't be used in an '{2}' position."
     correctionMessage: "Try removing the type parameter or change the explicit variance modifier declaration for the type parameter to another one of 'in', 'out', or 'inout'."
@@ -15723,7 +15789,7 @@
       }
       ```
 
-      The following code produces this diagnostic because the class `C` defineS
+      The following code produces this diagnostic because the class `C` defines
       a field:
 
       ```dart
@@ -16741,9 +16807,7 @@
   MISSING_FIELD_TYPE_IN_STRUCT:
     problemMessage: "Fields in struct classes must have an explicitly declared type of 'int', 'double' or 'Pointer'."
     correctionMessage: "Try using 'int', 'double' or 'Pointer'."
-    comment: |-
-      Parameters:
-      0: the type of the field
+    comment: No parameters.
     hasPublishedDocs: true
     documentation: |-
       #### Description
@@ -17086,7 +17150,8 @@
     correctionMessage: "Try using a native integer, 'Float', 'Double', 'Pointer', or subtype of 'Struct', 'Union', or 'AbiSpecificInteger'."
     comment: |-
       Parameters:
-      0: the type of the field
+      0: the name of the field
+      1: the type of the field
     hasPublishedDocs: true
     documentation: |-
       #### Description
@@ -17460,7 +17525,11 @@
   ASSIGNMENT_OF_DO_NOT_STORE:
     problemMessage: "'{0}' is marked 'doNotStore' and shouldn't be assigned to a field or top-level variable."
     correctionMessage: Try removing the assignment.
-    comment: Users should not assign values marked `@doNotStore`.
+    comment: |-
+      Users should not assign values marked `@doNotStore`.
+
+      Parameters:
+      0: the name of the field or variable
     hasPublishedDocs: true
     documentation: |-
       #### Description
@@ -18266,9 +18335,10 @@
     problemMessage: "The library '{0}' is legacy, and shouldn't be imported into a null safe library."
     correctionMessage: Try migrating the imported library.
     comment: |-
-      No parameters.
-
       https://github.com/dart-lang/sdk/issues/44063
+
+      Parameters:
+      0: the name of the library
     hasPublishedDocs: true
     documentation: |-
       #### Description
@@ -18310,12 +18380,18 @@
     comment: |-
       When "strict-inference" is enabled, collection literal types must be
       inferred via the context type, or have type arguments.
+
+      Parameters:
+      0: the name of the collection
   INFERENCE_FAILURE_ON_FUNCTION_INVOCATION:
     problemMessage: "The type argument(s) of the function '{0}' can't be inferred."
     correctionMessage: "Use explicit type argument(s) for '{0}'."
     comment: |-
       When "strict-inference" is enabled, types in function invocations must be
       inferred via the context type, or have type arguments.
+
+      Parameters:
+      0: the name of the function
   INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE:
     problemMessage: "The return type of '{0}' cannot be inferred."
     correctionMessage: "Declare the return type of '{0}'."
@@ -18325,12 +18401,18 @@
       specify a return type. See the strict-inference resource:
 
       https://github.com/dart-lang/language/blob/master/resources/type-system/strict-inference.md
+
+      Parameters:
+      0: the name of the function or method
   INFERENCE_FAILURE_ON_GENERIC_INVOCATION:
     problemMessage: "The type argument(s) of the generic function type '{0}' can't be inferred."
     correctionMessage: "Use explicit type argument(s) for '{0}'."
     comment: |-
       When "strict-inference" is enabled, types in function invocations must be
       inferred via the context type, or have type arguments.
+
+      Parameters:
+      0: the name of the type
   INFERENCE_FAILURE_ON_INSTANCE_CREATION:
     problemMessage: "The type argument(s) of the constructor '{0}' can't be inferred."
     correctionMessage: "Use explicit type argument(s) for '{0}'."
@@ -18338,18 +18420,27 @@
       When "strict-inference" is enabled, types in instance creation
       (constructor calls) must be inferred via the context type, or have type
       arguments.
+
+      Parameters:
+      0: the name of the constructor
   INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE:
     problemMessage: "The type of {0} can't be inferred without either a type or initializer."
     correctionMessage: Try specifying the type of the variable.
     comment: |-
       When "strict-inference" in enabled, uninitialized variables must be
       declared with a specific type.
+
+      Parameters:
+      0: the name of the variable
   INFERENCE_FAILURE_ON_UNTYPED_PARAMETER:
     problemMessage: "The type of {0} can't be inferred; a type must be explicitly provided."
     correctionMessage: Try specifying the type of the parameter.
     comment: |-
       When "strict-inference" in enabled, function parameters must be
       declared with a specific type, or inherit a type.
+
+      Parameters:
+      0: the name of the parameter
   INVALID_ANNOTATION_TARGET:
     problemMessage: "The annotation '{0}' can only be used on {1}."
     comment: |-
@@ -18427,6 +18518,7 @@
     comment: |-
       Parameters:
       0: the name of the element
+      1: ?
     hasPublishedDocs: true
     documentation: |-
       #### Description
@@ -18626,6 +18718,10 @@
     problemMessage: "The language version override can't specify a version greater than the latest known language version: {0}.{1}."
     correctionMessage: Try removing the language version override.
     hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the latest major version
+      1: the latest minor version
   INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN:
     sharedName: INVALID_LANGUAGE_VERSION_OVERRIDE
     problemMessage: "The Dart language version override number must begin with '@dart'."
@@ -19453,6 +19549,9 @@
     comment: |-
       Generate a hint for classes that inherit from classes annotated with
       `@immutable` but that are not immutable.
+
+      Parameters:
+      0: the name of the class
     documentation: |-
       #### Description
 
@@ -19905,7 +20004,9 @@
     problemMessage: "The class '{0}' wasn't exported from 'dart:core' until version 2.1, but this code is required to be able to run on earlier versions."
     correctionMessage: "Try either importing 'dart:async' or updating the SDK constraints."
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the class
     documentation: |-
       #### Description
 
@@ -20006,7 +20107,9 @@
     problemMessage: "The use of the operator '{0}' for 'bool' operands in a constant context wasn't supported until version 2.3.2, but this code is required to be able to run on earlier versions."
     correctionMessage: Try updating the SDK constraints.
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the operator
     documentation: |-
       #### Description
 
@@ -20548,6 +20651,9 @@
 
       A "raw type" is a type name that does not use inference to fill in missing
       type arguments; instead, each type argument is instantiated to its bound.
+
+      Parameters:
+      0: the name of the generic type
   SUBTYPE_OF_SEALED_CLASS:
     problemMessage: "The class '{0}' shouldn't be extended, mixed in, or implemented because it's sealed."
     correctionMessage: "Try composing instead of inheriting, or refer to the documentation of '{0}' for more information."
@@ -21286,9 +21392,9 @@
       - Assigning a value to a top-level variable (with a standard `=`
         assignment, or a null-aware `??=` assignment) does not count as using
         it.
-      - Refering to an element in a doc comment reference does not count as
+      - Referring to an element in a doc comment reference does not count as
         using it.
-      - Refering to a class, mixin, or enum in the right side of an `is`
+      - Referring to a class, mixin, or enum on the right side of an `is`
         expression does not count as using it.
 
       #### Example
@@ -21605,12 +21711,22 @@
   IMPLICIT_DYNAMIC_FIELD:
     problemMessage: "Missing field type for '{0}'."
     correctionMessage: Try adding an explicit type, or remove implicit-dynamic from your analysis options file.
+    comment: |-
+      Parameters:
+      0: the name of the field
   IMPLICIT_DYNAMIC_FUNCTION:
     problemMessage: "Missing type arguments for generic function '{0}<{1}>'."
     correctionMessage: Try adding an explicit type, or remove implicit-dynamic from your analysis options file.
+    comment: |-
+      Parameters:
+      0: the name of the function
+      1: the names of the type arguments
   IMPLICIT_DYNAMIC_INVOKE:
     problemMessage: "Missing type arguments for calling generic function type '{0}'."
     correctionMessage: Try adding an explicit type, or remove implicit-dynamic from your analysis options file.
+    comment: |-
+      Parameters:
+      0: the name of type
   IMPLICIT_DYNAMIC_LIST_LITERAL:
     problemMessage: Missing type argument for list literal.
     correctionMessage: Try adding an explicit type, or remove implicit-dynamic from your analysis options file.
@@ -21620,18 +21736,34 @@
   IMPLICIT_DYNAMIC_METHOD:
     problemMessage: "Missing type arguments for generic method '{0}<{1}>'."
     correctionMessage: Try adding an explicit type, or remove implicit-dynamic from your analysis options file.
+    comment: |-
+      Parameters:
+      0: the name of the function
+      1: the names of the type arguments
   IMPLICIT_DYNAMIC_PARAMETER:
     problemMessage: "Missing parameter type for '{0}'."
     correctionMessage: Try adding an explicit type, or remove implicit-dynamic from your analysis options file.
+    comment: |-
+      Parameters:
+      0: the name of the parameter
   IMPLICIT_DYNAMIC_RETURN:
     problemMessage: "Missing return type for '{0}'."
     correctionMessage: Try adding an explicit type, or remove implicit-dynamic from your analysis options file.
+    comment: |-
+      Parameters:
+      0: the name of the function or method
   IMPLICIT_DYNAMIC_TYPE:
     problemMessage: "Missing type arguments for generic type '{0}'."
     correctionMessage: Try adding an explicit type, or remove implicit-dynamic from your analysis options file.
+    comment: |-
+      Parameters:
+      0: the name of the type
   IMPLICIT_DYNAMIC_VARIABLE:
     problemMessage: "Missing variable type for '{0}'."
     correctionMessage: Try adding an explicit type, or remove implicit-dynamic from your analysis options file.
+    comment: |-
+      Parameters:
+      0: the name of the variable
 ManifestWarningCode:
   CAMERA_PERMISSIONS_INCOMPATIBLE:
     problemMessage: Camera permissions make app incompatible for Chrome OS, consider adding optional features "android.hardware.camera" and "android.hardware.camera.autofocus".
@@ -21655,6 +21787,9 @@
     comment: |-
       A code indicating that a specified permission is not supported on Chrome
       OS.
+
+      Parameters:
+      0: the name of the feature tag
   SETTING_ORIENTATION_ON_ACTIVITY:
     problemMessage: The `<activity>` element should not be locked to any orientation so that users can take advantage of the multi-window environments and larger screens on Chrome OS
     correctionMessage: Consider declaring the corresponding activity element with `screenOrientation="unspecified"` or `"fullSensor"` attribute.
@@ -21662,13 +21797,20 @@
   UNSUPPORTED_CHROME_OS_FEATURE:
     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.
+    comment: |-
+      A code indicating that a specified feature is not supported on Chrome OS.
+
+      Parameters:
+      0: the name of the feature
   UNSUPPORTED_CHROME_OS_HARDWARE:
     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
       Chrome OS.
+
+      Parameters:
+      0: the name of the feature
 ParserErrorCode:
   ABSTRACT_ENUM:
     problemMessage: "Enums can't be declared to be 'abstract'."
@@ -21752,6 +21894,22 @@
   EXPECTED_LIST_OR_MAP_LITERAL:
     problemMessage: Expected a list or map literal.
     correctionMessage: Try inserting a list or map literal, or remove the type arguments.
+  EXPECTED_NAMED_TYPE_EXTENDS:
+    sharedName: EXPECTED_NAMED_TYPE
+    problemMessage: Expected a class name.
+    correctionMessage: Try using a class name, possibly with type arguments.
+  EXPECTED_NAMED_TYPE_IMPLEMENTS:
+    sharedName: EXPECTED_NAMED_TYPE
+    problemMessage: Expected the name of a class or mixin.
+    correctionMessage: Try using a class or mixin name, possibly with type arguments.
+  EXPECTED_NAMED_TYPE_ON:
+    sharedName: EXPECTED_NAMED_TYPE
+    problemMessage: Expected the name of a class or mixin.
+    correctionMessage: Try using a class or mixin name, possibly with type arguments.
+  EXPECTED_NAMED_TYPE_WITH:
+    sharedName: EXPECTED_NAMED_TYPE
+    problemMessage: Expected a mixin name.
+    correctionMessage: Try using a mixin name, possibly with type arguments.
   EXPECTED_STRING_LITERAL:
     problemMessage: Expected a string literal.
   EXPECTED_TOKEN:
@@ -22119,7 +22277,9 @@
     problemMessage: "The value of the '{0}' field is expected to be a map."
     correctionMessage: Try converting the value to be a map.
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the field
     documentation: |-
       #### Description
 
@@ -22152,7 +22312,9 @@
     problemMessage: "The '{0}' field is no longer used and can be removed."
     correctionMessage: Try removing the field.
     hasPublishedDocs: true
-    comment: No parameters.
+    comment: |-
+      Parameters:
+      0: the name of the field
     documentation: |-
       #### Description
 
@@ -22649,6 +22811,11 @@
       <i>m2</i> explicitly specifies a default value for a formal parameter
       <i>p</i> and the signature of <i>m1</i> specifies a different default value
       for <i>p</i>.
+
+      Parameters:
+      0: the name of the super class
+      1: the name of the super method
+      2: the name of the overriding method
   INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL:
     problemMessage: "Parameters can't override default values, this method overrides '{0}.{1}' where this positional parameter has a different value."
     correctionMessage: Try using the same default value in both methods.
@@ -22658,6 +22825,9 @@
       <i>m2</i> explicitly specifies a default value for a formal parameter
       <i>p</i> and the signature of <i>m1</i> specifies a different default value
       for <i>p</i>.
+      Parameters:
+      0: the name of the super class
+      1: the name of the super method
   MISSING_ENUM_CONSTANT_IN_SWITCH:
     problemMessage: "Missing case clause for '{0}'."
     correctionMessage: Try adding a case clause for the missing constant, or adding a default clause.
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 9196fd8..9add5b3 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 4.7.0-dev
+version: 5.2.0-dev
 description: This package provides a library that performs static analysis of Dart code.
 repository: https://github.com/dart-lang/sdk/tree/main/pkg/analyzer
 
@@ -7,7 +7,7 @@
   sdk: '>=2.17.0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared: ^46.0.0
+  _fe_analyzer_shared: ^49.0.0
   collection: ^1.15.0
   convert: ^3.0.0
   crypto: ^3.0.0
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index 64790b4..d22109c 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -8,12 +8,10 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
-import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
 import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -22,142 +20,33 @@
 import '../../src/diagnostics/parser_diagnostics.dart';
 import '../../util/feature_sets.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ClassDeclarationTest);
-    defineReflectiveTests(ClassTypeAliasTest);
     defineReflectiveTests(ConstructorDeclarationTest);
     defineReflectiveTests(FieldFormalParameterTest);
     defineReflectiveTests(FormalParameterIsExplicitlyTypedTest);
+    defineReflectiveTests(HideClauseImplTest);
+    defineReflectiveTests(ImplementsClauseImplTest);
     defineReflectiveTests(IndexExpressionTest);
     defineReflectiveTests(InterpolationStringTest);
     defineReflectiveTests(MethodDeclarationTest);
     defineReflectiveTests(MethodInvocationTest);
     defineReflectiveTests(NodeListTest);
     defineReflectiveTests(NormalFormalParameterTest);
+    defineReflectiveTests(OnClauseImplTest);
     defineReflectiveTests(PreviousTokenTest);
     defineReflectiveTests(PropertyAccessTest);
+    defineReflectiveTests(ShowClauseImplTest);
     defineReflectiveTests(SimpleIdentifierTest);
     defineReflectiveTests(SimpleStringLiteralTest);
     defineReflectiveTests(SpreadElementTest);
     defineReflectiveTests(StringInterpolationTest);
     defineReflectiveTests(VariableDeclarationTest);
+    defineReflectiveTests(WithClauseImplTest);
   });
 }
 
 @reflectiveTest
-class ClassDeclarationTest extends ParserTestCase {
-  @Deprecated('Filter members instead')
-  void test_getConstructor() {
-    List<ConstructorInitializer> initializers = <ConstructorInitializer>[];
-    ConstructorDeclaration defaultConstructor =
-        AstTestFactory.constructorDeclaration(
-            AstTestFactory.identifier3("Test"),
-            null,
-            AstTestFactory.formalParameterList(),
-            initializers);
-    ConstructorDeclaration aConstructor = AstTestFactory.constructorDeclaration(
-        AstTestFactory.identifier3("Test"),
-        "a",
-        AstTestFactory.formalParameterList(),
-        initializers);
-    ConstructorDeclaration bConstructor = AstTestFactory.constructorDeclaration(
-        AstTestFactory.identifier3("Test"),
-        "b",
-        AstTestFactory.formalParameterList(),
-        initializers);
-    ClassDeclaration clazz = AstTestFactory.classDeclaration(
-        null, "Test", null, null, null, null,
-        members: [defaultConstructor, aConstructor, bConstructor]);
-    expect(clazz.getConstructor(null), same(defaultConstructor));
-    expect(clazz.getConstructor("a"), same(aConstructor));
-    expect(clazz.getConstructor("b"), same(bConstructor));
-    expect(clazz.getConstructor("noSuchConstructor"), isNull);
-  }
-
-  @Deprecated('Filter members instead')
-  void test_getField() {
-    VariableDeclaration aVar = AstTestFactory.variableDeclaration("a");
-    VariableDeclaration bVar = AstTestFactory.variableDeclaration("b");
-    VariableDeclaration cVar = AstTestFactory.variableDeclaration("c");
-    ClassDeclaration clazz = AstTestFactory.classDeclaration(
-        null, "Test", null, null, null, null,
-        members: [
-          AstTestFactory.fieldDeclaration2(false, null, [aVar]),
-          AstTestFactory.fieldDeclaration2(false, null, [bVar, cVar])
-        ]);
-    expect(clazz.getField("a"), same(aVar));
-    expect(clazz.getField("b"), same(bVar));
-    expect(clazz.getField("c"), same(cVar));
-    expect(clazz.getField("noSuchField"), isNull);
-  }
-
-  @Deprecated('Filter members instead')
-  void test_getMethod() {
-    MethodDeclaration aMethod = AstTestFactory.methodDeclaration(
-        null,
-        null,
-        null,
-        null,
-        AstTestFactory.identifier3("a"),
-        AstTestFactory.formalParameterList());
-    MethodDeclaration bMethod = AstTestFactory.methodDeclaration(
-        null,
-        null,
-        null,
-        null,
-        AstTestFactory.identifier3("b"),
-        AstTestFactory.formalParameterList());
-    ClassDeclaration clazz = AstTestFactory.classDeclaration(
-        null, "Test", null, null, null, null,
-        members: [aMethod, bMethod]);
-    expect(clazz.getMethod("a"), same(aMethod));
-    expect(clazz.getMethod("b"), same(bMethod));
-    expect(clazz.getMethod("noSuchMethod"), isNull);
-  }
-
-  @Deprecated('Use abstractKeyword instead')
-  void test_isAbstract() {
-    expect(
-        AstTestFactory.classDeclaration(null, "A", null, null, null, null)
-            .isAbstract,
-        isFalse);
-    expect(
-        AstTestFactory.classDeclaration(
-                Keyword.ABSTRACT, "B", null, null, null, null)
-            .isAbstract,
-        isTrue);
-  }
-}
-
-@reflectiveTest
-class ClassTypeAliasTest extends ParserTestCase {
-  @Deprecated('Use abstractKeyword instead')
-  void test_isAbstract() {
-    expect(
-        AstTestFactory.classTypeAlias(
-                "A",
-                null,
-                null,
-                AstTestFactory.namedType4('B'),
-                AstTestFactory.withClause([AstTestFactory.namedType4('M')]),
-                null)
-            .isAbstract,
-        isFalse);
-    expect(
-        AstTestFactory.classTypeAlias(
-                "B",
-                null,
-                Keyword.ABSTRACT,
-                AstTestFactory.namedType4('A'),
-                AstTestFactory.withClause([AstTestFactory.namedType4('M')]),
-                null)
-            .isAbstract,
-        isTrue);
-  }
-}
-
-@reflectiveTest
 class ConstructorDeclarationTest extends ParserDiagnosticsTest {
   void test_firstTokenAfterCommentAndMetadata_all_inverted() {
     final parseResult = parseStringWithErrors(r'''
@@ -650,6 +539,29 @@
 }
 
 @reflectiveTest
+class HideClauseImplTest extends ParserDiagnosticsTest {
+  void test_endToken_invalidClass() {
+    final parseResult = parseStringWithErrors('''
+import 'dart:core' hide int Function();
+''');
+    final node = parseResult.findNode.import('import');
+    expect(node.combinators[0].endToken, isNotNull);
+  }
+}
+
+@reflectiveTest
+class ImplementsClauseImplTest extends ParserDiagnosticsTest {
+  void test_endToken_invalidClass() {
+    final parseResult = parseStringWithErrors('''
+class A implements C Function() {}
+class C {}
+''');
+    final node = parseResult.findNode.classDeclaration('A');
+    expect(node.implementsClause!.endToken, isNotNull);
+  }
+}
+
+@reflectiveTest
 class IndexExpressionTest extends _AstTest {
   void test_inGetterContext_assignment_compound_left() {
     IndexExpression expression = AstTestFactory.indexExpression(
@@ -802,27 +714,22 @@
   }
 
   void test_isNullAware_false() {
-    final expression = AstTestFactory.indexExpression(
-      target: AstTestFactory.nullLiteral(),
-      index: AstTestFactory.nullLiteral(),
-    );
-    expect(expression.isNullAware, isFalse);
-  }
-
-  void test_isNullAware_regularIndex() {
-    final expression = AstTestFactory.indexExpression(
-      target: AstTestFactory.nullLiteral(),
-      index: AstTestFactory.nullLiteral(),
-    );
+    final findNode = _parseStringToFindNode('''
+void f() {
+  a[0];
+}
+''');
+    final expression = findNode.index('[0]');
     expect(expression.isNullAware, isFalse);
   }
 
   void test_isNullAware_true() {
-    final expression = AstTestFactory.indexExpression(
-      target: AstTestFactory.nullLiteral(),
-      hasQuestion: true,
-      index: AstTestFactory.nullLiteral(),
-    );
+    final findNode = _parseStringToFindNode('''
+void f() {
+  a?[0];
+}
+''');
+    final expression = findNode.index('[0]');
     expect(expression.isNullAware, isTrue);
   }
 }
@@ -1067,241 +974,109 @@
   }
 
   void test_isNullAware_regularInvocation() {
-    final invocation = AstTestFactory.methodInvocation3(
-        AstTestFactory.nullLiteral(), 'foo', null, [], TokenType.PERIOD);
+    final findNode = _parseStringToFindNode('''
+void f() {
+  a.foo();
+}
+''');
+    final invocation = findNode.methodInvocation('foo');
     expect(invocation.isNullAware, isFalse);
   }
 
   void test_isNullAware_true() {
-    final invocation = AstTestFactory.methodInvocation3(
-        AstTestFactory.nullLiteral(),
-        'foo',
-        null,
-        [],
-        TokenType.QUESTION_PERIOD);
+    final findNode = _parseStringToFindNode('''
+void f() {
+  a?.foo();
+}
+''');
+    final invocation = findNode.methodInvocation('foo');
     expect(invocation.isNullAware, isTrue);
   }
 }
 
 @reflectiveTest
-class NodeListTest {
-  void test_add() {
-    AstNode parent = AstTestFactory.argumentList();
-    AstNode firstNode = true_();
-    AstNode secondNode = false_();
-    NodeList<AstNode> list = astFactory.nodeList<AstNode>(parent);
-    list.insert(0, secondNode);
-    list.insert(0, firstNode);
-    expect(list, hasLength(2));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(secondNode));
-    expect(firstNode.parent, same(parent));
-    expect(secondNode.parent, same(parent));
-    AstNode thirdNode = false_();
-    list.insert(1, thirdNode);
-    expect(list, hasLength(3));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(thirdNode));
-    expect(list[2], same(secondNode));
-    expect(firstNode.parent, same(parent));
-    expect(secondNode.parent, same(parent));
-    expect(thirdNode.parent, same(parent));
-  }
-
-  void test_add_negative() {
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    try {
-      list.insert(-1, true_());
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
-  void test_add_tooBig() {
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    try {
-      list.insert(1, true_());
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
-  void test_addAll() {
-    AstNode parent = AstTestFactory.argumentList();
-    List<AstNode> firstNodes = <AstNode>[];
-    AstNode firstNode = true_();
-    AstNode secondNode = false_();
-    firstNodes.add(firstNode);
-    firstNodes.add(secondNode);
-    NodeList<AstNode> list = astFactory.nodeList<AstNode>(parent);
-    list.addAll(firstNodes);
-    expect(list, hasLength(2));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(secondNode));
-    expect(firstNode.parent, same(parent));
-    expect(secondNode.parent, same(parent));
-    List<AstNode> secondNodes = <AstNode>[];
-    AstNode thirdNode = true_();
-    AstNode fourthNode = false_();
-    secondNodes.add(thirdNode);
-    secondNodes.add(fourthNode);
-    list.addAll(secondNodes);
-    expect(list, hasLength(4));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(secondNode));
-    expect(list[2], same(thirdNode));
-    expect(list[3], same(fourthNode));
-    expect(firstNode.parent, same(parent));
-    expect(secondNode.parent, same(parent));
-    expect(thirdNode.parent, same(parent));
-    expect(fourthNode.parent, same(parent));
-  }
-
-  void test_creation() {
-    AstNode owner = AstTestFactory.argumentList();
-    NodeList<AstNode> list = astFactory.nodeList<AstNode>(owner);
-    expect(list, isNotNull);
-    expect(list, hasLength(0));
-    expect(list.owner, same(owner));
-  }
-
-  void test_get_negative() {
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    try {
-      list[-1];
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
-  void test_get_tooBig() {
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    try {
-      list[1];
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
+class NodeListTest extends ParserDiagnosticsTest {
   void test_getBeginToken_empty() {
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    expect(list.beginToken, isNull);
+    final parseResult = parseStringWithErrors(r'''
+final x = f();
+''');
+    parseResult.assertNoErrors();
+
+    final argumentList = parseResult.findNode.argumentList('()');
+    final nodeList = argumentList.arguments;
+    expect(nodeList.beginToken, isNull);
   }
 
   void test_getBeginToken_nonEmpty() {
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    AstNode node = AstTestFactory.parenthesizedExpression(true_());
-    list.add(node);
-    expect(list.beginToken, same(node.beginToken));
+    final parseResult = parseStringWithErrors(r'''
+final x = f(0, 1);
+''');
+    parseResult.assertNoErrors();
+
+    final argumentList = parseResult.findNode.argumentList('(0');
+    final nodeList = argumentList.arguments;
+    final first = nodeList[0];
+    expect(nodeList.beginToken, same(first.beginToken));
   }
 
   void test_getEndToken_empty() {
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    expect(list.endToken, isNull);
+    final parseResult = parseStringWithErrors(r'''
+final x = f();
+''');
+    parseResult.assertNoErrors();
+
+    final argumentList = parseResult.findNode.argumentList('()');
+    final nodeList = argumentList.arguments;
+    expect(nodeList.endToken, isNull);
   }
 
   void test_getEndToken_nonEmpty() {
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    AstNode node = AstTestFactory.parenthesizedExpression(true_());
-    list.add(node);
-    expect(list.endToken, same(node.endToken));
+    final parseResult = parseStringWithErrors(r'''
+final x = f(0, 1);
+''');
+    parseResult.assertNoErrors();
+
+    final argumentList = parseResult.findNode.argumentList('(0');
+    final nodeList = argumentList.arguments;
+    final last = nodeList[nodeList.length - 1];
+    expect(nodeList.endToken, same(last.endToken));
   }
 
   void test_indexOf() {
-    List<AstNode> nodes = <AstNode>[];
-    AstNode firstNode = true_();
-    AstNode secondNode = false_();
-    AstNode thirdNode = true_();
-    AstNode fourthNode = false_();
-    nodes.add(firstNode);
-    nodes.add(secondNode);
-    nodes.add(thirdNode);
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    list.addAll(nodes);
-    expect(list, hasLength(3));
-    expect(list.indexOf(firstNode), 0);
-    expect(list.indexOf(secondNode), 1);
-    expect(list.indexOf(thirdNode), 2);
-    expect(list.indexOf(fourthNode), -1);
-  }
+    final parseResult = parseStringWithErrors(r'''
+final x = f(0, 1, 2);
+final y = 42;
+''');
+    parseResult.assertNoErrors();
 
-  void test_remove() {
-    List<AstNode> nodes = <AstNode>[];
-    AstNode firstNode = true_();
-    AstNode secondNode = false_();
-    AstNode thirdNode = true_();
-    nodes.add(firstNode);
-    nodes.add(secondNode);
-    nodes.add(thirdNode);
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    list.addAll(nodes);
-    expect(list, hasLength(3));
-    expect(list.removeAt(1), same(secondNode));
-    expect(list, hasLength(2));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(thirdNode));
-  }
+    final argumentList = parseResult.findNode.argumentList('(0');
+    final nodeList = argumentList.arguments;
 
-  void test_remove_negative() {
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    try {
-      list.removeAt(-1);
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
+    final first = nodeList[0];
+    final second = nodeList[1];
+    final third = nodeList[2];
 
-  void test_remove_tooBig() {
-    NodeList<AstNode> list =
-        astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    try {
-      list.removeAt(1);
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
+    expect(nodeList, hasLength(3));
+    expect(nodeList.indexOf(first), 0);
+    expect(nodeList.indexOf(second), 1);
+    expect(nodeList.indexOf(third), 2);
 
-  void test_set() {
-    List<AstNode> nodes = <AstNode>[];
-    AstNode firstNode = true_();
-    AstNode secondNode = false_();
-    AstNode thirdNode = true_();
-    nodes.add(firstNode);
-    nodes.add(secondNode);
-    nodes.add(thirdNode);
-    var list = astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
-    list.addAll(nodes);
-    expect(list, hasLength(3));
-    AstNode fourthNode = AstTestFactory.integer(0);
-    list[1] = fourthNode;
-    expect(list, hasLength(3));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(fourthNode));
-    expect(list[2], same(thirdNode));
+    final notInList = parseResult.findNode.integerLiteral('42');
+    expect(nodeList.indexOf(notInList), -1);
   }
 
   void test_set_negative() {
-    AstNode node = true_();
-    var list = astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
+    final parseResult = parseStringWithErrors(r'''
+final x = f(0);
+final y = 42;
+''');
+    parseResult.assertNoErrors();
+
+    final argumentList = parseResult.findNode.argumentList('(0');
+    final nodeList = argumentList.arguments;
+
     try {
-      list[-1] = node;
+      nodeList[-1] = nodeList.first;
       fail("Expected IndexOutOfBoundsException");
     } on RangeError {
       // Expected
@@ -1309,29 +1084,21 @@
   }
 
   void test_set_tooBig() {
-    AstNode node = true_();
-    var list = astFactory.nodeList<AstNode>(AstTestFactory.argumentList());
+    final parseResult = parseStringWithErrors(r'''
+final x = f(0);
+final y = 42;
+''');
+    parseResult.assertNoErrors();
+
+    final argumentList = parseResult.findNode.argumentList('(0');
+    final nodeList = argumentList.arguments;
     try {
-      list[1] = node;
+      nodeList[1] = nodeList.first;
       fail("Expected IndexOutOfBoundsException");
     } on RangeError {
       // Expected
     }
   }
-
-  static BooleanLiteralImpl false_() {
-    return BooleanLiteralImpl(
-      literal: Tokens.true_(),
-      value: true,
-    );
-  }
-
-  static BooleanLiteralImpl true_() {
-    return BooleanLiteralImpl(
-      literal: Tokens.true_(),
-      value: true,
-    );
-  }
 }
 
 @reflectiveTest
@@ -1348,6 +1115,18 @@
 }
 
 @reflectiveTest
+class OnClauseImplTest extends ParserDiagnosticsTest {
+  void test_endToken_invalidClass() {
+    final parseResult = parseStringWithErrors('''
+mixin M on C Function() {}
+class C {}
+''');
+    final node = parseResult.findNode.mixinDeclaration('M');
+    expect(node.onClause!.endToken, isNotNull);
+  }
+}
+
+@reflectiveTest
 class PreviousTokenTest {
   static final String contents = '''
 class A {
@@ -1458,19 +1237,38 @@
   }
 
   void test_isNullAware_regularPropertyAccess() {
-    final invocation = AstTestFactory.propertyAccess2(
-        AstTestFactory.nullLiteral(), 'foo', TokenType.PERIOD);
+    final findNode = _parseStringToFindNode('''
+void f() {
+  (a).foo;
+}
+''');
+    final invocation = findNode.propertyAccess('foo');
     expect(invocation.isNullAware, isFalse);
   }
 
   void test_isNullAware_true() {
-    final invocation = AstTestFactory.propertyAccess2(
-        AstTestFactory.nullLiteral(), 'foo', TokenType.QUESTION_PERIOD);
+    final findNode = _parseStringToFindNode('''
+void f() {
+  a?.foo;
+}
+''');
+    final invocation = findNode.propertyAccess('foo');
     expect(invocation.isNullAware, isTrue);
   }
 }
 
 @reflectiveTest
+class ShowClauseImplTest extends ParserDiagnosticsTest {
+  void test_endToken_invalidClass() {
+    final parseResult = parseStringWithErrors('''
+import 'dart:core' show int Function();
+''');
+    final node = parseResult.findNode.import('import');
+    expect(node.combinators[0].endToken, isNotNull);
+  }
+}
+
+@reflectiveTest
 class SimpleIdentifierTest extends _AstTest {
   void test_inGetterContext() {
     for (_WrapperKind wrapper in _WrapperKind.values) {
@@ -1501,31 +1299,25 @@
     expect(identifier.inGetterContext(), isFalse);
   }
 
-  @deprecated
-  void test_inGetterContext_fieldFormalParameter() {
-    FieldFormalParameter parameter =
-        AstTestFactory.fieldFormalParameter2('test');
-    SimpleIdentifier identifier = parameter.identifier;
-    expect(identifier.inGetterContext(), isFalse);
-  }
-
   void test_inGetterContext_forEachLoop() {
-    SimpleIdentifier identifier = AstTestFactory.identifier3("a");
-    Expression iterator = AstTestFactory.listLiteral();
-    Statement body = BlockImpl(
-      leftBracket: Tokens.openCurlyBracket(),
-      statements: [],
-      rightBracket: Tokens.closeCurlyBracket(),
-    );
-    AstTestFactory.forStatement(
-        AstTestFactory.forEachPartsWithIdentifier(identifier, iterator), body);
+    final parseResult = parseStringWithErrors('''
+void f() {
+  for (v in [0]) {}
+}
+''');
+    final identifier = parseResult.findNode.simple('v in');
     expect(identifier.inGetterContext(), isFalse);
   }
 
   void test_inReferenceContext() {
-    SimpleIdentifier identifier = AstTestFactory.identifier3("id");
-    AstTestFactory.namedExpression(
-        AstTestFactory.label(identifier), AstTestFactory.identifier3("_"));
+    final parseResult = parseStringWithErrors('''
+void f() {
+  foo(id: 0);
+}
+final v = f(0, 1, 2);
+class C {}
+''');
+    final identifier = parseResult.findNode.simple('id:');
     expect(identifier.inGetterContext(), isFalse);
     expect(identifier.inSetterContext(), isFalse);
   }
@@ -1554,15 +1346,12 @@
   }
 
   void test_inSetterContext_forEachLoop() {
-    SimpleIdentifier identifier = AstTestFactory.identifier3("a");
-    Expression iterator = AstTestFactory.listLiteral();
-    Statement body = BlockImpl(
-      leftBracket: Tokens.openCurlyBracket(),
-      statements: [],
-      rightBracket: Tokens.closeCurlyBracket(),
-    );
-    AstTestFactory.forStatement(
-        AstTestFactory.forEachPartsWithIdentifier(identifier, iterator), body);
+    final parseResult = parseStringWithErrors('''
+void f() {
+  for (v in [0]) {}
+}
+''');
+    final identifier = parseResult.findNode.simple('v in');
     expect(identifier.inSetterContext(), isTrue);
   }
 
@@ -1575,18 +1364,24 @@
   }
 
   void test_isQualified_inMethodInvocation_noTarget() {
-    MethodInvocation invocation = AstTestFactory.methodInvocation2(
-        "test", [AstTestFactory.identifier3("arg0")]);
-    SimpleIdentifier identifier = invocation.methodName;
+    final findNode = _parseStringToFindNode('''
+void f() {
+  foo(0);
+}
+''');
+    final invocation = findNode.methodInvocation('foo');
+    final identifier = invocation.methodName;
     expect(identifier.isQualified, isFalse);
   }
 
   void test_isQualified_inMethodInvocation_withTarget() {
-    MethodInvocation invocation = AstTestFactory.methodInvocation(
-        AstTestFactory.identifier3("target"),
-        "test",
-        [AstTestFactory.identifier3("arg0")]);
-    SimpleIdentifier identifier = invocation.methodName;
+    final findNode = _parseStringToFindNode('''
+void f() {
+  a.foo();
+}
+''');
+    final invocation = findNode.methodInvocation('foo');
+    final identifier = invocation.methodName;
     expect(identifier.isQualified, isTrue);
   }
 
@@ -1970,154 +1765,177 @@
 }
 
 @reflectiveTest
-class SpreadElementTest extends ParserTestCase {
+class SpreadElementTest extends _AstTest {
   void test_notNullAwareSpread() {
-    final spread = AstTestFactory.spreadElement(
-        TokenType.PERIOD_PERIOD_PERIOD, AstTestFactory.nullLiteral());
+    final findNode = _parseStringToFindNode('''
+final x = [...foo];
+''');
+    final spread = findNode.spreadElement('...foo');
     expect(spread.isNullAware, isFalse);
   }
 
   void test_nullAwareSpread() {
-    final spread = AstTestFactory.spreadElement(
-        TokenType.PERIOD_PERIOD_PERIOD_QUESTION, AstTestFactory.nullLiteral());
+    final findNode = _parseStringToFindNode('''
+final x = [...?foo];
+''');
+    final spread = findNode.spreadElement('...?foo');
     expect(spread.isNullAware, isTrue);
   }
 }
 
 @reflectiveTest
-class StringInterpolationTest extends ParserTestCase {
+class StringInterpolationTest extends ParserDiagnosticsTest {
   void test_contentsOffsetEnd() {
-    var bb = AstTestFactory.interpolationExpression(
-        AstTestFactory.identifier3('bb'));
-    // 'a${bb}ccc'
     {
-      var ae = AstTestFactory.interpolationString("'a", "a");
-      var cToken = StringToken(TokenType.STRING, "ccc'", 10);
-      var cElement = astFactory.interpolationString(cToken, 'ccc');
-      StringInterpolation node = AstTestFactory.string([ae, bb, cElement]);
-      expect(node.contentsOffset, 1);
-      expect(node.contentsEnd, 10 + 4 - 1);
+      final parseResult = parseStringWithErrors(r'''
+final v = 'a${bb}ccc';
+''');
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
+      expect(node.contentsOffset, 11);
+      expect(node.contentsEnd, 20);
     }
-    // '''a${bb}ccc'''
+
     {
-      var ae = AstTestFactory.interpolationString("'''a", "a");
-      var cToken = StringToken(TokenType.STRING, "ccc'''", 10);
-      var cElement = astFactory.interpolationString(cToken, 'ccc');
-      StringInterpolation node = AstTestFactory.string([ae, bb, cElement]);
-      expect(node.contentsOffset, 3);
-      expect(node.contentsEnd, 10 + 4 - 1);
+      final parseResult = parseStringWithErrors(r"""
+final v = '''a${bb}ccc''';
+""");
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
+      expect(node.contentsOffset, 13);
+      expect(node.contentsEnd, 22);
     }
-    // """a${bb}ccc"""
+
     {
-      var ae = AstTestFactory.interpolationString('"""a', "a");
-      var cToken = StringToken(TokenType.STRING, 'ccc"""', 10);
-      var cElement = astFactory.interpolationString(cToken, 'ccc');
-      StringInterpolation node = AstTestFactory.string([ae, bb, cElement]);
-      expect(node.contentsOffset, 3);
-      expect(node.contentsEnd, 10 + 4 - 1);
+      final parseResult = parseStringWithErrors(r'''
+final v = """a${bb}ccc""";
+''');
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
+      expect(node.contentsOffset, 13);
+      expect(node.contentsEnd, 22);
     }
-    // r'a${bb}ccc'
+
     {
-      var ae = AstTestFactory.interpolationString("r'a", "a");
-      var cToken = StringToken(TokenType.STRING, "ccc'", 10);
-      var cElement = astFactory.interpolationString(cToken, 'ccc');
-      StringInterpolation node = AstTestFactory.string([ae, bb, cElement]);
-      expect(node.contentsOffset, 2);
-      expect(node.contentsEnd, 10 + 4 - 1);
+      final parseResult = parseStringWithErrors(r'''
+final v = r'a${bb}ccc';
+''');
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.simpleStringLiteral('ccc');
+      expect(node.contentsOffset, 12);
+      expect(node.contentsEnd, 21);
     }
-    // r'''a${bb}ccc'''
+
     {
-      var ae = AstTestFactory.interpolationString("r'''a", "a");
-      var cToken = StringToken(TokenType.STRING, "ccc'''", 10);
-      var cElement = astFactory.interpolationString(cToken, 'ccc');
-      StringInterpolation node = AstTestFactory.string([ae, bb, cElement]);
-      expect(node.contentsOffset, 4);
-      expect(node.contentsEnd, 10 + 4 - 1);
+      final parseResult = parseStringWithErrors(r"""
+final v = r'''a${bb}ccc''';
+""");
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.simpleStringLiteral('ccc');
+      expect(node.contentsOffset, 14);
+      expect(node.contentsEnd, 23);
     }
-    // r"""a${bb}ccc"""
+
     {
-      var ae = AstTestFactory.interpolationString('r"""a', "a");
-      var cToken = StringToken(TokenType.STRING, 'ccc"""', 10);
-      var cElement = astFactory.interpolationString(cToken, 'ccc');
-      StringInterpolation node = AstTestFactory.string([ae, bb, cElement]);
-      expect(node.contentsOffset, 4);
-      expect(node.contentsEnd, 10 + 4 - 1);
+      final parseResult = parseStringWithErrors(r'''
+final v = r"""a${bb}ccc""";
+''');
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.simpleStringLiteral('ccc');
+      expect(node.contentsOffset, 14);
+      expect(node.contentsEnd, 23);
     }
   }
 
   void test_isMultiline() {
-    var b = AstTestFactory.interpolationExpression(
-        AstTestFactory.identifier3('bb'));
-    // '
     {
-      var a = AstTestFactory.interpolationString("'a", "a");
-      var c = AstTestFactory.interpolationString("ccc'", "ccc");
-      StringInterpolation node = AstTestFactory.string([a, b, c]);
+      final parseResult = parseStringWithErrors(r'''
+final v = 'a${bb}ccc';
+''');
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
       expect(node.isMultiline, isFalse);
     }
-    // '''
+
     {
-      var a = AstTestFactory.interpolationString("'''a", "a");
-      var c = AstTestFactory.interpolationString("ccc'''", "ccc");
-      StringInterpolation node = AstTestFactory.string([a, b, c]);
+      final parseResult = parseStringWithErrors(r'''
+final v = "a${bb}ccc";
+''');
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
+      expect(node.isMultiline, isFalse);
+    }
+
+    {
+      final parseResult = parseStringWithErrors(r"""
+final v = '''a${bb}ccc''';
+""");
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
       expect(node.isMultiline, isTrue);
     }
-    // "
+
     {
-      var a = AstTestFactory.interpolationString('"a', "a");
-      var c = AstTestFactory.interpolationString('ccc"', "ccc");
-      StringInterpolation node = AstTestFactory.string([a, b, c]);
-      expect(node.isMultiline, isFalse);
-    }
-    // """
-    {
-      var a = AstTestFactory.interpolationString('"""a', "a");
-      var c = AstTestFactory.interpolationString('ccc"""', "ccc");
-      StringInterpolation node = AstTestFactory.string([a, b, c]);
+      final parseResult = parseStringWithErrors(r'''
+final v = """a${bb}ccc""";
+''');
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
       expect(node.isMultiline, isTrue);
     }
   }
 
   void test_isRaw() {
-    var node = parseStringLiteral('"first \$x last"') as StringInterpolation;
+    final parseResult = parseStringWithErrors(r'''
+final v = 'a${bb}ccc';
+''');
+    parseResult.assertNoErrors();
+    final node = parseResult.findNode.stringInterpolation('ccc');
     expect(node.isRaw, isFalse);
   }
 
   void test_isSingleQuoted() {
-    var b = AstTestFactory.interpolationExpression(
-        AstTestFactory.identifier3('bb'));
-    // "
     {
-      var a = AstTestFactory.interpolationString('"a', "a");
-      var c = AstTestFactory.interpolationString('ccc"', "ccc");
-      StringInterpolation node = AstTestFactory.string([a, b, c]);
-      expect(node.isSingleQuoted, isFalse);
-    }
-    // """
-    {
-      var a = AstTestFactory.interpolationString('"""a', "a");
-      var c = AstTestFactory.interpolationString('ccc"""', "ccc");
-      StringInterpolation node = AstTestFactory.string([a, b, c]);
-      expect(node.isSingleQuoted, isFalse);
-    }
-    // '
-    {
-      var a = AstTestFactory.interpolationString("'a", "a");
-      var c = AstTestFactory.interpolationString("ccc'", "ccc");
-      StringInterpolation node = AstTestFactory.string([a, b, c]);
+      final parseResult = parseStringWithErrors(r'''
+final v = 'a${bb}ccc';
+''');
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
       expect(node.isSingleQuoted, isTrue);
     }
-    // '''
+
     {
-      var a = AstTestFactory.interpolationString("'''a", "a");
-      var c = AstTestFactory.interpolationString("ccc'''", "ccc");
-      StringInterpolation node = AstTestFactory.string([a, b, c]);
+      final parseResult = parseStringWithErrors(r"""
+final v = '''a${bb}ccc''';
+""");
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
       expect(node.isSingleQuoted, isTrue);
     }
+
+    {
+      final parseResult = parseStringWithErrors(r'''
+final v = "a${bb}ccc";
+''');
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
+      expect(node.isSingleQuoted, isFalse);
+    }
+
+    {
+      final parseResult = parseStringWithErrors(r'''
+final v = """a${bb}ccc""";
+''');
+      parseResult.assertNoErrors();
+      final node = parseResult.findNode.stringInterpolation('ccc');
+      expect(node.isSingleQuoted, isFalse);
+    }
   }
 }
 
 @reflectiveTest
+// TODO(srawlins): Re-enable?
+// ignore: unreachable_from_main
 class SuperFormalParameterTest {
   void test_endToken_noParameters() {
     SuperFormalParameter parameter =
@@ -2162,6 +1980,18 @@
   }
 }
 
+@reflectiveTest
+class WithClauseImplTest extends ParserDiagnosticsTest {
+  void test_endToken_invalidClass() {
+    final parseResult = parseStringWithErrors('''
+class A with C Function() {}
+class C {}
+''');
+    final node = parseResult.findNode.classDeclaration('A');
+    expect(node.withClause!.endToken, isNotNull);
+  }
+}
+
 class _AssignmentKind {
   static const _AssignmentKind BINARY = _AssignmentKind('BINARY', 0);
 
diff --git a/pkg/analyzer/test/dart/ast/visitor_test.dart b/pkg/analyzer/test/dart/ast/visitor_test.dart
index 3499a33..4521e4b 100644
--- a/pkg/analyzer/test/dart/ast/visitor_test.dart
+++ b/pkg/analyzer/test/dart/ast/visitor_test.dart
@@ -43,12 +43,12 @@
     _BreadthFirstVisitorTestHelper visitor =
         _BreadthFirstVisitorTestHelper(nodes);
     visitor.visitAllNodes(unit);
-    expect(nodes, hasLength(59));
+    expect(nodes, hasLength(52));
     expect(nodes[0], isCompilationUnit);
     expect(nodes[2], isClassDeclaration);
     expect(nodes[3], isFunctionDeclaration);
-    expect(nodes[27], isFunctionDeclarationStatement);
-    expect(nodes[58], isIntegerLiteral); // 3
+    expect(nodes[22], isFunctionDeclarationStatement);
+    expect(nodes[51], isIntegerLiteral); // 3
   }
 }
 
diff --git a/pkg/analyzer/test/error/error_test.dart b/pkg/analyzer/test/error/error_test.dart
index d766e0e..854990c 100644
--- a/pkg/analyzer/test/error/error_test.dart
+++ b/pkg/analyzer/test/error/error_test.dart
@@ -38,13 +38,13 @@
         var extendsClause = declaration.extendsClause;
         if (extendsClause != null &&
             extendsClause.superclass.name.name == 'ErrorCode') {
-          String className = declaration.name2.lexeme;
+          String className = declaration.name.lexeme;
           for (ClassMember member in declaration.members) {
             if (member is FieldDeclaration && member.isStatic) {
               var fields = member.fields;
               if ((fields.type == null ? bad() : true) &&
                   fields.type!.toSource() == className) {
-                String fieldName = fields.variables[0].name2.lexeme;
+                String fieldName = fields.variables[0].name.lexeme;
                 declaredCodes.add('$className.$fieldName');
               }
             }
@@ -61,7 +61,7 @@
     TopLevelVariableDeclaration declaration = listingUnit.declarations
         .whereType<TopLevelVariableDeclaration>()
         .firstWhere((member) =>
-            member.variables.variables[0].name2.lexeme == 'errorCodeValues');
+            member.variables.variables[0].name.lexeme == 'errorCodeValues');
     var listLiteral =
         declaration.variables.variables[0].initializer as ListLiteral;
     for (var element in listLiteral.elements.cast<PrefixedIdentifier>()) {
diff --git a/pkg/analyzer/test/generated/class_member_parser_test.dart b/pkg/analyzer/test/generated/class_member_parser_test.dart
index 7d55bed..64cf9e8 100644
--- a/pkg/analyzer/test/generated/class_member_parser_test.dart
+++ b/pkg/analyzer/test/generated/class_member_parser_test.dart
@@ -39,7 +39,7 @@
     expect(constructor.externalKeyword, isNull);
     expect(constructor.constKeyword, isNull);
     expect(constructor.factoryKeyword, isNull);
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.period, isNull);
     expect(constructor.returnType, isNotNull);
@@ -96,7 +96,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2.lexeme, 'late');
+    expect(method.name.lexeme, 'late');
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -295,7 +295,7 @@
     expect(constructor.externalKeyword, isNull);
     expect(constructor.constKeyword, isNull);
     expect(constructor.factoryKeyword, isNull);
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.period, isNull);
     expect(constructor.returnType, isNotNull);
@@ -389,7 +389,7 @@
     expect(constructor.externalKeyword, isNull);
     expect(constructor.constKeyword, isNull);
     expect(constructor.factoryKeyword, isNull);
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.period, isNull);
     expect(constructor.returnType, isNotNull);
@@ -417,7 +417,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseClassMember_field_generic() {
@@ -452,7 +452,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseClassMember_field_gftType_gftReturnType() {
@@ -499,7 +499,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseClassMember_field_namedGet() {
@@ -524,7 +524,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseClassMember_field_namedOperator() {
@@ -549,7 +549,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseClassMember_field_namedOperator_withAssignment() {
@@ -574,7 +574,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
     expect(variable.initializer, isNotNull);
   }
 
@@ -600,7 +600,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseClassMember_field_nameKeyword() {
@@ -650,7 +650,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseClassMember_finalAndCovariantLateWithInitializer() {
@@ -676,7 +676,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNotNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.body, isNotNull);
     expect(method.parameters, isNull);
@@ -694,7 +694,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNotNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.body, isNotNull);
     expect(method.parameters, isNull);
@@ -710,7 +710,7 @@
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNotNull);
     expect(method.modifierKeyword, isNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -734,7 +734,7 @@
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNotNull);
     expect(method.modifierKeyword, isNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -754,7 +754,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNotNull);
     expect(method.parameters, isNotNull);
@@ -773,7 +773,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNotNull);
 
@@ -799,7 +799,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNotNull);
     expect(method.parameters, isNotNull);
@@ -818,11 +818,11 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect((method.returnType as NamedType).name.name, 'T');
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNotNull);
     TypeParameter tp = method.typeParameters!.typeParameters[0];
-    expect(tp.name2.lexeme, 'T');
+    expect(tp.name.lexeme, 'T');
     expect(tp.extendsKeyword, isNotNull);
     expect((tp.bound as NamedType).name.name, 'num');
     expect(method.parameters, isNotNull);
@@ -852,7 +852,7 @@
       expect((typeArguments[1] as NamedType).name.name, 'T');
     }
 
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNotNull);
     expect(method.parameters, isNotNull);
@@ -872,7 +872,7 @@
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
     expect((method.returnType as NamedType).name.name, 'T');
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNotNull);
     expect(method.parameters, isNotNull);
@@ -891,7 +891,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNotNull);
     expect(method.parameters, isNotNull);
@@ -910,7 +910,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -931,7 +931,7 @@
     expect(method.modifierKeyword, isNotNull);
     expect(method.propertyKeyword, isNotNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNull);
@@ -950,7 +950,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -969,7 +969,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1062,7 +1062,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1081,7 +1081,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1100,7 +1100,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1119,8 +1119,8 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
-    expect(method.name2.lexeme, 'm');
+    expect(method.name, isNotNull);
+    expect(method.name.lexeme, 'm');
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1139,7 +1139,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1158,7 +1158,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1179,7 +1179,7 @@
     expect(method.modifierKeyword, isNotNull);
     expect(method.propertyKeyword, isNotNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1198,7 +1198,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1217,7 +1217,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1234,7 +1234,7 @@
     expect(method.modifierKeyword, isNotNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1250,7 +1250,7 @@
     expect(method.modifierKeyword, isNotNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1269,7 +1269,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1288,7 +1288,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isGenericFunctionType);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNotNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1311,7 +1311,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2.lexeme, '>>>');
+    expect(method.name.lexeme, '>>>');
     expect(method.operatorKeyword, isNotNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1348,7 +1348,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNotNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1367,7 +1367,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNotNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1386,7 +1386,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2.lexeme, '<');
+    expect(method.name.lexeme, '<');
     expect(method.operatorKeyword, isNotNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -1403,7 +1403,7 @@
     expect(constructor.factoryKeyword!.keyword, Keyword.FACTORY);
     expect(constructor.returnType.name, 'C');
     expect(constructor.period, isNull);
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, isEmpty);
     expect(constructor.separator!.type, TokenType.EQ);
@@ -1425,7 +1425,7 @@
     expect(constructor.factoryKeyword!.keyword, Keyword.FACTORY);
     expect(constructor.returnType.name, 'C');
     expect(constructor.period, isNull);
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, isEmpty);
     expect(constructor.separator, isNull);
@@ -1452,7 +1452,7 @@
     expect(constructor.factoryKeyword!.keyword, Keyword.FACTORY);
     expect(constructor.returnType.name, 'C');
     expect(constructor.period, isNull);
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, isEmpty);
     expect(constructor.separator!.type, TokenType.EQ);
@@ -1500,7 +1500,7 @@
     expect(constructor.factoryKeyword, isNotNull);
     expect(constructor.returnType.name, 'C');
     expect(constructor.period!.type, TokenType.PERIOD);
-    expect(constructor.name2!.lexeme, 'foo');
+    expect(constructor.name!.lexeme, 'foo');
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, isEmpty);
     expect(constructor.separator, isNull);
@@ -1554,7 +1554,7 @@
     expect(constructor.factoryKeyword, isNull);
     expect(constructor.returnType.name, 'C');
     expect(constructor.period!.type, TokenType.PERIOD);
-    expect(constructor.name2!.lexeme, 'foo');
+    expect(constructor.name!.lexeme, 'foo');
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, isEmpty);
     expect(constructor.separator, isNull);
@@ -1605,7 +1605,7 @@
     expect(constructor.constKeyword, isNull);
     expect(constructor.factoryKeyword, isNull);
     expect(constructor.returnType.name, 'C');
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, isEmpty);
     expect(constructor.separator!.lexeme, ':');
@@ -1628,7 +1628,7 @@
     expect(constructor.constKeyword, isNull);
     expect(constructor.factoryKeyword, isNull);
     expect(constructor.returnType.name, 'C');
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, isEmpty);
     expect(constructor.separator!.lexeme, ':');
@@ -1650,7 +1650,7 @@
     expect(constructor.factoryKeyword, isNull);
     expect(constructor.returnType.name, 'C');
     expect(constructor.period, isNull);
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, isEmpty);
     expect(constructor.separator, isNull);
@@ -1783,7 +1783,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseField_external() {
@@ -1866,7 +1866,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseField_late() {
@@ -1890,7 +1890,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseField_late_const() {
@@ -1916,7 +1916,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseField_late_final() {
@@ -1940,7 +1940,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseField_late_var() {
@@ -1963,7 +1963,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseField_non_abstract() {
@@ -2009,7 +2009,7 @@
     NodeList<VariableDeclaration> variables = list.variables;
     expect(variables, hasLength(1));
     VariableDeclaration variable = variables[0];
-    expect(variable.name2, isNotNull);
+    expect(variable.name, isNotNull);
   }
 
   void test_parseGetter_identifier_colon_issue_36961() {
@@ -2026,7 +2026,7 @@
     expect(constructor.body, isNotNull);
     expect(constructor.documentationComment, isNull);
     expect(constructor.externalKeyword, isNull);
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.returnType, isNotNull);
   }
@@ -2040,7 +2040,7 @@
     expectCommentText(method.documentationComment, '/// Doc');
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.parameters, isNull);
     expect(method.propertyKeyword, isNotNull);
@@ -2056,7 +2056,7 @@
     expectCommentText(method.documentationComment, '/// Doc');
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword!.lexeme, 'static');
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNull);
@@ -2103,7 +2103,7 @@
     expectCommentText(method.documentationComment, '/// Doc');
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNotNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -2120,7 +2120,7 @@
     expectCommentText(method.documentationComment, '/// Doc');
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
@@ -2137,7 +2137,7 @@
     expectCommentText(method.documentationComment, '/// Doc');
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword!.lexeme, 'static');
-    expect(method.name2, isNotNull);
+    expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
     expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
diff --git a/pkg/analyzer/test/generated/collection_literal_parser_test.dart b/pkg/analyzer/test/generated/collection_literal_parser_test.dart
index 3c171bb..2a65303 100644
--- a/pkg/analyzer/test/generated/collection_literal_parser_test.dart
+++ b/pkg/analyzer/test/generated/collection_literal_parser_test.dart
@@ -97,7 +97,7 @@
     expect(second.rightParenthesis.lexeme, ')');
     var forLoopParts = second.forLoopParts as ForPartsWithDeclarations;
     VariableDeclaration forLoopVar = forLoopParts.variables.variables[0];
-    expect(forLoopVar.name2.lexeme, 'x');
+    expect(forLoopVar.name.lexeme, 'x');
     var condition = forLoopParts.condition as BinaryExpression;
     var rightOperand = condition.rightOperand as IntegerLiteral;
     expect(rightOperand.value, 10);
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index 40c90d5..f60dcdc 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -53,6 +53,18 @@
     await _assertValueInt(74 ^ 42, "74 ^ 42");
   }
 
+  /// See https://github.com/dart-lang/sdk/issues/50045
+  test_bool_fromEnvironment_dartLibraryJsUtil() async {
+    await resolveTestCode('''
+const x = bool.fromEnvironment('dart.library.js_util');
+''');
+
+    _assertTopVarConstValue('x', r'''
+bool <unknown>
+  variable: self::@variable::x
+''');
+  }
+
   test_conditionalExpression_unknownCondition_dynamic() async {
     await assertErrorsInCode('''
 const bool kIsWeb = identical(0, 0.0);
@@ -600,6 +612,54 @@
     expect(value, null);
   }
 
+  test_record_mixed() async {
+    await assertNoErrorsInCode(r'''
+const x = (0, f1: 10, f2: 2.3);
+''');
+
+    final value = _topVarConstValue('x');
+    assertDartObjectText(value, r'''
+Record
+  positionalFields
+    $0: int 0
+  namedFields
+    f1: int 10
+    f2: double 2.3
+  variable: self::@variable::x
+''');
+  }
+
+  test_record_named() async {
+    await assertNoErrorsInCode(r'''
+const x = (f1: 10, f2: -3);
+''');
+
+    final value = _topVarConstValue('x');
+    assertDartObjectText(value, r'''
+Record
+  namedFields
+    f1: int 10
+    f2: int -3
+  variable: self::@variable::x
+''');
+  }
+
+  test_record_positional() async {
+    await assertNoErrorsInCode(r'''
+const x = (20, 0, 7);
+''');
+
+    final value = _topVarConstValue('x');
+    assertDartObjectText(value, r'''
+Record
+  positionalFields
+    $0: int 20
+    $1: int 0
+    $2: int 7
+  variable: self::@variable::x
+''');
+  }
+
   @failingTest
   test_simpleIdentifier_invalid() async {
     var result = await _getExpressionValue("?");
@@ -981,6 +1041,10 @@
     var element = findElement.topVar(name) as ConstTopLevelVariableElementImpl;
     return element.evaluationResult!;
   }
+
+  DartObjectImpl _topVarConstValue(String name) {
+    return _topVarConstResult(name).value!;
+  }
 }
 
 class _UnitElementResult {
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index 0642108..d34a268 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -35,7 +35,7 @@
       expect(name3, isNull);
       if (annotationElement is ConstructorElement) {
         expect(annotationElement, same(name2.staticElement));
-        expect(annotationElement.enclosingElement3, name1.staticElement);
+        expect(annotationElement.enclosingElement, name1.staticElement);
         expect(annotationElement.displayName, 'A.named');
         expect(annotationElement.parameters, isEmpty);
       } else {
@@ -61,7 +61,7 @@
       expect(name3.staticElement!.displayName, 'A.named');
       if (annotationElement is ConstructorElement) {
         expect(annotationElement, same(name3.staticElement));
-        expect(annotationElement.enclosingElement3, name2.staticElement);
+        expect(annotationElement.enclosingElement, name2.staticElement);
         expect(annotationElement.displayName, 'A.named');
         expect(annotationElement.parameters, isEmpty);
       } else {
@@ -87,7 +87,7 @@
       expect(name3.staticElement!.displayName, 'V');
       if (annotationElement is PropertyAccessorElement) {
         expect(annotationElement, same(name3.staticElement));
-        expect(annotationElement.enclosingElement3, name2.staticElement);
+        expect(annotationElement.enclosingElement, name2.staticElement);
         expect(annotationElement.displayName, 'V');
       } else {
         fail('Expected "annotationElement" is PropertyAccessorElement, '
@@ -110,7 +110,7 @@
       expect(name2.staticElement!.displayName, 'A');
       expect(name3, isNull);
       if (annotationElement is ConstructorElement) {
-        expect(annotationElement.enclosingElement3, name2.staticElement);
+        expect(annotationElement.enclosingElement, name2.staticElement);
         expect(annotationElement.displayName, 'A');
         expect(annotationElement.parameters, isEmpty);
       } else {
@@ -135,7 +135,7 @@
       expect(name3, isNull);
       if (annotationElement is PropertyAccessorElement) {
         expect(annotationElement, same(name2.staticElement));
-        expect(annotationElement.enclosingElement3, name1.staticElement);
+        expect(annotationElement.enclosingElement, name1.staticElement);
         expect(annotationElement.displayName, 'V');
       } else {
         fail('Expected "annotationElement" is PropertyAccessorElement, '
@@ -157,7 +157,7 @@
       expect(name2, isNull);
       expect(name3, isNull);
       if (annotationElement is ConstructorElement) {
-        expect(annotationElement.enclosingElement3, name1.staticElement);
+        expect(annotationElement.enclosingElement, name1.staticElement);
         expect(annotationElement.displayName, 'A');
         expect(annotationElement.parameters, isEmpty);
       } else {
@@ -179,7 +179,7 @@
       expect(name3, isNull);
       if (annotationElement is PropertyAccessorElement) {
         expect(annotationElement, same(name1.staticElement));
-        expect(annotationElement.enclosingElement3, isCompilationUnitElement);
+        expect(annotationElement.enclosingElement, isCompilationUnitElement);
         expect(annotationElement.displayName, 'V');
       } else {
         fail('Expected "annotationElement" is PropertyAccessorElement, '
@@ -201,7 +201,7 @@
       expect(name3, isNull);
       if (annotationElement is PropertyAccessorElement) {
         expect(annotationElement, same(name2.staticElement));
-        expect(annotationElement.enclosingElement3, isCompilationUnitElement);
+        expect(annotationElement.enclosingElement, isCompilationUnitElement);
         expect(annotationElement.displayName, 'V');
       } else {
         fail('Expected "annotationElement" is PropertyAccessorElement, '
diff --git a/pkg/analyzer/test/generated/elements_types_mixin.dart b/pkg/analyzer/test/generated/elements_types_mixin.dart
index 19c9bac3..1f0bca7 100644
--- a/pkg/analyzer/test/generated/elements_types_mixin.dart
+++ b/pkg/analyzer/test/generated/elements_types_mixin.dart
@@ -520,7 +520,7 @@
     required DartType promotedBound,
   }) {
     return TypeParameterTypeImpl(
-      element: element,
+      element2: element,
       nullabilitySuffix: nullabilitySuffix,
       promotedBound: promotedBound,
     );
@@ -664,7 +664,7 @@
     DartType? promotedBound,
   }) {
     return TypeParameterTypeImpl(
-      element: element,
+      element2: element,
       nullabilitySuffix: nullabilitySuffix,
       promotedBound: promotedBound,
     );
diff --git a/pkg/analyzer/test/generated/error_parser_test.dart b/pkg/analyzer/test/generated/error_parser_test.dart
index da49dd5..f30512f 100644
--- a/pkg/analyzer/test/generated/error_parser_test.dart
+++ b/pkg/analyzer/test/generated/error_parser_test.dart
@@ -852,7 +852,7 @@
     expect(semicolon, isNotNull);
     expect(semicolon.isSynthetic, isTrue);
     ClassDeclaration clazz = unit.declarations[0] as ClassDeclaration;
-    expect(clazz.name2.lexeme, 'A');
+    expect(clazz.name.lexeme, 'A');
   }
 
   void test_expectedToken_semicolonMissingAfterExpression() {
@@ -888,7 +888,7 @@
     expect(semicolon, isNotNull);
     expect(semicolon.isSynthetic, isTrue);
     ClassDeclaration clazz = unit.declarations[0] as ClassDeclaration;
-    expect(clazz.name2.lexeme, 'A');
+    expect(clazz.name.lexeme, 'A');
   }
 
   void test_expectedToken_whileMissingInDoStatement() {
@@ -1446,7 +1446,7 @@
     listener.assertErrors([
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 7, 1),
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 1),
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 1)
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 1),
     ]);
   }
 
@@ -2172,12 +2172,6 @@
     expect(parameter.name, isNotNull);
   }
 
-  void test_missingNameInLibraryDirective() {
-    CompilationUnit unit = parseCompilationUnit("library;",
-        errors: [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 1)]);
-    expect(unit, isNotNull);
-  }
-
   void test_missingNameInPartOfDirective() {
     CompilationUnit unit = parseCompilationUnit("part of;",
         errors: [expectedError(ParserErrorCode.EXPECTED_STRING_LITERAL, 7, 1)]);
@@ -2837,6 +2831,18 @@
         errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 1)]);
   }
 
+  void test_unnamedLibraryDirective() {
+    CompilationUnit unit = parseCompilationUnit("library;",
+        errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 0, 7)]);
+    expect(unit, isNotNull);
+  }
+
+  void test_unnamedLibraryDirective_enabled() {
+    CompilationUnit unit = parseCompilationUnit("library;",
+        featureSet: FeatureSets.latestWithExperiments);
+    expect(unit, isNotNull);
+  }
+
   void test_unterminatedString_at_eof() {
     // Although the "unterminated string" error message is produced by the
     // scanner, we need to verify that the parser can handle the tokens
diff --git a/pkg/analyzer/test/generated/extension_methods_parser_test.dart b/pkg/analyzer/test/generated/extension_methods_parser_test.dart
index 3407fe0..8f98507 100644
--- a/pkg/analyzer/test/generated/extension_methods_parser_test.dart
+++ b/pkg/analyzer/test/generated/extension_methods_parser_test.dart
@@ -29,7 +29,7 @@
         ]);
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'extends');
     expect((extension.extendedType as NamedType).name.name, 'A');
     expect(extension.members, hasLength(0));
@@ -42,7 +42,7 @@
     ]);
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'implements');
     expect((extension.extendedType as NamedType).name.name, 'C');
     expect(extension.members, hasLength(0));
@@ -52,7 +52,7 @@
     var unit = parseCompilationUnit('extension E on C<T> { }');
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'on');
     var namedType = extension.extendedType as NamedType;
     expect(namedType.name.name, 'C');
@@ -64,7 +64,7 @@
     var unit = parseCompilationUnit('extension E<T> on C<T> { }');
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'on');
     var namedType = extension.extendedType as NamedType;
     expect(namedType.name.name, 'C');
@@ -76,7 +76,7 @@
     var unit = parseCompilationUnit('extension<T> on C<T> { }');
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2, isNull);
+    expect(extension.name, isNull);
     expect(extension.onKeyword.lexeme, 'on');
     var namedType = extension.extendedType as NamedType;
     expect(namedType.name.name, 'C');
@@ -120,7 +120,7 @@
     ]);
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'on');
     expect((extension.extendedType as NamedType).name.name, '');
     expect(extension.members, hasLength(0));
@@ -133,7 +133,7 @@
     ]);
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'on');
     expect((extension.extendedType as NamedType).name.name, '');
     expect(extension.members, hasLength(0));
@@ -145,7 +145,7 @@
     ]);
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'on');
     expect((extension.extendedType as NamedType).name.name, 'C');
     expect(extension.members, hasLength(0));
@@ -159,7 +159,7 @@
     expect(method.externalKeyword, isNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
-    expect(method.name2.lexeme, 'late');
+    expect(method.name.lexeme, 'late');
     expect(method.functionExpression, isNotNull);
 
     var body = method.functionExpression.body as BlockFunctionBody;
@@ -173,7 +173,7 @@
     var unit = parseCompilationUnit('extension E on C { }');
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'on');
     expect((extension.extendedType as NamedType).name.name, 'C');
     var namedType = extension.extendedType as NamedType;
@@ -188,7 +188,7 @@
     ]);
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'extends');
     expect((extension.extendedType as NamedType).name.name, 'C');
     expect(extension.members, hasLength(0));
@@ -200,7 +200,7 @@
     ]);
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'implements');
     expect((extension.extendedType as NamedType).name.name, 'C');
     expect(extension.members, hasLength(0));
@@ -210,7 +210,7 @@
     var unit = parseCompilationUnit('extension on C { }');
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2, isNull);
+    expect(extension.name, isNull);
     expect(extension.onKeyword.lexeme, 'on');
     expect((extension.extendedType as NamedType).name.name, 'C');
     var namedType = extension.extendedType as NamedType;
@@ -236,7 +236,7 @@
     ]);
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'with');
     expect((extension.extendedType as NamedType).name.name, 'C');
     expect(extension.members, hasLength(0));
@@ -246,7 +246,7 @@
     var unit = parseCompilationUnit('extension E on void { }');
     expect(unit.declarations, hasLength(1));
     var extension = unit.declarations[0] as ExtensionDeclaration;
-    expect(extension.name2!.lexeme, 'E');
+    expect(extension.name!.lexeme, 'E');
     expect(extension.onKeyword.lexeme, 'on');
     expect((extension.extendedType as NamedType).name.name, 'void');
     expect(extension.members, hasLength(0));
diff --git a/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart b/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
index e50a3a7..6fc3b56 100644
--- a/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
+++ b/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
@@ -194,7 +194,7 @@
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members.single as ConstructorDeclaration;
-    expect(constructorDeclaration.name2!.lexeme, 'new');
+    expect(constructorDeclaration.name!.lexeme, 'new');
   }
 
   void test_constructor_name_factory() {
@@ -207,7 +207,7 @@
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members[0] as ConstructorDeclaration;
-    expect(constructorDeclaration.name2!.lexeme, 'new');
+    expect(constructorDeclaration.name!.lexeme, 'new');
   }
 
   void test_constructor_tearoff() {
@@ -320,7 +320,7 @@
     var classDeclaration = unit.declarations.single as ClassDeclaration;
     var constructorDeclaration =
         classDeclaration.members.single as ConstructorDeclaration;
-    expect(constructorDeclaration.name2!.lexeme, 'new');
+    expect(constructorDeclaration.name!.lexeme, 'new');
   }
 
   void test_factory_redirection() {
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 2496ae6..8503da8 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -1458,7 +1458,7 @@
 ''');
     var x = findNode.namedExpression('arg: true');
     var y = x.staticParameterElement!;
-    expect(y.enclosingElement3, isNotNull);
+    expect(y.enclosingElement, isNotNull);
     expect(y.declaration, findElement.parameter('arg'));
   }
 
@@ -1471,7 +1471,7 @@
 ''');
     var x = findNode.namedExpression('arg: true');
     var y = x.staticParameterElement!;
-    expect(y.enclosingElement3, isNotNull);
+    expect(y.enclosingElement, isNotNull);
     expect(y.declaration, findElement.parameter('arg'));
   }
 
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index d01918d..b4f056b 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -204,6 +204,8 @@
   }
 }
 
+// TODO(srawlins): Re-enable?
+// ignore: unreachable_from_main
 class PubSuggestionCodeTest extends PubPackageResolutionTest {
   // TODO(brianwilkerson) The tests in this class are not being run, and all but
   //  the first would fail. We should implement these checks and enable the
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index c5ebdac..bbe9421 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -1021,9 +1021,9 @@
   }
 
   @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
     end('LibraryName');
-    super.endLibraryName(libraryKeyword, semicolon);
+    super.endLibraryName(libraryKeyword, semicolon, hasName);
   }
 
   @override
diff --git a/pkg/analyzer/test/generated/parser_test_base.dart b/pkg/analyzer/test/generated/parser_test_base.dart
index ccb7205..73599dc 100644
--- a/pkg/analyzer/test/generated/parser_test_base.dart
+++ b/pkg/analyzer/test/generated/parser_test_base.dart
@@ -14,9 +14,7 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/ast/ast.dart'
-    show ClassDeclarationImpl, CompilationUnitImpl;
-import 'package:analyzer/src/dart/ast/ast_factory.dart';
+import 'package:analyzer/src/dart/ast/ast.dart' show CompilationUnitImpl;
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/fasta/ast_builder.dart';
@@ -24,7 +22,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/string_source.dart';
-import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
+import 'package:collection/collection.dart';
 import 'package:pub_semver/src/version.dart';
 import 'package:test/test.dart';
 
@@ -421,7 +419,8 @@
     );
     AstBuilder astBuilder = AstBuilder(errorReporter, source.uri, true,
         featureSet!, LineInfo.fromContent(content));
-    fasta.Parser parser = fasta.Parser(astBuilder);
+    fasta.Parser parser = fasta.Parser(astBuilder,
+        allowPatterns: featureSet!.isEnabled(Feature.patterns));
     astBuilder.parser = parser;
     astBuilder.allowNativeClause = allowNativeClause;
     parser.parseUnit(_fastaTokens);
@@ -801,29 +800,11 @@
 
   ClassMember? parseClassMemberOrNull(String className) {
     return _run('ClassOrMixinBody', () {
-      astBuilder.classDeclaration = ClassDeclarationImpl(
-        comment: null,
-        metadata: null,
-        abstractKeyword: null,
-        macroKeyword: null,
-        augmentKeyword: null,
-        classKeyword: Token(Keyword.CLASS, 0),
-        name: astFactory.simpleIdentifier(fasta.StringTokenImpl.fromString(
-            TokenType.IDENTIFIER, className, 6)),
-        typeParameters: null,
-        extendsClause: null,
-        withClause: null,
-        implementsClause: null,
-        leftBracket: Tokens.openCurlyBracket(),
-        members: <ClassMember>[],
-        rightBracket: Tokens.closeCurlyBracket(),
-      );
+      final builder = astBuilder.createFakeClassDeclarationBuilder(className);
       // TODO(danrubel): disambiguate between class and mixin
       currentToken = fastaParser.parseClassMember(currentToken, className);
       //currentToken = fastaParser.parseMixinMember(currentToken);
-      ClassDeclaration declaration = astBuilder.classDeclaration!;
-      astBuilder.classDeclaration = null;
-      return declaration.members.isNotEmpty ? declaration.members[0] : null;
+      return builder.members.firstOrNull;
     });
   }
 
@@ -1527,6 +1508,18 @@
 ///
 /// Intended to be mixed in to parser test case classes.
 mixin ParserTestHelpers {
+  ExpectedError error(ErrorCode code, int offset, int length,
+          {Pattern? correctionContains,
+          String? text,
+          List<Pattern> messageContains = const [],
+          List<ExpectedContextMessage> contextMessages =
+              const <ExpectedContextMessage>[]}) =>
+      ExpectedError(code, offset, length,
+          correctionContains: correctionContains,
+          message: text,
+          messageContains: messageContains,
+          expectedContextMessages: contextMessages);
+
   void expectCommentText(Comment? comment, String expectedText) {
     comment!;
     expect(comment.beginToken, same(comment.endToken));
diff --git a/pkg/analyzer/test/generated/patterns_parser_test.dart b/pkg/analyzer/test/generated/patterns_parser_test.dart
new file mode 100644
index 0000000..41b0a8d
--- /dev/null
+++ b/pkg/analyzer/test/generated/patterns_parser_test.dart
@@ -0,0 +1,2621 @@
+// Copyright (c) 2022, 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/dart/analysis/features.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'parser_test_base.dart';
+import 'test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PatternsTest);
+  });
+}
+
+@reflectiveTest
+class PatternsTest extends FastaParserTestCase {
+  final FeatureSet _enabledFeatureSet = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: ExperimentStatus.currentVersion,
+    flags: [EnableString.patterns],
+  );
+
+  late FindNode findNode;
+
+  test_boolean_literal_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case true:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('true');
+    var constantPattern = switchPatternCase.pattern as ConstantPattern;
+    expect(constantPattern.expression, TypeMatcher<BooleanLiteral>());
+  }
+
+  test_boolean_literal_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case true as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('true as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ConstantPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_boolean_literal_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case true) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var constantPattern = caseClause.pattern as ConstantPattern;
+    expect(constantPattern.expression, TypeMatcher<BooleanLiteral>());
+  }
+
+  test_boolean_literal_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case true!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('true!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_boolean_literal_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case true?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('true?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_cast_inside_case() {
+    _parse('''
+test(dynamic x) {
+  const y = 1;
+  switch (x) {
+    case y as int:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y as int');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ConstantPattern>());
+    expect(castPattern.type.toString(), 'int');
+  }
+
+  test_cast_inside_extractor_pattern() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(f: 1 as int):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(f: 1 as int)");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(extractorPattern.fields[0].pattern, TypeMatcher<CastPattern>());
+  }
+
+  test_cast_inside_extractor_pattern_implicitly_named() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(: var f as int):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(: var f as int)");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(extractorPattern.fields[0].pattern, TypeMatcher<CastPattern>());
+  }
+
+  test_cast_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case var y as int) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    expect(caseClause.pattern, TypeMatcher<CastPattern>());
+  }
+
+  test_cast_inside_list_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case [1 as int]:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[1 as int]');
+    var listPattern = switchPatternCase.pattern as ListPattern;
+    expect(listPattern.elements[0], TypeMatcher<CastPattern>());
+  }
+
+  test_cast_inside_logical_and_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int? _ as double? & Object? _:
+      break;
+  }
+}
+''');
+    var switchPatternCase =
+        findNode.switchPatternCase('int? _ as double? & Object? _');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.leftOperand, TypeMatcher<CastPattern>());
+    expect(binaryPattern.rightOperand, TypeMatcher<VariablePattern>());
+  }
+
+  test_cast_inside_logical_and_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int? _ & double? _ as Object?:
+      break;
+  }
+}
+''');
+    var switchPatternCase =
+        findNode.switchPatternCase('int? _ & double? _ as Object?');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.leftOperand, TypeMatcher<VariablePattern>());
+    expect(binaryPattern.rightOperand, TypeMatcher<CastPattern>());
+  }
+
+  test_cast_inside_logical_or_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int? _ as double? | Object? _:
+      break;
+  }
+}
+''');
+    var switchPatternCase =
+        findNode.switchPatternCase('int? _ as double? | Object? _');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.leftOperand, TypeMatcher<CastPattern>());
+    expect(binaryPattern.rightOperand, TypeMatcher<VariablePattern>());
+  }
+
+  test_cast_inside_logical_or_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int? _ | double? _ as Object?:
+      break;
+  }
+}
+''');
+    var switchPatternCase =
+        findNode.switchPatternCase('int? _ | double? _ as Object?');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.leftOperand, TypeMatcher<VariablePattern>());
+    expect(binaryPattern.rightOperand, TypeMatcher<CastPattern>());
+  }
+
+  test_cast_inside_map_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case {'a': 1 as int}:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("{'a': 1 as int}");
+    var mapPattern = switchPatternCase.pattern as MapPattern;
+    expect(mapPattern.entries[0].value, TypeMatcher<CastPattern>());
+  }
+
+  test_cast_inside_parenthesized_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1 as int):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('(1 as int)');
+    var parenthesizedPattern =
+        switchPatternCase.pattern as ParenthesizedPattern;
+    expect(parenthesizedPattern.pattern, TypeMatcher<CastPattern>());
+  }
+
+  test_cast_inside_record_pattern_implicitly_named() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (: var n as int, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(: var n as int, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<CastPattern>());
+  }
+
+  test_cast_inside_record_pattern_named() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (n: 1 as int, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(n: 1 as int, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<CastPattern>());
+  }
+
+  test_cast_inside_record_pattern_unnamed() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1 as int, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(1 as int, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<CastPattern>());
+  }
+
+  test_constant_identifier_inside_case() {
+    _parse('''
+test(dynamic x) {
+  const y = 1;
+  switch (x) {
+    case y:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y:');
+    var constantPattern = switchPatternCase.pattern as ConstantPattern;
+    expect(constantPattern.expression.toString(), 'y');
+  }
+
+  test_constant_identifier_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  const y = 1;
+  switch (x) {
+    case y as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ConstantPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_constant_identifier_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  const y = 1;
+  if (x case y) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var constantPattern = caseClause.pattern as ConstantPattern;
+    expect(constantPattern.expression.toString(), 'y');
+  }
+
+  test_constant_identifier_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  const y = 1;
+  switch (x) {
+    case y!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_constant_identifier_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  const y = 1;
+  switch (x) {
+    case y?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_double_literal_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1.0:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1.0');
+    var constantPattern = switchPatternCase.pattern as ConstantPattern;
+    expect(constantPattern.expression, TypeMatcher<DoubleLiteral>());
+  }
+
+  test_double_literal_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1.0 as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1.0 as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ConstantPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_double_literal_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case 1.0) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var constantPattern = caseClause.pattern as ConstantPattern;
+    expect(constantPattern.expression, TypeMatcher<DoubleLiteral>());
+  }
+
+  test_double_literal_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1.0!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1.0!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_double_literal_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1.0?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1.0?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_error_recovery_after_question_suffix_in_expression() {
+    // Based on co19 test `Language/Expressions/Conditional/syntax_t06.dart`.
+    // Even though we now support suffix `?` in patterns, we need to make sure
+    // that a suffix `?` in an expression still causes the appropriate syntax
+    // error.
+    _parse('''
+f() {
+  try {
+    true ?  : 2;
+  } catch (e) {}
+}
+''', errors: [
+      error(ParserErrorCode.MISSING_IDENTIFIER, 26, 1),
+    ]);
+  }
+
+  test_extractor_pattern_inside_cast() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(f: 1) as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(f: 1) as Object");
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ExtractorPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_extractor_pattern_inside_null_assert() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(f: 1)!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(f: 1)!");
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ExtractorPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_extractor_pattern_inside_null_check() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(f: 1)?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(f: 1)?");
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ExtractorPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_extractor_pattern_with_type_args() {
+    _parse('''
+class C<T> {}
+test(dynamic x) {
+  switch (x) {
+    case C<int>():
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C<int>()");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(extractorPattern.typeName.toString(), 'C');
+    expect(extractorPattern.typeArguments.toString(), '<int>');
+  }
+
+  test_extractor_pattern_with_type_args_inside_null_assert() {
+    _parse('''
+class C<T> {
+  T? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C<int>(f: 1)!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C<int>(f: 1)!");
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ExtractorPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_final_variable_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case final y:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('final y');
+    var variablePattern = switchPatternCase.pattern as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'final');
+    expect(variablePattern.type, null);
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_final_variable_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case final y as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.type.toString(), 'Object');
+    var variablePattern = castPattern.pattern as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'final');
+    expect(variablePattern.type, null);
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_final_variable_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case final y) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var variablePattern = caseClause.pattern as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'final');
+    expect(variablePattern.type, null);
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_final_variable_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case final y!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operator.lexeme, '!');
+    var variablePattern = postfixPattern.operand as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'final');
+    expect(variablePattern.type, null);
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_final_variable_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case final y?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operator.lexeme, '?');
+    var variablePattern = postfixPattern.operand as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'final');
+    expect(variablePattern.type, null);
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_integer_literal_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1');
+    var constantPattern = switchPatternCase.pattern as ConstantPattern;
+    expect(constantPattern.expression, TypeMatcher<IntegerLiteral>());
+  }
+
+  test_integer_literal_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1 as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1 as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ConstantPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_integer_literal_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case 1) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var constantPattern = caseClause.pattern as ConstantPattern;
+    expect(constantPattern.expression, TypeMatcher<IntegerLiteral>());
+  }
+
+  test_integer_literal_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_integer_literal_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_list_pattern_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case [1, 2]:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[1, 2]');
+    var listPattern = switchPatternCase.pattern as ListPattern;
+    expect(listPattern.typeArguments, isNull);
+    expect(listPattern.leftBracket.lexeme, '[');
+    expect(listPattern.elements, hasLength(2));
+    expect(listPattern.elements[0].toString(), '1');
+    expect(listPattern.elements[1].toString(), '2');
+    expect(listPattern.rightBracket.lexeme, ']');
+  }
+
+  test_list_pattern_inside_case_empty() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case []:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[]');
+    var listPattern = switchPatternCase.pattern as ListPattern;
+    expect(listPattern.typeArguments, isNull);
+    expect(listPattern.leftBracket.lexeme, '[');
+    expect(listPattern.elements, isEmpty);
+    expect(listPattern.rightBracket.lexeme, ']');
+  }
+
+  test_list_pattern_inside_case_empty_whitespace() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case [ ]:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[ ]');
+    var listPattern = switchPatternCase.pattern as ListPattern;
+    expect(listPattern.typeArguments, isNull);
+    expect(listPattern.leftBracket.lexeme, '[');
+    expect(listPattern.elements, isEmpty);
+    expect(listPattern.rightBracket.lexeme, ']');
+  }
+
+  test_list_pattern_inside_case_with_type_arguments() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case <int>[1, 2]:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[1, 2]');
+    var listPattern = switchPatternCase.pattern as ListPattern;
+    expect(listPattern.typeArguments.toString(), '<int>');
+    expect(listPattern.leftBracket.lexeme, '[');
+    expect(listPattern.elements, hasLength(2));
+    expect(listPattern.elements[0].toString(), '1');
+    expect(listPattern.elements[1].toString(), '2');
+    expect(listPattern.rightBracket.lexeme, ']');
+  }
+
+  test_list_pattern_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case [1] as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[1] as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ListPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_list_pattern_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case [1]!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[1]!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ListPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_list_pattern_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case [1]?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[1]?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ListPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_logical_and_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case int? _ & double? _) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var binaryPattern = caseClause.pattern as BinaryPattern;
+    expect(binaryPattern.operator.lexeme, '&');
+  }
+
+  test_logical_and_inside_logical_and_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int? _ & double? _ & Object? _:
+      break;
+  }
+}
+''');
+    var switchPatternCase =
+        findNode.switchPatternCase('int? _ & double? _ & Object? _');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.leftOperand, TypeMatcher<BinaryPattern>());
+    expect(binaryPattern.rightOperand, TypeMatcher<VariablePattern>());
+  }
+
+  test_logical_and_inside_logical_or_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int? _ & double? _ | Object? _:
+      break;
+  }
+}
+''');
+    var switchPatternCase =
+        findNode.switchPatternCase('int? _ & double? _ | Object? _');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.leftOperand, TypeMatcher<BinaryPattern>());
+    expect(binaryPattern.rightOperand, TypeMatcher<VariablePattern>());
+  }
+
+  test_logical_and_inside_logical_or_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int? _ | double? _ & Object? _:
+      break;
+  }
+}
+''');
+    var switchPatternCase =
+        findNode.switchPatternCase('int? _ | double? _ & Object? _');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.leftOperand, TypeMatcher<VariablePattern>());
+    expect(binaryPattern.rightOperand, TypeMatcher<BinaryPattern>());
+  }
+
+  test_logical_or_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case int? _ | double? _) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var binaryPattern = caseClause.pattern as BinaryPattern;
+    expect(binaryPattern.operator.lexeme, '|');
+  }
+
+  test_logical_or_inside_logical_or_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int? _ | double? _ | Object? _:
+      break;
+  }
+}
+''');
+    var switchPatternCase =
+        findNode.switchPatternCase('int? _ | double? _ | Object? _');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.leftOperand, TypeMatcher<BinaryPattern>());
+    expect(binaryPattern.rightOperand, TypeMatcher<VariablePattern>());
+  }
+
+  test_map_pattern_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case {'a': 1, 'b': 2}:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("{'a': 1, 'b': 2}");
+    var mapPattern = switchPatternCase.pattern as MapPattern;
+    expect(mapPattern.typeArguments, isNull);
+    expect(mapPattern.leftBracket.lexeme, '{');
+    expect(mapPattern.entries, hasLength(2));
+    expect(mapPattern.entries[0].key.toString(), "'a'");
+    expect(mapPattern.entries[0].separator.lexeme, ':');
+    expect(mapPattern.entries[0].value.toString(), '1');
+    expect(mapPattern.entries[1].key.toString(), "'b'");
+    expect(mapPattern.entries[1].separator.lexeme, ':');
+    expect(mapPattern.entries[1].value.toString(), '2');
+    expect(mapPattern.rightBracket.lexeme, '}');
+  }
+
+  test_map_pattern_inside_case_empty() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case {}:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("{}");
+    var mapPattern = switchPatternCase.pattern as MapPattern;
+    expect(mapPattern.typeArguments, isNull);
+    expect(mapPattern.leftBracket.lexeme, '{');
+    expect(mapPattern.entries, isEmpty);
+    expect(mapPattern.rightBracket.lexeme, '}');
+  }
+
+  test_map_pattern_inside_case_with_type_arguments() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case <String, int>{'a': 1, 'b': 2}:
+      break;
+  }
+}
+''');
+    var switchPatternCase =
+        findNode.switchPatternCase("<String, int>{'a': 1, 'b': 2}");
+    var mapPattern = switchPatternCase.pattern as MapPattern;
+    expect(mapPattern.typeArguments.toString(), '<String, int>');
+    expect(mapPattern.leftBracket.lexeme, '{');
+    expect(mapPattern.entries, hasLength(2));
+    expect(mapPattern.entries[0].key.toString(), "'a'");
+    expect(mapPattern.entries[0].separator.lexeme, ':');
+    expect(mapPattern.entries[0].value.toString(), '1');
+    expect(mapPattern.entries[1].key.toString(), "'b'");
+    expect(mapPattern.entries[1].separator.lexeme, ':');
+    expect(mapPattern.entries[1].value.toString(), '2');
+    expect(mapPattern.rightBracket.lexeme, '}');
+  }
+
+  test_map_pattern_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case {'a': 1} as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("{'a': 1} as Object");
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<MapPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_map_pattern_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case {'a': 1}!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("{'a': 1}!");
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<MapPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_map_pattern_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case {'a': 1}?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("{'a': 1}?");
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<MapPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_null_assert_inside_case() {
+    _parse('''
+test(dynamic x) {
+  const y = 1;
+  switch (x) {
+    case y!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_null_assert_inside_extractor_pattern() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(f: 1!):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(f: 1!)");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(extractorPattern.fields[0].pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_assert_inside_extractor_pattern_implicitly_named() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(: var f!):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(: var f!)");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(extractorPattern.fields[0].pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_assert_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case var y!) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    expect(caseClause.pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_assert_inside_list_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case [1!]:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[1!]');
+    var listPattern = switchPatternCase.pattern as ListPattern;
+    expect(listPattern.elements[0], TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_assert_inside_logical_and_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1! & 2:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1! & 2');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<PostfixPattern>());
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.rightOperand, TypeMatcher<ConstantPattern>());
+  }
+
+  test_null_assert_inside_logical_and_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1 & 2!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1 & 2!');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<ConstantPattern>());
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.rightOperand, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_assert_inside_logical_or_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1! | 2:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1! | 2');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<PostfixPattern>());
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.rightOperand, TypeMatcher<ConstantPattern>());
+  }
+
+  test_null_assert_inside_logical_or_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1 | 2!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1 | 2!');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<ConstantPattern>());
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.rightOperand, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_assert_inside_map_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case {'a': 1!}:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("{'a': 1!}");
+    var mapPattern = switchPatternCase.pattern as MapPattern;
+    expect(mapPattern.entries[0].value, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_assert_inside_parenthesized_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1!):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('(1!)');
+    var parenthesizedPattern =
+        switchPatternCase.pattern as ParenthesizedPattern;
+    expect(parenthesizedPattern.pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_assert_inside_record_pattern_implicitly_named() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (: var n!, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(: var n!, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_assert_inside_record_pattern_named() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (n: 1!, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(n: 1!, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_assert_inside_record_pattern_unnamed() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1!, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(1!, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_case() {
+    _parse('''
+test(dynamic x) {
+  const y = 1;
+  switch (x) {
+    case y?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_null_check_inside_extractor_pattern() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(f: 1?):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(f: 1?)");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(extractorPattern.fields[0].pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_extractor_pattern_implicitly_named() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(: var f?):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(: var f?)");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(extractorPattern.fields[0].pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case var y?) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    expect(caseClause.pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_list_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case [1?]:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[1?]');
+    var listPattern = switchPatternCase.pattern as ListPattern;
+    expect(listPattern.elements[0], TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_logical_and_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1? & 2:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1? & 2');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<PostfixPattern>());
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.rightOperand, TypeMatcher<ConstantPattern>());
+  }
+
+  test_null_check_inside_logical_and_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1 & 2?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1 & 2?');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<ConstantPattern>());
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.rightOperand, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_logical_or_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1? | 2:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1? | 2');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<PostfixPattern>());
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.rightOperand, TypeMatcher<ConstantPattern>());
+  }
+
+  test_null_check_inside_logical_or_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1 | 2?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1 | 2?');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<ConstantPattern>());
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.rightOperand, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_map_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case {'a': 1?}:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("{'a': 1?}");
+    var mapPattern = switchPatternCase.pattern as MapPattern;
+    expect(mapPattern.entries[0].value, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_parenthesized_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1?):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('(1?)');
+    var parenthesizedPattern =
+        switchPatternCase.pattern as ParenthesizedPattern;
+    expect(parenthesizedPattern.pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_record_pattern_implicitly_named() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (: var n?, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(: var n?, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_record_pattern_named() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (n: 1?, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(n: 1?, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_check_inside_record_pattern_unnamed() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1?, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(1?, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<PostfixPattern>());
+  }
+
+  test_null_literal_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case null:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('null');
+    var constantPattern = switchPatternCase.pattern as ConstantPattern;
+    expect(constantPattern.expression, TypeMatcher<NullLiteral>());
+  }
+
+  test_null_literal_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case null as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('null as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ConstantPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_null_literal_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case null) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var constantPattern = caseClause.pattern as ConstantPattern;
+    expect(constantPattern.expression, TypeMatcher<NullLiteral>());
+  }
+
+  test_null_literal_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case null!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('null!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_null_literal_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case null?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('null?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_parenthesized_pattern_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1) as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('(1) as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ParenthesizedPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_parenthesized_pattern_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1)!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('(1)!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ParenthesizedPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_parenthesized_pattern_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1)?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('(1)?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ParenthesizedPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_prefixed_extractor_pattern_with_type_args() {
+    _parse('''
+import 'dart:async' as async;
+
+test(dynamic x) {
+  switch (x) {
+    case async.Future<int>():
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("async.Future<int>()");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(extractorPattern.typeName.toString(), 'async.Future');
+    expect(extractorPattern.typeArguments.toString(), '<int>');
+  }
+
+  test_prefixed_extractor_pattern_with_type_args_inside_cast() {
+    _parse('''
+import 'dart:async' as async;
+
+test(dynamic x) {
+  switch (x) {
+    case async.Future<int>() as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase =
+        findNode.switchPatternCase("async.Future<int>() as Object");
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ExtractorPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_prefixed_extractor_pattern_with_type_args_inside_null_assert() {
+    _parse('''
+import 'dart:async' as async;
+
+test(dynamic x) {
+  switch (x) {
+    case async.Future<int>()!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("async.Future<int>()!");
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ExtractorPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_prefixed_extractor_pattern_with_type_args_inside_null_check() {
+    _parse('''
+import 'dart:async' as async;
+
+test(dynamic x) {
+  switch (x) {
+    case async.Future<int>()?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("async.Future<int>()?");
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ExtractorPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_record_pattern_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(1, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.leftParenthesis.lexeme, '(');
+    expect(recordPattern.fields, hasLength(2));
+    expect(recordPattern.fields[0].toString(), '1');
+    expect(recordPattern.fields[1].toString(), '2');
+    expect(recordPattern.rightParenthesis.lexeme, ')');
+  }
+
+  test_record_pattern_inside_case_empty() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case ():
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("()");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.leftParenthesis.lexeme, '(');
+    expect(recordPattern.fields, isEmpty);
+    expect(recordPattern.rightParenthesis.lexeme, ')');
+  }
+
+  test_record_pattern_inside_case_singleton() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1,):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(1,)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.leftParenthesis.lexeme, '(');
+    expect(recordPattern.fields, hasLength(1));
+    expect(recordPattern.fields[0].toString(), '1');
+    expect(recordPattern.rightParenthesis.lexeme, ')');
+  }
+
+  test_record_pattern_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1, 2) as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(1, 2) as Object");
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<RecordPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_record_pattern_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1, 2)!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(1, 2)!");
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<RecordPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_record_pattern_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (1, 2)?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(1, 2)?");
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<RecordPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_relational_inside_case_equal() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case == 1 << 1:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('== 1 << 1');
+    var relationalPattern = switchPatternCase.pattern as RelationalPattern;
+    expect(relationalPattern.operator.lexeme, '==');
+    expect(relationalPattern.operand.toString(), '1 << 1');
+  }
+
+  test_relational_inside_case_greater_than() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case > 1 << 1:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('> 1 << 1');
+    var relationalPattern = switchPatternCase.pattern as RelationalPattern;
+    expect(relationalPattern.operator.lexeme, '>');
+    expect(relationalPattern.operand.toString(), '1 << 1');
+  }
+
+  test_relational_inside_case_greater_than_or_equal() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case >= 1 << 1:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('>= 1 << 1');
+    var relationalPattern = switchPatternCase.pattern as RelationalPattern;
+    expect(relationalPattern.operator.lexeme, '>=');
+    expect(relationalPattern.operand.toString(), '1 << 1');
+  }
+
+  test_relational_inside_case_less_than() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case < 1 << 1:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('< 1 << 1');
+    var relationalPattern = switchPatternCase.pattern as RelationalPattern;
+    expect(relationalPattern.operator.lexeme, '<');
+    expect(relationalPattern.operand.toString(), '1 << 1');
+  }
+
+  test_relational_inside_case_less_than_or_equal() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case <= 1 << 1:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('<= 1 << 1');
+    var relationalPattern = switchPatternCase.pattern as RelationalPattern;
+    expect(relationalPattern.operator.lexeme, '<=');
+    expect(relationalPattern.operand.toString(), '1 << 1');
+  }
+
+  test_relational_inside_case_not_equal() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case != 1 << 1:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('!= 1 << 1');
+    var relationalPattern = switchPatternCase.pattern as RelationalPattern;
+    expect(relationalPattern.operator.lexeme, '!=');
+    expect(relationalPattern.operand.toString(), '1 << 1');
+  }
+
+  test_relational_inside_extractor_pattern() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(f: == 1):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(f: == 1)");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(
+        extractorPattern.fields[0].pattern, TypeMatcher<RelationalPattern>());
+  }
+
+  test_relational_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case == 1) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    expect(caseClause.pattern, TypeMatcher<RelationalPattern>());
+  }
+
+  test_relational_inside_list_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case [== 1]:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[== 1]');
+    var listPattern = switchPatternCase.pattern as ListPattern;
+    expect(listPattern.elements[0], TypeMatcher<RelationalPattern>());
+  }
+
+  test_relational_inside_logical_and_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case == 1 & 2:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('== 1 & 2');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<RelationalPattern>());
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.rightOperand, TypeMatcher<ConstantPattern>());
+  }
+
+  test_relational_inside_logical_and_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1 & == 2:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1 & == 2');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<ConstantPattern>());
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.rightOperand, TypeMatcher<RelationalPattern>());
+  }
+
+  test_relational_inside_logical_or_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case == 1 | 2:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('== 1 | 2');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<RelationalPattern>());
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.rightOperand, TypeMatcher<ConstantPattern>());
+  }
+
+  test_relational_inside_logical_or_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1 | == 2:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1 | == 2');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<ConstantPattern>());
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.rightOperand, TypeMatcher<RelationalPattern>());
+  }
+
+  test_relational_inside_map_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case {'a': == 1}:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("{'a': == 1}");
+    var mapPattern = switchPatternCase.pattern as MapPattern;
+    expect(mapPattern.entries[0].value, TypeMatcher<RelationalPattern>());
+  }
+
+  test_relational_inside_parenthesized_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (== 1):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('(== 1)');
+    var parenthesizedPattern =
+        switchPatternCase.pattern as ParenthesizedPattern;
+    expect(parenthesizedPattern.pattern, TypeMatcher<RelationalPattern>());
+  }
+
+  test_relational_inside_record_pattern_named() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (n: == 1, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(n: == 1, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<RelationalPattern>());
+  }
+
+  test_relational_inside_record_pattern_unnamed() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (== 1, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(== 1, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<RelationalPattern>());
+  }
+
+  test_string_literal_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case "x":
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('"x"');
+    var constantPattern = switchPatternCase.pattern as ConstantPattern;
+    expect(constantPattern.expression, TypeMatcher<StringLiteral>());
+  }
+
+  test_string_literal_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case "x" as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('"x" as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.pattern, TypeMatcher<ConstantPattern>());
+    expect(castPattern.type.toString(), 'Object');
+  }
+
+  test_string_literal_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case "x") {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var constantPattern = caseClause.pattern as ConstantPattern;
+    expect(constantPattern.expression, TypeMatcher<StringLiteral>());
+  }
+
+  test_string_literal_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case "x"!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('"x"!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '!');
+  }
+
+  test_string_literal_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case "x"?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('"x"?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operand, TypeMatcher<ConstantPattern>());
+    expect(postfixPattern.operator.lexeme, '?');
+  }
+
+  test_typed_final_variable_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case final int y:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('final int y');
+    var variablePattern = switchPatternCase.pattern as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'final');
+    expect(variablePattern.type.toString(), 'int');
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_typed_final_variable_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case final int y as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.type.toString(), 'Object');
+    var variablePattern = castPattern.pattern as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'final');
+    expect(variablePattern.type, same(findNode.typeAnnotation('int')));
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_typed_final_variable_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case final int y) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var variablePattern = caseClause.pattern as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'final');
+    expect(variablePattern.type.toString(), 'int');
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_typed_final_variable_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case final int y!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operator.lexeme, '!');
+    var variablePattern = postfixPattern.operand as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'final');
+    expect(variablePattern.type, same(findNode.typeAnnotation('int')));
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_typed_final_variable_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case final int y?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operator.lexeme, '?');
+    var variablePattern = postfixPattern.operand as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'final');
+    expect(variablePattern.type, same(findNode.typeAnnotation('int')));
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_typed_variable_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int y:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('int y');
+    var variablePattern = switchPatternCase.pattern as VariablePattern;
+    expect(variablePattern.keyword, null);
+    expect(variablePattern.type.toString(), 'int');
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_typed_variable_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int y as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.type.toString(), 'Object');
+    var variablePattern = castPattern.pattern as VariablePattern;
+    expect(variablePattern.keyword, null);
+    expect(variablePattern.type, same(findNode.typeAnnotation('int')));
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_typed_variable_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case int y) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var variablePattern = caseClause.pattern as VariablePattern;
+    expect(variablePattern.keyword, null);
+    expect(variablePattern.type.toString(), 'int');
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_typed_variable_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int y!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operator.lexeme, '!');
+    var variablePattern = postfixPattern.operand as VariablePattern;
+    expect(variablePattern.keyword, null);
+    expect(variablePattern.type, same(findNode.typeAnnotation('int')));
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_typed_variable_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int y?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operator.lexeme, '?');
+    var variablePattern = postfixPattern.operand as VariablePattern;
+    expect(variablePattern.keyword, null);
+    expect(variablePattern.type, same(findNode.typeAnnotation('int')));
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_typed_variable_named_as_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int as:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('int as');
+    var variablePattern = switchPatternCase.pattern as VariablePattern;
+    expect(variablePattern.keyword, isNull);
+    expect(variablePattern.type.toString(), 'int');
+    expect(variablePattern.name.lexeme, 'as');
+  }
+
+  test_typed_variable_named_as_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int as as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('int as as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.type.toString(), 'Object');
+    var variablePattern = castPattern.pattern as VariablePattern;
+    expect(variablePattern.keyword, null);
+    expect(variablePattern.type, same(findNode.typeAnnotation('int')));
+    expect(variablePattern.name.lexeme, 'as');
+  }
+
+  test_typed_variable_named_as_inside_extractor_pattern() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(f: int as):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(f: int as)");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(extractorPattern.fields[0].pattern, TypeMatcher<VariablePattern>());
+  }
+
+  test_typed_variable_named_as_inside_extractor_pattern_implicitly_named() {
+    _parse('''
+class C {
+  int? f;
+}
+test(dynamic x) {
+  switch (x) {
+    case C(: int as):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("C(: int as)");
+    var extractorPattern = switchPatternCase.pattern as ExtractorPattern;
+    expect(extractorPattern.fields[0].pattern, TypeMatcher<VariablePattern>());
+  }
+
+  test_typed_variable_named_as_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case int as) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    expect(caseClause.pattern, TypeMatcher<VariablePattern>());
+  }
+
+  test_typed_variable_named_as_inside_list_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case [int as]:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('[int as]');
+    var listPattern = switchPatternCase.pattern as ListPattern;
+    expect(listPattern.elements[0], TypeMatcher<VariablePattern>());
+  }
+
+  test_typed_variable_named_as_inside_logical_and_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int as & 2:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('int as & 2');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<VariablePattern>());
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.rightOperand, TypeMatcher<ConstantPattern>());
+  }
+
+  test_typed_variable_named_as_inside_logical_and_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1 & int as:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1 & int as');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<ConstantPattern>());
+    expect(binaryPattern.operator.lexeme, '&');
+    expect(binaryPattern.rightOperand, TypeMatcher<VariablePattern>());
+  }
+
+  test_typed_variable_named_as_inside_logical_or_lhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int as | 2:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('int as | 2');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<VariablePattern>());
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.rightOperand, TypeMatcher<ConstantPattern>());
+  }
+
+  test_typed_variable_named_as_inside_logical_or_rhs() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case 1 | int as:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('1 | int as');
+    var binaryPattern = switchPatternCase.pattern as BinaryPattern;
+    expect(binaryPattern.leftOperand, TypeMatcher<ConstantPattern>());
+    expect(binaryPattern.operator.lexeme, '|');
+    expect(binaryPattern.rightOperand, TypeMatcher<VariablePattern>());
+  }
+
+  test_typed_variable_named_as_inside_map_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case {'a': int as}:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("{'a': int as}");
+    var mapPattern = switchPatternCase.pattern as MapPattern;
+    expect(mapPattern.entries[0].value, TypeMatcher<VariablePattern>());
+  }
+
+  test_typed_variable_named_as_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int as!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('int as!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operator.lexeme, '!');
+    var variablePattern = postfixPattern.operand as VariablePattern;
+    expect(variablePattern.keyword, null);
+    expect(variablePattern.type, same(findNode.typeAnnotation('int')));
+    expect(variablePattern.name.lexeme, 'as');
+  }
+
+  test_typed_variable_named_as_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case int as?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('int as?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operator.lexeme, '?');
+    var variablePattern = postfixPattern.operand as VariablePattern;
+    expect(variablePattern.keyword, null);
+    expect(variablePattern.type, same(findNode.typeAnnotation('int')));
+    expect(variablePattern.name.lexeme, 'as');
+  }
+
+  test_typed_variable_named_as_inside_parenthesized_pattern() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (int as):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('(int as)');
+    var parenthesizedPattern =
+        switchPatternCase.pattern as ParenthesizedPattern;
+    expect(parenthesizedPattern.pattern, TypeMatcher<VariablePattern>());
+  }
+
+  test_typed_variable_named_as_inside_record_pattern_implicitly_named() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (: int as, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(: int as, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<VariablePattern>());
+  }
+
+  test_typed_variable_named_as_inside_record_pattern_named() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (n: int as, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(n: int as, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<VariablePattern>());
+  }
+
+  test_typed_variable_named_as_inside_record_pattern_unnamed() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case (int as, 2):
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase("(int as, 2)");
+    var recordPattern = switchPatternCase.pattern as RecordPattern;
+    expect(recordPattern.fields[0].pattern, TypeMatcher<VariablePattern>());
+  }
+
+  test_var_variable_inside_case() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case var y:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('var y');
+    var variablePattern = switchPatternCase.pattern as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'var');
+    expect(variablePattern.type, null);
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_var_variable_inside_cast() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case var y as Object:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y as Object');
+    var castPattern = switchPatternCase.pattern as CastPattern;
+    expect(castPattern.type.toString(), 'Object');
+    var variablePattern = castPattern.pattern as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'var');
+    expect(variablePattern.type, null);
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_var_variable_inside_if_case() {
+    _parse('''
+test(dynamic x) {
+  if (x case var y) {}
+}
+''');
+    var ifStatement = findNode.ifStatement('x case');
+    expect(ifStatement.condition, same(findNode.simple('x case')));
+    var caseClause = ifStatement.caseClause!;
+    expect(caseClause, same(findNode.caseClause('case')));
+    var variablePattern = caseClause.pattern as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'var');
+    expect(variablePattern.type, null);
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_var_variable_inside_null_assert() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case var y!:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y!');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operator.lexeme, '!');
+    var variablePattern = postfixPattern.operand as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'var');
+    expect(variablePattern.type, null);
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  test_var_variable_inside_null_check() {
+    _parse('''
+test(dynamic x) {
+  switch (x) {
+    case var y?:
+      break;
+  }
+}
+''');
+    var switchPatternCase = findNode.switchPatternCase('y?');
+    var postfixPattern = switchPatternCase.pattern as PostfixPattern;
+    expect(postfixPattern.operator.lexeme, '?');
+    var variablePattern = postfixPattern.operand as VariablePattern;
+    expect(variablePattern.keyword!.lexeme, 'var');
+    expect(variablePattern.type, null);
+    expect(variablePattern.name.lexeme, 'y');
+  }
+
+  void _parse(String content, {List<ExpectedError>? errors}) {
+    var unit = parseCompilationUnit(content,
+        errors: errors, featureSet: _enabledFeatureSet);
+    findNode = FindNode(content, unit);
+  }
+}
diff --git a/pkg/analyzer/test/generated/recovery_parser_test.dart b/pkg/analyzer/test/generated/recovery_parser_test.dart
index fc3f193..9a891bd 100644
--- a/pkg/analyzer/test/generated/recovery_parser_test.dart
+++ b/pkg/analyzer/test/generated/recovery_parser_test.dart
@@ -389,7 +389,7 @@
     expect(unit.declarations, hasLength(1));
     var classDecl = unit.childEntities.first as ClassDeclaration;
     expect(classDecl, isNotNull);
-    expect(classDecl.name2.lexeme, 'foo');
+    expect(classDecl.name.lexeme, 'foo');
   }
 
   void test_equalityExpression_missing_LHS() {
@@ -489,8 +489,8 @@
   void test_functionExpression_in_ConstructorFieldInitializer() {
     CompilationUnit unit =
         parseCompilationUnit("class A { A() : a = (){}; var v; }", codes: [
+      ParserErrorCode.EXPECTED_CLASS_MEMBER,
       ParserErrorCode.MISSING_IDENTIFIER,
-      ParserErrorCode.EXPECTED_CLASS_MEMBER
     ]);
 // Make sure we recovered and parsed "var v" correctly
     ClassDeclaration declaration = unit.declarations[0] as ClassDeclaration;
@@ -500,7 +500,7 @@
     NodeList<VariableDeclaration> vars =
         (fieldDecl as FieldDeclaration).fields.variables;
     expect(vars, hasLength(1));
-    expect(vars[0].name2.lexeme, "v");
+    expect(vars[0].name.lexeme, "v");
   }
 
   void test_functionExpression_named() {
@@ -660,7 +660,7 @@
     NodeList<VariableDeclaration> variables =
         (member as TopLevelVariableDeclaration).variables.variables;
     expect(variables, hasLength(1));
-    final name = variables[0].name2;
+    final name = variables[0].name;
     expect(name.isSynthetic, isFalse);
   }
 
@@ -676,7 +676,7 @@
     NodeList<VariableDeclaration> variables =
         (member as TopLevelVariableDeclaration).variables.variables;
     expect(variables, hasLength(1));
-    final name = variables[0].name2;
+    final name = variables[0].name;
     expect(name.isSynthetic, isTrue);
   }
 
@@ -692,7 +692,7 @@
     NodeList<VariableDeclaration> variables =
         (member as TopLevelVariableDeclaration).variables.variables;
     expect(variables, hasLength(1));
-    final name = variables[0].name2;
+    final name = variables[0].name;
     expect(name.isSynthetic, isTrue);
   }
 
@@ -708,7 +708,7 @@
     NodeList<VariableDeclaration> variables =
         (member as TopLevelVariableDeclaration).variables.variables;
     expect(variables, hasLength(1));
-    final name = variables[0].name2;
+    final name = variables[0].name;
     expect(name.isSynthetic, isTrue);
   }
 
@@ -734,7 +734,7 @@
     NodeList<VariableDeclaration> fields = fieldList.variables;
     expect(fields, hasLength(1));
     VariableDeclaration field = fields[0];
-    expect(field.name2.isSynthetic, isTrue);
+    expect(field.name.isSynthetic, isTrue);
   }
 
   void test_incompleteField_final() {
@@ -759,7 +759,7 @@
     NodeList<VariableDeclaration> fields = fieldList.variables;
     expect(fields, hasLength(1));
     VariableDeclaration field = fields[0];
-    expect(field.name2.isSynthetic, isTrue);
+    expect(field.name.isSynthetic, isTrue);
   }
 
   void test_incompleteField_static() {
@@ -785,7 +785,7 @@
     NodeList<VariableDeclaration> fields = fieldList.variables;
     expect(fields, hasLength(1));
     VariableDeclaration field = fields[0];
-    expect(field.name2.isSynthetic, isFalse);
+    expect(field.name.isSynthetic, isFalse);
   }
 
   void test_incompleteField_static2() {
@@ -808,7 +808,7 @@
     NodeList<VariableDeclaration> fields = fieldList.variables;
     expect(fields, hasLength(1));
     VariableDeclaration field = fields[0];
-    expect(field.name2.isSynthetic, isFalse);
+    expect(field.name.isSynthetic, isFalse);
   }
 
   void test_incompleteField_type() {
@@ -834,7 +834,7 @@
     expect(fields, hasLength(1));
     VariableDeclaration field = fields[0];
     expect(type, isNull);
-    expect(field.name2.lexeme, 'A');
+    expect(field.name.lexeme, 'A');
   }
 
   void test_incompleteField_var() {
@@ -859,7 +859,7 @@
     NodeList<VariableDeclaration> fields = fieldList.variables;
     expect(fields, hasLength(1));
     VariableDeclaration field = fields[0];
-    expect(field.name2.isSynthetic, isTrue);
+    expect(field.name.isSynthetic, isTrue);
   }
 
   void test_incompleteForEach() {
@@ -964,7 +964,7 @@
     List<VariableDeclaration> fields = fieldList.variables;
     expect(fields, hasLength(1));
     VariableDeclaration field = fields[0];
-    expect(field.name2.lexeme, 'f');
+    expect(field.name.lexeme, 'f');
 // validate the type
     var typeArguments = (fieldList.type as NamedType).typeArguments!;
     expect(typeArguments.arguments, hasLength(1));
@@ -1056,7 +1056,7 @@
     var fields = classDecl.members.first as FieldDeclaration;
     expect(fields.fields.variables, hasLength(1));
     VariableDeclaration field = fields.fields.variables.first;
-    expect(field.name2.lexeme, 'g');
+    expect(field.name.lexeme, 'g');
   }
 
   void test_invalidTypeParameters_super() {
@@ -1099,7 +1099,7 @@
     ]);
     var declaration = unit.declarations[0] as ClassDeclaration;
     var method = declaration.members[0] as ConstructorDeclaration;
-    expect(method.name2!.lexeme, 'named');
+    expect(method.name!.lexeme, 'named');
     expect(method.parameters, isNotNull);
   }
 
@@ -1110,7 +1110,7 @@
         ]);
     var declaration = unit.declarations[0] as ClassDeclaration;
     var constructor = declaration.members[0] as ConstructorDeclaration;
-    expect(constructor.name2!.lexeme, 'named');
+    expect(constructor.name!.lexeme, 'named');
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, hasLength(0));
   }
@@ -1121,7 +1121,7 @@
     ]);
     var declaration = unit.declarations[0] as ClassDeclaration;
     var constructor = declaration.members[0] as ConstructorDeclaration;
-    expect(constructor.name2, isNull);
+    expect(constructor.name, isNull);
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, hasLength(0));
   }
@@ -1132,7 +1132,7 @@
     ]);
     var declaration = unit.declarations[0] as ClassDeclaration;
     var constructor = declaration.members[0] as ConstructorDeclaration;
-    expect(constructor.name2!.lexeme, 'named');
+    expect(constructor.name!.lexeme, 'named');
     expect(constructor.parameters, isNotNull);
     expect(constructor.parameters.parameters, hasLength(0));
   }
@@ -1145,7 +1145,7 @@
     ]);
     var declaration = unit.declarations[0] as ClassDeclaration;
     var method = declaration.members[0] as ConstructorDeclaration;
-    expect(method.name2!.lexeme, 'named');
+    expect(method.name!.lexeme, 'named');
     expect(method.parameters, isNotNull);
     expect(method.parameters.parameters, hasLength(0));
   }
@@ -1284,7 +1284,7 @@
     expect(members[0], isMethodDeclaration);
     ClassMember member = members[1];
     expect(member, isMethodDeclaration);
-    expect((member as MethodDeclaration).name2.lexeme, "foo");
+    expect((member as MethodDeclaration).name.lexeme, "foo");
   }
 
   void test_missingIdentifier_afterAnnotation() {
@@ -1309,7 +1309,7 @@
       expect(variables, hasLength(1));
       VariableDeclaration variable = variables[0];
       expect(variableList.type.toString(), expectedTypeName);
-      expect(variable.name2.lexeme, expectedName);
+      expect(variable.name.lexeme, expectedName);
       if (expectedSemicolon.isEmpty) {
         expect(declaration.semicolon.isSynthetic, isTrue);
       } else {
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 1f4018b..d556d49 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -4,10 +4,7 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
@@ -74,7 +71,7 @@
 
     var constructor = findElement.unnamedConstructor('C');
     var x = findElement.localFunction('x');
-    expect(x.enclosingElement3, constructor);
+    expect(x.enclosingElement, constructor);
   }
 }
 
@@ -107,175 +104,6 @@
   }
 }
 
-/// Instances of the class `StaticTypeVerifier` verify that all of the nodes in
-/// an AST structure that should have a static type associated with them do have
-/// a static type.
-class StaticTypeVerifier extends GeneralizingAstVisitor<void> {
-  /// A list containing all of the AST Expression nodes that were not resolved.
-  final List<Expression> _unresolvedExpressions = <Expression>[];
-
-  /// The TypeAnnotation nodes that were not resolved.
-  final List<TypeAnnotation> _unresolvedTypes = <TypeAnnotation>[];
-
-  /// Counter for the number of Expression nodes visited that are resolved.
-  int _resolvedExpressionCount = 0;
-
-  /// Counter for the number of TypeName nodes visited that are resolved.
-  int _resolvedTypeCount = 0;
-
-  /// Assert that all of the visited nodes have a static type associated with
-  /// them.
-  void assertResolved() {
-    if (_unresolvedExpressions.isNotEmpty || _unresolvedTypes.isNotEmpty) {
-      StringBuffer buffer = StringBuffer();
-      int unresolvedTypeCount = _unresolvedTypes.length;
-      if (unresolvedTypeCount > 0) {
-        buffer.write("Failed to resolve ");
-        buffer.write(unresolvedTypeCount);
-        buffer.write(" of ");
-        buffer.write(_resolvedTypeCount + unresolvedTypeCount);
-        buffer.writeln(" type names:");
-        for (TypeAnnotation identifier in _unresolvedTypes) {
-          buffer.write("  ");
-          buffer.write(identifier.toString());
-          buffer.write(" (");
-          buffer.write(_getFileName(identifier));
-          buffer.write(" : ");
-          buffer.write(identifier.offset);
-          buffer.writeln(")");
-        }
-      }
-      int unresolvedExpressionCount = _unresolvedExpressions.length;
-      if (unresolvedExpressionCount > 0) {
-        buffer.writeln("Failed to resolve ");
-        buffer.write(unresolvedExpressionCount);
-        buffer.write(" of ");
-        buffer.write(_resolvedExpressionCount + unresolvedExpressionCount);
-        buffer.writeln(" expressions:");
-        for (Expression expression in _unresolvedExpressions) {
-          buffer.write("  ");
-          buffer.write(expression.toString());
-          buffer.write(" (");
-          buffer.write(_getFileName(expression));
-          buffer.write(" : ");
-          buffer.write(expression.offset);
-          buffer.writeln(")");
-        }
-      }
-      fail(buffer.toString());
-    }
-  }
-
-  @override
-  void visitBreakStatement(BreakStatement node) {}
-
-  @override
-  void visitCommentReference(CommentReference node) {}
-
-  @override
-  void visitContinueStatement(ContinueStatement node) {}
-
-  @override
-  void visitExportDirective(ExportDirective node) {}
-
-  @override
-  void visitExpression(Expression node) {
-    node.visitChildren(this);
-    var staticType = node.staticType;
-    if (staticType == null) {
-      _unresolvedExpressions.add(node);
-    } else {
-      _resolvedExpressionCount++;
-    }
-  }
-
-  @override
-  void visitImportDirective(ImportDirective node) {}
-
-  @override
-  void visitLabel(Label node) {}
-
-  @override
-  void visitLibraryIdentifier(LibraryIdentifier node) {}
-
-  @override
-  void visitNamedType(NamedType node) {
-    // Note: do not visit children from this node, the child SimpleIdentifier in
-    // TypeName (i.e. "String") does not have a static type defined.
-    // TODO(brianwilkerson) Not visiting the children means that we won't catch
-    // type arguments that were not resolved.
-    if (node.type == null) {
-      _unresolvedTypes.add(node);
-    } else {
-      _resolvedTypeCount++;
-    }
-  }
-
-  @override
-  void visitPrefixedIdentifier(PrefixedIdentifier node) {
-    // In cases where we have a prefixed identifier where the prefix is dynamic,
-    // we don't want to assert that the node will have a type.
-    if (node.staticType == null && node.prefix.typeOrThrow.isDynamic) {
-      return;
-    }
-    super.visitPrefixedIdentifier(node);
-  }
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    // In cases where identifiers are being used for something other than an
-    // expressions, then they can be ignored.
-    var parent = node.parent;
-    if (parent is MethodInvocation && identical(node, parent.methodName)) {
-      return;
-    } else if (parent is RedirectingConstructorInvocation &&
-        identical(node, parent.constructorName)) {
-      return;
-    } else if (parent is SuperConstructorInvocation &&
-        identical(node, parent.constructorName)) {
-      return;
-    } else if (parent is ConstructorName && identical(node, parent.name)) {
-      return;
-    } else if (parent is ConstructorFieldInitializer &&
-        identical(node, parent.fieldName)) {
-      return;
-    } else if (node.staticElement is PrefixElement) {
-      // Prefixes don't have a type.
-      return;
-    }
-    super.visitSimpleIdentifier(node);
-  }
-
-  @override
-  void visitTypeAnnotation(TypeAnnotation node) {
-    if (node.type == null) {
-      _unresolvedTypes.add(node);
-    } else {
-      _resolvedTypeCount++;
-    }
-    super.visitTypeAnnotation(node);
-  }
-
-  String _getFileName(AstNode? node) {
-    // TODO (jwren) there are two copies of this method, one here and one in
-    // ResolutionVerifier, they should be resolved into a single method
-    if (node != null) {
-      AstNode root = node.root;
-      if (root is CompilationUnit) {
-        CompilationUnit rootCU = root;
-        if (rootCU.declaredElement != null) {
-          return rootCU.declaredElement!.source.fullName;
-        } else {
-          return "<unknown file- CompilationUnit.getElement() returned null>";
-        }
-      } else {
-        return "<unknown file- CompilationUnit.getRoot() is not a CompilationUnit>";
-      }
-    }
-    return "<unknown file- ASTNode is null>";
-  }
-}
-
 /// The class `StrictModeTest` contains tests to ensure that the correct errors
 /// and warnings are reported when the analysis engine is run in strict mode.
 @reflectiveTest
@@ -490,7 +318,6 @@
 }''';
     await resolveTestCode(code);
     assertType(findElement.localVar('v').type, 'int');
-    assertTypeNull(findNode.simple('v; // declare'));
     assertType(findNode.simple('v; // return'), 'int');
   }
 
@@ -501,7 +328,6 @@
   return v;
 }''');
     assertType(findElement.localVar('v').type, 'int');
-    assertTypeNull(findNode.simple('v = 0;'));
     assertType(findNode.simple('v;'), 'int');
   }
 
@@ -512,7 +338,6 @@
   return v;
 }''');
     assertType(findElement.localVar('v').type, 'List<int>');
-    assertTypeNull(findNode.simple('v ='));
     assertType(findNode.simple('v;'), 'List<int>');
   }
 
@@ -523,7 +348,6 @@
   return v;
 }''');
     assertType(findElement.localVar('v').type, 'int');
-    assertTypeNull(findNode.simple('v ='));
     assertType(findNode.simple('v;'), 'int');
   }
 
@@ -632,7 +456,6 @@
   toString(); // marker
 }''');
     assertTypeDynamic(findElement.localVar('toString').type);
-    assertTypeNull(findNode.simple('toString ='));
     assertTypeDynamic(findNode.simple('toString(); // marker'));
   }
 
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index 74459f0..f94f256 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -94,7 +94,7 @@
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     node.visitChildren(this);
-    if (node.declaredElement2 is LibraryElement) {
+    if (node.declaredElement is LibraryElement) {
       _wrongTypedNodes.add(node);
     }
   }
@@ -319,16 +319,6 @@
     return functionType;
   }
 
-  /// Looks up the identifier with [name] and validates that its element type
-  /// stringifies to [type] and that its generics match the given stringified
-  /// output.
-  FunctionType expectFunctionType2(String name, String type) {
-    var identifier = findNode.simple(name);
-    var functionType = _getFunctionTypedElementType(identifier);
-    assertType(functionType, type);
-    return functionType;
-  }
-
   /// Looks up the identifier with [name] and validates its static [type].
   ///
   /// If [type] is a string, validates that the identifier's static type
@@ -346,8 +336,7 @@
   /// stringifies to that text. Otherwise, [type] is used directly a [Matcher]
   /// to match the type.
   void expectInitializerType(String name, type) {
-    SimpleIdentifier identifier = findNode.simple(name);
-    var declaration = identifier.thisOrAncestorOfType<VariableDeclaration>()!;
+    final declaration = findNode.variableDeclaration(name);
     var initializer = declaration.initializer!;
     _expectType(initializer.staticType, type);
   }
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index db9c70a..2958d55 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -7,7 +7,6 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/string_source.dart';
@@ -24,6 +23,8 @@
   });
 }
 
+// TODO(srawlins): Re-enable?
+// ignore: unreachable_from_main
 class CharacterRangeReaderTest {
   void test_advance() {
     CharSequenceReader baseReader = CharSequenceReader("xyzzy");
@@ -265,65 +266,3 @@
   ScannerTest_ExpectedLocation(
       this._offset, this._lineNumber, this._columnNumber);
 }
-
-/// A `TokenStreamValidator` is used to validate the correct construction of a
-/// stream of tokens.
-class TokenStreamValidator {
-  /// Validate that the stream of tokens that starts with the given [token] is
-  /// correct.
-  void validate(Token token) {
-    StringBuffer buffer = StringBuffer();
-    _validateStream(buffer, token);
-    if (buffer.length > 0) {
-      fail(buffer.toString());
-    }
-  }
-
-  void _validateStream(StringBuffer buffer, Token? token) {
-    if (token == null) {
-      return;
-    }
-    late Token previousToken;
-    int previousEnd = -1;
-    Token? currentToken = token;
-    while (currentToken != null && !currentToken.isEof) {
-      _validateStream(buffer, currentToken.precedingComments);
-      TokenType type = currentToken.type;
-      if (type == TokenType.OPEN_CURLY_BRACKET ||
-          type == TokenType.OPEN_PAREN ||
-          type == TokenType.OPEN_SQUARE_BRACKET ||
-          type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
-        if (currentToken is! BeginToken) {
-          buffer.write("\r\nExpected BeginToken, found ");
-          buffer.write(currentToken.runtimeType.toString());
-          buffer.write(" ");
-          _writeToken(buffer, currentToken);
-        }
-      }
-      int currentStart = currentToken.offset;
-      int currentLength = currentToken.length;
-      int currentEnd = currentStart + currentLength - 1;
-      if (currentStart <= previousEnd) {
-        buffer.write("\r\nInvalid token sequence: ");
-        _writeToken(buffer, previousToken);
-        buffer.write(" followed by ");
-        _writeToken(buffer, currentToken);
-      }
-      previousEnd = currentEnd;
-      previousToken = currentToken;
-      currentToken = currentToken.next;
-    }
-  }
-
-  void _writeToken(StringBuffer buffer, Token token) {
-    buffer.write("[");
-    buffer.write(token.type);
-    buffer.write(", '");
-    buffer.write(token.lexeme);
-    buffer.write("', ");
-    buffer.write(token.offset);
-    buffer.write(", ");
-    buffer.write(token.length);
-    buffer.write("]");
-  }
-}
diff --git a/pkg/analyzer/test/generated/simple_parser_test.dart b/pkg/analyzer/test/generated/simple_parser_test.dart
index 01b61ea..53c2c61 100644
--- a/pkg/analyzer/test/generated/simple_parser_test.dart
+++ b/pkg/analyzer/test/generated/simple_parser_test.dart
@@ -63,13 +63,13 @@
     return classDecl.implementsClause!;
   }
 
-  LibraryIdentifier parseLibraryIdentifier(String name) {
+  LibraryIdentifier? parseLibraryIdentifier(String name) {
     createParser('library $name;');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expect(unit, isNotNull);
     expect(unit.directives, hasLength(1));
     var directive = unit.directives[0] as LibraryDirective;
-    return directive.name;
+    return directive.name2;
   }
 
   /// Parse the given [content] as a sequence of statements by enclosing it in a
@@ -108,10 +108,10 @@
 class C<@Foo.bar(const [], const [1], const{"":r""}, 0xFF + 2, .3, 4.5) T> {}
 ''');
     var clazz = unit.declarations[0] as ClassDeclaration;
-    expect(clazz.name2.lexeme, 'C');
+    expect(clazz.name.lexeme, 'C');
     expect(clazz.typeParameters!.typeParameters, hasLength(1));
     TypeParameter typeParameter = clazz.typeParameters!.typeParameters[0];
-    expect(typeParameter.name2.lexeme, 'T');
+    expect(typeParameter.name.lexeme, 'T');
     expect(typeParameter.metadata, hasLength(1));
     Annotation metadata = typeParameter.metadata[0];
     expect(metadata.name.name, 'Foo.bar');
@@ -126,7 +126,8 @@
       expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 18, 5),
       expectedError(ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 24, 5),
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 24, 5),
-      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 29, 1),
+      expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 29, 1),
+      expectedError(ParserErrorCode.RECORD_LITERAL_EMPTY, 30, 1),
     ]);
   }
 
@@ -1467,7 +1468,7 @@
 
   void test_parseLibraryIdentifier_builtin() {
     String name = "deferred";
-    LibraryIdentifier identifier = parseLibraryIdentifier(name);
+    LibraryIdentifier identifier = parseLibraryIdentifier(name)!;
     expectNotNullIfNoErrors(identifier);
     assertNoErrors();
     expect(identifier.name, name);
@@ -1483,7 +1484,7 @@
 
   void test_parseLibraryIdentifier_multiple() {
     String name = "a.b.c";
-    LibraryIdentifier identifier = parseLibraryIdentifier(name);
+    LibraryIdentifier identifier = parseLibraryIdentifier(name)!;
     expectNotNullIfNoErrors(identifier);
     assertNoErrors();
     expect(identifier.name, name);
@@ -1491,7 +1492,7 @@
 
   void test_parseLibraryIdentifier_pseudo() {
     String name = "await";
-    LibraryIdentifier identifier = parseLibraryIdentifier(name);
+    LibraryIdentifier identifier = parseLibraryIdentifier(name)!;
     expectNotNullIfNoErrors(identifier);
     assertNoErrors();
     expect(identifier.name, name);
@@ -1500,7 +1501,7 @@
 
   void test_parseLibraryIdentifier_single() {
     String name = "a";
-    LibraryIdentifier identifier = parseLibraryIdentifier(name);
+    LibraryIdentifier identifier = parseLibraryIdentifier(name)!;
     expectNotNullIfNoErrors(identifier);
     assertNoErrors();
     expect(identifier.name, name);
@@ -1849,7 +1850,7 @@
     assertNoErrors();
     expect(parameter.bound, isGenericFunctionType);
     expect(parameter.extendsKeyword, isNotNull);
-    expect(parameter.name2, isNotNull);
+    expect(parameter.name, isNotNull);
   }
 
   void test_parseTypeParameter_bounded_functionType_return() {
@@ -1859,7 +1860,7 @@
     assertNoErrors();
     expect(parameter.bound, isGenericFunctionType);
     expect(parameter.extendsKeyword, isNotNull);
-    expect(parameter.name2, isNotNull);
+    expect(parameter.name, isNotNull);
   }
 
   void test_parseTypeParameter_bounded_generic() {
@@ -1869,7 +1870,7 @@
     assertNoErrors();
     expect(parameter.bound, isNamedType);
     expect(parameter.extendsKeyword, isNotNull);
-    expect(parameter.name2, isNotNull);
+    expect(parameter.name, isNotNull);
   }
 
   void test_parseTypeParameter_bounded_simple() {
@@ -1879,7 +1880,7 @@
     assertNoErrors();
     expect(parameter.bound, isNamedType);
     expect(parameter.extendsKeyword, isNotNull);
-    expect(parameter.name2, isNotNull);
+    expect(parameter.name, isNotNull);
   }
 
   void test_parseTypeParameter_simple() {
@@ -1889,7 +1890,7 @@
     assertNoErrors();
     expect(parameter.bound, isNull);
     expect(parameter.extendsKeyword, isNull);
-    expect(parameter.name2, isNotNull);
+    expect(parameter.name, isNotNull);
   }
 
   void test_parseTypeParameterList_multiple() {
@@ -1921,7 +1922,7 @@
     expect(parameterList.rightBracket, isNotNull);
     expect(parameterList.typeParameters, hasLength(1));
     TypeParameter typeParameter = parameterList.typeParameters[0];
-    expect(typeParameter.name2.lexeme, 'A');
+    expect(typeParameter.name.lexeme, 'A');
     var bound = typeParameter.bound as NamedType;
     expect(bound.name.name, 'B');
     var typeArguments = bound.typeArguments!;
@@ -1955,7 +1956,7 @@
     VariableDeclaration declaration = parseVariableDeclaration('var a = b;');
     expectNotNullIfNoErrors(declaration);
     assertNoErrors();
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.equals, isNotNull);
     expect(declaration.initializer, isNotNull);
   }
@@ -2040,7 +2041,7 @@
     VariableDeclaration declaration = parseVariableDeclaration('var a;');
     expectNotNullIfNoErrors(declaration);
     assertNoErrors();
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.equals, isNull);
     expect(declaration.initializer, isNull);
   }
@@ -2072,7 +2073,7 @@
       expectedError(ScannerErrorCode.EXPECTED_TOKEN, 23, 1),
     ]);
     var typeAlias = unit.declarations[0] as GenericTypeAlias;
-    expect(typeAlias.name2.lexeme, 'K');
+    expect(typeAlias.name.lexeme, 'K');
     var functionType = typeAlias.functionType!;
     expect(functionType.parameters.parameters, hasLength(1));
     var parameter = functionType.parameters.parameters[0];
@@ -2086,7 +2087,7 @@
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 19, 1),
     ]);
     var typeAlias = unit.declarations[0] as GenericTypeAlias;
-    expect(typeAlias.name2.lexeme, 'T');
+    expect(typeAlias.name.lexeme, 'T');
     var functionType = typeAlias.functionType!;
     expect(functionType.parameters.parameters, hasLength(1));
     var parameter = functionType.parameters.parameters[0];
diff --git a/pkg/analyzer/test/generated/statement_parser_test.dart b/pkg/analyzer/test/generated/statement_parser_test.dart
index f358b2a..2843c1c 100644
--- a/pkg/analyzer/test/generated/statement_parser_test.dart
+++ b/pkg/analyzer/test/generated/statement_parser_test.dart
@@ -1072,7 +1072,7 @@
     assertNoErrors();
     List<VariableDeclaration> variables = statement.variables.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'Function');
+    expect(variables[0].name.lexeme, 'Function');
   }
 
   void test_parseNonLabeledStatement_variableDeclaration_gftType() {
@@ -1082,7 +1082,7 @@
     VariableDeclarationList variableList = statement.variables;
     List<VariableDeclaration> variables = variableList.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'v');
+    expect(variables[0].name.lexeme, 'v');
     expect(variableList.type, isGenericFunctionType);
   }
 
@@ -1095,7 +1095,7 @@
     VariableDeclarationList variableList = statement.variables;
     List<VariableDeclaration> variables = variableList.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'v');
+    expect(variables[0].name.lexeme, 'v');
     expect(variableList.type, isGenericFunctionType);
   }
 
@@ -1107,7 +1107,7 @@
     VariableDeclarationList variableList = statement.variables;
     List<VariableDeclaration> variables = variableList.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'v');
+    expect(variables[0].name.lexeme, 'v');
     expect(variableList.type, isGenericFunctionType);
   }
 
@@ -1119,7 +1119,7 @@
     VariableDeclarationList variableList = statement.variables;
     List<VariableDeclaration> variables = variableList.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'v');
+    expect(variables[0].name.lexeme, 'v');
     expect(variableList.type, isGenericFunctionType);
   }
 
@@ -1131,7 +1131,7 @@
     VariableDeclarationList variableList = statement.variables;
     List<VariableDeclaration> variables = variableList.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'v');
+    expect(variables[0].name.lexeme, 'v');
     expect(variableList.type, isGenericFunctionType);
   }
 
@@ -1142,7 +1142,7 @@
     VariableDeclarationList variableList = statement.variables;
     List<VariableDeclaration> variables = variableList.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'v');
+    expect(variables[0].name.lexeme, 'v');
     expect(variableList.type, isGenericFunctionType);
   }
 
@@ -1154,7 +1154,7 @@
     VariableDeclarationList variableList = statement.variables;
     List<VariableDeclaration> variables = variableList.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'v');
+    expect(variables[0].name.lexeme, 'v');
     expect(variableList.type, isGenericFunctionType);
   }
 
@@ -1164,7 +1164,7 @@
     VariableDeclarationList variableList = statement.variables;
     List<VariableDeclaration> variables = variableList.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'v');
+    expect(variables[0].name.lexeme, 'v');
     var typeName = variableList.type as NamedType;
     expect(typeName.name.name, 'C');
     expect(typeName.typeArguments!.arguments, hasLength(1));
@@ -1179,7 +1179,7 @@
     VariableDeclarationList variableList = statement.variables;
     List<VariableDeclaration> variables = variableList.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'v');
+    expect(variables[0].name.lexeme, 'v');
     var typeName = variableList.type as NamedType;
     expect(typeName.name.name, 'C');
     expect(typeName.typeArguments!.arguments, hasLength(1));
@@ -1194,7 +1194,7 @@
     VariableDeclarationList variableList = statement.variables;
     List<VariableDeclaration> variables = variableList.variables;
     expect(variables, hasLength(1));
-    expect(variables[0].name2.lexeme, 'v');
+    expect(variables[0].name.lexeme, 'v');
     var typeName = variableList.type as NamedType;
     expect(typeName.name.name, 'C');
     expect(typeName.typeArguments!.arguments, hasLength(1));
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index d9bf553..3f85ffa 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -223,7 +223,7 @@
       return exp;
     }
 
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement2!;
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement!;
 
     CascadeExpression cascade = fetch(0);
     _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.typeOrThrow);
@@ -369,8 +369,8 @@
     var body = constructor.body as BlockFunctionBody;
     var stmt = body.block.statements[0] as ReturnStatement;
     var exp = stmt.expression as InstanceCreationExpression;
-    ClassElement elementB = AstFinder.getClass(unit, "B").declaredElement2!;
-    ClassElement elementA = AstFinder.getClass(unit, "A").declaredElement2!;
+    ClassElement elementB = AstFinder.getClass(unit, "B").declaredElement!;
+    ClassElement elementA = AstFinder.getClass(unit, "A").declaredElement!;
     final type = exp.constructorName.type.typeOrThrow as InterfaceType;
     expect(type.element2, elementB);
     _isInstantiationOf(_hasElement(elementB))([
@@ -1118,7 +1118,7 @@
       error(HintCode.UNUSED_LOCAL_VARIABLE, 347, 2),
     ]);
 
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement2!;
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement!;
     List<Statement> statements =
         AstFinder.getStatementsInTopLevelFunction(unit, "test");
     void check(int i) {
@@ -1149,7 +1149,7 @@
     ]);
 
     DartType cType = findElement.localVar('c').type;
-    Element elementC = AstFinder.getClass(unit, "C").declaredElement2!;
+    Element elementC = AstFinder.getClass(unit, "C").declaredElement!;
 
     _isInstantiationOf(_hasElement(elementC))([_isDynamic])(cType);
   }
@@ -1426,7 +1426,7 @@
             as VariableDeclarationStatement)
         .variables
         .variables[0];
-    _isDynamic(h.declaredElement2!.type);
+    _isDynamic(h.declaredElement!.type);
     var fCall = h.initializer as MethodInvocation;
     assertInvokeType(fCall, 'dynamic Function(dynamic Function(dynamic))');
     var g = fCall.argumentList.arguments[0];
@@ -1480,9 +1480,9 @@
 
     VariableDeclaration mapB = AstFinder.getFieldInClass(unit, "B", "map");
     MethodDeclaration mapC = AstFinder.getMethodInClass(unit, "C", "map");
-    assertMapOfIntToListOfInt(mapB.declaredElement2!.type as InterfaceType);
+    assertMapOfIntToListOfInt(mapB.declaredElement!.type as InterfaceType);
     assertMapOfIntToListOfInt(
-        mapC.declaredElement2!.returnType as InterfaceType);
+        mapC.declaredElement!.returnType as InterfaceType);
 
     var mapLiteralB = mapB.initializer as SetOrMapLiteral;
     var mapLiteralC =
@@ -1667,12 +1667,12 @@
     void hasType(Asserter<DartType> assertion, Expression exp) =>
         assertion(exp.typeOrThrow);
 
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement2!;
-    Element elementB = AstFinder.getClass(unit, "B").declaredElement2!;
-    Element elementC = AstFinder.getClass(unit, "C").declaredElement2!;
-    Element elementD = AstFinder.getClass(unit, "D").declaredElement2!;
-    Element elementE = AstFinder.getClass(unit, "E").declaredElement2!;
-    Element elementF = AstFinder.getClass(unit, "F").declaredElement2!;
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement!;
+    Element elementB = AstFinder.getClass(unit, "B").declaredElement!;
+    Element elementC = AstFinder.getClass(unit, "C").declaredElement!;
+    Element elementD = AstFinder.getClass(unit, "D").declaredElement!;
+    Element elementE = AstFinder.getClass(unit, "E").declaredElement!;
+    Element elementF = AstFinder.getClass(unit, "F").declaredElement!;
 
     AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf =
         _isInstantiationOf(_hasElement(elementA));
@@ -2178,7 +2178,7 @@
     var body = test.functionExpression.body as ExpressionFunctionBody;
     DartType type = body.expression.typeOrThrow;
 
-    Element elementB = AstFinder.getClass(unit, "B").declaredElement2!;
+    Element elementB = AstFinder.getClass(unit, "B").declaredElement!;
 
     _isInstantiationOf(_hasElement(elementB))([_isNull])(type);
   }
@@ -2200,7 +2200,7 @@
     var body = test.functionExpression.body as ExpressionFunctionBody;
     DartType type = body.expression.typeOrThrow;
 
-    Element elementB = AstFinder.getClass(unit, "B").declaredElement2!;
+    Element elementB = AstFinder.getClass(unit, "B").declaredElement!;
 
     _isInstantiationOf(_hasElement(elementB))([_isNum])(type);
   }
@@ -2225,7 +2225,7 @@
     var body = test.functionExpression.body as ExpressionFunctionBody;
     DartType type = body.expression.typeOrThrow;
 
-    Element elementB = AstFinder.getClass(unit, "B").declaredElement2!;
+    Element elementB = AstFinder.getClass(unit, "B").declaredElement!;
 
     _isInstantiationOf(_hasElement(elementB))([_isNull])(type);
   }
@@ -2248,7 +2248,7 @@
     var body = test.functionExpression.body as ExpressionFunctionBody;
     DartType type = body.expression.typeOrThrow;
 
-    Element elementB = AstFinder.getClass(unit, "B").declaredElement2!;
+    Element elementB = AstFinder.getClass(unit, "B").declaredElement!;
 
     _isInstantiationOf(_hasElement(elementB))([_isInt])(type);
   }
@@ -2274,7 +2274,7 @@
     var functionType = body.expression.staticType as FunctionType;
     DartType type = functionType.normalParameterTypes[0];
 
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement2!;
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement!;
 
     _isInstantiationOf(_hasElement(elementA))([_isObject, _isObject])(type);
   }
@@ -2299,7 +2299,7 @@
     var functionType = body.expression.staticType as FunctionType;
     DartType type = functionType.normalParameterTypes[0];
 
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement2!;
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement!;
 
     _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type);
   }
@@ -2325,7 +2325,7 @@
     var functionType = body.expression.staticType as FunctionType;
     DartType type = functionType.normalParameterTypes[0];
 
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement2!;
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement!;
 
     _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type);
   }
@@ -2351,7 +2351,7 @@
     var functionType = body.expression.staticType as FunctionType;
     DartType type = functionType.normalParameterTypes[0];
 
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement2!;
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement!;
 
     _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type);
   }
@@ -2773,9 +2773,10 @@
     await assertNoErrorsInCode(r'''
 void g(T f<T>(T x)) {}
 ''');
-    var type = expectFunctionType2('f', 'T Function<T>(T)');
-    FunctionType ft = type.instantiate([typeProvider.stringType]);
-    assertType(ft, 'String Function(String)');
+
+    final fType = findElement.parameter('f').type;
+    fType as FunctionType;
+    assertType(fType, 'T Function<T>(T)');
   }
 
   test_genericFunction_static() async {
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index 065d67a..0281d0e 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -26,6 +26,7 @@
 import 'non_error_parser_test.dart' as non_error_parser;
 import 'non_error_resolver_test.dart' as non_error_resolver;
 import 'non_hint_code_test.dart' as non_hint_code;
+import 'patterns_parser_test.dart' as patterns_parser;
 import 'recovery_parser_test.dart' as recovery_parser;
 import 'resolver_test.dart' as resolver_test;
 import 'scanner_test.dart' as scanner_test;
@@ -67,6 +68,7 @@
     non_error_parser.main();
     non_error_resolver.main();
     non_hint_code.main();
+    patterns_parser.main();
     recovery_parser.main();
     resolver_test.main();
     scanner_test.main();
diff --git a/pkg/analyzer/test/generated/top_level_parser_test.dart b/pkg/analyzer/test/generated/top_level_parser_test.dart
index a628cb6..74fabcf 100644
--- a/pkg/analyzer/test/generated/top_level_parser_test.dart
+++ b/pkg/analyzer/test/generated/top_level_parser_test.dart
@@ -119,7 +119,7 @@
     expect(declaration.implementsClause, isNull);
     expect(declaration.classKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -138,7 +138,7 @@
     expect(declaration.implementsClause, isNull);
     expect(declaration.classKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -157,7 +157,7 @@
     expect(declaration.implementsClause, isNull);
     expect(declaration.classKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -176,7 +176,7 @@
     expect(declaration.implementsClause, isNotNull);
     expect(declaration.classKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -192,7 +192,7 @@
     expect(declaration.documentationComment, isNull);
     expect(declaration.abstractKeyword, isNull);
     expect(declaration.classKeyword, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.typeParameters, isNull);
     expect(declaration.extendsClause, isNotNull);
     expect(declaration.withClause, isNotNull);
@@ -212,7 +212,7 @@
     expect(declaration.documentationComment, isNull);
     expect(declaration.abstractKeyword, isNull);
     expect(declaration.classKeyword, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.typeParameters, isNull);
     expect(declaration.extendsClause, isNotNull);
     expect(declaration.withClause, isNotNull);
@@ -235,7 +235,7 @@
     expect(declaration.implementsClause, isNotNull);
     expect(declaration.classKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -377,7 +377,7 @@
     expect(declaration.implementsClause, isNull);
     expect(declaration.classKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.members, hasLength(1));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -391,7 +391,7 @@
     expect(member, isClassTypeAlias);
     var typeAlias = member as ClassTypeAlias;
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.withClause, isNotNull);
     expect(typeAlias.implementsClause, isNotNull);
@@ -408,7 +408,7 @@
     expect(member, isClassTypeAlias);
     var typeAlias = member as ClassTypeAlias;
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.withClause, isNotNull);
     expect(typeAlias.withClause.withKeyword, isNotNull);
@@ -430,7 +430,7 @@
     expect(declaration.implementsClause, isNull);
     expect(declaration.classKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNotNull);
@@ -652,7 +652,7 @@
     assertNoErrors();
     expect(member, isClassDeclaration);
     var declaration = member as ClassDeclaration;
-    expect(declaration.name2.lexeme, "A");
+    expect(declaration.name.lexeme, "A");
     expect(declaration.members, hasLength(0));
   }
 
@@ -663,7 +663,7 @@
     assertNoErrors();
     expect(member, isClassTypeAlias);
     var declaration = member as ClassTypeAlias;
-    expect(declaration.name2.lexeme, "A");
+    expect(declaration.name.lexeme, "A");
     expect(declaration.abstractKeyword, isNotNull);
   }
 
@@ -921,7 +921,7 @@
     expect(member, isClassTypeAlias);
     var typeAlias = member as ClassTypeAlias;
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2.lexeme, "C");
+    expect(typeAlias.name.lexeme, "C");
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.equals, isNotNull);
     expect(typeAlias.abstractKeyword, isNotNull);
@@ -939,7 +939,7 @@
     expect(member, isClassTypeAlias);
     var typeAlias = member as ClassTypeAlias;
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2.lexeme, "C");
+    expect(typeAlias.name.lexeme, "C");
     expect(typeAlias.typeParameters!.typeParameters, hasLength(1));
     expect(typeAlias.equals, isNotNull);
     expect(typeAlias.abstractKeyword, isNull);
@@ -957,7 +957,7 @@
     expect(member, isClassTypeAlias);
     var typeAlias = member as ClassTypeAlias;
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2.lexeme, "C");
+    expect(typeAlias.name.lexeme, "C");
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.equals, isNotNull);
     expect(typeAlias.abstractKeyword, isNull);
@@ -975,7 +975,7 @@
     expect(member, isClassTypeAlias);
     var typeAlias = member as ClassTypeAlias;
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2.lexeme, "C");
+    expect(typeAlias.name.lexeme, "C");
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.equals, isNotNull);
     expect(typeAlias.abstractKeyword, isNull);
@@ -992,7 +992,7 @@
     assertNoErrors();
     expect(member, TypeMatcher<FunctionTypeAlias>());
     var typeAlias = member as FunctionTypeAlias;
-    expect(typeAlias.name2.lexeme, "F");
+    expect(typeAlias.name.lexeme, "F");
     expect(typeAlias.parameters.parameters, hasLength(0));
   }
 
@@ -1121,32 +1121,32 @@
     expect(directive, TypeMatcher<LibraryDirective>());
     var libraryDirective = directive as LibraryDirective;
     expect(libraryDirective.libraryKeyword, isNotNull);
-    expect(libraryDirective.name, isNotNull);
+    expect(libraryDirective.name2, isNotNull);
     expect(libraryDirective.semicolon, isNotNull);
   }
 
   void test_parseDirective_library_1_component() {
     createParser("library a;");
     var lib = parseFullDirective() as LibraryDirective;
-    expect(lib.name.components, hasLength(1));
-    expect(lib.name.components[0].name, 'a');
+    expect(lib.name2!.components, hasLength(1));
+    expect(lib.name2!.components[0].name, 'a');
   }
 
   void test_parseDirective_library_2_components() {
     createParser("library a.b;");
     var lib = parseFullDirective() as LibraryDirective;
-    expect(lib.name.components, hasLength(2));
-    expect(lib.name.components[0].name, 'a');
-    expect(lib.name.components[1].name, 'b');
+    expect(lib.name2!.components, hasLength(2));
+    expect(lib.name2!.components[0].name, 'a');
+    expect(lib.name2!.components[1].name, 'b');
   }
 
   void test_parseDirective_library_3_components() {
     createParser("library a.b.c;");
     var lib = parseFullDirective() as LibraryDirective;
-    expect(lib.name.components, hasLength(3));
-    expect(lib.name.components[0].name, 'a');
-    expect(lib.name.components[1].name, 'b');
-    expect(lib.name.components[2].name, 'c');
+    expect(lib.name2!.components, hasLength(3));
+    expect(lib.name2!.components[0].name, 'a');
+    expect(lib.name2!.components[1].name, 'b');
+    expect(lib.name2!.components[2].name, 'c');
   }
 
   void test_parseDirective_library_annotation() {
@@ -1157,7 +1157,7 @@
     expect(directive, TypeMatcher<LibraryDirective>());
     var libraryDirective = directive as LibraryDirective;
     expect(libraryDirective.libraryKeyword, isNotNull);
-    expect(libraryDirective.name, isNotNull);
+    expect(libraryDirective.name2, isNotNull);
     expect(libraryDirective.semicolon, isNotNull);
     expect(libraryDirective.metadata, hasLength(1));
     expect(libraryDirective.metadata[0].name.name, 'A');
@@ -1172,12 +1172,18 @@
     expect(directive, TypeMatcher<LibraryDirective>());
     var libraryDirective = directive as LibraryDirective;
     expect(libraryDirective.libraryKeyword, isNotNull);
-    expect(libraryDirective.name, isNotNull);
+    expect(libraryDirective.name2, isNotNull);
     expect(libraryDirective.semicolon, isNotNull);
     expect(libraryDirective.metadata, hasLength(1));
     expect(libraryDirective.metadata[0].name.name, 'A');
   }
 
+  void test_parseDirective_library_unnamed() {
+    createParser("library;");
+    var lib = parseFullDirective() as LibraryDirective;
+    expect(lib.name2, isNull);
+  }
+
   void test_parseDirective_library_withDocumentationComment() {
     createParser('/// Doc\nlibrary l;');
     var directive = parseFullDirective() as LibraryDirective;
@@ -1305,7 +1311,7 @@
     expect(declaration.documentationComment, isNull);
     expect(declaration.enumKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.constants, hasLength(1));
     expect(declaration.rightBracket, isNotNull);
   }
@@ -1318,7 +1324,7 @@
     expect(declaration.documentationComment, isNull);
     expect(declaration.enumKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.constants, hasLength(1));
     expect(declaration.rightBracket, isNotNull);
   }
@@ -1331,7 +1337,7 @@
     expect(declaration.documentationComment, isNull);
     expect(declaration.enumKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     expect(declaration.constants, hasLength(2));
     expect(declaration.rightBracket, isNotNull);
   }
@@ -1456,7 +1462,7 @@
     assertNoErrors();
     expectCommentText(declaration.documentationComment, '/// Doc');
     expect((declaration.returnType as NamedType).name.name, 'T');
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     FunctionExpression expression = declaration.functionExpression;
     expect(expression, isNotNull);
     expect(expression.body, isNotNull);
@@ -1472,7 +1478,7 @@
     assertNoErrors();
     expectCommentText(declaration.documentationComment, '/// Doc');
     expect((declaration.returnType as NamedType).name.name, 'T');
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     FunctionExpression expression = declaration.functionExpression;
     expect(expression, isNotNull);
     expect(expression.body, isNotNull);
@@ -1488,7 +1494,7 @@
     assertNoErrors();
     expectCommentText(declaration.documentationComment, '/// Doc');
     expect((declaration.returnType as NamedType).name.name, 'T');
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     FunctionExpression expression = declaration.functionExpression;
     expect(expression, isNotNull);
     expect(expression.body, isNotNull);
@@ -1505,7 +1511,7 @@
     assertNoErrors();
     expect(declaration.documentationComment, isNull);
     expect((declaration.returnType as NamedType).name.name, 'T');
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     FunctionExpression expression = declaration.functionExpression;
     expect(expression, isNotNull);
     expect(expression.body, isNotNull);
@@ -1566,7 +1572,7 @@
     assertNoErrors();
     expectCommentText(declaration.documentationComment, '/// Doc');
     expect((declaration.returnType as NamedType).name.name, 'T');
-    expect(declaration.name2, isNotNull);
+    expect(declaration.name, isNotNull);
     FunctionExpression expression = declaration.functionExpression;
     expect(expression, isNotNull);
     expect(expression.body, isNotNull);
@@ -1580,8 +1586,8 @@
     var alias = parseFullCompilationUnitMember() as GenericTypeAlias;
     expect(alias, isNotNull);
     assertNoErrors();
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters, isNull);
     expect(alias.equals, isNotNull);
     expect(alias.functionType, isNotNull);
@@ -1593,8 +1599,8 @@
     var alias = parseFullCompilationUnitMember() as GenericTypeAlias;
     expect(alias, isNotNull);
     assertNoErrors();
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters!.typeParameters, hasLength(1));
     expect(alias.equals, isNotNull);
     expect(alias.functionType, isNotNull);
@@ -1608,8 +1614,8 @@
     var alias = parseFullCompilationUnitMember() as GenericTypeAlias;
     expect(alias, isNotNull);
     assertNoErrors();
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters!.typeParameters, hasLength(1));
     expect(alias.equals, isNotNull);
     expect(alias.functionType, isNotNull);
@@ -1621,8 +1627,8 @@
     var alias = parseFullCompilationUnitMember() as GenericTypeAlias;
     expect(alias, isNotNull);
     assertNoErrors();
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters!.typeParameters, hasLength(3));
     expect(alias.equals, isNotNull);
     expect(alias.functionType, isNotNull);
@@ -1636,8 +1642,8 @@
     var alias = parseFullCompilationUnitMember() as GenericTypeAlias;
     expect(alias, isNotNull);
     assertNoErrors();
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters!.typeParameters, hasLength(3));
     expect(alias.equals, isNotNull);
     expect(alias.functionType, isNotNull);
@@ -1649,8 +1655,8 @@
     var alias = parseFullCompilationUnitMember() as GenericTypeAlias;
     expect(alias, isNotNull);
     assertNoErrors();
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters!.typeParameters, hasLength(3));
     TypeParameter typeParam = alias.typeParameters!.typeParameters[2];
     var type = typeParam.bound as NamedType;
@@ -1666,8 +1672,8 @@
     var alias = parseFullCompilationUnitMember() as GenericTypeAlias;
     expect(alias, isNotNull);
     assertNoErrors();
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters!.typeParameters, hasLength(3));
     TypeParameter typeParam = alias.typeParameters!.typeParameters[2];
     var type = typeParam.bound as NamedType;
@@ -1684,8 +1690,8 @@
     var alias = parseFullCompilationUnitMember() as GenericTypeAlias;
     expect(alias, isNotNull);
     assertNoErrors();
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters!.typeParameters, hasLength(3));
     TypeParameter typeParam = alias.typeParameters!.typeParameters[2];
     var type = typeParam.bound as NamedType;
@@ -1702,8 +1708,8 @@
     var alias = parseFullCompilationUnitMember() as GenericTypeAlias;
     expect(alias, isNotNull);
     assertNoErrors();
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters!.typeParameters, hasLength(3));
     TypeParameter typeParam = alias.typeParameters!.typeParameters[2];
     var type = typeParam.bound as NamedType;
@@ -1721,11 +1727,11 @@
     assertErrors(errors: [
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
     ]);
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters, isNotNull);
     expect(alias.typeParameters!.typeParameters.length, 1);
-    expect(alias.typeParameters!.typeParameters.single.name2.lexeme, '');
+    expect(alias.typeParameters!.typeParameters.single.name.lexeme, '');
     expect(alias.equals, isNotNull);
     expect(alias.functionType, isNotNull);
     expect(alias.semicolon, isNotNull);
@@ -1739,11 +1745,11 @@
     assertErrors(errors: [
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 10, 2),
     ]);
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters, isNotNull);
     expect(alias.typeParameters!.typeParameters.length, 1);
-    expect(alias.typeParameters!.typeParameters.single.name2.lexeme, '');
+    expect(alias.typeParameters!.typeParameters.single.name.lexeme, '');
     expect(alias.equals, isNotNull);
     expect(alias.functionType, isNotNull);
     expect(alias.semicolon, isNotNull);
@@ -1757,11 +1763,11 @@
     assertErrors(errors: [
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 10, 1),
     ]);
-    expect(alias.name2, isNotNull);
-    expect(alias.name2.lexeme, 'F');
+    expect(alias.name, isNotNull);
+    expect(alias.name.lexeme, 'F');
     expect(alias.typeParameters, isNotNull);
     expect(alias.typeParameters!.typeParameters.length, 1);
-    expect(alias.typeParameters!.typeParameters.single.name2.lexeme, '');
+    expect(alias.typeParameters!.typeParameters.single.name.lexeme, '');
     expect(alias.equals, isNotNull);
     expect(alias.functionType, isNotNull);
     expect(alias.semicolon, isNotNull);
@@ -1904,7 +1910,7 @@
     expect(directive, isNotNull);
     assertNoErrors();
     expect(directive.libraryKeyword, isNotNull);
-    expect(directive.name, isNotNull);
+    expect(directive.name2, isNotNull);
     expect(directive.semicolon, isNotNull);
   }
 
@@ -1919,7 +1925,7 @@
     expect(declaration.implementsClause, isNull);
     expect(declaration.mixinKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2.lexeme, 'A');
+    expect(declaration.name.lexeme, 'A');
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -1941,7 +1947,7 @@
     expect(interfaces[0].typeArguments, isNull);
     expect(declaration.mixinKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2.lexeme, 'A');
+    expect(declaration.name.lexeme, 'A');
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -1965,7 +1971,7 @@
     expect(interfaces[1].typeArguments, isNull);
     expect(declaration.mixinKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2.lexeme, 'A');
+    expect(declaration.name.lexeme, 'A');
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -1984,7 +1990,7 @@
     expect(declaration.implementsClause, isNull);
     expect(declaration.mixinKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2.lexeme, 'A');
+    expect(declaration.name.lexeme, 'A');
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -2006,7 +2012,7 @@
     expect(declaration.implementsClause, isNull);
     expect(declaration.mixinKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2.lexeme, 'A');
+    expect(declaration.name.lexeme, 'A');
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -2030,7 +2036,7 @@
     expect(declaration.implementsClause, isNull);
     expect(declaration.mixinKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2.lexeme, 'A');
+    expect(declaration.name.lexeme, 'A');
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -2057,7 +2063,7 @@
     expect(interfaces[0].typeArguments, isNull);
     expect(declaration.mixinKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2.lexeme, 'A');
+    expect(declaration.name.lexeme, 'A');
     expect(declaration.members, hasLength(0));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -2080,7 +2086,7 @@
     expect(declaration.implementsClause, isNull);
     expect(declaration.mixinKeyword, isNotNull);
     expect(declaration.leftBracket, isNotNull);
-    expect(declaration.name2.lexeme, 'A');
+    expect(declaration.name.lexeme, 'A');
     expect(declaration.members, hasLength(4));
     expect(declaration.rightBracket, isNotNull);
     expect(declaration.typeParameters, isNull);
@@ -2209,7 +2215,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.parameters, isNotNull);
     expect(typeAlias.returnType, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
@@ -2222,7 +2228,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.parameters, isNotNull);
     expect(typeAlias.returnType, isNull);
     expect(typeAlias.semicolon, isNotNull);
@@ -2235,7 +2241,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.parameters, isNotNull);
     expect(typeAlias.returnType, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
@@ -2248,7 +2254,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.parameters, isNotNull);
     expect(typeAlias.returnType, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
@@ -2261,7 +2267,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.parameters, isNotNull);
     expect(typeAlias.returnType, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
@@ -2274,7 +2280,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.parameters, isNotNull);
     expect(typeAlias.returnType, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
@@ -2287,7 +2293,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2303,7 +2309,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2319,7 +2325,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2335,7 +2341,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2351,7 +2357,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2367,7 +2373,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2383,7 +2389,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2400,7 +2406,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2416,7 +2422,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2432,7 +2438,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2448,7 +2454,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNotNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
@@ -2464,7 +2470,7 @@
     expect(typeAlias, isNotNull);
     assertNoErrors();
     expect(typeAlias.typedefKeyword, isNotNull);
-    expect(typeAlias.name2, isNotNull);
+    expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNull);
     expect(typeAlias.semicolon, isNotNull);
     var functionType = typeAlias.functionType as GenericFunctionType;
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 0a2372c..1e69349 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -4,7 +4,6 @@
 
 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/ast/utilities.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
@@ -23,35 +22,6 @@
   });
 }
 
-class AstCloneComparator extends AstComparator {
-  final bool expectTokensCopied;
-
-  AstCloneComparator(this.expectTokensCopied);
-
-  @override
-  bool isEqualNodes(AstNode? first, AstNode? second) {
-    if (first != null && identical(first, second)) {
-      fail('Failed to copy node: $first (${first.offset})');
-    }
-    return super.isEqualNodes(first, second);
-  }
-
-  @override
-  bool isEqualTokens(Token? first, Token? second) {
-    if (expectTokensCopied && first != null && identical(first, second)) {
-      fail('Failed to copy token: ${first.lexeme} (${first.offset})');
-    }
-    var firstComment = first?.precedingComments;
-    if (firstComment != null) {
-      if (firstComment.parent != first) {
-        fail(
-            'Failed to link the comment "$firstComment" with the token "$first".');
-      }
-    }
-    return super.isEqualTokens(first, second);
-  }
-}
-
 @reflectiveTest
 class BooleanArrayTest {
   void test_get_negative() {
@@ -1008,8 +978,8 @@
 }
 ''');
     _assertReplacementForChildren<FunctionExpression>(
-      destination: findNode.functionExpression('<T>'),
-      source: findNode.functionExpression('<U>'),
+      destination: findNode.functionExpression('T>'),
+      source: findNode.functionExpression('U>'),
       childAccessors: [
         (node) => node.body,
         (node) => node.parameters!,
@@ -1268,7 +1238,7 @@
       destination: node,
       source: node,
       childAccessors: [
-        (node) => node.name,
+        (node) => node.name2!,
       ],
     );
   }
@@ -1380,20 +1350,6 @@
     );
   }
 
-  void test_nativeClause() {
-    var findNode = _parseStringToFindNode(r'''
-class A native 'foo' {}
-class B native 'bar' {}
-''');
-    _assertReplacementForChildren<NativeClause>(
-      destination: findNode.nativeClause('foo'),
-      source: findNode.nativeClause('bar'),
-      childAccessors: [
-        (node) => node.name!,
-      ],
-    );
-  }
-
   void test_nativeFunctionBody() {
     var findNode = _parseStringToFindNode(r'''
 void f() native 'foo';
@@ -1700,8 +1656,9 @@
     );
   }
 
-  void test_switchCase() {
+  void test_switchCase_language218() {
     var findNode = _parseStringToFindNode(r'''
+// @dart=2.18
 void f() {
   switch (x) {
     foo: bar:
@@ -1736,8 +1693,9 @@
     );
   }
 
-  void test_switchStatement() {
+  void test_switchStatement_language218() {
     var findNode = _parseStringToFindNode(r'''
+// @dart=2.18
 void f() {
   switch (0) {
     case 0: break;
diff --git a/pkg/analyzer/test/generated/variance_parser_test.dart b/pkg/analyzer/test/generated/variance_parser_test.dart
index 358a867..82be47c 100644
--- a/pkg/analyzer/test/generated/variance_parser_test.dart
+++ b/pkg/analyzer/test/generated/variance_parser_test.dart
@@ -64,14 +64,14 @@
     var unit = parseCompilationUnit('class A<in T, inout U, out V, W> { }');
     expect(unit.declarations, hasLength(1));
     var classDecl = unit.declarations[0] as ClassDeclaration;
-    expect(classDecl.name2.lexeme, 'A');
+    expect(classDecl.name.lexeme, 'A');
 
     var typeParameters = classDecl.typeParameters!;
     expect(typeParameters.typeParameters, hasLength(4));
-    expect(typeParameters.typeParameters[0].name2.lexeme, 'T');
-    expect(typeParameters.typeParameters[1].name2.lexeme, 'U');
-    expect(typeParameters.typeParameters[2].name2.lexeme, 'V');
-    expect(typeParameters.typeParameters[3].name2.lexeme, 'W');
+    expect(typeParameters.typeParameters[0].name.lexeme, 'T');
+    expect(typeParameters.typeParameters[1].name.lexeme, 'U');
+    expect(typeParameters.typeParameters[2].name.lexeme, 'V');
+    expect(typeParameters.typeParameters[3].name.lexeme, 'W');
 
     var typeParameterImplList = typeParameters.typeParameters;
     expect((typeParameterImplList[0] as TypeParameterImpl).varianceKeyword,
@@ -100,22 +100,22 @@
     ]);
     expect(unit.declarations, hasLength(1));
     var classDecl = unit.declarations[0] as ClassDeclaration;
-    expect(classDecl.name2.lexeme, 'A');
+    expect(classDecl.name.lexeme, 'A');
 
     var typeParameters = classDecl.typeParameters!;
     expect(typeParameters.typeParameters, hasLength(1));
-    expect(typeParameters.typeParameters[0].name2.lexeme, 'T');
+    expect(typeParameters.typeParameters[0].name.lexeme, 'T');
   }
 
   void test_class_enabled_single() {
     var unit = parseCompilationUnit('class A<in T> { }');
     expect(unit.declarations, hasLength(1));
     var classDecl = unit.declarations[0] as ClassDeclaration;
-    expect(classDecl.name2.lexeme, 'A');
+    expect(classDecl.name.lexeme, 'A');
 
     var typeParameters = classDecl.typeParameters!;
     expect(typeParameters.typeParameters, hasLength(1));
-    expect(typeParameters.typeParameters[0].name2.lexeme, 'T');
+    expect(typeParameters.typeParameters[0].name.lexeme, 'T');
 
     var typeParameterImpl =
         typeParameters.typeParameters[0] as TypeParameterImpl;
@@ -175,11 +175,11 @@
     var unit = parseCompilationUnit('mixin A<inout T> { }');
     expect(unit.declarations, hasLength(1));
     var mixinDecl = unit.declarations[0] as MixinDeclaration;
-    expect(mixinDecl.name2.lexeme, 'A');
+    expect(mixinDecl.name.lexeme, 'A');
 
     var typeParameters = mixinDecl.typeParameters!;
     expect(typeParameters.typeParameters, hasLength(1));
-    expect(typeParameters.typeParameters[0].name2.lexeme, 'T');
+    expect(typeParameters.typeParameters[0].name.lexeme, 'T');
   }
 
   void test_typedef_disabled() {
diff --git a/pkg/analyzer/test/id_tests/inferred_variable_types_test.dart b/pkg/analyzer/test/id_tests/inferred_variable_types_test.dart
index 4208009..e4a4ed6 100644
--- a/pkg/analyzer/test/id_tests/inferred_variable_types_test.dart
+++ b/pkg/analyzer/test/id_tests/inferred_variable_types_test.dart
@@ -50,7 +50,7 @@
   @override
   DartType? computeNodeValue(Id id, AstNode node) {
     if (node is VariableDeclaration) {
-      var element = node.declaredElement2!;
+      var element = node.declaredElement!;
       if (element.hasImplicitType) {
         return element.type;
       }
@@ -60,7 +60,7 @@
         return element.type;
       }
     } else if (node is FunctionDeclarationStatement) {
-      var element = node.functionDeclaration.declaredElement2!;
+      var element = node.functionDeclaration.declaredElement!;
       if (element.hasImplicitReturnType) {
         return element.returnType;
       }
diff --git a/pkg/analyzer/test/id_tests/inheritance_test.dart b/pkg/analyzer/test/id_tests/inheritance_test.dart
index ec2ed4b..6abbf99 100644
--- a/pkg/analyzer/test/id_tests/inheritance_test.dart
+++ b/pkg/analyzer/test/id_tests/inheritance_test.dart
@@ -90,7 +90,7 @@
   void computeForClass(Declaration node, Id? id) {
     super.computeForClass(node, id);
     if (node is ClassDeclaration) {
-      var element = node.declaredElement2!;
+      var element = node.declaredElement!;
 
       void registerMember(
           MemberId id, int offset, Object object, DartType type) {
@@ -102,8 +102,10 @@
       for (var name in interface.map.keys) {
         var executable = interface.map[name]!;
 
-        var enclosingClass = executable.enclosingElement3 as ClassElement;
-        if (enclosingClass.isDartCoreObject) continue;
+        var enclosingClass = executable.enclosingElement as InterfaceElement;
+        if (enclosingClass is ClassElement && enclosingClass.isDartCoreObject) {
+          continue;
+        }
 
         var id = MemberId.internal(
           name.name,
@@ -135,7 +137,7 @@
   @override
   String? computeNodeValue(Id id, AstNode node) {
     if (node is ClassDeclaration) {
-      var cls = node.declaredElement2!;
+      var cls = node.declaredElement!;
       var supertypes = <String>[];
       supertypes.add(supertypeToString(cls.thisType));
       for (var supertype in cls.allSupertypes) {
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index 0666197..735733e 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -12,8 +12,6 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:yaml/yaml.dart';
 
-import '../src/util/yaml_test.dart';
-
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AnalysisOptionsProviderTest);
@@ -95,6 +93,64 @@
   });
 }
 
+bool containsKey(Map<dynamic, YamlNode> map, dynamic key) =>
+    _getValue(map, key) != null;
+
+void expectEquals(YamlNode? actual, YamlNode? expected) {
+  if (expected is YamlScalar) {
+    actual!;
+    expect(actual, TypeMatcher<YamlScalar>());
+    expect(expected.value, actual.value);
+  } else if (expected is YamlList) {
+    if (actual is YamlList) {
+      expect(actual.length, expected.length);
+      List<YamlNode> expectedNodes = expected.nodes;
+      List<YamlNode> actualNodes = actual.nodes;
+      for (int i = 0; i < expectedNodes.length; i++) {
+        expectEquals(actualNodes[i], expectedNodes[i]);
+      }
+    } else {
+      fail('Expected a YamlList, found ${actual.runtimeType}');
+    }
+  } else if (expected is YamlMap) {
+    if (actual is YamlMap) {
+      expect(actual.length, expected.length);
+      Map<dynamic, YamlNode> expectedNodes = expected.nodes;
+      Map<dynamic, YamlNode> actualNodes = actual.nodes;
+      for (var expectedKey in expectedNodes.keys) {
+        if (!containsKey(actualNodes, expectedKey)) {
+          fail('Missing key $expectedKey');
+        }
+      }
+      for (var actualKey in actualNodes.keys) {
+        if (!containsKey(expectedNodes, actualKey)) {
+          fail('Extra key $actualKey');
+        }
+      }
+      for (var expectedKey in expectedNodes.keys) {
+        expectEquals(_getValue(actualNodes, expectedKey),
+            _getValue(expectedNodes, expectedKey));
+      }
+    } else {
+      fail('Expected a YamlMap, found ${actual.runtimeType}');
+    }
+  } else {
+    fail('Unknown type of node: ${expected.runtimeType}');
+  }
+}
+
+Object valueOf(Object object) => object is YamlNode ? object.value : object;
+
+YamlNode? _getValue(Map map, Object key) {
+  Object keyValue = valueOf(key);
+  for (var existingKey in map.keys) {
+    if (valueOf(existingKey) == keyValue) {
+      return map[existingKey];
+    }
+  }
+  return null;
+}
+
 @reflectiveTest
 class AnalysisOptionsProviderTest with ResourceProviderMixin {
   String get analysisOptionsYaml => file_paths.analysisOptionsYaml;
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 ff6839e..e9b5f04 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -41,11 +41,6 @@
     assertType(element.type, expected);
   }
 
-  void assertDeclaredVariableTypeObject(SimpleIdentifier node) {
-    var element = node.staticElement as VariableElement;
-    expect(element.type, typeProvider.objectType);
-  }
-
   /// Test that [argumentList] has exactly two type items `int` and `double`.
   void assertTypeArguments(
       TypeArgumentList argumentList, List<InterfaceType> expectedTypes) {
@@ -144,7 +139,7 @@
     var myDeclaration =
         result.unit.declarations[0] as TopLevelVariableDeclaration;
     var myVariable = myDeclaration.variables.variables[0];
-    var myElement = myVariable.declaredElement2 as TopLevelVariableElement;
+    var myElement = myVariable.declaredElement as TopLevelVariableElement;
 
     void assertMyAnnotation(AnnotatedNode node) {
       Annotation annotation = node.metadata[0];
@@ -352,7 +347,7 @@
 
     var c = result.unit.declarations[0] as ClassDeclaration;
     var constructor = c.members[1] as ConstructorDeclaration;
-    ConstructorElement element = constructor.declaredElement2!;
+    ConstructorElement element = constructor.declaredElement!;
 
     var main = result.unit.declarations[1] as FunctionDeclaration;
     var statement = (main.functionExpression.body as BlockFunctionBody)
@@ -362,7 +357,7 @@
     expect(annotation.element, same(element));
 
     var identifier_1 = annotation.name as SimpleIdentifier;
-    expect(identifier_1.staticElement, same(c.declaredElement2));
+    expect(identifier_1.staticElement, same(c.declaredElement));
   }
 
   test_annotation_onVariableList_topLevelVariable() async {
@@ -383,7 +378,7 @@
     var myDeclaration =
         result.unit.declarations[0] as TopLevelVariableDeclaration;
     VariableDeclaration myVariable = myDeclaration.variables.variables[0];
-    var myElement = myVariable.declaredElement2 as TopLevelVariableElement;
+    var myElement = myVariable.declaredElement as TopLevelVariableElement;
 
     var classNode = result.unit.declarations[1] as ClassDeclaration;
     var node = classNode.members[0] as MethodDeclaration;
@@ -661,9 +656,9 @@
 f() {}
 ''');
     await resolveTestFile();
-    var elementC = AstFinder.getClass(result.unit, 'C').declaredElement2!;
+    var elementC = AstFinder.getClass(result.unit, 'C').declaredElement!;
     var constructorC = elementC.constructors[0];
-    var elementD = AstFinder.getClass(result.unit, 'D').declaredElement2!;
+    var elementD = AstFinder.getClass(result.unit, 'D').declaredElement!;
     var constructorD = elementD.constructors[0];
     var atD = AstFinder.getTopLevelFunction(result.unit, 'f').metadata[0];
     var constC = atD.arguments!.arguments[0] as InstanceCreationExpression;
@@ -695,12 +690,12 @@
     var declaration_1 =
         result.unit.declarations[0] as TopLevelVariableDeclaration;
     VariableDeclaration variable_1 = declaration_1.variables.variables[0];
-    var element_1 = variable_1.declaredElement2 as TopLevelVariableElement;
+    var element_1 = variable_1.declaredElement as TopLevelVariableElement;
 
     var declaration_2 =
         result.unit.declarations[1] as TopLevelVariableDeclaration;
     VariableDeclaration variable_2 = declaration_2.variables.variables[0];
-    var element_2 = variable_2.declaredElement2 as TopLevelVariableElement;
+    var element_2 = variable_2.declaredElement as TopLevelVariableElement;
 
     var main = result.unit.declarations[2] as FunctionDeclaration;
 
@@ -733,7 +728,7 @@
     VariableElement vElement;
     {
       var statement = statements[0] as VariableDeclarationStatement;
-      vElement = statement.variables.variables[0].declaredElement2!;
+      vElement = statement.variables.variables[0].declaredElement!;
       expect(vElement.type, typeProvider.numType);
     }
 
@@ -780,7 +775,7 @@
 
     var statement = mainStatements[0] as VariableDeclarationStatement;
     VariableDeclaration vNode = statement.variables.variables[0];
-    VariableElement vElement = vNode.declaredElement2!;
+    VariableElement vElement = vNode.declaredElement!;
     expect(vElement.type, typeProvider.intType);
 
     var value = vNode.initializer as BinaryExpression;
@@ -956,12 +951,12 @@
     await resolveTestFile();
 
     var mainDeclaration = result.unit.declarations[0] as FunctionDeclaration;
-    var mainElement = mainDeclaration.declaredElement2 as FunctionElement;
+    var mainElement = mainDeclaration.declaredElement as FunctionElement;
     var mainBody = mainDeclaration.functionExpression.body as BlockFunctionBody;
     List<Statement> mainStatements = mainBody.block.statements;
 
     var itemsStatement = mainStatements[0] as VariableDeclarationStatement;
-    var itemsElement = itemsStatement.variables.variables[0].declaredElement2!;
+    var itemsElement = itemsStatement.variables.variables[0].declaredElement!;
 
     // First closure.
     ParameterElement itemElement1;
@@ -977,7 +972,7 @@
           forInvocation.argumentList.arguments[0] as FunctionExpression;
 
       var closureElement = closure.declaredElement as FunctionElementImpl;
-      expect(closureElement.enclosingElement3, same(mainElement));
+      expect(closureElement.enclosingElement, same(mainElement));
 
       ParameterElement itemElement = closureElement.parameters[0];
       itemElement1 = itemElement;
@@ -1018,7 +1013,7 @@
           forInvocation.argumentList.arguments[0] as FunctionExpression;
 
       var closureElement = closure.declaredElement as FunctionElementImpl;
-      expect(closureElement.enclosingElement3, same(mainElement));
+      expect(closureElement.enclosingElement, same(mainElement));
 
       ParameterElement itemElement = closureElement.parameters[0];
       expect(itemElement, isNot(same(itemElement1)));
@@ -1061,7 +1056,7 @@
     assertType(closure, 'List<T> Function<T>()');
 
     var closureElement = closure.declaredElement as FunctionElementImpl;
-    expect(closureElement.enclosingElement3, findElement.function('main'));
+    expect(closureElement.enclosingElement, findElement.function('main'));
     assertType(closureElement.returnType, 'List<T>');
     expect(closureElement.parameters, isEmpty);
 
@@ -1163,7 +1158,7 @@
     var cNode = result.unit.declarations[0] as ClassDeclaration;
 
     var constructorNode = cNode.members[0] as ConstructorDeclaration;
-    ParameterElement pElement = constructorNode.declaredElement2!.parameters[0];
+    ParameterElement pElement = constructorNode.declaredElement!.parameters[0];
 
     var constructorBody = constructorNode.body as BlockFunctionBody;
     var pStatement = constructorBody.block.statements[0] as ExpressionStatement;
@@ -1185,12 +1180,12 @@
     await resolveTestFile();
 
     var cNode = result.unit.declarations[0] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
     FieldElement fElement = cElement.getField('f')!;
 
     var constructorNode = cNode.members[1] as ConstructorDeclaration;
     ParameterElement pParameterElement =
-        constructorNode.declaredElement2!.parameters[0];
+        constructorNode.declaredElement!.parameters[0];
 
     {
       var initializer =
@@ -1216,7 +1211,7 @@
     await resolveTestFile();
 
     var aNode = result.unit.declarations[0] as ClassDeclaration;
-    ClassElement aElement = aNode.declaredElement2!;
+    ClassElement aElement = aNode.declaredElement!;
 
     var bNode = result.unit.declarations[1] as ClassDeclaration;
 
@@ -1258,7 +1253,7 @@
     await resolveTestFile();
 
     var cNode = result.unit.declarations[0] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
 
     {
       var unnamedConstructor = cElement.constructors[0];
@@ -1309,7 +1304,7 @@
     expect(result.errors, isEmpty);
 
     var aNode = result.unit.declarations[0] as ClassDeclaration;
-    ClassElement aElement = aNode.declaredElement2!;
+    ClassElement aElement = aNode.declaredElement!;
 
     var bNode = result.unit.declarations[1] as ClassDeclaration;
 
@@ -1317,7 +1312,7 @@
       ConstructorElement aUnnamed = aElement.constructors[0];
 
       var constructor = bNode.members[0] as ConstructorDeclaration;
-      ConstructorElement element = constructor.declaredElement2!;
+      ConstructorElement element = constructor.declaredElement!;
       expect(element.redirectedConstructor, same(aUnnamed));
 
       var constructorName = constructor.redirectedConstructor!;
@@ -1337,7 +1332,7 @@
       ConstructorElement aNamed = aElement.constructors[1];
 
       var constructor = bNode.members[1] as ConstructorDeclaration;
-      ConstructorElement element = constructor.declaredElement2!;
+      ConstructorElement element = constructor.declaredElement!;
       expect(element.redirectedConstructor, same(aNamed));
 
       var constructorName = constructor.redirectedConstructor!;
@@ -1370,11 +1365,11 @@
     expect(result.errors, isEmpty);
 
     var aNode = result.unit.declarations[0] as ClassDeclaration;
-    ClassElement aElement = aNode.declaredElement2!;
+    ClassElement aElement = aNode.declaredElement!;
 
     var bNode = result.unit.declarations[1] as ClassDeclaration;
     TypeParameterType uType =
-        typeParameterTypeNone(bNode.declaredElement2!.typeParameters[0]);
+        typeParameterTypeNone(bNode.declaredElement!.typeParameters[0]);
     InterfaceType auType = aElement.instantiate(
       typeArguments: [uType],
       nullabilitySuffix: NullabilitySuffix.none,
@@ -1384,7 +1379,7 @@
       ConstructorElement expectedElement = aElement.constructors[0];
 
       var constructor = bNode.members[0] as ConstructorDeclaration;
-      ConstructorElement element = constructor.declaredElement2!;
+      ConstructorElement element = constructor.declaredElement!;
 
       var actualMember = element.redirectedConstructor!;
       assertMember(actualMember, expectedElement, {'T': 'U'});
@@ -1406,7 +1401,7 @@
       ConstructorElement expectedElement = aElement.constructors[1];
 
       var constructor = bNode.members[1] as ConstructorDeclaration;
-      ConstructorElement element = constructor.declaredElement2!;
+      ConstructorElement element = constructor.declaredElement!;
 
       var actualMember = element.redirectedConstructor!;
       assertMember(actualMember, expectedElement, {'T': 'U'});
@@ -1707,7 +1702,7 @@
 
     var methodElement = invocation.methodName.staticElement as MethodElement;
     expect(methodElement.name, 'toString');
-    expect(methodElement.enclosingElement3, same(objectElement));
+    expect(methodElement.enclosingElement, same(objectElement));
   }
 
   test_error_unresolvedTypeAnnotation() async {
@@ -1728,11 +1723,7 @@
     expect(namedType.typeArguments!.arguments[0].type, typeProvider.intType);
 
     VariableDeclaration vNode = statement.variables.variables[0];
-
-    // ignore: deprecated_member_use_from_same_package
-    expect(vNode.name.staticType, isNull);
-    // ignore: deprecated_member_use_from_same_package
-    expect(vNode.declaredElement2!.type, isDynamicType);
+    expect(vNode.declaredElement!.type, isDynamicType);
   }
 
   test_field_context() async {
@@ -1744,11 +1735,11 @@
     await resolveTestFile();
 
     var cNode = result.unit.declarations[0] as ClassDeclaration;
-    var tElement = cNode.declaredElement2!.typeParameters[0];
+    var tElement = cNode.declaredElement!.typeParameters[0];
 
     var fDeclaration = cNode.members[0] as FieldDeclaration;
     VariableDeclaration fNode = fDeclaration.fields.variables[0];
-    var fElement = fNode.declaredElement2 as FieldElement;
+    var fElement = fNode.declaredElement as FieldElement;
     expect(
         fElement.type, typeProvider.listType(typeParameterTypeNone(tElement)));
   }
@@ -1790,8 +1781,7 @@
     List<FormalParameter> parameters = constructor.parameters.parameters;
 
     var p = parameters[0] as FunctionTypedFormalParameter;
-    expect(
-        p.declaredElement, same(constructor.declaredElement2!.parameters[0]));
+    expect(p.declaredElement, same(constructor.declaredElement!.parameters[0]));
 
     {
       var type = (p.declaredElement as ParameterElement).type as FunctionType;
@@ -1823,11 +1813,11 @@
 
     var fDeclaration = clazz.members[0] as FieldDeclaration;
     VariableDeclaration fNode = fDeclaration.fields.variables[0];
-    var fElement = fNode.declaredElement2 as FieldElement;
+    var fElement = fNode.declaredElement as FieldElement;
 
     var constructor = clazz.members[1] as ConstructorDeclaration;
 
-    var pElement = constructor.declaredElement2!.parameters[0]
+    var pElement = constructor.declaredElement!.parameters[0]
         as FieldFormalParameterElement;
     expect(pElement.field, same(fElement));
 
@@ -1856,12 +1846,12 @@
 
     var fDeclaration = clazz.members[0] as FieldDeclaration;
     VariableDeclaration fNode = fDeclaration.fields.variables[0];
-    var fElement = fNode.declaredElement2 as FieldElement;
+    var fElement = fNode.declaredElement as FieldElement;
 
     var constructor = clazz.members[1] as ConstructorDeclaration;
     List<FormalParameter> parameters = constructor.parameters.parameters;
 
-    var parameterElement = constructor.declaredElement2!.parameters[0]
+    var parameterElement = constructor.declaredElement!.parameters[0]
         as FieldFormalParameterElement;
     expect(parameterElement.field, same(fElement));
 
@@ -1883,12 +1873,12 @@
 
     var fDeclaration = clazz.members[0] as FieldDeclaration;
     VariableDeclaration fNode = fDeclaration.fields.variables[0];
-    var fElement = fNode.declaredElement2 as FieldElement;
+    var fElement = fNode.declaredElement as FieldElement;
 
     var constructor = clazz.members[1] as ConstructorDeclaration;
     List<FormalParameter> parameters = constructor.parameters.parameters;
 
-    var parameterElement = constructor.declaredElement2!.parameters[0]
+    var parameterElement = constructor.declaredElement!.parameters[0]
         as FieldFormalParameterElement;
     expect(parameterElement.field, same(fElement));
 
@@ -1910,7 +1900,7 @@
     await resolveTestFile();
 
 //    var aNode = result.unit!.declarations[0] as ClassDeclaration;
-//    ClassElement eElement = aNode.declaredElement2!;
+//    ClassElement eElement = aNode.declaredElement!;
 //    MethodElement mElement = eElement.getMethod('m');
 
     List<Statement> mainStatements = _getMainStatements(result);
@@ -1979,13 +1969,12 @@
 }
 ''');
     await resolveTestFile();
-    assertTypeNull(findNode.simple('f;'));
     var fType = findElement.localVar('f').type as FunctionType;
     var fTypeTypeParameter = fType.typeFormals[0];
     var fTypeParameter = fType.normalParameterTypes[0] as TypeParameterType;
     expect(fTypeParameter.element2, same(fTypeTypeParameter));
-    var tRef = findNode.simple('T>');
-    var functionTypeNode = tRef.parent!.parent!.parent as GenericFunctionType;
+    var tRef = findNode.typeParameter('T>');
+    var functionTypeNode = tRef.parent!.parent as GenericFunctionType;
     var functionType = functionTypeNode.type as FunctionType;
     assertElement(tRef, functionType.typeFormals[0]);
   }
@@ -2010,7 +1999,7 @@
     {
       var statement = mainStatements[0] as VariableDeclarationStatement;
       VariableDeclaration itemsNode = statement.variables.variables[0];
-      itemsElement = itemsNode.declaredElement2!;
+      itemsElement = itemsNode.declaredElement!;
       expect(itemsElement.type, listIntType);
     }
 
@@ -2041,7 +2030,7 @@
     CompilationUnit unit = result.unit;
 
     var cNode = unit.declarations[0] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
     ConstructorElement defaultConstructor = cElement.constructors[0];
     ConstructorElement namedConstructor = cElement.constructors[1];
 
@@ -2094,7 +2083,7 @@
     CompilationUnit unit = result.unit;
 
     var xNode = unit.declarations[0] as ClassDeclaration;
-    ClassElement xElement = xNode.declaredElement2!;
+    ClassElement xElement = xNode.declaredElement!;
     ConstructorElement constructorElement = xElement.constructors[0];
 
     var vDeclaration = unit.declarations[1] as TopLevelVariableDeclaration;
@@ -2135,7 +2124,7 @@
     CompilationUnit unit = result.unit;
 
     var cNode = unit.declarations[0] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
     ConstructorElement defaultConstructor = cElement.constructors[0];
     ConstructorElement namedConstructor = cElement.constructors[1];
 
@@ -2579,8 +2568,14 @@
     await resolveTestFile();
     expect(result.errors, isNotEmpty);
 
-    assertDeclaredVariableTypeObject(findNode.simple('x,'));
-    assertDeclaredVariableType(findNode.simple('y,'), 'StackTrace');
+    assertType(
+      findNode.catchClauseParameter('x,').declaredElement!.type,
+      'Object',
+    );
+    assertType(
+      findNode.catchClauseParameter('y,').declaredElement!.type,
+      'StackTrace',
+    );
   }
 
   test_invalid_catch_parameters_empty() async {
@@ -2602,8 +2597,14 @@
     await resolveTestFile();
     expect(result.errors, isNotEmpty);
 
-    assertDeclaredVariableTypeObject(findNode.simple('e,'));
-    assertDeclaredVariableType(findNode.simple('s})'), 'StackTrace');
+    assertType(
+      findNode.catchClauseParameter('e,').declaredElement!.type,
+      'Object',
+    );
+    assertType(
+      findNode.catchClauseParameter('s}').declaredElement!.type,
+      'StackTrace',
+    );
   }
 
   test_invalid_catch_parameters_optional_stack() async {
@@ -2615,8 +2616,14 @@
     await resolveTestFile();
     expect(result.errors, isNotEmpty);
 
-    assertDeclaredVariableTypeObject(findNode.simple('e,'));
-    assertDeclaredVariableType(findNode.simple('s])'), 'StackTrace');
+    assertType(
+      findNode.catchClauseParameter('e,').declaredElement!.type,
+      'Object',
+    );
+    assertType(
+      findNode.catchClauseParameter('s]').declaredElement!.type,
+      'StackTrace',
+    );
   }
 
   test_invalid_const_as() async {
@@ -3767,7 +3774,7 @@
     expect(result.errors, isNotEmpty);
 
     var tRef = findNode.simple('T.U v;');
-    var tElement = findNode.typeParameter('T>()').declaredElement2!;
+    var tElement = findNode.typeParameter('T>()').declaredElement!;
     assertElement(tRef, tElement);
     assertTypeDynamic(tRef);
   }
@@ -3958,15 +3965,10 @@
     var fStatement = mainStatements[0] as FunctionDeclarationStatement;
     FunctionDeclaration fNode = fStatement.functionDeclaration;
     FunctionExpression fExpression = fNode.functionExpression;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
     expect(fElement, isNotNull);
     assertType(fElement.type, fTypeString);
 
-    // ignore: deprecated_member_use_from_same_package
-    expect(fNode.name.staticElement, same(fElement));
-    // ignore: deprecated_member_use_from_same_package
-    expect(fNode.name.staticType, isNull);
-
     var fReturnTypeNode = fNode.returnType as NamedType;
     expect(fReturnTypeNode.name.staticElement, same(doubleType.element2));
     expect(fReturnTypeNode.type, doubleType);
@@ -3995,7 +3997,7 @@
 
     var vStatement = mainStatements[1] as VariableDeclarationStatement;
     VariableDeclaration vDeclaration = vStatement.variables.variables[0];
-    expect(vDeclaration.declaredElement2!.type, doubleType);
+    expect(vDeclaration.declaredElement!.type, doubleType);
 
     var fInvocation = vDeclaration.initializer as MethodInvocation;
     expect(fInvocation.methodName.staticElement, same(fElement));
@@ -4036,7 +4038,7 @@
     var fStatement = mainStatements[0] as FunctionDeclarationStatement;
     FunctionDeclaration fNode = fStatement.functionDeclaration;
     FunctionExpression fExpression = fNode.functionExpression;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
 
     TypeParameterElement tElement = fElement.typeParameters[0];
     TypeParameterElement uElement = fElement.typeParameters[1];
@@ -4046,28 +4048,15 @@
       expect(fTypeParameters, hasLength(2));
 
       TypeParameter tNode = fTypeParameters[0];
-      expect(tNode.declaredElement2, same(tElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(tNode.name.staticElement, same(tElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(tNode.name.staticType, typeProvider.typeType);
+      expect(tNode.declaredElement, same(tElement));
 
       TypeParameter uNode = fTypeParameters[1];
-      expect(uNode.declaredElement2, same(uElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(uNode.name.staticElement, same(uElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(uNode.name.staticType, typeProvider.typeType);
+      expect(uNode.declaredElement, same(uElement));
     }
 
     expect(fElement, isNotNull);
     assertType(fElement.type, 'T Function<T,U>(T, U)');
 
-    // ignore: deprecated_member_use_from_same_package
-    expect(fNode.name.staticElement, same(fElement));
-    // ignore: deprecated_member_use_from_same_package
-    expect(fNode.name.staticType, fElement.type);
-
     var fReturnTypeNode = fNode.returnType as NamedType;
     expect(fReturnTypeNode.name.staticElement, same(tElement));
     expect(fReturnTypeNode.type, typeParameterTypeStar(tElement));
@@ -4104,7 +4093,7 @@
 
     var vStatement = mainStatements[1] as VariableDeclarationStatement;
     VariableDeclaration vDeclaration = vStatement.variables.variables[0];
-    expect(vDeclaration.declaredElement2!.type, typeProvider.intType);
+    expect(vDeclaration.declaredElement!.type, typeProvider.intType);
 
     var fInvocation = vDeclaration.initializer as MethodInvocation;
     expect(fInvocation.methodName.staticElement, same(fElement));
@@ -4125,7 +4114,7 @@
 
     var fStatement = mainStatements[0] as FunctionDeclarationStatement;
     FunctionDeclaration fNode = fStatement.functionDeclaration;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
 
     assertType(
         fElement.type, 'void Function<T extends U, U, V extends U>(T, U, V)');
@@ -4147,7 +4136,7 @@
 
     var fStatement = mainStatements[0] as FunctionDeclarationStatement;
     FunctionDeclaration fNode = fStatement.functionDeclaration;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
 
     assertType(fElement.type, 'void Function<T>({T x})');
     var tElement = fElement.typeParameters[0];
@@ -4167,7 +4156,7 @@
 
     var fStatement = mainStatements[0] as FunctionDeclarationStatement;
     FunctionDeclaration fNode = fStatement.functionDeclaration;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
 
     assertType(fElement.type, 'void Function<T>([T])');
     var tElement = fElement.typeParameters[0];
@@ -4193,15 +4182,10 @@
     var fStatement = mainStatements[0] as FunctionDeclarationStatement;
     FunctionDeclaration fNode = fStatement.functionDeclaration;
     FunctionExpression fExpression = fNode.functionExpression;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
     expect(fElement, isNotNull);
     assertType(fElement.type, fTypeString);
 
-    // ignore: deprecated_member_use_from_same_package
-    expect(fNode.name.staticElement, same(fElement));
-    // ignore: deprecated_member_use_from_same_package
-    expect(fNode.name.staticType, isNull);
-
     var fReturnTypeNode = fNode.returnType as NamedType;
     expect(fReturnTypeNode.name.staticElement, same(doubleType.element2));
     expect(fReturnTypeNode.type, doubleType);
@@ -4258,17 +4242,12 @@
     var fStatement = mainStatements[0] as FunctionDeclarationStatement;
     FunctionDeclaration fNode = fStatement.functionDeclaration;
     FunctionExpression fExpression = fNode.functionExpression;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
 
     expect(fNode.returnType, isNull);
     expect(fElement, isNotNull);
     assertType(fElement.type, 'Null Function()');
 
-    // ignore: deprecated_member_use_from_same_package
-    expect(fNode.name.staticElement, same(fElement));
-    // ignore: deprecated_member_use_from_same_package
-    expect(fNode.name.staticType, isNull);
-
     expect(fExpression.declaredElement, same(fElement));
   }
 
@@ -4289,15 +4268,10 @@
     var fStatement = mainStatements[0] as FunctionDeclarationStatement;
     FunctionDeclaration fNode = fStatement.functionDeclaration;
     FunctionExpression fExpression = fNode.functionExpression;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
     expect(fElement, isNotNull);
     assertType(fElement.type, fTypeString);
 
-    // ignore: deprecated_member_use_from_same_package
-    expect(fNode.name.staticElement, same(fElement));
-    // ignore: deprecated_member_use_from_same_package
-    expect(fNode.name.staticType, isNull);
-
     var fReturnTypeNode = fNode.returnType as NamedType;
     expect(fReturnTypeNode.name.staticElement, same(doubleType.element2));
     expect(fReturnTypeNode.type, doubleType);
@@ -4333,7 +4307,7 @@
     {
       var statement = mainStatements[1] as VariableDeclarationStatement;
       VariableDeclaration declaration = statement.variables.variables[0];
-      expect(declaration.declaredElement2!.type, doubleType);
+      expect(declaration.declaredElement!.type, doubleType);
 
       var invocation = declaration.initializer as MethodInvocation;
       expect(invocation.methodName.staticElement, same(fElement));
@@ -4358,8 +4332,7 @@
 }
 ''');
     await resolveTestFile();
-    var callbackIdentifier = findNode.simple('callback<');
-    var callbackElement = callbackIdentifier.staticElement as ParameterElement;
+    var callbackElement = findElement.parameter('callback');
     assertType(callbackElement.type, 'C Function<T extends E>(D)');
     var cReference = findNode.simple('C callback');
     var cElement = findElement.class_('C');
@@ -4386,7 +4359,7 @@
     List<Statement> statements = _getMainStatements(result);
 
     // (int p)
-    VariableElement pElement = main.declaredElement2!.parameters[0];
+    VariableElement pElement = main.declaredElement!.parameters[0];
     expect(pElement.type, listNone(typeProvider.stringType));
 
     // p;
@@ -4417,7 +4390,7 @@
     var fStatement = mainStatements[0] as FunctionDeclarationStatement;
     FunctionDeclaration fNode = fStatement.functionDeclaration;
     FunctionExpression fExpression = fNode.functionExpression;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
     ParameterElement aElement = fElement.parameters[0];
     _assertSimpleParameter(
         fExpression.parameters!.parameters[0] as SimpleFormalParameter,
@@ -4440,7 +4413,7 @@
     var gStatement = fStatements[1] as FunctionDeclarationStatement;
     FunctionDeclaration gNode = gStatement.functionDeclaration;
     FunctionExpression gExpression = gNode.functionExpression;
-    var gElement = gNode.declaredElement2 as FunctionElement;
+    var gElement = gNode.declaredElement as FunctionElement;
     ParameterElement bElement = gElement.parameters[0];
     _assertSimpleParameter(
         gExpression.parameters!.parameters[0] as SimpleFormalParameter,
@@ -4473,7 +4446,7 @@
 
     var mainStatements = _getMainStatements(result);
     var fDeclaration = mainStatements[0] as FunctionDeclarationStatement;
-    var fElement = fDeclaration.functionDeclaration.declaredElement2!;
+    var fElement = fDeclaration.functionDeclaration.declaredElement!;
     var tElement = fElement.typeParameters[0];
     var body = fDeclaration.functionDeclaration.functionExpression.body
         as BlockFunctionBody;
@@ -4496,7 +4469,7 @@
 
     var mainStatements = _getMainStatements(result);
     var fDeclaration = mainStatements[0] as FunctionDeclarationStatement;
-    var fElement = fDeclaration.functionDeclaration.declaredElement2!;
+    var fElement = fDeclaration.functionDeclaration.declaredElement!;
     var tElement = fElement.typeParameters[0];
     var body = fDeclaration.functionDeclaration.functionExpression.body
         as BlockFunctionBody;
@@ -4528,7 +4501,7 @@
 
     var mainStatements = _getMainStatements(result);
     var fDeclaration = mainStatements[0] as FunctionDeclarationStatement;
-    var fElement = fDeclaration.functionDeclaration.declaredElement2!;
+    var fElement = fDeclaration.functionDeclaration.declaredElement!;
     var tElement = fElement.typeParameters[0];
     var body = fDeclaration.functionDeclaration.functionExpression.body
         as BlockFunctionBody;
@@ -4559,7 +4532,7 @@
 
     var mainStatements = _getMainStatements(result);
     var fDeclaration = mainStatements[0] as FunctionDeclarationStatement;
-    var fElement = fDeclaration.functionDeclaration.declaredElement2!;
+    var fElement = fDeclaration.functionDeclaration.declaredElement!;
     var tElement = fElement.typeParameters[0];
     var body = fDeclaration.functionDeclaration.functionExpression.body
         as BlockFunctionBody;
@@ -4591,7 +4564,7 @@
 
     var mainStatements = _getMainStatements(result);
     var fDeclaration = mainStatements[0] as FunctionDeclarationStatement;
-    var fElement = fDeclaration.functionDeclaration.declaredElement2!;
+    var fElement = fDeclaration.functionDeclaration.declaredElement!;
     var tElement = fElement.typeParameters[0];
     var body = fDeclaration.functionDeclaration.functionExpression.body
         as BlockFunctionBody;
@@ -4619,7 +4592,7 @@
 
     var mainStatements = _getMainStatements(result);
     var fDeclaration = mainStatements[0] as FunctionDeclarationStatement;
-    var fElement = fDeclaration.functionDeclaration.declaredElement2!;
+    var fElement = fDeclaration.functionDeclaration.declaredElement!;
     var tElement = fElement.typeParameters[0];
     var body = fDeclaration.functionDeclaration.functionExpression.body
         as BlockFunctionBody;
@@ -4647,7 +4620,7 @@
 
     var mainStatements = _getMainStatements(result);
     var fDeclaration = mainStatements[0] as FunctionDeclarationStatement;
-    var fElement = fDeclaration.functionDeclaration.declaredElement2!;
+    var fElement = fDeclaration.functionDeclaration.declaredElement!;
     var tElement = fElement.typeParameters[0];
     var body = fDeclaration.functionDeclaration.functionExpression.body
         as BlockFunctionBody;
@@ -4670,7 +4643,7 @@
 ''');
     await resolveTestFile();
 
-    var tElement = findNode.typeParameter('T>(T x)').declaredElement2!;
+    var tElement = findNode.typeParameter('T>(T x)').declaredElement!;
 
     var gType = findNode.namedType('Consumer<T>');
     var gTypeType = gType.type as FunctionType;
@@ -4697,7 +4670,7 @@
 ''');
     await resolveTestFile();
 
-    var tElement = findNode.typeParameter('T>(T x)').declaredElement2!;
+    var tElement = findNode.typeParameter('T>(T x)').declaredElement!;
 
     var gType = findNode.namedType('Consumer<T>');
     var gTypeType = gType.type as FunctionType;
@@ -4724,7 +4697,7 @@
 ''');
     await resolveTestFile();
 
-    var tElement = findNode.typeParameter('T>(T x)').declaredElement2!;
+    var tElement = findNode.typeParameter('T>(T x)').declaredElement!;
 
     var gType = findNode.namedType('Consumer<T>');
     var gTypeType = gType.type as FunctionType;
@@ -4751,7 +4724,7 @@
 ''');
     await resolveTestFile();
 
-    var tElement = findNode.typeParameter('T>(T x)').declaredElement2!;
+    var tElement = findNode.typeParameter('T>(T x)').declaredElement!;
 
     var gType = findNode.namedType('Producer<T>');
     var gTypeType = gType.type as FunctionType;
@@ -4776,12 +4749,7 @@
     InterfaceType intType = typeProvider.intType;
 
     var main = result.unit.declarations[0] as FunctionDeclaration;
-    expect(main.declaredElement2, isNotNull);
-
-    // ignore: deprecated_member_use_from_same_package
-    expect(main.name.staticElement, isNotNull);
-    // ignore: deprecated_member_use_from_same_package
-    expect(main.name.staticType, isNull);
+    expect(main.declaredElement, isNotNull);
 
     var body = main.functionExpression.body as BlockFunctionBody;
     NodeList<Statement> statements = body.block.statements;
@@ -4791,11 +4759,9 @@
     {
       var statement = statements[0] as VariableDeclarationStatement;
       VariableDeclaration vNode = statement.variables.variables[0];
-      // ignore: deprecated_member_use_from_same_package
-      expect(vNode.name.staticType, isNull);
       expect(vNode.initializer!.staticType, intType);
 
-      vElement = vNode.declaredElement2!;
+      vElement = vNode.declaredElement!;
       expect(vElement, isNotNull);
       expect(vElement.type, isNotNull);
       expect(vElement.type, intType);
@@ -4828,7 +4794,7 @@
 
     var vDeclaration = cDeclaration.members[0] as FieldDeclaration;
     VariableDeclaration vNode = vDeclaration.fields.variables[0];
-    var vElement = vNode.declaredElement2 as FieldElement;
+    var vElement = vNode.declaredElement as FieldElement;
     expect(vElement.type, typeProvider.numType);
 
     var fooDeclaration = cDeclaration.members[1] as MethodDeclaration;
@@ -4865,7 +4831,7 @@
 
     var vStatement = statements[0] as VariableDeclarationStatement;
     VariableDeclaration vNode = vStatement.variables.variables[0];
-    var vElement = vNode.declaredElement2 as LocalVariableElement;
+    var vElement = vNode.declaredElement as LocalVariableElement;
     expect(vElement.type, typeProvider.numType);
 
     var forEachStatement = statements[1] as ForStatement;
@@ -4899,7 +4865,7 @@
 
     var vDeclaration = unit.declarations[1] as TopLevelVariableDeclaration;
     VariableDeclaration vNode = vDeclaration.variables.variables[0];
-    var vElement = vNode.declaredElement2 as TopLevelVariableElement;
+    var vElement = vNode.declaredElement as TopLevelVariableElement;
     expect(vElement.type, typeProvider.numType);
 
     var forEachStatement = statements[0] as ForStatement;
@@ -4935,14 +4901,9 @@
         forEachStatement.forLoopParts as ForEachPartsWithDeclaration;
 
     DeclaredIdentifier vNode = forEachParts.loopVariable;
-    LocalVariableElement vElement = vNode.declaredElement2!;
+    LocalVariableElement vElement = vNode.declaredElement!;
     expect(vElement.type, typeProvider.intType);
 
-    // ignore: deprecated_member_use_from_same_package
-    expect(vNode.identifier.staticElement, vElement);
-    // ignore: deprecated_member_use_from_same_package
-    expect(vNode.identifier.staticType, isNull);
-
     var statement = forBlock.statements[0] as ExpressionStatement;
     var identifier = statement.expression as SimpleIdentifier;
     expect(identifier.staticElement, vElement);
@@ -4967,7 +4928,7 @@
         forEachStatement.forLoopParts as ForEachPartsWithDeclaration;
 
     DeclaredIdentifier vNode = forEachParts.loopVariable;
-    LocalVariableElement vElement = vNode.declaredElement2!;
+    LocalVariableElement vElement = vNode.declaredElement!;
     expect(vElement.type, typeProvider.numType);
 
     var vNamedType = vNode.type as NamedType;
@@ -4977,11 +4938,6 @@
     expect(vTypeIdentifier.staticElement, typeProvider.numType.element2);
     expect(vTypeIdentifier.staticType, isNull);
 
-    // ignore: deprecated_member_use_from_same_package
-    expect(vNode.identifier.staticElement, vElement);
-    // ignore: deprecated_member_use_from_same_package
-    expect(vNode.identifier.staticType, isNull);
-
     var statement = forBlock.statements[0] as ExpressionStatement;
     var identifier = statement.expression as SimpleIdentifier;
     expect(identifier.staticElement, vElement);
@@ -5001,11 +4957,11 @@
     var declarationStatement = statements[0] as VariableDeclarationStatement;
 
     VariableDeclaration aNode = declarationStatement.variables.variables[0];
-    var aElement = aNode.declaredElement2 as LocalVariableElement;
+    var aElement = aNode.declaredElement as LocalVariableElement;
     expect(aElement.type, typeProvider.intType);
 
     VariableDeclaration bNode = declarationStatement.variables.variables[1];
-    var bElement = bNode.declaredElement2 as LocalVariableElement;
+    var bElement = bNode.declaredElement as LocalVariableElement;
     expect(bElement.type, typeProvider.doubleType);
   }
 
@@ -5036,7 +4992,7 @@
     // int a;
     var aDeclaration = fStatements[0] as VariableDeclarationStatement;
     VariableElement aElement =
-        aDeclaration.variables.variables[0].declaredElement2!;
+        aDeclaration.variables.variables[0].declaredElement!;
 
     // a;
     {
@@ -5055,7 +5011,7 @@
     // double b;
     var bDeclaration = gStatements[0] as VariableDeclarationStatement;
     VariableElement bElement =
-        bDeclaration.variables.variables[0].declaredElement2!;
+        bDeclaration.variables.variables[0].declaredElement!;
 
     // a;
     {
@@ -5139,18 +5095,13 @@
     await resolveTestFile();
     var classDeclaration = result.unit.declarations[0] as ClassDeclaration;
     var methodDeclaration = classDeclaration.members[0] as MethodDeclaration;
-    var methodElement = methodDeclaration.declaredElement2 as MethodElement;
+    var methodElement = methodDeclaration.declaredElement as MethodElement;
 
     InterfaceType doubleType = typeProvider.doubleType;
 
     expect(methodElement, isNotNull);
     assertType(methodElement.type, fTypeString);
 
-    // ignore: deprecated_member_use_from_same_package
-    expect(methodDeclaration.name.staticElement, same(methodElement));
-    // ignore: deprecated_member_use_from_same_package
-    expect(methodDeclaration.name.staticType, isNull);
-
     var fReturnTypeNode = methodDeclaration.returnType as NamedType;
     expect(fReturnTypeNode.name.staticElement, same(doubleType.element2));
     expect(fReturnTypeNode.type, doubleType);
@@ -5208,7 +5159,7 @@
     expect(result.errors, isEmpty);
 
     var cNode = result.unit.declarations[0] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
     MethodElement callElement = cElement.methods[0];
 
     List<Statement> statements = _getMainStatements(result);
@@ -5234,7 +5185,7 @@
     expect(result.errors, isEmpty);
 
     var main = result.unit.declarations[0] as FunctionDeclaration;
-    var mainElement = main.declaredElement2 as FunctionElement;
+    var mainElement = main.declaredElement as FunctionElement;
     ParameterElement parameter = mainElement.parameters[0];
 
     var mainBody = main.functionExpression.body as BlockFunctionBody;
@@ -5272,7 +5223,7 @@
 
     var aNode = result.unit.declarations[0] as ClassDeclaration;
     var fooNode = aNode.members[0] as MethodDeclaration;
-    var fooElement = fooNode.declaredElement2 as MethodElement;
+    var fooElement = fooNode.declaredElement as MethodElement;
 
     List<Statement> mainStatements = _getMainStatements(result);
     var statement = mainStatements[0] as ExpressionStatement;
@@ -5356,7 +5307,7 @@
     List<Statement> mainStatements = _getMainStatements(result);
 
     var foo = result.unit.declarations[1] as FunctionDeclaration;
-    ExecutableElement fooElement = foo.declaredElement2!;
+    ExecutableElement fooElement = foo.declaredElement!;
 
     var statement = mainStatements[0] as ExpressionStatement;
     var invocation = statement.expression as MethodInvocation;
@@ -5503,9 +5454,9 @@
     List<Statement> mainStatements = _getMainStatements(result);
 
     var cNode = result.unit.declarations[1] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
     var mNode = cNode.members[0] as MethodDeclaration;
-    var mElement = mNode.declaredElement2 as MethodElement;
+    var mElement = mNode.declaredElement as MethodElement;
 
     {
       var statement = mainStatements[0] as ExpressionStatement;
@@ -5560,7 +5511,7 @@
     await resolveTestFile();
 
     var cNode = result.unit.declarations[0] as ClassDeclaration;
-    TypeParameterElement tElement = cNode.declaredElement2!.typeParameters[0];
+    TypeParameterElement tElement = cNode.declaredElement!.typeParameters[0];
 
     var barNode = cNode.members[1] as MethodDeclaration;
     var barBody = barNode.body as BlockFunctionBody;
@@ -5587,7 +5538,7 @@
     InterfaceType doubleType = typeProvider.doubleType;
 
     var fNode = result.unit.declarations[1] as FunctionDeclaration;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
 
     var statement = mainStatements[0] as ExpressionStatement;
     var invocation = statement.expression as MethodInvocation;
@@ -5616,7 +5567,7 @@
     List<Statement> mainStatements = _getMainStatements(result);
 
     var fNode = result.unit.declarations[1] as FunctionDeclaration;
-    var fElement = fNode.declaredElement2 as FunctionElement;
+    var fElement = fNode.declaredElement as FunctionElement;
 
     // f<bool, String>(true, 'str');
     {
@@ -6040,7 +5991,7 @@
     VariableElement v;
     {
       var statement = mainStatements[0] as VariableDeclarationStatement;
-      v = statement.variables.variables[0].declaredElement2!;
+      v = statement.variables.variables[0].declaredElement!;
       expect(v.type, typeProvider.intType);
     }
 
@@ -6142,12 +6093,12 @@
     List<Statement> statements = _getMainStatements(result);
 
     var cDeclaration = result.unit.declarations[1] as ClassDeclaration;
-    ClassElement cElement = cDeclaration.declaredElement2!;
+    ClassElement cElement = cDeclaration.declaredElement!;
     FieldElement fElement = cElement.fields[0];
 
     var cStatement = statements[0] as VariableDeclarationStatement;
     VariableElement vElement =
-        cStatement.variables.variables[0].declaredElement2!;
+        cStatement.variables.variables[0].declaredElement!;
 
     var statement = statements[1] as ExpressionStatement;
     var prefixed = statement.expression as PrefixedIdentifier;
@@ -6177,7 +6128,7 @@
     List<Statement> statements = _getMainStatements(result);
 
     var cDeclaration = result.unit.declarations[1] as ClassDeclaration;
-    ClassElement cElement = cDeclaration.declaredElement2!;
+    ClassElement cElement = cDeclaration.declaredElement!;
     FieldElement fElement = cElement.fields[0];
 
     var statement = statements[0] as ExpressionStatement;
@@ -6202,7 +6153,7 @@
     expect(result.errors, isEmpty);
 
     var main = result.unit.declarations[0] as FunctionDeclaration;
-    var mainElement = main.declaredElement2 as FunctionElement;
+    var mainElement = main.declaredElement as FunctionElement;
     ParameterElement parameter = mainElement.parameters[0];
 
     var mainBody = main.functionExpression.body as BlockFunctionBody;
@@ -6327,7 +6278,7 @@
     VariableElement v;
     {
       var statement = mainStatements[0] as VariableDeclarationStatement;
-      v = statement.variables.variables[0].declaredElement2!;
+      v = statement.variables.variables[0].declaredElement!;
       expect(v.type, typeProvider.intType);
     }
 
@@ -6373,7 +6324,7 @@
     VariableElement v;
     {
       var statement = mainStatements[0] as VariableDeclarationStatement;
-      v = statement.variables.variables[0].declaredElement2!;
+      v = statement.variables.variables[0].declaredElement!;
       expect(v.type, typeProvider.boolType);
     }
 
@@ -6407,7 +6358,7 @@
     CompilationUnit unit = result.unit;
 
     var cClassDeclaration = unit.declarations[1] as ClassDeclaration;
-    ClassElement cClassElement = cClassDeclaration.declaredElement2!;
+    ClassElement cClassElement = cClassDeclaration.declaredElement!;
     FieldElement fElement = cClassElement.getField('f')!;
 
     List<Statement> mainStatements = _getMainStatements(result);
@@ -6459,7 +6410,7 @@
     CompilationUnit unit = result.unit;
 
     var cClassDeclaration = unit.declarations[1] as ClassDeclaration;
-    ClassElement cClassElement = cClassDeclaration.declaredElement2!;
+    ClassElement cClassElement = cClassDeclaration.declaredElement!;
     FieldElement fElement = cClassElement.getField('f')!;
 
     List<Statement> mainStatements = _getMainStatements(result);
@@ -6496,7 +6447,7 @@
     CompilationUnit unit = result.unit;
 
     var cClassDeclaration = unit.declarations[1] as ClassDeclaration;
-    ClassElement cClassElement = cClassDeclaration.declaredElement2!;
+    ClassElement cClassElement = cClassDeclaration.declaredElement!;
     FieldElement fElement = cClassElement.getField('f')!;
 
     List<Statement> mainStatements = _getMainStatements(result);
@@ -6561,12 +6512,7 @@
 ''');
 
     var main = result.unit.declarations[0] as FunctionDeclaration;
-    expect(main.declaredElement2, isNotNull);
-
-    // ignore: deprecated_member_use_from_same_package
-    expect(main.name.staticElement, isNotNull);
-    // ignore: deprecated_member_use_from_same_package
-    expect(main.name.staticType, isNull);
+    expect(main.declaredElement, isNotNull);
 
     var body = main.functionExpression.body as BlockFunctionBody;
     NodeList<Statement> statements = body.block.statements;
@@ -6575,7 +6521,7 @@
     VariableElement vElement;
     {
       var statement = statements[0] as VariableDeclarationStatement;
-      vElement = statement.variables.variables[0].declaredElement2!;
+      vElement = statement.variables.variables[0].declaredElement!;
     }
 
     {
@@ -6649,10 +6595,10 @@
     var aNode = result.unit.declarations[0] as ClassDeclaration;
     var bNode = result.unit.declarations[1] as ClassDeclaration;
 
-    var methodElement = aNode.members[0].declaredElement2 as MethodElement;
+    var methodElement = aNode.members[0].declaredElement as MethodElement;
     var getterElement =
-        aNode.members[1].declaredElement2 as PropertyAccessorElement;
-    var operatorElement = aNode.members[3].declaredElement2 as MethodElement;
+        aNode.members[1].declaredElement as PropertyAccessorElement;
+    var operatorElement = aNode.members[3].declaredElement as MethodElement;
 
     var testNode = bNode.members[0] as MethodDeclaration;
     var testBody = testNode.body as BlockFunctionBody;
@@ -6675,7 +6621,7 @@
 
       var target = invocation.target as SuperExpression;
       expect(
-          target.staticType, interfaceTypeNone(bNode.declaredElement2!)); // raw
+          target.staticType, interfaceTypeNone(bNode.declaredElement!)); // raw
 
       expect(invocation.methodName.staticElement, same(methodElement));
     }
@@ -6697,7 +6643,7 @@
 
       var target = propertyAccess.target as SuperExpression;
       expect(
-          target.staticType, interfaceTypeNone(bNode.declaredElement2!)); // raw
+          target.staticType, interfaceTypeNone(bNode.declaredElement!)); // raw
 
       expect(propertyAccess.propertyName.staticElement, same(getterElement));
       expect(propertyAccess.propertyName.staticType, typeProvider.intType);
@@ -6721,7 +6667,7 @@
 
       var target = propertyAccess.target as SuperExpression;
       expect(
-          target.staticType, interfaceTypeNone(bNode.declaredElement2!)); // raw
+          target.staticType, interfaceTypeNone(bNode.declaredElement!)); // raw
 
       assertUnresolvedSimpleIdentifier(propertyAccess.propertyName);
     }
@@ -6733,7 +6679,7 @@
 
       var target = binary.leftOperand as ThisExpression;
       expect(
-          target.staticType, interfaceTypeNone(bNode.declaredElement2!)); // raw
+          target.staticType, interfaceTypeNone(bNode.declaredElement!)); // raw
 
       expect(binary.staticElement, same(operatorElement));
       expect(binary.staticType, typeProvider.intType);
@@ -6763,10 +6709,10 @@
 
     var aNode = result.unit.declarations[0] as ClassDeclaration;
 
-    var methodElement = aNode.members[0].declaredElement2 as MethodElement;
+    var methodElement = aNode.members[0].declaredElement as MethodElement;
     var getterElement =
-        aNode.members[1].declaredElement2 as PropertyAccessorElement;
-    var operatorElement = aNode.members[3].declaredElement2 as MethodElement;
+        aNode.members[1].declaredElement as PropertyAccessorElement;
+    var operatorElement = aNode.members[3].declaredElement as MethodElement;
 
     var testNode = aNode.members[4] as MethodDeclaration;
     var testBody = testNode.body as BlockFunctionBody;
@@ -6864,7 +6810,7 @@
     await resolveTestFile();
 
     var cNode = result.unit.declarations[0] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
 
     var constructorNode = cNode.members[1] as ConstructorDeclaration;
 
@@ -6909,21 +6855,15 @@
     await resolveTestFile();
 
     var aNode = result.unit.declarations[0] as ClassDeclaration;
-    ClassElement aElement = aNode.declaredElement2!;
+    ClassElement aElement = aNode.declaredElement!;
 
     var bNode = result.unit.declarations[1] as ClassDeclaration;
-    ClassElement bElement = bNode.declaredElement2!;
+    ClassElement bElement = bNode.declaredElement!;
 
     var cNode = result.unit.declarations[2] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
 
     var dNode = result.unit.declarations[3] as ClassDeclaration;
-    Element dElement = dNode.declaredElement2!;
-
-    // ignore: deprecated_member_use_from_same_package
-    SimpleIdentifier dName = dNode.name;
-    expect(dName.staticElement, same(dElement));
-    expect(dName.staticType, isNull);
 
     {
       var expectedType = aElement.instantiate(
@@ -6979,21 +6919,15 @@
     await resolveTestFile();
 
     var aNode = result.unit.declarations[0] as ClassDeclaration;
-    ClassElement aElement = aNode.declaredElement2!;
+    ClassElement aElement = aNode.declaredElement!;
 
     var bNode = result.unit.declarations[1] as ClassDeclaration;
-    ClassElement bElement = bNode.declaredElement2!;
+    ClassElement bElement = bNode.declaredElement!;
 
     var cNode = result.unit.declarations[2] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
 
     var dNode = result.unit.declarations[3] as ClassTypeAlias;
-    Element dElement = dNode.declaredElement2!;
-
-    // ignore: deprecated_member_use_from_same_package
-    SimpleIdentifier dName = dNode.name;
-    expect(dName.staticElement, same(dElement));
-    expect(dName.staticType, isNull);
 
     {
       var expectedType = aElement.instantiate(
@@ -7048,33 +6982,18 @@
     await resolveTestFile();
 
     var enumNode = result.unit.declarations[0] as EnumDeclaration;
-    final enumElement = enumNode.declaredElement2!;
-
-    // ignore: deprecated_member_use_from_same_package
-    SimpleIdentifier dName = enumNode.name;
-    expect(dName.staticElement, same(enumElement));
-    expect(dName.staticType, isNull);
+    final enumElement = enumNode.declaredElement!;
 
     {
       var aElement = enumElement.getField('A');
       var aNode = enumNode.constants[0];
-      expect(aNode.declaredElement2, same(aElement));
-
-      // ignore: deprecated_member_use_from_same_package
-      expect(aNode.name.staticElement, same(aElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(aNode.name.staticType, isNull);
+      expect(aNode.declaredElement, same(aElement));
     }
 
     {
       var bElement = enumElement.getField('B');
       var bNode = enumNode.constants[1];
-      expect(bNode.declaredElement2, same(bElement));
-
-      // ignore: deprecated_member_use_from_same_package
-      expect(bNode.name.staticElement, same(bElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(bNode.name.staticType, isNull);
+      expect(bNode.declaredElement, same(bElement));
     }
   }
 
@@ -7096,43 +7015,32 @@
     final intElement = intType.element2;
 
     var cNode = result.unit.declarations[0] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
-
-    // The class name identifier.
-    // ignore: deprecated_member_use_from_same_package
-    expect(cNode.name.staticElement, same(cElement));
-    // ignore: deprecated_member_use_from_same_package
-    expect(cNode.name.staticType, isNull);
+    ClassElement cElement = cNode.declaredElement!;
 
     // unnamed constructor
     {
       var node = cNode.members[0] as ConstructorDeclaration;
-      expect(node.declaredElement2, isNotNull);
-      assertType(node.declaredElement2!.type, 'C Function(int)');
+      expect(node.declaredElement, isNotNull);
+      assertType(node.declaredElement!.type, 'C Function(int)');
       expect(node.returnType.staticElement, same(cElement));
       expect(node.returnType.staticType, isNull);
-      expect(node.name2, isNull);
+      expect(node.name, isNull);
     }
 
     // named constructor
     {
       var node = cNode.members[1] as ConstructorDeclaration;
-      expect(node.declaredElement2, isNotNull);
-      assertType(node.declaredElement2!.type, 'C Function(int)');
+      expect(node.declaredElement, isNotNull);
+      assertType(node.declaredElement!.type, 'C Function(int)');
       expect(node.returnType.staticElement, same(cElement));
       expect(node.returnType.staticType, isNull);
-
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name!.staticElement, same(node.declaredElement2));
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name!.staticType, isNull);
     }
 
     // publicMethod()
     {
       var node = cNode.members[2] as MethodDeclaration;
-      expect(node.declaredElement2, isNotNull);
-      assertType(node.declaredElement2!.type, 'int Function(double)');
+      expect(node.declaredElement, isNotNull);
+      assertType(node.declaredElement!.type, 'int Function(double)');
 
       // method return type
       var returnType = node.returnType as NamedType;
@@ -7141,12 +7049,6 @@
       expect(returnTypeName.staticElement, intElement);
       expect(returnTypeName.staticType, isNull);
 
-      // method name
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticElement, same(node.declaredElement2));
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticType, isNull);
-
       // method parameter
       {
         var pNode = node.parameters!.parameters[0] as SimpleFormalParameter;
@@ -7162,8 +7064,8 @@
     // publicGetter()
     {
       var node = cNode.members[3] as MethodDeclaration;
-      expect(node.declaredElement2, isNotNull);
-      assertType(node.declaredElement2!.type, 'int Function()');
+      expect(node.declaredElement, isNotNull);
+      assertType(node.declaredElement!.type, 'int Function()');
 
       // getter return type
       var returnType = node.returnType as NamedType;
@@ -7171,19 +7073,13 @@
       expect(returnType.type, intType);
       expect(returnTypeName.staticElement, intElement);
       expect(returnTypeName.staticType, isNull);
-
-      // getter name
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticElement, same(node.declaredElement2));
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticType, isNull);
     }
 
     // publicSetter()
     {
       var node = cNode.members[4] as MethodDeclaration;
-      expect(node.declaredElement2, isNotNull);
-      assertType(node.declaredElement2!.type, 'void Function(double)');
+      expect(node.declaredElement, isNotNull);
+      assertType(node.declaredElement!.type, 'void Function(double)');
 
       // setter return type
       var returnType = node.returnType as NamedType;
@@ -7192,12 +7088,6 @@
       expect(returnTypeName.staticElement, isNull);
       expect(returnTypeName.staticType, isNull);
 
-      // setter name
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticElement, same(node.declaredElement2));
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticType, isNull);
-
       // setter parameter
       {
         var pNode = node.parameters!.parameters[0] as SimpleFormalParameter;
@@ -7226,8 +7116,8 @@
     // topFunction()
     {
       var node = result.unit.declarations[0] as FunctionDeclaration;
-      expect(node.declaredElement2, isNotNull);
-      assertType(node.declaredElement2!.type, 'int Function(double)');
+      expect(node.declaredElement, isNotNull);
+      assertType(node.declaredElement!.type, 'int Function(double)');
 
       // function return type
       var returnType = node.returnType as NamedType;
@@ -7236,12 +7126,6 @@
       expect(returnTypeName.staticElement, intElement);
       expect(returnTypeName.staticType, isNull);
 
-      // function name
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticElement, same(node.declaredElement2));
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticType, isNull);
-
       // function parameter
       {
         var pNode = node.functionExpression.parameters!.parameters[0]
@@ -7258,8 +7142,8 @@
     // topGetter()
     {
       var node = result.unit.declarations[1] as FunctionDeclaration;
-      expect(node.declaredElement2, isNotNull);
-      assertType(node.declaredElement2!.type, 'int Function()');
+      expect(node.declaredElement, isNotNull);
+      assertType(node.declaredElement!.type, 'int Function()');
 
       // getter return type
       var returnType = node.returnType as NamedType;
@@ -7267,19 +7151,13 @@
       expect(returnType.type, intType);
       expect(returnTypeName.staticElement, intElement);
       expect(returnTypeName.staticType, isNull);
-
-      // getter name
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticElement, same(node.declaredElement2));
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticType, isNull);
     }
 
     // topSetter()
     {
       var node = result.unit.declarations[2] as FunctionDeclaration;
-      expect(node.declaredElement2, isNotNull);
-      assertType(node.declaredElement2!.type, 'void Function(double)');
+      expect(node.declaredElement, isNotNull);
+      assertType(node.declaredElement!.type, 'void Function(double)');
 
       // setter return type
       var returnType = node.returnType as NamedType;
@@ -7288,12 +7166,6 @@
       expect(returnTypeName.staticElement, isNull);
       expect(returnTypeName.staticType, isNull);
 
-      // setter name
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticElement, same(node.declaredElement2));
-      // ignore: deprecated_member_use_from_same_package
-      expect(node.name.staticType, isNull);
-
       // setter parameter
       {
         var pNode = node.functionExpression.parameters!.parameters[0]
@@ -7322,7 +7194,7 @@
     CompilationUnitElement unitElement = unit.declaredElement!;
 
     var cNode = unit.declarations[0] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
     TypeParameterElement tElement = cElement.typeParameters[0];
     expect(cElement, same(unitElement.classes[0]));
 
@@ -7330,12 +7202,8 @@
       FieldElement aElement = cElement.getField('a')!;
       var aDeclaration = cNode.members[0] as FieldDeclaration;
       VariableDeclaration aNode = aDeclaration.fields.variables[0];
-      expect(aNode.declaredElement2, same(aElement));
+      expect(aNode.declaredElement, same(aElement));
       expect(aElement.type, typeProvider.intType);
-      // ignore: deprecated_member_use_from_same_package
-      expect(aNode.name.staticElement, same(aElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(aNode.name.staticType, isNull);
 
       var aValue = aNode.initializer as Expression;
       expect(aValue.staticType, typeProvider.intType);
@@ -7351,12 +7219,8 @@
       expect(typeIdentifier.staticType, isNull);
 
       VariableDeclaration bNode = bDeclaration.fields.variables[0];
-      expect(bNode.declaredElement2, same(bElement));
+      expect(bNode.declaredElement, same(bElement));
       expect(bElement.type, typeParameterTypeNone(tElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(bNode.name.staticElement, same(bElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(bNode.name.staticType, isNull);
     }
   }
 
@@ -7372,7 +7236,7 @@
     CompilationUnit unit = result.unit;
 
     var cNode = unit.declarations[0] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
 
     var fieldDeclaration = cNode.members[0] as FieldDeclaration;
 
@@ -7380,14 +7244,9 @@
       FieldElement aElement = cElement.getField('a')!;
 
       VariableDeclaration aNode = fieldDeclaration.fields.variables[0];
-      expect(aNode.declaredElement2, same(aElement));
+      expect(aNode.declaredElement, same(aElement));
       expect(aElement.type, typeProvider.intType);
 
-      // ignore: deprecated_member_use_from_same_package
-      expect(aNode.name.staticElement, same(aElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(aNode.name.staticType, isNull);
-
       Expression aValue = aNode.initializer!;
       expect(aValue.staticType, typeProvider.intType);
     }
@@ -7396,14 +7255,9 @@
       FieldElement bElement = cElement.getField('b')!;
 
       VariableDeclaration bNode = fieldDeclaration.fields.variables[1];
-      expect(bNode.declaredElement2, same(bElement));
+      expect(bNode.declaredElement, same(bElement));
       expect(bElement.type, typeProvider.doubleType);
 
-      // ignore: deprecated_member_use_from_same_package
-      expect(bNode.name.staticElement, same(bElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(bNode.name.staticType, isNull);
-
       Expression aValue = bNode.initializer!;
       expect(aValue.staticType, typeProvider.doubleType);
     }
@@ -7423,13 +7277,9 @@
     {
       var aDeclaration = unit.declarations[0] as TopLevelVariableDeclaration;
       VariableDeclaration aNode = aDeclaration.variables.variables[0];
-      var aElement = aNode.declaredElement2 as TopLevelVariableElement;
+      var aElement = aNode.declaredElement as TopLevelVariableElement;
       expect(aElement, same(unitElement.topLevelVariables[0]));
       expect(aElement.type, typeProvider.intType);
-      // ignore: deprecated_member_use_from_same_package
-      expect(aNode.name.staticElement, same(aElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(aNode.name.staticType, isNull);
 
       Expression aValue = aNode.initializer!;
       expect(aValue.staticType, typeProvider.intType);
@@ -7439,18 +7289,13 @@
       var bDeclaration = unit.declarations[1] as TopLevelVariableDeclaration;
 
       VariableDeclaration bNode = bDeclaration.variables.variables[0];
-      var bElement = bNode.declaredElement2 as TopLevelVariableElement;
+      var bElement = bNode.declaredElement as TopLevelVariableElement;
       expect(bElement, same(unitElement.topLevelVariables[1]));
       expect(bElement.type, typeProvider.doubleType);
 
       var namedType = bDeclaration.variables.type as NamedType;
       _assertNamedTypeSimple(namedType, typeProvider.doubleType);
 
-      // ignore: deprecated_member_use_from_same_package
-      expect(bNode.name.staticElement, same(bElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(bNode.name.staticType, isNull);
-
       Expression aValue = bNode.initializer!;
       expect(aValue.staticType, typeProvider.doubleType);
     }
@@ -7472,30 +7317,20 @@
 
     {
       VariableDeclaration aNode = variableDeclaration.variables.variables[0];
-      var aElement = aNode.declaredElement2 as TopLevelVariableElement;
+      var aElement = aNode.declaredElement as TopLevelVariableElement;
       expect(aElement, same(unitElement.topLevelVariables[0]));
       expect(aElement.type, typeProvider.intType);
 
-      // ignore: deprecated_member_use_from_same_package
-      expect(aNode.name.staticElement, same(aElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(aNode.name.staticType, isNull);
-
       Expression aValue = aNode.initializer!;
       expect(aValue.staticType, typeProvider.intType);
     }
 
     {
       VariableDeclaration bNode = variableDeclaration.variables.variables[1];
-      var bElement = bNode.declaredElement2 as TopLevelVariableElement;
+      var bElement = bNode.declaredElement as TopLevelVariableElement;
       expect(bElement, same(unitElement.topLevelVariables[1]));
       expect(bElement.type, typeProvider.doubleType);
 
-      // ignore: deprecated_member_use_from_same_package
-      expect(bNode.name.staticElement, same(bElement));
-      // ignore: deprecated_member_use_from_same_package
-      expect(bNode.name.staticType, isNull);
-
       Expression aValue = bNode.initializer!;
       expect(aValue.staticType, typeProvider.doubleType);
     }
@@ -7512,18 +7347,13 @@
 
     await resolveTestFile();
     var fDeclaration = result.unit.declarations[0] as FunctionDeclaration;
-    var fElement = fDeclaration.declaredElement2 as FunctionElement;
+    var fElement = fDeclaration.declaredElement as FunctionElement;
 
     InterfaceType doubleType = typeProvider.doubleType;
 
     expect(fElement, isNotNull);
     assertType(fElement.type, fTypeString);
 
-    // ignore: deprecated_member_use_from_same_package
-    expect(fDeclaration.name.staticElement, same(fElement));
-    // ignore: deprecated_member_use_from_same_package
-    expect(fDeclaration.name.staticType, isNull);
-
     var fReturnTypeNode = fDeclaration.returnType as NamedType;
     expect(fReturnTypeNode.name.staticElement, same(doubleType.element2));
     expect(fReturnTypeNode.type, doubleType);
@@ -7587,7 +7417,7 @@
     CompilationUnit unit = result.unit;
 
     var alias = unit.declarations[0] as FunctionTypeAlias;
-    TypeAliasElement aliasElement = alias.declaredElement2!;
+    TypeAliasElement aliasElement = alias.declaredElement!;
     var function = aliasElement.aliasedElement as GenericFunctionTypeElement;
     expect(aliasElement, same(findElement.typeAlias('F')));
     expect(function.returnType, typeProvider.intType);
@@ -7622,16 +7452,16 @@
     CompilationUnitElement unitElement = unit.declaredElement!;
 
     var aNode = unit.declarations[0] as ClassDeclaration;
-    ClassElement aElement = aNode.declaredElement2!;
+    ClassElement aElement = aNode.declaredElement!;
     expect(aElement, same(unitElement.classes[0]));
 
     var cNode = unit.declarations[1] as ClassDeclaration;
-    ClassElement cElement = cNode.declaredElement2!;
+    ClassElement cElement = cNode.declaredElement!;
     expect(cElement, same(unitElement.classes[1]));
 
     {
       TypeParameter tNode = cNode.typeParameters!.typeParameters[0];
-      expect(tNode.declaredElement2, same(cElement.typeParameters[0]));
+      expect(tNode.declaredElement, same(cElement.typeParameters[0]));
 
       var bound = tNode.bound as NamedType;
       expect(bound.type, interfaceTypeNone(aElement));
@@ -7649,7 +7479,7 @@
       );
 
       TypeParameter uNode = cNode.typeParameters!.typeParameters[1];
-      expect(uNode.declaredElement2, same(cElement.typeParameters[1]));
+      expect(uNode.declaredElement, same(cElement.typeParameters[1]));
 
       var bound = uNode.bound as NamedType;
       expect(bound.type, listOfA);
@@ -7668,7 +7498,7 @@
 
     {
       TypeParameter vNode = cNode.typeParameters!.typeParameters[2];
-      expect(vNode.declaredElement2, same(cElement.typeParameters[2]));
+      expect(vNode.declaredElement, same(cElement.typeParameters[2]));
       expect(vNode.bound, isNull);
     }
   }
@@ -7816,7 +7646,7 @@
     await resolveTestFile();
 
     FunctionTypeAlias alias = findNode.functionTypeAlias('F<T>');
-    TypeAliasElement aliasElement = alias.declaredElement2!;
+    TypeAliasElement aliasElement = alias.declaredElement!;
 
     FieldDeclaration fDeclaration = findNode.fieldDeclaration('F<int> f');
 
@@ -7914,7 +7744,7 @@
     CompilationUnit unit = result.unit;
 
     var fNode = unit.declarations[1] as FunctionTypeAlias;
-    TypeAliasElement fElement = fNode.declaredElement2!;
+    TypeAliasElement fElement = fNode.declaredElement!;
 
     var statements = _getMainStatements(result);
 
@@ -8695,7 +8525,7 @@
   List<Statement> _getMainStatements(ResolvedUnitResult result) {
     for (var declaration in result.unit.declarations) {
       if (declaration is FunctionDeclaration &&
-          declaration.name2.lexeme == 'main') {
+          declaration.name.lexeme == 'main') {
         var body = declaration.functionExpression.body as BlockFunctionBody;
         return body.block.statements;
       }
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 522fc5d..85d0ae6 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1876,7 +1876,7 @@
     expect(result.errors, hasLength(0));
 
     var f = result.unit.declarations[0] as FunctionDeclaration;
-    assertType(f.declaredElement2!.type, 'int Function()');
+    assertType(f.declaredElement!.type, 'int Function()');
     assertType(f.returnType!.typeOrThrow, 'int');
 
     // The same result is also received through the stream.
@@ -2441,7 +2441,7 @@
 
     var result = await driver.getResultValid(b);
     var c = _getTopLevelVar(result.unit, 'c');
-    var typeC = c.declaredElement2!.type as InterfaceType;
+    var typeC = c.declaredElement!.type as InterfaceType;
     // The class C has an old field 'foo', not the new 'bar'.
     expect(typeC.element2.getField('foo'), isNotNull);
     expect(typeC.element2.getField('bar'), isNull);
@@ -3381,7 +3381,7 @@
     expect(result.errors, hasLength(0));
 
     var f = result.unit.declarations[0] as FunctionDeclaration;
-    assertType(f.declaredElement2!.type, 'int Function()');
+    assertType(f.declaredElement!.type, 'int Function()');
     assertType(f.returnType!.typeOrThrow, 'int');
   }
 
@@ -3503,21 +3503,21 @@
   void _assertClassFieldType(CompilationUnit unit, String className,
       String fieldName, String expected) {
     var node = _getClassField(unit, className, fieldName);
-    var type = node.declaredElement2!.type;
+    var type = node.declaredElement!.type;
     assertType(type, expected);
   }
 
   void _assertClassMethodReturnType(CompilationUnit unit, String className,
       String fieldName, String expected) {
     var node = _getClassMethod(unit, className, fieldName);
-    var type = node.declaredElement2!.returnType;
+    var type = node.declaredElement!.returnType;
     assertType(type, expected);
   }
 
   void _assertTopLevelVarType(
       CompilationUnit unit, String name, String expected) {
     VariableDeclaration variable = _getTopLevelVar(unit, name);
-    assertType(variable.declaredElement2!.type, expected);
+    assertType(variable.declaredElement!.type, expected);
   }
 
   void _expectCircularityError(EvaluationResultImpl evaluationResult) {
@@ -3531,7 +3531,7 @@
   ClassDeclaration _getClass(CompilationUnit unit, String name) {
     for (CompilationUnitMember declaration in unit.declarations) {
       if (declaration is ClassDeclaration) {
-        if (declaration.name2.lexeme == name) {
+        if (declaration.name.lexeme == name) {
           return declaration;
         }
       }
@@ -3545,7 +3545,7 @@
     for (ClassMember declaration in classDeclaration.members) {
       if (declaration is FieldDeclaration) {
         for (var field in declaration.fields.variables) {
-          if (field.name2.lexeme == fieldName) {
+          if (field.name.lexeme == fieldName) {
             return field;
           }
         }
@@ -3559,7 +3559,7 @@
     ClassDeclaration classDeclaration = _getClass(unit, className);
     for (ClassMember declaration in classDeclaration.members) {
       if (declaration is MethodDeclaration &&
-          declaration.name2.lexeme == methodName) {
+          declaration.name.lexeme == methodName) {
         return declaration;
       }
     }
@@ -3581,7 +3581,7 @@
     for (CompilationUnitMember declaration in unit.declarations) {
       if (declaration is TopLevelVariableDeclaration) {
         for (VariableDeclaration variable in declaration.variables.variables) {
-          if (variable.name2.lexeme == name) {
+          if (variable.name.lexeme == name) {
             return variable;
           }
         }
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index 090bcaf..f0d83e6 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -61,13 +61,13 @@
 ''');
     ClassElement classElementA = findElement.class_('A');
     assertThat(classElementA)
-      ..isAncestorOf('B1 extends A')
-      ..isAncestorOf('B2 implements A')
-      ..isAncestorOf('C1 extends B1')
-      ..isAncestorOf('C2 extends B2')
-      ..isAncestorOf('C3 implements B1')
-      ..isAncestorOf('C4 implements B2')
-      ..isAncestorOf('M extends Object with A');
+      ..isAncestorOf('B1 extends A', length: 2)
+      ..isAncestorOf('B2 implements A', length: 2)
+      ..isAncestorOf('C1 extends B1', length: 2)
+      ..isAncestorOf('C2 extends B2', length: 2)
+      ..isAncestorOf('C3 implements B1', length: 2)
+      ..isAncestorOf('C4 implements B2', length: 2)
+      ..isAncestorOf('M extends Object with A', length: 1);
   }
 
   test_hasAncestor_ClassTypeAlias() async {
@@ -80,9 +80,9 @@
     ClassElement classElementA = findElement.class_('A');
     ClassElement classElementB = findElement.class_('B');
     assertThat(classElementA)
-      ..isAncestorOf('C1 = Object with A')
-      ..isAncestorOf('C2 = Object with B');
-    assertThat(classElementB).isAncestorOf('C2 = Object with B');
+      ..isAncestorOf('C1 = Object with A', length: 2)
+      ..isAncestorOf('C2 = Object with B', length: 2);
+    assertThat(classElementB).isAncestorOf('C2 = Object with B', length: 2);
   }
 
   test_hasAncestor_MixinDeclaration() async {
@@ -98,12 +98,12 @@
 ''');
     ClassElement classElementA = findElement.class_('A');
     assertThat(classElementA)
-      ..isAncestorOf('B extends A')
-      ..isAncestorOf('M1 on A')
-      ..isAncestorOf('M2 on B')
-      ..isAncestorOf('M3 implements A')
-      ..isAncestorOf('M4 implements B')
-      ..isAncestorOf('M5 on M2');
+      ..isAncestorOf('B extends A', length: 1)
+      ..isAncestorOf('M1 on A', length: 2)
+      ..isAncestorOf('M2 on B', length: 2)
+      ..isAncestorOf('M3 implements A', length: 2)
+      ..isAncestorOf('M4 implements B', length: 2)
+      ..isAncestorOf('M5 on M2', length: 2);
   }
 
   test_isExtendedBy_ClassDeclaration_isQualified() async {
@@ -362,11 +362,11 @@
 ''');
 
     var intMethod = findNode.methodDeclaration('foo() {} // int');
-    assertThat(intMethod.declaredElement2!)
+    assertThat(intMethod.declaredElement!)
         .isInvokedAt('foo(); // int ref', true);
 
     var doubleMethod = findNode.methodDeclaration('foo() {} // double');
-    assertThat(doubleMethod.declaredElement2!)
+    assertThat(doubleMethod.declaredElement!)
         .isInvokedAt('foo(); // double ref', true);
   }
 
@@ -663,6 +663,24 @@
       ..isReferencedAt('A>()', false);
   }
 
+  test_isReferencedBy_ClassElement_inRecordTypeAnnotation_named() async {
+    await _indexTestUnit('''
+class A {}
+
+void f(({int foo, A bar}) r) {}
+''');
+    assertThat(findElement.class_('A')).isReferencedAt('A bar', false);
+  }
+
+  test_isReferencedBy_ClassElement_inRecordTypeAnnotation_positional() async {
+    await _indexTestUnit('''
+class A {}
+
+void f((int, A) r) {}
+''');
+    assertThat(findElement.class_('A')).isReferencedAt('A)', false);
+  }
+
   test_isReferencedBy_ClassElement_inTypeAlias() async {
     await _indexTestUnit('''
 class A<T> {}
@@ -1047,15 +1065,17 @@
     FieldElement field = findElement.field('field');
     PropertyAccessorElement getter = field.getter!;
     PropertyAccessorElement setter = field.setter!;
+
     // A()
-    assertThat(field).isWrittenAt('field});', true);
+    assertThat(field)
+      ..isWrittenAt('field});', true, length: 5)
+      ..hasRelationCount(1);
     // m()
-    assertThat(setter).isReferencedAt('field = 2; // nq', false);
-    assertThat(getter).isReferencedAt('field); // nq', false);
+    assertThat(setter).isReferencedAt('field = 2; // nq', false, length: 5);
+    assertThat(getter).isReferencedAt('field); // nq', false, length: 5);
     // main()
-    assertThat(setter).isReferencedAt('field = 3; // q', true);
-    assertThat(getter).isReferencedAt('field); // q', true);
-    assertThat(field).isReferencedAt('field: 4', true);
+    assertThat(setter).isReferencedAt('field = 3; // q', true, length: 5);
+    assertThat(getter).isReferencedAt('field); // q', true, length: 5);
   }
 
   test_isReferencedBy_FieldElement_class_multiple() async {
@@ -1077,18 +1097,18 @@
       FieldElement field = findElement.field('aaa');
       PropertyAccessorElement getter = field.getter!;
       PropertyAccessorElement setter = field.setter!;
-      assertThat(field).isWrittenAt('aaa, ', true);
-      assertThat(getter).isReferencedAt('aaa);', false);
-      assertThat(setter).isReferencedAt('aaa = 1;', false);
+      assertThat(field).isWrittenAt('aaa, ', true, length: 3);
+      assertThat(getter).isReferencedAt('aaa);', false, length: 3);
+      assertThat(setter).isReferencedAt('aaa = 1;', false, length: 3);
     }
     // bbb
     {
       FieldElement field = findElement.field('bbb');
       PropertyAccessorElement getter = field.getter!;
       PropertyAccessorElement setter = field.setter!;
-      assertThat(field).isWrittenAt('bbb) {}', true);
-      assertThat(getter).isReferencedAt('bbb);', false);
-      assertThat(setter).isReferencedAt('bbb = 2;', false);
+      assertThat(field).isWrittenAt('bbb) {}', true, length: 3);
+      assertThat(getter).isReferencedAt('bbb);', false, length: 3);
+      assertThat(setter).isReferencedAt('bbb = 2;', false, length: 3);
     }
   }
 
@@ -1146,15 +1166,17 @@
     FieldElement field = findElement.field('field');
     PropertyAccessorElement getter = field.getter!;
     PropertyAccessorElement setter = field.setter!;
+
     // E()
-    assertThat(field).isWrittenAt('field});', true);
+    assertThat(field)
+      ..isWrittenAt('field});', true, length: 5)
+      ..hasRelationCount(1);
     // foo()
-    assertThat(setter).isReferencedAt('field = 2; // nq', false);
-    assertThat(getter).isReferencedAt('field; // nq', false);
+    assertThat(setter).isReferencedAt('field = 2; // nq', false, length: 5);
+    assertThat(getter).isReferencedAt('field; // nq', false, length: 5);
     // f()
-    assertThat(setter).isReferencedAt('field = 3; // q', true);
-    assertThat(getter).isReferencedAt('field; // q', true);
-    assertThat(field).isReferencedAt('field: 4', true);
+    assertThat(setter).isReferencedAt('field = 3; // q', true, length: 5);
+    assertThat(getter).isReferencedAt('field; // q', true, length: 5);
   }
 
   test_isReferencedBy_FieldElement_enum_index() async {
@@ -1384,7 +1406,7 @@
 }
 ''');
     var element = findElement.unnamedConstructor('A').parameter('a');
-    assertThat(element).isReferencedAt('a}); // ref', true);
+    assertThat(element).isReferencedAt('a}); // ref', true, length: 1);
   }
 
   test_isReferencedBy_ParameterElement_ofConstructor_super_positional() async {
@@ -1397,7 +1419,7 @@
 }
 ''');
     var element = findElement.unnamedConstructor('A').parameter('a');
-    assertThat(element).isReferencedAt('a); // ref', true);
+    assertThat(element).isReferencedAt('a); // ref', true, length: 1);
   }
 
   test_isReferencedBy_ParameterElement_optionalNamed_ofConstructor_genericClass() async {
@@ -1537,16 +1559,16 @@
 
     var intGetter = findNode.methodDeclaration('0; // int getter');
     var intSetter = findNode.methodDeclaration('{} // int setter');
-    assertThat(intGetter.declaredElement2!)
+    assertThat(intGetter.declaredElement!)
         .isReferencedAt('foo; // int getter ref', true);
-    assertThat(intSetter.declaredElement2!)
+    assertThat(intSetter.declaredElement!)
         .isReferencedAt('foo = 0; // int setter ref', true);
 
     var doubleGetter = findNode.methodDeclaration('0; // double getter');
     var doubleSetter = findNode.methodDeclaration('{} // double setter');
-    assertThat(doubleGetter.declaredElement2!)
+    assertThat(doubleGetter.declaredElement!)
         .isReferencedAt('foo; // double getter ref', true);
-    assertThat(doubleSetter.declaredElement2!)
+    assertThat(doubleSetter.declaredElement!)
         .isReferencedAt('foo = 0; // double setter ref', true);
   }
 
@@ -1655,8 +1677,8 @@
 ''');
     FieldElement element = findElement.field('field');
     assertThat(element)
-      ..isWrittenAt('field})', true)
-      ..isWrittenAt('field = 5', true);
+      ..isWrittenAt('field})', true, length: 5)
+      ..isWrittenAt('field = 5', true, length: 5);
   }
 
   test_subtypes_classDeclaration() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/results/get_element_declaration_test.dart b/pkg/analyzer/test/src/dart/analysis/results/get_element_declaration_test.dart
index 7000d88..c2f9401 100644
--- a/pkg/analyzer/test/src/dart/analysis/results/get_element_declaration_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/results/get_element_declaration_test.dart
@@ -25,10 +25,10 @@
     await resolveTestCode(r'''
 class A {}
 ''');
-    var element = findNode.classDeclaration('A').declaredElement2!;
+    var element = findNode.classDeclaration('A').declaredElement!;
     var result = await getElementDeclaration(element);
     var node = result!.node as ClassDeclaration;
-    expect(node.name2.lexeme, 'A');
+    expect(node.name.lexeme, 'A');
   }
 
   test_class_duplicate() async {
@@ -37,23 +37,23 @@
 class A {} // 2
 ''');
     {
-      var element = findNode.classDeclaration('A {} // 1').declaredElement2!;
+      var element = findNode.classDeclaration('A {} // 1').declaredElement!;
       var result = await getElementDeclaration(element);
       var node = result!.node as ClassDeclaration;
-      expect(node.name2.lexeme, 'A');
+      expect(node.name.lexeme, 'A');
       expect(
-        node.name2.offset,
+        node.name.offset,
         this.result.content.indexOf('A {} // 1'),
       );
     }
 
     {
-      var element = findNode.classDeclaration('A {} // 2').declaredElement2!;
+      var element = findNode.classDeclaration('A {} // 2').declaredElement!;
       var result = await getElementDeclaration(element);
       var node = result!.node as ClassDeclaration;
-      expect(node.name2.lexeme, 'A');
+      expect(node.name.lexeme, 'A');
       expect(
-        node.name2.offset,
+        node.name.offset,
         this.result.content.indexOf('A {} // 2'),
       );
     }
@@ -71,18 +71,18 @@
     var element = library.getClass('A')!;
     var result = await getElementDeclaration(element);
     var node = result!.node as ClassDeclaration;
-    expect(node.name2.lexeme, 'A');
+    expect(node.name.lexeme, 'A');
   }
 
   test_class_missingName() async {
     await resolveTestCode('''
 class {}
 ''');
-    var element = findNode.classDeclaration('class {}').declaredElement2!;
+    var element = findNode.classDeclaration('class {}').declaredElement!;
     var result = await getElementDeclaration(element);
     var node = result!.node as ClassDeclaration;
-    expect(node.name2.lexeme, '');
-    expect(node.name2.offset, 6);
+    expect(node.name.lexeme, '');
+    expect(node.name.offset, 6);
   }
 
   test_classTypeAlias() async {
@@ -94,7 +94,7 @@
     var element = findElement.class_('B');
     var result = await getElementDeclaration(element);
     var node = result!.node as ClassTypeAlias;
-    expect(node.name2.lexeme, 'B');
+    expect(node.name.lexeme, 'B');
   }
 
   test_compilationUnit() async {
@@ -112,17 +112,17 @@
 }
 ''');
     {
-      var unnamed = findNode.constructor('A();').declaredElement2!;
+      var unnamed = findNode.constructor('A();').declaredElement!;
       var result = await getElementDeclaration(unnamed);
       var node = result!.node as ConstructorDeclaration;
-      expect(node.name2, isNull);
+      expect(node.name, isNull);
     }
 
     {
-      var named = findNode.constructor('A.named();').declaredElement2!;
+      var named = findNode.constructor('A.named();').declaredElement!;
       var result = await getElementDeclaration(named);
       var node = result!.node as ConstructorDeclaration;
-      expect(node.name2!.lexeme, 'named');
+      expect(node.name!.lexeme, 'named');
     }
   }
 
@@ -134,23 +134,23 @@
 }
 ''');
     {
-      var element = findNode.constructor('A.named(); // 1').declaredElement2!;
+      var element = findNode.constructor('A.named(); // 1').declaredElement!;
       var result = await getElementDeclaration(element);
       var node = result!.node as ConstructorDeclaration;
-      expect(node.name2!.lexeme, 'named');
+      expect(node.name!.lexeme, 'named');
       expect(
-        node.name2!.offset,
+        node.name!.offset,
         this.result.content.indexOf('named(); // 1'),
       );
     }
 
     {
-      var element = findNode.constructor('A.named(); // 2').declaredElement2!;
+      var element = findNode.constructor('A.named(); // 2').declaredElement!;
       var result = await getElementDeclaration(element);
       var node = result!.node as ConstructorDeclaration;
-      expect(node.name2!.lexeme, 'named');
+      expect(node.name!.lexeme, 'named');
       expect(
-        node.name2!.offset,
+        node.name!.offset,
         this.result.content.indexOf('named(); // 2'),
       );
     }
@@ -164,10 +164,10 @@
 }
 ''');
     {
-      var element = findNode.constructor('A(); // 1').declaredElement2!;
+      var element = findNode.constructor('A(); // 1').declaredElement!;
       var result = await getElementDeclaration(element);
       var node = result!.node as ConstructorDeclaration;
-      expect(node.name2, isNull);
+      expect(node.name, isNull);
       expect(
         node.returnType.offset,
         this.result.content.indexOf('A(); // 1'),
@@ -175,10 +175,10 @@
     }
 
     {
-      var element = findNode.constructor('A(); // 2').declaredElement2!;
+      var element = findNode.constructor('A(); // 2').declaredElement!;
       var result = await getElementDeclaration(element);
       var node = result!.node as ConstructorDeclaration;
-      expect(node.name2, isNull);
+      expect(node.name, isNull);
       expect(
         node.returnType.offset,
         this.result.content.indexOf('A(); // 2'),
@@ -204,7 +204,7 @@
     var element = findElement.enum_('MyEnum');
     var result = await getElementDeclaration(element);
     var node = result!.node as EnumDeclaration;
-    expect(node.name2.lexeme, 'MyEnum');
+    expect(node.name.lexeme, 'MyEnum');
   }
 
   test_enum_constant() async {
@@ -214,17 +214,17 @@
     var element = findElement.field('a');
     var result = await getElementDeclaration(element);
     var node = result!.node as EnumConstantDeclaration;
-    expect(node.name2.lexeme, 'a');
+    expect(node.name.lexeme, 'a');
   }
 
   test_extension() async {
     await resolveTestCode(r'''
 extension E on int {}
 ''');
-    var element = findNode.extensionDeclaration('E').declaredElement2!;
+    var element = findNode.extensionDeclaration('E').declaredElement!;
     var result = await getElementDeclaration(element);
     var node = result!.node as ExtensionDeclaration;
-    expect(node.name2!.lexeme, 'E');
+    expect(node.name!.lexeme, 'E');
   }
 
   test_field() async {
@@ -237,7 +237,7 @@
 
     var result = await getElementDeclaration(element);
     var node = result!.node as VariableDeclaration;
-    expect(node.name2.lexeme, 'foo');
+    expect(node.name.lexeme, 'foo');
   }
 
   test_functionDeclaration_local() async {
@@ -250,7 +250,7 @@
 
     var result = await getElementDeclaration(element);
     var node = result!.node as FunctionDeclaration;
-    expect(node.name2.lexeme, 'foo');
+    expect(node.name.lexeme, 'foo');
   }
 
   test_functionDeclaration_top() async {
@@ -261,7 +261,7 @@
 
     var result = await getElementDeclaration(element);
     var node = result!.node as FunctionDeclaration;
-    expect(node.name2.lexeme, 'foo');
+    expect(node.name.lexeme, 'foo');
   }
 
   test_genericFunctionTypeElement() async {
@@ -282,7 +282,7 @@
     var element = findElement.getter('x');
     var result = await getElementDeclaration(element);
     var node = result!.node as MethodDeclaration;
-    expect(node.name2.lexeme, 'x');
+    expect(node.name.lexeme, 'x');
     expect(node.isGetter, isTrue);
   }
 
@@ -293,7 +293,7 @@
     var element = findElement.topGet('x');
     var result = await getElementDeclaration(element);
     var node = result!.node as FunctionDeclaration;
-    expect(node.name2.lexeme, 'x');
+    expect(node.name.lexeme, 'x');
     expect(node.isGetter, isTrue);
   }
 
@@ -316,7 +316,7 @@
 
     var result = await getElementDeclaration(element);
     var node = result!.node as VariableDeclaration;
-    expect(node.name2.lexeme, 'foo');
+    expect(node.name.lexeme, 'foo');
   }
 
   test_method() async {
@@ -329,7 +329,7 @@
 
     var result = await getElementDeclaration(element);
     var node = result!.node as MethodDeclaration;
-    expect(node.name2.lexeme, 'foo');
+    expect(node.name.lexeme, 'foo');
   }
 
   test_mixin() async {
@@ -339,7 +339,7 @@
     var element = findElement.mixin('M');
     var result = await getElementDeclaration(element);
     var node = result!.node as MixinDeclaration;
-    expect(node.name2.lexeme, 'M');
+    expect(node.name.lexeme, 'M');
   }
 
   test_parameter() async {
@@ -390,7 +390,7 @@
     var element = findElement.setter('x');
     var result = await getElementDeclaration(element);
     var node = result!.node as MethodDeclaration;
-    expect(node.name2.lexeme, 'x');
+    expect(node.name.lexeme, 'x');
     expect(node.isSetter, isTrue);
   }
 
@@ -401,7 +401,7 @@
     var element = findElement.topSet('x');
     var result = await getElementDeclaration(element);
     var node = result!.node as FunctionDeclaration;
-    expect(node.name2.lexeme, 'x');
+    expect(node.name.lexeme, 'x');
     expect(node.isSetter, isTrue);
   }
 
@@ -413,7 +413,7 @@
 
     var result = await getElementDeclaration(element);
     var node = result!.node as VariableDeclaration;
-    expect(node.name2.lexeme, 'foo');
+    expect(node.name.lexeme, 'foo');
   }
 
   test_topLevelVariable_synthetic() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index eea57e2..ca34986 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -18,6 +18,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(SearchTest);
+    defineReflectiveTests(SearchMultipleDriversTest);
   });
 }
 
@@ -64,6 +65,37 @@
 }
 
 @reflectiveTest
+class SearchMultipleDriversTest extends PubPackageResolutionTest {
+  @override
+  List<String> get collectionIncludedPaths =>
+      [workspaceRootPath, otherPackageRootPath];
+
+  AnalysisDriver get driver => driverFor(testFile);
+
+  String get otherPackageRootPath => '$workspaceRootPath/other';
+
+  test_declarations_searchesFilesOnlyOnce() async {
+    // Create another driver to search in to ensure we don't get dupe results.
+    var otherFile = newFile(convertPath('$otherPackageRootPath/main.dart'), '');
+    var otherDriver = driverFor(otherFile);
+    var results = WorkspaceSymbols();
+
+    // Search both drivers.
+    await FindDeclarations(
+      [driver, otherDriver],
+      results,
+      null,
+      null,
+    ).compute();
+
+    // Ensure only one result for an SDK class, and that the file was tracked as searched.
+    var declarations = results.declarations;
+    expect(declarations.where((element) => element.name == 'Duration'),
+        hasLength(1));
+  }
+}
+
+@reflectiveTest
 class SearchTest extends PubPackageResolutionTest {
   AnalysisDriver get driver => driverFor(testFile);
 
@@ -152,8 +184,8 @@
 ''');
     var results = WorkspaceSymbols();
     var token = CancelableToken();
-    var searchFuture = driver.search
-        .declarations(results, null, null, cancellationToken: token);
+    var searchFuture =
+        FindDeclarations([driver], results, null, null).compute(token);
     token.cancel();
     await searchFuture;
     expect(results.cancelled, isTrue);
@@ -171,7 +203,7 @@
 }
 ''');
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, null);
+    await FindDeclarations([driver], results, null, null).compute();
     var declarations = results.declarations;
     declarations.assertHas('C', DeclarationKind.CLASS,
         offset: 6, codeOffset: 0, codeLength: 91);
@@ -208,7 +240,7 @@
     await resolveTestCode('class T {}');
 
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, null);
+    await FindDeclarations([driver], results, null, null).compute();
     var declarations = results.declarations;
 
     declarations.assertHas('T', DeclarationKind.CLASS);
@@ -225,7 +257,7 @@
 ''');
 
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, null);
+    await FindDeclarations([driver], results, null, null).compute();
     var declarations = results.declarations;
 
     declarations.assertHas('E', DeclarationKind.ENUM,
@@ -248,7 +280,7 @@
 }
 ''');
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, null);
+    await FindDeclarations([driver], results, null, null).compute();
     var declarations = results.declarations;
     declarations.assertHas('E', DeclarationKind.EXTENSION,
         offset: 10, codeOffset: 0, codeLength: 82);
@@ -269,7 +301,7 @@
 class C {}
 ''');
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, 2);
+    await FindDeclarations([driver], results, null, 2).compute();
     expect(results.declarations, hasLength(2));
   }
 
@@ -283,7 +315,7 @@
 }
 ''');
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, null);
+    await FindDeclarations([driver], results, null, null).compute();
     var declarations = results.declarations;
     declarations.assertHas('M', DeclarationKind.MIXIN,
         offset: 6, codeOffset: 0, codeLength: 71);
@@ -302,7 +334,8 @@
     var b = newFile('$testPackageLibPath/b.dart', 'class B {}').path;
 
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, null, onlyForFile: b);
+    await FindDeclarations([driver], results, null, null, onlyForFile: b)
+        .compute();
     var declarations = results.declarations;
 
     expect(results.files, [b]);
@@ -320,7 +353,7 @@
 void f(bool a, String b) {}
 ''');
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, null);
+    await FindDeclarations([driver], results, null, null).compute();
     var declarations = results.declarations;
 
     var declaration = declarations.assertHas('C', DeclarationKind.CLASS);
@@ -346,7 +379,7 @@
 void f4(bool Function(int, String) a) {}
 ''');
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, null);
+    await FindDeclarations([driver], results, null, null).compute();
     var declarations = results.declarations;
 
     var declaration = declarations.assertHas('f1', DeclarationKind.FUNCTION);
@@ -371,7 +404,7 @@
 }
 ''');
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, null);
+    await FindDeclarations([driver], results, null, null).compute();
     var declarations = results.declarations;
 
     var declaration =
@@ -395,7 +428,7 @@
 class D {}
 ''');
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, RegExp(r'[A-C]'), null);
+    await FindDeclarations([driver], results, RegExp(r'[A-C]'), null).compute();
     var declarations = results.declarations;
 
     declarations.assertHas('A', DeclarationKind.CLASS);
@@ -414,7 +447,7 @@
 typedef tf2<T> = int Function<S>(T tp, S sp);
 ''');
     var results = WorkspaceSymbols();
-    await driver.search.declarations(results, null, null);
+    await FindDeclarations([driver], results, null, null).compute();
     var declarations = results.declarations;
 
     declarations.assertHas('g', DeclarationKind.GETTER,
@@ -436,6 +469,46 @@
         offset: 85, codeOffset: 77, codeLength: 45);
   }
 
+  test_issue49951_references_dontAddToKnown_unrelated() async {
+    final myRoot = newFolder('$workspaceRootPath/packages/my');
+
+    final myFile = newFile('${myRoot.path}/lib/my.dart', r'''
+class A {}
+''');
+
+    // Configure `package:my`.
+    writePackageConfig(
+      getFile('${myRoot.path}/.dart_tool/package_config.json').path,
+      PackageConfigFileBuilder()..add(name: 'my', rootPath: myRoot.path),
+    );
+
+    final myDriver = driverFor(myFile);
+    final mySession = contextFor(myFile).currentSession;
+    final libraryElementResult =
+        await mySession.getLibraryByUri('package:my/my.dart');
+    libraryElementResult as LibraryElementResult;
+
+    final A = libraryElementResult.element.getClass('A')!;
+
+    final searchedFiles = SearchedFiles();
+    searchedFiles.ownAnalyzed(myDriver.search);
+
+    final testDriver = driverFor(testFile);
+
+    // No references, but this is not the most important.
+    final references = await testDriver.search.references(A, searchedFiles);
+    expect(references, isEmpty);
+
+    // We should not add the file to known files. It is not in the
+    // `package:test` itself, and not in a package from its package config.
+    // So, it is absolutely unrelated to `package:test`.
+    for (final knowFile in testDriver.fsState.knownFiles) {
+      if (knowFile.path == myFile.path) {
+        fail('The file should not be added.');
+      }
+    }
+  }
+
   test_searchMemberReferences_qualified_resolved() async {
     await resolveTestCode('''
 class C {
@@ -614,6 +687,40 @@
     await _verifyReferences(element, expected);
   }
 
+  test_searchReferences_ClassElement_inRecordTypeAnnotation_named() async {
+    await resolveTestCode('''
+class A {}
+
+void f(({int foo, A bar}) r) {}
+''');
+    var element = findElement.class_('A');
+    var expected = [
+      _expectId(
+        findElement.parameter('r'),
+        SearchResultKind.REFERENCE,
+        'A bar',
+      ),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_ClassElement_inRecordTypeAnnotation_positional() async {
+    await resolveTestCode('''
+class A {}
+
+void f((int, A) r) {}
+''');
+    var element = findElement.class_('A');
+    var expected = [
+      _expectId(
+        findElement.parameter('r'),
+        SearchResultKind.REFERENCE,
+        'A)',
+      ),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
   test_searchReferences_ClassElement_mixin() async {
     await resolveTestCode('''
 mixin A {}
@@ -963,8 +1070,7 @@
     var main = findElement.method('main');
     var fieldParameter = findElement.parameter('field');
     var expected = [
-      _expectIdQ(fieldParameter, SearchResultKind.WRITE, 'field}'),
-      _expectIdQ(main, SearchResultKind.REFERENCE, 'field: 1'),
+      _expectIdQ(fieldParameter, SearchResultKind.WRITE, 'field}', length: 5),
       _expectId(main, SearchResultKind.READ, 'field); // ref-nq'),
       _expectIdQ(main, SearchResultKind.READ, 'field); // ref-q'),
       _expectId(main, SearchResultKind.READ, 'field(); // inv-nq'),
@@ -1018,10 +1124,9 @@
 }
 ''');
     await _verifyReferences(findElement.field('field'), [
-      _expectIdQ(
-          findElement.field('v'), SearchResultKind.REFERENCE, 'field: 0'),
       _expectIdQ(findElement.parameter('field'), SearchResultKind.WRITE,
-          'field}); // 1'),
+          'field}); // 1',
+          length: 5),
       _expectIdQ(
           findElement.topFunction('f'), SearchResultKind.READ, 'field; // 2'),
     ]);
@@ -1615,6 +1720,7 @@
         findElement.unnamedConstructor('B').superFormalParameter('a'),
         SearchResultKind.REFERENCE,
         'a}); // ref',
+        length: 1,
       ),
     ];
     await _verifyReferences(element, expected);
@@ -1635,6 +1741,7 @@
         findElement.unnamedConstructor('B').superFormalParameter('a'),
         SearchResultKind.REFERENCE,
         'a); // ref',
+        length: 1,
       ),
     ];
     await _verifyReferences(element, expected);
@@ -2393,7 +2500,7 @@
     }
   }
 
-  test_subtypes_class_discover() async {
+  test_subTypes_class_discover() async {
     var aaaPackageRootPath = '$packagesRootPath/aaa';
     var bbbPackageRootPath = '$packagesRootPath/bbb';
 
@@ -2463,7 +2570,7 @@
     expect(b.members, ['method1']);
   }
 
-  test_subTypes_class_discover() async {
+  test_subTypes_class_discover2() async {
     var aaaPackageRootPath = '$packagesRootPath/aaa';
     var bbbPackageRootPath = '$packagesRootPath/bbb';
     var cccPackageRootPath = '$packagesRootPath/ccc';
diff --git a/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart b/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart
index 75bf51f..0fb3167 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart
@@ -81,7 +81,7 @@
     var element = findElement.class_('A');
     var result = (await helper.getElementDeclaration(element))!;
     var node = result.node as ClassDeclaration;
-    expect(node.name2.lexeme, 'A');
+    expect(node.name.lexeme, 'A');
   }
 
   test_getResolvedUnitByElement() async {
@@ -89,7 +89,7 @@
 class A {}
 class B {}
 ''');
-    var element = findNode.classDeclaration('A').declaredElement2!;
+    var element = findNode.classDeclaration('A').declaredElement!;
     var resolvedUnit = (await helper.getResolvedUnitByElement(element))!;
     expect(resolvedUnit.unit.declarations, hasLength(2));
   }
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index 2a482d9..0bd813c 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -329,7 +329,7 @@
     var element = libraryResult.element.getClass('A')!;
     var declaration = parsedLibrary.getElementDeclaration(element)!;
     var node = declaration.node as ClassDeclaration;
-    expect(node.name2.lexeme, 'A');
+    expect(node.name.lexeme, 'A');
     expect(node.offset, 0);
     expect(node.length, 10);
   }
@@ -365,7 +365,7 @@
     // We can get the variable element declaration.
     var fooDeclaration = parsedLibrary.getElementDeclaration(fooElement)!;
     var fooNode = fooDeclaration.node as VariableDeclaration;
-    expect(fooNode.name2.lexeme, 'foo');
+    expect(fooNode.name.lexeme, 'foo');
     expect(fooNode.offset, 4);
     expect(fooNode.length, 7);
 
@@ -592,17 +592,17 @@
 
     var aDeclaration = resolvedLibrary.getElementDeclaration(aClass)!;
     var aNode = aDeclaration.node as ClassDeclaration;
-    expect(aNode.name2.lexeme, 'A');
+    expect(aNode.name.lexeme, 'A');
     expect(aNode.offset, 16);
     expect(aNode.length, 16);
-    expect(aNode.declaredElement2!.name, 'A');
+    expect(aNode.declaredElement!.name, 'A');
 
     var bDeclaration = resolvedLibrary.getElementDeclaration(bClass)!;
     var bNode = bDeclaration.node as ClassDeclaration;
-    expect(bNode.name2.lexeme, 'B');
+    expect(bNode.name.lexeme, 'B');
     expect(bNode.offset, 19);
     expect(bNode.length, 16);
-    expect(bNode.declaredElement2!.name, 'B');
+    expect(bNode.declaredElement!.name, 'B');
   }
 
   test_getResolvedLibrary_getElementDeclaration_notThisLibrary() async {
@@ -632,10 +632,10 @@
     // We can get the variable element declaration.
     var fooDeclaration = resolvedLibrary.getElementDeclaration(fooElement)!;
     var fooNode = fooDeclaration.node as VariableDeclaration;
-    expect(fooNode.name2.lexeme, 'foo');
+    expect(fooNode.name.lexeme, 'foo');
     expect(fooNode.offset, 4);
     expect(fooNode.length, 7);
-    expect(fooNode.declaredElement2!.name, 'foo');
+    expect(fooNode.declaredElement!.name, 'foo');
 
     // Synthetic elements don't have nodes.
     expect(resolvedLibrary.getElementDeclaration(fooElement.getter!), isNull);
diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart
index e3fa25c..44a9e38 100644
--- a/pkg/analyzer/test/src/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart
@@ -298,10 +298,30 @@
     assertInContext("C()}", true);
   }
 
+  @FailingTest(reason: 'not yet implemented')
   test_inConstantContext_instanceCreation_switch_true() {
     parse('''
 f(v) {
   switch (v) {
+  case const C():
+    break;
+  }
+}
+class C {
+  const C();
+}
+''');
+    assertInContext("C()", true);
+  }
+
+  @failingTest
+  test_inConstantContext_instanceCreation_switch_true_language218() {
+    // Expected: true
+    //   Actual: <false>
+    parse('''
+// @dart=2.18
+f(v) {
+  switch (v) {
   case C():
     break;
   }
@@ -431,10 +451,56 @@
     assertInContext("[]", true);
   }
 
+  test_inConstantContext_listLiteral_namedFields_recordLiteral_false() {
+    parse('''
+final x = (0, foo: [1]);
+''');
+    assertInContext('[1]', false);
+  }
+
+  test_inConstantContext_listLiteral_namedFields_recordLiteral_true() {
+    parse('''
+final x = const (0, foo: [1]);
+''');
+    assertInContext('[1]', true);
+  }
+
+  test_inConstantContext_listLiteral_positionalFields_recordLiteral_false() {
+    parse('''
+final x = (0, [1]);
+''');
+    assertInContext('[1]', false);
+  }
+
+  test_inConstantContext_listLiteral_positionalFields_recordLiteral_true() {
+    parse('''
+final x = const (0, [1]);
+''');
+    assertInContext('[1]', true);
+  }
+
+  @FailingTest(reason: 'not yet implemented')
   test_inConstantContext_listLiteral_switch_true() {
     parse('''
 f(v) {
   switch (v) {
+  case const []:
+    break;
+  }
+}
+''');
+    assertInContext("[]", true);
+  }
+
+  @failingTest
+  test_inConstantContext_listLiteral_switch_true_language218() {
+    // Expected: <Instance of 'ExpressionImpl'>
+    //   Actual: ListPatternImpl:<[]>
+    //    Which: is not an instance of 'ExpressionImpl'
+    parse('''
+// @dart=2.18
+f(v) {
+  switch (v) {
   case []:
     break;
   }
@@ -541,10 +607,28 @@
     assertInContext("{'d", true);
   }
 
+  @FailingTest(reason: 'not yet implemented')
   test_inConstantContext_mapLiteral_switch_true() {
     parse('''
 f(v) {
   switch (v) {
+  case const {}:
+    break;
+  }
+}
+''');
+    assertInContext("{}", true);
+  }
+
+  @failingTest
+  test_inConstantContext_mapLiteral_switch_true_language218() {
+    // Expected: <Instance of 'ExpressionImpl'>
+    //   Actual: MapPatternImpl:<{}>
+    //    Which: is not an instance of 'ExpressionImpl'
+    parse('''
+// @dart=2.18
+f(v) {
+  switch (v) {
   case {}:
     break;
   }
@@ -552,6 +636,48 @@
 ''');
     assertInContext("{}", true);
   }
+
+  test_inConstantContext_recordLiteral_listLiteral_false() {
+    parse('''
+final x = [0, (1, 2)];
+''');
+    assertInContext('(1, 2)', false);
+  }
+
+  test_inConstantContext_recordLiteral_listLiteral_true() {
+    parse('''
+final x = const [0, (1, 2)];
+''');
+    assertInContext('(1, 2)', true);
+  }
+
+  test_inConstantContext_recordLiteral_namedFields_recordLiteral_false() {
+    parse('''
+final x = (0, foo: (1, 2));
+''');
+    assertInContext('(1, 2)', false);
+  }
+
+  test_inConstantContext_recordLiteral_namedFields_recordLiteral_true() {
+    parse('''
+final x = const (0, foo: (1, 2));
+''');
+    assertInContext('(1, 2)', true);
+  }
+
+  test_inConstantContext_recordLiteral_positionalFields_recordLiteral_false() {
+    parse('''
+final x = (0, (1, 2));
+''');
+    assertInContext('(1, 2)', false);
+  }
+
+  test_inConstantContext_recordLiteral_positionalFields_recordLiteral_true() {
+    parse('''
+final x = const (0, (1, 2));
+''');
+    assertInContext('(1, 2)', true);
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/ast/element_locator_test.dart b/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
index 214b03a..c7037aa 100644
--- a/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
@@ -126,7 +126,7 @@
 
   test_locate_Identifier_className() async {
     await resolveTestCode('class A {}');
-    var node = findNode.simple('A');
+    var node = findNode.classDeclaration('A');
     var element = ElementLocator.locate(node);
     expect(element, isClassElement);
   }
@@ -137,7 +137,7 @@
   A.bar();
 }
 ''');
-    var node = findNode.simple('bar');
+    var node = findNode.constructor('bar');
     var element = ElementLocator.locate(node);
     expect(element, isConstructorElement);
   }
@@ -159,7 +159,7 @@
   var x;
 }
 ''');
-    var node = findNode.simple('x;');
+    var node = findNode.variableDeclaration('x;');
     var element = ElementLocator.locate(node);
     expect(element, isFieldElement);
   }
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 ec97b24..be378db 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
@@ -9,7 +9,6 @@
 import 'package:analyzer/src/dart/ast/to_source_visitor.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
-import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
 import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -152,6 +151,21 @@
     );
   }
 
+  void test_visitBinaryPattern() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case int? _ & double? _ & Object? _:
+      break;
+  }
+}
+''');
+    _assertSource(
+      'int? _ & double? _ & Object? _',
+      findNode.binaryPattern('Object?'),
+    );
+  }
+
   void test_visitBlock_empty() {
     final code = '{}';
     final findNode = _parseStringToFindNode('''
@@ -270,6 +284,21 @@
     _assertSource(code, findNode.cascade(code));
   }
 
+  void test_visitCastPattern() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case y as int:
+      break;
+  }
+}
+''');
+    _assertSource(
+      'y as int',
+      findNode.castPattern('as '),
+    );
+  }
+
   void test_visitCatchClause_catch_noStack() {
     final code = 'catch (e) {}';
     final findNode = _parseStringToFindNode('''
@@ -351,58 +380,45 @@
   }
 
   void test_visitClassDeclaration_extends() {
-    _assertSource(
-        "class C extends A {}",
-        AstTestFactory.classDeclaration(
-            null,
-            "C",
-            null,
-            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
-            null,
-            null));
+    final code = 'class C extends A {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_extends_implements() {
-    _assertSource(
-        "class C extends A implements B {}",
-        AstTestFactory.classDeclaration(
-            null,
-            "C",
-            null,
-            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
-            null,
-            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
+    final code = 'class C extends A implements B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_extends_with() {
-    _assertSource(
-        "class C extends A with M {}",
-        AstTestFactory.classDeclaration(
-            null,
-            "C",
-            null,
-            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M")]),
-            null));
+    final code = 'class C extends A with M {}';
+    final findNode = _parseStringToFindNode('''
+$code
+void f() {}
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_extends_with_implements() {
-    _assertSource(
-        "class C extends A with M implements B {}",
-        AstTestFactory.classDeclaration(
-            null,
-            "C",
-            null,
-            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M")]),
-            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
+    final code = 'class C extends A with M implements B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+void f() {}
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_implements() {
-    _assertSource(
-        "class C implements B {}",
-        AstTestFactory.classDeclaration(null, "C", null, null, null,
-            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
+    final code = 'class C implements B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_macro() {
@@ -416,15 +432,11 @@
   }
 
   void test_visitClassDeclaration_multipleMember() {
-    _assertSource(
-        "class C {var a; var b;}",
-        AstTestFactory.classDeclaration(null, "C", null, null, null, null,
-            members: [
-              AstTestFactory.fieldDeclaration2(false, Keyword.VAR,
-                  [AstTestFactory.variableDeclaration("a")]),
-              AstTestFactory.fieldDeclaration2(
-                  false, Keyword.VAR, [AstTestFactory.variableDeclaration("b")])
-            ]));
+    final code = 'class C {var a; var b;}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_parameters() {
@@ -435,63 +447,43 @@
   }
 
   void test_visitClassDeclaration_parameters_extends() {
-    _assertSource(
-        "class C<E> extends A {}",
-        AstTestFactory.classDeclaration(
-            null,
-            "C",
-            AstTestFactory.typeParameterList(["E"]),
-            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
-            null,
-            null));
+    final code = 'class C<E> extends A {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_parameters_extends_implements() {
-    _assertSource(
-        "class C<E> extends A implements B {}",
-        AstTestFactory.classDeclaration(
-            null,
-            "C",
-            AstTestFactory.typeParameterList(["E"]),
-            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
-            null,
-            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
+    final code = 'class C<E> extends A implements B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_parameters_extends_with() {
-    _assertSource(
-        "class C<E> extends A with M {}",
-        AstTestFactory.classDeclaration(
-            null,
-            "C",
-            AstTestFactory.typeParameterList(["E"]),
-            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M")]),
-            null));
+    final code = 'class C<E> extends A with M {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_parameters_extends_with_implements() {
-    _assertSource(
-        "class C<E> extends A with M implements B {}",
-        AstTestFactory.classDeclaration(
-            null,
-            "C",
-            AstTestFactory.typeParameterList(["E"]),
-            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M")]),
-            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
+    final code = 'class C<E> extends A with M implements B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_parameters_implements() {
-    _assertSource(
-        "class C<E> implements B {}",
-        AstTestFactory.classDeclaration(
-            null,
-            "C",
-            AstTestFactory.typeParameterList(["E"]),
-            null,
-            null,
-            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
+    final code = 'class C<E> implements B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classDeclaration(code));
   }
 
   void test_visitClassDeclaration_singleMember() {
@@ -511,53 +503,36 @@
   }
 
   void test_visitClassTypeAlias_abstract() {
-    _assertSource(
-        "abstract class C = S with M1;",
-        AstTestFactory.classTypeAlias(
-            "C",
-            null,
-            Keyword.ABSTRACT,
-            AstTestFactory.namedType4("S"),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
-            null));
+    final code = 'abstract class C = S with M;';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classTypeAlias(code));
   }
 
   void test_visitClassTypeAlias_abstract_implements() {
-    _assertSource(
-        "abstract class C = S with M1 implements I;",
-        AstTestFactory.classTypeAlias(
-            "C",
-            null,
-            Keyword.ABSTRACT,
-            AstTestFactory.namedType4("S"),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
-            AstTestFactory.implementsClause([AstTestFactory.namedType4("I")])));
+    final code = 'abstract class C = S with M implements I;';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classTypeAlias(code));
   }
 
   void test_visitClassTypeAlias_abstractAugment() {
-    _assertSource(
-        "abstract augment class C = S with M1;",
-        AstTestFactory.classTypeAlias(
-            "C",
-            null,
-            Keyword.ABSTRACT,
-            AstTestFactory.namedType4("S"),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
-            null,
-            isAugmentation: true));
+    // TODO(scheglov) Is this the right order of modifiers?
+    final code = 'augment abstract class C = S with M;';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classTypeAlias('class C'));
   }
 
   void test_visitClassTypeAlias_abstractMacro() {
-    _assertSource(
-        "abstract macro class C = S with M1;",
-        AstTestFactory.classTypeAlias(
-            "C",
-            null,
-            Keyword.ABSTRACT,
-            AstTestFactory.namedType4("S"),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
-            null,
-            isMacro: true));
+    final code = 'abstract macro class C = S with M;';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classTypeAlias(code));
   }
 
   void test_visitClassTypeAlias_augment() {
@@ -571,29 +546,19 @@
   }
 
   void test_visitClassTypeAlias_generic() {
-    _assertSource(
-        "class C<E> = S<E> with M1<E>;",
-        AstTestFactory.classTypeAlias(
-            "C",
-            AstTestFactory.typeParameterList(["E"]),
-            null,
-            AstTestFactory.namedType4("S", [AstTestFactory.namedType4("E")]),
-            AstTestFactory.withClause([
-              AstTestFactory.namedType4("M1", [AstTestFactory.namedType4("E")])
-            ]),
-            null));
+    final code = 'class C<E> = S<E> with M<E>;';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classTypeAlias(code));
   }
 
   void test_visitClassTypeAlias_implements() {
-    _assertSource(
-        "class C = S with M1 implements I;",
-        AstTestFactory.classTypeAlias(
-            "C",
-            null,
-            null,
-            AstTestFactory.namedType4("S"),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
-            AstTestFactory.implementsClause([AstTestFactory.namedType4("I")])));
+    final code = 'class C = S with M implements I;';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classTypeAlias(code));
   }
 
   void test_visitClassTypeAlias_macro() {
@@ -607,51 +572,35 @@
   }
 
   void test_visitClassTypeAlias_minimal() {
-    _assertSource(
-        "class C = S with M1;",
-        AstTestFactory.classTypeAlias(
-            "C",
-            null,
-            null,
-            AstTestFactory.namedType4("S"),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
-            null));
+    final code = 'class C = S with M;';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classTypeAlias(code));
   }
 
   void test_visitClassTypeAlias_parameters_abstract() {
-    _assertSource(
-        "abstract class C<E> = S with M1;",
-        AstTestFactory.classTypeAlias(
-            "C",
-            AstTestFactory.typeParameterList(["E"]),
-            Keyword.ABSTRACT,
-            AstTestFactory.namedType4("S"),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
-            null));
+    final code = 'abstract class C<E> = S with M;';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classTypeAlias(code));
   }
 
   void test_visitClassTypeAlias_parameters_abstract_implements() {
-    _assertSource(
-        "abstract class C<E> = S with M1 implements I;",
-        AstTestFactory.classTypeAlias(
-            "C",
-            AstTestFactory.typeParameterList(["E"]),
-            Keyword.ABSTRACT,
-            AstTestFactory.namedType4("S"),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
-            AstTestFactory.implementsClause([AstTestFactory.namedType4("I")])));
+    final code = 'abstract class C<E> = S with M implements I;';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classTypeAlias(code));
   }
 
   void test_visitClassTypeAlias_parameters_implements() {
-    _assertSource(
-        "class C<E> = S with M1 implements I;",
-        AstTestFactory.classTypeAlias(
-            "C",
-            AstTestFactory.typeParameterList(["E"]),
-            null,
-            AstTestFactory.namedType4("S"),
-            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
-            AstTestFactory.implementsClause([AstTestFactory.namedType4("I")])));
+    final code = 'class C<E> = S with M implements I;';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.classTypeAlias(code));
   }
 
   void test_visitClassTypeAlias_withMetadata() {
@@ -707,6 +656,13 @@
     _assertSource("", AstTestFactory.compilationUnit());
   }
 
+  void test_visitCompilationUnit_libraryWithoutName() {
+    _assertSource(
+      "library ;",
+      AstTestFactory.compilationUnit3([AstTestFactory.libraryDirective2(null)]),
+    );
+  }
+
   void test_visitCompilationUnit_script() {
     _assertSource(
         "!#/bin/dartvm", AstTestFactory.compilationUnit5("!#/bin/dartvm"));
@@ -749,6 +705,18 @@
     _assertSource(code, findNode.conditionalExpression(code));
   }
 
+  void test_visitConstantPattern() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  if (x case true) {}
+}
+''');
+    _assertSource(
+      'true',
+      findNode.constantPattern('true'),
+    );
+  }
+
   void test_visitConstructorDeclaration_const() {
     final code = 'const A();';
     final findNode = _parseStringToFindNode('''
@@ -1055,20 +1023,19 @@
   }
 
   void test_visitExportDirective_combinator() {
-    _assertSource(
-        "export 'a.dart' show A;",
-        AstTestFactory.exportDirective2("a.dart", [
-          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")])
-        ]));
+    final code = "export 'a.dart' show A;";
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.export(code));
   }
 
   void test_visitExportDirective_combinators() {
-    _assertSource(
-        "export 'a.dart' show A hide B;",
-        AstTestFactory.exportDirective2("a.dart", [
-          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")]),
-          AstTestFactory.hideCombinator([AstTestFactory.identifier3("B")])
-        ]));
+    final code = "export 'a.dart' show A hide B;";
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.export(code));
   }
 
   void test_visitExportDirective_configurations() {
@@ -1123,255 +1090,133 @@
   }
 
   void test_visitExpressionStatement() {
-    _assertSource("a;",
-        AstTestFactory.expressionStatement(AstTestFactory.identifier3("a")));
+    final code = '1 + 2;';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code
+}
+''');
+    _assertSource(code, findNode.expressionStatement(code));
   }
 
   void test_visitExtendsClause() {
-    _assertSource("extends C",
-        AstTestFactory.extendsClause(AstTestFactory.namedType4("C")));
+    final code = 'extends A';
+    final findNode = _parseStringToFindNode('''
+class C $code {}
+''');
+    _assertSource(code, findNode.extendsClause(code));
   }
 
   void test_visitExtensionDeclaration_empty() {
-    _assertSource(
-        'extension E on C {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            isExtensionTypeDeclaration: false));
+    final code = 'extension E on C {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclaration_multipleMember() {
-    _assertSource(
-        'extension E on C {var a; var b;}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            members: [
-              AstTestFactory.fieldDeclaration2(false, Keyword.VAR,
-                  [AstTestFactory.variableDeclaration('a')]),
-              AstTestFactory.fieldDeclaration2(
-                  false, Keyword.VAR, [AstTestFactory.variableDeclaration('b')])
-            ],
-            isExtensionTypeDeclaration: false));
+    final code = 'extension E on C {static var a; static var b;}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclaration_parameters() {
-    _assertSource(
-        'extension E<T> on C {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            typeParameters: AstTestFactory.typeParameterList(['T']),
-            extendedType: AstTestFactory.namedType4('C'),
-            isExtensionTypeDeclaration: false));
+    final code = 'extension E<T> on C {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclaration_singleMember() {
-    _assertSource(
-        'extension E on C {var a;}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            members: [
-              AstTestFactory.fieldDeclaration2(
-                  false, Keyword.VAR, [AstTestFactory.variableDeclaration('a')])
-            ],
-            isExtensionTypeDeclaration: false));
+    final code = 'extension E on C {static var a;}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclarationHideClause_empty() {
-    _assertSource(
-        'extension type E on C hide B {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            hideClause:
-                AstTestFactory.hideClause([AstTestFactory.namedType4("B")]),
-            isExtensionTypeDeclaration: true));
-  }
-
-  void test_visitExtensionDeclarationHideClause_multipleMember() {
-    _assertSource(
-        'extension type E on C hide B {var a; var b;}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            members: [
-              AstTestFactory.fieldDeclaration2(false, Keyword.VAR,
-                  [AstTestFactory.variableDeclaration('a')]),
-              AstTestFactory.fieldDeclaration2(
-                  false, Keyword.VAR, [AstTestFactory.variableDeclaration('b')])
-            ],
-            hideClause:
-                AstTestFactory.hideClause([AstTestFactory.namedType4("B")]),
-            isExtensionTypeDeclaration: true));
-  }
-
-  void test_visitExtensionDeclarationHideClause_parameters() {
-    _assertSource(
-        'extension type E<T> on C hide B {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            typeParameters: AstTestFactory.typeParameterList(['T']),
-            extendedType: AstTestFactory.namedType4('C'),
-            hideClause:
-                AstTestFactory.hideClause([AstTestFactory.namedType4("B")]),
-            isExtensionTypeDeclaration: true));
-  }
-
-  void test_visitExtensionDeclarationHideClause_singleMember() {
-    _assertSource(
-        'extension type E on C hide B {var a;}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            members: [
-              AstTestFactory.fieldDeclaration2(
-                  false, Keyword.VAR, [AstTestFactory.variableDeclaration('a')])
-            ],
-            hideClause:
-                AstTestFactory.hideClause([AstTestFactory.namedType4("B")]),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension E on C hide B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclarationShowClause_ambiguousElement() {
-    _assertSource(
-        'extension type E on C show foo {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            showClause: AstTestFactory.showClause(
-                [AstTestFactory.showHideElement("foo")]),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension E on C show foo {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclarationShowClause_empty() {
-    _assertSource(
-        'extension type E on C show B {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            showClause:
-                AstTestFactory.showClause([AstTestFactory.namedType4("B")]),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension E on C show B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclarationShowClause_getterElement() {
-    _assertSource(
-        'extension type E on C show get foo {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            showClause: AstTestFactory.showClause(
-                [AstTestFactory.showHideElementGetter("foo")]),
-            isExtensionTypeDeclaration: true));
-  }
-
-  void test_visitExtensionDeclarationShowClause_multipleMember() {
-    _assertSource(
-        'extension type E on C show B {var a; var b;}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            members: [
-              AstTestFactory.fieldDeclaration2(false, Keyword.VAR,
-                  [AstTestFactory.variableDeclaration('a')]),
-              AstTestFactory.fieldDeclaration2(
-                  false, Keyword.VAR, [AstTestFactory.variableDeclaration('b')])
-            ],
-            showClause:
-                AstTestFactory.showClause([AstTestFactory.namedType4("B")]),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension E on C show get foo {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclarationShowClause_operatorElement() {
-    _assertSource(
-        'extension type E on C show operator * {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            showClause: AstTestFactory.showClause(
-                [AstTestFactory.showHideElementOperator("*")]),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension E on C show operator * {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclarationShowClause_parameters() {
-    _assertSource(
-        'extension type E<T> on C show B {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            typeParameters: AstTestFactory.typeParameterList(['T']),
-            extendedType: AstTestFactory.namedType4('C'),
-            showClause:
-                AstTestFactory.showClause([AstTestFactory.namedType4("B")]),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension E<T> on C show B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclarationShowClause_qualifiedTypeElement() {
-    _assertSource(
-        'extension type E on C show prefix.B {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            showClause: AstTestFactory.showClause([
-              AstTestFactory.namedType3(
-                  AstTestFactory.identifier5('prefix', 'B'))
-            ]),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension E on C show prefix.B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclarationShowClause_setterElement() {
-    _assertSource(
-        'extension type E on C show set foo {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            showClause: AstTestFactory.showClause(
-                [AstTestFactory.showHideElementSetter("foo")]),
-            isExtensionTypeDeclaration: true));
-  }
-
-  void test_visitExtensionDeclarationShowClause_singleMember() {
-    _assertSource(
-        'extension type E on C show B {var a;}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            members: [
-              AstTestFactory.fieldDeclaration2(
-                  false, Keyword.VAR, [AstTestFactory.variableDeclaration('a')])
-            ],
-            showClause:
-                AstTestFactory.showClause([AstTestFactory.namedType4("B")]),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension E on C show set foo {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclarationShowClause_typeWithArgumentsElement() {
-    _assertSource(
-        'extension type E on C show B<int, String> {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            showClause: AstTestFactory.showClause([
-              AstTestFactory.namedType3(AstTestFactory.identifier3('B'), [
-                AstTestFactory.namedType4('int'),
-                AstTestFactory.namedType4('String')
-              ])
-            ]),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension E on C show B<int, String> {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionDeclarationShowHideClause_empty() {
-    _assertSource(
-        'extension type E on C show B hide foo {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            showClause:
-                AstTestFactory.showClause([AstTestFactory.namedType4("B")]),
-            hideClause: AstTestFactory.hideClause(
-                [AstTestFactory.showHideElement("foo")]),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension E on C show A hide B {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionOverride_prefixedName_noTypeArgs() {
@@ -1384,81 +1229,84 @@
   }
 
   void test_visitExtensionOverride_prefixedName_typeArgs() {
-    _assertSource(
-        'p.E<A>(o)',
-        AstTestFactory.extensionOverride(
-            extensionName: AstTestFactory.identifier5('p', 'E'),
-            typeArguments: AstTestFactory.typeArgumentList(
-                [AstTestFactory.namedType4('A')]),
-            argumentList: AstTestFactory.argumentList(
-                [AstTestFactory.identifier3('o')])));
+    // TODO(scheglov) restore
+    // _assertSource(
+    //     'p.E<A>(o)',
+    //     AstTestFactory.extensionOverride(
+    //         extensionName: AstTestFactory.identifier5('p', 'E'),
+    //         typeArguments: AstTestFactory.typeArgumentList(
+    //             [AstTestFactory.namedType4('A')]),
+    //         argumentList: AstTestFactory.argumentList(
+    //             [AstTestFactory.identifier3('o')])));
   }
 
   void test_visitExtensionOverride_simpleName_noTypeArgs() {
-    _assertSource(
-        'E(o)',
-        AstTestFactory.extensionOverride(
-            extensionName: AstTestFactory.identifier3('E'),
-            argumentList: AstTestFactory.argumentList(
-                [AstTestFactory.identifier3('o')])));
+    // TODO(scheglov) restore
+    // _assertSource(
+    //     'E(o)',
+    //     AstTestFactory.extensionOverride(
+    //         extensionName: AstTestFactory.identifier3('E'),
+    //         argumentList: AstTestFactory.argumentList(
+    //             [AstTestFactory.identifier3('o')])));
   }
 
   void test_visitExtensionOverride_simpleName_typeArgs() {
-    _assertSource(
-        'E<A>(o)',
-        AstTestFactory.extensionOverride(
-            extensionName: AstTestFactory.identifier3('E'),
-            typeArguments: AstTestFactory.typeArgumentList(
-                [AstTestFactory.namedType4('A')]),
-            argumentList: AstTestFactory.argumentList(
-                [AstTestFactory.identifier3('o')])));
+    // TODO(scheglov) restore
+    // _assertSource(
+    //     'E<A>(o)',
+    //     AstTestFactory.extensionOverride(
+    //         extensionName: AstTestFactory.identifier3('E'),
+    //         typeArguments: AstTestFactory.typeArgumentList(
+    //             [AstTestFactory.namedType4('A')]),
+    //         argumentList: AstTestFactory.argumentList(
+    //             [AstTestFactory.identifier3('o')])));
   }
 
   void test_visitExtensionTypeDeclaration_empty() {
-    _assertSource(
-        'extension type E on C {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension type E on C {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionTypeDeclaration_multipleMember() {
-    _assertSource(
-        'extension type E on C {var a; var b;}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            members: [
-              AstTestFactory.fieldDeclaration2(false, Keyword.VAR,
-                  [AstTestFactory.variableDeclaration('a')]),
-              AstTestFactory.fieldDeclaration2(
-                  false, Keyword.VAR, [AstTestFactory.variableDeclaration('b')])
-            ],
-            isExtensionTypeDeclaration: true));
+    final code = 'extension type E on C {static var a; static var b;}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionTypeDeclaration_parameters() {
-    _assertSource(
-        'extension type E<T> on C {}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            typeParameters: AstTestFactory.typeParameterList(['T']),
-            extendedType: AstTestFactory.namedType4('C'),
-            isExtensionTypeDeclaration: true));
+    final code = 'extension type E<T> on C {}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
   }
 
   void test_visitExtensionTypeDeclaration_singleMember() {
+    final code = 'extension type E on C {static var a;}';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.extensionDeclaration(code));
+  }
+
+  void test_visitExtractorPattern() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case C(f: 1):
+      break;
+  }
+}
+''');
     _assertSource(
-        'extension type E on C {var a;}',
-        AstTestFactory.extensionDeclaration(
-            name: 'E',
-            extendedType: AstTestFactory.namedType4('C'),
-            members: [
-              AstTestFactory.fieldDeclaration2(
-                  false, Keyword.VAR, [AstTestFactory.variableDeclaration('a')])
-            ],
-            isExtensionTypeDeclaration: true));
+      'C(f: 1)',
+      findNode.extractorPattern('C'),
+    );
   }
 
   void test_visitFieldDeclaration_abstract() {
@@ -1513,72 +1361,79 @@
   }
 
   void test_visitFieldFormalParameter_functionTyped() {
-    _assertSource(
-        "A this.a(b)",
-        AstTestFactory.fieldFormalParameter(
-            null,
-            AstTestFactory.namedType4("A"),
-            "a",
-            AstTestFactory.formalParameterList(
-                [AstTestFactory.simpleFormalParameter3("b")])));
+    final code = 'A this.a(b)';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.fieldFormalParameter(code));
   }
 
   void test_visitFieldFormalParameter_functionTyped_typeParameters() {
-    _assertSource(
-        "A this.a<E, F>(b)",
-        astFactory.fieldFormalParameter2(
-            type: AstTestFactory.namedType4('A'),
-            thisKeyword: TokenFactory.tokenFromKeyword(Keyword.THIS),
-            period: TokenFactory.tokenFromType(TokenType.PERIOD),
-            identifier: AstTestFactory.identifier3('a'),
-            typeParameters: AstTestFactory.typeParameterList(['E', 'F']),
-            parameters: AstTestFactory.formalParameterList(
-                [AstTestFactory.simpleFormalParameter3("b")])));
+    final code = 'A this.a<E, F>(b)';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.fieldFormalParameter(code));
   }
 
   void test_visitFieldFormalParameter_keyword() {
-    _assertSource("var this.a",
-        AstTestFactory.fieldFormalParameter(Keyword.VAR, null, "a"));
+    final code = 'var this.a';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.fieldFormalParameter(code));
   }
 
   void test_visitFieldFormalParameter_keywordAndType() {
-    _assertSource(
-        "final A this.a",
-        AstTestFactory.fieldFormalParameter(
-            Keyword.FINAL, AstTestFactory.namedType4("A"), "a"));
+    final code = 'final A this.a';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.fieldFormalParameter(code));
   }
 
   void test_visitFieldFormalParameter_type() {
-    _assertSource(
-        "A this.a",
-        AstTestFactory.fieldFormalParameter(
-            null, AstTestFactory.namedType4("A"), "a"));
+    final code = 'A this.a';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.fieldFormalParameter(code));
   }
 
   void test_visitFieldFormalParameter_type_covariant() {
-    var expected = AstTestFactory.fieldFormalParameter(
-        null, AstTestFactory.namedType4("A"), "a");
-    expected.covariantKeyword =
-        TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
-    _assertSource("covariant A this.a", expected);
-  }
-
-  void test_visitForEachPartsWithDeclaration() {
-    _assertSource(
-        'var e in l',
-        astFactory.forEachPartsWithDeclaration(
-            loopVariable: AstTestFactory.declaredIdentifier3('e'),
-            inKeyword: Tokens.in_(),
-            iterable: AstTestFactory.identifier3('l')));
+    final code = 'covariant A this.a';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.fieldFormalParameter(code));
   }
 
   void test_visitForEachPartsWithIdentifier() {
-    _assertSource(
-        'e in l',
-        astFactory.forEachPartsWithIdentifier(
-            identifier: AstTestFactory.identifier3('e'),
-            inKeyword: Tokens.in_(),
-            iterable: AstTestFactory.identifier3('l')));
+    final code = 'e in []';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  for ($code) {}
+}
+''');
+    _assertSource(code, findNode.forEachPartsWithIdentifier(code));
+  }
+
+  @failingTest
+  void test_visitForEachPartsWithPattern() {
+    // TODO(brianwilkerson) Test this when the parser allows.
+    fail('Unable to parse patterns');
   }
 
   void test_visitForEachStatement_declared() {
@@ -1612,18 +1467,11 @@
   }
 
   void test_visitForElement() {
-    _assertSource(
-      'for (e in l) 0',
-      astFactory.forElement(
-          forKeyword: Tokens.for_(),
-          leftParenthesis: Tokens.openParenthesis(),
-          forLoopParts: astFactory.forEachPartsWithIdentifier(
-              identifier: AstTestFactory.identifier3('e'),
-              inKeyword: Tokens.in_(),
-              iterable: AstTestFactory.identifier3('l')),
-          rightParenthesis: Tokens.closeParenthesis(),
-          body: AstTestFactory.integer(0)),
-    );
+    final code = 'for (e in []) 0';
+    final findNode = _parseStringToFindNode('''
+final v = [ $code ];
+''');
+    _assertSource(code, findNode.forElement(code));
   }
 
   void test_visitFormalParameterList_empty() {
@@ -1751,42 +1599,39 @@
   }
 
   void test_visitForPartsWithDeclarations() {
-    _assertSource(
-        'var v; b; u',
-        astFactory.forPartsWithDeclarations(
-            variables: AstTestFactory.variableDeclarationList2(
-                Keyword.VAR, [AstTestFactory.variableDeclaration('v')]),
-            leftSeparator: Tokens.semicolon(),
-            condition: AstTestFactory.identifier3('b'),
-            rightSeparator: Tokens.semicolon(),
-            updaters: [AstTestFactory.identifier3('u')]));
+    final code = 'var v = 0; v < 10; v++';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  for ($code) {}
+}
+''');
+    _assertSource(code, findNode.forPartsWithDeclarations(code));
   }
 
   void test_visitForPartsWithExpression() {
-    _assertSource(
-        'v; b; u',
-        astFactory.forPartsWithExpression(
-            initialization: AstTestFactory.identifier3('v'),
-            leftSeparator: Tokens.semicolon(),
-            condition: AstTestFactory.identifier3('b'),
-            rightSeparator: Tokens.semicolon(),
-            updaters: [AstTestFactory.identifier3('u')]));
+    final code = 'v = 0; v < 10; v++';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  for ($code) {}
+}
+''');
+    _assertSource(code, findNode.forPartsWithExpression(code));
+  }
+
+  @failingTest
+  void test_visitForPartsWithPattern() {
+    // TODO(brianwilkerson) Test this when the parser allows.
+    fail('Unable to parse patterns');
   }
 
   void test_visitForStatement() {
-    _assertSource(
-      'for (e in l) s;',
-      astFactory.forStatement(
-          forKeyword: Tokens.for_(),
-          leftParenthesis: Tokens.openParenthesis(),
-          forLoopParts: astFactory.forEachPartsWithIdentifier(
-              identifier: AstTestFactory.identifier3('e'),
-              inKeyword: Tokens.in_(),
-              iterable: AstTestFactory.identifier3('l')),
-          rightParenthesis: Tokens.closeParenthesis(),
-          body: AstTestFactory.expressionStatement(
-              AstTestFactory.identifier3('s'))),
-    );
+    final code = 'for (var v in [0]) {}';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code
+}
+''');
+    _assertSource(code, findNode.forStatement(code));
   }
 
   void test_visitForStatement_c() {
@@ -1982,35 +1827,39 @@
   }
 
   void test_visitFunctionExpressionInvocation_minimal() {
-    _assertSource(
-        "f()",
-        AstTestFactory.functionExpressionInvocation(
-            AstTestFactory.identifier3("f")));
+    final code = '(a)()';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code;
+}
+''');
+    _assertSource(code, findNode.functionExpressionInvocation(code));
   }
 
   void test_visitFunctionExpressionInvocation_typeArguments() {
-    _assertSource(
-        "f<A>()",
-        AstTestFactory.functionExpressionInvocation2(
-            AstTestFactory.identifier3("f"),
-            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('A')])));
+    final code = '(a)<int>()';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code;
+}
+''');
+    _assertSource(code, findNode.functionExpressionInvocation(code));
   }
 
   void test_visitFunctionTypeAlias_generic() {
-    _assertSource(
-        "typedef A F<B>();",
-        AstTestFactory.typeAlias(
-            AstTestFactory.namedType4("A"),
-            "F",
-            AstTestFactory.typeParameterList(["B"]),
-            AstTestFactory.formalParameterList()));
+    final code = 'typedef A F<B>();';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.functionTypeAlias(code));
   }
 
   void test_visitFunctionTypeAlias_nonGeneric() {
-    _assertSource(
-        "typedef A F();",
-        AstTestFactory.typeAlias(AstTestFactory.namedType4("A"), "F", null,
-            AstTestFactory.formalParameterList()));
+    final code = 'typedef A F();';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.functionTypeAlias(code));
   }
 
   void test_visitFunctionTypeAlias_withMetadata() {
@@ -2033,102 +1882,77 @@
   }
 
   void test_visitFunctionTypedFormalParameter_nullable() {
-    _assertSource(
-        "T f()?",
-        astFactory.functionTypedFormalParameter2(
-            returnType: AstTestFactory.namedType4("T"),
-            identifier: AstTestFactory.identifier3('f'),
-            parameters: AstTestFactory.formalParameterList([]),
-            question: TokenFactory.tokenFromType(TokenType.QUESTION)));
+    final code = 'T f()?';
+    final findNode = _parseStringToFindNode('''
+void f($code) {}
+''');
+    _assertSource(code, findNode.functionTypedFormalParameter(code));
   }
 
   void test_visitFunctionTypedFormalParameter_type() {
-    _assertSource(
-        "T f()",
-        AstTestFactory.functionTypedFormalParameter(
-            AstTestFactory.namedType4("T"), "f"));
+    final code = 'T f()';
+    final findNode = _parseStringToFindNode('''
+void f($code) {}
+''');
+    _assertSource(code, findNode.functionTypedFormalParameter(code));
   }
 
   void test_visitFunctionTypedFormalParameter_type_covariant() {
-    var expected = AstTestFactory.functionTypedFormalParameter(
-        AstTestFactory.namedType4("T"), "f");
-    expected.covariantKeyword =
-        TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
-    _assertSource("covariant T f()", expected);
+    final code = 'covariant T f()?';
+    final findNode = _parseStringToFindNode('''
+class A {
+  void foo($code) {}
+}
+''');
+    _assertSource(code, findNode.functionTypedFormalParameter(code));
   }
 
   void test_visitFunctionTypedFormalParameter_typeParameters() {
-    _assertSource(
-        "T f<E>()",
-        astFactory.functionTypedFormalParameter2(
-            returnType: AstTestFactory.namedType4("T"),
-            identifier: AstTestFactory.identifier3('f'),
-            typeParameters: AstTestFactory.typeParameterList(['E']),
-            parameters: AstTestFactory.formalParameterList([])));
+    final code = 'T f<E>()';
+    final findNode = _parseStringToFindNode('''
+void f($code) {}
+''');
+    _assertSource(code, findNode.functionTypedFormalParameter(code));
   }
 
   void test_visitGenericFunctionType() {
-    _assertSource(
-        "int Function<T>(T)",
-        AstTestFactory.genericFunctionType(
-            AstTestFactory.namedType4("int"),
-            AstTestFactory.typeParameterList2(['T']),
-            AstTestFactory.formalParameterList([
-              AstTestFactory.simpleFormalParameter4(
-                  AstTestFactory.namedType4("T"), null)
-            ])));
+    final code = 'int Function<T>(T)';
+    final findNode = _parseStringToFindNode('''
+void f($code x) {}
+''');
+    _assertSource(code, findNode.genericFunctionType(code));
   }
 
   void test_visitGenericFunctionType_withQuestion() {
-    _assertSource(
-        "int Function<T>(T)?",
-        AstTestFactory.genericFunctionType(
-            AstTestFactory.namedType4("int"),
-            AstTestFactory.typeParameterList2(['T']),
-            AstTestFactory.formalParameterList([
-              AstTestFactory.simpleFormalParameter4(
-                  AstTestFactory.namedType4("T"), null)
-            ]),
-            question: true));
+    final code = 'int Function<T>(T)?';
+    final findNode = _parseStringToFindNode('''
+void f($code x) {}
+''');
+    _assertSource(code, findNode.genericFunctionType(code));
   }
 
   void test_visitGenericTypeAlias() {
-    _assertSource(
-        "typedef X<S> = S Function<T>(T);",
-        AstTestFactory.genericTypeAlias(
-            'X',
-            AstTestFactory.typeParameterList2(['S']),
-            AstTestFactory.genericFunctionType(
-                AstTestFactory.namedType4("S"),
-                AstTestFactory.typeParameterList2(['T']),
-                AstTestFactory.formalParameterList([
-                  AstTestFactory.simpleFormalParameter4(
-                      AstTestFactory.namedType4("T"), null)
-                ]))));
+    final code = 'typedef X<S> = S Function<T>(T);';
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.genericTypeAlias(code));
   }
 
   void test_visitIfElement_else() {
-    _assertSource(
-        'if (b) 1 else 0',
-        astFactory.ifElement(
-            ifKeyword: Tokens.if_(),
-            leftParenthesis: Tokens.openParenthesis(),
-            condition: AstTestFactory.identifier3('b'),
-            rightParenthesis: Tokens.closeParenthesis(),
-            thenElement: AstTestFactory.integer(1),
-            elseKeyword: Tokens.else_(),
-            elseElement: AstTestFactory.integer(0)));
+    final code = 'if (b) 1 else 0';
+    final findNode = _parseStringToFindNode('''
+final v = [ $code ];
+''');
+    _assertSource(code, findNode.ifElement(code));
   }
 
   void test_visitIfElement_then() {
-    _assertSource(
-        'if (b) 1',
-        astFactory.ifElement(
-            ifKeyword: Tokens.if_(),
-            leftParenthesis: Tokens.openParenthesis(),
-            condition: AstTestFactory.identifier3('b'),
-            rightParenthesis: Tokens.closeParenthesis(),
-            thenElement: AstTestFactory.integer(1)));
+    final code = 'if (b) 1';
+    final findNode = _parseStringToFindNode('''
+final v = [ $code ];
+''');
+    _assertSource(code, findNode.ifElement(code));
   }
 
   void test_visitIfStatement_withElse() {
@@ -2144,7 +1968,7 @@
   void test_visitIfStatement_withoutElse() {
     final code = 'if (c) {}';
     final findNode = _parseStringToFindNode('''
-void f () {
+void f() {
   $code
 }
 ''');
@@ -2152,32 +1976,35 @@
   }
 
   void test_visitImplementsClause_multiple() {
-    _assertSource(
-        "implements A, B",
-        AstTestFactory.implementsClause(
-            [AstTestFactory.namedType4("A"), AstTestFactory.namedType4("B")]));
+    final code = 'implements A, B';
+    final findNode = _parseStringToFindNode('''
+class C $code {}
+''');
+    _assertSource(code, findNode.implementsClause(code));
   }
 
   void test_visitImplementsClause_single() {
-    _assertSource("implements A",
-        AstTestFactory.implementsClause([AstTestFactory.namedType4("A")]));
+    final code = 'implements A';
+    final findNode = _parseStringToFindNode('''
+class C $code {}
+''');
+    _assertSource(code, findNode.implementsClause(code));
   }
 
   void test_visitImportDirective_combinator() {
-    _assertSource(
-        "import 'a.dart' show A;",
-        AstTestFactory.importDirective3("a.dart", null, [
-          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")])
-        ]));
+    final code = "import 'a.dart' show A;";
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.import(code));
   }
 
   void test_visitImportDirective_combinators() {
-    _assertSource(
-        "import 'a.dart' show A hide B;",
-        AstTestFactory.importDirective3("a.dart", null, [
-          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")]),
-          AstTestFactory.hideCombinator([AstTestFactory.identifier3("B")])
-        ]));
+    final code = "import 'a.dart' show A hide B;";
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.import(code));
   }
 
   void test_visitImportDirective_configurations() {
@@ -2211,20 +2038,19 @@
   }
 
   void test_visitImportDirective_prefix_combinator() {
-    _assertSource(
-        "import 'a.dart' as p show A;",
-        AstTestFactory.importDirective3("a.dart", "p", [
-          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")])
-        ]));
+    final code = "import 'a.dart' as p show A;";
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.import(code));
   }
 
   void test_visitImportDirective_prefix_combinators() {
-    _assertSource(
-        "import 'a.dart' as p show A hide B;",
-        AstTestFactory.importDirective3("a.dart", "p", [
-          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")]),
-          AstTestFactory.hideCombinator([AstTestFactory.identifier3("B")])
-        ]));
+    final code = "import 'a.dart' as p show A hide B;";
+    final findNode = _parseStringToFindNode('''
+$code
+''');
+    _assertSource(code, findNode.import(code));
   }
 
   void test_visitImportDirective_withMetadata() {
@@ -2234,31 +2060,35 @@
   }
 
   void test_visitImportHideCombinator_multiple() {
-    _assertSource(
-        "hide a, b",
-        AstTestFactory.hideCombinator([
-          AstTestFactory.identifier3("a"),
-          AstTestFactory.identifier3("b")
-        ]));
+    final code = 'hide A, B';
+    final findNode = _parseStringToFindNode('''
+import 'a.dart' $code;
+''');
+    _assertSource(code, findNode.hideCombinator(code));
   }
 
   void test_visitImportHideCombinator_single() {
-    _assertSource("hide a",
-        AstTestFactory.hideCombinator([AstTestFactory.identifier3("a")]));
+    final code = 'hide A';
+    final findNode = _parseStringToFindNode('''
+import 'a.dart' $code;
+''');
+    _assertSource(code, findNode.hideCombinator(code));
   }
 
   void test_visitImportShowCombinator_multiple() {
-    _assertSource(
-        "show a, b",
-        AstTestFactory.showCombinator([
-          AstTestFactory.identifier3("a"),
-          AstTestFactory.identifier3("b")
-        ]));
+    final code = 'show A, B';
+    final findNode = _parseStringToFindNode('''
+import 'a.dart' $code;
+''');
+    _assertSource(code, findNode.showCombinator(code));
   }
 
   void test_visitImportShowCombinator_single() {
-    _assertSource("show a",
-        AstTestFactory.showCombinator([AstTestFactory.identifier3("a")]));
+    final code = 'show A';
+    final findNode = _parseStringToFindNode('''
+import 'a.dart' $code;
+''');
+    _assertSource(code, findNode.showCombinator(code));
   }
 
   void test_visitIndexExpression() {
@@ -2296,7 +2126,11 @@
   }
 
   void test_visitIntegerLiteral() {
-    _assertSource("42", AstTestFactory.integer(42));
+    final code = '42';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.integerLiteral(code));
   }
 
   void test_visitInterpolationExpression_expression() {
@@ -2311,40 +2145,57 @@
   }
 
   void test_visitInterpolationString() {
-    _assertSource("'x", AstTestFactory.interpolationString("'x", "x"));
+    final code = "ccc'";
+    final findNode = _parseStringToFindNode('''
+final x = 'a\${bb}$code;
+''');
+    _assertSource(code, findNode.interpolationString(code));
   }
 
   void test_visitIsExpression_negated() {
-    _assertSource(
-        "a is! C",
-        AstTestFactory.isExpression(AstTestFactory.identifier3("a"), true,
-            AstTestFactory.namedType4("C")));
+    final code = 'a is! int';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.isExpression(code));
   }
 
   void test_visitIsExpression_normal() {
-    _assertSource(
-        "a is C",
-        AstTestFactory.isExpression(AstTestFactory.identifier3("a"), false,
-            AstTestFactory.namedType4("C")));
+    final code = 'a is int';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.isExpression(code));
   }
 
   void test_visitLabel() {
-    _assertSource("a:", AstTestFactory.label2("a"));
+    final code = 'myLabel:';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code for (final x in []) {}
+}
+''');
+    _assertSource(code, findNode.label(code));
   }
 
   void test_visitLabeledStatement_multiple() {
-    _assertSource(
-        "a: b: return;",
-        AstTestFactory.labeledStatement(
-            [AstTestFactory.label2("a"), AstTestFactory.label2("b")],
-            AstTestFactory.returnStatement()));
+    final code = 'a: b: return;';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code
+}
+''');
+    _assertSource(code, findNode.labeledStatement(code));
   }
 
   void test_visitLabeledStatement_single() {
-    _assertSource(
-        "a: return;",
-        AstTestFactory.labeledStatement(
-            [AstTestFactory.label2("a")], AstTestFactory.returnStatement()));
+    final code = 'a: return;';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code
+}
+''');
+    _assertSource(code, findNode.labeledStatement(code));
   }
 
   void test_visitLibraryAugmentationDirective() {
@@ -2383,40 +2234,11 @@
   }
 
   void test_visitListLiteral_complex() {
-    _assertSource(
-        '<int>[0, for (e in l) 0, if (b) 1, ...[0]]',
-        astFactory.listLiteral(
-            null,
-            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
-            Tokens.openSquareBracket(),
-            [
-              AstTestFactory.integer(0),
-              astFactory.forElement(
-                  forKeyword: Tokens.for_(),
-                  leftParenthesis: Tokens.openParenthesis(),
-                  forLoopParts: astFactory.forEachPartsWithIdentifier(
-                      identifier: AstTestFactory.identifier3('e'),
-                      inKeyword: Tokens.in_(),
-                      iterable: AstTestFactory.identifier3('l')),
-                  rightParenthesis: Tokens.closeParenthesis(),
-                  body: AstTestFactory.integer(0)),
-              astFactory.ifElement(
-                  ifKeyword: Tokens.if_(),
-                  leftParenthesis: Tokens.openParenthesis(),
-                  condition: AstTestFactory.identifier3('b'),
-                  rightParenthesis: Tokens.closeParenthesis(),
-                  thenElement: AstTestFactory.integer(1)),
-              astFactory.spreadElement(
-                  spreadOperator: TokenFactory.tokenFromType(
-                      TokenType.PERIOD_PERIOD_PERIOD),
-                  expression: astFactory.listLiteral(
-                      null,
-                      null,
-                      Tokens.openSquareBracket(),
-                      [AstTestFactory.integer(0)],
-                      Tokens.closeSquareBracket()))
-            ],
-            Tokens.closeSquareBracket()));
+    final code = '<int>[0, for (e in []) 0, if (b) 1, ...[0]]';
+    final findNode = _parseStringToFindNode('''
+final v = $code;
+''');
+    _assertSource(code, findNode.listLiteral(code));
   }
 
   void test_visitListLiteral_const() {
@@ -2438,43 +2260,80 @@
   }
 
   void test_visitListLiteral_withConst_withoutTypeArgs() {
-    _assertSource(
-        'const [0]',
-        astFactory.listLiteral(
-            TokenFactory.tokenFromKeyword(Keyword.CONST),
-            null,
-            Tokens.openSquareBracket(),
-            [AstTestFactory.integer(0)],
-            Tokens.closeSquareBracket()));
+    final code = 'const [0]';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.listLiteral(code));
   }
 
   void test_visitListLiteral_withConst_withTypeArgs() {
-    _assertSource(
-        'const <int>[0]',
-        astFactory.listLiteral(
-            TokenFactory.tokenFromKeyword(Keyword.CONST),
-            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
-            Tokens.openSquareBracket(),
-            [AstTestFactory.integer(0)],
-            Tokens.closeSquareBracket()));
+    final code = 'const <int>[0]';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.listLiteral(code));
   }
 
   void test_visitListLiteral_withoutConst_withoutTypeArgs() {
-    _assertSource(
-        '[0]',
-        astFactory.listLiteral(null, null, Tokens.openSquareBracket(),
-            [AstTestFactory.integer(0)], Tokens.closeSquareBracket()));
+    final code = '[0]';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.listLiteral(code));
   }
 
   void test_visitListLiteral_withoutConst_withTypeArgs() {
+    final code = '<int>[0]';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.listLiteral(code));
+  }
+
+  void test_visitListPattern_empty() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case []:
+      break;
+  }
+}
+''');
     _assertSource(
-        '<int>[0]',
-        astFactory.listLiteral(
-            null,
-            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
-            Tokens.openSquareBracket(),
-            [AstTestFactory.integer(0)],
-            Tokens.closeSquareBracket()));
+      '[]',
+      findNode.listPattern('[]'),
+    );
+  }
+
+  void test_visitListPattern_nonEmpty() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case [1, 2]:
+      break;
+  }
+}
+''');
+    _assertSource(
+      '[1, 2]',
+      findNode.listPattern('1'),
+    );
+  }
+
+  void test_visitListPattern_withTypeArguments() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case <int>[]:
+      break;
+  }
+}
+''');
+    _assertSource(
+      '<int>[]',
+      findNode.listPattern('[]'),
+    );
   }
 
   void test_visitMapLiteral_const() {
@@ -2487,18 +2346,79 @@
   }
 
   void test_visitMapLiteral_nonEmpty() {
-    _assertSource(
-        "{'a' : a, 'b' : b, 'c' : c}",
-        AstTestFactory.setOrMapLiteral(null, null, [
-          AstTestFactory.mapLiteralEntry("a", AstTestFactory.identifier3("a")),
-          AstTestFactory.mapLiteralEntry("b", AstTestFactory.identifier3("b")),
-          AstTestFactory.mapLiteralEntry("c", AstTestFactory.identifier3("c"))
-        ]));
+    final code = '{0 : a, 1 : b, 2 : c}';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitMapLiteralEntry() {
-    _assertSource("'a' : b",
-        AstTestFactory.mapLiteralEntry("a", AstTestFactory.identifier3("b")));
+    final code = '0 : a';
+    final findNode = _parseStringToFindNode('''
+final x = {$code};
+''');
+    _assertSource(code, findNode.mapLiteralEntry(code));
+  }
+
+  void test_visitMapPattern_empty() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case {}:
+      break;
+  }
+}
+''');
+    _assertSource(
+      '{}',
+      findNode.mapPattern('{}'),
+    );
+  }
+
+  void test_visitMapPattern_notEmpty() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case {1: 2}:
+      break;
+  }
+}
+''');
+    _assertSource(
+      '{1: 2}',
+      findNode.mapPattern('1'),
+    );
+  }
+
+  void test_visitMapPattern_withTypeArguments() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case <int, int>{}:
+      break;
+  }
+}
+''');
+    _assertSource(
+      '<int, int>{}',
+      findNode.mapPattern('{}'),
+    );
+  }
+
+  void test_visitMapPatternEntry() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case {1: 2}:
+      break;
+  }
+}
+''');
+    _assertSource(
+      '1: 2',
+      findNode.mapPatternEntry('1'),
+    );
   }
 
   void test_visitMethodDeclaration_external() {
@@ -2514,15 +2434,13 @@
   }
 
   void test_visitMethodDeclaration_external_returnType() {
-    _assertSource(
-        "external T m();",
-        AstTestFactory.methodDeclaration(
-            null,
-            AstTestFactory.namedType4("T"),
-            null,
-            null,
-            AstTestFactory.identifier3("m"),
-            AstTestFactory.formalParameterList()));
+    final code = 'external int foo();';
+    final findNode = _parseStringToFindNode('''
+class A {
+  $code
+}
+''');
+    _assertSource(code, findNode.methodDeclaration(code));
   }
 
   void test_visitMethodDeclaration_getter() {
@@ -2656,31 +2574,53 @@
   }
 
   void test_visitMethodInvocation_conditional() {
-    _assertSource(
-        "t?.m()",
-        AstTestFactory.methodInvocation(AstTestFactory.identifier3("t"), "m",
-            [], TokenType.QUESTION_PERIOD));
+    final code = 'a?.foo()';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code;
+}
+''');
+    _assertSource(code, findNode.methodInvocation(code));
   }
 
   void test_visitMethodInvocation_noTarget() {
-    _assertSource("m()", AstTestFactory.methodInvocation2("m"));
+    final code = 'foo()';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code;
+}
+''');
+    _assertSource(code, findNode.methodInvocation(code));
   }
 
   void test_visitMethodInvocation_target() {
-    _assertSource("t.m()",
-        AstTestFactory.methodInvocation(AstTestFactory.identifier3("t"), "m"));
+    final code = 'a.foo()';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code;
+}
+''');
+    _assertSource(code, findNode.methodInvocation(code));
   }
 
   void test_visitMethodInvocation_typeArguments() {
-    _assertSource(
-        "m<A>()",
-        AstTestFactory.methodInvocation3(null, "m",
-            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('A')])));
+    final code = 'foo<int>()';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  $code;
+}
+''');
+    _assertSource(code, findNode.methodInvocation(code));
   }
 
   void test_visitNamedExpression() {
-    _assertSource("a: b",
-        AstTestFactory.namedExpression2("a", AstTestFactory.identifier3("b")));
+    final code = 'a: 0';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  foo($code);
+}
+''');
+    _assertSource(code, findNode.namedExpression(code));
   }
 
   void test_visitNamedFormalParameter() {
@@ -2692,7 +2632,11 @@
   }
 
   void test_visitNativeClause() {
-    _assertSource("native 'code'", AstTestFactory.nativeClause("code"));
+    final code = "native 'code'";
+    final findNode = _parseStringToFindNode('''
+class A $code {}
+''');
+    _assertSource(code, findNode.nativeClause(code));
   }
 
   void test_visitNativeFunctionBody() {
@@ -2700,7 +2644,11 @@
   }
 
   void test_visitNullLiteral() {
-    _assertSource("null", AstTestFactory.nullLiteral());
+    final code = 'null';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.nullLiteral(code));
   }
 
   void test_visitParenthesizedExpression() {
@@ -2710,6 +2658,21 @@
             AstTestFactory.identifier3("a")));
   }
 
+  void test_visitParenthesizedPattern() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case (3):
+      break;
+  }
+}
+''');
+    _assertSource(
+      '(3)',
+      findNode.parenthesizedPattern('(3'),
+    );
+  }
+
   void test_visitPartDirective() {
     _assertSource("part 'a.dart';", AstTestFactory.partDirective2("a.dart"));
   }
@@ -2738,6 +2701,30 @@
     _assertSource(code, findNode.partOf(code));
   }
 
+  @failingTest
+  void test_visitPatternAssignment() {
+    // TODO(brianwilkerson) Test this when the parser allows.
+    fail('Unable to parse patterns');
+  }
+
+  @failingTest
+  void test_visitPatternAssignmentStatement() {
+    // TODO(brianwilkerson) Test this when the parser allows.
+    fail('Unable to parse patterns');
+  }
+
+  @failingTest
+  void test_visitPatternVariableDeclaration() {
+    // TODO(brianwilkerson) Test this when the parser allows.
+    fail('Unable to parse patterns');
+  }
+
+  @failingTest
+  void test_visitPatternVariableDeclarationStatement() {
+    // TODO(brianwilkerson) Test this when the parser allows.
+    fail('Unable to parse patterns');
+  }
+
   void test_visitPositionalFormalParameter() {
     final code = 'var a = 0';
     final findNode = _parseStringToFindNode('''
@@ -2753,6 +2740,21 @@
             AstTestFactory.identifier3("a"), TokenType.PLUS_PLUS));
   }
 
+  void test_visitPostfixPattern() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case true!:
+      break;
+  }
+}
+''');
+    _assertSource(
+      'true!',
+      findNode.postfixPattern('true'),
+    );
+  }
+
   void test_visitPrefixedIdentifier() {
     _assertSource("a.b", AstTestFactory.identifier5("a", "b"));
   }
@@ -2819,6 +2821,66 @@
     );
   }
 
+  void test_visitRecordPattern() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case (1, 2):
+      break;
+  }
+}
+''');
+    _assertSource(
+      '(1, 2)',
+      findNode.recordPattern('(1'),
+    );
+  }
+
+  void test_visitRecordPatternField_named() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case (a: 1):
+      break;
+  }
+}
+''');
+    _assertSource(
+      'a: 1',
+      findNode.recordPatternField('1'),
+    );
+  }
+
+  void test_visitRecordPatternField_positional() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case (1,):
+      break;
+  }
+}
+''');
+    _assertSource(
+      '1',
+      findNode.recordPatternField('1'),
+    );
+  }
+
+  void test_visitRecordPatternFieldName() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case (b: 2):
+      break;
+  }
+}
+''');
+    _assertSource(
+      'b:',
+      findNode.recordPatternFieldName('b:'),
+    );
+  }
+
   void test_visitRecordTypeAnnotation_mixed() {
     final code = '(int, bool, {int a, bool b})';
     var findNode = _parseStringToFindNode('''
@@ -2852,6 +2914,17 @@
     );
   }
 
+  void test_visitRecordTypeAnnotation_positional_nullable() {
+    final code = '(int, bool)?';
+    var findNode = _parseStringToFindNode('''
+$code f() {}
+''');
+    _assertSource(
+      code,
+      findNode.recordTypeAnnotation(code),
+    );
+  }
+
   void test_visitRedirectingConstructorInvocation_named() {
     _assertSource(
         "this.c()", AstTestFactory.redirectingConstructorInvocation2("c"));
@@ -2861,6 +2934,21 @@
     _assertSource("this()", AstTestFactory.redirectingConstructorInvocation());
   }
 
+  void test_visitRelationalPattern() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case > 3:
+      break;
+  }
+}
+''');
+    _assertSource(
+      '> 3',
+      findNode.relationalPattern('>'),
+    );
+  }
+
   void test_visitRethrowExpression() {
     _assertSource("rethrow", AstTestFactory.rethrowExpression());
   }
@@ -2880,193 +2968,84 @@
   }
 
   void test_visitSetOrMapLiteral_map_complex() {
-    _assertSource(
-      "<String, String>{'a' : 'b', for (c in d) 'e' : 'f', if (g) 'h' : 'i', ...{'j' : 'k'}}",
-      astFactory.setOrMapLiteral(
-        leftBracket: Tokens.openCurlyBracket(),
-        typeArguments: AstTestFactory.typeArgumentList([
-          AstTestFactory.namedType4('String'),
-          AstTestFactory.namedType4('String')
-        ]),
-        elements: [
-          AstTestFactory.mapLiteralEntry3('a', 'b'),
-          astFactory.forElement(
-              forKeyword: Tokens.for_(),
-              leftParenthesis: Tokens.openParenthesis(),
-              forLoopParts: astFactory.forEachPartsWithIdentifier(
-                identifier: AstTestFactory.identifier3('c'),
-                inKeyword: Tokens.in_(),
-                iterable: AstTestFactory.identifier3('d'),
-              ),
-              rightParenthesis: Tokens.closeParenthesis(),
-              body: AstTestFactory.mapLiteralEntry3('e', 'f')),
-          astFactory.ifElement(
-            ifKeyword: Tokens.if_(),
-            leftParenthesis: Tokens.openParenthesis(),
-            condition: AstTestFactory.identifier3('g'),
-            rightParenthesis: Tokens.closeParenthesis(),
-            thenElement: AstTestFactory.mapLiteralEntry3('h', 'i'),
-          ),
-          astFactory.spreadElement(
-            spreadOperator:
-                TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD),
-            expression: astFactory.setOrMapLiteral(
-              leftBracket: Tokens.openCurlyBracket(),
-              elements: [AstTestFactory.mapLiteralEntry3('j', 'k')],
-              rightBracket: Tokens.closeCurlyBracket(),
-            ),
-          )
-        ],
-        rightBracket: Tokens.closeCurlyBracket(),
-      ),
-    );
+    final code =
+        "<String, String>{'a' : 'b', for (c in d) 'e' : 'f', if (g) 'h' : 'i', ...{'j' : 'k'}}";
+    final findNode = _parseStringToFindNode('''
+final v = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitSetOrMapLiteral_map_withConst_withoutTypeArgs() {
-    _assertSource(
-      "const {'a' : 'b'}",
-      astFactory.setOrMapLiteral(
-        leftBracket: Tokens.openCurlyBracket(),
-        constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
-        elements: [AstTestFactory.mapLiteralEntry3('a', 'b')],
-        rightBracket: Tokens.closeCurlyBracket(),
-      ),
-    );
+    final code = 'const {0 : a}';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitSetOrMapLiteral_map_withConst_withTypeArgs() {
-    _assertSource(
-      "const <String, String>{'a' : 'b'}",
-      astFactory.setOrMapLiteral(
-        constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
-        typeArguments: AstTestFactory.typeArgumentList([
-          AstTestFactory.namedType4('String'),
-          AstTestFactory.namedType4('String')
-        ]),
-        leftBracket: Tokens.openCurlyBracket(),
-        elements: [AstTestFactory.mapLiteralEntry3('a', 'b')],
-        rightBracket: Tokens.closeCurlyBracket(),
-      ),
-    );
+    final code = 'const <int, String>{0 : a}';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitSetOrMapLiteral_map_withoutConst_withoutTypeArgs() {
-    _assertSource(
-      "{'a' : 'b'}",
-      astFactory.setOrMapLiteral(
-        leftBracket: Tokens.openCurlyBracket(),
-        elements: [AstTestFactory.mapLiteralEntry3('a', 'b')],
-        rightBracket: Tokens.closeCurlyBracket(),
-      ),
-    );
+    final code = '{0 : a}';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitSetOrMapLiteral_map_withoutConst_withTypeArgs() {
-    _assertSource(
-      "<String, String>{'a' : 'b'}",
-      astFactory.setOrMapLiteral(
-        typeArguments: AstTestFactory.typeArgumentList([
-          AstTestFactory.namedType4('String'),
-          AstTestFactory.namedType4('String')
-        ]),
-        leftBracket: Tokens.openCurlyBracket(),
-        elements: [AstTestFactory.mapLiteralEntry3('a', 'b')],
-        rightBracket: Tokens.closeCurlyBracket(),
-      ),
-    );
+    final code = '<int, String>{0 : a}';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitSetOrMapLiteral_set_complex() {
-    _assertSource(
-      '<int>{0, for (e in l) 0, if (b) 1, ...[0]}',
-      astFactory.setOrMapLiteral(
-        typeArguments:
-            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
-        leftBracket: Tokens.openCurlyBracket(),
-        elements: [
-          AstTestFactory.integer(0),
-          astFactory.forElement(
-              forKeyword: Tokens.for_(),
-              leftParenthesis: Tokens.openParenthesis(),
-              forLoopParts: astFactory.forEachPartsWithIdentifier(
-                identifier: AstTestFactory.identifier3('e'),
-                inKeyword: Tokens.in_(),
-                iterable: AstTestFactory.identifier3('l'),
-              ),
-              rightParenthesis: Tokens.closeParenthesis(),
-              body: AstTestFactory.integer(0)),
-          astFactory.ifElement(
-            ifKeyword: Tokens.if_(),
-            leftParenthesis: Tokens.openParenthesis(),
-            condition: AstTestFactory.identifier3('b'),
-            rightParenthesis: Tokens.closeParenthesis(),
-            thenElement: AstTestFactory.integer(1),
-          ),
-          astFactory.spreadElement(
-            spreadOperator:
-                TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD),
-            expression: astFactory.listLiteral(
-              null,
-              null,
-              Tokens.openSquareBracket(),
-              [AstTestFactory.integer(0)],
-              Tokens.closeSquareBracket(),
-            ),
-          )
-        ],
-        rightBracket: Tokens.closeCurlyBracket(),
-      ),
-    );
+    final code = '<int>{0, for (e in l) 0, if (b) 1, ...[0]}';
+    final findNode = _parseStringToFindNode('''
+final v = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitSetOrMapLiteral_set_withConst_withoutTypeArgs() {
-    _assertSource(
-      'const {0}',
-      astFactory.setOrMapLiteral(
-        constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
-        leftBracket: Tokens.openCurlyBracket(),
-        elements: [AstTestFactory.integer(0)],
-        rightBracket: Tokens.closeCurlyBracket(),
-      ),
-    );
+    final code = 'const {0}';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitSetOrMapLiteral_set_withConst_withTypeArgs() {
-    _assertSource(
-      'const <int>{0}',
-      astFactory.setOrMapLiteral(
-        constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
-        typeArguments:
-            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
-        leftBracket: Tokens.openCurlyBracket(),
-        elements: [AstTestFactory.integer(0)],
-        rightBracket: Tokens.closeCurlyBracket(),
-      ),
-    );
+    final code = 'const <int>{0}';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitSetOrMapLiteral_set_withoutConst_withoutTypeArgs() {
-    _assertSource(
-      '{0}',
-      astFactory.setOrMapLiteral(
-        leftBracket: Tokens.openCurlyBracket(),
-        elements: [AstTestFactory.integer(0)],
-        rightBracket: Tokens.closeCurlyBracket(),
-      ),
-    );
+    final code = '{0}';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitSetOrMapLiteral_set_withoutConst_withTypeArgs() {
-    _assertSource(
-      '<int>{0}',
-      astFactory.setOrMapLiteral(
-        typeArguments:
-            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
-        leftBracket: Tokens.openCurlyBracket(),
-        elements: [AstTestFactory.integer(0)],
-        rightBracket: Tokens.closeCurlyBracket(),
-      ),
-    );
+    final code = '<int>{0}';
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.setOrMapLiteral(code));
   }
 
   void test_visitSimpleFormalParameter_annotation() {
@@ -3083,25 +3062,29 @@
   }
 
   void test_visitSimpleFormalParameter_keyword_type() {
-    _assertSource(
-        "final A a",
-        AstTestFactory.simpleFormalParameter2(
-            Keyword.FINAL, AstTestFactory.namedType4("A"), "a"));
+    final code = 'final int a';
+    final findNode = _parseStringToFindNode('''
+void f($code) {}
+''');
+    _assertSource(code, findNode.simpleFormalParameter(code));
   }
 
   void test_visitSimpleFormalParameter_type() {
-    _assertSource(
-        "A a",
-        AstTestFactory.simpleFormalParameter4(
-            AstTestFactory.namedType4("A"), "a"));
+    final code = 'int a';
+    final findNode = _parseStringToFindNode('''
+void f($code) {}
+''');
+    _assertSource(code, findNode.simpleFormalParameter(code));
   }
 
   void test_visitSimpleFormalParameter_type_covariant() {
-    var expected = AstTestFactory.simpleFormalParameter4(
-        AstTestFactory.namedType4("A"), "a");
-    expected.covariantKeyword =
-        TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
-    _assertSource("covariant A a", expected);
+    final code = 'covariant int a';
+    final findNode = _parseStringToFindNode('''
+class A {
+  void foo($code) {}
+}
+''');
+    _assertSource(code, findNode.simpleFormalParameter(code));
   }
 
   void test_visitSimpleIdentifier() {
@@ -3113,45 +3096,27 @@
   }
 
   void test_visitSpreadElement_nonNullable() {
-    _assertSource(
-        '...[0]',
-        astFactory.spreadElement(
-            spreadOperator:
-                TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD),
-            expression: astFactory.listLiteral(
-                null,
-                null,
-                Tokens.openSquareBracket(),
-                [AstTestFactory.integer(0)],
-                Tokens.closeSquareBracket())));
+    final code = '...[0]';
+    final findNode = _parseStringToFindNode('''
+final x = [$code];
+''');
+    _assertSource(code, findNode.spreadElement(code));
   }
 
-  @failingTest
   void test_visitSpreadElement_nullable() {
-    // TODO(brianwilkerson) Replace the token type below when there is one for
-    //  '...?'.
-    _assertSource(
-        '...?[0]',
-        astFactory.spreadElement(
-            spreadOperator:
-                TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD),
-            expression: astFactory.listLiteral(
-                null,
-                null,
-                Tokens.openSquareBracket(),
-                [AstTestFactory.integer(0)],
-                Tokens.closeSquareBracket())));
+    final code = '...?[0]';
+    final findNode = _parseStringToFindNode('''
+final x = [$code];
+''');
+    _assertSource(code, findNode.spreadElement(code));
   }
 
   void test_visitStringInterpolation() {
-    _assertSource(
-        "'a\${e}b'",
-        AstTestFactory.string([
-          AstTestFactory.interpolationString("'a", "a"),
-          AstTestFactory.interpolationExpression(
-              AstTestFactory.identifier3("e")),
-          AstTestFactory.interpolationString("b'", "b")
-        ]));
+    final code = r"'a${bb}ccc'";
+    final findNode = _parseStringToFindNode('''
+final x = $code;
+''');
+    _assertSource(code, findNode.stringInterpolation(code));
   }
 
   void test_visitSuperConstructorInvocation() {
@@ -3177,27 +3142,23 @@
   }
 
   void test_visitSuperFormalParameter_functionTyped() {
-    _assertSource(
-        "A super.a(b)",
-        AstTestFactory.superFormalParameter(
-            null,
-            AstTestFactory.namedType4("A"),
-            "a",
-            AstTestFactory.formalParameterList(
-                [AstTestFactory.simpleFormalParameter3("b")])));
+    final code = 'int super.a(b)';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.superFormalParameter(code));
   }
 
   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")])));
+    final code = 'int super.a<E, F>(b)';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.superFormalParameter(code));
   }
 
   void test_visitSuperFormalParameter_keyword() {
@@ -3206,30 +3167,39 @@
   }
 
   void test_visitSuperFormalParameter_keywordAndType() {
-    _assertSource(
-        "final A super.a",
-        AstTestFactory.superFormalParameter(
-            Keyword.FINAL, AstTestFactory.namedType4("A"), "a"));
+    final code = 'final int super.a';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.superFormalParameter(code));
   }
 
   void test_visitSuperFormalParameter_type() {
-    _assertSource(
-        "A super.a",
-        AstTestFactory.superFormalParameter(
-            null, AstTestFactory.namedType4("A"), "a"));
+    final code = 'int super.a';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.superFormalParameter(code));
   }
 
   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);
+    final code = 'covariant int super.a';
+    final findNode = _parseStringToFindNode('''
+class A {
+  A($code);
+}
+''');
+    _assertSource(code, findNode.superFormalParameter(code));
   }
 
   void test_visitSwitchCase_multipleLabels() {
     final code = 'l1: l2: case a: {}';
     final findNode = _parseStringToFindNode('''
+// @dart=2.18
 void f() {
   switch (x) {
     $code
@@ -3242,6 +3212,7 @@
   void test_visitSwitchCase_multipleStatements() {
     final code = 'case a: foo(); bar();';
     final findNode = _parseStringToFindNode('''
+// @dart=2.18
 void f() {
   switch (x) {
     $code
@@ -3254,6 +3225,7 @@
   void test_visitSwitchCase_noLabels() {
     final code = 'case a: {}';
     final findNode = _parseStringToFindNode('''
+// @dart=2.18
 void f() {
   switch (x) {
     $code
@@ -3266,6 +3238,7 @@
   void test_visitSwitchCase_singleLabel() {
     final code = 'l1: case a: {}';
     final findNode = _parseStringToFindNode('''
+// @dart=2.18
 void f() {
   switch (x) {
     $code
@@ -3323,6 +3296,78 @@
     _assertSource(code, findNode.switchDefault(code));
   }
 
+  @failingTest
+  void test_visitSwitchExpression() {
+    // TODO(brianwilkerson) Test this when the parser allows.
+    fail('Unable to parse patterns');
+  }
+
+  @failingTest
+  void test_visitSwitchExpressionCase() {
+    // TODO(brianwilkerson) Test this when the parser allows.
+    fail('Unable to parse patterns');
+  }
+
+  @failingTest
+  void test_visitSwitchExpressionDefault() {
+    // TODO(brianwilkerson) Test this when the parser allows.
+    fail('Unable to parse patterns');
+  }
+
+  @failingTest
+  void test_visitSwitchGuard() {
+    // TODO(brianwilkerson) Test this when the parser allows.
+    fail('Unable to parse patterns');
+  }
+
+  void test_visitSwitchPatternCase_multipleLabels() {
+    final code = 'l1: l2: case a: {}';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  switch (x) {
+    $code
+  }
+}
+''');
+    _assertSource(code, findNode.switchPatternCase(code));
+  }
+
+  void test_visitSwitchPatternCase_multipleStatements() {
+    final code = 'case a: foo(); bar();';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  switch (x) {
+    $code
+  }
+}
+''');
+    _assertSource(code, findNode.switchPatternCase(code));
+  }
+
+  void test_visitSwitchPatternCase_noLabels() {
+    final code = 'case a: {}';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  switch (x) {
+    $code
+  }
+}
+''');
+    _assertSource(code, findNode.switchPatternCase(code));
+  }
+
+  void test_visitSwitchPatternCase_singleLabel() {
+    final code = 'l1: case a: {}';
+    final findNode = _parseStringToFindNode('''
+void f() {
+  switch (x) {
+    $code
+  }
+}
+''');
+    _assertSource(code, findNode.switchPatternCase(code));
+  }
+
   void test_visitSwitchStatement() {
     final code = 'switch (x) {case 0: foo(); default: bar();}';
     final findNode = _parseStringToFindNode('''
@@ -3415,48 +3460,67 @@
   }
 
   void test_visitTypeArgumentList_multiple() {
-    _assertSource(
-        "<E, F>",
-        AstTestFactory.typeArgumentList2(
-            [AstTestFactory.namedType4("E"), AstTestFactory.namedType4("F")]));
+    final code = '<int, String>';
+    final findNode = _parseStringToFindNode('''
+final x = $code[];
+''');
+    _assertSource(code, findNode.typeArgumentList(code));
   }
 
   void test_visitTypeArgumentList_single() {
-    _assertSource("<E>",
-        AstTestFactory.typeArgumentList2([AstTestFactory.namedType4("E")]));
+    final code = '<int>';
+    final findNode = _parseStringToFindNode('''
+final x = $code[];
+''');
+    _assertSource(code, findNode.typeArgumentList(code));
   }
 
   void test_visitTypeName_multipleArgs() {
-    _assertSource(
-        "C<D, E>",
-        AstTestFactory.namedType4("C",
-            [AstTestFactory.namedType4("D"), AstTestFactory.namedType4("E")]));
+    final code = 'Map<int, String>';
+    final findNode = _parseStringToFindNode('''
+final x = <$code>[];
+''');
+    _assertSource(code, findNode.namedType(code));
   }
 
   void test_visitTypeName_nestedArg() {
-    _assertSource(
-        "C<D<E>>",
-        AstTestFactory.namedType4("C", [
-          AstTestFactory.namedType4("D", [AstTestFactory.namedType4("E")])
-        ]));
+    final code = 'List<Set<int>>';
+    final findNode = _parseStringToFindNode('''
+final x = <$code>[];
+''');
+    _assertSource(code, findNode.namedType(code));
   }
 
   void test_visitTypeName_noArgs() {
-    _assertSource("C", AstTestFactory.namedType4("C"));
+    final code = 'int';
+    final findNode = _parseStringToFindNode('''
+final x = <$code>[];
+''');
+    _assertSource(code, findNode.namedType(code));
   }
 
   void test_visitTypeName_noArgs_withQuestion() {
-    _assertSource("C?", AstTestFactory.namedType4("C", null, true));
+    final code = 'int?';
+    final findNode = _parseStringToFindNode('''
+final x = <$code>[];
+''');
+    _assertSource(code, findNode.namedType(code));
   }
 
   void test_visitTypeName_singleArg() {
-    _assertSource("C<D>",
-        AstTestFactory.namedType4("C", [AstTestFactory.namedType4("D")]));
+    final code = 'Set<int>';
+    final findNode = _parseStringToFindNode('''
+final x = <$code>[];
+''');
+    _assertSource(code, findNode.namedType(code));
   }
 
   void test_visitTypeName_singleArg_withQuestion() {
-    _assertSource("C<D>?",
-        AstTestFactory.namedType4("C", [AstTestFactory.namedType4("D")], true));
+    final code = 'Set<int>?';
+    final findNode = _parseStringToFindNode('''
+final x = <$code>[];
+''');
+    _assertSource(code, findNode.namedType(code));
   }
 
   void test_visitTypeParameter_variance_contravariant() {
@@ -3472,8 +3536,11 @@
   }
 
   void test_visitTypeParameter_withExtends() {
-    _assertSource("E extends C",
-        AstTestFactory.typeParameter2("E", AstTestFactory.namedType4("C")));
+    final code = 'T extends num';
+    final findNode = _parseStringToFindNode('''
+class A<$code> {}
+''');
+    _assertSource(code, findNode.typeParameter(code));
   }
 
   void test_visitTypeParameter_withMetadata() {
@@ -3508,50 +3575,58 @@
   }
 
   void test_visitVariableDeclarationList_const_type() {
-    _assertSource(
-        "const C a, b",
-        AstTestFactory.variableDeclarationList(
-            Keyword.CONST, AstTestFactory.namedType4("C"), [
-          AstTestFactory.variableDeclaration("a"),
-          AstTestFactory.variableDeclaration("b")
-        ]));
+    final code = 'const int a = 0, b = 0';
+    final findNode = _parseStringToFindNode('''
+$code;
+''');
+    _assertSource(code, findNode.variableDeclarationList(code));
   }
 
   void test_visitVariableDeclarationList_final_noType() {
-    _assertSource(
-        "final a, b",
-        AstTestFactory.variableDeclarationList2(Keyword.FINAL, [
-          AstTestFactory.variableDeclaration("a"),
-          AstTestFactory.variableDeclaration("b")
-        ]));
+    final code = 'final a = 0, b = 0';
+    final findNode = _parseStringToFindNode('''
+$code;
+''');
+    _assertSource(code, findNode.variableDeclarationList(code));
   }
 
   void test_visitVariableDeclarationList_type() {
-    _assertSource(
-        "C a, b",
-        AstTestFactory.variableDeclarationList(
-            null, AstTestFactory.namedType4("C"), [
-          AstTestFactory.variableDeclaration("a"),
-          AstTestFactory.variableDeclaration("b")
-        ]));
+    final code = 'int a, b';
+    final findNode = _parseStringToFindNode('''
+$code;
+''');
+    _assertSource(code, findNode.variableDeclarationList(code));
   }
 
   void test_visitVariableDeclarationList_var() {
-    _assertSource(
-        "var a, b",
-        AstTestFactory.variableDeclarationList2(Keyword.VAR, [
-          AstTestFactory.variableDeclaration("a"),
-          AstTestFactory.variableDeclaration("b")
-        ]));
+    final code = 'var a, b';
+    final findNode = _parseStringToFindNode('''
+$code;
+''');
+    _assertSource(code, findNode.variableDeclarationList(code));
   }
 
   void test_visitVariableDeclarationStatement() {
+    final code = 'int a';
+    final findNode = _parseStringToFindNode('''
+$code;
+''');
+    _assertSource(code, findNode.variableDeclarationList(code));
+  }
+
+  void test_visitVariablePattern() {
+    var findNode = _parseStringToFindNode('''
+void f(x) {
+  switch (x) {
+    case int? _:
+      break;
+  }
+}
+''');
     _assertSource(
-        "C c;",
-        AstTestFactory.variableDeclarationStatement(
-            null,
-            AstTestFactory.namedType4("C"),
-            [AstTestFactory.variableDeclaration("c")]));
+      'int? _',
+      findNode.variablePattern('int?'),
+    );
   }
 
   void test_visitWhileStatement() {
@@ -3565,18 +3640,19 @@
   }
 
   void test_visitWithClause_multiple() {
-    _assertSource(
-        "with A, B, C",
-        AstTestFactory.withClause([
-          AstTestFactory.namedType4("A"),
-          AstTestFactory.namedType4("B"),
-          AstTestFactory.namedType4("C")
-        ]));
+    final code = 'with A, B, C';
+    final findNode = _parseStringToFindNode('''
+class X $code {}
+''');
+    _assertSource(code, findNode.withClause(code));
   }
 
   void test_visitWithClause_single() {
-    _assertSource(
-        "with A", AstTestFactory.withClause([AstTestFactory.namedType4("A")]));
+    final code = 'with M';
+    final findNode = _parseStringToFindNode('''
+class X $code {}
+''');
+    _assertSource(code, findNode.withClause(code));
   }
 
   void test_visitYieldStatement() {
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 7468a58..0282b26 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -18,7 +18,18 @@
 }
 
 @reflectiveTest
-class NodeLocator2Test extends ParserTestCase {
+class NodeLocator2Test extends _SharedNodeLocatorTests {
+  @override
+  AstNode? locate(
+    CompilationUnit unit,
+    int start, [
+    int? end,
+  ]) {
+    var locator = NodeLocator2(start, end);
+    var node = locator.searchWithin(unit)!;
+    return node;
+  }
+
   void test_onlyStartOffset() {
     String code = ' int vv; ';
     //             012345678
@@ -26,15 +37,11 @@
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     VariableDeclarationList variableList = declaration.variables;
     Identifier typeName = (variableList.type as NamedType).name;
-    // ignore: deprecated_member_use_from_same_package
-    SimpleIdentifier varName = variableList.variables[0].name;
     expect(NodeLocator2(0).searchWithin(unit), same(unit));
     expect(NodeLocator2(1).searchWithin(unit), same(typeName));
     expect(NodeLocator2(2).searchWithin(unit), same(typeName));
     expect(NodeLocator2(3).searchWithin(unit), same(typeName));
     expect(NodeLocator2(4).searchWithin(unit), same(variableList));
-    expect(NodeLocator2(5).searchWithin(unit), same(varName));
-    expect(NodeLocator2(6).searchWithin(unit), same(varName));
     expect(NodeLocator2(7).searchWithin(unit), same(declaration));
     expect(NodeLocator2(8).searchWithin(unit), same(unit));
     expect(NodeLocator2(9).searchWithin(unit), isNull);
@@ -48,14 +55,11 @@
     var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
     VariableDeclarationList variableList = declaration.variables;
     Identifier typeName = (variableList.type as NamedType).name;
-    // ignore: deprecated_member_use_from_same_package
-    SimpleIdentifier varName = variableList.variables[0].name;
     expect(NodeLocator2(-1, 2).searchWithin(unit), isNull);
     expect(NodeLocator2(0, 2).searchWithin(unit), same(unit));
     expect(NodeLocator2(1, 2).searchWithin(unit), same(typeName));
     expect(NodeLocator2(1, 3).searchWithin(unit), same(typeName));
     expect(NodeLocator2(1, 4).searchWithin(unit), same(variableList));
-    expect(NodeLocator2(5, 6).searchWithin(unit), same(varName));
     expect(NodeLocator2(5, 7).searchWithin(unit), same(declaration));
     expect(NodeLocator2(5, 8).searchWithin(unit), same(unit));
     expect(NodeLocator2(5, 100).searchWithin(unit), isNull);
@@ -64,7 +68,19 @@
 }
 
 @reflectiveTest
-class NodeLocatorTest extends ParserTestCase {
+class NodeLocatorTest extends _SharedNodeLocatorTests {
+  @override
+  AstNode? locate(
+    CompilationUnit unit,
+    int start, [
+    int? end,
+  ]) {
+    var locator = NodeLocator(start, end);
+    var node = locator.searchWithin(unit)!;
+    expect(locator.foundNode, same(node));
+    return node;
+  }
+
   void test_range() {
     CompilationUnit unit = parseCompilationUnit("library myLib;");
     var node = _assertLocate(unit, 4, 10);
@@ -99,15 +115,94 @@
     var node = locator.searchWithin(unit.declarations[1]);
     expect(node, isNull);
   }
+}
+
+abstract class _SharedNodeLocatorTests extends ParserTestCase {
+  AstNode? locate(
+    CompilationUnit unit,
+    int start, [
+    int? end,
+  ]);
+
+  void test_searchWithin_constructor_afterName_beforeParameters() {
+    var source = r'''
+class A {
+  A() {}
+}
+''';
+    var unit = parseCompilationUnit(source);
+    // TODO(dantup): Update these tests to use markers.
+    var node = _assertLocate(unit, source.indexOf('() {}'));
+    expect(node, isConstructorDeclaration);
+  }
+
+  void test_searchWithin_function_afterName_beforeParameters() {
+    var source = r'''
+void f() {}
+''';
+    var unit = parseCompilationUnit(source);
+    var node = _assertLocate(unit, source.indexOf('() {}'));
+    expect(node, isFunctionDeclaration);
+  }
+
+  void test_searchWithin_function_afterName_beforeTypeParameters() {
+    var source = r'''
+void f<T>() {}
+''';
+    var unit = parseCompilationUnit(source);
+    var node = _assertLocate(unit, source.indexOf('<T>() {}'));
+    expect(node, isFunctionDeclaration);
+  }
+
+  void test_searchWithin_method_afterName_beforeParameters() {
+    var source = r'''
+class A {
+  void m() {}
+}
+''';
+    var unit = parseCompilationUnit(source);
+    var node = _assertLocate(unit, source.indexOf('() {}'));
+    expect(node, isMethodDeclaration);
+  }
+
+  void test_searchWithin_method_afterName_beforeTypeParameters() {
+    var source = r'''
+class A {
+  void m<T>() {}
+}
+''';
+    var unit = parseCompilationUnit(source);
+    var node = _assertLocate(unit, source.indexOf('<T>() {}'));
+    expect(node, isMethodDeclaration);
+  }
+
+  void test_searchWithin_namedConstructor_afterName_beforeParameters() {
+    var source = r'''
+class A {
+  A.c() {}
+}
+''';
+    var unit = parseCompilationUnit(source);
+    var node = _assertLocate(unit, source.indexOf('() {}'));
+    expect(node, isConstructorDeclaration);
+  }
+
+  void test_searchWithin_setter_afterName_beforeParameters() {
+    var source = r'''
+set s(int i) {}
+''';
+    var unit = parseCompilationUnit(source);
+    var node = _assertLocate(unit, source.indexOf('(int i)'));
+    expect(node, isFunctionDeclaration);
+  }
 
   AstNode _assertLocate(
     CompilationUnit unit,
-    int start,
-    int end,
-  ) {
-    NodeLocator locator = NodeLocator(start, end);
-    var node = locator.searchWithin(unit)!;
-    expect(locator.foundNode, same(node));
+    int start, [
+    int? end,
+  ]) {
+    end ??= start;
+    var node = locate(unit, start, end)!;
     expect(node.offset <= start, isTrue, reason: "Node starts after range");
     expect(node.offset + node.length > end, isTrue,
         reason: "Node ends before range");
diff --git a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
index 2b32a30..7c51f98 100644
--- a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
@@ -1039,6 +1039,36 @@
 ''', () => _xInitializer(), () => [findNode.propertyAccess('p.a.b + 1')]);
   }
 
+  test_recordLiteral() async {
+    await _assertConst(r'''
+var x = const (0, 1, 2);
+''', () => _xInitializer());
+  }
+
+  test_recordLiteral_constructorParameter() async {
+    await _assertConst(r'''
+class C {
+  final Object f;
+  const C(int a) : f = (0, a);
+}
+''', () => findNode.recordLiteral('(0'));
+  }
+
+  test_recordLiteral_notConst() async {
+    await _assertConst(r'''
+var x = (0, 1, 2);
+''', () => _xInitializer());
+  }
+
+  test_recordLiteral_notConst_element() async {
+    await _assertNotConst(r'''
+final a = 0;
+final b = 1;
+var x = const (a, b, 2);
+''', () => _xInitializer(),
+        () => [findNode.simple('a,'), findNode.simple('b,')]);
+  }
+
   test_setLiteral() async {
     await _assertConst(r'''
 var x = const {0, 1, 2};
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index 08999f7..eac71ce 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -473,6 +473,25 @@
     expect(_symbolValue("a"), _symbolValue("a"));
   }
 
+  void test_getField_record() {
+    final record = _recordValue([
+      _intValue(0),
+      _intValue(1),
+    ], {
+      'a': _intValue(2),
+      'b': _intValue(3),
+    });
+
+    expect(record.getField(r'$0'), _intValue(0));
+    expect(record.getField(r'$1'), _intValue(1));
+    expect(record.getField(r'$2'), isNull);
+    expect(record.getField(r'$-2'), isNull);
+
+    expect(record.getField(r'a'), _intValue(2));
+    expect(record.getField(r'b'), _intValue(3));
+    expect(record.getField(r'c'), isNull);
+  }
+
   void test_getValue_bool_false() {
     expect(_boolValue(false).toBoolValue(), false);
   }
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index a900ede..f195ad5 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -112,62 +112,6 @@
     expect(classB.hasNonFinalField, isTrue);
   }
 
-  @deprecated
-  void test_hasStaticMember_false_empty() {
-    var classA = class_(name: 'A');
-    // no members
-    expect(classA.hasStaticMember, isFalse);
-  }
-
-  @deprecated
-  void test_hasStaticMember_false_instanceMethod() {
-    var classA = class_(name: 'A');
-    MethodElement method = ElementFactory.methodElement("foo", intNone);
-    classA.methods = <MethodElement>[method];
-    expect(classA.hasStaticMember, isFalse);
-  }
-
-  @deprecated
-  void test_hasStaticMember_instanceGetter() {
-    var classA = class_(name: 'A');
-    PropertyAccessorElement getter =
-        ElementFactory.getterElement("foo", false, intNone);
-    classA.accessors = <PropertyAccessorElement>[getter];
-    expect(classA.hasStaticMember, isFalse);
-  }
-
-  @deprecated
-  void test_hasStaticMember_true_getter() {
-    var classA = class_(name: 'A');
-    PropertyAccessorElementImpl getter =
-        ElementFactory.getterElement("foo", false, intNone);
-    classA.accessors = <PropertyAccessorElement>[getter];
-    // "foo" is static
-    getter.isStatic = true;
-    expect(classA.hasStaticMember, isTrue);
-  }
-
-  @deprecated
-  void test_hasStaticMember_true_method() {
-    var classA = class_(name: 'A');
-    MethodElementImpl method = ElementFactory.methodElement("foo", intNone);
-    classA.methods = <MethodElement>[method];
-    // "foo" is static
-    method.isStatic = true;
-    expect(classA.hasStaticMember, isTrue);
-  }
-
-  @deprecated
-  void test_hasStaticMember_true_setter() {
-    var classA = class_(name: 'A');
-    PropertyAccessorElementImpl setter =
-        ElementFactory.setterElement("foo", false, intNone);
-    classA.accessors = <PropertyAccessorElement>[setter];
-    // "foo" is static
-    setter.isStatic = true;
-    expect(classA.hasStaticMember, isTrue);
-  }
-
   void test_lookUpConcreteMethod_declared() {
     // class A {
     //   m() {}
@@ -1514,10 +1458,8 @@
   }
 }
 ''');
-    expect(
-        findNode.variableDeclaration('x = 0').declaredElement2!.location,
-        isNot(
-            findNode.variableDeclaration('x = 1').declaredElement2!.location));
+    expect(findNode.variableDeclaration('x = 0').declaredElement!.location,
+        isNot(findNode.variableDeclaration('x = 1').declaredElement!.location));
   }
 }
 
diff --git a/pkg/analyzer/test/src/dart/element/function_type_test.dart b/pkg/analyzer/test/src/dart/element/function_type_test.dart
index f50f174..ac6d4b9 100644
--- a/pkg/analyzer/test/src/dart/element/function_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/function_type_test.dart
@@ -19,8 +19,6 @@
 
 DynamicTypeImpl get dynamicType => DynamicTypeImpl.instance;
 
-VoidTypeImpl get voidType => VoidTypeImpl.instance;
-
 @reflectiveTest
 class FunctionTypeTest extends AbstractTypeSystemTest {
   InterfaceType get intType => typeProvider.intType;
@@ -386,27 +384,3 @@
         typeFormals: [same(t)]);
   }
 }
-
-class MockCompilationUnitElement implements CompilationUnitElement {
-  const MockCompilationUnitElement();
-
-  @override
-  get enclosingElement => const MockLibraryElement();
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    return super.noSuchMethod(invocation);
-  }
-}
-
-class MockLibraryElement implements LibraryElement {
-  const MockLibraryElement();
-
-  @override
-  get enclosingElement => null;
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    return super.noSuchMethod(invocation);
-  }
-}
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 a4c5008..9d5e541 100644
--- a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
+++ b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
@@ -5,7 +5,7 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/ast/ast_factory.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
@@ -651,7 +651,9 @@
       declaredReturnType: ft.returnType,
       contextReturnType: returnType,
       errorReporter: reporter,
-      errorNode: astFactory.nullLiteral(KeywordToken(Keyword.NULL, 0)),
+      errorNode: NullLiteralImpl(
+        literal: KeywordToken(Keyword.NULL, 0),
+      ),
       genericMetadataIsEnabled: true,
     );
     inferrer.constrainArguments(
diff --git a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
index 89a3ffb..f731879 100644
--- a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
+++ b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
@@ -1416,7 +1416,7 @@
 
   void _assertExecutable(ExecutableElement? element, String? expected) {
     if (expected != null && element != null) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
 
       var type = element.type;
       var typeStr = typeString(type);
@@ -1426,7 +1426,7 @@
 
       if (element is PropertyAccessorElement) {
         var variable = element.variable;
-        expect(variable.enclosingElement3, same(element.enclosingElement3));
+        expect(variable.enclosingElement, same(element.enclosingElement));
         expect(variable.name, element.displayName);
         if (element.isGetter) {
           expect(variable.type, element.returnType);
@@ -1508,7 +1508,7 @@
       var element = entry.value;
       var type = element.type;
 
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement.name == 'Object') continue;
 
       var typeStr = type.getDisplayString(withNullability: false);
diff --git a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
index 36e0c11..d930a78 100644
--- a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
@@ -468,7 +468,7 @@
         {tElement: typeArgument},
       ).substituteType(
         TypeParameterTypeImpl(
-          element: tElement,
+          element2: tElement,
           nullabilitySuffix: typeParameterNullability,
         ),
       );
diff --git a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
index 8607d74..c134b9a 100644
--- a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
+++ b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
@@ -1301,6 +1301,15 @@
     _checkGreatestLowerBound2('(int)', 'void Function()', 'Never');
   }
 
+  test_recordType_dartCoreRecord() {
+    void check(String T) {
+      _checkGreatestLowerBound2(T, 'Record', T);
+    }
+
+    check('(int, String)');
+    check('({int f1, String f2})');
+  }
+
   test_self() {
     var T = typeParameter('T');
 
@@ -2644,6 +2653,15 @@
     _checkLeastUpperBound2('(int)', 'void Function()', 'Object');
   }
 
+  test_record_dartCoreRecord() {
+    void check(String T1) {
+      _checkLeastUpperBound2(T1, 'Record', 'Record');
+    }
+
+    check('(int, String)');
+    check('({int f1, String f2})');
+  }
+
   test_sameShape_named() {
     _checkLeastUpperBound2(
       '({int f1})',
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index a694e0b..6f00f15 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -1455,7 +1455,7 @@
             staticElement: self::@class::B
             staticType: null
           type: B
-        staticElement: self::@class::B::@constructor::•
+        staticElement: self::@class::B::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
@@ -1667,6 +1667,1054 @@
 ''');
   }
 
+  /// Has record getter:    false
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_named_FFFF_compound() async {
+    await assertErrorsInCode(r'''
+void f(({int bar}) r) {
+  r.foo += 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_GETTER, 28, 3),
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 28, 3),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({int bar})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: dynamic
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: <null>
+  staticType: dynamic
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_named_FFFF_simple() async {
+    await assertErrorsInCode(r'''
+void f(({int bar}) r) {
+  r.foo = 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 28, 3),
+    ]);
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({int bar})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: true
+  test_propertyAccess_recordTypeField_named_FFFT_compound() async {
+    await assertErrorsInCode(r'''
+extension E on ({int bar}) {
+  set foo(int _) {}
+}
+
+void f(({int bar}) r) {
+  r.foo += 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_GETTER, 80, 3),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({int bar})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: self::@extension::E::@setter::foo
+  readType: dynamic
+  writeElement: self::@extension::E::@setter::foo
+  writeType: int
+  staticElement: <null>
+  staticType: dynamic
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: true
+  test_propertyAccess_recordTypeField_named_FFFT_simple() async {
+    await assertNoErrorsInCode(r'''
+extension E on ({int bar}) {
+  set foo(int _) {}
+}
+
+void f(({int bar}) r) {
+  r.foo = 0;
+}
+''');
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({int bar})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: self::@extension::E::@setter::foo::@parameter::_
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: self::@extension::E::@setter::foo
+  writeType: int
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: true
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_named_FTFF_compound() async {
+    await assertErrorsInCode(r'''
+extension E on ({int bar}) {
+  int get foo => 0;
+}
+
+void f(({int bar}) r) {
+  r.foo += 0;
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER, 80, 3),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({int bar})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: dart:core::@class::num::@method::+::@parameter::other
+    staticType: int
+  readElement: self::@extension::E::@getter::foo
+  readType: int
+  writeElement: self::@extension::E::@getter::foo
+  writeType: dynamic
+  staticElement: dart:core::@class::num::@method::+
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: true
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_named_FTFF_simple() async {
+    await assertErrorsInCode(r'''
+extension E on ({int bar}) {
+  int get foo => 0;
+}
+
+void f(({int bar}) r) {
+  r.foo = 0;
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER, 80, 3),
+    ]);
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({int bar})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: self::@extension::E::@getter::foo
+  writeType: dynamic
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: true
+  /// Has record setter:    false
+  /// Has extension setter: true
+  test_propertyAccess_recordTypeField_named_FTFT_compound() async {
+    await assertNoErrorsInCode(r'''
+extension E on ({int bar}) {
+  int get foo => 0;
+  set foo(int _) {}
+}
+
+void f(({int bar}) r) {
+  r.foo += 0;
+}
+''');
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({int bar})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: dart:core::@class::num::@method::+::@parameter::other
+    staticType: int
+  readElement: self::@extension::E::@getter::foo
+  readType: int
+  writeElement: self::@extension::E::@setter::foo
+  writeType: int
+  staticElement: dart:core::@class::num::@method::+
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: true
+  /// Has record setter:    false
+  /// Has extension setter: true
+  test_propertyAccess_recordTypeField_named_FTFT_simple() async {
+    await assertNoErrorsInCode(r'''
+extension E on ({int bar}) {
+  int get foo => 0;
+  set foo(int _) {}
+}
+
+void f(({int bar}) r) {
+  r.foo = 0;
+}
+''');
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({int bar})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: self::@extension::E::@setter::foo::@parameter::_
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: self::@extension::E::@setter::foo
+  writeType: int
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_named_TFFF_compound() async {
+    await assertErrorsInCode(r'''
+void f(({int foo, String bar}) r) {
+  r.foo += 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 40, 3),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({String bar, int foo})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: dart:core::@class::num::@method::+::@parameter::other
+    staticType: int
+  readElement: <null>
+  readType: int
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: dart:core::@class::num::@method::+
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_named_TFFF_simple() async {
+    await assertErrorsInCode(r'''
+void f(({int foo, String bar}) r) {
+  r.foo = 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 40, 3),
+    ]);
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({String bar, int foo})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: true
+  test_propertyAccess_recordTypeField_named_TFFT_compound() async {
+    await assertErrorsInCode(r'''
+extension E on ({int foo, String bar}) {
+  set foo(int _) {}
+}
+
+void f(({int foo, String bar}) r) {
+  r.foo += 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 104, 3),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({String bar, int foo})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: dart:core::@class::num::@method::+::@parameter::other
+    staticType: int
+  readElement: <null>
+  readType: int
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: dart:core::@class::num::@method::+
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: true
+  test_propertyAccess_recordTypeField_named_TFFT_simple() async {
+    await assertErrorsInCode(r'''
+extension E on ({int foo, String bar}) {
+  set foo(int _) {}
+}
+
+void f(({int foo, String bar}) r) {
+  r.foo = 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 104, 3),
+    ]);
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({String bar, int foo})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: true
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_named_TTFF_compound() async {
+    await assertErrorsInCode(r'''
+extension E on ({int foo, String bar}) {
+  int get foo => 0;
+}
+ 
+void f(({int foo, String bar}) r) {
+  r.foo += 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 105, 3),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({String bar, int foo})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: dart:core::@class::num::@method::+::@parameter::other
+    staticType: int
+  readElement: <null>
+  readType: int
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: dart:core::@class::num::@method::+
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: true
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_named_TTFF_simple() async {
+    await assertErrorsInCode(r'''
+extension E on ({int foo, String bar}) {
+  int get foo => 0;
+}
+ 
+void f(({int foo, String bar}) r) {
+  r.foo = 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 105, 3),
+    ]);
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({String bar, int foo})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: true
+  /// Has record setter:    false
+  /// Has extension setter: true
+  test_propertyAccess_recordTypeField_named_TTFT_compound() async {
+    await assertErrorsInCode(r'''
+extension E on ({int foo, String bar}) {
+  int get foo => 0;
+  set foo(int _) {}
+}
+ 
+void f(({int foo, String bar}) r) {
+  r.foo += 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 125, 3),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({String bar, int foo})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: dart:core::@class::num::@method::+::@parameter::other
+    staticType: int
+  readElement: <null>
+  readType: int
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: dart:core::@class::num::@method::+
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: true
+  /// Has record setter:    false
+  /// Has extension setter: true
+  test_propertyAccess_recordTypeField_named_TTFT_simple() async {
+    await assertErrorsInCode(r'''
+extension E on ({int foo, String bar}) {
+  int get foo => 0;
+  set foo(int _) {}
+}
+ 
+void f(({int foo, String bar}) r) {
+  r.foo = 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 125, 3),
+    ]);
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({String bar, int foo})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_positional_FFFF_compound() async {
+    await assertErrorsInCode(r'''
+void f((int, String) r) {
+  r.$3 += 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_GETTER, 30, 2),
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 30, 2),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: (int, String)
+    operator: .
+    propertyName: SimpleIdentifier
+      token: $3
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: dynamic
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: <null>
+  staticType: dynamic
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_positional_FFFF_simple() async {
+    await assertErrorsInCode(r'''
+void f((int, String) r) {
+  r.$3 = 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 30, 2),
+    ]);
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: (int, String)
+    operator: .
+    propertyName: SimpleIdentifier
+      token: $3
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: true
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_positional_FTFF_compound() async {
+    await assertErrorsInCode(r'''
+extension E on (int, String) {
+  int get $2 => 0;
+}
+
+void f((int, String) r) {
+  r.$2 += 0;
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER, 83, 2),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: (int, String)
+    operator: .
+    propertyName: SimpleIdentifier
+      token: $2
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: dart:core::@class::num::@method::+::@parameter::other
+    staticType: int
+  readElement: self::@extension::E::@getter::$2
+  readType: int
+  writeElement: self::@extension::E::@getter::$2
+  writeType: dynamic
+  staticElement: dart:core::@class::num::@method::+
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    false
+  /// Has extension getter: true
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_positional_FTFF_simple() async {
+    await assertErrorsInCode(r'''
+extension E on (int, String) {
+  int get $2 => 0;
+}
+
+void f((int, String) r) {
+  r.$2 = 0;
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER, 83, 2),
+    ]);
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: (int, String)
+    operator: .
+    propertyName: SimpleIdentifier
+      token: $2
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: self::@extension::E::@getter::$2
+  writeType: dynamic
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_positional_TFFF_compound() async {
+    await assertErrorsInCode(r'''
+void f((int, String) r) {
+  r.$0 += 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 30, 2),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: (int, String)
+    operator: .
+    propertyName: SimpleIdentifier
+      token: $0
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: dart:core::@class::num::@method::+::@parameter::other
+    staticType: int
+  readElement: <null>
+  readType: int
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: dart:core::@class::num::@method::+
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: false
+  test_propertyAccess_recordTypeField_positional_TFFF_simple() async {
+    await assertErrorsInCode(r'''
+void f((int, String) r) {
+  r.$0 = 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 30, 2),
+    ]);
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: (int, String)
+    operator: .
+    propertyName: SimpleIdentifier
+      token: $0
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: true
+  test_propertyAccess_recordTypeField_positional_TFFT_compound() async {
+    await assertErrorsInCode(r'''
+extension E on (int, String) {
+  set $0(int _) {}
+}
+
+void f((int, String) r) {
+  r.$0 += 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 83, 2),
+    ]);
+
+    final node = findNode.assignment('+= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: (int, String)
+    operator: .
+    propertyName: SimpleIdentifier
+      token: $0
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: +=
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: dart:core::@class::num::@method::+::@parameter::other
+    staticType: int
+  readElement: <null>
+  readType: int
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: dart:core::@class::num::@method::+
+  staticType: int
+''');
+  }
+
+  /// Has record getter:    true
+  /// Has extension getter: false
+  /// Has record setter:    false
+  /// Has extension setter: true
+  test_propertyAccess_recordTypeField_positional_TFFT_simple() async {
+    await assertErrorsInCode(r'''
+extension E on (int, String) {
+  set $0(int _) {}
+}
+
+void f((int, String) r) {
+  r.$0 = 0;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 83, 2),
+    ]);
+
+    final node = findNode.assignment('= 0');
+    assertResolvedNodeText(node, r'''
+AssignmentExpression
+  leftHandSide: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: (int, String)
+    operator: .
+    propertyName: SimpleIdentifier
+      token: $0
+      staticElement: <null>
+      staticType: null
+    staticType: null
+  operator: =
+  rightHandSide: IntegerLiteral
+    literal: 0
+    parameter: <null>
+    staticType: int
+  readElement: <null>
+  readType: null
+  writeElement: <null>
+  writeType: dynamic
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
   test_propertyAccess_super_compound() async {
     await assertNoErrorsInCode(r'''
 class A {
@@ -2267,7 +3315,7 @@
           staticElement: self::@class::C
           staticType: null
         type: C
-      staticElement: self::@class::C::@constructor::•
+      staticElement: self::@class::C::@constructor::new
     argumentList: ArgumentList
       leftParenthesis: (
       rightParenthesis: )
@@ -2871,7 +3919,7 @@
           staticElement: self::@class::C
           staticType: null
         type: C
-      staticElement: self::@class::C::@constructor::•
+      staticElement: self::@class::C::@constructor::new
     argumentList: ArgumentList
       leftParenthesis: (
       rightParenthesis: )
diff --git a/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart b/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart
index f2100ef..a968701 100644
--- a/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart
@@ -392,7 +392,7 @@
         rightBracket: >
       type: A<int, String>
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int, U: String}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -400,7 +400,7 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: self::@class::A::@constructor::•::@parameter::a
+          base: self::@class::A::@constructor::new::@parameter::a
           substitution: {T: int, U: String}
         staticType: int
     rightParenthesis: )
@@ -520,7 +520,7 @@
         rightBracket: >
       type: A<int, String>
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int, U: String}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -528,7 +528,7 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: self::@class::A::@constructor::•::@parameter::_
+          base: self::@class::A::@constructor::new::@parameter::_
           substitution: {T: int, U: String}
         staticType: int
     rightParenthesis: )
@@ -730,11 +730,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: package:test/a.dart::@class::A::@constructor::•
+        base: package:test/a.dart::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: package:test/a.dart::@class::A::@constructor::•
+      base: package:test/a.dart::@class::A::@constructor::new
       substitution: {T: int}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -742,7 +742,7 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: package:test/a.dart::@class::A::@constructor::•::@parameter::a
+          base: package:test/a.dart::@class::A::@constructor::new::@parameter::a
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
@@ -1000,11 +1000,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: dynamic, U: dynamic}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: dynamic, U: dynamic}
   typeArguments: TypeArgumentList
     leftBracket: <
@@ -1028,7 +1028,7 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: self::@class::A::@constructor::•::@parameter::a
+          base: self::@class::A::@constructor::new::@parameter::a
           substitution: {T: dynamic, U: dynamic}
         staticType: int
     rightParenthesis: )
@@ -1101,7 +1101,7 @@
         rightBracket: >
       type: A<int, String>
     staticElement: ConstructorMember
-      base: package:test/a.dart::@class::A::@constructor::•
+      base: package:test/a.dart::@class::A::@constructor::new
       substitution: {T: int, U: String}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -1109,7 +1109,7 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: package:test/a.dart::@class::A::@constructor::•::@parameter::a
+          base: package:test/a.dart::@class::A::@constructor::new::@parameter::a
           substitution: {T: int, U: String}
         staticType: int
     rightParenthesis: )
diff --git a/pkg/analyzer/test/src/dart/resolution/binary_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/binary_pattern_test.dart
new file mode 100644
index 0000000..87d6d3a
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/binary_pattern_test.dart
@@ -0,0 +1,214 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(BinaryPattern_LogicalAnd_ResolutionTest);
+    defineReflectiveTests(BinaryPattern_LogicalOr_ResolutionTest);
+  });
+}
+
+@reflectiveTest
+class BinaryPattern_LogicalAnd_ResolutionTest extends PatternsResolutionTest {
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case int? _ & double? _) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+      question: ?
+    name: _
+  operator: &
+  rightOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: double
+      question: ?
+    name: _
+''');
+  }
+
+  test_inside_logicalAnd_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int? _ & double? _ & Object? _:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: BinaryPattern
+    leftOperand: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: int
+        question: ?
+      name: _
+    operator: &
+    rightOperand: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: double
+        question: ?
+      name: _
+  operator: &
+  rightOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: Object
+      question: ?
+    name: _
+''');
+  }
+
+  test_inside_logicalOr_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int? _ & double? _ | Object? _:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: BinaryPattern
+    leftOperand: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: int
+        question: ?
+      name: _
+    operator: &
+    rightOperand: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: double
+        question: ?
+      name: _
+  operator: |
+  rightOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: Object
+      question: ?
+    name: _
+''');
+  }
+
+  test_inside_logicalOr_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int? _ | double? _ & Object? _:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+      question: ?
+    name: _
+  operator: |
+  rightOperand: BinaryPattern
+    leftOperand: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: double
+        question: ?
+      name: _
+    operator: &
+    rightOperand: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: Object
+        question: ?
+      name: _
+''');
+  }
+}
+
+@reflectiveTest
+class BinaryPattern_LogicalOr_ResolutionTest extends PatternsResolutionTest {
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case int? _ | double? _) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+      question: ?
+    name: _
+  operator: |
+  rightOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: double
+      question: ?
+    name: _
+''');
+  }
+
+  test_inside_logicalOr_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int? _ | double? _ | Object? _:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: BinaryPattern
+    leftOperand: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: int
+        question: ?
+      name: _
+    operator: |
+    rightOperand: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: double
+        question: ?
+      name: _
+  operator: |
+  rightOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: Object
+      question: ?
+    name: _
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/cast_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/cast_pattern_test.dart
new file mode 100644
index 0000000..cc729d9
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/cast_pattern_test.dart
@@ -0,0 +1,447 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(CastPatternResolutionTest);
+  });
+}
+
+@reflectiveTest
+class CastPatternResolutionTest extends PatternsResolutionTest {
+  test_inside_extractorPattern_explicitName() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(f: 0 as int):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: SimpleIdentifier
+    token: C
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        name: f
+        colon: :
+      pattern: CastPattern
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+        asToken: as
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_extractorPattern_implicitName() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(: var f as int):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: SimpleIdentifier
+    token: C
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        colon: :
+      pattern: CastPattern
+        pattern: VariablePattern
+          keyword: var
+          name: f
+        asToken: as
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case var y as int) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertParsedNodeText(node, r'''
+CastPattern
+  pattern: VariablePattern
+    keyword: var
+    name: y
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: int
+''');
+  }
+
+  test_inside_listPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case [0 as int]:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ListPattern
+  leftBracket: [
+  elements
+    CastPattern
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 0
+      asToken: as
+      type: NamedType
+        name: SimpleIdentifier
+          token: int
+  rightBracket: ]
+''');
+  }
+
+  test_inside_logicalAnd_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int? _ as double? & Object? _:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: CastPattern
+    pattern: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: int
+        question: ?
+      name: _
+    asToken: as
+    type: NamedType
+      name: SimpleIdentifier
+        token: double
+      question: ?
+  operator: &
+  rightOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: Object
+      question: ?
+    name: _
+''');
+  }
+
+  test_inside_logicalAnd_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int? _ & double? _ as Object?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+      question: ?
+    name: _
+  operator: &
+  rightOperand: CastPattern
+    pattern: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: double
+        question: ?
+      name: _
+    asToken: as
+    type: NamedType
+      name: SimpleIdentifier
+        token: Object
+      question: ?
+''');
+  }
+
+  test_inside_logicalOr_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int? _ as double? | Object? _:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: CastPattern
+    pattern: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: int
+        question: ?
+      name: _
+    asToken: as
+    type: NamedType
+      name: SimpleIdentifier
+        token: double
+      question: ?
+  operator: |
+  rightOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: Object
+      question: ?
+    name: _
+''');
+  }
+
+  test_inside_logicalOr_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int? _ | double? _ as Object?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+      question: ?
+    name: _
+  operator: |
+  rightOperand: CastPattern
+    pattern: VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: double
+        question: ?
+      name: _
+    asToken: as
+    type: NamedType
+      name: SimpleIdentifier
+        token: Object
+      question: ?
+''');
+  }
+
+  test_inside_mapPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case {'a': 0 as int}:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+MapPattern
+  leftBracket: {
+  entries
+    MapPatternEntry
+      key: SimpleStringLiteral
+        literal: 'a'
+      separator: :
+      value: CastPattern
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+        asToken: as
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+  rightBracket: }
+''');
+  }
+
+  test_inside_parenthesizedPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (0 as int):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+ParenthesizedPattern
+  leftParenthesis: (
+  pattern: CastPattern
+    pattern: ConstantPattern
+      expression: IntegerLiteral
+        literal: 0
+        staticType: int
+    asToken: as
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_namedExplicitly() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (n: 1 as int, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        name: n
+        colon: :
+      pattern: CastPattern
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 1
+        asToken: as
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_namedImplicitly() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (: var n as int, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        colon: :
+      pattern: CastPattern
+        pattern: VariablePattern
+          keyword: var
+          name: n
+        asToken: as
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_unnamed() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (1 as int, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      pattern: CastPattern
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 1
+        asToken: as
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x, y) {
+  switch (x) {
+    case y as int:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+CastPattern
+  pattern: ConstantPattern
+    expression: SimpleIdentifier
+      token: y
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: int
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/comment_test.dart b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
index 430e5d8..db8ae1f 100644
--- a/pkg/analyzer/test/src/dart/resolution/comment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
@@ -68,9 +68,9 @@
     period: .
     identifier: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
     staticType: null
 ''');
   }
@@ -506,7 +506,7 @@
     operator: .
     propertyName: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
     staticType: null
 ''');
@@ -1004,7 +1004,7 @@
 CommentReference
   expression: SimpleIdentifier
     token: p
-    staticElement: self::@class::A::@constructor::•::@parameter::p
+    staticElement: self::@class::A::@constructor::new::@parameter::p
     staticType: null
 ''');
   }
@@ -1203,7 +1203,7 @@
   newKeyword: new
   expression: SimpleIdentifier
     token: A
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
     staticType: null
 ''');
 
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_pattern_test.dart
new file mode 100644
index 0000000..f4ea1b2
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/constant_pattern_test.dart
@@ -0,0 +1,649 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConstantPattern_BooleanLiteral_ResolutionTest);
+    defineReflectiveTests(ConstantPattern_DoubleLiteral_ResolutionTest);
+    defineReflectiveTests(ConstantPattern_IntegerLiteral_ResolutionTest);
+    defineReflectiveTests(ConstantPattern_NullLiteral_ResolutionTest);
+    defineReflectiveTests(ConstantPattern_SimpleIdentifier_ResolutionTest);
+    defineReflectiveTests(ConstantPattern_SimpleStringLiteral_ResolutionTest);
+  });
+}
+
+@reflectiveTest
+class ConstantPattern_BooleanLiteral_ResolutionTest
+    extends PatternsResolutionTest {
+  test_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case true as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: ConstantPattern
+    expression: BooleanLiteral
+      literal: true
+      staticType: bool
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case true) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+ConstantPattern
+  expression: BooleanLiteral
+    literal: true
+    staticType: bool
+''');
+  }
+
+  test_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case true!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: BooleanLiteral
+      literal: true
+      staticType: bool
+  operator: !
+''');
+  }
+
+  test_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case true?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: BooleanLiteral
+      literal: true
+      staticType: bool
+  operator: ?
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case true:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ConstantPattern
+  expression: BooleanLiteral
+    literal: true
+''');
+  }
+}
+
+@reflectiveTest
+class ConstantPattern_DoubleLiteral_ResolutionTest
+    extends PatternsResolutionTest {
+  test_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1.0 as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: ConstantPattern
+    expression: DoubleLiteral
+      literal: 1.0
+      staticType: double
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case 1.0) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+ConstantPattern
+  expression: DoubleLiteral
+    literal: 1.0
+    staticType: double
+''');
+  }
+
+  test_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1.0!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: DoubleLiteral
+      literal: 1.0
+      staticType: double
+  operator: !
+''');
+  }
+
+  test_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1.0?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: DoubleLiteral
+      literal: 1.0
+      staticType: double
+  operator: ?
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1.0:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ConstantPattern
+  expression: DoubleLiteral
+    literal: 1.0
+''');
+  }
+}
+
+@reflectiveTest
+class ConstantPattern_IntegerLiteral_ResolutionTest
+    extends PatternsResolutionTest {
+  test_contextType_double() async {
+    await assertNoErrorsInCode(r'''
+void f(double x) {
+  switch (x) {
+    case 0:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+ConstantPattern
+  expression: IntegerLiteral
+    literal: 0
+    staticType: double
+''');
+  }
+
+  test_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 0 as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: ConstantPattern
+    expression: IntegerLiteral
+      literal: 0
+      staticType: int
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case 0) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+ConstantPattern
+  expression: IntegerLiteral
+    literal: 0
+    staticType: int
+''');
+  }
+
+  test_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 0!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 0
+      staticType: int
+  operator: !
+''');
+  }
+
+  test_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 0?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 0
+      staticType: int
+  operator: ?
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 0:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+ConstantPattern
+  expression: IntegerLiteral
+    literal: 0
+    staticType: int
+''');
+  }
+}
+
+@reflectiveTest
+class ConstantPattern_NullLiteral_ResolutionTest
+    extends PatternsResolutionTest {
+  test_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case null as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: ConstantPattern
+    expression: NullLiteral
+      literal: null
+      staticType: Null
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case null) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+ConstantPattern
+  expression: NullLiteral
+    literal: null
+    staticType: Null
+''');
+  }
+
+  test_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case null!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: NullLiteral
+      literal: null
+      staticType: Null
+  operator: !
+''');
+  }
+
+  test_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case null?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: NullLiteral
+      literal: null
+      staticType: Null
+  operator: ?
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case null:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ConstantPattern
+  expression: NullLiteral
+    literal: null
+''');
+  }
+}
+
+@reflectiveTest
+class ConstantPattern_SimpleIdentifier_ResolutionTest
+    extends PatternsResolutionTest {
+  test_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x, int y) {
+  switch (x) {
+    case y as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: ConstantPattern
+    expression: SimpleIdentifier
+      token: y
+      staticElement: self::@function::f::@parameter::y
+      staticType: int
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x, int y) {
+  if (x case y) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+ConstantPattern
+  expression: SimpleIdentifier
+    token: y
+    staticElement: self::@function::f::@parameter::y
+    staticType: int
+''');
+  }
+
+  test_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x, int y) {
+  switch (x) {
+    case y!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: SimpleIdentifier
+      token: y
+      staticElement: self::@function::f::@parameter::y
+      staticType: int
+  operator: !
+''');
+  }
+
+  test_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x, int y) {
+  switch (x) {
+    case y?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: SimpleIdentifier
+      token: y
+      staticElement: self::@function::f::@parameter::y
+      staticType: int
+  operator: ?
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x, y) {
+  switch (x) {
+    case y:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ConstantPattern
+  expression: SimpleIdentifier
+    token: y
+''');
+  }
+}
+
+@reflectiveTest
+class ConstantPattern_SimpleStringLiteral_ResolutionTest
+    extends PatternsResolutionTest {
+  test_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 'x' as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: ConstantPattern
+    expression: SimpleStringLiteral
+      literal: 'x'
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case 'x') {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+ConstantPattern
+  expression: SimpleStringLiteral
+    literal: 'x'
+''');
+  }
+
+  test_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 'x'!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: SimpleStringLiteral
+      literal: 'x'
+  operator: !
+''');
+  }
+
+  test_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 'x'?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: SimpleStringLiteral
+      literal: 'x'
+  operator: ?
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 'x':
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ConstantPattern
+  expression: SimpleStringLiteral
+    literal: 'x'
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/constructor_reference_test.dart b/pkg/analyzer/test/src/dart/resolution/constructor_reference_test.dart
index b06ac22..07b723f 100644
--- a/pkg/analyzer/test/src/dart/resolution/constructor_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constructor_reference_test.dart
@@ -232,11 +232,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
@@ -293,11 +293,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
@@ -341,11 +341,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: String}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: String}
   staticType: A<String> Function()
 ''');
@@ -384,11 +384,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
@@ -565,11 +565,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
@@ -697,11 +697,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
@@ -742,11 +742,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
@@ -787,11 +787,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
@@ -834,11 +834,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: String}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: String}
   staticType: A<String> Function()
 ''');
@@ -890,11 +890,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: package:test/a.dart::@class::A::@constructor::•
+        base: package:test/a.dart::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: package:test/a.dart::@class::A::@constructor::•
+      base: package:test/a.dart::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
@@ -1003,11 +1003,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: package:test/a.dart::@class::A::@constructor::•
+        base: package:test/a.dart::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: package:test/a.dart::@class::A::@constructor::•
+      base: package:test/a.dart::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
@@ -1058,11 +1058,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: package:test/a.dart::@class::A::@constructor::•
+        base: package:test/a.dart::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: package:test/a.dart::@class::A::@constructor::•
+      base: package:test/a.dart::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
@@ -1097,9 +1097,9 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   staticType: A Function()
 ''');
   }
@@ -1134,9 +1134,9 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   staticType: A Function()
 ''');
   }
@@ -1173,9 +1173,9 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   staticType: A Function()
 ''');
   }
@@ -1333,9 +1333,9 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   staticType: A Function()
 ''');
   }
@@ -1395,9 +1395,9 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   staticType: A Function()
 ''');
   }
@@ -1479,9 +1479,9 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: package:test/a.dart::@class::A::@constructor::•
+      staticElement: package:test/a.dart::@class::A::@constructor::new
       staticType: null
-    staticElement: package:test/a.dart::@class::A::@constructor::•
+    staticElement: package:test/a.dart::@class::A::@constructor::new
   staticType: A Function()
 ''');
   }
@@ -1561,9 +1561,9 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: package:test/a.dart::@class::A::@constructor::•
+      staticElement: package:test/a.dart::@class::A::@constructor::new
       staticType: null
-    staticElement: package:test/a.dart::@class::A::@constructor::•
+    staticElement: package:test/a.dart::@class::A::@constructor::new
   staticType: A Function()
 ''');
   }
@@ -1591,9 +1591,9 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   staticType: A<T> Function<T>()
 ''');
   }
@@ -1654,11 +1654,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::A::@constructor::•
+        base: self::@class::A::@constructor::new
         substitution: {T: int}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   staticType: A<int> Function()
 ''');
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 3387df3..f5ea391 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -312,6 +312,16 @@
   }
 }
 
+class PatternsResolutionTest extends PubPackageResolutionTest {
+  @override
+  List<String> get experiments {
+    return [
+      ...super.experiments,
+      EnableString.patterns,
+    ];
+  }
+}
+
 class PubPackageResolutionTest extends ContextResolutionTest {
   AnalysisOptionsImpl get analysisOptions {
     return contextFor(testFile).analysisOptions as AnalysisOptionsImpl;
diff --git a/pkg/analyzer/test/src/dart/resolution/dart_object_printer.dart b/pkg/analyzer/test/src/dart/resolution/dart_object_printer.dart
index 40861f1..255d331 100644
--- a/pkg/analyzer/test/src/dart/resolution/dart_object_printer.dart
+++ b/pkg/analyzer/test/src/dart/resolution/dart_object_printer.dart
@@ -23,6 +23,7 @@
   void write(DartObjectImpl? object) {
     if (object != null) {
       final type = object.type;
+      final state = object.state;
       if (object.isUnknown) {
         sink.write(
           type.getDisplayString(
@@ -30,6 +31,9 @@
           ),
         );
         sink.writeln(' <unknown>');
+      } else if (type.isDartCoreBool) {
+        sink.write('bool ');
+        sink.writeln(object.toBoolValue());
       } else if (type.isDartCoreDouble) {
         sink.write('double ');
         sink.writeln(object.toDoubleValue());
@@ -71,6 +75,8 @@
             }
           }
         });
+      } else if (state is RecordState) {
+        _writeRecord(state);
       } else {
         throw UnimplementedError();
       }
@@ -114,6 +120,36 @@
     sink.writeln(line);
   }
 
+  void _writeRecord(RecordState state) {
+    sink.writeln('Record');
+    _withIndent(() {
+      final positionalFields = state.positionalFields;
+      if (positionalFields.isNotEmpty) {
+        _writelnWithIndent('positionalFields');
+        _withIndent(() {
+          positionalFields.forEachIndexed((index, field) {
+            sink.write(indent);
+            sink.write('\$$index: ');
+            write(field);
+          });
+        });
+      }
+
+      final namedFields = state.namedFields;
+      if (namedFields.isNotEmpty) {
+        _writelnWithIndent('namedFields');
+        _withIndent(() {
+          final entries = namedFields.entries.sortedBy((entry) => entry.key);
+          for (final entry in entries) {
+            sink.write(indent);
+            sink.write('${entry.key}: ');
+            write(entry.value);
+          }
+        });
+      }
+    });
+  }
+
   void _writeVariable(DartObjectImpl object) {
     final variable = object.variable;
     if (variable is VariableElementImpl) {
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index dd2db98..883a1c0 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -30,7 +30,7 @@
 ListLiteral
   leftBracket: [
   rightBracket: ]
-  parameter: self::@enum::E::@constructor::•::@parameter::a
+  parameter: self::@enum::E::@constructor::new::@parameter::a
   staticType: List<int>
 ''');
   }
@@ -131,12 +131,12 @@
         IntegerLiteral
           literal: 42
           parameter: ParameterMember
-            base: self::@enum::E::@constructor::•::@parameter::a
+            base: self::@enum::E::@constructor::new::@parameter::a
             substitution: {T: int}
           staticType: int
       rightParenthesis: )
   constructorElement: ConstructorMember
-    base: self::@enum::E::@constructor::•
+    base: self::@enum::E::@constructor::new
     substitution: {T: int}
   declaredElement: self::@enum::E::@field::v
 ''');
@@ -238,10 +238,10 @@
       arguments
         IntegerLiteral
           literal: 42
-          parameter: self::@enum::E::@constructor::•::@parameter::a
+          parameter: self::@enum::E::@constructor::new::@parameter::a
           staticType: int
       rightParenthesis: )
-  constructorElement: self::@enum::E::@constructor::•
+  constructorElement: self::@enum::E::@constructor::new
   declaredElement: self::@enum::E::@field::v
 ''');
   }
@@ -257,7 +257,7 @@
     assertResolvedNodeText(node, r'''
 EnumConstantDeclaration
   name: v
-  constructorElement: self::@enum::E::@constructor::•
+  constructorElement: self::@enum::E::@constructor::new
   declaredElement: self::@enum::E::@field::v
 ''');
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/extractor_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/extractor_pattern_test.dart
new file mode 100644
index 0000000..ab14c84
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/extractor_pattern_test.dart
@@ -0,0 +1,463 @@
+// Copyright (c) 2022, 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/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExtractorPatternResolutionTest);
+  });
+}
+
+@reflectiveTest
+class ExtractorPatternResolutionTest extends PatternsResolutionTest {
+  test_identifier_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(f: 0) as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+CastPattern
+  pattern: ExtractorPattern
+    typeName: SimpleIdentifier
+      token: C
+    leftParenthesis: (
+    fields
+      RecordPatternField
+        fieldName: RecordPatternFieldName
+          name: f
+          colon: :
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+    rightParenthesis: )
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+''');
+  }
+
+  test_identifier_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(f: 0)!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ExtractorPattern
+    typeName: SimpleIdentifier
+      token: C
+    leftParenthesis: (
+    fields
+      RecordPatternField
+        fieldName: RecordPatternFieldName
+          name: f
+          colon: :
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+    rightParenthesis: )
+  operator: !
+''');
+  }
+
+  test_identifier_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(f: 0)?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ExtractorPattern
+    typeName: SimpleIdentifier
+      token: C
+    leftParenthesis: (
+    fields
+      RecordPatternField
+        fieldName: RecordPatternFieldName
+          name: f
+          colon: :
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+    rightParenthesis: )
+  operator: ?
+''');
+  }
+
+  test_identifier_withTypeArguments() async {
+    await assertNoErrorsInCode(r'''
+class C<T> {}
+
+void f(x) {
+  switch (x) {
+    case C<int>():
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: SimpleIdentifier
+    token: C
+  typeArguments: TypeArgumentList
+    leftBracket: <
+    arguments
+      NamedType
+        name: SimpleIdentifier
+          token: int
+    rightBracket: >
+  leftParenthesis: (
+  rightParenthesis: )
+''');
+  }
+
+  test_identifier_withTypeArguments_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+class C<T> {}
+
+void f(x) {
+  switch (x) {
+    case C<int>()!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ExtractorPattern
+    typeName: SimpleIdentifier
+      token: C
+    typeArguments: TypeArgumentList
+      leftBracket: <
+      arguments
+        NamedType
+          name: SimpleIdentifier
+            token: int
+      rightBracket: >
+    leftParenthesis: (
+    rightParenthesis: )
+  operator: !
+''');
+  }
+
+  test_identifier_withTypeArguments_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+class C<T> {}
+
+void f(x) {
+  switch (x) {
+    case C<int>()?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ExtractorPattern
+    typeName: SimpleIdentifier
+      token: C
+    typeArguments: TypeArgumentList
+      leftBracket: <
+      arguments
+        NamedType
+          name: SimpleIdentifier
+            token: int
+      rightBracket: >
+    leftParenthesis: (
+    rightParenthesis: )
+  operator: ?
+''');
+  }
+
+  test_prefixedIdentifier_inside_castPattern() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+class C {
+  int? f;
+}
+''');
+
+    await assertErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+void f(x) {
+  switch (x) {
+    case prefix.C(f: 0) as Object:
+      break;
+  }
+}
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 8),
+    ]);
+
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+CastPattern
+  pattern: ExtractorPattern
+    typeName: PrefixedIdentifier
+      prefix: SimpleIdentifier
+        token: prefix
+      period: .
+      identifier: SimpleIdentifier
+        token: C
+    leftParenthesis: (
+    fields
+      RecordPatternField
+        fieldName: RecordPatternFieldName
+          name: f
+          colon: :
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+    rightParenthesis: )
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+''');
+  }
+
+  test_prefixedIdentifier_inside_nullAssert() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+class C {
+  int? f;
+}
+''');
+
+    await assertErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+void f(x) {
+  switch (x) {
+    case prefix.C(f: 0)!:
+      break;
+  }
+}
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 8),
+    ]);
+
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ExtractorPattern
+    typeName: PrefixedIdentifier
+      prefix: SimpleIdentifier
+        token: prefix
+      period: .
+      identifier: SimpleIdentifier
+        token: C
+    leftParenthesis: (
+    fields
+      RecordPatternField
+        fieldName: RecordPatternFieldName
+          name: f
+          colon: :
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+    rightParenthesis: )
+  operator: !
+''');
+  }
+
+  test_prefixedIdentifier_inside_nullCheck() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+class C {
+  int? f;
+}
+''');
+
+    await assertErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+void f(x) {
+  switch (x) {
+    case prefix.C(f: 0)?:
+      break;
+  }
+}
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 8),
+    ]);
+
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ExtractorPattern
+    typeName: PrefixedIdentifier
+      prefix: SimpleIdentifier
+        token: prefix
+      period: .
+      identifier: SimpleIdentifier
+        token: C
+    leftParenthesis: (
+    fields
+      RecordPatternField
+        fieldName: RecordPatternFieldName
+          name: f
+          colon: :
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+    rightParenthesis: )
+  operator: ?
+''');
+  }
+
+  test_prefixedIdentifier_withTypeArguments() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+class C<T> {}
+''');
+
+    await assertErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+void f(x) {
+  switch (x) {
+    case prefix.C<int>():
+      break;
+  }
+}
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 8),
+    ]);
+
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: PrefixedIdentifier
+    prefix: SimpleIdentifier
+      token: prefix
+    period: .
+    identifier: SimpleIdentifier
+      token: C
+  typeArguments: TypeArgumentList
+    leftBracket: <
+    arguments
+      NamedType
+        name: SimpleIdentifier
+          token: int
+    rightBracket: >
+  leftParenthesis: (
+  rightParenthesis: )
+''');
+  }
+
+  test_prefixedIdentifier_withTypeArguments_inside_nullAssert() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+class C<T> {}
+''');
+
+    await assertErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+void f(x) {
+  switch (x) {
+    case prefix.C<int>()!:
+      break;
+  }
+}
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 8),
+    ]);
+
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ExtractorPattern
+    typeName: PrefixedIdentifier
+      prefix: SimpleIdentifier
+        token: prefix
+      period: .
+      identifier: SimpleIdentifier
+        token: C
+    typeArguments: TypeArgumentList
+      leftBracket: <
+      arguments
+        NamedType
+          name: SimpleIdentifier
+            token: int
+      rightBracket: >
+    leftParenthesis: (
+    rightParenthesis: )
+  operator: !
+''');
+  }
+
+  test_prefixedIdentifier_withTypeArguments_inside_nullCheck() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+class C<T> {}
+''');
+
+    await assertErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+void f(x) {
+  switch (x) {
+    case prefix.C<int>()?:
+      break;
+  }
+}
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 8),
+    ]);
+
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ExtractorPattern
+    typeName: PrefixedIdentifier
+      prefix: SimpleIdentifier
+        token: prefix
+      period: .
+      identifier: SimpleIdentifier
+        token: C
+    typeArguments: TypeArgumentList
+      leftBracket: <
+      arguments
+        NamedType
+          name: SimpleIdentifier
+            token: int
+      rightBracket: >
+    leftParenthesis: (
+    rightParenthesis: )
+  operator: ?
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/for_element_test.dart b/pkg/analyzer/test/src/dart/resolution/for_element_test.dart
index 3030ba7..b7df822 100644
--- a/pkg/analyzer/test/src/dart/resolution/for_element_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/for_element_test.dart
@@ -45,11 +45,11 @@
 
     assertElement(
       findNode.simple('i]; // 1'),
-      findNode.simple('i in [1, 2').staticElement,
+      findNode.declaredIdentifier('i in [1, 2').declaredElement!,
     );
     assertElement(
       findNode.simple('i]; // 2'),
-      findNode.simple('i in [1.1').staticElement,
+      findNode.declaredIdentifier('i in [1.1').declaredElement!,
     );
   }
 
@@ -95,11 +95,11 @@
 
     assertElement(
       findNode.simple('i]; // 1'),
-      findNode.simple('i = 1;').staticElement,
+      findNode.variableDeclaration('i = 1;').declaredElement!,
     );
     assertElement(
       findNode.simple('i]; // 2'),
-      findNode.simple('i = 1.1;').staticElement,
+      findNode.variableDeclaration('i = 1.1;').declaredElement!,
     );
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/for_statement_test.dart b/pkg/analyzer/test/src/dart/resolution/for_statement_test.dart
index aab1ca9..95aca6d 100644
--- a/pkg/analyzer/test/src/dart/resolution/for_statement_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/for_statement_test.dart
@@ -65,7 +65,7 @@
 ''');
 
     assertElement(
-      findNode.simple('x) {'),
+      findNode.simpleFormalParameter('x) {'),
       findElement.parameter('x'),
     );
 
diff --git a/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart
index 0ed4d13..2e84ca2 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart
@@ -192,6 +192,115 @@
       type: 'bool?',
     );
   }
+
+  test_record_field_named() async {
+    await assertNoErrorsInCode(r'''
+void f(({void Function(int) foo}) r) {
+  r.foo(0);
+}
+''');
+
+    final node = findNode.functionExpressionInvocation('(0)');
+    assertResolvedNodeText(node, r'''
+FunctionExpressionInvocation
+  function: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: ({void Function(int) foo})
+    operator: .
+    propertyName: SimpleIdentifier
+      token: foo
+      staticElement: <null>
+      staticType: void Function(int)
+    staticType: void Function(int)
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      IntegerLiteral
+        literal: 0
+        parameter: root::@parameter::
+        staticType: int
+    rightParenthesis: )
+  staticElement: <null>
+  staticInvokeType: void Function(int)
+  staticType: void
+''');
+  }
+
+  test_record_field_positional_rewrite() async {
+    await assertNoErrorsInCode(r'''
+void f((void Function(int),) r) {
+  r.$0(0);
+}
+''');
+
+    final node = findNode.functionExpressionInvocation('(0)');
+    assertResolvedNodeText(node, r'''
+FunctionExpressionInvocation
+  function: PropertyAccess
+    target: SimpleIdentifier
+      token: r
+      staticElement: self::@function::f::@parameter::r
+      staticType: (void Function(int))
+    operator: .
+    propertyName: SimpleIdentifier
+      token: $0
+      staticElement: <null>
+      staticType: void Function(int)
+    staticType: void Function(int)
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      IntegerLiteral
+        literal: 0
+        parameter: root::@parameter::
+        staticType: int
+    rightParenthesis: )
+  staticElement: <null>
+  staticInvokeType: void Function(int)
+  staticType: void
+''');
+  }
+
+  test_record_field_positional_withParenthesis() async {
+    await assertNoErrorsInCode(r'''
+void f((void Function(int),) r) {
+  (r.$0)(0);
+}
+''');
+
+    final node = findNode.functionExpressionInvocation('(0)');
+    assertResolvedNodeText(node, r'''
+FunctionExpressionInvocation
+  function: ParenthesizedExpression
+    leftParenthesis: (
+    expression: PropertyAccess
+      target: SimpleIdentifier
+        token: r
+        staticElement: self::@function::f::@parameter::r
+        staticType: (void Function(int))
+      operator: .
+      propertyName: SimpleIdentifier
+        token: $0
+        staticElement: <null>
+        staticType: void Function(int)
+      staticType: void Function(int)
+    rightParenthesis: )
+    staticType: void Function(int)
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      IntegerLiteral
+        literal: 0
+        parameter: root::@parameter::
+        staticType: int
+    rightParenthesis: )
+  staticElement: <null>
+  staticInvokeType: void Function(int)
+  staticType: void
+''');
+  }
 }
 
 @reflectiveTest
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 7e50d1e..65878bd 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -261,11 +261,11 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: self::@class::C::@constructor::•
+      staticElement: self::@class::C::@constructor::new
       staticType: null
       tearOffTypeArgumentTypes
         int
-    staticElement: self::@class::C::@constructor::•
+    staticElement: self::@class::C::@constructor::new
   staticType: C<int> Function(int)
 ''');
   }
@@ -669,9 +669,9 @@
         period: .
         name: SimpleIdentifier
           token: new
-          staticElement: self::@class::A::@constructor::•
+          staticElement: self::@class::A::@constructor::new
           staticType: null
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       staticType: A<T> Function<T>()
     rightParenthesis: )
     staticType: A<T> Function<T>()
diff --git a/pkg/analyzer/test/src/dart/resolution/generic_function_type_test.dart b/pkg/analyzer/test/src/dart/resolution/generic_function_type_test.dart
index feceda6..4ae2a74 100644
--- a/pkg/analyzer/test/src/dart/resolution/generic_function_type_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/generic_function_type_test.dart
@@ -55,7 +55,7 @@
 Function<@a T>()? x;
 ''');
     var T = findNode.typeParameter('T');
-    var annotation = T.declaredElement2!.metadata[0];
+    var annotation = T.declaredElement!.metadata[0];
     expect(annotation.element, findElement.topGet('a'));
   }
 
diff --git a/pkg/analyzer/test/src/dart/resolution/if_statement_test.dart b/pkg/analyzer/test/src/dart/resolution/if_statement_test.dart
index 95972aa..92872c0 100644
--- a/pkg/analyzer/test/src/dart/resolution/if_statement_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/if_statement_test.dart
@@ -8,27 +8,93 @@
 
 main() {
   defineReflectiveSuite(() {
+    defineReflectiveTests(IfStatementCaseResolutionTest);
     defineReflectiveTests(IfStatementResolutionTest);
   });
 }
 
 @reflectiveTest
-class IfStatementResolutionTest extends PubPackageResolutionTest {
-  test_condition_rewrite() async {
+class IfStatementCaseResolutionTest extends PatternsResolutionTest {
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/50077')
+  test_caseClause_rewrite() async {
     await assertNoErrorsInCode(r'''
-f(bool Function() b) {
-  if ( b() ) {
-    print(0);
-  }
+void f(x, int Function() a) {
+  if (x case const a()) {}
 }
 ''');
 
-    assertFunctionExpressionInvocation(
-      findNode.functionExpressionInvocation('b()'),
-      element: null,
-      typeArgumentTypes: [],
-      invokeType: 'bool Function()',
-      type: 'bool',
-    );
+    final node = findNode.ifStatement('if');
+    assertResolvedNodeText(node, r'''
+TODO
+''');
+  }
+
+  test_expression_rewrite() async {
+    await assertNoErrorsInCode(r'''
+void f(int Function() a) {
+  if (a() case 42) {}
+}
+''');
+
+    final node = findNode.ifStatement('if');
+    assertResolvedNodeText(node, r'''
+IfStatement
+  ifKeyword: if
+  leftParenthesis: (
+  condition: FunctionExpressionInvocation
+    function: SimpleIdentifier
+      token: a
+      staticElement: self::@function::f::@parameter::a
+      staticType: int Function()
+    argumentList: ArgumentList
+      leftParenthesis: (
+      rightParenthesis: )
+    staticElement: <null>
+    staticInvokeType: int Function()
+    staticType: int
+  caseClause: CaseClause
+    caseKeyword: case
+    pattern: ConstantPattern
+      expression: IntegerLiteral
+        literal: 42
+        staticType: int
+  rightParenthesis: )
+  thenStatement: Block
+    leftBracket: {
+    rightBracket: }
+''');
+  }
+}
+
+@reflectiveTest
+class IfStatementResolutionTest extends PubPackageResolutionTest {
+  test_expression_rewrite() async {
+    await assertNoErrorsInCode(r'''
+void f(bool Function() a) {
+  if (a()) {}
+}
+''');
+
+    final node = findNode.ifStatement('if');
+    assertResolvedNodeText(node, r'''
+IfStatement
+  ifKeyword: if
+  leftParenthesis: (
+  condition: FunctionExpressionInvocation
+    function: SimpleIdentifier
+      token: a
+      staticElement: self::@function::f::@parameter::a
+      staticType: bool Function()
+    argumentList: ArgumentList
+      leftParenthesis: (
+      rightParenthesis: )
+    staticElement: <null>
+    staticInvokeType: bool Function()
+    staticType: bool
+  rightParenthesis: )
+  thenStatement: Block
+    leftBracket: {
+    rightBracket: }
+''');
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
index d1babc1..89a758e 100644
--- a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
@@ -2,6 +2,7 @@
 // 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/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'context_collection_resolution.dart';
@@ -14,6 +15,136 @@
 
 @reflectiveTest
 class IndexExpressionTest extends PubPackageResolutionTest {
+  test_contextType_read() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  bool operator [](int index) => false;
+  operator []=(String index, bool value) {}
+}
+
+void f(A a) {
+  a[ g() ];
+}
+
+T g<T>() => throw 0;
+''');
+
+    var node = findNode.methodInvocation('g()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: g
+    staticElement: self::@function::g
+    staticType: T Function<T>()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  parameter: self::@class::A::@method::[]::@parameter::index
+  staticInvokeType: int Function()
+  staticType: int
+  typeArgumentTypes
+    int
+''');
+  }
+
+  test_contextType_readWrite_readLower() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  int operator [](int index) => 0;
+  operator []=(num index, int value) {}
+}
+
+void f(A a) {
+  a[ g() ]++;
+}
+
+T g<T>() => throw 0;
+''');
+
+    var node = findNode.methodInvocation('g()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: g
+    staticElement: self::@function::g
+    staticType: T Function<T>()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  parameter: self::@class::A::@method::[]=::@parameter::index
+  staticInvokeType: int Function()
+  staticType: int
+  typeArgumentTypes
+    int
+''');
+  }
+
+  test_contextType_readWrite_writeLower() async {
+    await assertErrorsInCode(r'''
+class A {
+  int operator [](num index) => 0;
+  operator []=(int index, int value) {}
+}
+
+void f(A a) {
+  a[ g() ]++;
+}
+
+T g<T>() => throw 0;
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 107, 3),
+    ]);
+
+    var node = findNode.methodInvocation('g()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: g
+    staticElement: self::@function::g
+    staticType: T Function<T>()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  parameter: self::@class::A::@method::[]=::@parameter::index
+  staticInvokeType: num Function()
+  staticType: num
+  typeArgumentTypes
+    num
+''');
+  }
+
+  test_contextType_write() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  bool operator [](int index) => false;
+  operator []=(String index, bool value) {}
+}
+
+void f(A a) {
+  a[ g() ] = true;
+}
+
+T g<T>() => throw 0;
+''');
+
+    var node = findNode.methodInvocation('g()');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: g
+    staticElement: self::@function::g
+    staticType: T Function<T>()
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  parameter: self::@class::A::@method::[]=::@parameter::index
+  staticInvokeType: String Function()
+  staticType: String
+  typeArgumentTypes
+    String
+''');
+  }
+
   test_invalid_inDefaultValue_nullAware() async {
     await assertInvalidTestCode(r'''
 void f({a = b?[0]}) {}
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 8504247..7ad31f9 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -139,7 +139,7 @@
         staticType: null
       type: A<int>
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -147,7 +147,7 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: self::@class::A::@constructor::•::@parameter::t
+          base: self::@class::A::@constructor::new::@parameter::t
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
@@ -186,7 +186,7 @@
         rightBracket: >
       type: A<int>
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -218,13 +218,13 @@
         staticElement: self::@class::A
         staticType: null
       type: A
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   argumentList: ArgumentList
     leftParenthesis: (
     arguments
       IntegerLiteral
         literal: 0
-        parameter: self::@class::A::@constructor::•::@parameter::a
+        parameter: self::@class::A::@constructor::new::@parameter::a
         staticType: int
     rightParenthesis: )
   staticType: A
@@ -256,7 +256,7 @@
         staticType: null
       type: A<S>
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: S}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -264,7 +264,7 @@
       SimpleIdentifier
         token: s
         parameter: ParameterMember
-          base: self::@class::A::@constructor::•::@parameter::t
+          base: self::@class::A::@constructor::new::@parameter::t
           substitution: {T: S}
         staticElement: self::@function::f::@parameter::s
         staticType: S & int
@@ -301,7 +301,7 @@
         rightBracket: >
       type: Map<dynamic, dynamic>
     staticElement: ConstructorMember
-      base: dart:core::@class::Map::@constructor::•
+      base: dart:core::@class::Map::@constructor::new
       substitution: {K: dynamic, V: dynamic}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -393,11 +393,11 @@
     name: SimpleIdentifier
       token: new
       staticElement: ConstructorMember
-        base: self::@class::Foo::@constructor::•
+        base: self::@class::Foo::@constructor::new
         substitution: {X: dynamic}
       staticType: null
     staticElement: ConstructorMember
-      base: self::@class::Foo::@constructor::•
+      base: self::@class::Foo::@constructor::new
       substitution: {X: dynamic}
   typeArguments: TypeArgumentList
     leftBracket: <
@@ -624,7 +624,7 @@
         staticElement: self::@class::X
         staticType: null
       type: X
-    staticElement: self::@class::X::@constructor::•
+    staticElement: self::@class::X::@constructor::new
   argumentList: ArgumentList
     leftParenthesis: (
     arguments
@@ -636,7 +636,7 @@
         argumentList: ArgumentList
           leftParenthesis: (
           rightParenthesis: )
-        parameter: self::@class::X::@constructor::•::@parameter::a
+        parameter: self::@class::X::@constructor::new::@parameter::a
         staticInvokeType: A Function()
         staticType: A
         typeArgumentTypes
@@ -645,7 +645,7 @@
         name: Label
           label: SimpleIdentifier
             token: c
-            staticElement: self::@class::X::@constructor::•::@parameter::c
+            staticElement: self::@class::X::@constructor::new::@parameter::c
             staticType: null
           colon: :
         expression: MethodInvocation
@@ -660,7 +660,7 @@
           staticType: C?
           typeArgumentTypes
             C?
-        parameter: self::@class::X::@constructor::•::@parameter::c
+        parameter: self::@class::X::@constructor::new::@parameter::c
       MethodInvocation
         methodName: SimpleIdentifier
           token: g2
@@ -669,7 +669,7 @@
         argumentList: ArgumentList
           leftParenthesis: (
           rightParenthesis: )
-        parameter: self::@class::X::@constructor::•::@parameter::b
+        parameter: self::@class::X::@constructor::new::@parameter::b
         staticInvokeType: B Function()
         staticType: B
         typeArgumentTypes
@@ -678,7 +678,7 @@
         name: Label
           label: SimpleIdentifier
             token: d
-            staticElement: self::@class::X::@constructor::•::@parameter::d
+            staticElement: self::@class::X::@constructor::new::@parameter::d
             staticType: null
           colon: :
         expression: MethodInvocation
@@ -693,7 +693,7 @@
           staticType: D?
           typeArgumentTypes
             D?
-        parameter: self::@class::X::@constructor::•::@parameter::d
+        parameter: self::@class::X::@constructor::new::@parameter::d
     rightParenthesis: )
   staticType: X
 ''');
@@ -819,7 +819,7 @@
         staticType: null
       type: A<int>
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -827,7 +827,7 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: self::@class::A::@constructor::•::@parameter::t
+          base: self::@class::A::@constructor::new::@parameter::t
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
@@ -859,7 +859,7 @@
         staticType: null
       type: A<int, String>
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: int, U: String}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -867,7 +867,7 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: self::@class::A::@constructor::•::@parameter::t
+          base: self::@class::A::@constructor::new::@parameter::t
           substitution: {T: int, U: String}
         staticType: int
       SimpleStringLiteral
@@ -952,7 +952,7 @@
         staticType: null
       type: A<String>
     staticElement: ConstructorMember
-      base: self::@class::A::@constructor::•
+      base: self::@class::A::@constructor::new
       substitution: {T: String}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -960,7 +960,7 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: self::@class::A::@constructor::•::@parameter::t
+          base: self::@class::A::@constructor::new::@parameter::t
           substitution: {T: String}
         staticType: int
     rightParenthesis: )
@@ -990,13 +990,13 @@
         staticElement: self::@class::A
         staticType: null
       type: A
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   argumentList: ArgumentList
     leftParenthesis: (
     arguments
       IntegerLiteral
         literal: 0
-        parameter: self::@class::A::@constructor::•::@parameter::a
+        parameter: self::@class::A::@constructor::new::@parameter::a
         staticType: int
     rightParenthesis: )
   staticType: A
@@ -1028,15 +1028,15 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   argumentList: ArgumentList
     leftParenthesis: (
     arguments
       IntegerLiteral
         literal: 0
-        parameter: self::@class::A::@constructor::•::@parameter::a
+        parameter: self::@class::A::@constructor::new::@parameter::a
         staticType: int
     rightParenthesis: )
   staticType: A
@@ -1068,15 +1068,15 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   argumentList: ArgumentList
     leftParenthesis: (
     arguments
       IntegerLiteral
         literal: 0
-        parameter: self::@class::A::@constructor::•::@parameter::a
+        parameter: self::@class::A::@constructor::new::@parameter::a
         staticType: int
     rightParenthesis: )
   staticType: A
@@ -1115,15 +1115,15 @@
     period: .
     name: SimpleIdentifier
       token: new
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
       staticType: null
-    staticElement: self::@class::A::@constructor::•
+    staticElement: self::@class::A::@constructor::new
   argumentList: ArgumentList
     leftParenthesis: (
     arguments
       IntegerLiteral
         literal: 0
-        parameter: self::@class::A::@constructor::•::@parameter::a
+        parameter: self::@class::A::@constructor::new::@parameter::a
         staticType: int
     rightParenthesis: )
   staticType: A
diff --git a/pkg/analyzer/test/src/dart/resolution/library_import_prefix_test.dart b/pkg/analyzer/test/src/dart/resolution/library_import_prefix_test.dart
index 66c665f..d32801e 100644
--- a/pkg/analyzer/test/src/dart/resolution/library_import_prefix_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/library_import_prefix_test.dart
@@ -44,8 +44,8 @@
       error(CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 52, 1),
     ]);
 
-    var xRef = findNode.simple('x in');
-    expect(xRef.staticElement, isNotNull);
+    var xRef = findNode.declaredIdentifier('x in');
+    expect(xRef.declaredElement, isNotNull);
 
     var pRef = findNode.simple('p) {}');
     assertElement(pRef, findElement.prefix('p'));
diff --git a/pkg/analyzer/test/src/dart/resolution/library_import_test.dart b/pkg/analyzer/test/src/dart/resolution/library_import_test.dart
index e575fbf..6a795ad 100644
--- a/pkg/analyzer/test/src/dart/resolution/library_import_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/library_import_test.dart
@@ -354,7 +354,7 @@
                     staticElement: package:test/a.dart::@class::A
                     staticType: null
                   type: A
-                staticElement: package:test/a.dart::@class::A::@constructor::•
+                staticElement: package:test/a.dart::@class::A::@constructor::new
               argumentList: ArgumentList
                 leftParenthesis: (
                 rightParenthesis: )
@@ -456,7 +456,7 @@
                     staticElement: package:test/a_html.dart::@class::A
                     staticType: null
                   type: A
-                staticElement: package:test/a_html.dart::@class::A::@constructor::•
+                staticElement: package:test/a_html.dart::@class::A::@constructor::new
               argumentList: ArgumentList
                 leftParenthesis: (
                 rightParenthesis: )
@@ -680,7 +680,7 @@
                     staticElement: package:test/a_io.dart::@class::A
                     staticType: null
                   type: A
-                staticElement: package:test/a_io.dart::@class::A::@constructor::•
+                staticElement: package:test/a_io.dart::@class::A::@constructor::new
               argumentList: ArgumentList
                 leftParenthesis: (
                 rightParenthesis: )
diff --git a/pkg/analyzer/test/src/dart/resolution/list_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/list_pattern_test.dart
new file mode 100644
index 0000000..d31801d
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/list_pattern_test.dart
@@ -0,0 +1,195 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ListPatternResolutionTest);
+  });
+}
+
+@reflectiveTest
+class ListPatternResolutionTest extends PatternsResolutionTest {
+  test_empty() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case []:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ListPattern
+  leftBracket: [
+  rightBracket: ]
+''');
+  }
+
+  test_empty_withWhitespace() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case [ ]:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ListPattern
+  leftBracket: [
+  rightBracket: ]
+''');
+  }
+
+  test_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case [0] as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+CastPattern
+  pattern: ListPattern
+    leftBracket: [
+    elements
+      ConstantPattern
+        expression: IntegerLiteral
+          literal: 0
+    rightBracket: ]
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case [0]) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertParsedNodeText(node, r'''
+ListPattern
+  leftBracket: [
+  elements
+    ConstantPattern
+      expression: IntegerLiteral
+        literal: 0
+  rightBracket: ]
+''');
+  }
+
+  test_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case [0]!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ListPattern
+    leftBracket: [
+    elements
+      ConstantPattern
+        expression: IntegerLiteral
+          literal: 0
+    rightBracket: ]
+  operator: !
+''');
+  }
+
+  test_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case [0]?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ListPattern
+    leftBracket: [
+    elements
+      ConstantPattern
+        expression: IntegerLiteral
+          literal: 0
+    rightBracket: ]
+  operator: ?
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case [1, 2]:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ListPattern
+  leftBracket: [
+  elements
+    ConstantPattern
+      expression: IntegerLiteral
+        literal: 1
+    ConstantPattern
+      expression: IntegerLiteral
+        literal: 2
+  rightBracket: ]
+''');
+  }
+
+  test_withTypeArguments() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case <int>[1, 2]:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ListPattern
+  typeArguments: TypeArgumentList
+    leftBracket: <
+    arguments
+      NamedType
+        name: SimpleIdentifier
+          token: int
+    rightBracket: >
+  leftBracket: [
+  elements
+    ConstantPattern
+      expression: IntegerLiteral
+        literal: 1
+    ConstantPattern
+      expression: IntegerLiteral
+        literal: 2
+  rightBracket: ]
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/local_function_test.dart b/pkg/analyzer/test/src/dart/resolution/local_function_test.dart
index 2aa51ca2..a8c2186 100644
--- a/pkg/analyzer/test/src/dart/resolution/local_function_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/local_function_test.dart
@@ -40,7 +40,7 @@
       error(HintCode.UNUSED_ELEMENT, 23, 1),
     ]);
     var node = findNode.functionDeclaration('g() {}');
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     expect(element.name, 'g');
     expect(element.nameOffset, 23);
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/map_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/map_pattern_test.dart
new file mode 100644
index 0000000..08588af
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/map_pattern_test.dart
@@ -0,0 +1,208 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(MapPatternResolutionTest);
+  });
+}
+
+@reflectiveTest
+class MapPatternResolutionTest extends PatternsResolutionTest {
+  test_empty() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case {}:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+MapPattern
+  leftBracket: {
+  rightBracket: }
+''');
+  }
+
+  test_empty_withWhitespace() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case { }:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+MapPattern
+  leftBracket: {
+  rightBracket: }
+''');
+  }
+
+  test_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case {'a': 0} as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+CastPattern
+  pattern: MapPattern
+    leftBracket: {
+    entries
+      MapPatternEntry
+        key: SimpleStringLiteral
+          literal: 'a'
+        separator: :
+        value: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+    rightBracket: }
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+''');
+  }
+
+  test_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case {'a': 0}!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: MapPattern
+    leftBracket: {
+    entries
+      MapPatternEntry
+        key: SimpleStringLiteral
+          literal: 'a'
+        separator: :
+        value: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+    rightBracket: }
+  operator: !
+''');
+  }
+
+  test_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case {'a': 0}?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: MapPattern
+    leftBracket: {
+    entries
+      MapPatternEntry
+        key: SimpleStringLiteral
+          literal: 'a'
+        separator: :
+        value: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+    rightBracket: }
+  operator: ?
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case {'a': 1, 'b': 2}:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+MapPattern
+  leftBracket: {
+  entries
+    MapPatternEntry
+      key: SimpleStringLiteral
+        literal: 'a'
+      separator: :
+      value: ConstantPattern
+        expression: IntegerLiteral
+          literal: 1
+    MapPatternEntry
+      key: SimpleStringLiteral
+        literal: 'b'
+      separator: :
+      value: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightBracket: }
+''');
+  }
+
+  test_withTypeArguments() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case <String, int>{'a': 1, 'b': 2}:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+MapPattern
+  typeArguments: TypeArgumentList
+    leftBracket: <
+    arguments
+      NamedType
+        name: SimpleIdentifier
+          token: String
+      NamedType
+        name: SimpleIdentifier
+          token: int
+    rightBracket: >
+  leftBracket: {
+  entries
+    MapPatternEntry
+      key: SimpleStringLiteral
+        literal: 'a'
+      separator: :
+      value: ConstantPattern
+        expression: IntegerLiteral
+          literal: 1
+    MapPatternEntry
+      key: SimpleStringLiteral
+        literal: 'b'
+      separator: :
+      value: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightBracket: }
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index dc0c9bc..f048c77 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -114,19 +114,19 @@
               staticElement: self::@class::A
               staticType: null
             type: A
-          staticElement: self::@class::A::@constructor::•
+          staticElement: self::@class::A::@constructor::new
         argumentList: ArgumentList
           leftParenthesis: (
           arguments
             IntegerLiteral
               literal: 0
-              parameter: self::@class::A::@constructor::•::@parameter::f
+              parameter: self::@class::A::@constructor::new::@parameter::f
               staticType: int
           rightParenthesis: )
-        parameter: self::@class::A::@constructor::•::@parameter::f
+        parameter: self::@class::A::@constructor::new::@parameter::f
         staticType: A
     rightParenthesis: )
-  element: self::@class::A::@constructor::•
+  element: self::@class::A::@constructor::new
 ''');
     _assertAnnotationValueText(annotation, r'''
 A
@@ -215,10 +215,10 @@
     arguments
       IntegerLiteral
         literal: 3
-        parameter: self::@class::A::@constructor::•::@parameter::a
+        parameter: self::@class::A::@constructor::new::@parameter::a
         staticType: int
     rightParenthesis: )
-  element: self::@class::A::@constructor::•
+  element: self::@class::A::@constructor::new
 ''');
 
     final localVariable = findElement.localVar('x');
@@ -272,6 +272,72 @@
     _assertAtFoo42();
   }
 
+  test_location_recordTypeAnnotation_named() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  final int f;
+  const A(this.f);
+}
+
+({@A(0) int f1, String f2}) f() => throw 0;
+''');
+    final node = findNode.annotation('@A');
+    assertResolvedNodeText(node, r'''
+Annotation
+  atSign: @
+  name: SimpleIdentifier
+    token: A
+    staticElement: self::@class::A
+    staticType: null
+  arguments: ArgumentList
+    leftParenthesis: (
+    arguments
+      IntegerLiteral
+        literal: 0
+        parameter: self::@class::A::@constructor::new::@parameter::f
+        staticType: int
+    rightParenthesis: )
+  element: self::@class::A::@constructor::new
+''');
+    _assertAnnotationValueText(node, r'''
+A
+  f: int 0
+''');
+  }
+
+  test_location_recordTypeAnnotation_positional() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  final int f;
+  const A(this.f);
+}
+
+(int, @A(0) String) f() => throw 0;
+''');
+    final node = findNode.annotation('@A');
+    assertResolvedNodeText(node, r'''
+Annotation
+  atSign: @
+  name: SimpleIdentifier
+    token: A
+    staticElement: self::@class::A
+    staticType: null
+  arguments: ArgumentList
+    leftParenthesis: (
+    arguments
+      IntegerLiteral
+        literal: 0
+        parameter: self::@class::A::@constructor::new::@parameter::f
+        staticType: int
+    rightParenthesis: )
+  element: self::@class::A::@constructor::new
+''');
+    _assertAnnotationValueText(node, r'''
+A
+  f: int 0
+''');
+  }
+
   test_optIn_fromOptOut_class() async {
     newFile('$testPackageLibPath/a.dart', r'''
 class A {
@@ -300,12 +366,12 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: package:test/a.dart::@class::A::@constructor::•::@parameter::a
+          base: package:test/a.dart::@class::A::@constructor::new::@parameter::a
           isLegacy: true
         staticType: int*
     rightParenthesis: )
   element: ConstructorMember
-    base: package:test/a.dart::@class::A::@constructor::•
+    base: package:test/a.dart::@class::A::@constructor::new
     isLegacy: true
 ''');
   }
@@ -535,12 +601,12 @@
       IntegerLiteral
         literal: 0
         parameter: ParameterMember
-          base: package:test/a.dart::@class::A::@constructor::•::@parameter::a
+          base: package:test/a.dart::@class::A::@constructor::new::@parameter::a
           isLegacy: true
         staticType: int*
     rightParenthesis: )
   element: ConstructorMember
-    base: package:test/a.dart::@class::A::@constructor::•
+    base: package:test/a.dart::@class::A::@constructor::new
     isLegacy: true
 ''');
   }
@@ -720,11 +786,6 @@
 A
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-    );
   }
 
   test_value_class_staticConstField() async {
@@ -785,20 +846,15 @@
     arguments
       IntegerLiteral
         literal: 42
-        parameter: self::@class::A::@constructor::•::@parameter::f
+        parameter: self::@class::A::@constructor::new::@parameter::f
         staticType: int
     rightParenthesis: )
-  element: self::@class::A::@constructor::•
+  element: self::@class::A::@constructor::new
 ''');
     _assertAnnotationValueText(annotation, r'''
 A
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-    );
   }
 
   test_value_genericClass_downwards_inference_namedConstructor() async {
@@ -852,11 +908,6 @@
   f: List
     elementType: List<Object?>
 ''');
-    assertElement2(
-      findNode.listLiteral('[]').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'Object?'},
-    );
   }
 
   test_value_genericClass_downwards_inference_unnamedConstructor() async {
@@ -885,12 +936,12 @@
         leftBracket: [
         rightBracket: ]
         parameter: FieldFormalParameterMember
-          base: self::@class::A::@constructor::•::@parameter::f
+          base: self::@class::A::@constructor::new::@parameter::f
           substitution: {T: Object?}
         staticType: List<List<Object?>>
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::A::@constructor::•
+    base: self::@class::A::@constructor::new
     substitution: {T: Object?}
 ''');
     _assertAnnotationValueText(annotation, r'''
@@ -898,11 +949,6 @@
   f: List
     elementType: List<Object?>
 ''');
-    assertElement2(
-      findNode.listLiteral('[]').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'Object?'},
-    );
   }
 
   test_value_genericClass_inference_namedConstructor() async {
@@ -954,11 +1000,6 @@
 A<int>
   f: int 42
 ''');
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_genericClass_inference_unnamedConstructor() async {
@@ -986,23 +1027,18 @@
       IntegerLiteral
         literal: 42
         parameter: FieldFormalParameterMember
-          base: self::@class::A::@constructor::•::@parameter::f
+          base: self::@class::A::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::A::@constructor::•
+    base: self::@class::A::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
 A<int>
   f: int 42
 ''');
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_genericClass_instanceGetter() async {
@@ -1172,11 +1208,6 @@
 A<int>
   f: int 42
 ''');
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_genericClass_typeArguments_unnamedConstructor() async {
@@ -1214,23 +1245,18 @@
       IntegerLiteral
         literal: 42
         parameter: FieldFormalParameterMember
-          base: self::@class::A::@constructor::•::@parameter::f
+          base: self::@class::A::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::A::@constructor::•
+    base: self::@class::A::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
 A<int>
   f: int 42
 ''');
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_genericClass_unnamedConstructor_noGenericMetadata() async {
@@ -1259,23 +1285,18 @@
       IntegerLiteral
         literal: 42
         parameter: FieldFormalParameterMember
-          base: self::@class::A::@constructor::•::@parameter::f
+          base: self::@class::A::@constructor::new::@parameter::f
           substitution: {T: dynamic}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::A::@constructor::•
+    base: self::@class::A::@constructor::new
     substitution: {T: dynamic}
 ''');
     _assertAnnotationValueText(annotation, r'''
 A<dynamic>
   f: int 42
 ''');
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'dynamic'},
-    );
   }
 
   test_value_genericMixinApplication_inference_unnamedConstructor() async {
@@ -1307,12 +1328,12 @@
       IntegerLiteral
         literal: 42
         parameter: ParameterMember
-          base: self::@class::B::@constructor::•::@parameter::f
+          base: self::@class::B::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::B::@constructor::•
+    base: self::@class::B::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
@@ -1354,12 +1375,12 @@
       IntegerLiteral
         literal: 42
         parameter: ParameterMember
-          base: self::@class::B::@constructor::•::@parameter::f
+          base: self::@class::B::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::B::@constructor::•
+    base: self::@class::B::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
@@ -1398,12 +1419,12 @@
       IntegerLiteral
         literal: 42
         parameter: ParameterMember
-          base: self::@class::B::@constructor::•::@parameter::f
+          base: self::@class::B::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::B::@constructor::•
+    base: self::@class::B::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
@@ -1441,12 +1462,12 @@
       IntegerLiteral
         literal: 42
         parameter: ParameterMember
-          base: self::@class::B::@constructor::•::@parameter::f
+          base: self::@class::B::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::B::@constructor::•
+    base: self::@class::B::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
@@ -1485,12 +1506,12 @@
       IntegerLiteral
         literal: 42
         parameter: ParameterMember
-          base: self::@class::B::@constructor::•::@parameter::f
+          base: self::@class::B::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::B::@constructor::•
+    base: self::@class::B::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
@@ -1531,12 +1552,12 @@
       IntegerLiteral
         literal: 42
         parameter: ParameterMember
-          base: self::@class::B::@constructor::•::@parameter::f
+          base: self::@class::B::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::B::@constructor::•
+    base: self::@class::B::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
@@ -1585,12 +1606,12 @@
       IntegerLiteral
         literal: 42
         parameter: ParameterMember
-          base: self::@class::B::@constructor::•::@parameter::f
+          base: self::@class::B::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::B::@constructor::•
+    base: self::@class::B::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
@@ -1790,12 +1811,6 @@
 A<int>
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.importFind('package:test/a.dart').parameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_prefix_typeAlias_generic_class_generic_all_inference_unnamedConstructor() async {
@@ -1836,24 +1851,18 @@
       IntegerLiteral
         literal: 42
         parameter: FieldFormalParameterMember
-          base: package:test/a.dart::@class::A::@constructor::•::@parameter::f
+          base: package:test/a.dart::@class::A::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: package:test/a.dart::@class::A::@constructor::•
+    base: package:test/a.dart::@class::A::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
 A<int>
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.importFind('package:test/a.dart').parameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_prefix_typeAlias_generic_class_generic_all_typeArguments_namedConstructor() async {
@@ -1923,12 +1932,6 @@
 A<int>
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.importFind('package:test/a.dart').parameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_prefix_typeAlias_generic_class_generic_all_typeArguments_unnamedConstructor() async {
@@ -1979,24 +1982,18 @@
       IntegerLiteral
         literal: 42
         parameter: FieldFormalParameterMember
-          base: package:test/a.dart::@class::A::@constructor::•::@parameter::f
+          base: package:test/a.dart::@class::A::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: package:test/a.dart::@class::A::@constructor::•
+    base: package:test/a.dart::@class::A::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
 A<int>
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.importFind('package:test/a.dart').parameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_typeAlias_class_staticConstField() async {
@@ -2099,18 +2096,6 @@
   t: int 42
   u: double 1.2
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('t'),
-      substitution: {'T': 'int', 'U': 'double'},
-    );
-
-    assertElement2(
-      findNode.doubleLiteral('1.2').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('u'),
-      substitution: {'T': 'int', 'U': 'double'},
-    );
   }
 
   test_value_typeAlias_generic_class_generic_1of2_typeArguments_unnamedConstructor() async {
@@ -2151,18 +2136,18 @@
       IntegerLiteral
         literal: 42
         parameter: FieldFormalParameterMember
-          base: self::@class::A::@constructor::•::@parameter::t
+          base: self::@class::A::@constructor::new::@parameter::t
           substitution: {T: int, U: double}
         staticType: int
       DoubleLiteral
         literal: 1.2
         parameter: FieldFormalParameterMember
-          base: self::@class::A::@constructor::•::@parameter::u
+          base: self::@class::A::@constructor::new::@parameter::u
           substitution: {T: int, U: double}
         staticType: double
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::A::@constructor::•
+    base: self::@class::A::@constructor::new
     substitution: {T: int, U: double}
 ''');
     _assertAnnotationValueText(annotation, r'''
@@ -2170,18 +2155,6 @@
   t: int 42
   u: double 1.2
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('t'),
-      substitution: {'T': 'int', 'U': 'double'},
-    );
-
-    assertElement2(
-      findNode.doubleLiteral('1.2').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('u'),
-      substitution: {'T': 'int', 'U': 'double'},
-    );
   }
 
   test_value_typeAlias_generic_class_generic_all_inference_namedConstructor() async {
@@ -2235,12 +2208,6 @@
 A<int>
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_typeAlias_generic_class_generic_all_inference_unnamedConstructor() async {
@@ -2270,24 +2237,18 @@
       IntegerLiteral
         literal: 42
         parameter: FieldFormalParameterMember
-          base: self::@class::A::@constructor::•::@parameter::f
+          base: self::@class::A::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::A::@constructor::•
+    base: self::@class::A::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
 A<int>
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_typeAlias_generic_class_generic_all_typeArguments_namedConstructor() async {
@@ -2346,12 +2307,6 @@
 A<int>
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_typeAlias_generic_class_generic_all_typeArguments_unnamedConstructor() async {
@@ -2391,24 +2346,18 @@
       IntegerLiteral
         literal: 42
         parameter: FieldFormalParameterMember
-          base: self::@class::A::@constructor::•::@parameter::f
+          base: self::@class::A::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::A::@constructor::•
+    base: self::@class::A::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
 A<int>
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_typeAlias_notGeneric_class_generic_namedConstructor() async {
@@ -2462,12 +2411,6 @@
 A<int>
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_typeAlias_notGeneric_class_generic_unnamedConstructor() async {
@@ -2497,24 +2440,18 @@
       IntegerLiteral
         literal: 42
         parameter: FieldFormalParameterMember
-          base: self::@class::A::@constructor::•::@parameter::f
+          base: self::@class::A::@constructor::new::@parameter::f
           substitution: {T: int}
         staticType: int
     rightParenthesis: )
   element: ConstructorMember
-    base: self::@class::A::@constructor::•
+    base: self::@class::A::@constructor::new
     substitution: {T: int}
 ''');
     _assertAnnotationValueText(annotation, r'''
 A<int>
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-      substitution: {'T': 'int'},
-    );
   }
 
   test_value_typeAlias_notGeneric_class_notGeneric_namedConstructor() async {
@@ -2560,11 +2497,6 @@
 A
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-    );
   }
 
   test_value_typeAlias_notGeneric_class_notGeneric_unnamedConstructor() async {
@@ -2593,20 +2525,15 @@
     arguments
       IntegerLiteral
         literal: 42
-        parameter: self::@class::A::@constructor::•::@parameter::f
+        parameter: self::@class::A::@constructor::new::@parameter::f
         staticType: int
     rightParenthesis: )
-  element: self::@class::A::@constructor::•
+  element: self::@class::A::@constructor::new
 ''');
     _assertAnnotationValueText(annotation, r'''
 A
   f: int 42
 ''');
-
-    assertElement2(
-      findNode.integerLiteral('42').staticParameterElement,
-      declaration: findElement.fieldFormalParameter('f'),
-    );
   }
 
   void _assertAnnotationValueText(Annotation annotation, String expected) {
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 8265b92..29cb4e1 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -505,6 +505,117 @@
 ''');
   }
 
+  test_hasReceiver_record_defined_extension() async {
+    await assertNoErrorsInCode(r'''
+extension E on (int, String) {
+  void foo(int a) {}
+}
+
+void f((int, String) r) {
+  r.foo(0);
+}
+''');
+
+    final node = findNode.methodInvocation('r.foo(0)');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: r
+    staticElement: self::@function::f::@parameter::r
+    staticType: (int, String)
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: self::@extension::E::@method::foo
+    staticType: void Function(int)
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      IntegerLiteral
+        literal: 0
+        parameter: self::@extension::E::@method::foo::@parameter::a
+        staticType: int
+    rightParenthesis: )
+  staticInvokeType: void Function(int)
+  staticType: void
+''');
+  }
+
+  test_hasReceiver_recordQ_defined_extension() async {
+    await assertNoErrorsInCode(r'''
+extension E on (int, String)? {
+  void foo(int a) {}
+}
+
+void f((int, String)? r) {
+  r.foo(0);
+}
+''');
+
+    final node = findNode.methodInvocation('r.foo(0)');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: r
+    staticElement: self::@function::f::@parameter::r
+    staticType: (int, String)?
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: self::@extension::E::@method::foo
+    staticType: void Function(int)
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      IntegerLiteral
+        literal: 0
+        parameter: self::@extension::E::@method::foo::@parameter::a
+        staticType: int
+    rightParenthesis: )
+  staticInvokeType: void Function(int)
+  staticType: void
+''');
+  }
+
+  test_hasReceiver_recordQ_notDefined_extension() async {
+    await assertErrorsInCode(r'''
+extension E on (int, String) {
+  void foo(int a) {}
+}
+
+void f((int, String)? r) {
+  r.foo(0);
+}
+''', [
+      error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
+          86, 3),
+    ]);
+
+    final node = findNode.methodInvocation('r.foo(0)');
+    assertResolvedNodeText(node, r'''
+MethodInvocation
+  target: SimpleIdentifier
+    token: r
+    staticElement: self::@function::f::@parameter::r
+    staticType: (int, String)?
+  operator: .
+  methodName: SimpleIdentifier
+    token: foo
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    arguments
+      IntegerLiteral
+        literal: 0
+        parameter: <null>
+        staticType: int
+    rightParenthesis: )
+  staticInvokeType: dynamic
+  staticType: dynamic
+''');
+  }
+
   test_hasReceiver_typeAlias_staticMethod() async {
     await assertNoErrorsInCode(r'''
 class A {
@@ -857,7 +968,7 @@
           staticElement: self::@class::A
           staticType: null
         type: A
-      staticElement: self::@class::A::@constructor::•
+      staticElement: self::@class::A::@constructor::new
     argumentList: ArgumentList
       leftParenthesis: (
       rightParenthesis: )
@@ -7432,6 +7543,84 @@
     }
   }
 
+  test_noReceiver_call_extension_on_FunctionType() async {
+    await assertNoErrorsInCode(r'''
+extension E on int Function() {
+  void f() {
+    call();
+  }
+}
+''');
+
+    final node = findNode.methodInvocation('call()');
+    if (isNullSafetyEnabled) {
+      assertResolvedNodeText(node, r'''
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: call
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: int Function()
+  staticType: int
+''');
+    } else {
+      assertResolvedNodeText(node, r'''
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: call
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: int* Function()*
+  staticType: int*
+''');
+    }
+  }
+
+  test_noReceiver_call_extension_on_FunctionType_bounded() async {
+    await assertNoErrorsInCode(r'''
+extension E<T extends int Function()> on T {
+  void f() {
+    call();
+  }
+}
+''');
+
+    final node = findNode.methodInvocation('call()');
+    if (isNullSafetyEnabled) {
+      assertResolvedNodeText(node, r'''
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: call
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: int Function()
+  staticType: int
+''');
+    } else {
+      assertResolvedNodeText(node, r'''
+MethodInvocation
+  methodName: SimpleIdentifier
+    token: call
+    staticElement: <null>
+    staticType: dynamic
+  argumentList: ArgumentList
+    leftParenthesis: (
+    rightParenthesis: )
+  staticInvokeType: int* Function()*
+  staticType: int*
+''');
+    }
+  }
+
   test_noReceiver_getter_superClass() async {
     await assertNoErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 495a3e4..d17692e 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -32,7 +32,7 @@
     assertElementName(gElement, 'g', offset: 20);
 
     var gNode = findNode.methodDeclaration('g =>');
-    expect(gNode.declaredElement2, same(gElement));
+    expect(gNode.declaredElement, same(gElement));
 
     var fields = element.fields;
     expect(fields, hasLength(1));
@@ -55,7 +55,7 @@
     assertElementName(fooElement, 'foo', offset: 17);
 
     var fooNode = findNode.methodDeclaration('foo()');
-    expect(fooNode.declaredElement2, same(fooElement));
+    expect(fooNode.declaredElement, same(fooElement));
   }
 
   test_accessor_setter() async {
@@ -74,7 +74,7 @@
     assertElementName(sElement, 's=', offset: 21);
 
     var gNode = findNode.methodDeclaration('s(int _)');
-    expect(gNode.declaredElement2, same(sElement));
+    expect(gNode.declaredElement, same(sElement));
 
     var fields = element.fields;
     expect(fields, hasLength(1));
@@ -136,14 +136,7 @@
     expect(element.typeParameters, isEmpty);
 
     expect(element.supertype, isNull);
-    expect(element.isAbstract, isTrue);
-    // ignore: deprecated_member_use_from_same_package
-    expect(element.isEnum, isFalse);
-    // ignore: deprecated_member_use_from_same_package
-    expect(element.isMixin, isTrue);
-    expect(element.isMixinApplication, isFalse);
     expect(element.thisType.isDartCoreObject, isFalse);
-    expect(element.isDartCoreObject, isFalse);
 
     assertElementTypes(
       element.superclassConstraints,
@@ -208,7 +201,7 @@
     assertEnclosingElement(tElement, element);
 
     var tNode = findNode.typeParameter('T> {');
-    assertElement(tNode.declaredElement2, tElement);
+    assertElement(tNode.declaredElement, tElement);
 
     var fields = element.fields;
     expect(fields, hasLength(1));
@@ -218,7 +211,7 @@
     assertEnclosingElement(fElement, element);
 
     var fNode = findNode.variableDeclaration('f;');
-    assertElement(fNode.declaredElement2, fElement);
+    assertElement(fNode.declaredElement, fElement);
 
     assertNamedType(findNode.namedType('T f'), tElement, 'T');
 
diff --git a/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart b/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
index 6306b35..9635f6f 100644
--- a/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
@@ -57,7 +57,7 @@
         staticType: null
       type: B<num>
     staticElement: ConstructorMember
-      base: package:test/a.dart::@class::B::@constructor::•
+      base: package:test/a.dart::@class::B::@constructor::new
       substitution: {T: num}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -122,7 +122,7 @@
         staticType: null
       type: B<num>
     staticElement: ConstructorMember
-      base: package:test/a.dart::@class::B::@constructor::•
+      base: package:test/a.dart::@class::B::@constructor::new
       substitution: {T: num}
   argumentList: ArgumentList
     leftParenthesis: (
@@ -166,7 +166,7 @@
         staticElement: package:test/a.dart::@class::A
         staticType: null
       type: A
-    staticElement: package:test/a.dart::@class::A::@constructor::•
+    staticElement: package:test/a.dart::@class::A::@constructor::new
   argumentList: ArgumentList
     leftParenthesis: (
     rightParenthesis: )
@@ -225,7 +225,7 @@
         staticElement: package:test/a.dart::@class::A
         staticType: null
       type: A
-    staticElement: package:test/a.dart::@class::A::@constructor::•
+    staticElement: package:test/a.dart::@class::A::@constructor::new
   argumentList: ArgumentList
     leftParenthesis: (
     rightParenthesis: )
@@ -275,7 +275,7 @@
         rightBracket: >
       type: C<int>
     staticElement: ConstructorMember
-      base: package:test/a.dart::@class::C::@constructor::•
+      base: package:test/a.dart::@class::C::@constructor::new
       substitution: {T: int}
   argumentList: ArgumentList
     leftParenthesis: (
diff --git a/pkg/analyzer/test/src/dart/resolution/parenthesized_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/parenthesized_pattern_test.dart
new file mode 100644
index 0000000..642818e
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/parenthesized_pattern_test.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ParenthesizedPatternResolutionTest);
+  });
+}
+
+@reflectiveTest
+class ParenthesizedPatternResolutionTest extends PatternsResolutionTest {
+  test_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (0) as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: ParenthesizedPattern
+    leftParenthesis: (
+    pattern: ConstantPattern
+      expression: IntegerLiteral
+        literal: 0
+        staticType: int
+    rightParenthesis: )
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (0)!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ParenthesizedPattern
+    leftParenthesis: (
+    pattern: ConstantPattern
+      expression: IntegerLiteral
+        literal: 0
+    rightParenthesis: )
+  operator: !
+''');
+  }
+
+  test_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (0)?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: ParenthesizedPattern
+    leftParenthesis: (
+    pattern: ConstantPattern
+      expression: IntegerLiteral
+        literal: 0
+    rightParenthesis: )
+  operator: ?
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
index cf819fe..6e08bca 100644
--- a/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
@@ -877,7 +877,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
@@ -908,7 +908,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A*
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
diff --git a/pkg/analyzer/test/src/dart/resolution/postfix_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/postfix_pattern_test.dart
new file mode 100644
index 0000000..be3becc
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/postfix_pattern_test.dart
@@ -0,0 +1,744 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PostfixPattern_NullAssert_ResolutionTest);
+    defineReflectiveTests(PostfixPattern_NullCheck_ResolutionTest);
+  });
+}
+
+@reflectiveTest
+class PostfixPattern_NullAssert_ResolutionTest extends PatternsResolutionTest {
+  test_inside_extractorPattern_namedExplicitly() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(f: 0!):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: SimpleIdentifier
+    token: C
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        name: f
+        colon: :
+      pattern: PostfixPattern
+        operand: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+        operator: !
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_extractorPattern_namedImplicitly() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(: var f!):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: SimpleIdentifier
+    token: C
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        colon: :
+      pattern: PostfixPattern
+        operand: VariablePattern
+          keyword: var
+          name: f
+        operator: !
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(int? x) {
+  if (x case var y!) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    keyword: var
+    name: y
+    declaredElement: hasImplicitType y@34
+      type: int
+  operator: !
+''');
+  }
+
+  test_inside_listPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case [0!]:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ListPattern
+  leftBracket: [
+  elements
+    PostfixPattern
+      operand: ConstantPattern
+        expression: IntegerLiteral
+          literal: 0
+      operator: !
+  rightBracket: ]
+''');
+  }
+
+  test_inside_logicalAnd_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1! & 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: PostfixPattern
+    operand: ConstantPattern
+      expression: IntegerLiteral
+        literal: 1
+    operator: !
+  operator: &
+  rightOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_inside_logicalAnd_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1 & 2!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 1
+  operator: &
+  rightOperand: PostfixPattern
+    operand: ConstantPattern
+      expression: IntegerLiteral
+        literal: 2
+    operator: !
+''');
+  }
+
+  test_inside_logicalOr_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1! | 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: PostfixPattern
+    operand: ConstantPattern
+      expression: IntegerLiteral
+        literal: 1
+    operator: !
+  operator: |
+  rightOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_inside_logicalOr_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1 | 2!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 1
+  operator: |
+  rightOperand: PostfixPattern
+    operand: ConstantPattern
+      expression: IntegerLiteral
+        literal: 2
+    operator: !
+''');
+  }
+
+  test_inside_mapPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case {'a': 0!}:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+MapPattern
+  leftBracket: {
+  entries
+    MapPatternEntry
+      key: SimpleStringLiteral
+        literal: 'a'
+      separator: :
+      value: PostfixPattern
+        operand: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+        operator: !
+  rightBracket: }
+''');
+  }
+
+  test_inside_parenthesizedPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (0!):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+ParenthesizedPattern
+  leftParenthesis: (
+  pattern: PostfixPattern
+    operand: ConstantPattern
+      expression: IntegerLiteral
+        literal: 0
+        staticType: int
+    operator: !
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_namedExplicitly() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (n: 1!, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        name: n
+        colon: :
+      pattern: PostfixPattern
+        operand: ConstantPattern
+          expression: IntegerLiteral
+            literal: 1
+        operator: !
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_namedImplicitly() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (: var n!, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        colon: :
+      pattern: PostfixPattern
+        operand: VariablePattern
+          keyword: var
+          name: n
+        operator: !
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_unnamed() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (1!, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      pattern: PostfixPattern
+        operand: ConstantPattern
+          expression: IntegerLiteral
+            literal: 1
+        operator: !
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x, int y) {
+  switch (x) {
+    case y!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: SimpleIdentifier
+      token: y
+      staticElement: self::@function::f::@parameter::y
+      staticType: int
+  operator: !
+''');
+  }
+}
+
+@reflectiveTest
+class PostfixPattern_NullCheck_ResolutionTest extends PatternsResolutionTest {
+  test_inside_extractorPattern_namedExplicitly() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(f: 0?):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: SimpleIdentifier
+    token: C
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        name: f
+        colon: :
+      pattern: PostfixPattern
+        operand: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+        operator: ?
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_extractorPattern_namedImplicitly() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(: var f?):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: SimpleIdentifier
+    token: C
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        colon: :
+      pattern: PostfixPattern
+        operand: VariablePattern
+          keyword: var
+          name: f
+        operator: ?
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(int? x) {
+  if (x case var y?) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    keyword: var
+    name: y
+    declaredElement: hasImplicitType y@34
+      type: int
+  operator: ?
+''');
+  }
+
+  test_inside_listPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case [0?]:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ListPattern
+  leftBracket: [
+  elements
+    PostfixPattern
+      operand: ConstantPattern
+        expression: IntegerLiteral
+          literal: 0
+      operator: ?
+  rightBracket: ]
+''');
+  }
+
+  test_inside_logicalAnd_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1? & 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: PostfixPattern
+    operand: ConstantPattern
+      expression: IntegerLiteral
+        literal: 1
+    operator: ?
+  operator: &
+  rightOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_inside_logicalAnd_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1 & 2?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 1
+  operator: &
+  rightOperand: PostfixPattern
+    operand: ConstantPattern
+      expression: IntegerLiteral
+        literal: 2
+    operator: ?
+''');
+  }
+
+  test_inside_logicalOr_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1? | 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: PostfixPattern
+    operand: ConstantPattern
+      expression: IntegerLiteral
+        literal: 1
+    operator: ?
+  operator: |
+  rightOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_inside_logicalOr_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1 | 2?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 1
+  operator: |
+  rightOperand: PostfixPattern
+    operand: ConstantPattern
+      expression: IntegerLiteral
+        literal: 2
+    operator: ?
+''');
+  }
+
+  test_inside_mapPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case {'a': 0?}:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+MapPattern
+  leftBracket: {
+  entries
+    MapPatternEntry
+      key: SimpleStringLiteral
+        literal: 'a'
+      separator: :
+      value: PostfixPattern
+        operand: ConstantPattern
+          expression: IntegerLiteral
+            literal: 0
+        operator: ?
+  rightBracket: }
+''');
+  }
+
+  test_inside_parenthesizedPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (0?):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+ParenthesizedPattern
+  leftParenthesis: (
+  pattern: PostfixPattern
+    operand: ConstantPattern
+      expression: IntegerLiteral
+        literal: 0
+        staticType: int
+    operator: ?
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_namedExplicitly() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (n: 1?, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        name: n
+        colon: :
+      pattern: PostfixPattern
+        operand: ConstantPattern
+          expression: IntegerLiteral
+            literal: 1
+        operator: ?
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_namedImplicitly() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (: var n?, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        colon: :
+      pattern: PostfixPattern
+        operand: VariablePattern
+          keyword: var
+          name: n
+        operator: ?
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_unnamed() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (1?, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      pattern: PostfixPattern
+        operand: ConstantPattern
+          expression: IntegerLiteral
+            literal: 1
+        operator: ?
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x, int y) {
+  switch (x) {
+    case y?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: ConstantPattern
+    expression: SimpleIdentifier
+      token: y
+      staticElement: self::@function::f::@parameter::y
+      staticType: int
+  operator: ?
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
index dd07c0b..9410ac9 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
@@ -796,7 +796,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
@@ -827,7 +827,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A*
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index b28c322..3cd60c2 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -399,6 +399,29 @@
 ''');
   }
 
+  test_ofRecordType_namedField_ofTypeParameter() async {
+    await assertNoErrorsInCode(r'''
+void f<T extends ({int foo})>(T r) {
+  r.foo;
+}
+''');
+
+    final node = findNode.propertyAccess(r'foo;');
+    assertResolvedNodeText(node, r'''
+PropertyAccess
+  target: SimpleIdentifier
+    token: r
+    staticElement: self::@function::f::@parameter::r
+    staticType: T
+  operator: .
+  propertyName: SimpleIdentifier
+    token: foo
+    staticElement: <null>
+    staticType: int
+  staticType: int
+''');
+  }
+
   test_ofRecordType_Object_hashCode() async {
     await assertNoErrorsInCode('''
 void f(({int foo}) r) {
@@ -622,6 +645,29 @@
 ''');
   }
 
+  test_ofRecordType_positionalField_ofTypeParameter() async {
+    await assertNoErrorsInCode(r'''
+void f<T extends (int, String)>(T r) {
+  r.$0;
+}
+''');
+
+    final node = findNode.propertyAccess(r'$0;');
+    assertResolvedNodeText(node, r'''
+PropertyAccess
+  target: SimpleIdentifier
+    token: r
+    staticElement: self::@function::f::@parameter::r
+    staticType: T
+  operator: .
+  propertyName: SimpleIdentifier
+    token: $0
+    staticElement: <null>
+    staticType: int
+  staticType: int
+''');
+  }
+
   test_ofRecordType_unresolved() async {
     await assertErrorsInCode('''
 void f(({int foo}) r) {
@@ -957,7 +1003,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
@@ -992,7 +1038,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A*
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
@@ -1046,7 +1092,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
@@ -1081,7 +1127,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A*
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
@@ -1296,7 +1342,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
@@ -1331,7 +1377,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A*
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
@@ -1387,7 +1433,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
@@ -1422,7 +1468,7 @@
             staticElement: self::@class::A
             staticType: null
           type: A*
-        staticElement: self::@class::A::@constructor::•
+        staticElement: self::@class::A::@constructor::new
       argumentList: ArgumentList
         leftParenthesis: (
         rightParenthesis: )
diff --git a/pkg/analyzer/test/src/dart/resolution/record_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/record_literal_test.dart
index 39e3054..e3917f2 100644
--- a/pkg/analyzer/test/src/dart/resolution/record_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/record_literal_test.dart
@@ -14,6 +14,295 @@
 
 @reflectiveTest
 class RecordLiteralTest extends PubPackageResolutionTest {
+  test_hasContext_mixed() async {
+    await assertNoErrorsInCode(r'''
+class A1 {}
+class A2 {}
+class A3 {}
+class A4 {}
+class A5 {}
+
+final (A1, A2, A3, {A4 f1, A5 f2}) x = (g(), f1: g(), g(), f2: g(), g());
+
+T g<T>() => throw 0;
+''');
+
+    final node = findNode.recordLiteral('(g(),');
+    assertResolvedNodeText(node, r'''
+RecordLiteral
+  leftParenthesis: (
+  fields
+    MethodInvocation
+      methodName: SimpleIdentifier
+        token: g
+        staticElement: self::@function::g
+        staticType: T Function<T>()
+      argumentList: ArgumentList
+        leftParenthesis: (
+        rightParenthesis: )
+      staticInvokeType: A1 Function()
+      staticType: A1
+      typeArgumentTypes
+        A1
+    NamedExpression
+      name: Label
+        label: SimpleIdentifier
+          token: f1
+          staticElement: <null>
+          staticType: null
+        colon: :
+      expression: MethodInvocation
+        methodName: SimpleIdentifier
+          token: g
+          staticElement: self::@function::g
+          staticType: T Function<T>()
+        argumentList: ArgumentList
+          leftParenthesis: (
+          rightParenthesis: )
+        staticInvokeType: A4 Function()
+        staticType: A4
+        typeArgumentTypes
+          A4
+    MethodInvocation
+      methodName: SimpleIdentifier
+        token: g
+        staticElement: self::@function::g
+        staticType: T Function<T>()
+      argumentList: ArgumentList
+        leftParenthesis: (
+        rightParenthesis: )
+      staticInvokeType: A2 Function()
+      staticType: A2
+      typeArgumentTypes
+        A2
+    NamedExpression
+      name: Label
+        label: SimpleIdentifier
+          token: f2
+          staticElement: <null>
+          staticType: null
+        colon: :
+      expression: MethodInvocation
+        methodName: SimpleIdentifier
+          token: g
+          staticElement: self::@function::g
+          staticType: T Function<T>()
+        argumentList: ArgumentList
+          leftParenthesis: (
+          rightParenthesis: )
+        staticInvokeType: A5 Function()
+        staticType: A5
+        typeArgumentTypes
+          A5
+    MethodInvocation
+      methodName: SimpleIdentifier
+        token: g
+        staticElement: self::@function::g
+        staticType: T Function<T>()
+      argumentList: ArgumentList
+        leftParenthesis: (
+        rightParenthesis: )
+      staticInvokeType: A3 Function()
+      staticType: A3
+      typeArgumentTypes
+        A3
+  rightParenthesis: )
+  staticType: (A1, A2, A3, {A4 f1, A5 f2})
+''');
+  }
+
+  test_hasContext_named() async {
+    await assertNoErrorsInCode(r'''
+final ({int f1, String f2}) x = (f1: g(), f2: g());
+
+T g<T>() => throw 0;
+''');
+
+    final node = findNode.recordLiteral('(f1:');
+    assertResolvedNodeText(node, r'''
+RecordLiteral
+  leftParenthesis: (
+  fields
+    NamedExpression
+      name: Label
+        label: SimpleIdentifier
+          token: f1
+          staticElement: <null>
+          staticType: null
+        colon: :
+      expression: MethodInvocation
+        methodName: SimpleIdentifier
+          token: g
+          staticElement: self::@function::g
+          staticType: T Function<T>()
+        argumentList: ArgumentList
+          leftParenthesis: (
+          rightParenthesis: )
+        staticInvokeType: int Function()
+        staticType: int
+        typeArgumentTypes
+          int
+    NamedExpression
+      name: Label
+        label: SimpleIdentifier
+          token: f2
+          staticElement: <null>
+          staticType: null
+        colon: :
+      expression: MethodInvocation
+        methodName: SimpleIdentifier
+          token: g
+          staticElement: self::@function::g
+          staticType: T Function<T>()
+        argumentList: ArgumentList
+          leftParenthesis: (
+          rightParenthesis: )
+        staticInvokeType: String Function()
+        staticType: String
+        typeArgumentTypes
+          String
+  rightParenthesis: )
+  staticType: ({int f1, String f2})
+''');
+  }
+
+  test_hasContext_named_differentOrder() async {
+    await assertNoErrorsInCode(r'''
+final ({int f1, String f2}) x = (f2: g(), f1: g());
+
+T g<T>() => throw 0;
+''');
+
+    final node = findNode.recordLiteral('(f2:');
+    assertResolvedNodeText(node, r'''
+RecordLiteral
+  leftParenthesis: (
+  fields
+    NamedExpression
+      name: Label
+        label: SimpleIdentifier
+          token: f2
+          staticElement: <null>
+          staticType: null
+        colon: :
+      expression: MethodInvocation
+        methodName: SimpleIdentifier
+          token: g
+          staticElement: self::@function::g
+          staticType: T Function<T>()
+        argumentList: ArgumentList
+          leftParenthesis: (
+          rightParenthesis: )
+        staticInvokeType: String Function()
+        staticType: String
+        typeArgumentTypes
+          String
+    NamedExpression
+      name: Label
+        label: SimpleIdentifier
+          token: f1
+          staticElement: <null>
+          staticType: null
+        colon: :
+      expression: MethodInvocation
+        methodName: SimpleIdentifier
+          token: g
+          staticElement: self::@function::g
+          staticType: T Function<T>()
+        argumentList: ArgumentList
+          leftParenthesis: (
+          rightParenthesis: )
+        staticInvokeType: int Function()
+        staticType: int
+        typeArgumentTypes
+          int
+  rightParenthesis: )
+  staticType: ({int f1, String f2})
+''');
+  }
+
+  test_hasContext_notRecordType() async {
+    await assertNoErrorsInCode(r'''
+final Object x = (g(), g());
+
+T g<T>() => throw 0;
+''');
+
+    final node = findNode.recordLiteral('(g(),');
+    assertResolvedNodeText(node, r'''
+RecordLiteral
+  leftParenthesis: (
+  fields
+    MethodInvocation
+      methodName: SimpleIdentifier
+        token: g
+        staticElement: self::@function::g
+        staticType: T Function<T>()
+      argumentList: ArgumentList
+        leftParenthesis: (
+        rightParenthesis: )
+      staticInvokeType: dynamic Function()
+      staticType: dynamic
+      typeArgumentTypes
+        dynamic
+    MethodInvocation
+      methodName: SimpleIdentifier
+        token: g
+        staticElement: self::@function::g
+        staticType: T Function<T>()
+      argumentList: ArgumentList
+        leftParenthesis: (
+        rightParenthesis: )
+      staticInvokeType: dynamic Function()
+      staticType: dynamic
+      typeArgumentTypes
+        dynamic
+  rightParenthesis: )
+  staticType: (dynamic, dynamic)
+''');
+  }
+
+  test_hasContext_positional() async {
+    await assertNoErrorsInCode(r'''
+final (int, String) x = (g(), g());
+
+T g<T>() => throw 0;
+''');
+
+    final node = findNode.recordLiteral('(g(),');
+    assertResolvedNodeText(node, r'''
+RecordLiteral
+  leftParenthesis: (
+  fields
+    MethodInvocation
+      methodName: SimpleIdentifier
+        token: g
+        staticElement: self::@function::g
+        staticType: T Function<T>()
+      argumentList: ArgumentList
+        leftParenthesis: (
+        rightParenthesis: )
+      staticInvokeType: int Function()
+      staticType: int
+      typeArgumentTypes
+        int
+    MethodInvocation
+      methodName: SimpleIdentifier
+        token: g
+        staticElement: self::@function::g
+        staticType: T Function<T>()
+      argumentList: ArgumentList
+        leftParenthesis: (
+        rightParenthesis: )
+      staticInvokeType: String Function()
+      staticType: String
+      typeArgumentTypes
+        String
+  rightParenthesis: )
+  staticType: (int, String)
+''');
+  }
+
   test_noContext_mixed() async {
     await assertNoErrorsInCode(r'''
 final x = (0, f1: 1, 2, f2: 3, 4);
diff --git a/pkg/analyzer/test/src/dart/resolution/record_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/record_pattern_test.dart
new file mode 100644
index 0000000..2363a85
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/record_pattern_test.dart
@@ -0,0 +1,168 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RecordPatternResolutionTest);
+  });
+}
+
+@reflectiveTest
+class RecordPatternResolutionTest extends PatternsResolutionTest {
+  test_empty() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case ():
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (1, 2) as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+CastPattern
+  pattern: RecordPattern
+    leftParenthesis: (
+    fields
+      RecordPatternField
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 1
+      RecordPatternField
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 2
+    rightParenthesis: )
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+''');
+  }
+
+  test_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (1, 2)!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: RecordPattern
+    leftParenthesis: (
+    fields
+      RecordPatternField
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 1
+      RecordPatternField
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 2
+    rightParenthesis: )
+  operator: !
+''');
+  }
+
+  test_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (1, 2)?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+PostfixPattern
+  operand: RecordPattern
+    leftParenthesis: (
+    fields
+      RecordPatternField
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 1
+      RecordPatternField
+        pattern: ConstantPattern
+          expression: IntegerLiteral
+            literal: 2
+    rightParenthesis: )
+  operator: ?
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (1, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 1
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_singleton() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (0,):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 0
+  rightParenthesis: )
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/relational_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/relational_pattern_test.dart
new file mode 100644
index 0000000..4b95740
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/relational_pattern_test.dart
@@ -0,0 +1,431 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RelationalPatternResolutionTest);
+  });
+}
+
+@reflectiveTest
+class RelationalPatternResolutionTest extends PatternsResolutionTest {
+  test_equal() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case == 1 << 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RelationalPattern
+  operator: ==
+  operand: BinaryExpression
+    leftOperand: IntegerLiteral
+      literal: 1
+    operator: <<
+    rightOperand: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_greaterThan() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case > 1 << 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RelationalPattern
+  operator: >
+  operand: BinaryExpression
+    leftOperand: IntegerLiteral
+      literal: 1
+    operator: <<
+    rightOperand: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_greaterThanOrEqualTo() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case >= 1 << 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RelationalPattern
+  operator: >=
+  operand: BinaryExpression
+    leftOperand: IntegerLiteral
+      literal: 1
+    operator: <<
+    rightOperand: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_inside_extractorPattern() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(f: == 0):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: SimpleIdentifier
+    token: C
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        name: f
+        colon: :
+      pattern: RelationalPattern
+        operator: ==
+        operand: IntegerLiteral
+          literal: 0
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case == 0) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertParsedNodeText(node, r'''
+RelationalPattern
+  operator: ==
+  operand: IntegerLiteral
+    literal: 0
+''');
+  }
+
+  test_inside_listPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case [== 0]:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ListPattern
+  leftBracket: [
+  elements
+    RelationalPattern
+      operator: ==
+      operand: IntegerLiteral
+        literal: 0
+  rightBracket: ]
+''');
+  }
+
+  test_inside_logicalAnd_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case == 1 & 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: RelationalPattern
+    operator: ==
+    operand: IntegerLiteral
+      literal: 1
+  operator: &
+  rightOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_inside_logicalAnd_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1 & == 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 1
+  operator: &
+  rightOperand: RelationalPattern
+    operator: ==
+    operand: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_inside_logicalOr_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case == 1 | 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: RelationalPattern
+    operator: ==
+    operand: IntegerLiteral
+      literal: 1
+  operator: |
+  rightOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_inside_logicalOr_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1 | == 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 1
+  operator: |
+  rightOperand: RelationalPattern
+    operator: ==
+    operand: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_inside_mapPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case {'a': == 0}:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+MapPattern
+  leftBracket: {
+  entries
+    MapPatternEntry
+      key: SimpleStringLiteral
+        literal: 'a'
+      separator: :
+      value: RelationalPattern
+        operator: ==
+        operand: IntegerLiteral
+          literal: 0
+  rightBracket: }
+''');
+  }
+
+  test_inside_parenthesizedPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (== 0):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ParenthesizedPattern
+  leftParenthesis: (
+  pattern: RelationalPattern
+    operator: ==
+    operand: IntegerLiteral
+      literal: 0
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_named() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (a: == 1, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        name: a
+        colon: :
+      pattern: RelationalPattern
+        operator: ==
+        operand: IntegerLiteral
+          literal: 1
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_recordPattern_unnamed() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (== 1, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      pattern: RelationalPattern
+        operator: ==
+        operand: IntegerLiteral
+          literal: 1
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case == 0:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RelationalPattern
+  operator: ==
+  operand: IntegerLiteral
+    literal: 0
+''');
+  }
+
+  test_lessThan() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case < 1 << 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RelationalPattern
+  operator: <
+  operand: BinaryExpression
+    leftOperand: IntegerLiteral
+      literal: 1
+    operator: <<
+    rightOperand: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_lessThanOrEqualTo() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case <= 1 << 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RelationalPattern
+  operator: <=
+  operand: BinaryExpression
+    leftOperand: IntegerLiteral
+      literal: 1
+    operator: <<
+    rightOperand: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_notEqual() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case != 1 << 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RelationalPattern
+  operator: !=
+  operand: BinaryExpression
+    leftOperand: IntegerLiteral
+      literal: 1
+    operator: <<
+    rightOperand: IntegerLiteral
+      literal: 2
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 300867f..92b5513 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -223,7 +223,7 @@
   }
 
   void assertEnclosingElement(Element element, Element expectedEnclosing) {
-    expect(element.enclosingElement3, expectedEnclosing);
+    expect(element.enclosingElement, expectedEnclosing);
   }
 
   Future<void> assertErrorsInCode(
@@ -428,6 +428,22 @@
     assertType(parameterElement.type, expected);
   }
 
+  void assertParsedNodeText(
+    AstNode node,
+    String expected, {
+    bool skipArgumentList = false,
+  }) {
+    var actual = _parsedNodeText(
+      node,
+      skipArgumentList: skipArgumentList,
+    );
+    if (actual != expected) {
+      print(actual);
+      NodeTextExpectationsCollector.add(actual);
+    }
+    expect(actual, expected);
+  }
+
   void assertPrefixedIdentifier(
     PrefixedIdentifier node, {
     required Object? element,
@@ -500,7 +516,7 @@
   ) {
     var actualMapString = Map.fromEntries(
       substitution.map.entries.where((entry) {
-        return entry.key.enclosingElement3 is! ExecutableElement;
+        return entry.key.enclosingElement is! ExecutableElement;
       }).map((entry) {
         return MapEntry(
           entry.key.name,
@@ -689,7 +705,7 @@
     } else if (node is ConstructorReference) {
       return node.constructorName.staticElement;
     } else if (node is Declaration) {
-      return node.declaredElement2;
+      return node.declaredElement;
     } else if (node is ExtensionOverride) {
       return node.staticElement;
     } else if (node is FormalParameter) {
@@ -803,6 +819,23 @@
     fail('Expected SimpleIdentifier: (${node.runtimeType}) $node');
   }
 
+  String _parsedNodeText(
+    AstNode node, {
+    bool skipArgumentList = false,
+  }) {
+    var buffer = StringBuffer();
+    node.accept(
+      ResolvedAstPrinter(
+        selfUriStr: '${result.libraryElement.source.uri}',
+        sink: buffer,
+        indent: '',
+        skipArgumentList: skipArgumentList,
+        withResolution: false,
+      ),
+    );
+    return buffer.toString();
+  }
+
   String _resolvedNodeText(
     AstNode node, {
     bool skipArgumentList = false,
diff --git a/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart b/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart
index e37f2e8..85fdc46 100644
--- a/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/simple_identifier_test.dart
@@ -77,6 +77,214 @@
     assertElement(identifier, findElement.parameter('a'));
     assertType(identifier, 'A?');
   }
+
+  test_inExtension_onFunctionType_call() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(double) {
+  void f() {
+    call;
+  }
+}
+''');
+
+    final node = findNode.simple('call;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: call
+  staticElement: <null>
+  staticType: int Function(double)
+''');
+  }
+
+  test_inExtension_onFunctionType_call_inference() async {
+    await assertNoErrorsInCode('''
+extension E on int Function<T>(T) {
+  int Function(double) f() {
+    return call;
+  }
+}
+''');
+
+    final node = findNode.simple('call;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: call
+  staticElement: <null>
+  staticType: int Function(double)
+  tearOffTypeArgumentTypes
+    double
+''');
+  }
+
+  test_inExtension_onRecordType_fromTypeParameterBound_named() async {
+    await assertNoErrorsInCode('''
+extension E<T extends ({int foo})> on T {
+  void f() {
+    foo;
+  }
+}
+''');
+
+    final node = findNode.simple('foo;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: foo
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  test_inExtension_onRecordType_fromTypeParameterBound_positional() async {
+    await assertNoErrorsInCode(r'''
+extension E<T extends (int, String)> on T {
+  void f() {
+    $0;
+  }
+}
+''');
+
+    final node = findNode.simple(r'$0;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: $0
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  test_inExtension_onRecordType_named() async {
+    await assertNoErrorsInCode('''
+extension E on ({int foo}) {
+  void f() {
+    foo;
+  }
+}
+''');
+
+    final node = findNode.simple('foo;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: foo
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  test_inExtension_onRecordType_named_fromExtension() async {
+    await assertNoErrorsInCode('''
+extension E on ({int foo}) {
+  bool get bar => true;
+
+  void f() {
+    bar;
+  }
+}
+''');
+
+    final node = findNode.simple('bar;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: bar
+  staticElement: self::@extension::E::@getter::bar
+  staticType: bool
+''');
+  }
+
+  test_inExtension_onRecordType_named_unresolved() async {
+    await assertErrorsInCode('''
+extension E on ({int foo}) {
+  void f() {
+    bar;
+  }
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 46, 3),
+    ]);
+
+    final node = findNode.simple('bar;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: bar
+  staticElement: <null>
+  staticType: dynamic
+''');
+  }
+
+  test_inExtension_onRecordType_positional_0() async {
+    await assertNoErrorsInCode(r'''
+extension E on (int, String) {
+  void f() {
+    $0;
+  }
+}
+''');
+
+    final node = findNode.simple(r'$0;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: $0
+  staticElement: <null>
+  staticType: int
+''');
+  }
+
+  test_inExtension_onRecordType_positional_1() async {
+    await assertNoErrorsInCode(r'''
+extension E on (int, String) {
+  void f() {
+    $1;
+  }
+}
+''');
+
+    final node = findNode.simple(r'$1;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: $1
+  staticElement: <null>
+  staticType: String
+''');
+  }
+
+  test_inExtension_onRecordType_positional_2_fromExtension() async {
+    await assertNoErrorsInCode(r'''
+extension E on (int, String) {
+  bool get $2 => true;
+
+  void f() {
+    $2;
+  }
+}
+''');
+
+    final node = findNode.simple(r'$2;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: $2
+  staticElement: self::@extension::E::@getter::$2
+  staticType: bool
+''');
+  }
+
+  test_inExtension_onRecordType_positional_2_unresolved() async {
+    await assertErrorsInCode(r'''
+extension E on (int, String) {
+  void f() {
+    $2;
+  }
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 48, 2),
+    ]);
+
+    final node = findNode.simple(r'$2;');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: $2
+  staticElement: <null>
+  staticType: dynamic
+''');
+  }
 }
 
 mixin SimpleIdentifierResolutionTestCases on PubPackageResolutionTest {
diff --git a/pkg/analyzer/test/src/dart/resolution/super_formal_parameter_test.dart b/pkg/analyzer/test/src/dart/resolution/super_formal_parameter_test.dart
index 1e9388a..ab0f8c9 100644
--- a/pkg/analyzer/test/src/dart/resolution/super_formal_parameter_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/super_formal_parameter_test.dart
@@ -68,27 +68,45 @@
 }
 
 class B extends A {
-  B(super.a<T>(int b));
+  B(T super.a<T>(int b));
 }
 ''');
 
-    var B = findElement.unnamedConstructor('B');
-    var element = B.superFormalParameter('a');
-
-    assertElement(
-      findNode.superFormalParameter('super.a'),
-      element,
-    );
-
-    assertElement(
-      findNode.typeParameter('T>'),
-      element.typeParameters[0],
-    );
-
-    assertElement(
-      findNode.simpleFormalParameter('b));'),
-      element.parameters[0],
-    );
+    final node = findNode.superFormalParameter('super.');
+    assertResolvedNodeText(node, r'''
+SuperFormalParameter
+  type: NamedType
+    name: SimpleIdentifier
+      token: T
+      staticElement: T@62
+      staticType: null
+    type: T
+  superKeyword: super
+  period: .
+  name: a
+  typeParameters: TypeParameterList
+    leftBracket: <
+    typeParameters
+      TypeParameter
+        name: T
+        declaredElement: T@62
+    rightBracket: >
+  parameters: FormalParameterList
+    leftParenthesis: (
+    parameter: SimpleFormalParameter
+      type: NamedType
+        name: SimpleIdentifier
+          token: int
+          staticElement: dart:core::@class::int
+          staticType: null
+        type: int
+      name: b
+      declaredElement: self::@class::B::@constructor::new::@parameter::a::@parameter::b
+      declaredElementType: int
+    rightParenthesis: )
+  declaredElement: self::@class::B::@constructor::new::@parameter::a
+  declaredElementType: T Function<T>(int)
+''');
   }
 
   test_invalid_notConstructor() async {
@@ -98,14 +116,15 @@
       error(CompileTimeErrorCode.INVALID_SUPER_FORMAL_PARAMETER_LOCATION, 7, 5),
     ]);
 
-    var f = findElement.topFunction('f');
-    var element = f.superFormalParameter('a');
-    assertTypeDynamic(element.type);
-
-    assertElement(
-      findNode.superFormalParameter('super.a'),
-      element,
-    );
+    final node = findNode.superFormalParameter('super.');
+    assertResolvedNodeText(node, r'''
+SuperFormalParameter
+  superKeyword: super
+  period: .
+  name: a
+  declaredElement: self::@function::f::@parameter::a
+  declaredElementType: dynamic
+''');
   }
 
   test_optionalNamed() async {
@@ -119,10 +138,15 @@
 }
 ''');
 
-    assertElement(
-      findNode.superFormalParameter('super.a'),
-      findElement.unnamedConstructor('B').superFormalParameter('a'),
-    );
+    final node = findNode.superFormalParameter('super.');
+    assertResolvedNodeText(node, r'''
+SuperFormalParameter
+  superKeyword: super
+  period: .
+  name: a
+  declaredElement: self::@class::B::@constructor::new::@parameter::a
+  declaredElementType: int?
+''');
   }
 
   test_optionalPositional() async {
@@ -136,10 +160,15 @@
 }
 ''');
 
-    assertElement(
-      findNode.superFormalParameter('super.a'),
-      findElement.unnamedConstructor('B').superFormalParameter('a'),
-    );
+    final node = findNode.superFormalParameter('super.');
+    assertResolvedNodeText(node, r'''
+SuperFormalParameter
+  superKeyword: super
+  period: .
+  name: a
+  declaredElement: self::@class::B::@constructor::new::@parameter::a
+  declaredElementType: int?
+''');
   }
 
   test_requiredNamed() async {
@@ -153,10 +182,16 @@
 }
 ''');
 
-    assertElement(
-      findNode.superFormalParameter('super.a'),
-      findElement.unnamedConstructor('B').superFormalParameter('a'),
-    );
+    final node = findNode.superFormalParameter('super.');
+    assertResolvedNodeText(node, r'''
+SuperFormalParameter
+  requiredKeyword: required
+  superKeyword: super
+  period: .
+  name: a
+  declaredElement: self::@class::B::@constructor::new::@parameter::a
+  declaredElementType: int
+''');
   }
 
   test_requiredPositional() async {
@@ -170,10 +205,15 @@
 }
 ''');
 
-    assertElement(
-      findNode.superFormalParameter('super.a'),
-      findElement.unnamedConstructor('B').superFormalParameter('a'),
-    );
+    final node = findNode.superFormalParameter('super.');
+    assertResolvedNodeText(node, r'''
+SuperFormalParameter
+  superKeyword: super
+  period: .
+  name: a
+  declaredElement: self::@class::B::@constructor::new::@parameter::a
+  declaredElementType: int
+''');
   }
 
   test_scoping_inBody() async {
@@ -190,10 +230,13 @@
 }
 ''');
 
-    assertElement(
-      findNode.simple('a; // ref'),
-      findElement.getter('a', of: 'A'),
-    );
+    final node = findNode.simple('a; // ref');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: a
+  staticElement: self::@class::A::@getter::a
+  staticType: int
+''');
   }
 
   test_scoping_inInitializer() async {
@@ -208,9 +251,12 @@
 }
 ''');
 
-    assertElement(
-      findNode.simple('a; }'),
-      findElement.unnamedConstructor('B').superFormalParameter('a'),
-    );
+    final node = findNode.simple('a; }');
+    assertResolvedNodeText(node, r'''
+SimpleIdentifier
+  token: a
+  staticElement: self::@class::B::@constructor::new::@parameter::a
+  staticType: int
+''');
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 026d3ae..ebb56f8 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -9,16 +9,20 @@
 import 'augmentation_import_test.dart' as augmentation_import;
 import 'await_expression_test.dart' as await_expression;
 import 'binary_expression_test.dart' as binary_expression;
+import 'binary_pattern_test.dart' as binary_pattern;
+import 'cast_pattern_test.dart' as cast_pattern;
 import 'class_alias_test.dart' as class_alias;
 import 'class_test.dart' as class_resolution;
 import 'comment_test.dart' as comment;
 import 'conditional_expression_test.dart' as conditional_expression;
+import 'constant_pattern_test.dart' as constant_pattern;
 import 'constant_test.dart' as constant;
 import 'constructor_reference_test.dart' as constructor_reference;
 import 'constructor_test.dart' as constructor;
 import 'enum_test.dart' as enum_resolution;
 import 'extension_method_test.dart' as extension_method;
 import 'extension_override_test.dart' as extension_override;
+import 'extractor_pattern_test.dart' as extractor_pattern;
 import 'field_formal_parameter_test.dart' as field_formal_parameter;
 import 'field_test.dart' as field;
 import 'for_element_test.dart' as for_element;
@@ -45,9 +49,11 @@
 import 'library_export_test.dart' as library_export;
 import 'library_import_prefix_test.dart' as library_import_prefix;
 import 'library_import_test.dart' as library_import;
+import 'list_pattern_test.dart' as list_pattern;
 import 'local_function_test.dart' as local_function;
 import 'local_variable_test.dart' as local_variable;
 import 'macro_test.dart' as macro;
+import 'map_pattern_test.dart' as map_pattern;
 import 'metadata_test.dart' as metadata;
 import 'method_declaration_test.dart' as method_declaration;
 import 'method_invocation_test.dart' as method_invocation;
@@ -57,14 +63,18 @@
 import 'non_nullable_blaze_workspace_test.dart' as non_nullable_blaze_workspace;
 import 'non_nullable_test.dart' as non_nullable;
 import 'optional_const_test.dart' as optional_const;
+import 'parenthesized_pattern_test.dart' as parenthesized_pattern;
 import 'part_test.dart' as part_;
 import 'postfix_expression_test.dart' as postfix_expression;
+import 'postfix_pattern_test.dart' as postfix_pattern;
 import 'prefix_element_test.dart' as prefix_element;
 import 'prefix_expression_test.dart' as prefix_expression;
 import 'prefixed_identifier_test.dart' as prefixed_identifier;
 import 'property_access_test.dart' as property_access;
 import 'record_literal_test.dart' as record_literal;
+import 'record_pattern_test.dart' as record_pattern;
 import 'record_type_annotation_test.dart' as record_type_annotation;
+import 'relational_pattern_test.dart' as relational_pattern;
 import 'simple_identifier_test.dart' as simple_identifier;
 import 'super_formal_parameter_test.dart' as super_formal_parameter;
 import 'top_level_variable_test.dart' as top_level_variable;
@@ -73,6 +83,7 @@
 import 'type_inference/test_all.dart' as type_inference;
 import 'type_literal_test.dart' as type_literal;
 import 'type_name_test.dart' as type_name;
+import 'variable_pattern_test.dart' as variable_pattern;
 import 'variance_test.dart' as variance_test;
 import 'yield_statement_test.dart' as yield_statement;
 
@@ -83,9 +94,12 @@
     augmentation_import.main();
     await_expression.main();
     binary_expression.main();
+    binary_pattern.main();
+    cast_pattern.main();
     class_alias.main();
     class_resolution.main();
     conditional_expression.main();
+    constant_pattern.main();
     comment.main();
     constant.main();
     constructor.main();
@@ -93,6 +107,7 @@
     enum_resolution.main();
     extension_method.main();
     extension_override.main();
+    extractor_pattern.main();
     field_formal_parameter.main();
     field.main();
     for_element.main();
@@ -116,9 +131,11 @@
     library_export.main();
     library_import_prefix.main();
     library_import.main();
+    list_pattern.main();
     local_function.main();
     local_variable.main();
     macro.main();
+    map_pattern.main();
     metadata.main();
     method_declaration.main();
     method_invocation.main();
@@ -127,14 +144,18 @@
     non_nullable_blaze_workspace.main();
     non_nullable.main();
     optional_const.main();
+    parenthesized_pattern.main();
     part_.main();
     postfix_expression.main();
+    postfix_pattern.main();
     prefix_element.main();
     prefix_expression.main();
     prefixed_identifier.main();
     property_access.main();
     record_literal.main();
+    record_pattern.main();
     record_type_annotation.main();
+    relational_pattern.main();
     simple_identifier.main();
     super_formal_parameter.main();
     top_level_variable.main();
@@ -143,6 +164,7 @@
     type_inference.main();
     type_literal.main();
     type_name.main();
+    variable_pattern.main();
     variance_test.main();
     yield_statement.main();
     defineReflectiveTests(UpdateNodeTextExpectations);
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/inference_update_1_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/inference_update_1_test.dart
index dacf213..df511ab 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/inference_update_1_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/inference_update_1_test.dart
@@ -64,8 +64,8 @@
       assertType(findElement.localVar('a').type, 'int');
       assertType(findElement.parameter('x').type, 'int');
       assertType(findElement.parameter('y').type, 'int');
-      expect(findNode.binary('x + y').staticElement!.enclosingElement3.name,
-          'num');
+      expect(
+          findNode.binary('x + y').staticElement!.enclosingElement.name, 'num');
     } else {
       await assertErrorsInCode(code, [
         error(HintCode.UNUSED_LOCAL_VARIABLE, 32, 1),
@@ -106,7 +106,7 @@
                 'List<dynamic> Function(int Function()))');
     assertType(findNode.simpleParameter('h)').declaredElement!.type,
         _isEnabled ? 'int Function()' : 'Object?');
-    assertType(findNode.variableDeclaration('a =').declaredElement2!.type,
+    assertType(findNode.variableDeclaration('a =').declaredElement!.type,
         _isEnabled ? 'List<int>' : 'List<dynamic>');
   }
 
@@ -130,7 +130,7 @@
     assertType(findElement.localVar('a').type, _isEnabled ? 'int' : 'dynamic');
     assertType(findElement.parameter('x').type, _isEnabled ? 'int' : 'Object?');
     assertType(findElement.parameter('y').type, 'int');
-    expect(findNode.binary('+ y').staticElement?.enclosingElement3.name,
+    expect(findNode.binary('+ y').staticElement?.enclosingElement.name,
         _isEnabled ? 'num' : null);
   }
 
@@ -153,7 +153,7 @@
             : 'List<Object?> Function(List<Object?> Function(int), int Function())');
     assertType(findNode.simpleParameter('x)').declaredElement!.type,
         _isEnabled ? 'int' : 'Object?');
-    assertType(findNode.variableDeclaration('a =').declaredElement2!.type,
+    assertType(findNode.variableDeclaration('a =').declaredElement!.type,
         _isEnabled ? 'List<int>' : 'List<Object?>');
   }
 
@@ -176,7 +176,7 @@
             : 'List<Object?> Function(int Function(), List<Object?> Function(int))');
     assertType(findNode.simpleParameter('x)').declaredElement!.type,
         _isEnabled ? 'int' : 'Object?');
-    assertType(findNode.variableDeclaration('a =').declaredElement2!.type,
+    assertType(findNode.variableDeclaration('a =').declaredElement!.type,
         _isEnabled ? 'List<int>' : 'List<Object?>');
   }
 
@@ -199,7 +199,7 @@
             : 'List<Object?> Function(int, List<Object?> Function(int))');
     assertType(findNode.simpleParameter('x)').declaredElement!.type,
         _isEnabled ? 'int' : 'Object?');
-    assertType(findNode.variableDeclaration('a =').declaredElement2!.type,
+    assertType(findNode.variableDeclaration('a =').declaredElement!.type,
         _isEnabled ? 'List<int>' : 'List<Object?>');
   }
 
@@ -294,7 +294,7 @@
     assertType(findElement.localVar('a').type, 'int?');
     assertType(findElement.parameter('x').type, 'int?');
     assertType(findElement.parameter('y').type, 'int');
-    expect(findNode.binary('+ y').staticElement!.enclosingElement3.name, 'num');
+    expect(findNode.binary('+ y').staticElement!.enclosingElement.name, 'num');
   }
 
   test_horizontal_inference_unnecessary_due_to_explicit_parameter_type_named() async {
@@ -311,7 +311,7 @@
     assertType(findElement.localVar('a').type, 'int?');
     assertType(findElement.parameter('x').type, 'int?');
     assertType(findElement.parameter('y').type, 'int');
-    expect(findNode.binary('+ y').staticElement!.enclosingElement3.name, 'num');
+    expect(findNode.binary('+ y').staticElement!.enclosingElement.name, 'num');
   }
 
   test_horizontal_inference_unnecessary_due_to_no_dependency() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/variable_pattern_test.dart b/pkg/analyzer/test/src/dart/resolution/variable_pattern_test.dart
new file mode 100644
index 0000000..aea6d2f
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/variable_pattern_test.dart
@@ -0,0 +1,965 @@
+// Copyright (c) 2022, 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_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(VariablePatternResolutionTest);
+  });
+}
+
+@reflectiveTest
+class VariablePatternResolutionTest extends PatternsResolutionTest {
+  test_final_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(int x) {
+  switch (x) {
+    case final y as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: VariablePattern
+    keyword: final
+    name: y
+    declaredElement: hasImplicitType isFinal y@46
+      type: Object
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_final_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(int x) {
+  if (x case final y) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  keyword: final
+  name: y
+  declaredElement: hasImplicitType isFinal y@35
+    type: int
+''');
+  }
+
+  test_final_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(int? x) {
+  switch (x) {
+    case final y!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    keyword: final
+    name: y
+    declaredElement: hasImplicitType isFinal y@47
+      type: int
+  operator: !
+''');
+  }
+
+  test_final_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(int? x) {
+  switch (x) {
+    case final y?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    keyword: final
+    name: y
+    declaredElement: hasImplicitType isFinal y@47
+      type: int
+  operator: ?
+''');
+  }
+
+  test_final_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(int x) {
+  switch (x) {
+    case final y:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  keyword: final
+  name: y
+  declaredElement: hasImplicitType isFinal y@46
+    type: int
+''');
+  }
+
+  test_final_typed_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case final int y as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: VariablePattern
+    keyword: final
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+    name: y
+    declaredElement: isFinal y@46
+      type: int
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_final_typed_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case final int y) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  keyword: final
+  type: NamedType
+    name: SimpleIdentifier
+      token: int
+      staticElement: dart:core::@class::int
+      staticType: null
+    type: int
+  name: y
+  declaredElement: isFinal y@35
+    type: int
+''');
+  }
+
+  test_final_typed_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case final int y!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    keyword: final
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+    name: y
+    declaredElement: isFinal y@46
+      type: int
+  operator: !
+''');
+  }
+
+  test_final_typed_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case final int y?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    keyword: final
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+    name: y
+    declaredElement: isFinal y@46
+      type: int
+  operator: ?
+''');
+  }
+
+  test_final_typed_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case final int y:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  keyword: final
+  type: NamedType
+    name: SimpleIdentifier
+      token: int
+      staticElement: dart:core::@class::int
+      staticType: null
+    type: int
+  name: y
+  declaredElement: isFinal y@46
+    type: int
+''');
+  }
+
+  test_typed_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int y as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+    name: y
+    declaredElement: y@40
+      type: int
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_typed_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case int y) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  type: NamedType
+    name: SimpleIdentifier
+      token: int
+      staticElement: dart:core::@class::int
+      staticType: null
+    type: int
+  name: y
+  declaredElement: y@29
+    type: int
+''');
+  }
+
+  test_typed_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int y!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+    name: y
+    declaredElement: y@40
+      type: int
+  operator: !
+''');
+  }
+
+  test_typed_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int y?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+    name: y
+    declaredElement: y@40
+      type: int
+  operator: ?
+''');
+  }
+
+  test_typed_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int y:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  type: NamedType
+    name: SimpleIdentifier
+      token: int
+      staticElement: dart:core::@class::int
+      staticType: null
+    type: int
+  name: y
+  declaredElement: y@40
+    type: int
+''');
+  }
+
+  test_typed_named_as_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int as as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+    name: as
+    declaredElement: as@40
+      type: int
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_typed_named_as_inside_extractorPattern_namedExplicitly() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(f: int as):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: SimpleIdentifier
+    token: C
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        name: f
+        colon: :
+      pattern: VariablePattern
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+        name: as
+  rightParenthesis: )
+''');
+  }
+
+  test_typed_named_as_inside_extractorPattern_namedImplicitly() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int? f;
+}
+
+void f(x) {
+  switch (x) {
+    case C(: int as):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ExtractorPattern
+  typeName: SimpleIdentifier
+    token: C
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        colon: :
+      pattern: VariablePattern
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+        name: as
+  rightParenthesis: )
+''');
+  }
+
+  test_typed_named_as_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  if (x case int as) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  type: NamedType
+    name: SimpleIdentifier
+      token: int
+      staticElement: dart:core::@class::int
+      staticType: null
+    type: int
+  name: as
+  declaredElement: as@29
+    type: int
+''');
+  }
+
+  test_typed_named_as_inside_listPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case [int as]:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+ListPattern
+  leftBracket: [
+  elements
+    VariablePattern
+      type: NamedType
+        name: SimpleIdentifier
+          token: int
+      name: as
+  rightBracket: ]
+''');
+  }
+
+  test_typed_named_as_inside_logicalAnd_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int as & 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+    name: as
+  operator: &
+  rightOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_typed_named_as_inside_logicalAnd_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1 & int as:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 1
+  operator: &
+  rightOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+    name: as
+''');
+  }
+
+  test_typed_named_as_inside_logicalOr_left() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int as | 2:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+    name: as
+  operator: |
+  rightOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 2
+''');
+  }
+
+  test_typed_named_as_inside_logicalOr_right() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case 1 | int as:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+BinaryPattern
+  leftOperand: ConstantPattern
+    expression: IntegerLiteral
+      literal: 1
+  operator: |
+  rightOperand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+    name: as
+''');
+  }
+
+  test_typed_named_as_inside_mapPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case {'a': int as}:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+MapPattern
+  leftBracket: {
+  entries
+    MapPatternEntry
+      key: SimpleStringLiteral
+        literal: 'a'
+      separator: :
+      value: VariablePattern
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+        name: as
+  rightBracket: }
+''');
+  }
+
+  test_typed_named_as_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int as!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+    name: as
+    declaredElement: as@40
+      type: int
+  operator: !
+''');
+  }
+
+  test_typed_named_as_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int as?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+    name: as
+    declaredElement: as@40
+      type: int
+  operator: ?
+''');
+  }
+
+  test_typed_named_as_inside_parenthesizedPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (int as):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+ParenthesizedPattern
+  leftParenthesis: (
+  pattern: VariablePattern
+    type: NamedType
+      name: SimpleIdentifier
+        token: int
+        staticElement: dart:core::@class::int
+        staticType: null
+      type: int
+    name: as
+    declaredElement: as@41
+      type: int
+  rightParenthesis: )
+''');
+  }
+
+  test_typed_named_as_inside_recordPattern_namedExplicitly() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (n: int as, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        name: n
+        colon: :
+      pattern: VariablePattern
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+        name: as
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_typed_named_as_inside_recordPattern_namedImplicitly() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (: int as, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      fieldName: RecordPatternFieldName
+        colon: :
+      pattern: VariablePattern
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+        name: as
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_typed_named_as_inside_recordPattern_unnamed() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case (int as, 2):
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertParsedNodeText(node, r'''
+RecordPattern
+  leftParenthesis: (
+  fields
+    RecordPatternField
+      pattern: VariablePattern
+        type: NamedType
+          name: SimpleIdentifier
+            token: int
+        name: as
+    RecordPatternField
+      pattern: ConstantPattern
+        expression: IntegerLiteral
+          literal: 2
+  rightParenthesis: )
+''');
+  }
+
+  test_typed_named_as_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int as:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  type: NamedType
+    name: SimpleIdentifier
+      token: int
+      staticElement: dart:core::@class::int
+      staticType: null
+    type: int
+  name: as
+  declaredElement: as@40
+    type: int
+''');
+  }
+
+  test_typed_wildcard_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {
+  switch (x) {
+    case int _:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  type: NamedType
+    name: SimpleIdentifier
+      token: int
+      staticElement: dart:core::@class::int
+      staticType: null
+    type: int
+  name: _
+''');
+  }
+
+  test_var_inside_castPattern() async {
+    await assertNoErrorsInCode(r'''
+void f(int x) {
+  switch (x) {
+    case var y as Object:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+CastPattern
+  pattern: VariablePattern
+    keyword: var
+    name: y
+    declaredElement: hasImplicitType y@44
+      type: Object
+  asToken: as
+  type: NamedType
+    name: SimpleIdentifier
+      token: Object
+      staticElement: dart:core::@class::Object
+      staticType: null
+    type: Object
+''');
+  }
+
+  test_var_inside_ifStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(int x) {
+  if (x case var y) {}
+}
+''');
+    final node = findNode.caseClause('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  keyword: var
+  name: y
+  declaredElement: hasImplicitType y@33
+    type: int
+''');
+  }
+
+  test_var_inside_nullAssert() async {
+    await assertNoErrorsInCode(r'''
+void f(int? x) {
+  switch (x) {
+    case var y!:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    keyword: var
+    name: y
+    declaredElement: hasImplicitType y@45
+      type: int
+  operator: !
+''');
+  }
+
+  test_var_inside_nullCheck() async {
+    await assertNoErrorsInCode(r'''
+void f(int? x) {
+  switch (x) {
+    case var y?:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+PostfixPattern
+  operand: VariablePattern
+    keyword: var
+    name: y
+    declaredElement: hasImplicitType y@45
+      type: int
+  operator: ?
+''');
+  }
+
+  test_var_inside_switchStatement_case() async {
+    await assertNoErrorsInCode(r'''
+void f(int x) {
+  switch (x) {
+    case var y:
+      break;
+  }
+}
+''');
+    final node = findNode.switchPatternCase('case').pattern;
+    assertResolvedNodeText(node, r'''
+VariablePattern
+  keyword: var
+  name: y
+  declaredElement: hasImplicitType y@44
+    type: int
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/variance_test.dart b/pkg/analyzer/test/src/dart/resolution/variance_test.dart
index 96e40ac..a92cfd6 100644
--- a/pkg/analyzer/test/src/dart/resolution/variance_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/variance_test.dart
@@ -83,7 +83,7 @@
         staticType: null
       type: B<num>
     staticElement: ConstructorMember
-      base: self::@class::B::@constructor::•
+      base: self::@class::B::@constructor::new
       substitution: {T: num}
   staticType: B<num>
 ''',
diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_export_use_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_export_use_test.dart
index 8e14f9c..897e3a0 100644
--- a/pkg/analyzer/test/src/diagnostics/deprecated_export_use_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/deprecated_export_use_test.dart
@@ -249,6 +249,39 @@
     ]);
   }
 
+  /// While linking `b.dart` and `c.dart` library cycle, we build their
+  /// import scopes, and while doing this we access `hasDeprecated` on the
+  /// `export a.dart` in `b.dart`. But because the metadata is not resolved
+  /// yet (we are still linking!), we cache metadata flags that don't
+  /// reflect the actual state. So, we need to reset them after linking.
+  /// If we don't, we will fail to report the hint.
+  test_deprecated_libraryCycle() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+void foo() {}
+''');
+
+    newFile('$testPackageLibPath/b.dart', r'''
+import 'c.dart';
+
+@deprecated
+export 'a.dart';
+''');
+
+    newFile('$testPackageLibPath/c.dart', r'''
+import 'b.dart';
+''');
+
+    await assertErrorsInCode('''
+import 'b.dart';
+
+void f() {
+  foo();
+}
+''', [
+      error(HintCode.DEPRECATED_EXPORT_USE, 31, 3),
+    ]);
+  }
+
   test_deprecated_setter() async {
     newFile('$testPackageLibPath/a.dart', r'''
 void set foo(int _) {}
diff --git a/pkg/analyzer/test/src/diagnostics/extends_disallowed_class_test.dart b/pkg/analyzer/test/src/diagnostics/extends_disallowed_class_test.dart
index aaba875..9a3968f 100644
--- a/pkg/analyzer/test/src/diagnostics/extends_disallowed_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/extends_disallowed_class_test.dart
@@ -92,6 +92,14 @@
     ]);
   }
 
+  test_class_Record() async {
+    await assertErrorsInCode('''
+class A extends Record {}
+''', [
+      error(CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS, 16, 6),
+    ]);
+  }
+
   test_class_String() async {
     await assertErrorsInCode('''
 class A extends String {}
diff --git a/pkg/analyzer/test/src/diagnostics/ffi_native_test.dart b/pkg/analyzer/test/src/diagnostics/ffi_native_test.dart
index 866072a..02d46a3 100644
--- a/pkg/analyzer/test/src/diagnostics/ffi_native_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ffi_native_test.dart
@@ -123,6 +123,14 @@
     ]);
   }
 
+  test_FfiNativePointerParameter() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:ffi';
+@FfiNative<Void Function(Pointer)>('free')
+external void posixFree(Pointer pointer);
+''');
+  }
+
   test_FfiNativeTooFewParameters() async {
     await assertErrorsInCode(r'''
 import 'dart:ffi';
diff --git a/pkg/analyzer/test/src/diagnostics/implements_disallowed_class_test.dart b/pkg/analyzer/test/src/diagnostics/implements_disallowed_class_test.dart
index c36452c..9b05544 100644
--- a/pkg/analyzer/test/src/diagnostics/implements_disallowed_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/implements_disallowed_class_test.dart
@@ -116,6 +116,14 @@
     ]);
   }
 
+  test_class_Record() async {
+    await assertErrorsInCode('''
+class A implements Record {}
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, 19, 6),
+    ]);
+  }
+
   test_class_String() async {
     await assertErrorsInCode('''
 class A implements String {}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_field_name_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_field_name_test.dart
index a47e49a..f12722b 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_field_name_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_field_name_test.dart
@@ -27,14 +27,45 @@
     ]);
   }
 
-  void test_positional() async {
+  void test_fromObject_withPositional() async {
     await assertErrorsInCode(r'''
-var r = (a: 1, $12: 2);
+var r = (0, hashCode: 1, noSuchMethod: 2, runtimeType: 3, toString: 4);
 ''', [
-      error(CompileTimeErrorCode.INVALID_FIELD_NAME_POSITIONAL, 15, 3),
+      error(CompileTimeErrorCode.INVALID_FIELD_NAME_FROM_OBJECT, 12, 8),
+      error(CompileTimeErrorCode.INVALID_FIELD_NAME_FROM_OBJECT, 25, 12),
+      error(CompileTimeErrorCode.INVALID_FIELD_NAME_FROM_OBJECT, 42, 11),
+      error(CompileTimeErrorCode.INVALID_FIELD_NAME_FROM_OBJECT, 58, 8),
     ]);
   }
 
+  void test_positional_named_conflict() async {
+    await assertErrorsInCode(r'''
+var r = (0, $0: 2);
+''', [
+      error(CompileTimeErrorCode.INVALID_FIELD_NAME_POSITIONAL, 12, 2),
+    ]);
+  }
+
+  void test_positional_named_conflict_namedBeforePositional() async {
+    await assertErrorsInCode(r'''
+var r = ($0: 2, 1);
+''', [
+      error(CompileTimeErrorCode.INVALID_FIELD_NAME_POSITIONAL, 9, 2),
+    ]);
+  }
+
+  void test_positional_named_leadingZero() async {
+    await assertNoErrorsInCode(r'''
+var r = (0, 1, $01: 2);
+''');
+  }
+
+  void test_positional_named_noConflict() async {
+    await assertNoErrorsInCode(r'''
+var r = (0, $1: 2);
+''');
+  }
+
   void test_private() async {
     await assertErrorsInCode(r'''
 var r = (_a: 1, b: 2);
@@ -69,22 +100,46 @@
     ]);
   }
 
-  void test_positional_named() async {
+  void test_positional_named_conflict() async {
     await assertErrorsInCode(r'''
-void f(({int $21}) r) {}
+void f((int, String, {int $1}) r) {}
 ''', [
-      error(CompileTimeErrorCode.INVALID_FIELD_NAME_POSITIONAL, 13, 3),
+      error(CompileTimeErrorCode.INVALID_FIELD_NAME_POSITIONAL, 26, 2),
     ]);
   }
 
-  void test_positional_positional() async {
+  void test_positional_named_leadingZero() async {
+    await assertNoErrorsInCode(r'''
+void f((int, String, {int $01}) r) {}
+''');
+  }
+
+  void test_positional_named_noConflict() async {
+    await assertNoErrorsInCode(r'''
+void f(({int $21}) r) {}
+''');
+  }
+
+  void test_positional_positional_conflict() async {
     await assertErrorsInCode(r'''
-void f((int $3, int b) r) {}
+void f((int $1, int b) r) {}
 ''', [
       error(CompileTimeErrorCode.INVALID_FIELD_NAME_POSITIONAL, 12, 2),
     ]);
   }
 
+  void test_positional_positional_noConflict_same() async {
+    await assertNoErrorsInCode(r'''
+void f((int $0, int b) r) {}
+''');
+  }
+
+  void test_positional_positional_noConflict_unused() async {
+    await assertNoErrorsInCode(r'''
+void f((int $3, int b) r) {}
+''');
+  }
+
   void test_private_named() async {
     await assertErrorsInCode(r'''
 void f(({int _a}) r) {}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_super_in_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_super_in_initializer_test.dart
index 8006c99..72319fa 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_super_in_initializer_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_super_in_initializer_test.dart
@@ -24,7 +24,7 @@
       error(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 18, 5),
       error(ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 24, 5),
       error(ParserErrorCode.MISSING_IDENTIFIER, 24, 5),
-      error(ParserErrorCode.MISSING_IDENTIFIER, 29, 1),
+      error(ParserErrorCode.RECORD_LITERAL_EMPTY, 30, 1)
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
index 4dc5158..af22783 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
@@ -41,7 +41,8 @@
     await assertErrorsInCode('''
 var f = ([int a]) {};
 ''', [
-      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 14, 1),
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL,
+          14, 1),
     ]);
   }
 
@@ -87,7 +88,8 @@
   C._();
 }
 ''', [
-      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 27, 1),
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL,
+          27, 1),
     ]);
   }
 
@@ -164,7 +166,8 @@
   C([int a]);
 }
 ''', [
-      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 19, 1),
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL,
+          19, 1),
     ]);
   }
 
@@ -199,7 +202,8 @@
   B([int super.a]);
 }
 ''', [
-      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 61, 1),
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL,
+          61, 1),
     ]);
   }
 
@@ -212,7 +216,8 @@
   B([int super.a]);
 }
 ''', [
-      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 66, 1),
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL,
+          66, 1),
     ]);
   }
 
@@ -397,7 +402,8 @@
     await assertErrorsInCode('''
 void f([int a]) {}
 ''', [
-      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 12, 1),
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL,
+          12, 1),
     ]);
   }
 
@@ -631,7 +637,8 @@
   void foo([int a]) {}
 }
 ''', [
-      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 26, 1),
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL,
+          26, 1),
     ]);
   }
 
@@ -659,7 +666,8 @@
   void foo([T a]) {}
 }
 ''', [
-      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER, 43, 1),
+      error(CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL,
+          43, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_of_disallowed_class_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_of_disallowed_class_test.dart
index 8b32940..ac69af8 100644
--- a/pkg/analyzer/test/src/diagnostics/mixin_of_disallowed_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/mixin_of_disallowed_class_test.dart
@@ -82,6 +82,14 @@
     ]);
   }
 
+  test_class_Record() async {
+    await assertErrorsInCode('''
+class A extends Object with Record {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS, 28, 6),
+    ]);
+  }
+
   test_class_String() async {
     await assertErrorsInCode('''
 class A extends Object with String {}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart
index 98e12ec..b59049d 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart
@@ -80,10 +80,10 @@
     await assertErrorsInCode(r'''
 class A {
   int y = 0;
-  A({x: y}) {}
+  A({x = y}) {}
 }
 ''', [
-      error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 31, 1),
+      error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 32, 1),
     ]);
   }
 
@@ -120,12 +120,82 @@
   test_function_named() async {
     await assertErrorsInCode(r'''
 int y = 0;
-f({x: y}) {}
+f({x = y}) {}
 ''', [
-      error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 17, 1),
+      error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 18, 1),
     ]);
   }
 
+  test_function_named_constList() async {
+    await assertNoErrorsInCode(r'''
+void f({x = const [0, 1]}) {}
+''');
+  }
+
+  test_function_named_constList_elements_listLiteral() async {
+    await assertNoErrorsInCode(r'''
+void f({x = const [0, [1]]}) {}
+''');
+  }
+
+  test_function_named_constRecord() async {
+    await assertNoErrorsInCode(r'''
+void f({x = const (0, 1)}) {}
+''');
+  }
+
+  test_function_named_constRecord_namedFields_listLiteral() async {
+    await assertNoErrorsInCode(r'''
+void f({x = const (0, foo: [1])}) {}
+''');
+  }
+
+  test_function_named_constRecord_positionalFields_listLiteral() async {
+    await assertNoErrorsInCode(r'''
+void f({x = const (0, [1])}) {}
+''');
+  }
+
+  test_function_named_record_namedFields_integerLiteral() async {
+    await assertNoErrorsInCode(r'''
+void f({x = (a: 0, b: 1)}) {}
+''');
+  }
+
+  test_function_named_record_namedFields_listLiteral() async {
+    await assertErrorsInCode(r'''
+void f({x = (a: 0, b: [1])}) {}
+''', [
+      error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 22, 3),
+    ]);
+  }
+
+  test_function_named_record_namedFields_listLiteral_const() async {
+    await assertNoErrorsInCode(r'''
+void f({x = (a: 0, b: const [1])}) {}
+''');
+  }
+
+  test_function_named_record_positionalFields_integerLiteral() async {
+    await assertNoErrorsInCode(r'''
+void f({x = (0, 1)}) {}
+''');
+  }
+
+  test_function_named_record_positionalFields_listLiteral() async {
+    await assertErrorsInCode(r'''
+void f({x = (0, [1])}) {}
+''', [
+      error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 16, 3),
+    ]);
+  }
+
+  test_function_named_record_positionalFields_listLiteral_const() async {
+    await assertNoErrorsInCode(r'''
+void f({x = (0, const [1])}) {}
+''');
+  }
+
   test_function_positional() async {
     await assertErrorsInCode(r'''
 int y = 0;
@@ -139,10 +209,10 @@
     await assertErrorsInCode(r'''
 class A {
   int y = 0;
-  m({x: y}) {}
+  m({x = y}) {}
 }
 ''', [
-      error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 31, 1),
+      error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 32, 1),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart b/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart
index 4f2c5af..e02e36a 100644
--- a/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart
@@ -341,7 +341,7 @@
             staticType: null
           type: A*
         staticElement: ConstructorMember
-          base: package:test/a.dart::@class::A::@constructor::•
+          base: package:test/a.dart::@class::A::@constructor::new
           isLegacy: true
       argumentList: ArgumentList
         leftParenthesis: (
@@ -400,7 +400,7 @@
             staticType: null
           type: A*
         staticElement: ConstructorMember
-          base: package:test/a.dart::@class::A::@constructor::•
+          base: package:test/a.dart::@class::A::@constructor::new
           isLegacy: true
       argumentList: ArgumentList
         leftParenthesis: (
diff --git a/pkg/analyzer/test/src/diagnostics/switch_expression_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/switch_expression_not_assignable_test.dart
index 564d92f..285366d4 100644
--- a/pkg/analyzer/test/src/diagnostics/switch_expression_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/switch_expression_not_assignable_test.dart
@@ -16,6 +16,23 @@
 @reflectiveTest
 class SwitchExpressionNotAssignableTest extends PubPackageResolutionTest
     with WithoutNullSafetyMixin {
+  test_do_not_report_on_cases_after_the_first() async {
+    await assertErrorsInCode('''
+f() {
+  var x = 1;
+  try {
+    switch (x) {
+      case 0:
+      case 2:
+      case "false":
+    }
+  } catch (e) {}
+}
+''', [
+      error(CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES, 83, 7),
+    ]);
+  }
+
   test_simple() async {
     await assertErrorsInCode('''
 f(int p) {
diff --git a/pkg/analyzer/test/src/diagnostics/unused_result_test.dart b/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
index 0bc49c7..5881a42 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
@@ -1168,6 +1168,71 @@
 ''');
   }
 
+  test_topLevelFunction_prefixExpression_bang() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+@useResult
+bool foo() => true;
+
+bool f() {
+  return !foo();
+}
+''');
+  }
+
+  test_topLevelFunction_prefixExpression_decrement() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+@useResult
+int foo = 1;
+
+int f() {
+  return --foo;
+}
+''');
+  }
+
+  test_topLevelFunction_prefixExpression_increment() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+@useResult
+int foo = 1;
+
+int f() {
+  return ++foo;
+}
+''');
+  }
+
+  test_topLevelFunction_prefixExpression_minus() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+@useResult
+int foo() => 1;
+
+int f() {
+  return -foo();
+}
+''');
+  }
+
+  test_topLevelFunction_prefixExpression_tilde() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+@useResult
+int foo() => 1;
+
+int f() {
+  return ~foo();
+}
+''');
+  }
+
   test_topLevelFunction_result_assigned() async {
     await assertNoErrorsInCode(r'''
 import 'package:meta/meta.dart';
diff --git a/pkg/analyzer/test/src/diagnostics/wrong_number_of_parameters_for_operator_test.dart b/pkg/analyzer/test/src/diagnostics/wrong_number_of_parameters_for_operator_test.dart
index 9ee48c6..9069e42 100644
--- a/pkg/analyzer/test/src/diagnostics/wrong_number_of_parameters_for_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/wrong_number_of_parameters_for_operator_test.dart
@@ -34,6 +34,26 @@
     await _checkTooFewAndTooMany('[]');
   }
 
+  test_compound_assignment_ok_in_legacy_code() async {
+    // Prior to the fix for https://github.com/dart-lang/sdk/issues/46569,
+    // attempting to use a binary operator with no args as part of a compound
+    // assignment would crash the analyzer.  Check that that doesn't happen
+    // anymore.
+    await assertErrorsInCode('''
+// @dart=2.9
+class C {
+  C operator+() => C();
+}
+
+void f(C c) {
+  c += 1;
+}
+''', [
+      error(
+          CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, 35, 1),
+    ]);
+  }
+
   test_correct_number_of_parameters_binary() async {
     await _checkCorrectSingle("<");
     await _checkCorrectSingle(">");
diff --git a/pkg/analyzer/test/src/fasta/ast_builder_test.dart b/pkg/analyzer/test/src/fasta/ast_builder_test.dart
index 82bb936..9390d33 100644
--- a/pkg/analyzer/test/src/fasta/ast_builder_test.dart
+++ b/pkg/analyzer/test/src/fasta/ast_builder_test.dart
@@ -165,11 +165,57 @@
         withOffsets: true);
   }
 
+  void test_class_constructor_named() {
+    var parseResult = parseStringWithErrors(r'''
+class A {
+  A.named();
+}
+''');
+    parseResult.assertNoErrors();
+
+    var node = parseResult.findNode.constructor('A.named()');
+    assertParsedNodeText(node, r'''
+ConstructorDeclaration
+  returnType: SimpleIdentifier
+    token: A
+  period: .
+  name: named
+  parameters: FormalParameterList
+    leftParenthesis: (
+    rightParenthesis: )
+  body: EmptyFunctionBody
+    semicolon: ;
+''');
+  }
+
+  void test_class_constructor_unnamed() {
+    var parseResult = parseStringWithErrors(r'''
+class A {
+  A();
+}
+''');
+    parseResult.assertNoErrors();
+
+    var node = parseResult.findNode.constructor('A()');
+    assertParsedNodeText(node, r'''
+ConstructorDeclaration
+  returnType: SimpleIdentifier
+    token: A
+  parameters: FormalParameterList
+    leftParenthesis: (
+    rightParenthesis: )
+  body: EmptyFunctionBody
+    semicolon: ;
+''');
+  }
+
   void test_class_extendsClause_recordType() {
     var parseResult = parseStringWithErrors(r'''
 class C extends (int, int) {}
 ''');
-    parseResult.assertNoErrors();
+    parseResult.assertErrors([
+      error(ParserErrorCode.EXPECTED_NAMED_TYPE_EXTENDS, 16, 10),
+    ]);
 
     final node = parseResult.findNode.classDeclaration('class C');
     assertParsedNodeText(
@@ -186,9 +232,11 @@
 
   void test_class_implementsClause_recordType() {
     var parseResult = parseStringWithErrors(r'''
-class C implements (int, int) {}
+class C implements A, (int, int), B {}
 ''');
-    parseResult.assertNoErrors();
+    parseResult.assertErrors([
+      error(ParserErrorCode.EXPECTED_NAMED_TYPE_IMPLEMENTS, 22, 10),
+    ]);
 
     final node = parseResult.findNode.classDeclaration('class C');
     assertParsedNodeText(
@@ -199,8 +247,15 @@
   name: C @6
   implementsClause: ImplementsClause
     implementsKeyword: implements @8
-  leftBracket: { @30
-  rightBracket: } @31
+    interfaces
+      NamedType
+        name: SimpleIdentifier
+          token: A @19
+      NamedType
+        name: SimpleIdentifier
+          token: B @34
+  leftBracket: { @36
+  rightBracket: } @37
 ''',
         withOffsets: true);
   }
@@ -224,23 +279,29 @@
 
   void test_class_withClause_recordType() {
     var parseResult = parseStringWithErrors(r'''
-class C with (int, int) {}
+class C with A, (int, int), B {}
 ''');
-    parseResult.assertNoErrors();
+    parseResult.assertErrors([
+      error(ParserErrorCode.EXPECTED_NAMED_TYPE_WITH, 16, 10),
+    ]);
 
     final node = parseResult.findNode.classDeclaration('class C');
-    assertParsedNodeText(
-        node,
-        r'''
+    assertParsedNodeText(node, r'''
 ClassDeclaration
-  classKeyword: class @0
-  name: C @6
+  classKeyword: class
+  name: C
   withClause: WithClause
-    withKeyword: with @8
-  leftBracket: { @24
-  rightBracket: } @25
-''',
-        withOffsets: true);
+    withKeyword: with
+    mixinTypes
+      NamedType
+        name: SimpleIdentifier
+          token: A
+      NamedType
+        name: SimpleIdentifier
+          token: B
+  leftBracket: {
+  rightBracket: }
+''');
   }
 
   void test_classAlias_macro() {
@@ -272,10 +333,12 @@
 
   void test_classTypeAlias_implementsClause_recordType() {
     var parseResult = parseStringWithErrors(r'''
-class C = Object with M implements (int, int);
+class C = Object with M implements A, (int, int), B;
 mixin M {}
 ''');
-    parseResult.assertNoErrors();
+    parseResult.assertErrors([
+      error(ParserErrorCode.EXPECTED_NAMED_TYPE_IMPLEMENTS, 38, 10),
+    ]);
 
     final node = parseResult.findNode.classTypeAlias('class C');
     assertParsedNodeText(
@@ -296,16 +359,25 @@
           token: M @22
   implementsClause: ImplementsClause
     implementsKeyword: implements @24
-  semicolon: ; @45
+    interfaces
+      NamedType
+        name: SimpleIdentifier
+          token: A @35
+      NamedType
+        name: SimpleIdentifier
+          token: B @50
+  semicolon: ; @51
 ''',
         withOffsets: true);
   }
 
   void test_classTypeAlias_withClause_recordType() {
     var parseResult = parseStringWithErrors(r'''
-class C = Object with (int, int);
+class C = Object with A, (int, int), B;
 ''');
-    parseResult.assertNoErrors();
+    parseResult.assertErrors([
+      error(ParserErrorCode.EXPECTED_NAMED_TYPE_WITH, 25, 10),
+    ]);
 
     final node = parseResult.findNode.classTypeAlias('class C');
     assertParsedNodeText(
@@ -320,7 +392,14 @@
       token: Object @10
   withClause: WithClause
     withKeyword: with @17
-  semicolon: ; @32
+    mixinTypes
+      NamedType
+        name: SimpleIdentifier
+          token: A @22
+      NamedType
+        name: SimpleIdentifier
+          token: B @37
+  semicolon: ; @38
 ''',
         withOffsets: true);
   }
@@ -669,12 +748,50 @@
 ''');
   }
 
+  void test_library_with_name() {
+    var parseResult = parseStringWithErrors(r'''
+library name.and.dots;
+''');
+    parseResult.assertNoErrors();
+
+    var node = parseResult.findNode.library('library');
+    assertParsedNodeText(node, r'''
+LibraryDirective
+  libraryKeyword: library
+  name: LibraryIdentifier
+    components
+      SimpleIdentifier
+        token: name
+      SimpleIdentifier
+        token: and
+      SimpleIdentifier
+        token: dots
+  semicolon: ;
+''');
+  }
+
+  void test_library_without_name() {
+    var parseResult = parseStringWithErrors(r'''
+library;
+''');
+    parseResult.assertNoErrors();
+
+    var node = parseResult.findNode.library('library');
+    assertParsedNodeText(node, r'''
+LibraryDirective
+  libraryKeyword: library
+  semicolon: ;
+''');
+  }
+
   void test_mixin_implementsClause_recordType() {
     var parseResult = parseStringWithErrors(r'''
 class C {}
-mixin M on C implements (int, int) {}
+mixin M on C implements A, (int, int), B {}
 ''');
-    parseResult.assertNoErrors();
+    parseResult.assertErrors([
+      error(ParserErrorCode.EXPECTED_NAMED_TYPE_IMPLEMENTS, 38, 10),
+    ]);
 
     final node = parseResult.findNode.mixinDeclaration('mixin M');
     assertParsedNodeText(
@@ -691,17 +808,26 @@
           token: C @22
   implementsClause: ImplementsClause
     implementsKeyword: implements @24
-  leftBracket: { @46
-  rightBracket: } @47
+    interfaces
+      NamedType
+        name: SimpleIdentifier
+          token: A @35
+      NamedType
+        name: SimpleIdentifier
+          token: B @50
+  leftBracket: { @52
+  rightBracket: } @53
 ''',
         withOffsets: true);
   }
 
   void test_mixin_onClause_recordType() {
     var parseResult = parseStringWithErrors(r'''
-mixin M on (int, int) {}
+mixin M on A, (int, int), B {}
 ''');
-    parseResult.assertNoErrors();
+    parseResult.assertErrors([
+      error(ParserErrorCode.EXPECTED_NAMED_TYPE_ON, 14, 10),
+    ]);
 
     final node = parseResult.findNode.mixinDeclaration('mixin M');
     assertParsedNodeText(
@@ -712,8 +838,15 @@
   name: M @6
   onClause: OnClause
     onKeyword: on @8
-  leftBracket: { @22
-  rightBracket: } @23
+    superclassConstraints
+      NamedType
+        name: SimpleIdentifier
+          token: A @11
+      NamedType
+        name: SimpleIdentifier
+          token: B @26
+  leftBracket: { @28
+  rightBracket: } @29
 ''',
         withOffsets: true);
   }
@@ -766,6 +899,23 @@
 ''');
   }
 
+  void test_recordLiteral_positional_one_trailingComma() {
+    var parseResult = parseStringWithErrors(r'''
+final x = (0,);
+''');
+    parseResult.assertNoErrors();
+
+    var node = parseResult.findNode.recordLiteral('(0');
+    assertParsedNodeText(node, r'''
+RecordLiteral
+  leftParenthesis: (
+  fields
+    IntegerLiteral
+      literal: 0
+  rightParenthesis: )
+''');
+  }
+
   void test_recordLiteral_positional_trailingComma() {
     var parseResult = parseStringWithErrors(r'''
 final x = (0, 1,);
@@ -785,7 +935,6 @@
 ''');
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49826')
   void test_recordTypeAnnotation_empty() {
     var parseResult = parseStringWithErrors(r'''
 () f() {}
@@ -940,6 +1089,47 @@
 ''');
   }
 
+  void test_recordTypeAnnotation_positional_one() {
+    var parseResult = parseStringWithErrors(r'''
+void f((int) r) {}
+''');
+    parseResult.assertErrors([
+      error(
+          ParserErrorCode.RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA, 11, 1),
+    ]);
+
+    var node = parseResult.findNode.recordTypeAnnotation('(int');
+    assertParsedNodeText(node, r'''
+RecordTypeAnnotation
+  leftParenthesis: (
+  positionalFields
+    RecordTypeAnnotationPositionalField
+      type: NamedType
+        name: SimpleIdentifier
+          token: int
+  rightParenthesis: )
+''');
+  }
+
+  void test_recordTypeAnnotation_positional_one_trailingComma() {
+    var parseResult = parseStringWithErrors(r'''
+void f((int, ) r) {}
+''');
+    parseResult.assertNoErrors();
+
+    var node = parseResult.findNode.recordTypeAnnotation('(int');
+    assertParsedNodeText(node, r'''
+RecordTypeAnnotation
+  leftParenthesis: (
+  positionalFields
+    RecordTypeAnnotationPositionalField
+      type: NamedType
+        name: SimpleIdentifier
+          token: int
+  rightParenthesis: )
+''');
+  }
+
   void test_recordTypeAnnotation_positional_trailingComma() {
     var parseResult = parseStringWithErrors(r'''
 void f((int, bool,) r) {}
diff --git a/pkg/analyzer/test/src/fasta/message_coverage_test.dart b/pkg/analyzer/test/src/fasta/message_coverage_test.dart
index 3c3c34d..ca0f350a 100644
--- a/pkg/analyzer/test/src/fasta/message_coverage_test.dart
+++ b/pkg/analyzer/test/src/fasta/message_coverage_test.dart
@@ -66,7 +66,7 @@
     var astBuilder = unit.declarations[0] as ClassDeclaration;
     var method = astBuilder.members
         .whereType<MethodDeclaration>()
-        .firstWhere((x) => x.name2.lexeme == 'reportMessage');
+        .firstWhere((x) => x.name.lexeme == 'reportMessage');
     SwitchStatement statement = (method.body as BlockFunctionBody)
         .block
         .statements
diff --git a/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart b/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
index 950c741..00b1394 100644
--- a/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
@@ -199,9 +199,18 @@
   }
 
   CompilationUnitImpl _moveFirstDirectiveToEnd(CompilationUnitImpl unit) {
-    unit.directives.add(unit.directives.removeAt(0));
-    unit.beginToken = unit.directives[0].beginToken;
-    return unit;
+    return CompilationUnitImpl(
+      unit.directives.skip(1).first.beginToken,
+      unit.scriptTag,
+      [
+        ...unit.directives.skip(1),
+        unit.directives.first,
+      ],
+      unit.declarations,
+      unit.endToken,
+      unit.featureSet,
+      unit.lineInfo,
+    );
   }
 
   CompilationUnitImpl _updateBeginToken(CompilationUnitImpl unit) {
diff --git a/pkg/analyzer/test/src/lint/linter/resolve_name_in_scope_test.dart b/pkg/analyzer/test/src/lint/linter/resolve_name_in_scope_test.dart
index 96728c2..86db280 100644
--- a/pkg/analyzer/test/src/lint/linter/resolve_name_in_scope_test.dart
+++ b/pkg/analyzer/test/src/lint/linter/resolve_name_in_scope_test.dart
@@ -446,7 +446,7 @@
   void foo<T>(int T) {}
 }
 ''');
-    var node = findNode.simple('T)');
+    var node = findNode.simpleFormalParameter('T)');
     _resultRequested(node, 'T', false, findElement.typeParameter('T'));
   }
 
@@ -586,7 +586,7 @@
   A(int T) {}
 }
 ''');
-    var node = findNode.simple('T)');
+    var node = findNode.simpleFormalParameter('T)');
     _resultRequested(node, 'T', false, findElement.typeParameter('T'));
   }
 
@@ -606,7 +606,7 @@
   void foo(int T) {}
 }
 ''');
-    var node = findNode.simple('T)');
+    var node = findNode.simpleFormalParameter('T)');
     _resultRequested(node, 'T', false, findElement.typeParameter('T'));
   }
 
@@ -616,7 +616,7 @@
   set foo(int T) {}
 }
 ''');
-    var node = findNode.simple('T)');
+    var node = findNode.simpleFormalParameter('T)');
     _resultRequested(node, 'T', false, findElement.typeParameter('T'));
   }
 
@@ -696,7 +696,7 @@
   void foo(int T) {}
 }
 ''');
-    var node = findNode.simple('T)');
+    var node = findNode.simpleFormalParameter('T)');
     _resultRequested(node, 'T', false, findElement.typeParameter('T'));
   }
 
@@ -704,7 +704,7 @@
     await resolve('''
 void foo<T>(int T) {}
 ''');
-    var node = findNode.simple('T)');
+    var node = findNode.simpleFormalParameter('T)');
     _resultRequested(node, 'T', false, findElement.typeParameter('T'));
   }
 
@@ -712,8 +712,8 @@
     await resolve('''
 void foo(void Function<T>(String T) b) {}
 ''');
-    var node = findNode.simple('T)');
-    var T = findNode.typeParameter('T>').declaredElement2!;
+    var node = findNode.simpleFormalParameter('T)');
+    var T = findNode.typeParameter('T>').declaredElement!;
     _resultRequested(node, 'T', false, T);
   }
 
@@ -767,7 +767,7 @@
   void foo(int T) {}
 }
 ''');
-    var node = findNode.simple('T)');
+    var node = findNode.simpleFormalParameter('T)');
     _resultRequested(node, 'T', false, findElement.typeParameter('T'));
   }
 
diff --git a/pkg/analyzer/test/src/lint/pub_test.dart b/pkg/analyzer/test/src/lint/pub_test.dart
index 303e6d3..d9bf3a9 100644
--- a/pkg/analyzer/test/src/lint/pub_test.dart
+++ b/pkg/analyzer/test/src/lint/pub_test.dart
@@ -213,14 +213,6 @@
   });
 }
 
-testEntry(String label, PSEntry node, Matcher m) {
-  group(label, () {
-    test('entry', () {
-      expect(node, m);
-    });
-  });
-}
-
 testKeySpan(String label, PSEntry? node, {int? startOffset, int? endOffset}) {
   group(label, () {
     group('key', () {
diff --git a/pkg/analyzer/test/src/options/options_rule_validator_test.dart b/pkg/analyzer/test/src/options/options_rule_validator_test.dart
index 506b2b6..83151ea 100644
--- a/pkg/analyzer/test/src/options/options_rule_validator_test.dart
+++ b/pkg/analyzer/test/src/options/options_rule_validator_test.dart
@@ -56,6 +56,14 @@
       ''', [DEPRECATED_LINT_HINT]);
   }
 
+  test_deprecated_rule_map() {
+    assertErrors('''
+linter:
+  rules:
+    deprecated_lint: false
+      ''', [DEPRECATED_LINT_HINT]);
+  }
+
   test_duplicated_rule() {
     assertErrors('''
 linter:
@@ -74,6 +82,24 @@
       ''', [INCOMPATIBLE_LINT_WARNING]);
   }
 
+  test_incompatible_rule_map() {
+    assertErrors('''
+linter:
+  rules:
+    rule_pos: true
+    rule_neg: true
+      ''', [INCOMPATIBLE_LINT_WARNING]);
+  }
+
+  test_incompatible_rule_map_disabled() {
+    assertErrors('''
+linter:
+  rules:
+    rule_pos: true
+    rule_neg: false
+      ''', []);
+  }
+
   test_stable_rule() {
     assertErrors('''
 linter:
@@ -82,6 +108,14 @@
       ''', []);
   }
 
+  test_stable_rule_map() {
+    assertErrors('''
+linter:
+  rules:
+    stable_lint: true
+      ''', []);
+  }
+
   test_undefined_rule() {
     assertErrors('''
 linter:
@@ -89,6 +123,14 @@
     - this_rule_does_not_exist
       ''', [UNDEFINED_LINT_WARNING]);
   }
+
+  test_undefined_rule_map() {
+    assertErrors('''
+linter:
+  rules:
+    this_rule_does_not_exist: false
+      ''', [UNDEFINED_LINT_WARNING]);
+  }
 }
 
 class RuleNeg extends LintRule {
@@ -99,6 +141,7 @@
           description: '',
           details: '',
         );
+
   @override
   List<String> get incompatibleRules => ['rule_pos'];
 }
@@ -111,6 +154,7 @@
           description: '',
           details: '',
         );
+
   @override
   List<String> get incompatibleRules => ['rule_neg'];
 }
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 83acdeb..e72b0fb 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -199,12 +199,12 @@
 
     expect(accessor.variable, same(property));
 
-    var propertyEnclosing = property.enclosingElement3;
-    expect(accessor.enclosingElement3, same(propertyEnclosing));
+    var propertyEnclosing = property.enclosingElement;
+    expect(accessor.enclosingElement, same(propertyEnclosing));
 
     if (propertyEnclosing is CompilationUnitElement) {
       expect(propertyEnclosing.accessors, contains(accessor));
-    } else if (propertyEnclosing is ClassElement) {
+    } else if (propertyEnclosing is InterfaceElement) {
       expect(propertyEnclosing.accessors, contains(accessor));
     }
   }
@@ -318,12 +318,7 @@
       _writeCodeRange(e);
       _writeTypeParameterElements(e.typeParameters);
 
-      InterfaceType? supertype;
-      if (e is ClassElement) {
-        supertype = e.supertype;
-      } else if (e is EnumElement) {
-        supertype = e.supertype;
-      }
+      final supertype = e.supertype;
       if (supertype != null &&
           (supertype.element2.name != 'Object' || e.mixins.isNotEmpty)) {
         _writeType('supertype', supertype);
@@ -388,7 +383,7 @@
       var classReference = reference.parent!.parent!;
       // We need this `if` for duplicate declarations.
       // The reference might be filled by another declaration.
-      if (identical(classReference.element, e.enclosingElement3)) {
+      if (identical(classReference.element, e.enclosingElement)) {
         expect(reference.element, same(e));
       }
     }
@@ -425,7 +420,7 @@
 
       var superConstructor = e.superConstructor;
       if (superConstructor != null) {
-        final enclosingElement = superConstructor.enclosingElement3;
+        final enclosingElement = superConstructor.enclosingElement;
         if (enclosingElement is ClassElement &&
             !enclosingElement.isDartCoreObject) {
           _writeElementReference('superConstructor', superConstructor);
@@ -445,7 +440,7 @@
 
     if (e.isSynthetic) {
       expect(e.nameOffset, -1);
-      expect(e.nonSynthetic, same(e.enclosingElement3));
+      expect(e.nonSynthetic, same(e.enclosingElement));
     } else {
       if (!e.isTempAugmentation) {
         expect(e.nameOffset, isPositive);
@@ -695,9 +690,9 @@
       _writeNonSyntheticElement(e);
     });
 
-    if (e.isSynthetic && e.enclosingElement3 is EnumElementImpl) {
+    if (e.isSynthetic && e.enclosingElement is EnumElementImpl) {
       expect(e.name, 'toString');
-      expect(e.nonSynthetic, same(e.enclosingElement3));
+      expect(e.nonSynthetic, same(e.enclosingElement));
     } else {
       _assertNonSyntheticElementSelf(e);
     }
@@ -802,10 +797,10 @@
     PropertyInducingElement variable = e.variable;
     expect(variable, isNotNull);
 
-    var variableEnclosing = variable.enclosingElement3;
+    var variableEnclosing = variable.enclosingElement;
     if (variableEnclosing is CompilationUnitElement) {
       expect(variableEnclosing.topLevelVariables, contains(variable));
-    } else if (variableEnclosing is ClassElement) {
+    } else if (variableEnclosing is InterfaceElement) {
       expect(variableEnclosing.fields, contains(variable));
     }
 
diff --git a/pkg/analyzer/test/src/summary/elements_test.dart b/pkg/analyzer/test/src/summary/elements_test.dart
index 4d453f1..dc16003 100644
--- a/pkg/analyzer/test/src/summary/elements_test.dart
+++ b/pkg/analyzer/test/src/summary/elements_test.dart
@@ -21,6 +21,8 @@
 }
 
 @reflectiveTest
+// TODO(srawlins): Re-enable?
+// ignore: unreachable_from_main
 class ApplyCheckElementTextReplacements {
   test_applyReplacements() {
     applyCheckElementTextReplacements();
@@ -40,6 +42,104 @@
 }
 
 abstract class ElementsTest extends ElementsBaseTest {
+  test_annotationArgument_recordLiteral() async {
+    var library = await buildLibrary('''
+@A((2, a: 3))
+class C {}
+class A {
+  const A(o);
+}
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    classes
+      class C @20
+        metadata
+          Annotation
+            atSign: @ @0
+            name: SimpleIdentifier
+              token: A @1
+              staticElement: self::@class::A
+              staticType: null
+            arguments: ArgumentList
+              leftParenthesis: ( @2
+              arguments
+                RecordLiteral
+                  leftParenthesis: ( @3
+                  fields
+                    IntegerLiteral
+                      literal: 2 @4
+                      staticType: int
+                    NamedExpression
+                      name: Label
+                        label: SimpleIdentifier
+                          token: a @7
+                          staticElement: <null>
+                          staticType: null
+                        colon: : @8
+                      expression: IntegerLiteral
+                        literal: 3 @10
+                        staticType: int
+                  rightParenthesis: ) @11
+                  staticType: (int, {int a})
+              rightParenthesis: ) @12
+            element: self::@class::A::@constructor::new
+        constructors
+          synthetic @-1
+      class A @31
+        constructors
+          const @43
+            parameters
+              requiredPositional o @45
+                type: dynamic
+''');
+  }
+
+  test_annotationArgument_recordLiteral_withConst() async {
+    var library = await buildLibrary('''
+@A(const ('',))
+class C {}
+class A {
+  const A(o);
+}
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    classes
+      class C @22
+        metadata
+          Annotation
+            atSign: @ @0
+            name: SimpleIdentifier
+              token: A @1
+              staticElement: self::@class::A
+              staticType: null
+            arguments: ArgumentList
+              leftParenthesis: ( @2
+              arguments
+                RecordLiteral
+                  constKeyword: const @3
+                  leftParenthesis: ( @9
+                  fields
+                    SimpleStringLiteral
+                      literal: '' @10
+                  rightParenthesis: ) @13
+                  staticType: (String)
+              rightParenthesis: ) @14
+            element: self::@class::A::@constructor::new
+        constructors
+          synthetic @-1
+      class A @33
+        constructors
+          const @45
+            parameters
+              requiredPositional o @47
+                type: dynamic
+''');
+  }
+
   test_augmentation_augmentationImports_augmentation() async {
     newFile('$testPackageLibPath/a.dart', r'''
 library augment 'test.dart';
@@ -175,7 +275,7 @@
             supertype: A
             constructors
               @51
-                superConstructor: self::@class::A::@constructor::•
+                superConstructor: self::@class::A::@constructor::new
   definingUnit
     classes
       class A @31
@@ -484,7 +584,7 @@
                       staticElement: package:test/a.dart::@class::A
                       staticType: null
                     type: A
-                  staticElement: package:test/a.dart::@class::A::@constructor::•
+                  staticElement: package:test/a.dart::@class::A::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @57
                   rightParenthesis: ) @58
@@ -1498,7 +1598,7 @@
                 condition: BinaryExpression
                   leftOperand: SimpleIdentifier
                     token: x @36
-                    staticElement: self::@class::C::@constructor::•::@parameter::x
+                    staticElement: self::@class::C::@constructor::new::@parameter::x
                     staticType: int
                   operator: >= @38
                   rightOperand: IntegerLiteral
@@ -1534,7 +1634,7 @@
                 condition: BinaryExpression
                   leftOperand: SimpleIdentifier
                     token: x @36
-                    staticElement: self::@class::C::@constructor::•::@parameter::x
+                    staticElement: self::@class::C::@constructor::new::@parameter::x
                     staticType: int
                   operator: >= @38
                   rightOperand: IntegerLiteral
@@ -1661,7 +1761,7 @@
                 equals: = @54
                 expression: SimpleIdentifier
                   token: f @56
-                  staticElement: self::@class::A::@constructor::•::@parameter::f
+                  staticElement: self::@class::A::@constructor::new::@parameter::f
                   staticType: int
         accessors
           synthetic get _f @-1
@@ -1669,6 +1769,51 @@
 ''');
   }
 
+  test_class_constructor_initializers_field_recordLiteral() async {
+    var library = await buildLibrary('''
+class C {
+  final Object x;
+  const C(int a) : x = (0, a);
+}
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    classes
+      class C @6
+        fields
+          final x @25
+            type: Object
+        constructors
+          const @36
+            parameters
+              requiredPositional a @42
+                type: int
+            constantInitializers
+              ConstructorFieldInitializer
+                fieldName: SimpleIdentifier
+                  token: x @47
+                  staticElement: self::@class::C::@field::x
+                  staticType: null
+                equals: = @49
+                expression: RecordLiteral
+                  leftParenthesis: ( @51
+                  fields
+                    IntegerLiteral
+                      literal: 0 @52
+                      staticType: int
+                    SimpleIdentifier
+                      token: a @55
+                      staticElement: self::@class::C::@constructor::new::@parameter::a
+                      staticType: int
+                  rightParenthesis: ) @56
+                  staticType: (int, int)
+        accessors
+          synthetic get x @-1
+            returnType: Object
+''');
+  }
+
   test_class_constructor_initializers_field_withParameter() async {
     var library = await buildLibrary('''
 class C {
@@ -1703,7 +1848,7 @@
                   operator: + @46
                   rightOperand: SimpleIdentifier
                     token: p @48
-                    staticElement: self::@class::C::@constructor::•::@parameter::p
+                    staticElement: self::@class::C::@constructor::new::@parameter::p
                     staticType: int
                   staticElement: dart:core::@class::num::@method::+
                   staticInvokeType: num Function(num)
@@ -1773,15 +1918,15 @@
                             rightBracket: > @96
                           type: A<dynamic Function()>
                         staticElement: ConstructorMember
-                          base: self::@class::A::@constructor::•
+                          base: self::@class::A::@constructor::new
                           substitution: {T: dynamic Function()}
                       argumentList: ArgumentList
                         leftParenthesis: ( @97
                         rightParenthesis: ) @98
                       staticType: A<dynamic Function()>
                   rightParenthesis: ) @99
-                staticElement: self::@class::B::@constructor::•
-            redirectedConstructor: self::@class::B::@constructor::•
+                staticElement: self::@class::B::@constructor::new
+            redirectedConstructor: self::@class::B::@constructor::new
 ''');
   }
 
@@ -1820,8 +1965,8 @@
                       rightBracket: ] @91
                       staticType: List<String>
                   rightParenthesis: ) @92
-                staticElement: self::@class::A::@constructor::•
-            superConstructor: self::@class::A::@constructor::•
+                staticElement: self::@class::A::@constructor::new
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2000,8 +2145,8 @@
                       literal: 42 @74
                       staticType: int
                   rightParenthesis: ) @76
-                staticElement: self::@class::A::@constructor::•
-            superConstructor: self::@class::A::@constructor::•
+                staticElement: self::@class::A::@constructor::new
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2037,8 +2182,8 @@
                       rightBracket: ] @74
                       staticType: List<String>
                   rightParenthesis: ) @75
-                staticElement: self::@class::A::@constructor::•
-            redirectedConstructor: self::@class::A::@constructor::•
+                staticElement: self::@class::A::@constructor::new
+            redirectedConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2166,8 +2311,8 @@
                     SimpleStringLiteral
                       literal: 'bbb' @38
                   rightParenthesis: ) @43
-                staticElement: self::@class::C::@constructor::•
-            redirectedConstructor: self::@class::C::@constructor::•
+                staticElement: self::@class::C::@constructor::new
+            redirectedConstructor: self::@class::C::@constructor::new
           const @54
             parameters
               requiredPositional a @60
@@ -2210,8 +2355,8 @@
                 parameters
                   requiredPositional d @82
                     type: T
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::a
-            superConstructor: self::@class::A::@constructor::•
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::a
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2242,8 +2387,8 @@
             parameters
               requiredPositional final super.a @59
                 type: int
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::a
-            superConstructor: self::@class::A::@constructor::•
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::a
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2274,8 +2419,8 @@
             parameters
               requiredPositional final super.a @61
                 type: int?
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::a
-            superConstructor: self::@class::A::@constructor::•
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::a
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2327,13 +2472,13 @@
                 type: String
               optionalNamed final super.a @97
                 type: int
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::a
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::a
               optionalNamed o2 @107
                 type: String
               optionalNamed final super.b @117
                 type: double
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::b
-            superConstructor: self::@class::A::@constructor::•
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::b
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2365,7 +2510,7 @@
               optionalNamed final super.b @67
                 type: dynamic
                 superConstructorParameter: <null>
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2397,7 +2542,7 @@
               optionalNamed final super.a @56
                 type: dynamic
                 superConstructorParameter: <null>
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2432,13 +2577,13 @@
                 type: String
               optionalPositional final super.a @77
                 type: int
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::a
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::a
               optionalPositional o2 @87
                 type: String
               optionalPositional final super.b @97
                 type: double
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::b
-            superConstructor: self::@class::A::@constructor::•
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::b
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2478,13 +2623,13 @@
                 type: String
               requiredNamed final super.a @124
                 type: int
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::a
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::a
               requiredNamed o2 @147
                 type: String
               requiredNamed final super.b @170
                 type: double
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::b
-            superConstructor: self::@class::A::@constructor::•
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::b
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2519,13 +2664,13 @@
                 type: String
               requiredPositional final super.a @76
                 type: int
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::a
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::a
               requiredPositional o2 @86
                 type: String
               requiredPositional final super.b @96
                 type: double
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::b
-            superConstructor: self::@class::A::@constructor::•
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::b
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2562,8 +2707,8 @@
             parameters
               requiredPositional final super.a @64
                 type: int
-                superConstructorParameter: self::@class::B::@constructor::•::@parameter::a
-            superConstructor: self::@class::B::@constructor::•
+                superConstructorParameter: self::@class::B::@constructor::new::@parameter::a
+            superConstructor: self::@class::B::@constructor::new
       class B @77
         supertype: A
         constructors
@@ -2571,8 +2716,8 @@
             parameters
               requiredPositional final super.a @101
                 type: int
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::a
-            superConstructor: self::@class::A::@constructor::•
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::a
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2610,10 +2755,10 @@
               requiredPositional final super.a @63
                 type: int
                 superConstructorParameter: SuperFormalParameterMember
-                  base: self::@class::B::@constructor::•::@parameter::a
+                  base: self::@class::B::@constructor::new::@parameter::a
                   substitution: {T: String}
             superConstructor: ConstructorMember
-              base: self::@class::B::@constructor::•
+              base: self::@class::B::@constructor::new
               substitution: {T: String}
       class B @76
         typeParameters
@@ -2625,8 +2770,8 @@
             parameters
               requiredPositional final super.a @103
                 type: int
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::a
-            superConstructor: self::@class::A::@constructor::•
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::a
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2653,7 +2798,7 @@
               requiredPositional final super.a @42
                 type: dynamic
                 superConstructorParameter: <null>
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -2685,7 +2830,7 @@
               requiredPositional final super.a @65
                 type: dynamic
                 superConstructorParameter: <null>
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -3030,7 +3175,7 @@
       class C @6
         constructors
           factory @20
-            redirectedConstructor: self::@class::D::@constructor::•
+            redirectedConstructor: self::@class::D::@constructor::new
           _ @33
             periodOffset: 32
             nameEnd: 34
@@ -3065,7 +3210,7 @@
         constructors
           factory @26
             redirectedConstructor: ConstructorMember
-              base: self::@class::D::@constructor::•
+              base: self::@class::D::@constructor::new
               substitution: {T: U, U: T}
           _ @45
             periodOffset: 44
@@ -3109,7 +3254,7 @@
         constructors
           factory @53
             redirectedConstructor: ConstructorMember
-              base: self::@class::C::@constructor::•
+              base: self::@class::C::@constructor::new
               substitution: {T: U, U: T}
         methods
           abstract B_ @70
@@ -3157,7 +3302,7 @@
       class C @25
         constructors
           factory @39
-            redirectedConstructor: package:test/foo.dart::@class::D::@constructor::•
+            redirectedConstructor: package:test/foo.dart::@class::D::@constructor::new
           _ @52
             periodOffset: 51
             nameEnd: 53
@@ -3193,7 +3338,7 @@
         constructors
           factory @45
             redirectedConstructor: ConstructorMember
-              base: package:test/foo.dart::@class::D::@constructor::•
+              base: package:test/foo.dart::@class::D::@constructor::new
               substitution: {T: U, U: T}
           _ @64
             periodOffset: 63
@@ -3225,7 +3370,7 @@
       class C @25
         constructors
           factory @39
-            redirectedConstructor: package:test/foo.dart::@class::B::@constructor::•
+            redirectedConstructor: package:test/foo.dart::@class::B::@constructor::new
           _ @52
             periodOffset: 51
             nameEnd: 53
@@ -3255,7 +3400,7 @@
       class C @32
         constructors
           factory @46
-            redirectedConstructor: package:test/foo.dart::@class::D::@constructor::•
+            redirectedConstructor: package:test/foo.dart::@class::D::@constructor::new
           _ @63
             periodOffset: 62
             nameEnd: 64
@@ -3291,7 +3436,7 @@
         constructors
           factory @52
             redirectedConstructor: ConstructorMember
-              base: package:test/foo.dart::@class::D::@constructor::•
+              base: package:test/foo.dart::@class::D::@constructor::new
               substitution: {T: U, U: T}
           _ @75
             periodOffset: 74
@@ -3323,7 +3468,7 @@
       class C @32
         constructors
           factory @46
-            redirectedConstructor: package:test/foo.dart::@class::B::@constructor::•
+            redirectedConstructor: package:test/foo.dart::@class::B::@constructor::new
           _ @63
             periodOffset: 62
             nameEnd: 64
@@ -3367,7 +3512,7 @@
       class B @21
         constructors
           factory @35
-            redirectedConstructor: self::@class::C::@constructor::•
+            redirectedConstructor: self::@class::C::@constructor::new
           _ @48
             periodOffset: 47
             nameEnd: 49
@@ -3495,8 +3640,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @47
                   rightParenthesis: ) @48
-                staticElement: self::@class::C::@constructor::•
-            redirectedConstructor: self::@class::C::@constructor::•
+                staticElement: self::@class::C::@constructor::new
+            redirectedConstructor: self::@class::C::@constructor::new
 ''');
   }
 
@@ -3526,8 +3671,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @50
                   rightParenthesis: ) @51
-                staticElement: self::@class::C::@constructor::•
-            redirectedConstructor: self::@class::C::@constructor::•
+                staticElement: self::@class::C::@constructor::new
+            redirectedConstructor: self::@class::C::@constructor::new
 ''');
   }
 
@@ -3548,7 +3693,7 @@
           named @21
             periodOffset: 20
             nameEnd: 26
-            redirectedConstructor: self::@class::C::@constructor::•
+            redirectedConstructor: self::@class::C::@constructor::new
 ''');
   }
 
@@ -3630,7 +3775,7 @@
         supertype: A
         constructors
           @33
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -3652,7 +3797,7 @@
         supertype: A
         constructors
           @33
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -3672,7 +3817,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
 ''');
   }
 
@@ -3729,7 +3874,7 @@
                         staticElement: self::@class::D
                         staticType: null
                       type: D
-                    staticElement: self::@class::D::@constructor::•
+                    staticElement: self::@class::D::@constructor::new
                   argumentList: ArgumentList
                     leftParenthesis: ( @46
                     rightParenthesis: ) @47
@@ -3759,7 +3904,7 @@
                         staticElement: self::@class::C
                         staticType: null
                       type: C
-                    staticElement: self::@class::C::@constructor::•
+                    staticElement: self::@class::C::@constructor::new
                   argumentList: ArgumentList
                     leftParenthesis: ( @98
                     rightParenthesis: ) @99
@@ -4074,7 +4219,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @39
               rightParenthesis: ) @40
-            element: self::@class::Annotation::@constructor::•
+            element: self::@class::Annotation::@constructor::new
         constructors
           synthetic @-1
       class BeforeMetaNamed @117
@@ -4112,7 +4257,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @148
               rightParenthesis: ) @149
-            element: self::@class::Annotation::@constructor::•
+            element: self::@class::Annotation::@constructor::new
         constructors
           synthetic @-1
       class AroundMeta @247
@@ -4127,7 +4272,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @224
               rightParenthesis: ) @225
-            element: self::@class::Annotation::@constructor::•
+            element: self::@class::Annotation::@constructor::new
         constructors
           synthetic @-1
       class DocBeforeMetaNotDocAfter @319
@@ -4142,7 +4287,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @290
               rightParenthesis: ) @291
-            element: self::@class::Annotation::@constructor::•
+            element: self::@class::Annotation::@constructor::new
         constructors
           synthetic @-1
       class Annotation @354
@@ -4499,7 +4644,7 @@
                       rightBracket: > @80
                     type: A<int Function(double)>
                   staticElement: ConstructorMember
-                    base: self::@class::A::@constructor::•
+                    base: self::@class::A::@constructor::new
                     substitution: {T: int Function(double)}
                 argumentList: ArgumentList
                   leftParenthesis: ( @81
@@ -4596,7 +4741,7 @@
               requiredPositional final this.v @34
                 type: int
                 field: self::@class::C::@field::v
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
         accessors
           synthetic get v @-1
             returnType: int
@@ -4723,7 +4868,7 @@
             type: int
         constructors
           synthetic @-1
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
         accessors
           synthetic get v @-1
             returnType: int
@@ -4786,7 +4931,7 @@
                 staticType: List<int>
         constructors
           const @94
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         accessors
           synthetic get f @-1
             returnType: List<int>
@@ -4861,7 +5006,7 @@
                 staticType: double
         constructors
           const @80
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         accessors
           synthetic get foo @-1
             returnType: double
@@ -5326,7 +5471,7 @@
             type: int
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         accessors
           synthetic get f @-1
             returnType: int
@@ -5368,7 +5513,7 @@
             type: int
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         accessors
           synthetic get f @-1
             returnType: int
@@ -5827,7 +5972,7 @@
         supertype: D
         constructors
           synthetic @-1
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
         methods
           f @25
             parameters
@@ -5863,7 +6008,7 @@
         supertype: D
         constructors
           synthetic @-1
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
         methods
           f @22
             returnType: int
@@ -5915,7 +6060,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           A @38
             returnType: void
@@ -6113,7 +6258,7 @@
           G
         constructors
           synthetic @-1
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
       class D @40
         constructors
           synthetic @-1
@@ -6147,7 +6292,7 @@
           C<double>
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
       class A @50
         constructors
           synthetic @-1
@@ -6980,7 +7125,7 @@
             type: double
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         accessors
           synthetic get t @-1
             returnType: double
@@ -6995,7 +7140,7 @@
           B
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
       class D @96
         supertype: C
         fields
@@ -7003,7 +7148,7 @@
             type: dynamic
         constructors
           synthetic @-1
-            superConstructor: self::@class::C::@constructor::•
+            superConstructor: self::@class::C::@constructor::new
         accessors
           set t @121
             parameters
@@ -7028,7 +7173,7 @@
             type: int
         constructors
           synthetic @-1
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
         accessors
           set f @29
             parameters
@@ -7305,7 +7450,7 @@
         supertype: D
         constructors
           synthetic @-1
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
       class D @27
         constructors
           synthetic @-1
@@ -7326,7 +7471,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::D::@constructor::•
+              base: self::@class::D::@constructor::new
               substitution: {T1: int, T2: double}
       class D @40
         typeParameters
@@ -7359,7 +7504,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: B}
 ''');
   }
@@ -7976,8 +8121,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @32
         constructors
           synthetic @-1
@@ -8015,8 +8160,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @35
         constructors
           synthetic @-1
@@ -8053,8 +8198,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @43
         constructors
           synthetic @-1
@@ -8091,8 +8236,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @48
         constructors
           synthetic @-1
@@ -8129,8 +8274,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @87
         constructors
           synthetic @-1
@@ -8164,8 +8309,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::A::@constructor::•
-            superConstructor: self::@class::A::@constructor::•
+                staticElement: self::@class::A::@constructor::new
+            superConstructor: self::@class::A::@constructor::new
       class A @42
         constructors
           synthetic @-1
@@ -8210,8 +8355,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @39
         constructors
           synthetic @-1
@@ -8248,8 +8393,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @29
         constructors
           synthetic @-1
@@ -8283,8 +8428,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @26
         constructors
           synthetic @-1
@@ -8328,8 +8473,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: package:test/a.dart::@class::Base::@constructor::•
-            superConstructor: package:test/a.dart::@class::Base::@constructor::•
+                staticElement: package:test/a.dart::@class::Base::@constructor::new
+            superConstructor: package:test/a.dart::@class::Base::@constructor::new
           synthetic const named @-1
             constantInitializers
               SuperConstructorInvocation
@@ -8389,8 +8534,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: package:test/a.dart::@class::Base::@constructor::•
-            superConstructor: package:test/a.dart::@class::Base::@constructor::•
+                staticElement: package:test/a.dart::@class::Base::@constructor::new
+            superConstructor: package:test/a.dart::@class::Base::@constructor::new
           synthetic noArgs @-1
             constantInitializers
               SuperConstructorInvocation
@@ -8695,8 +8840,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @26
         constructors
           synthetic @-1
@@ -8855,7 +9000,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @75
               rightParenthesis: ) @76
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 68
         codeLength: 32
         constructors
@@ -8872,7 +9017,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @109
               rightParenthesis: ) @110
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 102
         codeLength: 70
         constructors
@@ -8889,7 +9034,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @211
               rightParenthesis: ) @212
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 174
         codeLength: 70
         constructors
@@ -8906,7 +9051,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @268
               rightParenthesis: ) @269
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 261
         codeLength: 57
         constructors
@@ -8976,7 +9121,7 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: dart:core::@class::Object::@constructor::•
+                staticElement: dart:core::@class::Object::@constructor::new
       class alias HasDocComment @91
         documentationComment: /// Comment 1.\n/// Comment 2.
         codeOffset: 55
@@ -8993,7 +9138,7 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: dart:core::@class::Object::@constructor::•
+                staticElement: dart:core::@class::Object::@constructor::new
       class alias HasAnnotation @142
         metadata
           Annotation
@@ -9005,7 +9150,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @133
               rightParenthesis: ) @134
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 126
         codeLength: 49
         supertype: Object
@@ -9020,7 +9165,7 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: dart:core::@class::Object::@constructor::•
+                staticElement: dart:core::@class::Object::@constructor::new
       class alias AnnotationThenComment @223
         documentationComment: /// Comment 1.\n/// Comment 2.
         metadata
@@ -9033,7 +9178,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @184
               rightParenthesis: ) @185
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 177
         codeLength: 87
         supertype: Object
@@ -9048,7 +9193,7 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: dart:core::@class::Object::@constructor::•
+                staticElement: dart:core::@class::Object::@constructor::new
       class alias CommentThenAnnotation @312
         documentationComment: /// Comment 1.\n/// Comment 2.
         metadata
@@ -9061,7 +9206,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @303
               rightParenthesis: ) @304
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 266
         codeLength: 87
         supertype: Object
@@ -9076,7 +9221,7 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: dart:core::@class::Object::@constructor::•
+                staticElement: dart:core::@class::Object::@constructor::new
       class alias CommentAroundAnnotation @401
         documentationComment: /// Comment 2.
         metadata
@@ -9089,7 +9234,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @377
               rightParenthesis: ) @378
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 370
         codeLength: 74
         supertype: Object
@@ -9104,7 +9249,7 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: dart:core::@class::Object::@constructor::•
+                staticElement: dart:core::@class::Object::@constructor::new
 ''',
         withCodeRanges: true);
   }
@@ -9174,7 +9319,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @99
                   rightParenthesis: ) @100
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 92
             codeLength: 32
             periodOffset: 105
@@ -9191,7 +9336,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @135
                   rightParenthesis: ) @136
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 128
             codeLength: 74
             periodOffset: 175
@@ -9208,7 +9353,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @247
                   rightParenthesis: ) @248
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 206
             codeLength: 74
             periodOffset: 253
@@ -9225,7 +9370,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @308
                   rightParenthesis: ) @309
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 301
             codeLength: 59
             periodOffset: 331
@@ -9299,7 +9444,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @152
                   rightParenthesis: ) @153
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 145
             codeLength: 49
             periodOffset: 166
@@ -9316,7 +9461,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @205
                   rightParenthesis: ) @206
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 198
             codeLength: 91
             periodOffset: 253
@@ -9333,7 +9478,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @334
                   rightParenthesis: ) @335
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 293
             codeLength: 91
             periodOffset: 348
@@ -9350,7 +9495,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @412
                   rightParenthesis: ) @413
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 405
             codeLength: 76
             periodOffset: 443
@@ -9389,7 +9534,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -9407,7 +9552,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -9425,7 +9570,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -9525,7 +9670,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @105
               rightParenthesis: ) @106
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 98
         codeLength: 41
         extendedType: A
@@ -9541,7 +9686,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @148
               rightParenthesis: ) @149
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 141
         codeLength: 79
         extendedType: A
@@ -9557,7 +9702,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @259
               rightParenthesis: ) @260
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 222
         codeLength: 79
         extendedType: A
@@ -9573,7 +9718,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @325
               rightParenthesis: ) @326
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 318
         codeLength: 66
         extendedType: A
@@ -9720,7 +9865,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @91
                   rightParenthesis: ) @92
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 84
             codeLength: 29
             type: int
@@ -9735,7 +9880,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @91
                   rightParenthesis: ) @92
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 115
             codeLength: 14
             type: int
@@ -9751,7 +9896,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @141
                   rightParenthesis: ) @142
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 134
             codeLength: 71
             type: int
@@ -9767,7 +9912,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @141
                   rightParenthesis: ) @142
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 207
             codeLength: 22
             type: int
@@ -9783,7 +9928,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @275
                   rightParenthesis: ) @276
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 234
             codeLength: 71
             type: int
@@ -9799,7 +9944,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @275
                   rightParenthesis: ) @276
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 307
             codeLength: 22
             type: int
@@ -9815,7 +9960,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @358
                   rightParenthesis: ) @359
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 351
             codeLength: 56
             type: int
@@ -9831,7 +9976,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @358
                   rightParenthesis: ) @359
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 409
             codeLength: 24
             type: int
@@ -9964,7 +10109,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @77
               rightParenthesis: ) @78
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 70
         codeLength: 33
         returnType: void
@@ -9980,7 +10125,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @112
               rightParenthesis: ) @113
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 105
         codeLength: 71
         returnType: void
@@ -9996,7 +10141,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @215
               rightParenthesis: ) @216
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 178
         codeLength: 71
         returnType: void
@@ -10012,7 +10157,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @273
               rightParenthesis: ) @274
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 266
         codeLength: 58
         returnType: void
@@ -10076,7 +10221,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @79
               rightParenthesis: ) @80
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 72
         codeLength: 34
         aliasedType: dynamic Function()
@@ -10094,7 +10239,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @115
               rightParenthesis: ) @116
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 108
         codeLength: 72
         aliasedType: dynamic Function()
@@ -10112,7 +10257,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @219
               rightParenthesis: ) @220
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 182
         codeLength: 72
         aliasedType: dynamic Function()
@@ -10130,7 +10275,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @278
               rightParenthesis: ) @279
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 271
         codeLength: 59
         aliasedType: dynamic Function()
@@ -10196,7 +10341,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @101
               rightParenthesis: ) @102
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 94
         codeLength: 45
         aliasedType: dynamic Function()
@@ -10214,7 +10359,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @148
               rightParenthesis: ) @149
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 141
         codeLength: 83
         aliasedType: dynamic Function()
@@ -10232,7 +10377,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @263
               rightParenthesis: ) @264
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 226
         codeLength: 83
         aliasedType: dynamic Function()
@@ -10250,7 +10395,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @333
               rightParenthesis: ) @334
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 326
         codeLength: 70
         aliasedType: dynamic Function()
@@ -10320,7 +10465,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @97
                   rightParenthesis: ) @98
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 90
             codeLength: 35
             returnType: void
@@ -10336,7 +10481,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @136
                   rightParenthesis: ) @137
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 129
             codeLength: 77
             returnType: void
@@ -10352,7 +10497,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @251
                   rightParenthesis: ) @252
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 210
             codeLength: 77
             returnType: void
@@ -10368,7 +10513,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @315
                   rightParenthesis: ) @316
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
             codeOffset: 308
             codeLength: 62
             returnType: void
@@ -10426,7 +10571,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @12
                   rightParenthesis: ) @13
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
           requiredPositional b @26
             type: int
           requiredPositional c @43
@@ -10441,7 +10586,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @36
                   rightParenthesis: ) @37
-                element: dart:core::@class::Object::@constructor::•
+                element: dart:core::@class::Object::@constructor::new
         returnType: dynamic
 ''');
   }
@@ -10571,7 +10716,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @73
               rightParenthesis: ) @74
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 66
         codeLength: 27
         type: int
@@ -10586,7 +10731,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @73
               rightParenthesis: ) @74
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 95
         codeLength: 14
         type: int
@@ -10602,7 +10747,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @119
               rightParenthesis: ) @120
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 112
         codeLength: 65
         type: int
@@ -10618,7 +10763,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @119
               rightParenthesis: ) @120
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 179
         codeLength: 22
         type: int
@@ -10634,7 +10779,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @241
               rightParenthesis: ) @242
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 204
         codeLength: 65
         type: int
@@ -10650,7 +10795,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @241
               rightParenthesis: ) @242
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 271
         codeLength: 22
         type: int
@@ -10666,7 +10811,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @318
               rightParenthesis: ) @319
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 311
         codeLength: 52
         type: int
@@ -10682,7 +10827,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @318
               rightParenthesis: ) @319
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         codeOffset: 365
         codeLength: 24
         type: int
@@ -11045,7 +11190,7 @@
                   staticType: null
                 type: C<int>
               staticElement: ConstructorMember
-                base: self::@class::C::@constructor::•
+                base: self::@class::C::@constructor::new
                 substitution: {T: int}
             argumentList: ArgumentList
               leftParenthesis: ( @96
@@ -11345,7 +11490,7 @@
         constructors
           const @64
             superConstructor: ConstructorMember
-              base: self::@class::P::@constructor::•
+              base: self::@class::P::@constructor::new
               substitution: {T: T}
       class P2 @79
         typeParameters
@@ -11355,7 +11500,7 @@
         constructors
           const @108
             superConstructor: ConstructorMember
-              base: self::@class::P::@constructor::•
+              base: self::@class::P::@constructor::new
               substitution: {T: T}
     topLevelVariables
       static const values @131
@@ -11373,7 +11518,7 @@
                       staticType: null
                     type: P1<dynamic>
                   staticElement: ConstructorMember
-                    base: self::@class::P1::@constructor::•
+                    base: self::@class::P1::@constructor::new
                     substitution: {T: dynamic}
                 argumentList: ArgumentList
                   leftParenthesis: ( @146
@@ -11398,7 +11543,7 @@
                       rightBracket: > @158
                     type: P2<int>
                   staticElement: ConstructorMember
-                    base: self::@class::P2::@constructor::•
+                    base: self::@class::P2::@constructor::new
                     substitution: {T: int}
                 argumentList: ArgumentList
                   leftParenthesis: ( @159
@@ -11894,7 +12039,7 @@
                   staticType: null
                 type: C<dynamic, dynamic>
               staticElement: ConstructorMember
-                base: self::@class::C::@constructor::•
+                base: self::@class::C::@constructor::new
                 substitution: {K: dynamic, V: dynamic}
             argumentList: ArgumentList
               leftParenthesis: ( @48
@@ -11955,7 +12100,7 @@
                   rightBracket: > @60
                 type: C<int, String>
               staticElement: ConstructorMember
-                base: self::@class::C::@constructor::•
+                base: self::@class::C::@constructor::new
                 substitution: {K: int, V: String}
             argumentList: ArgumentList
               leftParenthesis: ( @61
@@ -12012,7 +12157,7 @@
                   rightBracket: > @46
                 type: C<int, String>
               staticElement: ConstructorMember
-                base: package:test/a.dart::@class::C::@constructor::•
+                base: package:test/a.dart::@class::C::@constructor::new
                 substitution: {K: int, V: String}
             argumentList: ArgumentList
               leftParenthesis: ( @47
@@ -12077,7 +12222,7 @@
                   rightBracket: > @53
                 type: C<int, String>
               staticElement: ConstructorMember
-                base: package:test/a.dart::@class::C::@constructor::•
+                base: package:test/a.dart::@class::C::@constructor::new
                 substitution: {K: int, V: String}
             argumentList: ArgumentList
               leftParenthesis: ( @54
@@ -12564,7 +12709,7 @@
                   staticElement: self::@class::C
                   staticType: null
                 type: C
-              staticElement: self::@class::C::@constructor::•
+              staticElement: self::@class::C::@constructor::new
             argumentList: ArgumentList
               leftParenthesis: ( @42
               rightParenthesis: ) @43
@@ -12603,7 +12748,7 @@
                   staticElement: package:test/a.dart::@class::C
                   staticType: null
                 type: C
-              staticElement: package:test/a.dart::@class::C::@constructor::•
+              staticElement: package:test/a.dart::@class::C::@constructor::new
             argumentList: ArgumentList
               leftParenthesis: ( @34
               rightParenthesis: ) @35
@@ -12650,7 +12795,7 @@
                   staticElement: package:test/a.dart::@class::C
                   staticType: null
                 type: C
-              staticElement: package:test/a.dart::@class::C::@constructor::•
+              staticElement: package:test/a.dart::@class::C::@constructor::new
             argumentList: ArgumentList
               leftParenthesis: ( @41
               rightParenthesis: ) @42
@@ -14043,6 +14188,99 @@
 ''');
   }
 
+  void test_const_recordLiteral() async {
+    var library = await buildLibrary('''
+const a = 0;
+const b = (a, a: a);
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    topLevelVariables
+      static const a @6
+        type: int
+        constantInitializer
+          IntegerLiteral
+            literal: 0 @10
+            staticType: int
+      static const b @19
+        type: (int, {int a})
+        constantInitializer
+          RecordLiteral
+            leftParenthesis: ( @23
+            fields
+              SimpleIdentifier
+                token: a @24
+                staticElement: self::@getter::a
+                staticType: int
+              NamedExpression
+                name: Label
+                  label: SimpleIdentifier
+                    token: a @27
+                    staticElement: <null>
+                    staticType: null
+                  colon: : @28
+                expression: SimpleIdentifier
+                  token: a @30
+                  staticElement: self::@getter::a
+                  staticType: int
+            rightParenthesis: ) @31
+            staticType: (int, {int a})
+    accessors
+      synthetic static get a @-1
+        returnType: int
+      synthetic static get b @-1
+        returnType: (int, {int a})
+''');
+  }
+
+  void test_const_recordLiteral_explicitConst() async {
+    var library = await buildLibrary('''
+const a = 0;
+const b = const (a, a: a);
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    topLevelVariables
+      static const a @6
+        type: int
+        constantInitializer
+          IntegerLiteral
+            literal: 0 @10
+            staticType: int
+      static const b @19
+        type: (int, {int a})
+        constantInitializer
+          RecordLiteral
+            constKeyword: const @23
+            leftParenthesis: ( @29
+            fields
+              SimpleIdentifier
+                token: a @30
+                staticElement: self::@getter::a
+                staticType: int
+              NamedExpression
+                name: Label
+                  label: SimpleIdentifier
+                    token: a @33
+                    staticElement: <null>
+                    staticType: null
+                  colon: : @34
+                expression: SimpleIdentifier
+                  token: a @36
+                  staticElement: self::@getter::a
+                  staticType: int
+            rightParenthesis: ) @37
+            staticType: (int, {int a})
+    accessors
+      synthetic static get a @-1
+        returnType: int
+      synthetic static get b @-1
+        returnType: (int, {int a})
+''');
+  }
+
   test_const_reference_staticField() async {
     var library = await buildLibrary(r'''
 class C {
@@ -14614,7 +14852,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -14630,7 +14868,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -14646,7 +14884,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -16885,7 +17123,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -16901,7 +17139,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -16917,7 +17155,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -16993,7 +17231,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -17276,7 +17514,7 @@
                           rightBracket: > @71
                         type: A<dynamic Function()>
                       staticElement: ConstructorMember
-                        base: self::@class::A::@constructor::•
+                        base: self::@class::A::@constructor::new
                         substitution: {T: dynamic Function()}
                     argumentList: ArgumentList
                       leftParenthesis: ( @72
@@ -17397,6 +17635,49 @@
 ''');
   }
 
+  test_defaultValue_recordLiteral_named_const() async {
+    var library = await buildLibrary('''
+void f({({int f1, bool f2}) x = const (f1: 1, f2: true)}) {}
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    functions
+      f @5
+        parameters
+          optionalNamed x @28
+            type: ({int f1, bool f2})
+            constantInitializer
+              RecordLiteral
+                constKeyword: const @32
+                leftParenthesis: ( @38
+                fields
+                  NamedExpression
+                    name: Label
+                      label: SimpleIdentifier
+                        token: f1 @39
+                        staticElement: <null>
+                        staticType: null
+                      colon: : @41
+                    expression: IntegerLiteral
+                      literal: 1 @43
+                      staticType: int
+                  NamedExpression
+                    name: Label
+                      label: SimpleIdentifier
+                        token: f2 @46
+                        staticElement: <null>
+                        staticType: null
+                      colon: : @48
+                    expression: BooleanLiteral
+                      literal: true @50
+                      staticType: bool
+                rightParenthesis: ) @54
+                staticType: ({int f1, bool f2})
+        returnType: void
+''');
+  }
+
   test_defaultValue_recordLiteral_positional() async {
     var library = await buildLibrary('''
 void f({(int, bool) x = (1, true)}) {}
@@ -17425,6 +17706,35 @@
 ''');
   }
 
+  void test_defaultValue_recordLiteral_positional_const() async {
+    var library = await buildLibrary('''
+void f({(int, bool) x = const (1, true)}) {}
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    functions
+      f @5
+        parameters
+          optionalNamed x @20
+            type: (int, bool)
+            constantInitializer
+              RecordLiteral
+                constKeyword: const @24
+                leftParenthesis: ( @30
+                fields
+                  IntegerLiteral
+                    literal: 1 @31
+                    staticType: int
+                  BooleanLiteral
+                    literal: true @34
+                    staticType: bool
+                rightParenthesis: ) @38
+                staticType: (int, bool)
+        returnType: void
+''');
+  }
+
   test_defaultValue_refersToExtension_method_inside() async {
     var library = await buildLibrary('''
 class A {}
@@ -17499,7 +17809,7 @@
                           staticType: null
                         type: B<int, double>
                       staticElement: ConstructorMember
-                        base: self::@class::B::@constructor::•
+                        base: self::@class::B::@constructor::new
                         substitution: {T1: int, T2: double}
                     argumentList: ArgumentList
                       leftParenthesis: ( @81
@@ -17548,7 +17858,7 @@
                           staticType: null
                         type: B<Never>
                       staticElement: ConstructorMember
-                        base: self::@class::B::@constructor::•
+                        base: self::@class::B::@constructor::new
                         substitution: {T: Never}
                     argumentList: ArgumentList
                       leftParenthesis: ( @68
@@ -17607,7 +17917,7 @@
                           staticType: null
                         type: B<Never>
                       staticElement: ConstructorMember
-                        base: self::@class::B::@constructor::•
+                        base: self::@class::B::@constructor::new
                         substitution: {T: Never}
                     argumentList: ArgumentList
                       leftParenthesis: ( @133
@@ -17667,7 +17977,7 @@
                           staticType: null
                         type: B<Null*>*
                       staticElement: ConstructorMember
-                        base: self::@class::B::@constructor::•
+                        base: self::@class::B::@constructor::new
                         substitution: {T: Null*}
                     argumentList: ArgumentList
                       leftParenthesis: ( @148
@@ -17716,7 +18026,7 @@
                           staticType: null
                         type: B<Null*>*
                       staticElement: ConstructorMember
-                        base: self::@class::B::@constructor::•
+                        base: self::@class::B::@constructor::new
                         substitution: {T: Null*}
                     argumentList: ArgumentList
                       leftParenthesis: ( @83
@@ -17760,7 +18070,7 @@
                       staticType: null
                     type: B<Never>
                   staticElement: ConstructorMember
-                    base: self::@class::B::@constructor::•
+                    base: self::@class::B::@constructor::new
                     substitution: {T: Never}
                 argumentList: ArgumentList
                   leftParenthesis: ( @57
@@ -17810,7 +18120,7 @@
                           staticType: null
                         type: B<Never>
                       staticElement: ConstructorMember
-                        base: self::@class::B::@constructor::•
+                        base: self::@class::B::@constructor::new
                         substitution: {T: Never}
                     argumentList: ArgumentList
                       leftParenthesis: ( @69
@@ -17865,7 +18175,7 @@
                           staticType: null
                         type: B<Never, Never>
                       staticElement: ConstructorMember
-                        base: self::@class::B::@constructor::•
+                        base: self::@class::B::@constructor::new
                         substitution: {T1: Never, T2: Never}
                     argumentList: ArgumentList
                       leftParenthesis: ( @84
@@ -17916,7 +18226,7 @@
                           staticType: null
                         type: B<Never>
                       staticElement: ConstructorMember
-                        base: self::@class::B::@constructor::•
+                        base: self::@class::B::@constructor::new
                         substitution: {T: Never}
                     argumentList: ArgumentList
                       leftParenthesis: ( @69
@@ -18004,8 +18314,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::A::@constructor::•
-            superConstructor: self::@class::A::@constructor::•
+                staticElement: self::@class::A::@constructor::new
+            superConstructor: self::@class::A::@constructor::new
       class alias X @48
         supertype: B
         mixins
@@ -18018,8 +18328,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::B::@constructor::•
-            superConstructor: self::@class::B::@constructor::•
+                staticElement: self::@class::B::@constructor::new
+            superConstructor: self::@class::B::@constructor::new
     mixins
       mixin M @68
         superclassConstraints
@@ -18050,7 +18360,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18066,7 +18376,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18110,7 +18420,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18126,7 +18436,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18142,7 +18452,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18419,7 +18729,7 @@
                       staticType: null
                     type: E<int>
                   staticElement: ConstructorMember
-                    base: self::@enum::E::@constructor::•
+                    base: self::@enum::E::@constructor::new
                     substitution: {T: int}
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18441,7 +18751,7 @@
                       staticType: null
                     type: E<String>
                   staticElement: ConstructorMember
-                    base: self::@enum::E::@constructor::•
+                    base: self::@enum::E::@constructor::new
                     substitution: {T: String}
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18506,7 +18816,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18572,7 +18882,7 @@
                       rightBracket: > @22
                     type: E<double>
                   staticElement: ConstructorMember
-                    base: self::@enum::E::@constructor::•
+                    base: self::@enum::E::@constructor::new
                     substitution: {T: double}
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -18631,7 +18941,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18683,7 +18993,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18738,7 +19048,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18791,7 +19101,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18856,7 +19166,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18920,7 +19230,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -18977,7 +19287,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19050,7 +19360,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19111,7 +19421,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19172,7 +19482,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19298,7 +19608,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   arguments
@@ -19362,7 +19672,7 @@
                       staticType: null
                     type: E<dynamic>
                   staticElement: ConstructorMember
-                    base: self::@enum::E::@constructor::•
+                    base: self::@enum::E::@constructor::new
                     substitution: {T: dynamic}
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19394,7 +19704,7 @@
                 condition: IsExpression
                   expression: SimpleIdentifier
                     token: a @57
-                    staticElement: self::@enum::E::@constructor::•::@parameter::a
+                    staticElement: self::@enum::E::@constructor::new::@parameter::a
                     staticType: T?
                   isOperator: is @59
                   type: NamedType
@@ -19450,7 +19760,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19502,7 +19812,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19562,7 +19872,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19624,7 +19934,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19689,7 +19999,7 @@
                       staticType: null
                     type: E<dynamic>
                   staticElement: ConstructorMember
-                    base: self::@enum::E::@constructor::•
+                    base: self::@enum::E::@constructor::new
                     substitution: {U: dynamic}
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19753,7 +20063,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19809,7 +20119,7 @@
                       staticType: null
                     type: E<dynamic>
                   staticElement: ConstructorMember
-                    base: self::@enum::E::@constructor::•
+                    base: self::@enum::E::@constructor::new
                     substitution: {T: dynamic}
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -19872,7 +20182,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19929,7 +20239,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -19989,7 +20299,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20054,7 +20364,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20116,7 +20426,7 @@
                       staticType: null
                     type: E<dynamic>
                   staticElement: ConstructorMember
-                    base: self::@enum::E::@constructor::•
+                    base: self::@enum::E::@constructor::new
                     substitution: {T: dynamic}
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -20176,7 +20486,7 @@
                       staticType: null
                     type: E<num, num>
                   staticElement: ConstructorMember
-                    base: self::@enum::E::@constructor::•
+                    base: self::@enum::E::@constructor::new
                     substitution: {T: num, U: num}
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -20449,7 +20759,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20466,7 +20776,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20541,7 +20851,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20566,7 +20876,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20629,7 +20939,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20645,7 +20955,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20698,7 +21008,7 @@
                       staticElement: self::@enum::E1
                       staticType: null
                     type: E1
-                  staticElement: self::@enum::E1::@constructor::•
+                  staticElement: self::@enum::E1::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20736,7 +21046,7 @@
                       staticElement: self::@enum::E2
                       staticType: null
                     type: E2
-                  staticElement: self::@enum::E2::@constructor::•
+                  staticElement: self::@enum::E2::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20825,7 +21135,7 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: dart:core::@class::Object::@constructor::•
+                staticElement: dart:core::@class::Object::@constructor::new
     enums
       enum E @5
         supertype: Enum
@@ -20841,7 +21151,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20857,7 +21167,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -20873,7 +21183,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -21411,7 +21721,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: package:test/foo.dart::@class::A::@constructor::•
+            superConstructor: package:test/foo.dart::@class::A::@constructor::new
 ''');
     var typeA = library.definingCompilationUnit.getClass('B')!.supertype!;
     expect(typeA.element2.source.shortName, 'foo.dart');
@@ -21444,7 +21754,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: package:test/foo_io.dart::@class::A::@constructor::•
+            superConstructor: package:test/foo_io.dart::@class::A::@constructor::new
 ''');
     var typeA = library.definingCompilationUnit.getClass('B')!.supertype!;
     expect(typeA.element2.source.shortName, 'foo_io.dart');
@@ -21477,7 +21787,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: package:test/foo_html.dart::@class::A::@constructor::•
+            superConstructor: package:test/foo_html.dart::@class::A::@constructor::new
 ''');
     var typeA = library.definingCompilationUnit.getClass('B')!.supertype!;
     expect(typeA.element2.source.shortName, 'foo_html.dart');
@@ -22353,14 +22663,14 @@
 
     var T = F.typeParameters[0];
     expect(T.name, 'T');
-    expect(T.enclosingElement3, same(F));
+    expect(T.enclosingElement, same(F));
 
     var function = F.aliasedElement as GenericFunctionTypeElement;
-    expect(function.enclosingElement3, same(F));
+    expect(function.enclosingElement, same(F));
 
     var a = function.parameters[0];
     expect(a.name, 'a');
-    expect(a.enclosingElement3, same(function));
+    expect(a.enclosingElement, same(function));
   }
 
   test_functionTypeAlias_type_element() async {
@@ -23000,7 +23310,7 @@
               leftParenthesis: ( @55
               rightParenthesis: ) @56
             element: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int Function(String)}
         constructors
           synthetic @-1
@@ -23072,7 +23382,7 @@
               leftParenthesis: ( @55
               rightParenthesis: ) @56
             element: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int Function(String)}
         type: int
     accessors
@@ -23156,7 +23466,7 @@
                   rightBracket: > @66
                 type: A<String Function({int? a})>
               staticElement: ConstructorMember
-                base: self::@class::A::@constructor::•
+                base: self::@class::A::@constructor::new
                 substitution: {T: String Function({int? a})}
             argumentList: ArgumentList
               leftParenthesis: ( @67
@@ -23238,7 +23548,7 @@
                   rightBracket: > @66
                 type: A<String Function([int?])>
               staticElement: ConstructorMember
-                base: self::@class::A::@constructor::•
+                base: self::@class::A::@constructor::new
                 substitution: {T: String Function([int?])}
             argumentList: ArgumentList
               leftParenthesis: ( @67
@@ -23320,7 +23630,7 @@
                   rightBracket: > @74
                 type: A<String Function({required int a})>
               staticElement: ConstructorMember
-                base: self::@class::A::@constructor::•
+                base: self::@class::A::@constructor::new
                 substitution: {T: String Function({required int a})}
             argumentList: ArgumentList
               leftParenthesis: ( @75
@@ -23396,7 +23706,7 @@
                   rightBracket: > @63
                 type: A<String Function(int)>
               staticElement: ConstructorMember
-                base: self::@class::A::@constructor::•
+                base: self::@class::A::@constructor::new
                 substitution: {T: String Function(int)}
             argumentList: ArgumentList
               leftParenthesis: ( @64
@@ -23454,9 +23764,9 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::A::@constructor::•
+                staticElement: self::@class::A::@constructor::new
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: void Function()}
     mixins
       mixin M @20
@@ -23507,18 +23817,18 @@
 
     var T = F.typeParameters[0];
     expect(T.name, 'T');
-    expect(T.enclosingElement3, same(F));
+    expect(T.enclosingElement, same(F));
 
     var function = F.aliasedElement as GenericFunctionTypeElement;
-    expect(function.enclosingElement3, same(F));
+    expect(function.enclosingElement, same(F));
 
     var U = function.typeParameters[0];
     expect(U.name, 'U');
-    expect(U.enclosingElement3, same(function));
+    expect(U.enclosingElement, same(function));
 
     var a = function.parameters[0];
     expect(a.name, 'a');
-    expect(a.enclosingElement3, same(function));
+    expect(a.enclosingElement, same(function));
   }
 
   test_genericTypeAlias_recursive() async {
@@ -23626,7 +23936,7 @@
             type: int
         constructors
           synthetic @-1
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
         accessors
           get f @24
             returnType: int
@@ -23718,7 +24028,7 @@
                     ImplicitCallReference
                       expression: SimpleIdentifier
                         token: c @68
-                        staticElement: self::@class::D::@constructor::•::@parameter::c
+                        staticElement: self::@class::D::@constructor::new::@parameter::c
                         staticType: C
                       staticElement: self::@class::C::@method::call
                       staticType: void Function()
@@ -23857,7 +24167,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: package:test/foo.dart::@class::A::@constructor::•
+            superConstructor: package:test/foo.dart::@class::A::@constructor::new
 ''');
     var typeA = library.definingCompilationUnit.getClass('B')!.supertype!;
     expect(typeA.element2.source.shortName, 'foo.dart');
@@ -23888,7 +24198,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: package:test/foo_io.dart::@class::A::@constructor::•
+            superConstructor: package:test/foo_io.dart::@class::A::@constructor::new
 ''');
     var typeA = library.definingCompilationUnit.getClass('B')!.supertype!;
     expect(typeA.element2.source.shortName, 'foo_io.dart');
@@ -23919,7 +24229,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: package:test/foo_io.dart::@class::A::@constructor::•
+            superConstructor: package:test/foo_io.dart::@class::A::@constructor::new
 ''');
     var typeA = library.definingCompilationUnit.getClass('B')!.supertype!;
     expect(typeA.element2.source.shortName, 'foo_io.dart');
@@ -23950,7 +24260,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: package:test/foo_html.dart::@class::A::@constructor::•
+            superConstructor: package:test/foo_html.dart::@class::A::@constructor::new
 ''');
     var typeA = library.definingCompilationUnit.getClass('B')!.supertype!;
     expect(typeA.element2.source.shortName, 'foo_html.dart');
@@ -23981,7 +24291,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: package:test/foo_html.dart::@class::A::@constructor::•
+            superConstructor: package:test/foo_html.dart::@class::A::@constructor::new
 ''');
     var typeA = library.definingCompilationUnit.getClass('B')!.supertype!;
     expect(typeA.element2.source.shortName, 'foo_html.dart');
@@ -24134,14 +24444,6 @@
     addSource('$testPackageLibPath/a.dart', 'library a; class C {}');
     var library = await buildLibrary('import "a.dart" as a; a.C c;');
 
-    // TODO(scheglov) Remove when removing `imports`.
-    {
-      // ignore: deprecated_member_use_from_same_package
-      final prefixElement = library.imports[0].prefix!;
-      expect(prefixElement.nameOffset, 19);
-      expect(prefixElement.nameLength, 1);
-    }
-
     final prefixElement = library.libraryImports[0].prefix!.element;
     expect(prefixElement.nameOffset, 19);
 
@@ -24187,7 +24489,7 @@
         supertype: C
         constructors
           synthetic @-1
-            superConstructor: self::@class::C::@constructor::•
+            superConstructor: self::@class::C::@constructor::new
 ''');
   }
 
@@ -24338,7 +24640,7 @@
                   staticType: null
                 type: C<int>
               staticElement: ConstructorMember
-                base: self::@class::C::@constructor::•
+                base: self::@class::C::@constructor::new
                 substitution: {V: int}
             argumentList: ArgumentList
               leftParenthesis: ( @129
@@ -24407,7 +24709,7 @@
                   staticElement: self::@class::C
                   staticType: null
                 type: C
-              staticElement: self::@class::C::@constructor::•
+              staticElement: self::@class::C::@constructor::new
             argumentList: ArgumentList
               leftParenthesis: ( @112
               arguments
@@ -24451,7 +24753,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
       class S @40
         typeParameters
           covariant T @42
@@ -24529,7 +24831,7 @@
         supertype: C
         constructors
           synthetic @-1
-            superConstructor: self::@class::C::@constructor::•
+            superConstructor: self::@class::C::@constructor::new
     topLevelVariables
       static a @111
         type: A
@@ -24927,7 +25229,7 @@
               alias: self::@typeAlias::F
         constructors
           synthetic @-1
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
         accessors
           synthetic get v @-1
             returnType: int Function(String)
@@ -25084,7 +25386,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::D::@constructor::•
+              base: self::@class::D::@constructor::new
               substitution: {U: int, V: T}
         accessors
           synthetic get v @-1
@@ -25174,7 +25476,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::D::@constructor::•
+              base: self::@class::D::@constructor::new
               substitution: {V: U, W: int}
         methods
           f @41
@@ -25232,7 +25534,7 @@
         supertype: D
         constructors
           synthetic @-1
-            superConstructor: package:test/a.dart::@class::D::@constructor::•
+            superConstructor: package:test/a.dart::@class::D::@constructor::new
         methods
           f @44
             parameters
@@ -25255,7 +25557,7 @@
         supertype: D
         constructors
           synthetic @-1
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
         methods
           f @25
             parameters
@@ -25361,7 +25663,7 @@
             type: int Function(String)
         constructors
           synthetic @-1
-            superConstructor: self::@class::D::@constructor::•
+            superConstructor: self::@class::D::@constructor::new
         accessors
           set f @29
             parameters
@@ -25409,7 +25711,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: package:test/a.dart::@class::A::@constructor::•
+            superConstructor: package:test/a.dart::@class::A::@constructor::new
         methods
           m @39
             parameters
@@ -25423,9 +25725,7 @@
     // when the type is defined in a part of an SDK library. So, test that
     // the type is actually in a part.
     final streamElement = (p.type as InterfaceType).element2;
-    if (streamElement is ClassElement) {
-      expect(streamElement.source, isNot(streamElement.library.source));
-    }
+    expect(streamElement.source, isNot(streamElement.library.source));
   }
 
   test_inferredType_implicitCreation() async {
@@ -25597,7 +25897,7 @@
             type: dynamic
         constructors
           synthetic @-1
-            superConstructor: self::@class::C::@constructor::•
+            superConstructor: self::@class::C::@constructor::new
         accessors
           synthetic get f @-1
             returnType: dynamic
@@ -25799,7 +26099,7 @@
         supertype: LegacyDefault*
         constructors
           synthetic @-1
-            superConstructor: package:test/legacy.dart::@class::LegacyDefault::@constructor::•
+            superConstructor: package:test/legacy.dart::@class::LegacyDefault::@constructor::new
         methods
           == @86
             parameters
@@ -25810,7 +26110,7 @@
         supertype: LegacyObject*
         constructors
           synthetic @-1
-            superConstructor: package:test/legacy.dart::@class::LegacyObject::@constructor::•
+            superConstructor: package:test/legacy.dart::@class::LegacyObject::@constructor::new
         methods
           == @155
             parameters
@@ -25821,7 +26121,7 @@
         supertype: LegacyInt*
         constructors
           synthetic @-1
-            superConstructor: package:test/legacy.dart::@class::LegacyInt::@constructor::•
+            superConstructor: package:test/legacy.dart::@class::LegacyInt::@constructor::new
         methods
           == @221
             parameters
@@ -25882,7 +26182,7 @@
           NullSafeDefault*
         constructors
           synthetic @-1
-            superConstructor: package:test/legacy.dart::@class::LegacyDefault::@constructor::•
+            superConstructor: package:test/legacy.dart::@class::LegacyDefault::@constructor::new
         methods
           == @136
             parameters
@@ -25895,7 +26195,7 @@
           NullSafeObject*
         constructors
           synthetic @-1
-            superConstructor: package:test/legacy.dart::@class::LegacyObject::@constructor::•
+            superConstructor: package:test/legacy.dart::@class::LegacyObject::@constructor::new
         methods
           == @231
             parameters
@@ -25908,7 +26208,7 @@
           NullSafeInt*
         constructors
           synthetic @-1
-            superConstructor: package:test/legacy.dart::@class::LegacyInt::@constructor::•
+            superConstructor: package:test/legacy.dart::@class::LegacyInt::@constructor::new
         methods
           == @320
             parameters
@@ -25952,7 +26252,7 @@
         supertype: NullSafeDefault
         constructors
           synthetic @-1
-            superConstructor: package:test/nullSafe.dart::@class::NullSafeDefault::@constructor::•
+            superConstructor: package:test/nullSafe.dart::@class::NullSafeDefault::@constructor::new
         methods
           == @74
             parameters
@@ -25963,7 +26263,7 @@
         supertype: NullSafeObject
         constructors
           synthetic @-1
-            superConstructor: package:test/nullSafe.dart::@class::NullSafeObject::@constructor::•
+            superConstructor: package:test/nullSafe.dart::@class::NullSafeObject::@constructor::new
         methods
           == @145
             parameters
@@ -25974,7 +26274,7 @@
         supertype: NullSafeInt
         constructors
           synthetic @-1
-            superConstructor: package:test/nullSafe.dart::@class::NullSafeInt::@constructor::•
+            superConstructor: package:test/nullSafe.dart::@class::NullSafeInt::@constructor::new
         methods
           == @213
             parameters
@@ -26693,7 +26993,7 @@
 
     final import_0 = library.augmentationImports[0];
     final augmentation = import_0.importedAugmentation!;
-    expect(augmentation.enclosingElement3, same(library));
+    expect(augmentation.enclosingElement, same(library));
   }
 
   test_library_augmentationImports_noRelativeUriStr() async {
@@ -27366,8 +27666,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::C::@constructor::•
-            superConstructor: self::@class::C::@constructor::•
+                staticElement: self::@class::C::@constructor::new
+            superConstructor: self::@class::C::@constructor::new
       class C @29
         constructors
           synthetic @-1
@@ -27847,8 +28147,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @45
         constructors
           synthetic @-1
@@ -28369,7 +28669,7 @@
                   literal: 0 @33
                   staticType: int
               rightParenthesis: ) @34
-            element: self::@class::A::@constructor::•
+            element: self::@class::A::@constructor::new
         constructors
           synthetic @-1
 ''');
@@ -28413,7 +28713,7 @@
                   staticType: int
               rightParenthesis: ) @36
             element: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int}
         constructors
           synthetic @-1
@@ -28461,7 +28761,7 @@
               leftParenthesis: ( @36
               rightParenthesis: ) @37
             element: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int}
         constructors
           synthetic @-1
@@ -28501,7 +28801,7 @@
                   literal: 0 @33
                   staticType: int
               rightParenthesis: ) @34
-            element: package:test/foo.dart::@class::A::@constructor::•
+            element: package:test/foo.dart::@class::A::@constructor::new
         constructors
           synthetic @-1
 ''');
@@ -28548,7 +28848,7 @@
                   staticType: int
               rightParenthesis: ) @34
             element: ConstructorMember
-              base: package:test/foo.dart::@class::A::@constructor::•
+              base: package:test/foo.dart::@class::A::@constructor::new
               substitution: {T: int}
         constructors
           synthetic @-1
@@ -28602,7 +28902,7 @@
               leftParenthesis: ( @37
               rightParenthesis: ) @38
             element: ConstructorMember
-              base: package:test/foo.dart::@class::A::@constructor::•
+              base: package:test/foo.dart::@class::A::@constructor::new
               substitution: {T: int}
         constructors
           synthetic @-1
@@ -28644,8 +28944,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::A::@constructor::•
-            superConstructor: self::@class::A::@constructor::•
+                staticElement: self::@class::A::@constructor::new
+            superConstructor: self::@class::A::@constructor::new
       class D @73
         metadata
           Annotation
@@ -28658,7 +28958,7 @@
               leftParenthesis: ( @64
               rightParenthesis: ) @65
             element: ConstructorMember
-              base: self::@class::C::@constructor::•
+              base: self::@class::C::@constructor::new
               substitution: {T: dynamic}
         constructors
           synthetic @-1
@@ -28697,7 +28997,7 @@
                   literal: null @27
                   staticType: Null
               rightParenthesis: ) @31
-            element: self::@class::A::@constructor::•
+            element: self::@class::A::@constructor::new
         constructors
           synthetic @-1
 ''');
@@ -28794,7 +29094,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -28880,7 +29180,7 @@
                       literal: 100 @73
                       staticType: int
                   rightParenthesis: ) @76
-                element: self::@class::A::@constructor::•
+                element: self::@class::A::@constructor::new
             type: E
             constantInitializer
               InstanceCreationExpression
@@ -28891,7 +29191,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -28907,7 +29207,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -28927,7 +29227,7 @@
                       literal: 300 @91
                       staticType: int
                   rightParenthesis: ) @94
-                element: self::@class::A::@constructor::•
+                element: self::@class::A::@constructor::new
             type: E
             constantInitializer
               InstanceCreationExpression
@@ -28938,7 +29238,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -29010,7 +29310,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -29064,7 +29364,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -29136,7 +29436,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -29234,7 +29534,7 @@
                       staticType: null
                     type: E<dynamic>
                   staticElement: ConstructorMember
-                    base: self::@enum::E::@constructor::•
+                    base: self::@enum::E::@constructor::new
                     substitution: {T: dynamic}
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -29328,7 +29628,7 @@
                       staticType: null
                     type: E<dynamic>
                   staticElement: ConstructorMember
-                    base: self::@enum::E::@constructor::•
+                    base: self::@enum::E::@constructor::new
                     substitution: {T: dynamic}
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
@@ -29394,7 +29694,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -29570,7 +29870,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @37
               rightParenthesis: ) @38
-            element: dart:core::@class::Object::@constructor::•
+            element: dart:core::@class::Object::@constructor::new
         extendedType: A
     topLevelVariables
       static const a @6
@@ -30895,8 +31195,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::A::@constructor::•
-            superConstructor: self::@class::A::@constructor::•
+                staticElement: self::@class::A::@constructor::new
+            superConstructor: self::@class::A::@constructor::new
     mixins
       mixin M @33
         superclassConstraints
@@ -30959,7 +31259,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -30975,7 +31275,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -30999,7 +31299,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -31909,8 +32209,8 @@
                       staticElement: self::@getter::a
                       staticType: null
                     element: self::@getter::a
-                superConstructorParameter: self::@class::A::@constructor::•::@parameter::x
-            superConstructor: self::@class::A::@constructor::•
+                superConstructorParameter: self::@class::A::@constructor::new::@parameter::x
+            superConstructor: self::@class::A::@constructor::new
     topLevelVariables
       static const a @6
         type: dynamic
@@ -32025,8 +32325,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::D::@constructor::•
-            superConstructor: self::@class::D::@constructor::•
+                staticElement: self::@class::D::@constructor::new
+            superConstructor: self::@class::D::@constructor::new
       class D @48
         constructors
           synthetic @-1
@@ -32246,7 +32546,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -32262,7 +32562,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -32278,7 +32578,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -32685,7 +32985,7 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: dart:core::@class::Object::@constructor::•
+                staticElement: dart:core::@class::Object::@constructor::new
       class alias C @51
         supertype: A<int>
         mixins
@@ -32698,9 +32998,9 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::A::@constructor::•
+                staticElement: self::@class::A::@constructor::new
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int}
 ''');
   }
@@ -32750,7 +33050,7 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: dart:core::@class::Object::@constructor::•
+                staticElement: dart:core::@class::Object::@constructor::new
       class Base @75
         interfaces
           A1<int>
@@ -32768,8 +33068,8 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::Base::@constructor::•
-            superConstructor: self::@class::Base::@constructor::•
+                staticElement: self::@class::Base::@constructor::new
+            superConstructor: self::@class::Base::@constructor::new
 ''');
   }
 
@@ -32797,7 +33097,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int*}
     mixins
       mixin M @35
@@ -32832,7 +33132,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int Function(String)}
     mixins
       mixin M @20
@@ -32869,7 +33169,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: List<int>}
     mixins
       mixin M @29
@@ -32904,7 +33204,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int}
     mixins
       mixin M @20
@@ -32943,7 +33243,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: package:test/a.dart::@class::A::@constructor::•
+              base: package:test/a.dart::@class::A::@constructor::new
               substitution: {T: int*}
 ''');
   }
@@ -32971,7 +33271,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: package:test/a.dart::@class::A::@constructor::•
+              base: package:test/a.dart::@class::A::@constructor::new
               substitution: {T: int*}
 ''');
   }
@@ -33027,9 +33327,9 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: self::@class::I::@constructor::•
+                staticElement: self::@class::I::@constructor::new
             superConstructor: ConstructorMember
-              base: self::@class::I::@constructor::•
+              base: self::@class::I::@constructor::new
               substitution: {X: int}
     mixins
       mixin M1 @20
@@ -33077,7 +33377,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::S::@constructor::•
+              base: self::@class::S::@constructor::new
               substitution: {T3: String}
     mixins
       mixin M @6
@@ -33129,7 +33429,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::S::@constructor::•
+              base: self::@class::S::@constructor::new
               substitution: {T4: String}
     mixins
       mixin M @6
@@ -34092,7 +34392,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -34109,7 +34409,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -34513,7 +34813,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: T}
         methods
           f @75
@@ -34550,7 +34850,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @68
             parameters
@@ -35101,6 +35401,19 @@
 ''');
   }
 
+  test_recordType_topFunction_returnType_positional_one() async {
+    var library = await buildLibrary('''
+(int,) f() {}
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    functions
+      f @7
+        returnType: (int)
+''');
+  }
+
   test_recordType_topVariable() async {
     var library = await buildLibrary('''
 final (int, String) x;
@@ -35755,12 +36068,12 @@
                   arguments
                     SimpleIdentifier
                       token: value @-1
-                      staticElement: self::@class::B::@constructor::•::@parameter::value
+                      staticElement: self::@class::B::@constructor::new::@parameter::value
                       staticType: T
                   rightParenthesis: ) @0
-                staticElement: self::@class::A::@constructor::•
+                staticElement: self::@class::A::@constructor::new
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: T}
       class C @78
         fields
@@ -35977,7 +36290,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
       class C @40
         typeParameters
           covariant T @42
@@ -36336,7 +36649,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -36463,7 +36776,7 @@
                         staticElement: self::@enum::E
                         staticType: null
                       type: E
-                    staticElement: self::@enum::E::@constructor::•
+                    staticElement: self::@enum::E::@constructor::new
                   argumentList: ArgumentList
                     leftParenthesis: ( @0
                     rightParenthesis: ) @0
@@ -36523,7 +36836,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -36621,7 +36934,7 @@
                         staticElement: self::@enum::E
                         staticType: null
                       type: E
-                    staticElement: self::@enum::E::@constructor::•
+                    staticElement: self::@enum::E::@constructor::new
                   argumentList: ArgumentList
                     leftParenthesis: ( @0
                     rightParenthesis: ) @0
@@ -36716,7 +37029,7 @@
                         staticElement: self::@enum::E
                         staticType: null
                       type: E
-                    staticElement: self::@enum::E::@constructor::•
+                    staticElement: self::@enum::E::@constructor::new
                   argumentList: ArgumentList
                     leftParenthesis: ( @0
                     rightParenthesis: ) @0
@@ -36879,7 +37192,7 @@
                       staticElement: self::@enum::E
                       staticType: null
                     type: E
-                  staticElement: self::@enum::E::@constructor::•
+                  staticElement: self::@enum::E::@constructor::new
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
@@ -39218,7 +39531,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int}
     typeAliases
       X @8
@@ -39250,7 +39563,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int}
     typeAliases
       X @8
@@ -39326,7 +39639,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int?}
     typeAliases
       X @8
@@ -39853,7 +40166,7 @@
                   superKeyword: super @30
                   staticType: dynamic
               rightParenthesis: ) @35
-            element: self::@class::A::@constructor::•
+            element: self::@class::A::@constructor::new
         constructors
           synthetic @-1
 ''');
@@ -39893,7 +40206,7 @@
                   thisKeyword: this @30
                   staticType: dynamic
               rightParenthesis: ) @34
-            element: self::@class::A::@constructor::•
+            element: self::@class::A::@constructor::new
         constructors
           synthetic @-1
 ''');
@@ -41008,7 +41321,7 @@
                   staticType: null
                 type: A<int>
               staticElement: ConstructorMember
-                base: self::@class::A::@constructor::•
+                base: self::@class::A::@constructor::new
                 substitution: {T: int}
             argumentList: ArgumentList
               leftParenthesis: ( @46
diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart
index f096fe7..02adda9 100644
--- a/pkg/analyzer/test/src/summary/macro_test.dart
+++ b/pkg/analyzer/test/src/summary/macro_test.dart
@@ -402,7 +402,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @26
               rightParenthesis: ) @27
-            element: package:test/a.dart::@class::MyMacro::@constructor::•
+            element: package:test/a.dart::@class::MyMacro::@constructor::new
         constructors
           synthetic @-1
   parts
@@ -547,7 +547,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @43
               rightParenthesis: ) @44
-            element: package:test/a.dart::@class::MyMacro::@constructor::•
+            element: package:test/a.dart::@class::MyMacro::@constructor::new
         constructors
           synthetic @-1
   parts
@@ -923,7 +923,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @26
               rightParenthesis: ) @27
-            element: package:test/a.dart::@class::MyMacro::@constructor::•
+            element: package:test/a.dart::@class::MyMacro::@constructor::new
         constructors
           synthetic @-1
           named @-1
@@ -975,7 +975,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @26
               rightParenthesis: ) @27
-            element: package:test/a.dart::@class::MyMacro::@constructor::•
+            element: package:test/a.dart::@class::MyMacro::@constructor::new
         fields
           foo @-1
             type: int
@@ -1034,7 +1034,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @26
               rightParenthesis: ) @27
-            element: package:test/a.dart::@class::MyMacro::@constructor::•
+            element: package:test/a.dart::@class::MyMacro::@constructor::new
         fields
           synthetic foo @-1
             type: int
@@ -1088,7 +1088,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @26
               rightParenthesis: ) @27
-            element: package:test/a.dart::@class::MyMacro::@constructor::•
+            element: package:test/a.dart::@class::MyMacro::@constructor::new
         constructors
           synthetic @-1
         methods
@@ -1142,7 +1142,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @26
               rightParenthesis: ) @27
-            element: package:test/a.dart::@class::MyMacro::@constructor::•
+            element: package:test/a.dart::@class::MyMacro::@constructor::new
         fields
           synthetic foo @-1
             type: int
@@ -1724,7 +1724,7 @@
                 argumentList: ArgumentList
                   leftParenthesis: ( @0
                   rightParenthesis: ) @0
-                staticElement: dart:core::@class::Object::@constructor::•
+                staticElement: dart:core::@class::Object::@constructor::new
     mixins
       mixin M @6
         superclassConstraints
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 8a18121..f263bc3 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -156,6 +157,14 @@
   }
 
   @override
+  void visitBinaryPattern(BinaryPattern node) {
+    _writeln('BinaryPattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitBlock(Block node) {
     _writeln('Block');
     _withIndent(() {
@@ -200,6 +209,22 @@
   }
 
   @override
+  void visitCaseClause(CaseClause node) {
+    _writeln('CaseClause');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
+  void visitCastPattern(CastPattern node) {
+    _writeln('CastPattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitCatchClause(CatchClause node) {
     _writeln('CatchClause');
     _withIndent(() {
@@ -213,7 +238,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -224,7 +249,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -277,12 +302,20 @@
   }
 
   @override
+  void visitConstantPattern(ConstantPattern node) {
+    _writeln('ConstantPattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     _writeln('ConstructorDeclaration');
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -337,7 +370,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -407,7 +440,7 @@
       _writeNamedChildEntities(node);
       if (_withResolution) {
         _writeElement('constructorElement', node.constructorElement);
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -418,7 +451,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -462,7 +495,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -479,12 +512,20 @@
   }
 
   @override
+  void visitExtractorPattern(ExtractorPattern node) {
+    _writeln('ExtractorPattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitFieldDeclaration(FieldDeclaration node) {
     _writeln('FieldDeclaration');
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -555,8 +596,8 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
-        _writeType('declaredElementType', node.declaredElement2!.type);
+        _writeElement('declaredElement', node.declaredElement);
+        _writeType('declaredElementType', node.declaredElement!.type);
       }
     });
   }
@@ -611,7 +652,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -649,7 +690,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -811,6 +852,14 @@
   }
 
   @override
+  void visitListPattern(ListPattern node) {
+    _writeln('ListPattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitMapLiteralEntry(MapLiteralEntry node) {
     _writeln('SetOrMapLiteral');
     _withIndent(() {
@@ -819,13 +868,29 @@
   }
 
   @override
+  void visitMapPattern(MapPattern node) {
+    _writeln('MapPattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
+  void visitMapPatternEntry(MapPatternEntry node) {
+    _writeln('MapPatternEntry');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitMethodDeclaration(MethodDeclaration node) {
     _writeln('MethodDeclaration');
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
-        _writeType('declaredElementType', node.declaredElement2!.type);
+        _writeElement('declaredElement', node.declaredElement);
+        _writeType('declaredElementType', node.declaredElement!.type);
       }
     });
   }
@@ -848,7 +913,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -900,6 +965,14 @@
   }
 
   @override
+  void visitParenthesizedPattern(ParenthesizedPattern node) {
+    _writeln('ParenthesizedPattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitPartDirective(PartDirective node) {
     _writeln('PartDirective');
     _withIndent(() {
@@ -935,6 +1008,14 @@
   }
 
   @override
+  void visitPostfixPattern(PostfixPattern node) {
+    _writeln('PostfixPattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitPrefixedIdentifier(PrefixedIdentifier node) {
     _writeln('PrefixedIdentifier');
     _withIndent(() {
@@ -982,6 +1063,30 @@
   }
 
   @override
+  void visitRecordPattern(RecordPattern node) {
+    _writeln('RecordPattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
+  void visitRecordPatternField(RecordPatternField node) {
+    _writeln('RecordPatternField');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
+  void visitRecordPatternFieldName(RecordPatternFieldName node) {
+    _writeln('RecordPatternFieldName');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitRecordTypeAnnotation(RecordTypeAnnotation node) {
     _writeln('RecordTypeAnnotation');
     _withIndent(() {
@@ -1029,6 +1134,14 @@
   }
 
   @override
+  void visitRelationalPattern(RelationalPattern node) {
+    _writeln('RelationalPattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitReturnStatement(ReturnStatement node) {
     _writeln('ReturnStatement');
     _withIndent(() {
@@ -1061,7 +1174,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement);
+        _writeDeclaredElement(node, node.declaredElement);
         _writeType('declaredElementType', node.declaredElement!.type);
       }
     });
@@ -1136,7 +1249,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement);
+        _writeDeclaredElement(node, node.declaredElement);
         _writeType('declaredElementType', node.declaredElement!.type);
       }
     });
@@ -1159,6 +1272,14 @@
   }
 
   @override
+  void visitSwitchPatternCase(SwitchPatternCase node) {
+    _writeln('SwitchPatternCase');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+    });
+  }
+
+  @override
   void visitSwitchStatement(SwitchStatement node) {
     _writeln('SwitchStatement');
     _withIndent(() {
@@ -1201,7 +1322,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -1238,7 +1359,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -1257,7 +1378,7 @@
     _withIndent(() {
       _writeNamedChildEntities(node);
       if (_withResolution) {
-        _writeElement('declaredElement', node.declaredElement2);
+        _writeElement('declaredElement', node.declaredElement);
       }
     });
   }
@@ -1279,6 +1400,28 @@
   }
 
   @override
+  void visitVariablePattern(VariablePattern node) {
+    _writeln('VariablePattern');
+    _withIndent(() {
+      _writeNamedChildEntities(node);
+      if (_withResolution) {
+        final element = node.declaredElement;
+        if (element != null) {
+          element as VariablePatternElementImpl;
+          _sink.write(_indent);
+          _sink.write('declaredElement: ');
+          _writeIf(element.hasImplicitType, 'hasImplicitType ');
+          _writeIf(element.isFinal, 'isFinal ');
+          _sink.writeln('${element.name}@${element.nameOffset}');
+          _withIndent(() {
+            _writeType('type', element.type);
+          });
+        }
+      }
+    });
+  }
+
+  @override
   void visitWhileStatement(WhileStatement node) {
     _writeln('WhileStatement');
     _withIndent(() {
@@ -1354,7 +1497,7 @@
   }
 
   String _elementToReferenceString(Element element) {
-    final enclosingElement = element.enclosingElement3;
+    final enclosingElement = element.enclosingElement;
     final reference = (element as ElementImpl).reference;
     if (reference != null) {
       return _referenceToString(reference);
@@ -1394,7 +1537,7 @@
 
     var name = reference.name;
     if (name.isEmpty) {
-      name = '•';
+      fail('Currently every reference must have a name');
     }
     return '${_referenceToString(parent)}::$name';
   }
@@ -1430,6 +1573,17 @@
     });
   }
 
+  void _writeDeclaredElement(AstNode node, Element? declaredElement) {
+    if (_withResolution) {
+      if (node is FormalParameter) {
+        final expected = _expectedFormalParameterElements(node);
+        _assertHasIdenticalElement(expected, declaredElement);
+      }
+    }
+
+    _writeElement('declaredElement', declaredElement);
+  }
+
   void _writeDirectiveUri(DirectiveUri? uri) {
     if (uri == null) {
       _writeln('<null>');
@@ -1533,6 +1687,12 @@
     }
   }
 
+  void _writeIf(bool flag, String str) {
+    if (flag) {
+      _sink.write(str);
+    }
+  }
+
   void _writeLibraryExportElement(LibraryExportElement element) {
     _writeln('LibraryExportElement');
     _withIndent(() {
@@ -1696,6 +1856,15 @@
     }
   }
 
+  static void _assertHasIdenticalElement<T>(List<T> elements, T expected) {
+    for (final element in elements) {
+      if (identical(element, expected)) {
+        return;
+      }
+    }
+    fail('No $expected in $elements');
+  }
+
   static Token _entityBeginToken(SyntacticEntity entity) {
     if (entity is Token) {
       return entity;
@@ -1716,6 +1885,35 @@
     }
   }
 
+  /// Every [FormalParameter] declares an element, and this element must be
+  /// in the list of formal parameter elements of some declaration, e.g. of
+  /// [ConstructorDeclaration], [MethodDeclaration], or a local
+  /// [FunctionDeclaration].
+  static List<ParameterElement> _expectedFormalParameterElements(
+    FormalParameter node,
+  ) {
+    final parametersParent = node.parentFormalParameterList.parent;
+    if (parametersParent is ConstructorDeclaration) {
+      final declaredElement = parametersParent.declaredElement!;
+      return declaredElement.parameters;
+    } else if (parametersParent is FormalParameter) {
+      final declaredElement = parametersParent.declaredElement!;
+      return declaredElement.parameters;
+    } else if (parametersParent is FunctionExpression) {
+      final declaredElement = parametersParent.declaredElement!;
+      return declaredElement.parameters;
+    } else if (parametersParent is GenericFunctionTypeImpl) {
+      final declaredElement = parametersParent.declaredElement!;
+      return declaredElement.parameters;
+    } else if (parametersParent is MethodDeclaration) {
+      final declaredElement = parametersParent.declaredElement!;
+      return declaredElement.parameters;
+    }
+    throw UnimplementedError(
+      '(${parametersParent.runtimeType}) $parametersParent',
+    );
+  }
+
   static String _nameOfMemberClass(Member member) {
     return '${member.runtimeType}';
   }
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index 8b4204f..c711ccb 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -19,6 +19,8 @@
 }
 
 @reflectiveTest
+// TODO(srawlins): Re-enable?
+// ignore: unreachable_from_main
 class ApplyCheckElementTextReplacements {
   test_applyReplacements() {
     applyCheckElementTextReplacements();
@@ -1663,7 +1665,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           foo @52
             returnType: int
@@ -4717,7 +4719,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int}
         accessors
           get x @114
@@ -4905,7 +4907,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @58
             parameters
@@ -4957,7 +4959,7 @@
           B
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @100
             typeInferenceError: overrideNoCombinedSuperSignature
@@ -5108,7 +5110,7 @@
           B
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @88
             typeInferenceError: overrideNoCombinedSuperSignature
@@ -5163,7 +5165,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {T: int}
         methods
           m @112
@@ -5224,7 +5226,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {K: int, V: String}
         methods
           m @119
@@ -5262,7 +5264,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @53
             parameters
@@ -5300,7 +5302,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @53
             parameters
@@ -5338,7 +5340,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @44
             parameters
@@ -5374,7 +5376,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @63
             parameters
@@ -5415,7 +5417,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @48
             parameters
@@ -5461,14 +5463,14 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {K: int, V: T}
       class C @70
         supertype: B<String>
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::B::@constructor::•
+              base: self::@class::B::@constructor::new
               substitution: {T: String}
         methods
           m @94
@@ -5508,7 +5510,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @55
             parameters
@@ -5519,7 +5521,7 @@
         supertype: B
         constructors
           synthetic @-1
-            superConstructor: self::@class::B::@constructor::•
+            superConstructor: self::@class::B::@constructor::new
         methods
           m @87
             parameters
@@ -5569,7 +5571,7 @@
         supertype: B
         constructors
           synthetic @-1
-            superConstructor: self::@class::B::@constructor::•
+            superConstructor: self::@class::B::@constructor::new
         methods
           m @90
             parameters
@@ -5620,7 +5622,7 @@
         supertype: B
         constructors
           synthetic @-1
-            superConstructor: self::@class::B::@constructor::•
+            superConstructor: self::@class::B::@constructor::new
         methods
           m @99
             parameters
@@ -5664,7 +5666,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {K: int, V: String}
         methods
           m @77
@@ -5703,7 +5705,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @55
             parameters
@@ -5741,7 +5743,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @67
             parameters
@@ -5781,7 +5783,7 @@
         supertype: A
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @67
             parameters
@@ -5829,14 +5831,14 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {K: int, V: T}
       class C @70
         supertype: B<String>
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::B::@constructor::•
+              base: self::@class::B::@constructor::new
               substitution: {T: String}
         methods
           m @94
@@ -5962,7 +5964,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {K: T2, V: T1}
       class C @91
         interfaces
@@ -6008,7 +6010,7 @@
         supertype: A1
         constructors
           synthetic @-1
-            superConstructor: self::@class::A1::@constructor::•
+            superConstructor: self::@class::A1::@constructor::new
         methods
           _foo @77
             returnType: int
@@ -6101,7 +6103,7 @@
         constructors
           synthetic @-1
             superConstructor: ConstructorMember
-              base: self::@class::A::@constructor::•
+              base: self::@class::A::@constructor::new
               substitution: {K: int, V: String}
         methods
           m @119
@@ -6152,7 +6154,7 @@
           B
         constructors
           synthetic @-1
-            superConstructor: self::@class::A::@constructor::•
+            superConstructor: self::@class::A::@constructor::new
         methods
           m @101
             parameters
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index bf13737..2d98e22 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -452,14 +452,6 @@
 ''', [AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED]);
   }
 
-  test_analyzer_strong_mode_deprecated_key() {
-    validate('''
-analyzer:
-  strong-mode:
-    declaration-casts: false
-''', [AnalysisOptionsWarningCode.ANALYSIS_OPTION_DEPRECATED]);
-  }
-
   test_analyzer_strong_mode_error_code_supported() {
     validate('''
 analyzer:
diff --git a/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart b/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart
index 87a1477..ccd4d64 100644
--- a/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart
+++ b/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart
@@ -204,9 +204,9 @@
     await resolveTestCode(code);
     void assertTypes(
         String vSearch, String vType, String fSearch, String fType) {
-      var node = findNode.simple(vSearch);
+      var node = findNode.declaredIdentifier(vSearch);
 
-      var element = node.staticElement as LocalVariableElement;
+      var element = node.declaredElement as LocalVariableElement;
       assertType(element.type, vType);
 
       var invocation = findNode.methodInvocation(fSearch);
@@ -265,12 +265,12 @@
 var y = {};
 ''';
     await resolveTestCode(code);
-    var xNode = findNode.simple('x = ');
-    var xElement = xNode.staticElement as VariableElement;
+    var xNode = findNode.variableDeclaration('x = ');
+    var xElement = xNode.declaredElement!;
     assertType(xElement.type, 'List<dynamic>');
 
-    var yNode = findNode.simple('y = ');
-    var yElement = yNode.staticElement as VariableElement;
+    var yNode = findNode.variableDeclaration('y = ');
+    var yElement = yNode.declaredElement!;
     assertType(yElement.type, 'Map<dynamic, dynamic>');
   }
 
@@ -280,12 +280,12 @@
 var y = {null: null};
 ''';
     await resolveTestCode(code);
-    var xNode = findNode.simple('x = ');
-    var xElement = xNode.staticElement as VariableElement;
+    var xNode = findNode.variableDeclaration('x = ');
+    var xElement = xNode.declaredElement!;
     assertType(xElement.type, 'List<Null>');
 
-    var yNode = findNode.simple('y = ');
-    var yElement = yNode.staticElement as VariableElement;
+    var yNode = findNode.variableDeclaration('y = ');
+    var yElement = yNode.declaredElement!;
     assertType(yElement.type, 'Map<Null, Null>');
   }
 
@@ -319,12 +319,12 @@
 }
 ''';
     await resolveTestCode(code);
-    var xNode = findNode.simple('x = ');
-    var xElement = xNode.staticElement as VariableElement;
+    var xNode = findNode.variableDeclaration('x = ');
+    var xElement = xNode.declaredElement!;
     expect(xElement.type, VoidTypeImpl.instance);
 
-    var yNode = findNode.simple('y = ');
-    var yElement = yNode.staticElement as VariableElement;
+    var yNode = findNode.variableDeclaration('y = ');
+    var yElement = yNode.declaredElement!;
     expect(yElement.type, VoidTypeImpl.instance);
   }
 
@@ -337,12 +337,12 @@
 }
 ''';
     await resolveTestCode(code);
-    var xNode = findNode.simple('x = ');
-    var xElement = xNode.staticElement as VariableElement;
+    var xNode = findNode.variableDeclaration('x = ');
+    var xElement = xNode.declaredElement!;
     expect(xElement.type, VoidTypeImpl.instance);
 
-    var yNode = findNode.simple('y = ');
-    var yElement = yNode.staticElement as VariableElement;
+    var yNode = findNode.variableDeclaration('y = ');
+    var yElement = yNode.declaredElement!;
     expect(yElement.type, VoidTypeImpl.instance);
   }
 
diff --git a/pkg/analyzer/test/src/util/yaml_test.dart b/pkg/analyzer/test/src/util/yaml_test.dart
index 3877098..ee5aab4 100644
--- a/pkg/analyzer/test/src/util/yaml_test.dart
+++ b/pkg/analyzer/test/src/util/yaml_test.dart
@@ -100,56 +100,8 @@
 
 final Merger merger = Merger();
 
-bool containsKey(Map<dynamic, YamlNode> map, dynamic key) =>
-    _getValue(map, key) != null;
-
-void expectEquals(YamlNode? actual, YamlNode? expected) {
-  if (expected is YamlScalar) {
-    actual!;
-    expect(actual, TypeMatcher<YamlScalar>());
-    expect(expected.value, actual.value);
-  } else if (expected is YamlList) {
-    if (actual is YamlList) {
-      expect(actual.length, expected.length);
-      List<YamlNode> expectedNodes = expected.nodes;
-      List<YamlNode> actualNodes = actual.nodes;
-      for (int i = 0; i < expectedNodes.length; i++) {
-        expectEquals(actualNodes[i], expectedNodes[i]);
-      }
-    } else {
-      fail('Expected a YamlList, found ${actual.runtimeType}');
-    }
-  } else if (expected is YamlMap) {
-    if (actual is YamlMap) {
-      expect(actual.length, expected.length);
-      Map<dynamic, YamlNode> expectedNodes = expected.nodes;
-      Map<dynamic, YamlNode> actualNodes = actual.nodes;
-      for (var expectedKey in expectedNodes.keys) {
-        if (!containsKey(actualNodes, expectedKey)) {
-          fail('Missing key $expectedKey');
-        }
-      }
-      for (var actualKey in actualNodes.keys) {
-        if (!containsKey(expectedNodes, actualKey)) {
-          fail('Extra key $actualKey');
-        }
-      }
-      for (var expectedKey in expectedNodes.keys) {
-        expectEquals(_getValue(actualNodes, expectedKey),
-            _getValue(expectedNodes, expectedKey));
-      }
-    } else {
-      fail('Expected a YamlMap, found ${actual.runtimeType}');
-    }
-  } else {
-    fail('Unknown type of node: ${expected.runtimeType}');
-  }
-}
-
 Object merge(Object o1, Object o2) => merger.merge(wrap(o1), wrap(o2)).value;
 
-Object valueOf(Object object) => object is YamlNode ? object.value : object;
-
 YamlNode wrap(Object value) {
   if (value is List) {
     var wrappedElements = value.map((e) => wrap(e)).toList();
@@ -168,16 +120,6 @@
   }
 }
 
-YamlNode? _getValue(Map map, Object key) {
-  Object keyValue = valueOf(key);
-  for (var existingKey in map.keys) {
-    if (valueOf(existingKey) == keyValue) {
-      return map[existingKey];
-    }
-  }
-  return null;
-}
-
 class _FileSpanMock implements FileSpan {
   static final FileSpan instance = _FileSpanMock();
 
diff --git a/pkg/analyzer/test/src/utilities/extensions/collection_test.dart b/pkg/analyzer/test/src/utilities/extensions/collection_test.dart
index 0b0f9f2..c530c63 100644
--- a/pkg/analyzer/test/src/utilities/extensions/collection_test.dart
+++ b/pkg/analyzer/test/src/utilities/extensions/collection_test.dart
@@ -28,6 +28,8 @@
 }
 
 @reflectiveTest
+// TODO(srawlins): Re-enable?
+// ignore: unreachable_from_main
 class SetExtensionTest {
   test_addIfNotNull_notNull() {
     var elements = {0, 1};
diff --git a/pkg/analyzer/test/src/utilities/extensions/string_test.dart b/pkg/analyzer/test/src/utilities/extensions/string_test.dart
index c6c480b..6d8edef 100644
--- a/pkg/analyzer/test/src/utilities/extensions/string_test.dart
+++ b/pkg/analyzer/test/src/utilities/extensions/string_test.dart
@@ -9,6 +9,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(IterableOfStringExtensionTest);
+    defineReflectiveTests(StringExtensionTest);
   });
 }
 
@@ -80,3 +81,14 @@
     expect(<String>[].quotedAndCommaSeparatedWithAnd, isEmpty);
   }
 }
+
+@reflectiveTest
+class StringExtensionTest {
+  void test_ifNotEmptyOrElse_empty() {
+    expect(''.ifNotEmptyOrElse('orElse'), 'orElse');
+  }
+
+  void test_ifNotEmptyOrElse_notEmpty() {
+    expect('test'.ifNotEmptyOrElse('orElse'), 'test');
+  }
+}
diff --git a/pkg/analyzer/test/util/ast_check.dart b/pkg/analyzer/test/util/ast_check.dart
deleted file mode 100644
index 6a3e71f..0000000
--- a/pkg/analyzer/test/util/ast_check.dart
+++ /dev/null
@@ -1,177 +0,0 @@
-// 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/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer_utilities/check/check.dart';
-
-import 'token_check.dart';
-
-extension ArgumentListExtension on CheckTarget<ArgumentList> {
-  CheckTarget<List<Expression>> get arguments {
-    return nest(
-      value.arguments,
-      (selected) => 'has arguments ${valueStr(selected)}',
-    );
-  }
-
-  void get isSynthetic {
-    leftParenthesis
-      ..isOpenParenthesis
-      ..isSynthetic;
-    rightParenthesis
-      ..isCloseParenthesis
-      ..isSynthetic;
-    arguments.isEmpty;
-  }
-
-  CheckTarget<Token> get leftParenthesis {
-    return nest(
-      value.leftParenthesis,
-      (selected) => 'has leftParenthesis ${valueStr(selected)}',
-    );
-  }
-
-  CheckTarget<Token> get rightParenthesis {
-    return nest(
-      value.rightParenthesis,
-      (selected) => 'has rightParenthesis ${valueStr(selected)}',
-    );
-  }
-}
-
-extension ConstructorSelectorExtension on CheckTarget<ConstructorSelector> {
-  CheckTarget<SimpleIdentifier> get name {
-    return nest(
-      value.name,
-      (selected) => 'has name ${valueStr(selected)}',
-    );
-  }
-}
-
-extension EnumConstantArgumentsExtension on CheckTarget<EnumConstantArguments> {
-  CheckTarget<ArgumentList> get argumentList {
-    return nest(
-      value.argumentList,
-      (selected) => 'has argumentList ${valueStr(selected)}',
-    );
-  }
-
-  CheckTarget<ConstructorSelector?> get constructorSelector {
-    return nest(
-      value.constructorSelector,
-      (selected) => 'has constructorSelector ${valueStr(selected)}',
-    );
-  }
-
-  CheckTarget<TypeArgumentList?> get typeArguments {
-    return nest(
-      value.typeArguments,
-      (selected) => 'has typeArguments ${valueStr(selected)}',
-    );
-  }
-}
-
-extension EnumConstantDeclarationExtension
-    on CheckTarget<EnumConstantDeclaration> {
-  CheckTarget<EnumConstantArguments?> get arguments {
-    return nest(
-      value.arguments,
-      (selected) => 'has arguments ${valueStr(selected)}',
-    );
-  }
-}
-
-extension EnumDeclarationExtension on CheckTarget<EnumDeclaration> {
-  CheckTarget<Token?> get semicolon {
-    return nest(
-      value.semicolon,
-      (selected) => 'has semicolon ${valueStr(selected)}',
-    );
-  }
-}
-
-extension SimpleFormalParameterExtension on CheckTarget<SimpleFormalParameter> {
-  CheckTarget<Token?> get keyword {
-    return nest(
-      value.keyword,
-      (selected) => 'has keyword ${valueStr(selected)}',
-    );
-  }
-
-  CheckTarget<TypeAnnotation?> get type {
-    return nest(
-      value.type,
-      (selected) => 'has type ${valueStr(selected)}',
-    );
-  }
-}
-
-extension SimpleIdentifierExtension on CheckTarget<SimpleIdentifier> {
-  CheckTarget<bool> get inDeclarationContext {
-    return nest(
-      value.inDeclarationContext(),
-      (selected) => 'has inDeclarationContext() ${valueStr(selected)}',
-    );
-  }
-
-  void get isSynthetic {
-    if (!value.token.isSynthetic) {
-      fail('Is not synthetic');
-    }
-  }
-
-  CheckTarget<String> get name {
-    return nest(
-      value.name,
-      (selected) => 'has name ${valueStr(selected)}',
-    );
-  }
-}
-
-extension SuperFormalParameterExtension on CheckTarget<SuperFormalParameter> {
-  CheckTarget<Token?> get keyword {
-    return nest(
-      value.keyword,
-      (selected) => 'has keyword ${valueStr(selected)}',
-    );
-  }
-
-  CheckTarget<FormalParameterList?> get parameters {
-    return nest(
-      value.parameters,
-      (selected) => 'has parameters ${valueStr(selected)}',
-    );
-  }
-
-  CheckTarget<Token?> get superKeyword {
-    return nest(
-      value.superKeyword,
-      (selected) => 'has superKeyword ${valueStr(selected)}',
-    );
-  }
-
-  CheckTarget<TypeAnnotation?> get type {
-    return nest(
-      value.type,
-      (selected) => 'has type ${valueStr(selected)}',
-    );
-  }
-
-  CheckTarget<TypeParameterList?> get typeParameters {
-    return nest(
-      value.typeParameters,
-      (selected) => 'has typeParameters ${valueStr(selected)}',
-    );
-  }
-}
-
-extension TypeParameterListExtension on CheckTarget<TypeParameterList> {
-  CheckTarget<List<TypeParameter>> get typeParameters {
-    return nest(
-      value.typeParameters,
-      (selected) => 'has typeParameters ${valueStr(selected)}',
-    );
-  }
-}
diff --git a/pkg/analyzer/test/util/feature_sets.dart b/pkg/analyzer/test/util/feature_sets.dart
index f925df7..e084b92 100644
--- a/pkg/analyzer/test/util/feature_sets.dart
+++ b/pkg/analyzer/test/util/feature_sets.dart
@@ -32,16 +32,24 @@
     flags: [],
   );
 
+  static final FeatureSet language_2_19 = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: Version.parse('2.19.0'),
+    flags: [],
+  );
+
   static final FeatureSet latest = FeatureSet.latestLanguageVersion();
 
   static final FeatureSet latestWithExperiments = FeatureSet.fromEnableFlags2(
     sdkLanguageVersion: ExperimentStatus.currentVersion,
     flags: [
       EnableString.enhanced_enums,
+      EnableString.extension_types,
       EnableString.macros,
       EnableString.named_arguments_anywhere,
+      EnableString.patterns,
       EnableString.records,
       EnableString.super_parameters,
+      EnableString.unnamed_libraries,
     ],
   );
 
diff --git a/pkg/analyzer/test/util/id_testing_helper.dart b/pkg/analyzer/test/util/id_testing_helper.dart
index 27d9ac8..46bb47d 100644
--- a/pkg/analyzer/test/util/id_testing_helper.dart
+++ b/pkg/analyzer/test/util/id_testing_helper.dart
@@ -213,20 +213,20 @@
       if (className != null) {
         for (var declaration in unit.declarations) {
           if (declaration is ClassDeclaration &&
-              declaration.name2.lexeme == className) {
+              declaration.name.lexeme == className) {
             for (var member in declaration.members) {
               if (member is ConstructorDeclaration) {
-                if (member.name2!.lexeme == name) {
+                if (member.name!.lexeme == name) {
                   return member.offset;
                 }
               } else if (member is FieldDeclaration) {
                 for (var variable in member.fields.variables) {
-                  if (variable.name2.lexeme == name) {
+                  if (variable.name.lexeme == name) {
                     return variable.offset;
                   }
                 }
               } else if (member is MethodDeclaration) {
-                if (member.name2.lexeme == name) {
+                if (member.name.lexeme == name) {
                   return member.offset;
                 }
               }
@@ -239,12 +239,12 @@
       }
       for (var declaration in unit.declarations) {
         if (declaration is FunctionDeclaration) {
-          if (declaration.name2.lexeme == name) {
+          if (declaration.name.lexeme == name) {
             return declaration.offset;
           }
         } else if (declaration is TopLevelVariableDeclaration) {
           for (var variable in declaration.variables.variables) {
-            if (variable.name2.lexeme == name) {
+            if (variable.name.lexeme == name) {
               return variable.offset;
             }
           }
@@ -258,7 +258,7 @@
               .unit;
       for (var declaration in unit.declarations) {
         if (declaration is ClassDeclaration &&
-            declaration.name2.lexeme == className) {
+            declaration.name.lexeme == className) {
           return declaration.offset;
         }
       }
diff --git a/pkg/analyzer/test/util/token_check.dart b/pkg/analyzer/test/util/token_check.dart
deleted file mode 100644
index 67671d0..0000000
--- a/pkg/analyzer/test/util/token_check.dart
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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/dart/ast/token.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer_utilities/check/check.dart';
-
-extension KeywordTokenExtension on CheckTarget<KeywordToken> {
-  CheckTarget<Keyword> get keyword {
-    return nest(
-      value.keyword,
-      (selected) => 'has keyword ${valueStr(selected)}',
-    );
-  }
-}
-
-extension TokenExtension on CheckTarget<Token> {
-  void get isCloseParenthesis {
-    type.isEqualTo(TokenType.CLOSE_PAREN);
-  }
-
-  void get isOpenParenthesis {
-    type.isEqualTo(TokenType.OPEN_PAREN);
-  }
-
-  void get isSemicolon {
-    type.isEqualTo(TokenType.SEMICOLON);
-  }
-
-  void get isSynthetic {
-    if (value.isSynthetic) return;
-    fail('Not synthetic');
-  }
-
-  CheckTarget<Token?> get next {
-    return nest(
-      value.next,
-      (selected) => 'has next ${valueStr(selected)}',
-    );
-  }
-
-  CheckTarget<Token?> get previous {
-    return nest(
-      value.previous,
-      (selected) => 'has previous ${valueStr(selected)}',
-    );
-  }
-
-  CheckTarget<TokenType> get type {
-    return nest(
-      value.type,
-      (selected) => 'has type ${valueStr(selected)}',
-    );
-  }
-
-  void isLinkedToNext(Token next) {
-    this.next.isEqualTo(next);
-    nest(next, (value) => 'next ${valueStr(value)}').previous.isEqualTo(value);
-  }
-
-  void isLinkedToPrevious(Token previous) {
-    nest(previous, (value) => 'given previous ${valueStr(value)}')
-        .next
-        .isEqualTo(value);
-    this.previous.isEqualTo(previous);
-  }
-}
-
-extension TokenQuestionExtension on CheckTarget<Token?> {
-  CheckTarget<KeywordToken> get isKeyword {
-    return isA<KeywordToken>();
-  }
-
-  void get isKeywordConst {
-    isKeyword.keyword.isEqualTo(Keyword.CONST);
-  }
-
-  void get isKeywordSuper {
-    isKeyword.keyword.isEqualTo(Keyword.SUPER);
-  }
-
-  void get isKeywordVar {
-    isKeyword.keyword.isEqualTo(Keyword.VAR);
-  }
-}
diff --git a/pkg/analyzer/test/utils.dart b/pkg/analyzer/test/utils.dart
index 6939069..b47f47a 100644
--- a/pkg/analyzer/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -31,7 +31,7 @@
     NodeList<CompilationUnitMember> unitMembers = unit.declarations;
     for (CompilationUnitMember unitMember in unitMembers) {
       if (unitMember is ClassDeclaration &&
-          unitMember.name2.lexeme == className) {
+          unitMember.name.lexeme == className) {
         return unitMember;
       }
     }
@@ -48,7 +48,7 @@
     NodeList<ClassMember> classMembers = unitMember.members;
     for (ClassMember classMember in classMembers) {
       if (classMember is ConstructorDeclaration) {
-        if (classMember.name2?.lexeme == constructorName) {
+        if (classMember.name?.lexeme == constructorName) {
           return classMember;
         }
       }
@@ -66,7 +66,7 @@
       if (classMember is FieldDeclaration) {
         NodeList<VariableDeclaration> fields = classMember.fields.variables;
         for (VariableDeclaration field in fields) {
-          if (field.name2.lexeme == fieldName) {
+          if (field.name.lexeme == fieldName) {
             return field;
           }
         }
@@ -79,7 +79,7 @@
   /// with the given [className] in the given compilation [unit].
   static FieldElement? getFieldInClassElement(
       CompilationUnit unit, String className, String fieldName) {
-    return getFieldInClass(unit, className, fieldName).declaredElement2
+    return getFieldInClass(unit, className, fieldName).declaredElement
         as FieldElement;
   }
 
@@ -91,7 +91,7 @@
     NodeList<ClassMember> classMembers = unitMember.members;
     for (ClassMember classMember in classMembers) {
       if (classMember is MethodDeclaration) {
-        if (classMember.name2.lexeme == methodName) {
+        if (classMember.name.lexeme == methodName) {
           return classMember;
         }
       }
@@ -125,7 +125,7 @@
     NodeList<CompilationUnitMember> unitMembers = unit.declarations;
     for (CompilationUnitMember unitMember in unitMembers) {
       if (unitMember is FunctionDeclaration) {
-        if (unitMember.name2.lexeme == functionName) {
+        if (unitMember.name.lexeme == functionName) {
           return unitMember;
         }
       }
@@ -143,7 +143,7 @@
         NodeList<VariableDeclaration> variables =
             unitMember.variables.variables;
         for (VariableDeclaration variable in variables) {
-          if (variable.name2.lexeme == variableName) {
+          if (variable.name.lexeme == variableName) {
             return variable;
           }
         }
@@ -155,7 +155,7 @@
   /// Return the top-level variable element with the given [name].
   static TopLevelVariableElement getTopLevelVariableElement(
       CompilationUnit unit, String name) {
-    return getTopLevelVariable(unit, name).declaredElement2
+    return getTopLevelVariable(unit, name).declaredElement
         as TopLevelVariableElement;
   }
 }
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 1a3ee99..028dd86 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -349,7 +349,7 @@
 }
 {% endprettify %}
 
-The following code produces this diagnostic because the class `C` defineS
+The following code produces this diagnostic because the class `C` defines
 a field:
 
 {% prettify dart tag=pre+code %}
@@ -4158,7 +4158,7 @@
 {% endprettify %}
 
 If there are multiple named constructors and all except one of them are
-unneeded, then remove the constructorsthat aren't needed:
+unneeded, then remove the constructors that aren't needed:
 
 {% prettify dart tag=pre+code %}
 class C {
@@ -12992,7 +12992,7 @@
 
 ### non_type_as_type_argument
 
-_The name '{0}' isn't a type so it can't be used as a type argument._
+_The name '{0}' isn't a type, so it can't be used as a type argument._
 
 #### Description
 
@@ -16452,7 +16452,7 @@
 
 ### subtype_of_disallowed_type
 
-_''{0}' can't be used as a superclass constraint._
+_'{0}' can't be used as a superclass constraint._
 
 _Classes and mixins can't implement '{0}'._
 
@@ -19407,9 +19407,9 @@
 - Assigning a value to a top-level variable (with a standard `=`
   assignment, or a null-aware `??=` assignment) does not count as using
   it.
-- Refering to an element in a doc comment reference does not count as
+- Referring to an element in a doc comment reference does not count as
   using it.
-- Refering to a class, mixin, or enum in the right side of an `is`
+- Referring to a class, mixin, or enum on the right side of an `is`
   expression does not count as using it.
 
 #### Example
diff --git a/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart b/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart
index 7f1c6fb..4925e49 100644
--- a/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart
+++ b/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart
@@ -173,11 +173,11 @@
         .unit;
     for (var declaration in unit.declarations) {
       if (declaration is! ClassDeclaration) continue;
-      var className = declaration.name2.lexeme;
+      var className = declaration.name.lexeme;
       for (var member in declaration.members) {
         if (member is! FieldDeclaration) continue;
         for (var variable in member.fields.variables) {
-          (result[className] ??= {})[variable.name2.lexeme] = variable;
+          (result[className] ??= {})[variable.name.lexeme] = variable;
         }
       }
     }
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
index 6c3f1bec..77931f3 100644
--- a/pkg/analyzer/tool/messages/generate.dart
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -24,7 +24,7 @@
 
 import 'error_code_info.dart';
 
-main() async {
+void main() async {
   await GeneratedContent.generateAll(analyzerPkgPath, allTargets);
 
   _SyntacticErrorGenerator()
diff --git a/pkg/analyzer/tool/messages/generate_test.dart b/pkg/analyzer/tool/messages/generate_test.dart
index 02a43cf..ffba861 100644
--- a/pkg/analyzer/tool/messages/generate_test.dart
+++ b/pkg/analyzer/tool/messages/generate_test.dart
@@ -11,7 +11,7 @@
 import 'error_code_info.dart';
 import 'generate.dart';
 
-main() async {
+void main() async {
   await GeneratedContent.checkAll(analyzerPkgPath,
       join(analyzerPkgPath, 'tool', 'messages', 'generate.dart'), allTargets);
 }
diff --git a/pkg/analyzer/tool/messages/messages_test.dart b/pkg/analyzer/tool/messages/messages_test.dart
new file mode 100644
index 0000000..1eb4bca
--- /dev/null
+++ b/pkg/analyzer/tool/messages/messages_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2022, 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/expect.dart';
+
+import 'error_code_info.dart';
+
+/// Check that the file 'messages.yaml' has corresponding parameters count
+/// between the errors 'problemMessage'/'correctionMessage' and 'comment'.
+void main() {
+  var classValues = analyzerMessages.values;
+  for (var classValue in classValues) {
+    for (var errorEntry in classValue.entries) {
+      var error = errorEntry.value;
+      if (_getMessagesParameters(error) !=
+          _getCommentParameters(error.comment ?? '')) {
+        fail(
+            "Parameters don't match between the problemMessage and comment in ${errorEntry.key}");
+      }
+    }
+  }
+}
+
+int _getCommentParameters(String message) {
+  var i = 0;
+  while (message.contains('\n$i: ')) {
+    i++;
+  }
+  return i;
+}
+
+int _getMessagesParameters(ErrorCodeInfo info) {
+  var i = 0;
+  while (info.problemMessage.contains('{$i}')) {
+    i++;
+  }
+  while (info.correctionMessage?.contains('{$i}') ?? false) {
+    i++;
+  }
+  return i;
+}
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index d07bb77..8d9079d 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -328,9 +328,11 @@
   }
 
   @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
     debugEvent("LibraryName");
-    pop(); // Library name
+    if (hasName) {
+      pop(); // Library name
+    }
     pop(); // Metadata
     pop(); // Comment
   }
diff --git a/pkg/analyzer_plugin/CHANGELOG.md b/pkg/analyzer_plugin/CHANGELOG.md
index d4e4585..6bd1493 100644
--- a/pkg/analyzer_plugin/CHANGELOG.md
+++ b/pkg/analyzer_plugin/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.11.2
+
+- Support version `5.x` of the `analyzer` package
+
 ## 0.11.1
 - Call `analyzeFiles` from `handleAffectedFiles` only for files that are
   analyzed in this analysis context.
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 080188d..e3d98b0 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
@@ -261,6 +261,8 @@
   @override
   void setSelection(Position position) {
     _selection = position;
+    // Clear any existing selection range, since it is no long valid.
+    _selectionRange = null;
   }
 
   /// Return a copy of the linked edit [group].
@@ -306,6 +308,11 @@
 
   void _setSelectionRange(SourceRange range) {
     _selectionRange = range;
+    // If we previously had a selection, update it to this new offset.
+    final selection = _selection;
+    if (selection != null) {
+      _selection = Position(selection.file, range.offset);
+    }
   }
 
   /// Update the offsets of any positions that occur at or after the given
@@ -327,6 +334,13 @@
     if (selection != null) {
       updatePosition(selection);
     }
+    var selectionRange = _selectionRange;
+    if (selectionRange != null) {
+      if (selectionRange.offset >= offset) {
+        _selectionRange =
+            SourceRange(selectionRange.offset + delta, selectionRange.length);
+      }
+    }
   }
 }
 
@@ -585,8 +599,9 @@
     var range = builder._selectionRange;
     if (range != null) {
       var position = Position(fileEdit.file, range.offset + _deltaToEdit(edit));
+      var newRange = SourceRange(position.offset, range.length);
       changeBuilder.setSelection(position);
-      changeBuilder._setSelectionRange(range);
+      changeBuilder._setSelectionRange(newRange);
     }
   }
 
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 42ee3c1..38fbffc 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
@@ -693,7 +693,7 @@
 
   @override
   void writeReference(Element element) {
-    if (element.enclosingElement3 is CompilationUnitElement) {
+    if (element.enclosingElement is CompilationUnitElement) {
       _writeLibraryReference(element);
     }
     write(element.displayName);
@@ -906,6 +906,12 @@
       return true;
     }
 
+    if (type is RecordType) {
+      // TODO(brianwilkerson) This should return `false` if the `records`
+      //  feature is not enabled.
+      return true;
+    }
+
     throw UnimplementedError('(${type.runtimeType}) $type');
   }
 
@@ -1112,10 +1118,10 @@
     if (type is TypeParameterType) {
       _initializeEnclosingElements();
       var element = type.element2;
-      var enclosing = element.enclosingElement3;
+      var enclosing = element.enclosingElement;
       while (enclosing is GenericFunctionTypeElement ||
           enclosing is ParameterElement) {
-        enclosing = enclosing!.enclosingElement3;
+        enclosing = enclosing!.enclosingElement;
       }
       if (enclosing == _enclosingExecutable ||
           enclosing == _enclosingClass ||
@@ -1279,6 +1285,50 @@
       return true;
     }
 
+    if (type is RecordType) {
+      // TODO(brianwilkerson) This should return `false` if the `records`
+      //  feature is not enabled. More importantly, we can't currently return
+      //  `false` if some portion of a type has already been written, so we
+      //  need to figure out what to do when a record type is nested in another
+      //  type in a context where it isn't allowed. For example, we might
+      //  enhance `_canWriteType` to be recursive, then guard all invocations of
+      //  this method with a call to `_canWriteType` (and remove the return type
+      //  from this method).
+      write('(');
+      var isFirst = true;
+      for (var field in type.positionalFields) {
+        if (isFirst) {
+          isFirst = false;
+        } else {
+          write(', ');
+        }
+        _writeType(field.type);
+      }
+      var namedFields = type.namedFields;
+      if (namedFields.isNotEmpty) {
+        if (isFirst) {
+          write('{');
+        } else {
+          write(', {');
+        }
+        isFirst = true;
+        for (var field in namedFields) {
+          if (isFirst) {
+            isFirst = false;
+          } else {
+            write(', ');
+          }
+          _writeType(field.type);
+          write(' ');
+          write(field.name);
+        }
+        write('}');
+      }
+      write(')');
+      _writeTypeNullability(type);
+      return true;
+    }
+
     throw UnimplementedError('(${type.runtimeType}) $type');
   }
 
@@ -1550,10 +1600,11 @@
     var importList = imports.toList();
     importList.sort((a, b) => a.uriText.compareTo(b.uriText));
 
+    var quote = codeStyleOptions.preferredQuoteForUris(importDirectives);
     void writeImport(EditBuilder builder, _LibraryToImport import) {
-      builder.write("import '");
+      builder.write('import $quote');
       builder.write(import.uriText);
-      builder.write("'");
+      builder.write(quote);
       var prefix = import.prefix;
       if (prefix != null) {
         builder.write(' as ');
@@ -1910,13 +1961,13 @@
     var node = NodeLocator2(offset).searchWithin(target);
     while (node != null) {
       if (node is ClassDeclaration) {
-        enclosingClass = node.declaredElement2;
+        enclosingClass = node.declaredElement;
       } else if (node is ConstructorDeclaration) {
-        enclosingExecutable = node.declaredElement2;
+        enclosingExecutable = node.declaredElement;
       } else if (node is MethodDeclaration) {
-        enclosingExecutable = node.declaredElement2;
+        enclosingExecutable = node.declaredElement;
       } else if (node is FunctionDeclaration) {
-        enclosingExecutable = node.declaredElement2;
+        enclosingExecutable = node.declaredElement;
       }
       node = node.parent;
     }
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 de84532..b343e55 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -123,9 +123,9 @@
     final unitMember =
         containingNode.thisOrAncestorOfType<CompilationUnitMember>();
     if (unitMember is ClassDeclaration) {
-      return unitMember.declaredElement2;
+      return unitMember.declaredElement;
     } else if (unitMember is MixinDeclaration) {
-      return unitMember.declaredElement2;
+      return unitMember.declaredElement;
     } else {
       return null;
     }
@@ -134,7 +134,7 @@
   /// The enclosing [ExtensionElement], or `null` if not in an extension.
   late final ExtensionElement? enclosingExtensionElement = containingNode
       .thisOrAncestorOfType<ExtensionDeclaration>()
-      ?.declaredElement2;
+      ?.declaredElement;
 
   /// Compute the appropriate [CompletionTarget] for the given [offset] within
   /// the [entryPoint].
@@ -392,14 +392,8 @@
           token.type == TokenType.COMMA;
     }
 
-    var entity = this.entity;
-
-    Token token;
-    if (entity is AstNode) {
-      token = entity.endToken;
-    } else if (entity is Token) {
-      token = entity;
-    } else {
+    final token = lastTokenOfEntity;
+    if (token == null) {
       return false;
     }
 
@@ -409,6 +403,37 @@
     return isExistingComma(token);
   }
 
+  /// Return `true` if the [offset] is followed by a `)`.
+  bool get isFollowedByRightParenthesis {
+    bool isExistingRightParenthesis(Token? token) {
+      return token != null &&
+          !token.isSynthetic &&
+          token.type == TokenType.CLOSE_PAREN;
+    }
+
+    final token = lastTokenOfEntity;
+    if (token == null) {
+      return false;
+    }
+
+    if (isExistingRightParenthesis(token)) {
+      return true;
+    }
+
+    return isExistingRightParenthesis(token.next);
+  }
+
+  Token? get lastTokenOfEntity {
+    final entity = this.entity;
+    if (entity is AstNode) {
+      return entity.endToken;
+    } else if (entity is Token) {
+      return entity;
+    } else {
+      return null;
+    }
+  }
+
   /// If the target is an argument in an argument list, and the invocation is
   /// resolved, return the corresponding [ParameterElement].
   ParameterElement? get parameterElement {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart
index 7d683d3..127cb49 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart
@@ -70,7 +70,7 @@
           // Pair getter/setter by updating the existing suggestion
           if (existingSuggestion != null) {
             var getter = element.isGetter ? suggestion : existingSuggestion;
-            var elemKind = element.enclosingElement3 is ClassElement
+            var elemKind = element.enclosingElement is ClassElement
                 ? protocol.ElementKind.FIELD
                 : protocol.ElementKind.TOP_LEVEL_VARIABLE;
             existingSuggestion.element = protocol.Element(
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index 4ead783..74f8607 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -569,7 +569,7 @@
           }
         }
       } else if (parent is MethodDeclaration) {
-        type = parent.declaredElement2?.returnType;
+        type = parent.declaredElement?.returnType;
         if (type != null && type.isVoid) {
           optype.includeVoidReturnSuggestions = true;
         }
@@ -628,7 +628,7 @@
       // class A { static late ^ }
       if (node.staticKeyword != null &&
           variables.length == 1 &&
-          variables[0].name2.lexeme == 'late') {
+          variables[0].name.lexeme == 'late') {
         optype.completionLocation = 'FieldDeclaration_static_late';
         optype.includeTypeNameSuggestions = true;
         return;
@@ -637,7 +637,7 @@
       if (node.staticKeyword == null &&
           offset <= node.semicolon.offset &&
           variables.length == 1 &&
-          variables[0].name2.lexeme == 'static') {
+          variables[0].name.lexeme == 'static') {
         optype.completionLocation = 'FieldDeclaration_static';
         optype.includeTypeNameSuggestions = true;
         return;
@@ -806,7 +806,7 @@
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     if (identical(entity, node.returnType) ||
-        identical(entity, node.name2) && node.returnType == null) {
+        identical(entity, node.name) && node.returnType == null) {
       optype.completionLocation = 'FunctionDeclaration_returnType';
       optype.includeTypeNameSuggestions = true;
     }
@@ -821,7 +821,7 @@
   @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     if (identical(entity, node.returnType) ||
-        identical(entity, node.name2) && node.returnType == null) {
+        identical(entity, node.name) && node.returnType == null) {
       optype.includeTypeNameSuggestions = true;
     }
   }
@@ -948,7 +948,7 @@
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
     if (identical(entity, node.returnType) ||
-        identical(entity, node.name2) && node.returnType == null) {
+        identical(entity, node.name) && node.returnType == null) {
       optype.completionLocation = 'MethodDeclaration_returnType';
     }
     // TODO(brianwilkerson) In visitFunctionDeclaration, this is conditional. It
@@ -1144,6 +1144,61 @@
   }
 
   @override
+  void visitRecordLiteral(RecordLiteral node) {
+    optype.completionLocation = 'RecordLiteral_fields';
+
+    final entity = this.entity;
+    if (entity is NamedExpression && offset <= entity.name.colon.offset) {
+      // No values, only names.
+    } else {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitRecordTypeAnnotation(RecordTypeAnnotation node) {
+    optype.completionLocation = 'RecordTypeAnnotation_positionalFields';
+
+    final entity = this.entity;
+    if (entity is Token && entity == node.rightParenthesis) {
+      final previous = entity.previous;
+      if (previous != null) {
+        if (previous.type != TokenType.COMMA) {
+          optype.includeVarNameSuggestions = true;
+          return;
+        }
+      }
+    }
+
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitRecordTypeAnnotationNamedField(
+    RecordTypeAnnotationNamedField node,
+  ) {
+    optype.completionLocation = 'RecordTypeAnnotationNamedField_name';
+    optype.includeVarNameSuggestions = true;
+  }
+
+  @override
+  void visitRecordTypeAnnotationNamedFields(
+    RecordTypeAnnotationNamedFields node,
+  ) {
+    optype.completionLocation = 'RecordTypeAnnotationNamedFields_fields';
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitRecordTypeAnnotationPositionalField(
+    RecordTypeAnnotationPositionalField node,
+  ) {
+    optype.completionLocation = 'RecordTypeAnnotationPositionalField_name';
+    optype.includeVarNameSuggestions = true;
+  }
+
+  @override
   void visitReturnStatement(ReturnStatement node) {
     if (identical(entity, node.expression) ||
         (identical(entity, node.semicolon) && node.expression == null)) {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/suggestion_builder.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/suggestion_builder.dart
index 7e7bbe2..e452d3d 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/suggestion_builder.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/suggestion_builder.dart
@@ -94,7 +94,7 @@
     suggestion.docSummary = getDartDocSummary(doc);
 
     suggestion.element = converter.convertElement(element);
-    var enclosingElement = element.enclosingElement3;
+    var enclosingElement = element.enclosingElement;
     if (enclosingElement is ClassElement) {
       suggestion.declaringType = enclosingElement.displayName;
     }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
index 7af1d92..b207854 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
@@ -128,12 +128,12 @@
     if (forLoopParts is ForEachPartsWithDeclaration) {
       var loopVariable = forLoopParts.loopVariable;
       declaredLocalVar(
-          loopVariable.name, loopVariable.type, loopVariable.declaredElement2!);
+          loopVariable.name, loopVariable.type, loopVariable.declaredElement!);
     } else if (forLoopParts is ForPartsWithDeclarations) {
       var varList = forLoopParts.variables;
       for (var varDecl in varList.variables) {
-        declaredLocalVar(varDecl.name2, varList.type,
-            varDecl.declaredElement2 as LocalVariableElement);
+        declaredLocalVar(varDecl.name, varList.type,
+            varDecl.declaredElement as LocalVariableElement);
       }
     }
     visitNode(node);
@@ -145,12 +145,12 @@
     if (forLoopParts is ForEachPartsWithDeclaration) {
       var loopVariable = forLoopParts.loopVariable;
       declaredLocalVar(
-          loopVariable.name, loopVariable.type, loopVariable.declaredElement2!);
+          loopVariable.name, loopVariable.type, loopVariable.declaredElement!);
     } else if (forLoopParts is ForPartsWithDeclarations) {
       var varList = forLoopParts.variables;
       for (var varDecl in varList.variables) {
-        declaredLocalVar(varDecl.name2, varList.type,
-            varDecl.declaredElement2 as LocalVariableElement);
+        declaredLocalVar(varDecl.name, varList.type,
+            varDecl.declaredElement as LocalVariableElement);
       }
     }
     visitNode(node);
@@ -322,14 +322,14 @@
           var varList = stmt.variables;
           for (var varDecl in varList.variables) {
             if (varDecl.end < offset) {
-              declaredLocalVar(varDecl.name2, varList.type,
-                  varDecl.declaredElement2 as LocalVariableElement);
+              declaredLocalVar(varDecl.name, varList.type,
+                  varDecl.declaredElement as LocalVariableElement);
             }
           }
         } else if (stmt is FunctionDeclarationStatement) {
           var declaration = stmt.functionDeclaration;
           if (declaration.offset < offset) {
-            var name = declaration.name2.lexeme;
+            var name = declaration.name.lexeme;
             if (name.isNotEmpty) {
               declaredFunction(declaration);
               _visitTypeParameters(
diff --git a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
index 2545739..658e533 100644
--- a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
+++ b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
@@ -226,7 +226,7 @@
         // in either or both of these cases?
         ) {
       final type = element.type;
-      if (type is InterfaceType && type.element2 == element.enclosingElement3) {
+      if (type is InterfaceType && type.element2 == element.enclosingElement) {
         return plugin.ElementKind.ENUM_CONSTANT;
       }
     }
@@ -326,15 +326,15 @@
     if (currentElement is analyzer.CompilationUnitElement) {
       return currentElement;
     }
-    if (currentElement.enclosingElement3 is analyzer.LibraryElement) {
-      currentElement = currentElement.enclosingElement3;
+    if (currentElement.enclosingElement is analyzer.LibraryElement) {
+      currentElement = currentElement.enclosingElement;
     }
     if (currentElement is analyzer.LibraryElement) {
       return currentElement.definingCompilationUnit;
     }
     for (;
         currentElement != null;
-        currentElement = currentElement.enclosingElement3) {
+        currentElement = currentElement.enclosingElement) {
       if (currentElement is analyzer.CompilationUnitElement) {
         return currentElement;
       }
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 54c1d02..77cc825 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
@@ -41,12 +41,12 @@
       return;
     }
     var classDecl = _enclosingClass(target);
-    if (classDecl == null || classDecl.declaredElement2 == null) {
+    if (classDecl == null || classDecl.declaredElement == null) {
       return;
     }
     containingLibrary = request.result.libraryElement;
     _computeSuggestionsForClass2(
-        collector, target, classDecl.declaredElement2!, optype);
+        collector, target, classDecl.declaredElement!, optype);
   }
 
   /// Clients should not overload this function.
@@ -67,10 +67,10 @@
     }
     if (classElement == null) {
       var classDecl = _enclosingClass(target);
-      if (classDecl == null || classDecl.declaredElement2 == null) {
+      if (classDecl == null || classDecl.declaredElement == null) {
         return;
       }
-      classElement = classDecl.declaredElement2;
+      classElement = classDecl.declaredElement;
     }
     containingLibrary = request.result.libraryElement;
     _computeSuggestionsForClass2(collector, target, classElement!, optype,
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 151d387..577ad0e 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
@@ -106,7 +106,7 @@
       // the most likely completion is a super expression with same name
       var containingMethod =
           expression.thisOrAncestorOfType<MethodDeclaration>();
-      var id = containingMethod?.name2;
+      var id = containingMethod?.name;
       if (id != null) {
         containingMethodName = id.lexeme;
       }
@@ -140,7 +140,7 @@
 
   @override
   void declaredClass(ClassDeclaration declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       // no type
       finished();
     }
@@ -148,7 +148,7 @@
 
   @override
   void declaredClassTypeAlias(ClassTypeAlias declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       // no type
       finished();
     }
@@ -159,7 +159,7 @@
 
   @override
   void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-    if (varDecl.name2.lexeme == targetName) {
+    if (varDecl.name.lexeme == targetName) {
       // Type provided by the element in computeFull above
       finished();
     }
@@ -167,7 +167,7 @@
 
   @override
   void declaredFunction(FunctionDeclaration declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       var typeName = declaration.returnType;
       if (typeName != null) {
         typeFound = typeName.type;
@@ -178,7 +178,7 @@
 
   @override
   void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       var typeName = declaration.returnType;
       if (typeName != null) {
         typeFound = typeName.type;
@@ -189,7 +189,7 @@
 
   @override
   void declaredGenericTypeAlias(GenericTypeAlias declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       var typeName = declaration.functionType?.returnType;
       if (typeName != null) {
         typeFound = typeName.type;
@@ -220,7 +220,7 @@
 
   @override
   void declaredMethod(MethodDeclaration declaration) {
-    if (declaration.name2.lexeme == targetName) {
+    if (declaration.name.lexeme == targetName) {
       var typeName = declaration.returnType;
       if (typeName != null) {
         typeFound = typeName.type;
@@ -240,7 +240,7 @@
   @override
   void declaredTopLevelVar(
       VariableDeclarationList varList, VariableDeclaration varDecl) {
-    if (varDecl.name2.lexeme == targetName) {
+    if (varDecl.name.lexeme == targetName) {
       // Type provided by the element in computeFull above
       finished();
     }
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index 3e8ceef..43fbccd 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -28,14 +28,6 @@
   } else {
     var node = _getNodeForRange(unit, offset, length);
 
-    {
-      final parent = node?.parent;
-      // ignore: deprecated_member_use
-      if (parent is ConstructorDeclaration && parent.name == node) {
-        node = parent;
-      }
-    }
-
     if (node != null) {
       node = _getNavigationTargetNode(node);
     }
@@ -88,7 +80,23 @@
   _DartNavigationCollector(
       this.collector, this.requestedOffset, this.requestedLength);
 
-  void _addRegion(int offset, int length, Element? element) {
+  void _addRegion(
+    int offset,
+    int length,
+    protocol.ElementKind kind,
+    protocol.Location location, {
+    Element? targetElement,
+  }) {
+    // Discard elements that don't span the offset/range given (if provided).
+    if (!_isWithinRequestedRange(offset, length)) {
+      return;
+    }
+
+    collector.addRegion(offset, length, kind, location,
+        targetElement: targetElement);
+  }
+
+  void _addRegionForElement(int offset, int length, Element? element) {
     element = element?.nonSynthetic;
     if (element == null || element == DynamicElementImpl.instance) {
       return;
@@ -107,7 +115,7 @@
       return;
     }
 
-    collector.addRegion(offset, length, kind, location, targetElement: element);
+    _addRegion(offset, length, kind, location, targetElement: element);
   }
 
   void _addRegionForNode(AstNode? node, Element? element) {
@@ -116,13 +124,13 @@
     }
     var offset = node.offset;
     var length = node.length;
-    _addRegion(offset, length, element);
+    _addRegionForElement(offset, length, element);
   }
 
   void _addRegionForToken(Token token, Element? element) {
     var offset = token.offset;
     var length = token.length;
-    _addRegion(offset, length, element);
+    _addRegionForElement(offset, length, element);
   }
 
   /// Checks if offset/length intersect with the range the user requested
@@ -149,6 +157,7 @@
 class _DartNavigationComputerVisitor extends RecursiveAstVisitor<void> {
   final ResourceProvider resourceProvider;
   final _DartNavigationCollector computer;
+  String? _examplesApiPath;
 
   _DartNavigationComputerVisitor(this.resourceProvider, this.computer);
 
@@ -156,7 +165,7 @@
   void visitAnnotation(Annotation node) {
     var element = node.element;
     if (element is ConstructorElement && element.isSynthetic) {
-      element = element.enclosingElement3;
+      element = element.enclosingElement;
     }
     var name = node.name;
     if (name is PrefixedIdentifier) {
@@ -193,7 +202,24 @@
   }
 
   @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    computer._addRegionForToken(node.name, node.declaredElement);
+    super.visitClassDeclaration(node);
+  }
+
+  @override
   void visitComment(Comment node) {
+    if (!node.isDocumentation) {
+      super.visitComment(node);
+      return;
+    }
+    _examplesApiPath ??= _computeParentWithExamplesAPI(node, resourceProvider);
+    if (_examplesApiPath == null) {
+      // Examples directory doesn't exist.
+      super.visitComment(node);
+      return;
+    }
+
     for (var commentReference in node.references) {
       commentReference.accept(this);
     }
@@ -211,27 +237,34 @@
       if (inToolAnnotation) {
         if (strValue.contains('{@end-tool}')) {
           inToolAnnotation = false;
-        } else if (strValue.contains('** See code in ')) {
-          var startIndex = strValue.indexOf('** See code in ') + 15;
-          var endIndex = strValue.indexOf('.dart') + 5;
-          var pathSnippet = strValue.substring(startIndex, endIndex);
-          var parentPath =
-              _computeParentWithExamplesAPI(node, resourceProvider);
-          if (parentPath != null) {
+        } else {
+          var seeCodeIn = '** See code in ';
+          var startIndex = strValue.indexOf('${seeCodeIn}examples/api/');
+          if (startIndex != -1) {
+            startIndex += seeCodeIn.length;
+            var endIndex = strValue.indexOf('.dart') + 5;
+            var pathSnippet = strValue.substring(startIndex, endIndex);
+            // Split on '/' because that's what the comment syntax uses, but
+            // re-join it using the resource provider to get the right separator
+            // for the platform.
+            var examplePath = resourceProvider.pathContext
+                .joinAll('${_examplesApiPath!}/$pathSnippet'.split('/'));
             var start = token.offset + startIndex;
             var end = token.offset + endIndex;
-            computer.collector.addRegion(
-                start,
-                end - start,
-                protocol.ElementKind.LIBRARY,
-                protocol.Location(
-                    resourceProvider.pathContext.join(parentPath, pathSnippet),
-                    0,
-                    0,
-                    0,
-                    0,
-                    endLine: 0,
-                    endColumn: 0));
+            computer._addRegion(
+              start,
+              end - start,
+              protocol.ElementKind.LIBRARY,
+              protocol.Location(
+                examplePath,
+                0,
+                0,
+                0,
+                0,
+                endLine: 0,
+                endColumn: 0,
+              ),
+            );
           }
         }
       } else if (strValue.contains('{@tool ')) {
@@ -242,6 +275,9 @@
 
   @override
   void visitCompilationUnit(CompilationUnit unit) {
+    // Reset the examples path for this compilation unit.
+    _examplesApiPath = null;
+
     // prepare top-level nodes sorted by their offsets
     var nodes = <AstNode>[];
     nodes.addAll(unit.directives);
@@ -281,12 +317,12 @@
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     // For a default constructor, override the class name to be the declaration
     // itself rather than linking to the class.
-    var nameToken = node.name2;
+    var nameToken = node.name;
     if (nameToken == null) {
-      computer._addRegionForNode(node.returnType, node.declaredElement2);
+      computer._addRegionForNode(node.returnType, node.declaredElement);
     } else {
       node.returnType.accept(this);
-      computer._addRegionForToken(nameToken, node.declaredElement2);
+      computer._addRegionForToken(nameToken, node.declaredElement);
     }
     node.parameters.accept(this);
     node.initializers.accept(this);
@@ -328,7 +364,7 @@
     if (node.type == null) {
       var token = node.keyword;
       if (token != null && token.keyword == Keyword.VAR) {
-        var inferredType = node.declaredElement2?.type;
+        var inferredType = node.declaredElement?.type;
         if (inferredType is InterfaceType) {
           computer._addRegionForToken(token, inferredType.element2);
         }
@@ -339,7 +375,7 @@
 
   @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    computer._addRegionForToken(node.name2, node.constructorElement);
+    computer._addRegionForToken(node.name, node.constructorElement);
 
     var arguments = node.arguments;
     if (arguments != null) {
@@ -376,6 +412,12 @@
   }
 
   @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    computer._addRegionForToken(node.name, node.declaredElement);
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
   void visitImportDirective(ImportDirective node) {
     var importElement = node.element2;
     if (importElement != null) {
@@ -395,7 +437,13 @@
 
   @override
   void visitLibraryDirective(LibraryDirective node) {
-    computer._addRegionForNode(node.name, node.element2);
+    computer._addRegionForNode(node.name2, node.element2);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    computer._addRegionForToken(node.name, node.declaredElement);
+    super.visitMethodDeclaration(node);
   }
 
   @override
@@ -444,7 +492,7 @@
       RedirectingConstructorInvocation node) {
     Element? element = node.staticElement;
     if (element != null && element.isSynthetic) {
-      element = element.enclosingElement3;
+      element = element.enclosingElement;
     }
     // add region
     computer._addRegionForToken(node.thisKeyword, element);
@@ -454,6 +502,16 @@
   }
 
   @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    final nameToken = node.name;
+    if (nameToken != null) {
+      computer._addRegionForToken(nameToken, node.declaredElement);
+    }
+
+    super.visitSimpleFormalParameter(node);
+  }
+
+  @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
     var element = node.writeOrReadElement;
     computer._addRegionForNode(node, element);
@@ -463,7 +521,7 @@
   void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
     Element? element = node.staticElement;
     if (element != null && element.isSynthetic) {
-      element = element.enclosingElement3;
+      element = element.enclosingElement;
     }
     // add region
     computer._addRegionForToken(node.superKeyword, element);
@@ -487,19 +545,31 @@
   }
 
   @override
+  void visitTypeParameter(TypeParameter node) {
+    computer._addRegionForToken(node.name, node.declaredElement);
+    super.visitTypeParameter(node);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    computer._addRegionForToken(node.name, node.declaredElement);
+    super.visitVariableDeclaration(node);
+  }
+
+  @override
   void visitVariableDeclarationList(VariableDeclarationList node) {
     /// Return the element for the type inferred for each of the variables in
     /// the given list of [variables], or `null` if not all variable have the
     /// same inferred type.
     Element? getCommonElement(List<VariableDeclaration> variables) {
-      final firstType = variables[0].declaredElement2?.type;
+      final firstType = variables[0].declaredElement?.type;
       if (firstType is! InterfaceType) {
         return null;
       }
 
       var firstElement = firstType.element2;
       for (var i = 1; i < variables.length; i++) {
-        final type = variables[i].declaredElement2?.type;
+        final type = variables[i].declaredElement?.type;
         if (type is! InterfaceType) {
           return null;
         }
@@ -533,11 +603,12 @@
     }
   }
 
-  /// Given some [Comment], compute and return the parent directory absolute
-  /// path which contains the directories 'examples/api/'. Null is returned if
-  /// such directories are not found.
+  /// Given some [AstNode], compute and return the parent directory absolute
+  /// path which contains the directories 'examples/api/'.
+  ///
+  /// Null is returned if such directories are not found.
   String? _computeParentWithExamplesAPI(
-      Comment node, ResourceProvider resourceProvider) {
+      AstNode node, ResourceProvider resourceProvider) {
     var source =
         node.thisOrAncestorOfType<CompilationUnit>()?.declaredElement?.source;
     if (source == null) {
diff --git a/pkg/analyzer_plugin/lib/utilities/range_factory.dart b/pkg/analyzer_plugin/lib/utilities/range_factory.dart
index 6a8789c..6ed5dc9 100644
--- a/pkg/analyzer_plugin/lib/utilities/range_factory.dart
+++ b/pkg/analyzer_plugin/lib/utilities/range_factory.dart
@@ -78,6 +78,8 @@
               type == TokenType.MULTI_LINE_COMMENT)) {
         var firstToken = node.firstTokenAfterCommentAndMetadata;
         startOffset = firstToken.previous!.end;
+      } else if (begin.previous!.isEof) {
+        startOffset = begin.offset;
       } else {
         startOffset = begin.previous!.end;
       }
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml
index 29516fa..cf785ea 100644
--- a/pkg/analyzer_plugin/pubspec.yaml
+++ b/pkg/analyzer_plugin/pubspec.yaml
@@ -1,13 +1,13 @@
 name: analyzer_plugin
 description: A framework and support code for building plugins for the analysis server.
-version: 0.11.1
+version: 0.11.2
 repository: https://github.com/dart-lang/sdk/tree/main/pkg/analyzer_plugin
 
 environment:
   sdk: '>=2.17.0 <3.0.0'
 
 dependencies:
-  analyzer: ^4.3.0
+  analyzer: ^5.0.0
   collection: ^1.15.0
   dart_style: ^2.2.1
   pub_semver: ^2.0.0
@@ -20,6 +20,7 @@
 dev_dependencies:
   analyzer_utilities: any
   lints: any
+  linter: any
   meta: any
   path: any
   test_reflective_loader: any
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
index 39598e0..c11b7d6 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
@@ -456,6 +456,48 @@
     expect(edits[1].replacement, text);
   }
 
+  Future<void> test_addSimpleInsertion_updatesSelection_futureEdits() async {
+    // Set a selection position.
+    builder.setSelection(Position(path, 5));
+
+    // Ensure a simple insertion before the selection moves it along by this
+    // length.
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addSimpleInsertion(0, '123');
+    });
+    expect(builder.sourceChange.selection, Position(path, 8));
+  }
+
+  Future<void>
+      test_addSimpleInsertion_updatesSelectionRange_futureEdits() async {
+    // Set a selection range.
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addInsertion(5, (builder) => builder.selectHere());
+    });
+
+    // Ensure a simple insertion before the selection moves it along by this
+    // length.
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addSimpleInsertion(0, '123');
+    });
+    expect(builder.selectionRange, SourceRange(8, 0));
+  }
+
+  Future<void> test_addSimpleInsertion_updatesSelections_priorEdits() async {
+    // Insert some text at the start.
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addSimpleInsertion(0, '123');
+    });
+
+    // Ensure a subsequent insertion has its selection offset to account for
+    // the insertion above.
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addInsertion(5, (builder) => builder.selectHere());
+    });
+    expect(builder.sourceChange.selection, Position(path, 8));
+    expect(builder.selectionRange, SourceRange(8, 0));
+  }
+
   Future<void> test_addSimpleReplacement() async {
     var offset = 23;
     var length = 7;
@@ -538,6 +580,32 @@
       expect(sourceEdit.replacement, isEmpty);
     });
   }
+
+  Future<void> test_setSelection_clearsSelectionRange() async {
+    // Set a selection range.
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addInsertion(0, (builder) => builder.selectHere());
+    });
+
+    // Ensure setting a selection position removes the range.
+    expect(builder.selectionRange, isNotNull);
+    builder.setSelection(Position(path, 0));
+    expect(builder.selectionRange, isNull);
+  }
+
+  Future<void> test_setSelectionRange_updatesSelection() async {
+    // Set a selection position.
+    builder.setSelection(Position(path, 0));
+
+    // Ensure setting a selection range moves the position to the new offset.
+    await builder.addGenericFileEdit(path, (builder) {
+      builder.addInsertion(0, (builder) {
+        builder.write('123');
+        builder.selectHere();
+      });
+    });
+    expect(builder.sourceChange.selection, Position(path, 3));
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index abaa99d..7d355e8 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -15,6 +15,7 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart'
     show DartLinkedEditBuilderImpl;
+import 'package:linter/src/rules.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -61,6 +62,22 @@
   Future<void> test_writeType_Never_question() async {
     await _assertWriteType('Never?');
   }
+
+  Future<void> test_writeType_recordType_mixed() async {
+    await _assertWriteType('(int, {int y})');
+  }
+
+  Future<void> test_writeType_recordType_named() async {
+    await _assertWriteType('({int x, int y})');
+  }
+
+  Future<void> test_writeType_recordType_nullable() async {
+    await _assertWriteType('(int, {int y})?');
+  }
+
+  Future<void> test_writeType_recordType_positional() async {
+    await _assertWriteType('(int, int)');
+  }
 }
 
 @reflectiveTest
@@ -838,7 +855,7 @@
           initializerWriter: () {
             builder.write('null');
           },
-          type: A.declaredElement2?.instantiate(
+          type: A.declaredElement?.instantiate(
             typeArguments: [],
             nullabilitySuffix: NullabilitySuffix.star,
           ),
@@ -866,7 +883,7 @@
       builder.addInsertion(11, (builder) {
         builder.writeLocalVariableDeclaration(
           'foo',
-          type: A.declaredElement2?.instantiate(
+          type: A.declaredElement?.instantiate(
             typeArguments: [],
             nullabilitySuffix: NullabilitySuffix.star,
           ),
@@ -903,7 +920,7 @@
         builder.writeLocalVariableDeclaration(
           'foo',
           isFinal: true,
-          type: A.declaredElement2?.instantiate(
+          type: A.declaredElement?.instantiate(
             typeArguments: [],
             nullabilitySuffix: NullabilitySuffix.star,
           ),
@@ -1984,7 +2001,7 @@
     var classC = unit.declarations[2] as ClassDeclaration;
     var builder = DartLinkedEditBuilderImpl(MockEditBuilderImpl());
     builder.addSuperTypesAsSuggestions(
-      classC.declaredElement2?.instantiate(
+      classC.declaredElement?.instantiate(
         typeArguments: [],
         nullabilitySuffix: NullabilitySuffix.star,
       ),
@@ -2072,6 +2089,88 @@
     );
   }
 
+  Future<void> test_default_quote() async {
+    await _assertImportLibrary(
+      initialCode: '''
+''',
+      uriList: ['dart:aaa'],
+      expectedCode: '''
+import 'dart:aaa';
+''',
+    );
+  }
+
+  Future<void> test_directive_adjacent_strings() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:' "async";
+''',
+      uriList: ['dart:aaa'],
+      expectedCode: '''
+import 'dart:aaa';
+import 'dart:' "async";
+''',
+    );
+  }
+
+  Future<void> test_directive_common_double_quote() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import "dart:async";
+import "dart:math";
+import 'dart:bbb';
+''',
+      uriList: ['dart:aaa'],
+      expectedCode: '''
+import "dart:aaa";
+import "dart:async";
+import "dart:math";
+import 'dart:bbb';
+''',
+    );
+  }
+
+  Future<void> test_directive_common_single_quote() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import "dart:math";
+import 'dart:bbb';
+''',
+      uriList: ['dart:aaa'],
+      expectedCode: '''
+import 'dart:aaa';
+import "dart:math";
+import 'dart:bbb';
+''',
+    );
+  }
+
+  Future<void> test_directive_double_quote() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import "dart:bbb";
+''',
+      uriList: ['dart:aaa'],
+      expectedCode: '''
+import "dart:aaa";
+import "dart:bbb";
+''',
+    );
+  }
+
+  Future<void> test_directive_single_quote() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:bbb';
+''',
+      uriList: ['dart:aaa'],
+      expectedCode: '''
+import 'dart:aaa';
+import 'dart:bbb';
+''',
+    );
+  }
+
   Future<void> test_multiple_dart_then_package() async {
     await _assertImportLibrary(
       initialCode: '''
@@ -2379,6 +2478,36 @@
     );
   }
 
+  Future<void> test_prefer_double_quotes() async {
+    registerLintRules();
+    writeTestPackageAnalysisOptionsFile(lints: ['prefer_double_quotes']);
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:bbb';
+''',
+      uriList: ['dart:aaa'],
+      expectedCode: '''
+import "dart:aaa";
+import 'dart:bbb';
+''',
+    );
+  }
+
+  Future<void> test_prefer_single_quotes() async {
+    registerLintRules();
+    writeTestPackageAnalysisOptionsFile(lints: ['prefer_single_quotes']);
+    await _assertImportLibrary(
+      initialCode: '''
+import "dart:bbb";
+''',
+      uriList: ['dart:aaa'],
+      expectedCode: '''
+import 'dart:aaa';
+import "dart:bbb";
+''',
+    );
+  }
+
   Future<void> test_relative_afterDart() async {
     await _assertImportLibrary(
       initialCode: '''
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
index ab696eb..c48664f 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
@@ -960,7 +960,7 @@
   }
 
   static String _executableNameStr(ExecutableElement executable) {
-    var executableEnclosing = executable.enclosingElement3;
+    var executableEnclosing = executable.enclosingElement;
     if (executableEnclosing is CompilationUnitElement) {
       return executable.name;
     } else if (executable is ConstructorElement) {
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index 2ce11d7..d8ef43f 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -1356,7 +1356,6 @@
     await assertOpType();
   }
 
-//
   Future<void> test_forStatement_initializer_type() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {List a; for (i^ v = 0;)}');
@@ -2224,6 +2223,145 @@
         voidReturn: true);
   }
 
+  Future<void> test_recordLiteral_fieldName() async {
+    addTestSource('final x = (foo^: 0)');
+    await assertOpType(
+      completionLocation: 'RecordLiteral_fields',
+    );
+  }
+
+  Future<void> test_recordLiteral_fields() async {
+    addTestSource('final x = (0, ^)');
+    await assertOpType(
+      completionLocation: 'RecordLiteral_fields',
+      constructors: true,
+      returnValue: true,
+      typeNames: true,
+    );
+  }
+
+  Future<void> test_recordTypeAnnotation_named_comma_prefix_x_right() async {
+    addTestSource('({int f01, Str^}) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotationNamedFields_fields',
+      typeNames: true,
+    );
+  }
+
+  Future<void>
+      test_recordTypeAnnotation_named_comma_prefix_x_suffix_right() async {
+    addTestSource('({int f01, Str^ng}) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotationNamedFields_fields',
+      typeNames: true,
+    );
+  }
+
+  Future<void>
+      test_recordTypeAnnotation_named_comma_type_space_prefix_x_right() async {
+    addTestSource('({int f01, String ^}) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotationNamedField_name',
+      varNames: true,
+    );
+  }
+
+  Future<void>
+      test_recordTypeAnnotation_named_comma_type_x_space_name_right() async {
+    addTestSource('({int foo, String^ str}) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotationNamedFields_fields',
+      typeNames: true,
+    );
+  }
+
+  Future<void> test_recordTypeAnnotation_named_comma_x_right() async {
+    addTestSource('({int f01, ^}) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotationNamedFields_fields',
+      typeNames: true,
+    );
+  }
+
+  Future<void>
+      test_recordTypeAnnotation_named_comma_x_space_named_right() async {
+    addTestSource('({int f01, ^ f02}) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotationNamedFields_fields',
+      typeNames: true,
+    );
+  }
+
+  Future<void> test_recordTypeAnnotation_named_comma_x_space_right() async {
+    addTestSource('({int f01, ^ }) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotationNamedFields_fields',
+      typeNames: true,
+    );
+  }
+
+  Future<void>
+      test_recordTypeAnnotation_positional_comma_prefix_x_right() async {
+    addTestSource('(int, Str^) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotation_positionalFields',
+      typeNames: true,
+    );
+  }
+
+  Future<void>
+      test_recordTypeAnnotation_positional_comma_type_space_prefix_x_right() async {
+    addTestSource('(int, String str^) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotationPositionalField_name',
+      varNames: true,
+    );
+  }
+
+  Future<void>
+      test_recordTypeAnnotation_positional_comma_type_space_x_right() async {
+    addTestSource('(int, String ^) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotation_positionalFields',
+      varNames: true,
+    );
+  }
+
+  Future<void>
+      test_recordTypeAnnotation_positional_comma_type_space_x_space_right() async {
+    addTestSource('(int, String ^ ) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotation_positionalFields',
+      varNames: true,
+    );
+  }
+
+  Future<void>
+      test_recordTypeAnnotation_positional_comma_type_x_space_name_right() async {
+    addTestSource('(int, String^ str) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotation_positionalFields',
+      typeNames: true,
+    );
+  }
+
+  Future<void> test_recordTypeAnnotation_positional_comma_x_right() async {
+    addTestSource('(int, ^) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotation_positionalFields',
+      typeNames: true,
+    );
+  }
+
+  Future<void>
+      test_recordTypeAnnotation_positional_comma_x_space_name_right() async {
+    addTestSource('(int, ^ str) f() {}');
+    await assertOpType(
+      completionLocation: 'RecordTypeAnnotation_positionalFields',
+      typeNames: true,
+    );
+  }
+
   Future<void> test_returnStatement_empty_noSemicolon() async {
     addTestSource('f() { return ^ }');
     await assertOpType(
diff --git a/pkg/analyzer_plugin/test/support/abstract_context.dart b/pkg/analyzer_plugin/test/support/abstract_context.dart
index 7663cde..8b14c9b 100644
--- a/pkg/analyzer_plugin/test/support/abstract_context.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_context.dart
@@ -126,6 +126,25 @@
     newFile(path, config.toContent(toUriStr: toUriStr));
   }
 
+  /// Write an analysis options file based on the given arguments.
+  /// TODO(asashour) Use AnalysisOptionsFileConfig
+  void writeTestPackageAnalysisOptionsFile({
+    List<String>? lints,
+  }) {
+    var buffer = StringBuffer();
+
+    if (lints != null) {
+      buffer.writeln('linter:');
+      buffer.writeln('  rules:');
+      for (var lint in lints) {
+        buffer.writeln('    - $lint');
+      }
+    }
+
+    print(buffer);
+    newFile('$testPackageRootPath/analysis_options.yaml', buffer.toString());
+  }
+
   void writeTestPackageConfig({
     PackageConfigFileBuilder? config,
     String? languageVersion,
diff --git a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
index 10e9c9f..8520e20 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
@@ -1777,7 +1777,7 @@
   }
 
   Future<void> test_FieldFormalParameter_in_non_constructor() async {
-    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('class A {B(this.^foo) {}}');
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
diff --git a/pkg/analyzer_plugin/test/utilities/range_factory_test.dart b/pkg/analyzer_plugin/test/utilities/range_factory_test.dart
index ad2aacb..b7729fb 100644
--- a/pkg/analyzer_plugin/test/utilities/range_factory_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/range_factory_test.dart
@@ -480,6 +480,14 @@
 ''');
   }
 
+  Future<void> test_deletionRange_only() async {
+    await _deletionRange(declarationIndex: 0, '''
+class A {}
+''', expected: '''
+
+''');
+  }
+
   Future<void> test_deletionRange_variableDeclaration() async {
     await _deletionRange(declarationIndex: 0, '''
 var x = 1;
@@ -510,7 +518,7 @@
   Future<void> test_endEnd() async {
     await resolveTestCode('main() {}');
     var mainFunction = testUnit.declarations[0] as FunctionDeclaration;
-    var mainName = mainFunction.name2;
+    var mainName = mainFunction.name;
     var mainBody = mainFunction.functionExpression.body;
     expect(range.endEnd(mainName, mainBody), SourceRange(4, 5));
   }
@@ -518,14 +526,14 @@
   Future<void> test_endLength() async {
     await resolveTestCode('main() {}');
     var mainFunction = testUnit.declarations[0] as FunctionDeclaration;
-    var mainName = mainFunction.name2;
+    var mainName = mainFunction.name;
     expect(range.endLength(mainName, 3), SourceRange(4, 3));
   }
 
   Future<void> test_endStart() async {
     await resolveTestCode('main() {}');
     var mainFunction = testUnit.declarations[0] as FunctionDeclaration;
-    var mainName = mainFunction.name2;
+    var mainName = mainFunction.name;
     var mainBody = mainFunction.functionExpression.body;
     expect(range.endStart(mainName, mainBody), SourceRange(4, 3));
   }
@@ -566,7 +574,7 @@
   Future<void> test_startEnd_nodeNode() async {
     await resolveTestCode(' main() {}');
     var mainFunction = testUnit.declarations[0] as FunctionDeclaration;
-    var mainName = mainFunction.name2;
+    var mainName = mainFunction.name;
     var mainBody = mainFunction.functionExpression.body;
     expect(range.startEnd(mainName, mainBody), SourceRange(1, 9));
   }
@@ -593,7 +601,7 @@
   Future<void> test_token() async {
     await resolveTestCode(' main() {}');
     var mainFunction = testUnit.declarations[0] as FunctionDeclaration;
-    var mainName = mainFunction.name2;
+    var mainName = mainFunction.name;
     expect(range.token(mainName), SourceRange(1, 4));
   }
 
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart b/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
index 40d6e68..50e5978 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
@@ -25,6 +25,15 @@
     codeGeneratorSettings.languageName = 'dart';
   }
 
+  /// Generate the given [constant].
+  void generateConstant(_Constant constant) {
+    write('const String ');
+    write(constant.name);
+    write(' = ');
+    write(constant.value);
+    writeln(';');
+  }
+
   /// Generate all of the constants associated with the [api].
   void generateConstants() {
     var visitor = _ConstantVisitor(api);
@@ -32,19 +41,10 @@
     var constants = visitor.constants;
     constants.sort((first, second) => first.name.compareTo(second.name));
     for (var constant in constants) {
-      generateContant(constant);
+      generateConstant(constant);
     }
   }
 
-  /// Generate the given [constant].
-  void generateContant(_Constant constant) {
-    write('const String ');
-    write(constant.name);
-    write(' = ');
-    write(constant.value);
-    writeln(';');
-  }
-
   @override
   void visitApi() {
     outputHeader(year: '2017');
diff --git a/pkg/analyzer_utilities/lib/check/bool.dart b/pkg/analyzer_utilities/lib/check/bool.dart
deleted file mode 100644
index 1b13751..0000000
--- a/pkg/analyzer_utilities/lib/check/bool.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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 isFalse {
-    if (value) {
-      fail('is not false');
-    }
-  }
-
-  void get isTrue {
-    if (!value) {
-      fail('is not true');
-    }
-  }
-}
diff --git a/pkg/analyzer_utilities/lib/check/check.dart b/pkg/analyzer_utilities/lib/check/check.dart
deleted file mode 100644
index 54b57c9..0000000
--- a/pkg/analyzer_utilities/lib/check/check.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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/nullability.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
deleted file mode 100644
index c7e33f5..0000000
--- a/pkg/analyzer_utilities/lib/check/check_target.dart
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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);
-
-  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)}';
-    });
-  }
-
-  String valueStr(value) {
-    if (value is String) {
-      return "'$value'";
-    }
-    return '$value';
-  }
-
-  /// Use this if multiple checks are required on the value.
-  void which(void Function(CheckTarget<T> e) checker) {
-    checker(this);
-  }
-}
diff --git a/pkg/analyzer_utilities/lib/check/equality.dart b/pkg/analyzer_utilities/lib/check/equality.dart
deleted file mode 100644
index 9701bb3..0000000
--- a/pkg/analyzer_utilities/lib/check/equality.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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 isIdenticalTo(Object? other) {
-    if (!identical(value, other)) {
-      fail('is not identical 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
deleted file mode 100644
index 59587b2..0000000
--- a/pkg/analyzer_utilities/lib/check/int.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 0b921bf..0000000
--- a/pkg/analyzer_utilities/lib/check/iterable.dart
+++ /dev/null
@@ -1,199 +0,0 @@
-// 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';
-import 'package:test/test.dart' as test_package;
-
-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');
-    }
-  }
-
-  /// Succeeds if there is an element that matches the [matcher],
-  void containsMatch(void Function(CheckTarget<T> element) matcher) {
-    var elementList = value.toList();
-    for (var i = 0; i < elementList.length; i++) {
-      if (_matches(elementList, i, matcher)) {
-        return;
-      }
-    }
-    fail('Does not contain at least one element that matches');
-  }
-
-  /// Fails if for any matcher there is an element that matches.
-  void excludesAll(
-    Iterable<void Function(CheckTarget<T> element)> matchers,
-  ) {
-    var elementList = value.toList();
-    var matcherList = matchers.toList();
-    var included = <int>[];
-    for (var i = 0; i < matcherList.length; i++) {
-      var matcher = matcherList[i];
-      for (var j = 0; j < elementList.length; j++) {
-        if (_matches(elementList, j, matcher)) {
-          included.add(i);
-          break;
-        }
-      }
-    }
-    if (included.isNotEmpty) {
-      fail('Unexpectedly includes matchers at ${valueStr(included)}');
-    }
-  }
-
-  @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');
-  }
-
-  /// Succeeds if for each matcher in [matchers] there is at least one
-  /// matching element.
-  void includesAll(
-    Iterable<void Function(CheckTarget<T> element)> matchers,
-  ) {
-    var elementList = value.toList();
-    var matcherList = matchers.toList();
-    var notIncluded = <int>[];
-    for (var i = 0; i < matcherList.length; i++) {
-      var matcher = matcherList[i];
-      notIncluded.add(i);
-      for (var j = 0; j < elementList.length; j++) {
-        if (_matches(elementList, j, matcher)) {
-          notIncluded.removeLast();
-          break;
-        }
-      }
-    }
-    if (notIncluded.isNotEmpty) {
-      fail('Does not include matchers at ${valueStr(notIncluded)}');
-    }
-  }
-
-  /// Succeeds if for each matcher there is exactly one matching element,
-  /// in the same relative order.
-  void includesAllInOrder(
-    Iterable<void Function(CheckTarget<T> element)> matchers,
-  ) {
-    var elementList = value.toList();
-    var matcherList = matchers.toList();
-    var elementIndex = 0;
-    for (var i = 0; i < matcherList.length; i++) {
-      var matcher = matcherList[i];
-      var hasMatch = false;
-      for (; elementIndex < elementList.length; elementIndex++) {
-        if (_matches(elementList, elementIndex, matcher)) {
-          hasMatch = true;
-          for (var j = elementIndex + 1; j < elementList.length; j++) {
-            if (_matches(elementList, j, matcher)) {
-              fail(
-                'Matcher at ${valueStr(i)} matches elements at '
-                '${valueStr(elementIndex)} and ${valueStr(j)}',
-              );
-            }
-          }
-          break;
-        } else {}
-      }
-      if (!hasMatch) {
-        fail('Does not include matcher at ${valueStr(i)}');
-      }
-    }
-  }
-
-  /// Succeeds if the number of [matchers] is exactly the same as the number
-  /// of elements in [value], and each matcher matches the element at the
-  /// corresponding index.
-  void matches(
-    Iterable<void Function(CheckTarget<T> element)> matchers,
-  ) {
-    var elementList = value.toList();
-    var matcherList = matchers.toList();
-    if (elementList.length != matcherList.length) {
-      fail('Expected ${valueStr(matcherList.length)} elements, '
-          'actually ${valueStr(elementList.length)}');
-    }
-
-    for (var index = 0; index < matcherList.length; index++) {
-      var element = elementList[index];
-      var matcher = matcherList[index];
-      matcher(
-        nest(
-          element,
-          (element) => 'element ${valueStr(element)} at ${valueStr(index)}',
-        ),
-      );
-    }
-  }
-
-  /// Succeeds if the number of [matchers] is exactly the same as the number
-  /// of elements in [value], and for each matcher there is exactly one element
-  /// that matches.
-  void matchesInAnyOrder(
-    Iterable<void Function(CheckTarget<T> element)> matchers,
-  ) {
-    var elementList = value.toList();
-    var matcherList = matchers.toList();
-    if (elementList.length != matcherList.length) {
-      fail('Expected ${valueStr(matcherList.length)} elements, '
-          'actually ${valueStr(elementList.length)}');
-    }
-
-    for (var matcherIndex = 0;
-        matcherIndex < matcherList.length;
-        matcherIndex++) {
-      var matcher = matcherList[matcherIndex];
-      T? matchedElement;
-      for (var elementIndex = 0;
-          elementIndex < elementList.length;
-          elementIndex++) {
-        var element = elementList[elementIndex];
-        if (!_matches(elementList, elementIndex, matcher)) {
-          continue;
-        }
-        // The element matches, check that it is unique.
-        if (matchedElement == null) {
-          matchedElement = element;
-        } else {
-          fail('Already matched ${valueStr(matchedElement)}, '
-              'found ${valueStr(element)}');
-        }
-      }
-      if (matchedElement == null) {
-        fail('No match at ${valueStr(matcherIndex)}');
-      }
-    }
-  }
-
-  bool _matches(
-    List<T> elementList,
-    int index,
-    void Function(CheckTarget<T> element) matcher,
-  ) {
-    var elementTarget = nest(
-      elementList[index],
-      (element) => 'element ${valueStr(element)} at ${valueStr(index)}',
-    );
-    try {
-      matcher(elementTarget);
-      return true;
-    } on test_package.TestFailure {
-      return false;
-    }
-  }
-}
diff --git a/pkg/analyzer_utilities/lib/check/nullability.dart b/pkg/analyzer_utilities/lib/check/nullability.dart
deleted file mode 100644
index ef1860e..0000000
--- a/pkg/analyzer_utilities/lib/check/nullability.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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 NullabilityExtension<T> on CheckTarget<T?> {
-  CheckTarget<T> get isNotNull {
-    final value = this.value;
-    if (value == null) {
-      fail('is null');
-    }
-    return nest(value, (value) => 'is not null');
-  }
-
-  void get isNull {
-    if (value != null) {
-      fail('is not null');
-    }
-  }
-}
diff --git a/pkg/analyzer_utilities/lib/check/string.dart b/pkg/analyzer_utilities/lib/check/string.dart
deleted file mode 100644
index 75278b8..0000000
--- a/pkg/analyzer_utilities/lib/check/string.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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)}');
-    }
-  }
-
-  @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');
-  }
-
-  void startsWith(Pattern other) {
-    if (!value.startsWith(other)) {
-      fail('does not start with ${valueStr(other)}');
-    }
-  }
-}
diff --git a/pkg/analyzer_utilities/lib/check/type.dart b/pkg/analyzer_utilities/lib/check/type.dart
deleted file mode 100644
index c261e2a..0000000
--- a/pkg/analyzer_utilities/lib/check/type.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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> hasExactType<U extends T>() {
-    final value = this.value;
-    if (value.runtimeType == U) {
-      return nest(value as U, (_) => 'is of type $U');
-    } else {
-      fail('is not of type $U');
-    }
-  }
-
-  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/lib/verify_tests.dart b/pkg/analyzer_utilities/lib/verify_tests.dart
index bdbf86d..40aac89 100644
--- a/pkg/analyzer_utilities/lib/verify_tests.dart
+++ b/pkg/analyzer_utilities/lib/verify_tests.dart
@@ -59,7 +59,7 @@
   /// May be overridden in a derived class to indicate whether it is ok for
   /// a `test_all.dart` file to be missing from [folder].
   ///
-  /// Default beahvior is not to allow `test_all.dart` to be missing from any
+  /// Default behavior is not to allow `test_all.dart` to be missing from any
   /// folder.
   bool isOkForTestAllToBeMissing(Folder folder) => false;
 
diff --git a/pkg/analyzer_utilities/pubspec.yaml b/pkg/analyzer_utilities/pubspec.yaml
index f803290..02779d2 100644
--- a/pkg/analyzer_utilities/pubspec.yaml
+++ b/pkg/analyzer_utilities/pubspec.yaml
@@ -8,7 +8,6 @@
 # Use 'any' constraints here; we get our versions from the DEPS file.
 dependencies:
   analyzer: any
-  meta: any
   path: any
   test: any
 
diff --git a/pkg/analyzer_utilities/test/check/check_test.dart b/pkg/analyzer_utilities/test/check/check_test.dart
deleted file mode 100644
index 0f9bda1..0000000
--- a/pkg/analyzer_utilities/test/check/check_test.dart
+++ /dev/null
@@ -1,366 +0,0 @@
-// 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('equality', () {
-      test('isIdenticalTo', () {
-        final a = Object();
-        final b = Object();
-        check(a).isIdenticalTo(a);
-        _fails(() => check(a).isIdenticalTo(b));
-      });
-    });
-    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('containsMatch', () {
-        check(<int>[0]).containsMatch((e) => e.isZero);
-        check(<int>[1, 0, 2]).containsMatch((e) => e.isZero);
-        _fails(() => check(<int>[]).containsMatch((e) => e.isZero));
-        _fails(() => check(<int>[1]).containsMatch((e) => e.isZero));
-      });
-      test('excludesAll', () {
-        check(<int>[]).excludesAll([
-          (e) => e.isEqualTo(0),
-        ]);
-        check([1]).excludesAll([
-          (e) => e.isEqualTo(0),
-          (e) => e.isEqualTo(2),
-        ]);
-        // Fails if any match.
-        _fails(() {
-          check(<int>[0]).excludesAll([
-            (e) => e.isEqualTo(0),
-          ]);
-        });
-        _fails(() {
-          check(<int>[0]).excludesAll([
-            (e) => e.isZero,
-          ]);
-        });
-        _fails(() {
-          check(<int>[0]).excludesAll([
-            (e) => e.isEqualTo(2),
-            (e) => e.isEqualTo(1),
-            (e) => e.isEqualTo(0),
-          ]);
-        });
-      });
-      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('includesAll', () {
-        // Extra elements are OK.
-        check([0, 1, 2]).includesAll([
-          (e) => e.isEqualTo(0),
-          (e) => e.isEqualTo(1),
-        ]);
-        // Order does not matter.
-        check([0, 1, 2]).includesAll([
-          (e) => e.isEqualTo(1),
-          (e) => e.isEqualTo(0),
-        ]);
-        // Must have all elements.
-        _fails(() {
-          check(<int>[]).includesAll([
-            (e) => e.isEqualTo(0),
-          ]);
-        });
-        _fails(() {
-          check([0]).includesAll([
-            (e) => e.isEqualTo(0),
-            (e) => e.isEqualTo(1),
-          ]);
-        });
-        _fails(() {
-          check([1]).includesAll([
-            (e) => e.isEqualTo(0),
-            (e) => e.isEqualTo(1),
-          ]);
-        });
-      });
-      test('includesAllInOrder', () {
-        // Extra elements are OK.
-        check([0, 1, 2, 3, 4]).includesAllInOrder([
-          (e) => e.isEqualTo(0),
-          (e) => e.isEqualTo(3),
-        ]);
-        // Exactly one element should match.
-        _fails(() {
-          check([0, 1, 0, 2]).includesAllInOrder([
-            (e) => e.isZero,
-          ]);
-        });
-        // Must be in the requested order.
-        _fails(() {
-          check([0, 1, 2]).includesAllInOrder([
-            (e) => e.isEqualTo(1),
-            (e) => e.isEqualTo(0),
-          ]);
-        });
-        // Must have all elements.
-        _fails(() {
-          check(<int>[]).includesAllInOrder([
-            (e) => e.isEqualTo(0),
-          ]);
-        });
-        _fails(() {
-          check([0]).includesAllInOrder([
-            (e) => e.isEqualTo(0),
-            (e) => e.isEqualTo(1),
-          ]);
-        });
-        _fails(() {
-          check([1]).includesAllInOrder([
-            (e) => e.isEqualTo(0),
-            (e) => e.isEqualTo(1),
-          ]);
-        });
-      });
-      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);
-      });
-      test('matches', () {
-        check(<int>[]).matches([]);
-        check(<int>[0]).matches([
-          (e) => e.isEqualTo(0),
-        ]);
-        check(<int>[0, 1]).matches([
-          (e) => e.isEqualTo(0),
-          (e) => e.isEqualTo(1),
-        ]);
-        // Order is important.
-        _fails(
-          () => check([0, 1]).matches([
-            (e) => e.isEqualTo(1),
-            (e) => e.isEqualTo(0),
-          ]),
-        );
-        // Too few matchers.
-        _fails(
-          () => check([0, 1]).matches([
-            (e) => e.isEqualTo(0),
-          ]),
-        );
-        // Too many matchers.
-        _fails(
-          () => check([0]).matches([
-            (e) => e.isEqualTo(0),
-            (e) => e.isEqualTo(1),
-          ]),
-        );
-      });
-      test('matchesInAnyOrder', () {
-        // Order does not matter.
-        check([0, 1]).matchesInAnyOrder([
-          (e) => e.isEqualTo(0),
-          (e) => e.isEqualTo(1),
-        ]);
-        check([0, 1]).matchesInAnyOrder([
-          (e) => e.isEqualTo(1),
-          (e) => e.isEqualTo(0),
-        ]);
-        // Matchers can be different.
-        check([0, 1]).matchesInAnyOrder([
-          (e) => e.isZero,
-          (e) => e.isEqualTo(1),
-        ]);
-        check([0, 10]).matchesInAnyOrder([
-          (e) => e.isZero,
-          (e) => e.isGreaterThan(5),
-        ]);
-        // Wrong number of matchers.
-        _fails(
-          () => check([0, 1]).matchesInAnyOrder([
-            (e) => e.isZero,
-          ]),
-        );
-        // The first matcher accepts more than one element.
-        _fails(
-          () => check([1, 2]).matchesInAnyOrder([
-            (e) => e.isGreaterThan(0),
-            (e) => e.isEqualTo(2),
-          ]),
-        );
-        // The second matcher accepts more than one element.
-        _fails(
-          () => check([1, 2]).matchesInAnyOrder([
-            (e) => e.isEqualTo(2),
-            (e) => e.isGreaterThan(0),
-          ]),
-        );
-      });
-    });
-    group('nullability', () {
-      // ignore: unnecessary_nullable_for_final_variable_declarations
-      const int? notNullable = 0;
-      const int? nullable = null;
-      test('isNotNull', () {
-        check(notNullable).isNotNull;
-        _fails(() => check(nullable).isNotNull.isZero);
-      });
-      test('isNull', () {
-        check(nullable).isNull;
-        _fails(() => check(notNullable).isNull);
-      });
-    });
-    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('hasExactType', () {
-        check(42).hasExactType<int>();
-        _fails(() => check(42 as dynamic).hasExactType<num>());
-      });
-      test('isA', () {
-        check(0).isA<int>();
-        _fails(() => check('abc' as dynamic).isA<int>());
-      });
-    });
-    test('which', () {
-      check(0).which((e) => e.isZero);
-      _fails(() => check(1).which((e) => e.isZero));
-    });
-  });
-}
-
-void _fails(void Function() f) {
-  try {
-    f();
-  } on TestFailure {
-    return;
-  }
-  fail('expected to fail');
-}
diff --git a/pkg/compiler/analysis_options.yaml b/pkg/compiler/analysis_options.yaml
index 1645941..c2ef0bc 100644
--- a/pkg/compiler/analysis_options.yaml
+++ b/pkg/compiler/analysis_options.yaml
@@ -14,3 +14,4 @@
     - prefer_final_fields
     - prefer_if_null_operators
     - prefer_null_aware_operators
+    - use_super_parameters
diff --git a/pkg/compiler/lib/src/call_graph/applies_to.dart b/pkg/compiler/lib/src/call_graph/applies_to.dart
new file mode 100644
index 0000000..74b49ed
--- /dev/null
+++ b/pkg/compiler/lib/src/call_graph/applies_to.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2022, 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:compiler/src/common/names.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/inferrer/abstract_value_domain.dart';
+import 'package:compiler/src/world_interfaces.dart';
+import 'package:compiler/src/universe/selector.dart';
+
+class MemberAppliesTo {
+  final MemberEntity member;
+  AbstractValue mask;
+
+  MemberAppliesTo(this.member, this.mask);
+
+  @override
+  String toString() => 'MemberAppliesTo($member:$mask)';
+}
+
+class MemberAppliesToBuilder {
+  final JClosedWorld _closedWorld;
+  final Map<Selector, Iterable<MemberAppliesTo>> _memberSetsBySelector = {};
+  final Map<Selector, List<MemberEntity>> _membersBySelector = {};
+
+  MemberAppliesToBuilder(this._closedWorld) {
+    for (final member in _closedWorld.liveInstanceMembers) {
+      if (member.isFunction || member.isGetter || member.isSetter) {
+        (_membersBySelector[Selector.fromElement(member)] ??= []).add(member);
+      }
+    }
+  }
+
+  Iterable<MemberAppliesTo> _buildSets(Selector selector) {
+    final List<MemberAppliesTo> memberSets = [];
+    final members = _membersBySelector.remove(selector);
+    if (members == null) {
+      return selector == Selectors.noSuchMethod_
+          ? const []
+          : forSelector(Selectors.noSuchMethod_);
+    }
+    for (final member in members) {
+      // TODO(fishythefish): Use type cone mask here.
+      final mask = _closedWorld.abstractValueDomain
+          .createNonNullSubclass(member.enclosingClass!);
+      final memberSet = MemberAppliesTo(member, mask);
+      memberSets.add(memberSet);
+    }
+    return memberSets;
+  }
+
+  Iterable<MemberAppliesTo> forSelector(Selector selector) =>
+      _memberSetsBySelector[selector] ??= _buildSets(selector);
+}
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index e3ba5f5..e889b07 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -2,13 +2,12 @@
 // 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.10
-
 import 'package:kernel/ast.dart' as ir;
 import 'common.dart';
 import 'elements/entities.dart';
 import 'js_model/closure.dart';
-import 'js_model/element_map.dart';
+import 'js_model/element_map_interfaces.dart';
+import 'js_model/element_map_migrated.dart';
 import 'serialization/serialization.dart';
 
 export 'closure_migrated.dart'
@@ -88,7 +87,6 @@
       case ScopeInfoKind.closureRepresentationInfo:
         return JsClosureClassInfo.readFromDataSource(source);
     }
-    throw UnsupportedError('Unexpected ScopeInfoKind $kind');
   }
 
   /// Serializes this [ScopeInfo] to [sink].
@@ -98,7 +96,7 @@
 
   /// Convenience reference pointer to the element representing `this`.
   /// If this scope is not in an instance member, it will be null.
-  Local get thisLocal => null;
+  Local? get thisLocal => null;
 
   /// Returns true if this [variable] is used inside a `try` block or a `sync*`
   /// generator (this is important to know because boxing/redirection needs to
@@ -147,7 +145,6 @@
       case ScopeInfoKind.capturedLoopScope:
         return JsCapturedLoopScope.readFromDataSource(source);
     }
-    throw UnsupportedError('Unexpected ScopeInfoKind $kind');
   }
 
   /// If true, this closure accesses a variable that was defined in an outside
@@ -161,7 +158,7 @@
   /// executed. This will encapsulate the value of any variables that have been
   /// scoped into this context from outside. This is an accessor to the
   /// contextBox that [requiresContextBox] is testing is required.
-  Local get contextBox => null;
+  Local? get contextBox => null;
 }
 
 /// Class that describes the actual mechanics of how values of variables
@@ -193,7 +190,6 @@
       case ScopeInfoKind.capturedLoopScope:
         return JsCapturedLoopScope.readFromDataSource(source);
     }
-    throw UnsupportedError('Unexpected ScopeInfoKind $kind');
   }
 
   /// True if this loop scope declares in the first part of the loop
@@ -263,27 +259,26 @@
       case ScopeInfoKind.closureRepresentationInfo:
         return JsClosureClassInfo.readFromDataSource(source);
     }
-    throw UnsupportedError('Unexpected ScopeInfoKind $kind');
   }
 
   /// The original local function before any translation.
   ///
   /// Will be null for methods.
-  Local getClosureEntity(KernelToLocalsMap localsMap) => null;
+  Local? getClosureEntity(KernelToLocalsMap localsMap) => null;
 
   /// The entity for the class used to represent the rewritten closure in the
   /// emitted JavaScript.
   ///
   /// Closures are rewritten in the form of classes that have fields to control
   /// the redirection and editing of captured variables.
-  ClassEntity get closureClassEntity => null;
+  ClassEntity? get closureClassEntity => null;
 
   /// The function that implements the [local] function as a `call` method on
   /// the closure class.
-  FunctionEntity get callMethod => null;
+  FunctionEntity? get callMethod => null;
 
   /// The signature method for [callMethod] if needed.
-  FunctionEntity get signatureMethod => null;
+  FunctionEntity? get signatureMethod => null;
 
   /// List of locals that this closure class has created corresponding field
   /// entities for.
@@ -301,7 +296,7 @@
 
   /// Convenience pointer to the field entity representation in the closure
   /// class of the element representing `this`.
-  FieldEntity get thisFieldEntity => null;
+  FieldEntity? get thisFieldEntity => null;
 
   /// Loop through each variable that has been boxed in this closure class. Only
   /// captured variables that are mutated need to be "boxed" (which basically
diff --git a/pkg/compiler/lib/src/code_organization.md b/pkg/compiler/lib/src/code_organization.md
index 8fea527..e591518 100644
--- a/pkg/compiler/lib/src/code_organization.md
+++ b/pkg/compiler/lib/src/code_organization.md
@@ -1,6 +1,6 @@
 [comment]: WIP - code is being refactored...
 
-##General code organization of this pacakge
+##General code organization of this package
 
   lib/src/
     |- ...
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 8e83316..672bb8d 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -94,6 +94,7 @@
   static const String suppressWarnings = '--suppress-warnings';
   static const String terse = '--terse';
   static const String testMode = '--test-mode';
+  static const String experimentalInferrer = '--experimental-inferrer';
   static const String trustPrimitives = '--trust-primitives';
   static const String trustTypeAnnotations = '--trust-type-annotations';
   static const String trustJSInteropTypeAnnotations =
diff --git a/pkg/compiler/lib/src/common/elements.dart b/pkg/compiler/lib/src/common/elements.dart
index 9fc40de..e4cbdba 100644
--- a/pkg/compiler/lib/src/common/elements.dart
+++ b/pkg/compiler/lib/src/common/elements.dart
@@ -30,63 +30,63 @@
   CommonElements(this.dartTypes, this._env);
 
   /// The `Object` class defined in 'dart:core'.
-  late final ClassEntity objectClass = _findClass(coreLibrary, 'Object')!;
+  late final ClassEntity objectClass = _findClass(coreLibrary, 'Object');
 
   /// The `bool` class defined in 'dart:core'.
-  late final ClassEntity boolClass = _findClass(coreLibrary, 'bool')!;
+  late final ClassEntity boolClass = _findClass(coreLibrary, 'bool');
 
   /// The `num` class defined in 'dart:core'.
-  late final ClassEntity numClass = _findClass(coreLibrary, 'num')!;
+  late final ClassEntity numClass = _findClass(coreLibrary, 'num');
 
   /// The `int` class defined in 'dart:core'.
-  late final ClassEntity intClass = _findClass(coreLibrary, 'int')!;
+  late final ClassEntity intClass = _findClass(coreLibrary, 'int');
 
   /// The `double` class defined in 'dart:core'.
-  late final ClassEntity doubleClass = _findClass(coreLibrary, 'double')!;
+  late final ClassEntity doubleClass = _findClass(coreLibrary, 'double');
 
   /// The `String` class defined in 'dart:core'.
-  late final ClassEntity stringClass = _findClass(coreLibrary, 'String')!;
+  late final ClassEntity stringClass = _findClass(coreLibrary, 'String');
 
   /// The `Function` class defined in 'dart:core'.
-  late final ClassEntity functionClass = _findClass(coreLibrary, 'Function')!;
+  late final ClassEntity functionClass = _findClass(coreLibrary, 'Function');
 
   /// The `Resource` class defined in 'dart:core'.
-  late final ClassEntity resourceClass = _findClass(coreLibrary, 'Resource')!;
+  late final ClassEntity resourceClass = _findClass(coreLibrary, 'Resource');
 
   /// The `Symbol` class defined in 'dart:core'.
-  late final ClassEntity symbolClass = _findClass(coreLibrary, 'Symbol')!;
+  late final ClassEntity symbolClass = _findClass(coreLibrary, 'Symbol');
 
   /// The `Null` class defined in 'dart:core'.
-  late final ClassEntity nullClass = _findClass(coreLibrary, 'Null')!;
+  late final ClassEntity nullClass = _findClass(coreLibrary, 'Null');
 
   /// The `Type` class defined in 'dart:core'.
-  late final ClassEntity typeClass = _findClass(coreLibrary, 'Type')!;
+  late final ClassEntity typeClass = _findClass(coreLibrary, 'Type');
 
   /// The `StackTrace` class defined in 'dart:core';
   late final ClassEntity stackTraceClass =
-      _findClass(coreLibrary, 'StackTrace')!;
+      _findClass(coreLibrary, 'StackTrace');
 
   /// The `List` class defined in 'dart:core';
-  late final ClassEntity listClass = _findClass(coreLibrary, 'List')!;
+  late final ClassEntity listClass = _findClass(coreLibrary, 'List');
 
   /// The `Set` class defined in 'dart:core';
-  late final ClassEntity setClass = _findClass(coreLibrary, 'Set')!;
+  late final ClassEntity setClass = _findClass(coreLibrary, 'Set');
 
   /// The `Map` class defined in 'dart:core';
-  late final ClassEntity mapClass = _findClass(coreLibrary, 'Map')!;
+  late final ClassEntity mapClass = _findClass(coreLibrary, 'Map');
 
   /// The `Set` class defined in 'dart:core';
   late final ClassEntity unmodifiableSetClass =
-      _findClass(_env.lookupLibrary(Uris.dart_collection), '_UnmodifiableSet')!;
+      _findClass(collectionLibrary, '_UnmodifiableSet');
 
   /// The `Iterable` class defined in 'dart:core';
-  late final ClassEntity iterableClass = _findClass(coreLibrary, 'Iterable')!;
+  late final ClassEntity iterableClass = _findClass(coreLibrary, 'Iterable');
 
   /// The `Future` class defined in 'async';.
-  late final ClassEntity futureClass = _findClass(asyncLibrary, 'Future')!;
+  late final ClassEntity futureClass = _findClass(asyncLibrary, 'Future');
 
   /// The `Stream` class defined in 'async';
-  late final ClassEntity streamClass = _findClass(asyncLibrary, 'Stream')!;
+  late final ClassEntity streamClass = _findClass(asyncLibrary, 'Stream');
 
   /// The dart:core library.
   late final LibraryEntity coreLibrary =
@@ -95,14 +95,22 @@
   /// The dart:async library.
   late final LibraryEntity? asyncLibrary = _env.lookupLibrary(Uris.dart_async);
 
+  /// The dart:collection library.
+  late final LibraryEntity? collectionLibrary =
+      _env.lookupLibrary(Uris.dart_collection);
+
   /// The dart:mirrors library.
   /// Null if the program doesn't access dart:mirrors.
   late final LibraryEntity? mirrorsLibrary =
       _env.lookupLibrary(Uris.dart_mirrors);
 
   /// The dart:typed_data library.
-  late final LibraryEntity? typedDataLibrary =
-      _env.lookupLibrary(Uris.dart__native_typed_data);
+  late final LibraryEntity typedDataLibrary =
+      _env.lookupLibrary(Uris.dart__native_typed_data, required: true)!;
+
+  /// The dart:_js_shared_embedded_names library.
+  late final LibraryEntity sharedEmbeddedNamesLibrary =
+      _env.lookupLibrary(Uris.dart__js_shared_embedded_names, required: true)!;
 
   /// The dart:_js_helper library.
   late final LibraryEntity? jsHelperLibrary =
@@ -141,7 +149,7 @@
 
   /// The `NativeTypedData` class from dart:typed_data.
   ClassEntity get typedDataClass =>
-      _findClass(typedDataLibrary, 'NativeTypedData')!;
+      _findClass(typedDataLibrary, 'NativeTypedData');
 
   /// Constructor of the `Symbol` class in dart:internal.
   ///
@@ -152,7 +160,7 @@
     // so this cannot be found in kernel. Find a consistent way to handle
     // this and similar cases.
     return _symbolConstructorTarget ??=
-        _findConstructor(symbolImplementationClass, '');
+        _env.lookupConstructor(symbolImplementationClass, '')!;
   }
 
   void _ensureSymbolConstructorDependencies() {
@@ -161,21 +169,22 @@
     if (_symbolConstructorTarget == null) {
       if (_symbolImplementationClass == null) {
         _symbolImplementationClass =
-            _findClass(internalLibrary, 'Symbol', required: false);
+            _findClassOrNull(internalLibrary, 'Symbol');
       }
       if (_symbolImplementationClass != null) {
-        _symbolConstructorTarget =
-            _findConstructor(_symbolImplementationClass!, '', required: false);
+        _symbolConstructorTarget = _env.lookupConstructor(
+            _symbolImplementationClass!, '',
+            required: false);
       }
     }
     if (_symbolClass == null) {
-      _symbolClass = _findClass(coreLibrary, 'Symbol', required: false);
+      _symbolClass = _findClassOrNull(coreLibrary, 'Symbol');
     }
     if (_symbolClass == null) {
       return;
     }
     _symbolConstructorImplementationTarget =
-        _findConstructor(symbolClass, '', required: false);
+        _env.lookupConstructor(symbolClass, '', required: false);
   }
 
   /// Whether [element] is the same as [symbolConstructor].
@@ -310,10 +319,13 @@
     return _createInterfaceType(streamClass, [elementType]);
   }
 
-  ClassEntity? _findClass(LibraryEntity? library, String name,
-      {bool required = true}) {
+  ClassEntity _findClass(LibraryEntity? library, String name) {
+    return _env.lookupClass(library!, name, required: true)!;
+  }
+
+  ClassEntity? _findClassOrNull(LibraryEntity? library, String name) {
     if (library == null) return null;
-    return _env.lookupClass(library, name, required: required);
+    return _env.lookupClass(library, name, required: false);
   }
 
   T? _findLibraryMember<T extends MemberEntity>(
@@ -324,16 +336,17 @@
         setter: setter, required: required) as T?;
   }
 
-  T _findClassMember<T extends MemberEntity>(ClassEntity cls, String name,
-      {bool setter = false, bool required = true}) {
+  T? _findClassMemberOrNull<T extends MemberEntity>(
+      ClassEntity cls, String name) {
     return _env.lookupLocalClassMember(
-        cls, Name(name, cls.library.canonicalUri, isSetter: setter),
-        required: required) as T;
+        cls, Name(name, cls.library.canonicalUri, isSetter: false),
+        required: false) as T?;
   }
 
-  ConstructorEntity _findConstructor(ClassEntity cls, String name,
-      {bool required = true}) {
-    return _env.lookupConstructor(cls, name, required: required);
+  T _findClassMember<T extends MemberEntity>(ClassEntity cls, String name) {
+    return _env.lookupLocalClassMember(
+        cls, Name(name, cls.library.canonicalUri, isSetter: false),
+        required: true) as T;
   }
 
   /// Return the raw type of [cls].
@@ -387,17 +400,16 @@
     if (_mapLiteralClass == null) {
       _mapLiteralClass = _env.lookupClass(coreLibrary, 'LinkedHashMap');
       if (_mapLiteralClass == null) {
-        _mapLiteralClass = _findClass(
-            _env.lookupLibrary(Uris.dart_collection), 'LinkedHashMap');
+        _mapLiteralClass = _findClass(collectionLibrary, 'LinkedHashMap');
       }
     }
     return _mapLiteralClass!;
   }
 
   late final ConstructorEntity mapLiteralConstructor =
-      _env.lookupConstructor(mapLiteralClass, '_literal');
+      _env.lookupConstructor(mapLiteralClass, '_literal')!;
   late final ConstructorEntity mapLiteralConstructorEmpty =
-      _env.lookupConstructor(mapLiteralClass, '_empty');
+      _env.lookupConstructor(mapLiteralClass, '_empty')!;
   late final FunctionEntity mapLiteralUntypedMaker =
       _env.lookupLocalClassMember(mapLiteralClass,
               PrivateName('_makeLiteral', mapLiteralClass.library.canonicalUri))
@@ -408,12 +420,12 @@
           as FunctionEntity;
 
   late final ClassEntity setLiteralClass =
-      _findClass(_env.lookupLibrary(Uris.dart_collection), 'LinkedHashSet')!;
+      _findClass(collectionLibrary, 'LinkedHashSet');
 
   late final ConstructorEntity setLiteralConstructor =
-      _env.lookupConstructor(setLiteralClass, '_literal');
+      _env.lookupConstructor(setLiteralClass, '_literal')!;
   late final ConstructorEntity setLiteralConstructorEmpty =
-      _env.lookupConstructor(setLiteralClass, '_empty');
+      _env.lookupConstructor(setLiteralClass, '_empty')!;
   late final FunctionEntity setLiteralUntypedMaker =
       _env.lookupLocalClassMember(setLiteralClass,
               PrivateName('_makeLiteral', setLiteralClass.library.canonicalUri))
@@ -436,7 +448,7 @@
 
   // From dart:async
   ClassEntity _findAsyncHelperClass(String name) =>
-      _findClass(asyncLibrary, name)!;
+      _findClass(asyncLibrary, name);
 
   FunctionEntity _findAsyncHelperFunction(String name) =>
       _findLibraryMember(asyncLibrary, name)!;
@@ -489,7 +501,7 @@
   ClassEntity get streamIterator => _findAsyncHelperClass("StreamIterator");
 
   ConstructorEntity get streamIteratorConstructor =>
-      _env.lookupConstructor(streamIterator, "");
+      _env.lookupConstructor(streamIterator, "")!;
 
   late final FunctionEntity syncStarIterableFactory =
       _findAsyncHelperFunction('_makeSyncStarIterable');
@@ -502,7 +514,7 @@
 
   // From dart:_interceptors
   ClassEntity _findInterceptorsClass(String name) =>
-      _findClass(interceptorsLibrary, name)!;
+      _findClass(interceptorsLibrary, name);
 
   FunctionEntity _findInterceptorsFunction(String name) =>
       _findLibraryMember(interceptorsLibrary, name)!;
@@ -580,7 +592,7 @@
       _findInterceptorsFunction('getNativeInterceptor');
 
   late final ConstructorEntity jsArrayTypedConstructor =
-      _findConstructor(jsArrayClass, 'typed');
+      _env.lookupConstructor(jsArrayClass, 'typed')!;
 
   // From dart:_js_helper
   // TODO(johnniwinther): Avoid the need for this (from [CheckedModeHelper]).
@@ -590,7 +602,7 @@
       _findLibraryMember(jsHelperLibrary, name)!;
 
   ClassEntity _findHelperClass(String name) =>
-      _findClass(jsHelperLibrary, name)!;
+      _findClass(jsHelperLibrary, name);
 
   FunctionEntity _findLateHelperFunction(String name) =>
       _findLibraryMember(lateHelperLibrary, name)!;
@@ -787,7 +799,7 @@
 
   // From dart:_rti
 
-  ClassEntity _findRtiClass(String name) => _findClass(rtiLibrary, name)!;
+  ClassEntity _findRtiClass(String name) => _findClass(rtiLibrary, name);
 
   FunctionEntity _findRtiFunction(String name) =>
       _findLibraryMember(rtiLibrary, name)!;
@@ -808,9 +820,9 @@
 
   late final FunctionEntity checkTypeBound = _findRtiFunction('checkTypeBound');
 
-  ClassEntity get _rtiImplClass => _findClass(rtiLibrary, 'Rti')!;
+  ClassEntity get _rtiImplClass => _findRtiClass('Rti');
 
-  ClassEntity get _rtiUniverseClass => _findClass(rtiLibrary, '_Universe')!;
+  ClassEntity get _rtiUniverseClass => _findRtiClass('_Universe');
 
   FieldEntity _findRtiClassField(String name) =>
       _findClassMember(_rtiImplClass, name);
@@ -916,19 +928,18 @@
   // From dart:_internal
 
   late final ClassEntity symbolImplementationClass =
-      _findClass(internalLibrary, 'Symbol')!;
+      _findClass(internalLibrary, 'Symbol');
 
   /// Used to annotate items that have the keyword "native".
   late final ClassEntity externalNameClass =
-      _findClass(internalLibrary, 'ExternalName')!;
+      _findClass(internalLibrary, 'ExternalName');
 
   InterfaceType get externalNameType => _getRawType(externalNameClass);
 
   // From dart:_js_embedded_names
 
-  late final ClassEntity jsGetNameEnum = _findClass(
-      _env.lookupLibrary(Uris.dart__js_shared_embedded_names, required: true),
-      'JsGetName')!;
+  late final ClassEntity jsGetNameEnum =
+      _findClass(sharedEmbeddedNamesLibrary, 'JsGetName');
 
   /// Returns `true` if [member] is a "foreign helper", that is, a member whose
   /// semantics is defined synthetically and not through Dart code.
@@ -1022,24 +1033,23 @@
 }
 
 class KCommonElements extends CommonElements {
-  KCommonElements(DartTypes dartTypes, ElementEnvironment env)
-      : super(dartTypes, env);
+  KCommonElements(super.dartTypes, super.env);
 
   // From package:js
 
   late final ClassEntity? jsAnnotationClass1 =
-      _findClass(packageJsLibrary, 'JS', required: false);
+      _findClassOrNull(packageJsLibrary, 'JS');
 
   late final ClassEntity? jsAnonymousClass1 =
-      _findClass(packageJsLibrary, '_Anonymous', required: false);
+      _findClassOrNull(packageJsLibrary, '_Anonymous');
 
   // From dart:_js_annotations
 
   late final ClassEntity? jsAnnotationClass2 =
-      _findClass(dartJsAnnotationsLibrary, 'JS', required: false);
+      _findClassOrNull(dartJsAnnotationsLibrary, 'JS');
 
   late final ClassEntity? jsAnonymousClass2 =
-      _findClass(dartJsAnnotationsLibrary, '_Anonymous', required: false);
+      _findClassOrNull(dartJsAnnotationsLibrary, '_Anonymous');
 
   /// Returns `true` if [cls] is a @JS() annotation.
   ///
@@ -1055,7 +1065,7 @@
     return cls == jsAnonymousClass1 || cls == jsAnonymousClass2;
   }
 
-  late final ClassEntity pragmaClass = _findClass(coreLibrary, 'pragma')!;
+  late final ClassEntity pragmaClass = _findClass(coreLibrary, 'pragma');
 
   late final FieldEntity pragmaClassNameField =
       _findClassMember(pragmaClass, 'name');
@@ -1065,10 +1075,7 @@
 }
 
 class JCommonElements extends CommonElements {
-  FunctionEntity? _jsStringSplit;
-
-  JCommonElements(DartTypes dartTypes, ElementEnvironment env)
-      : super(dartTypes, env);
+  JCommonElements(super.dartTypes, super.env);
 
   /// Returns `true` if [element] is the unnamed constructor of `List`.
   ///
@@ -1125,25 +1132,21 @@
   /// Returns `true` if [selector] applies to `JSString.split` on [receiver]
   /// in the given [world].
   ///
-  /// Returns `false` if `JSString.split` is not available.
+  /// Returns `false` if `JSString.split` is not available (e.g. the
+  /// method was tree-shaken in an earlier compilation phase).
   bool appliesToJsStringSplit(Selector selector, AbstractValue? receiver,
       AbstractValueDomain abstractValueDomain) {
-    if (_jsStringSplit == null) {
-      ClassEntity? cls =
-          _findClass(interceptorsLibrary, 'JSString', required: false);
-      if (cls == null) return false;
-      _jsStringSplit = _findClassMember(cls, 'split', required: false);
-      if (_jsStringSplit == null) return false;
-    }
-    return selector.applies(_jsStringSplit!) &&
+    final splitMember = jsStringSplit;
+    if (splitMember == null) return false;
+    return selector.applies(splitMember) &&
         (receiver == null ||
             abstractValueDomain
-                .isTargetingMember(receiver, jsStringSplit, selector.memberName)
+                .isTargetingMember(receiver, splitMember, selector.memberName)
                 .isPotentiallyTrue);
   }
 
-  FunctionEntity get jsStringSplit =>
-      _jsStringSplit ??= _findClassMember(jsStringClass, 'split');
+  late final FunctionEntity? jsStringSplit =
+      _findClassMemberOrNull(jsStringClass, 'split');
 
   late final FunctionEntity jsStringToString =
       _findClassMember(jsStringClass, 'toString');
@@ -1151,7 +1154,7 @@
   late final FunctionEntity jsStringOperatorAdd =
       _findClassMember(jsStringClass, '+');
 
-  late final ClassEntity jsConstClass = _findClass(foreignLibrary, 'JS_CONST')!;
+  late final ClassEntity jsConstClass = _findClass(foreignLibrary, 'JS_CONST');
 
   /// Return `true` if [member] is the 'checkInt' function defined in
   /// dart:_js_helpers.
@@ -1188,17 +1191,14 @@
 
   // From dart:_native_typed_data
 
-  late final ClassEntity? typedArrayOfIntClass = _findClass(
-      _env.lookupLibrary(Uris.dart__native_typed_data, required: true),
-      'NativeTypedArrayOfInt');
+  late final ClassEntity? typedArrayOfIntClass =
+      _findClass(typedDataLibrary, 'NativeTypedArrayOfInt');
 
-  late final ClassEntity typedArrayOfDoubleClass = _findClass(
-      _env.lookupLibrary(Uris.dart__native_typed_data, required: true),
-      'NativeTypedArrayOfDouble')!;
+  late final ClassEntity typedArrayOfDoubleClass =
+      _findClass(typedDataLibrary, 'NativeTypedArrayOfDouble');
 
-  late final ClassEntity jsBuiltinEnum = _findClass(
-      _env.lookupLibrary(Uris.dart__js_shared_embedded_names, required: true),
-      'JsBuiltin')!;
+  late final ClassEntity jsBuiltinEnum =
+      _findClass(sharedEmbeddedNamesLibrary, 'JsBuiltin');
 
   bool isForeign(MemberEntity element) => element.library == foreignLibrary;
 
@@ -1226,10 +1226,10 @@
 // both resolution and codegen.
 abstract class ElementEnvironment {
   /// Returns the main library for the compilation.
-  LibraryEntity get mainLibrary;
+  LibraryEntity? get mainLibrary;
 
   /// Returns the main method for the compilation.
-  FunctionEntity get mainFunction;
+  FunctionEntity? get mainFunction;
 
   /// Returns all known libraries.
   Iterable<LibraryEntity> get libraries;
@@ -1278,7 +1278,7 @@
 
   /// Lookup the constructor [name] in [cls], fail if the class is missing and
   /// [required].
-  ConstructorEntity lookupConstructor(ClassEntity cls, String name,
+  ConstructorEntity? lookupConstructor(ClassEntity cls, String name,
       {bool required = false});
 
   /// Calls [f] for each class member declared in [cls].
@@ -1396,7 +1396,7 @@
   ///
   /// The mixin classes of `B` and `C` are `A` and `B`, respectively, but the
   /// _effective_ mixin class of both is `A`.
-  ClassEntity getEffectiveMixinClass(ClassEntity cls);
+  ClassEntity? getEffectiveMixinClass(ClassEntity cls);
 }
 
 abstract class KElementEnvironment extends ElementEnvironment {
@@ -1474,7 +1474,7 @@
   /// Calls [f] for each parameter of [function] providing the type and name of
   /// the parameter and the [defaultValue] if the parameter is optional.
   void forEachParameter(covariant FunctionEntity function,
-      void f(DartType type, String name, ConstantValue defaultValue));
+      void f(DartType type, String? name, ConstantValue? defaultValue));
 
   /// Calls [f] for each parameter - given as a [Local] - of [function].
   void forEachParameterAsLocal(GlobalLocalsMap globalLocalsMap,
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 8385afe..e0ebd24 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -38,6 +38,12 @@
 import 'inferrer/typemasks/masks.dart' show TypeMaskStrategy;
 import 'inferrer/types.dart'
     show GlobalTypeInferenceResults, GlobalTypeInferenceTask;
+import 'inferrer_experimental/trivial.dart' as experimentalInferrer
+    show TrivialAbstractValueStrategy;
+import 'inferrer_experimental/types.dart' as experimentalInferrer
+    show GlobalTypeInferenceTask;
+import 'inferrer_experimental/typemasks/masks.dart' as experimentalInferrer
+    show TypeMaskStrategy;
 import 'inferrer/wrapped.dart' show WrappedAbstractValueStrategy;
 import 'ir/modular.dart';
 import 'js_backend/backend.dart' show CodegenInputs;
@@ -116,6 +122,7 @@
   fe.InitializedCompilerState initializedCompilerState;
   bool forceSerializationForTesting = false;
   GlobalTypeInferenceTask globalInference;
+  experimentalInferrer.GlobalTypeInferenceTask experimentalGlobalInference;
   CodegenWorldBuilder _codegenWorldBuilder;
 
   AbstractValueStrategy abstractValueStrategy;
@@ -155,9 +162,13 @@
     options.deriveOptions();
     options.validate();
 
-    abstractValueStrategy = options.useTrivialAbstractValueDomain
-        ? const TrivialAbstractValueStrategy()
-        : const TypeMaskStrategy();
+    abstractValueStrategy = options.experimentalInferrer
+        ? (options.useTrivialAbstractValueDomain
+            ? const experimentalInferrer.TrivialAbstractValueStrategy()
+            : const experimentalInferrer.TypeMaskStrategy())
+        : (options.useTrivialAbstractValueDomain
+            ? const TrivialAbstractValueStrategy()
+            : const TypeMaskStrategy());
     if (options.experimentalWrapped || options.testMode) {
       abstractValueStrategy =
           WrappedAbstractValueStrategy(abstractValueStrategy);
@@ -186,6 +197,8 @@
       loadKernelTask = GenericTask('kernel loader', measurer),
       kernelFrontEndTask,
       globalInference = GlobalTypeInferenceTask(this),
+      experimentalGlobalInference =
+          experimentalInferrer.GlobalTypeInferenceTask(this),
       deferredLoadTask = frontendStrategy.createDeferredLoadTask(this),
       dumpInfoTask = DumpInfoTask(this),
       selfTask,
@@ -472,6 +485,18 @@
   bool get shouldStopAfterModularAnalysis =>
       compilationFailed || options.writeModularAnalysisUri != null;
 
+  GlobalTypeInferenceResults performExperimentalGlobalTypeInference(
+      JClosedWorld closedWorld) {
+    FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction;
+    reporter.log('Performing experimental global type inference');
+    GlobalLocalsMap globalLocalsMap =
+        GlobalLocalsMap(closedWorld.closureDataLookup.getEnclosingMember);
+    InferredDataBuilder inferredDataBuilder =
+        InferredDataBuilderImpl(closedWorld.annotationsData);
+    return experimentalGlobalInference.runGlobalTypeInference(
+        mainFunction, closedWorld, globalLocalsMap, inferredDataBuilder);
+  }
+
   GlobalTypeInferenceResults performGlobalTypeInference(
       JClosedWorld closedWorld) {
     FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction;
@@ -594,8 +619,13 @@
     JsClosedWorld closedWorld = closedWorldAndIndices.data;
     DataAndIndices<GlobalTypeInferenceResults> globalTypeInferenceResults;
     if (options.readDataUri == null) {
-      globalTypeInferenceResults =
-          DataAndIndices(performGlobalTypeInference(closedWorld), null);
+      if (options.experimentalInferrer) {
+        globalTypeInferenceResults = DataAndIndices(
+            performExperimentalGlobalTypeInference(closedWorld), null);
+      } else {
+        globalTypeInferenceResults =
+            DataAndIndices(performGlobalTypeInference(closedWorld), null);
+      }
       if (options.writeDataUri != null) {
         serializationTask.serializeGlobalTypeInference(
             globalTypeInferenceResults.data, closedWorldAndIndices.indices);
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 658aad0..1bbef12 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -515,10 +515,9 @@
   @override
   final int hashCode;
 
-  ListConstantValue(InterfaceType type, List<ConstantValue> entries)
+  ListConstantValue(super.type, List<ConstantValue> entries)
       : this.entries = entries,
-        hashCode = Hashing.listHash(entries, Hashing.objectHash(type)),
-        super(type);
+        hashCode = Hashing.listHash(entries, Hashing.objectHash(type));
 
   @override
   bool operator ==(var other) {
@@ -578,10 +577,9 @@
   @override
   final int hashCode;
 
-  SetConstantValue(InterfaceType type, List<ConstantValue> values)
+  SetConstantValue(super.type, List<ConstantValue> values)
       : values = values,
-        hashCode = Hashing.listHash(values, Hashing.objectHash(type)),
-        super(type);
+        hashCode = Hashing.listHash(values, Hashing.objectHash(type));
 
   @override
   bool operator ==(var other) {
@@ -642,12 +640,11 @@
   Map<ConstantValue, ConstantValue>? _lookupMap;
 
   MapConstantValue(
-      InterfaceType type, List<ConstantValue> keys, List<ConstantValue> values)
+      super.type, List<ConstantValue> keys, List<ConstantValue> values)
       : this.keys = keys,
         this.values = values,
         this.hashCode = Hashing.listHash(
-            values, Hashing.listHash(keys, Hashing.objectHash(type))),
-        super(type) {
+            values, Hashing.listHash(keys, Hashing.objectHash(type))) {
     assert(keys.length == values.length);
   }
 
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 7765e59..c4a89b8 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -6,7 +6,7 @@
 
 library dart2js.cmdline;
 
-import 'dart:async' show Future;
+import 'dart:async' show Future, StreamSubscription;
 import 'dart:convert' show utf8, LineSplitter;
 import 'dart:io' show exit, File, FileMode, Platform, stdin, stderr;
 import 'dart:isolate' show Isolate;
@@ -657,6 +657,7 @@
     OptionHandler(Flags.useOldRti, passThrough),
     OptionHandler(Flags.useSimpleLoadIds, passThrough),
     OptionHandler(Flags.testMode, passThrough),
+    OptionHandler(Flags.experimentalInferrer, passThrough),
     OptionHandler('${Flags.dumpSsa}=.+', passThrough),
     OptionHandler('${Flags.cfeInvocationModes}=.+', passThrough),
     OptionHandler('${Flags.invoker}=.+', setInvoker),
@@ -1492,7 +1493,7 @@
   };
 
   var stream = stdin.transform(utf8.decoder).transform(LineSplitter());
-  var subscription;
+  StreamSubscription subscription;
   fe.InitializedCompilerState kernelInitializedCompilerState;
   subscription = stream.listen((line) {
     Future.sync(() {
diff --git a/pkg/compiler/lib/src/deferred_load/deferred_load.dart b/pkg/compiler/lib/src/deferred_load/deferred_load.dart
index 0499e5f..a7af6e7 100644
--- a/pkg/compiler/lib/src/deferred_load/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load/deferred_load.dart
@@ -20,10 +20,10 @@
 /// generates _load lists_: a list of JavaScript files that need to be
 /// downloaded for every deferred import in the program.
 ///
-/// Each generated JavaScript file has an initialzation within it. The files can
-/// be concatenated together in a bundle without affecting the initialization
-/// logic. This is used by customers to reduce the download latency when they
-/// know that multiple files will be loaded at once.
+/// Each generated JavaScript file has an initialization within it. The files
+/// can be concatenated together in a bundle without affecting the
+/// initialization logic. This is used by customers to reduce the download
+/// latency when they know that multiple files will be loaded at once.
 ///
 /// *The code splitting algorithm*
 ///
@@ -262,7 +262,7 @@
 /// into a set containing `{A, B}`.
 ///
 // TODO(joshualitt): update doc above when main is represented by a set
-// containing an implict import corresponding to `main`.
+// containing an implicit import corresponding to `main`.
 // TODO(sigmund): investigate different heuristics for how to select the next
 // work item (e.g. we might converge faster if we pick first the update that
 // contains a bigger delta.)
diff --git a/pkg/compiler/lib/src/deferred_load/entity_data.dart b/pkg/compiler/lib/src/deferred_load/entity_data.dart
index bfb81f2..f63b192 100644
--- a/pkg/compiler/lib/src/deferred_load/entity_data.dart
+++ b/pkg/compiler/lib/src/deferred_load/entity_data.dart
@@ -26,7 +26,7 @@
     visitor.visitClassEntityData(entity);
   }
 
-  ClassEntityData(ClassEntity entity) : super(entity);
+  ClassEntityData(super.entity);
 }
 
 class ClassTypeEntityData extends EntityData<ClassEntity> {
@@ -35,7 +35,7 @@
     visitor.visitClassTypeEntityData(entity);
   }
 
-  ClassTypeEntityData(ClassEntity entity) : super(entity);
+  ClassTypeEntityData(super.entity);
 }
 
 class MemberEntityData extends EntityData<MemberEntity> {
@@ -44,7 +44,7 @@
     visitor.visitMemberEntityData(entity);
   }
 
-  MemberEntityData(MemberEntity entity) : super(entity);
+  MemberEntityData(super.entity);
 }
 
 class LocalFunctionEntityData extends EntityData<Local> {
@@ -56,7 +56,7 @@
   @override
   bool get needsRecursiveUpdate => false;
 
-  LocalFunctionEntityData(Local entity) : super(entity);
+  LocalFunctionEntityData(super.entity);
 }
 
 class ConstantEntityData extends EntityData<ConstantValue> {
@@ -65,7 +65,7 @@
     visitor.visitConstantEntityData(entity);
   }
 
-  ConstantEntityData(ConstantValue entity) : super(entity);
+  ConstantEntityData(super.entity);
 }
 
 /// A registry used to canonicalize [EntityData].
diff --git a/pkg/compiler/lib/src/deferred_load/entity_data_info.dart b/pkg/compiler/lib/src/deferred_load/entity_data_info.dart
index 81630f2..13e980e 100644
--- a/pkg/compiler/lib/src/deferred_load/entity_data_info.dart
+++ b/pkg/compiler/lib/src/deferred_load/entity_data_info.dart
@@ -281,7 +281,7 @@
     void addClassAndMaybeAddEffectiveMixinClass(ClassEntity cls) {
       infoBuilder.addClass(cls);
       if (elementEnvironment.isMixinApplication(cls)) {
-        infoBuilder.addClass(elementEnvironment.getEffectiveMixinClass(cls));
+        infoBuilder.addClass(elementEnvironment.getEffectiveMixinClass(cls)!);
       }
     }
 
diff --git a/pkg/compiler/lib/src/deferred_load/program_split_constraints/builder.dart b/pkg/compiler/lib/src/deferred_load/program_split_constraints/builder.dart
index 0ecaced..a70b046 100644
--- a/pkg/compiler/lib/src/deferred_load/program_split_constraints/builder.dart
+++ b/pkg/compiler/lib/src/deferred_load/program_split_constraints/builder.dart
@@ -120,7 +120,7 @@
     }
 
     // 3) Build a graph of [Constraint]s by processing user constraints and
-    // intializing each [Constraint]'s predecessor / successor members.
+    // initializing each [Constraint]'s predecessor / successor members.
     void createEdge(NamedNode successorNode, NamedNode predecessorNode) {
       var successor = nodeToConstraintMap[successorNode]!;
       var predecessor = nodeToConstraintMap[predecessorNode]!;
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 50abe03..9970565 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,7 +44,7 @@
   Uri get uri => _uriAndPrefix.uri;
   String get prefix => _uriAndPrefix.prefix;
 
-  ReferenceNode(String name, this._uriAndPrefix) : super(name);
+  ReferenceNode(super.name, this._uriAndPrefix);
 
   @override
   Map<String, dynamic> toJson() {
@@ -117,7 +117,7 @@
   final CombinerType type;
   final Set<ReferenceNode> nodes;
 
-  CombinerNode(String name, this.type, this.nodes) : super(name);
+  CombinerNode(super.name, this.type, this.nodes);
 
   @override
   Map<String, dynamic> toJson() {
diff --git a/pkg/compiler/lib/src/elements/names.dart b/pkg/compiler/lib/src/elements/names.dart
index 5a29f20..13fe1fe 100644
--- a/pkg/compiler/lib/src/elements/names.dart
+++ b/pkg/compiler/lib/src/elements/names.dart
@@ -115,8 +115,7 @@
   @override
   final Uri uri;
 
-  PrivateName(String text, this.uri, {bool isSetter = false})
-      : super(text, isSetter: isSetter);
+  PrivateName(super.text, this.uri, {super.isSetter});
 
   @override
   Name get getter => isSetter ? PrivateName(text, uri) : this;
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index d07daa3..4dfbf7b 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -1187,9 +1187,9 @@
     //      C extends D,
     //      D extends Map<B, F>>(){}
     //
-    // A and B have a cycle but are not changed by the subsitution of F->G. C is
-    // indirectly changed by the substitution of F. When D is replaced by `D2
-    // extends Map<B,G>`, C must be replaced by `C2 extends D2`.
+    // A and B have a cycle but are not changed by the substitution of F->G.
+    // C is indirectly changed by the substitution of F. When D is replaced by
+    // `D2 extends Map<B,G>`, C must be replaced by `C2 extends D2`.
 
     List<FunctionTypeVariable?> undecided = List.of(variables, growable: false);
     List<FunctionTypeVariable>? newVariables;
diff --git a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
index fbfd6cd..0df88c8 100644
--- a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
@@ -236,7 +236,8 @@
   /// interpreted as nullable. This is passed as `false` for is-tests and `true`
   /// for as-checks and other contexts (e.g. parameter checks).
   AbstractValueWithPrecision createFromStaticType(DartType type,
-      {ClassRelation classRelation = ClassRelation.subtype, bool nullable});
+      {ClassRelation classRelation = ClassRelation.subtype,
+      required bool nullable});
 
   /// Creates an [AbstractValue] for a non-null exact instance of [cls].
   AbstractValue createNonNullExact(ClassEntity cls);
@@ -304,7 +305,7 @@
 
   /// Returns the [ClassEntity] if this [value] is a non-null instance of an
   /// exact class at runtime, and `null` otherwise.
-  ClassEntity getExactClass(covariant AbstractValue value);
+  ClassEntity? getExactClass(covariant AbstractValue value);
 
   /// Returns an [AbstractBool] that describes whether [value] is `null` at
   /// runtime.
@@ -449,9 +450,9 @@
   /// The [allocationNode] is used to identify this particular map allocation.
   /// The [allocationElement] is used only for debugging.
   AbstractValue createContainerValue(
-      AbstractValue originalValue,
-      Object allocationNode,
-      MemberEntity allocationElement,
+      AbstractValue? originalValue,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
       AbstractValue elementType,
       int? length);
 
@@ -462,7 +463,7 @@
   /// Return the known length of [value] if it represents a container value
   /// at runtime. Returns `null` if the length is unknown or if [value] doesn't
   /// represent a container value at runtime.
-  int getContainerLength(AbstractValue value);
+  int? getContainerLength(AbstractValue value);
 
   /// Returns `true` if [value] represents a set value at runtime.
   bool isSet(covariant AbstractValue value);
@@ -473,9 +474,9 @@
   /// The [allocationNode] is used to identify this particular set allocation.
   /// The [allocationElement] is used only for debugging.
   AbstractValue createSetValue(
-      AbstractValue originalValue,
-      Object allocationNode,
-      MemberEntity allocationElement,
+      AbstractValue? originalValue,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
       AbstractValue elementType);
 
   /// Returns the element type of [value] if it represents a set value at
@@ -491,9 +492,9 @@
   /// The [allocationNode] is used to identify this particular map allocation.
   /// The [allocationElement] is used only for debugging.
   AbstractValue createMapValue(
-      AbstractValue originalValue,
-      Object allocationNode,
-      MemberEntity allocationElement,
+      AbstractValue? originalValue,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
       AbstractValue key,
       AbstractValue value);
 
@@ -515,9 +516,9 @@
   /// The [allocationNode] is used to identify this particular map allocation.
   /// The [allocationElement] is used only for debugging.
   AbstractValue createDictionaryValue(
-      AbstractValue originalValue,
-      Object allocationNode,
-      MemberEntity allocationElement,
+      AbstractValue? originalValue,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
       AbstractValue key,
       AbstractValue value,
       Map<String, AbstractValue> mappings);
@@ -543,21 +544,21 @@
   ///
   /// Specializations are created through [createPrimitiveValue],
   /// [createMapValue], [createDictionaryValue] and [createContainerValue].
-  AbstractValue getGeneralization(AbstractValue value);
+  AbstractValue? getGeneralization(AbstractValue? value);
 
   /// Return the object identifying the allocation of [value] if it is an
   /// allocation based specialization. Otherwise returns `null`.
   ///
   /// Allocation based specializations are created through [createMapValue],
   /// [createDictionaryValue] and [createContainerValue]
-  Object getAllocationNode(AbstractValue value);
+  Object? getAllocationNode(AbstractValue value);
 
   /// Return the allocation element of [value] if it is an allocation based
   /// specialization. Otherwise returns `null`.
   ///
   /// Allocation based specializations are created through [createMapValue],
   /// [createDictionaryValue] and [createContainerValue]
-  MemberEntity getAllocationElement(AbstractValue value);
+  MemberEntity? getAllocationElement(AbstractValue value);
 
   /// Returns `true` if [value] a known primitive JavaScript value at runtime.
   bool isPrimitiveValue(covariant AbstractValue value);
@@ -570,7 +571,7 @@
   /// Returns the primitive JavaScript value of [value] if it represents a
   /// primitive JavaScript value at runtime, value at runtime. Returns `null`
   /// otherwise.
-  PrimitiveConstantValue getPrimitiveValue(covariant AbstractValue value);
+  PrimitiveConstantValue? getPrimitiveValue(covariant AbstractValue value);
 
   /// Compute the type of all potential receivers of the set of live [members].
   AbstractValue computeReceiver(Iterable<MemberEntity> members);
@@ -589,7 +590,7 @@
   /// Returns the [AbstractValue] for the [parameterType] of a native
   /// method. May return `null`, for example, if [parameterType] is not modelled
   /// precisely by an [AbstractValue].
-  AbstractValue getAbstractValueForNativeMethodParameterType(DartType type);
+  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type);
 
   /// Returns an [AbstractBool] that describes if the set of runtime values of
   /// [subset] are known to all be in the set of runtime values of [superset].
@@ -599,7 +600,7 @@
   /// [receiver].
   ///
   /// Returns `null` if 0 or more than 1 member can be hit at runtime.
-  MemberEntity locateSingleMember(AbstractValue receiver, Selector selector);
+  MemberEntity? locateSingleMember(AbstractValue receiver, Selector selector);
 
   /// Returns an [AbstractBool] that describes if [value] is known to be an
   /// indexable JavaScript value at runtime.
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index d1b8542..93938d9 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -2,15 +2,12 @@
 // 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.10
-
 library compiler.src.inferrer.closure_tracer;
 
 import '../common/names.dart' show Identifiers, Names;
 import '../elements/entities.dart';
-import '../universe/selector.dart' show Selector;
 import 'debug.dart' as debug;
-import 'engine.dart';
+import 'engine_interfaces.dart';
 import 'node_tracer.dart';
 import 'type_graph_nodes.dart';
 
@@ -29,7 +26,8 @@
   }
 
   @override
-  ApplyableTypeInformation get tracedType => super.tracedType;
+  ApplyableTypeInformation get tracedType =>
+      super.tracedType as ApplyableTypeInformation;
 
   void run() {
     analyze();
@@ -44,7 +42,7 @@
     }
   }
 
-  void _tagAsFunctionApplyTarget([String reason]) {
+  void _tagAsFunctionApplyTarget([String? reason]) {
     tracedType.mightBePassedToFunctionApply = true;
     if (debug.VERBOSE) {
       print("Closure $tracedType might be passed to apply: $reason");
@@ -56,7 +54,7 @@
   }
 
   void _analyzeCall(CallSiteTypeInformation info) {
-    Selector selector = info.selector;
+    final selector = info.selector!;
     tracedElements.forEach((FunctionEntity functionElement) {
       if (!selector.callStructure
           .signatureApplies(functionElement.parameterStructure)) {
@@ -83,24 +81,28 @@
     super.visitStaticCallSiteTypeInformation(info);
     MemberEntity called = info.calledElement;
     if (inferrer.closedWorld.commonElements.isForeign(called)) {
-      String name = called.name;
+      final name = called.name!;
       if (name == Identifiers.JS || name == Identifiers.DART_CLOSURE_TO_JS) {
         bailout('Used in JS ${info.debugName}');
       } else if (name == Identifiers.RAW_DART_FUNCTION_REF) {
         bailout('Escaped raw function reference');
       }
     }
+
+    final selector = info.selector;
     if (called.isGetter &&
-        info.selector != null &&
-        info.selector.isCall &&
+        selector != null &&
+        selector.isCall &&
         inferrer.types.getInferredTypeOfMember(called) == currentUser) {
       // This node can be a closure call as well. For example, `foo()`
       // where `foo` is a getter.
       _registerCallForLaterAnalysis(info);
     }
+
+    final arguments = info.arguments;
     if (_checkIfFunctionApply(called) &&
-        info.arguments != null &&
-        info.arguments.contains(currentUser)) {
+        arguments != null &&
+        arguments.contains(currentUser)) {
       _tagAsFunctionApplyTarget("static call");
     }
   }
@@ -115,8 +117,9 @@
   @override
   visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
     super.visitDynamicCallSiteTypeInformation(info);
-    if (info.selector.isCall) {
-      if (info.arguments.contains(currentUser)) {
+    final selector = info.selector!;
+    if (selector.isCall) {
+      if (info.arguments!.contains(currentUser)) {
         if (info.hasClosureCallTargets ||
             info.concreteTargets.any((element) => !element.isFunction)) {
           bailout('Passed to a closure');
@@ -127,8 +130,7 @@
       } else if (info.concreteTargets.any(_checkIfCurrentUser)) {
         _registerCallForLaterAnalysis(info);
       }
-    } else if (info.selector.isGetter &&
-        info.selector.memberName == Names.call) {
+    } else if (selector.isGetter && selector.memberName == Names.call) {
       // We are potentially tearing off ourself here
       addNewEscapeInformation(info);
     }
@@ -143,9 +145,11 @@
   @override
   visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
     super.visitStaticCallSiteTypeInformation(info);
+
+    final selector = info.selector;
     if (info.calledElement == tracedElements.first &&
-        info.selector != null &&
-        info.selector.isGetter) {
+        selector != null &&
+        selector.isGetter) {
       addNewEscapeInformation(info);
     }
   }
diff --git a/pkg/compiler/lib/src/inferrer/engine.dart b/pkg/compiler/lib/src/inferrer/engine.dart
index 9ce44f0..9755d89 100644
--- a/pkg/compiler/lib/src/inferrer/engine.dart
+++ b/pkg/compiler/lib/src/inferrer/engine.dart
@@ -50,6 +50,7 @@
 class InferrerEngine implements interfaces.InferrerEngine {
   /// A set of selector names that [List] implements, that we know return their
   /// element type.
+  @override
   final Set<Selector> returnsListElementTypeSet = Set<Selector>.from(<Selector>[
     Selector.getter(const PublicName('first')),
     Selector.getter(const PublicName('last')),
@@ -261,6 +262,7 @@
     return abstractValueDomain.isMap(mask) && selector.isIndex;
   }
 
+  @override
   void analyzeListAndEnqueue(ListTypeInformation info) {
     if (info.analyzed) return;
     info.analyzed = true;
@@ -277,6 +279,7 @@
     _workQueue.add(info.elementType);
   }
 
+  @override
   void analyzeSetAndEnqueue(SetTypeInformation info) {
     if (info.analyzed) return;
     info.analyzed = true;
@@ -294,6 +297,7 @@
     _workQueue.add(info.elementType);
   }
 
+  @override
   void analyzeMapAndEnqueue(MapTypeInformation info) {
     if (info.analyzed) return;
     info.analyzed = true;
diff --git a/pkg/compiler/lib/src/inferrer/engine_interfaces.dart b/pkg/compiler/lib/src/inferrer/engine_interfaces.dart
index ce45629..39d632b 100644
--- a/pkg/compiler/lib/src/inferrer/engine_interfaces.dart
+++ b/pkg/compiler/lib/src/inferrer/engine_interfaces.dart
@@ -24,6 +24,7 @@
   InferredDataBuilder get inferredDataBuilder;
   FunctionEntity get mainElement;
   NoSuchMethodData get noSuchMethodData;
+  Set<Selector> get returnsListElementTypeSet;
 
   TypeInformation typeOfNativeBehavior(NativeBehavior nativeBehavior);
   bool canFieldBeUsedForGlobalOptimizations(FieldEntity element);
@@ -40,4 +41,7 @@
       {required bool remove, bool addToQueue = true});
   bool returnsListElementType(Selector selector, AbstractValue mask);
   bool returnsMapValueType(Selector selector, AbstractValue mask);
+  void analyzeListAndEnqueue(ListTypeInformation info);
+  void analyzeSetAndEnqueue(SetTypeInformation info);
+  void analyzeMapAndEnqueue(MapTypeInformation info);
 }
diff --git a/pkg/compiler/lib/src/inferrer/list_tracer.dart b/pkg/compiler/lib/src/inferrer/list_tracer.dart
index 2617b52..6124abf 100644
--- a/pkg/compiler/lib/src/inferrer/list_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/list_tracer.dart
@@ -2,14 +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.
 
-// @dart = 2.10
-
 library compiler.src.inferrer.list_tracer;
 
 import '../common/names.dart';
 import '../elements/entities.dart';
 import '../native/behavior.dart';
-import '../universe/selector.dart' show Selector;
 import '../util/util.dart' show Setlet;
 import 'node_tracer.dart';
 import 'type_graph_nodes.dart';
@@ -136,14 +133,14 @@
   Set<TypeInformation> inputs = Setlet<TypeInformation>();
   bool callsGrowableMethod = false;
 
-  ListTracerVisitor(tracedType, inferrer) : super(tracedType, inferrer);
+  ListTracerVisitor(super.tracedType, super.inferrer);
 
   /// Returns [true] if the analysis completed successfully, [false] if it
   /// bailed out. In the former case, [inputs] holds a list of
   /// [TypeInformation] nodes that flow into the element type of this list.
   bool run() {
     analyze();
-    ListTypeInformation list = tracedType;
+    final list = tracedType as ListTypeInformation;
     if (continueAnalyzing) {
       if (!callsGrowableMethod && list.inferredLength == null) {
         list.inferredLength = list.originalLength;
@@ -152,7 +149,7 @@
       return true;
     } else {
       callsGrowableMethod = true;
-      inputs = null;
+      inputs.clear();
       return false;
     }
   }
@@ -181,26 +178,27 @@
   @override
   visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
     super.visitDynamicCallSiteTypeInformation(info);
-    Selector selector = info.selector;
+    final selector = info.selector!;
     String selectorName = selector.name;
+    final arguments = info.arguments;
     if (currentUser == info.receiver) {
       if (!okListSelectorsSet.contains(selectorName)) {
         if (selector.isCall) {
-          int positionalLength = info.arguments.positional.length;
+          int positionalLength = arguments!.positional.length;
           if (selectorName == 'add') {
             if (positionalLength == 1) {
-              inputs.add(info.arguments.positional[0]);
+              inputs.add(arguments.positional[0]);
             }
           } else if (selectorName == 'insert') {
             if (positionalLength == 2) {
-              inputs.add(info.arguments.positional[1]);
+              inputs.add(arguments.positional[1]);
             }
           } else {
             bailout('Used in a not-ok selector');
             return;
           }
         } else if (selector.isIndexSet) {
-          inputs.add(info.arguments.positional[1]);
+          inputs.add(arguments!.positional[1]);
         } else if (!selector.isIndex) {
           bailout('Used in a not-ok selector');
           return;
diff --git a/pkg/compiler/lib/src/inferrer/map_tracer.dart b/pkg/compiler/lib/src/inferrer/map_tracer.dart
index f997f1a..fe3bf6b 100644
--- a/pkg/compiler/lib/src/inferrer/map_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/map_tracer.dart
@@ -2,13 +2,10 @@
 // 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.10
-
 library compiler.src.inferrer.map_tracer;
 
 import '../common/names.dart';
 import '../elements/entities.dart';
-import '../universe/selector.dart' show Selector;
 import 'node_tracer.dart';
 import 'type_graph_nodes.dart';
 
@@ -43,7 +40,7 @@
   // this map.
   List<MapTypeInformation> mapInputs = <MapTypeInformation>[];
 
-  MapTracerVisitor(tracedType, inferrer) : super(tracedType, inferrer);
+  MapTracerVisitor(super.tracedType, super.inferrer);
 
   /// Returns [true] if the analysis completed successfully, [false]
   /// if it bailed out. In the former case, [keyInputs] and
@@ -51,12 +48,14 @@
   /// flow into the key and value types of this map.
   bool run() {
     analyze();
-    MapTypeInformation map = tracedType;
+    final map = tracedType as MapTypeInformation;
     if (continueAnalyzing) {
       map.addFlowsIntoTargets(flowsInto);
       return true;
     }
-    keyInputs = valueInputs = mapInputs = null;
+    keyInputs.clear();
+    valueInputs.clear();
+    mapInputs.clear();
     return false;
   }
 
@@ -78,15 +77,16 @@
   @override
   visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
     super.visitDynamicCallSiteTypeInformation(info);
-    Selector selector = info.selector;
-    String selectorName = selector.name;
+    final selector = info.selector!;
+    final selectorName = selector.name;
+    final arguments = info.arguments;
     if (currentUser == info.receiver) {
       if (!okMapSelectorsSet.contains(selectorName)) {
         if (selector.isCall) {
           if (selectorName == 'addAll') {
             // All keys and values from the argument flow into
             // the map.
-            TypeInformation map = info.arguments.positional[0];
+            TypeInformation map = arguments!.positional[0];
             if (map is MapTypeInformation) {
               inferrer.analyzeMapAndEnqueue(map);
               mapInputs.add(map);
@@ -105,7 +105,7 @@
             // to go to dynamic.
             // TODO(herhut,16507): Use return type of closure in
             // Map.putIfAbsent.
-            keyInputs.add(info.arguments.positional[0]);
+            keyInputs.add(arguments!.positional[0]);
             valueInputs.add(inferrer.types.dynamicType);
           } else {
             // It would be nice to handle [Map.keys] and [Map.values], too.
@@ -117,8 +117,8 @@
             return;
           }
         } else if (selector.isIndexSet) {
-          keyInputs.add(info.arguments.positional[0]);
-          valueInputs.add(info.arguments.positional[1]);
+          keyInputs.add(arguments!.positional[0]);
+          valueInputs.add(arguments.positional[1]);
         } else if (!selector.isIndex) {
           bailout('Map used in a not-ok selector [$selectorName]');
           return;
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index e873855..82176f4 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 library compiler.src.inferrer.node_tracer;
 
 import '../common/names.dart' show Identifiers;
@@ -11,7 +9,7 @@
 import '../util/util.dart' show Setlet;
 import 'abstract_value_domain.dart';
 import 'debug.dart' as debug;
-import 'engine.dart';
+import 'engine_interfaces.dart';
 import 'type_graph_nodes.dart';
 
 // A set of selectors we know do not escape the elements inside the
@@ -104,7 +102,9 @@
 
   static const int MAX_ANALYSIS_COUNT =
       int.fromEnvironment('dart2js.tracing.limit', defaultValue: 32);
-  final Setlet<MemberEntity> analyzedElements = Setlet<MemberEntity>();
+  // TODO(natebiggs): We allow null here to maintain current functionality
+  // but we should verify we actually need to allow it.
+  final Setlet<MemberEntity?> analyzedElements = Setlet<MemberEntity?>();
 
   TracerVisitor(this.tracedType, this.inferrer);
 
@@ -130,7 +130,7 @@
   final Setlet<TypeInformation> flowsInto = Setlet<TypeInformation>();
 
   // The current [TypeInformation] in the analysis.
-  TypeInformation currentUser;
+  TypeInformation? currentUser;
   bool continueAnalyzing = true;
 
   void addNewEscapeInformation(TypeInformation info) {
@@ -157,12 +157,12 @@
     // as well as the operations done on all these [TypeInformation]s.
     addNewEscapeInformation(tracedType);
     while (!workList.isEmpty) {
-      currentUser = workList.removeLast();
-      if (_wouldBeTooManyUsers(currentUser.users)) {
+      final user = currentUser = workList.removeLast();
+      if (_wouldBeTooManyUsers(user.users)) {
         bailout('Too many users');
         break;
       }
-      for (TypeInformation info in currentUser.users) {
+      for (final info in user.users) {
         analyzedElements.add(info.owner);
         info.accept(this);
       }
@@ -283,8 +283,8 @@
             if (user.receiver != flow) return;
             if (inferrer.returnsListElementTypeSet.contains(user.selector)) {
               addNewEscapeInformation(user);
-            } else if (!doesNotEscapeListSet.contains(user.selector.name)) {
-              bailout('Escape from a list via [${user.selector.name}]');
+            } else if (!doesNotEscapeListSet.contains(user.selector?.name)) {
+              bailout('Escape from a list via [${user.selector?.name}]');
             }
           }
         });
@@ -301,10 +301,11 @@
         flow.users.forEach((TypeInformation user) {
           if (user is DynamicCallSiteTypeInformation) {
             if (user.receiver != flow) return;
-            if (user.selector.isIndex) {
+            final selector = user.selector!;
+            if (selector.isIndex) {
               addNewEscapeInformation(user);
-            } else if (!doesNotEscapeSetSet.contains(user.selector.name)) {
-              bailout('Escape from a set via [${user.selector.name}]');
+            } else if (!doesNotEscapeSetSet.contains(selector.name)) {
+              bailout('Escape from a set via [${selector.name}]');
             }
           }
         });
@@ -321,10 +322,11 @@
         flow.users.forEach((TypeInformation user) {
           if (user is DynamicCallSiteTypeInformation) {
             if (user.receiver != flow) return;
-            if (user.selector.isIndex) {
+            final selector = user.selector!;
+            if (selector.isIndex) {
               addNewEscapeInformation(user);
-            } else if (!doesNotEscapeMapSet.contains(user.selector.name)) {
-              bailout('Escape from a map via [${user.selector.name}]');
+            } else if (!doesNotEscapeMapSet.contains(selector.name)) {
+              bailout('Escape from a map via [${selector.name}]');
             }
           }
         });
@@ -336,23 +338,25 @@
   /// what list adding means has to stay in sync with
   /// [isParameterOfListAddingMethod].
   bool mightAddToContainer(DynamicCallSiteTypeInformation info) {
-    if (info.arguments == null) return false;
-    if (info.arguments.named.isNotEmpty) return false;
-    String selectorName = info.selector.name;
-    List<TypeInformation> arguments = info.arguments.positional;
-    if (arguments.length == 1) {
-      return (selectorName == 'add' && currentUser == arguments[0]);
-    } else if (arguments.length == 2) {
-      return (selectorName == 'insert' && currentUser == arguments[1]);
+    final arguments = info.arguments;
+    if (arguments == null) return false;
+    if (arguments.named.isNotEmpty) return false;
+    String selectorName = info.selector!.name;
+    List<TypeInformation> positionalArguments = arguments.positional;
+    if (positionalArguments.length == 1) {
+      return (selectorName == 'add' && currentUser == positionalArguments[0]);
+    } else if (positionalArguments.length == 2) {
+      return (selectorName == 'insert' &&
+          currentUser == positionalArguments[1]);
     }
     return false;
   }
 
   bool isIndexSetArgument(DynamicCallSiteTypeInformation info, int index) {
-    String selectorName = info.selector.name;
+    final selectorName = info.selector!.name;
     if (selectorName != '[]=') return false;
-    assert(info.arguments.length == 2);
-    List<TypeInformation> arguments = info.arguments.positional;
+    assert(info.arguments!.length == 2);
+    List<TypeInformation> arguments = info.arguments!.positional;
     return currentUser == arguments[index];
   }
 
@@ -371,7 +375,7 @@
   }
 
   void bailoutIfReaches(bool predicate(ParameterTypeInformation e)) {
-    for (var user in currentUser.users) {
+    for (var user in currentUser!.users) {
       if (user is ParameterTypeInformation) {
         if (predicate(user)) {
           bailout('Reached suppressed parameter without precise receiver');
@@ -385,11 +389,11 @@
   void visitDynamicCallSiteTypeInformation(
       DynamicCallSiteTypeInformation info) {
     void addsToContainer(AbstractValue mask) {
-      Object allocationNode =
+      final allocationNode =
           inferrer.abstractValueDomain.getAllocationNode(mask);
       if (allocationNode != null) {
-        ListTypeInformation list =
-            inferrer.types.allocatedLists[allocationNode];
+        final list = inferrer.types.allocatedLists[allocationNode]
+            as ListTypeInformation;
         listsToAnalyze.add(list);
       } else {
         // The [mask] is a union of two containers, and we lose track of where
@@ -399,10 +403,11 @@
     }
 
     void addsToMapValue(AbstractValue mask) {
-      Object allocationNode =
+      final allocationNode =
           inferrer.abstractValueDomain.getAllocationNode(mask);
       if (allocationNode != null) {
-        MapTypeInformation map = inferrer.types.allocatedMaps[allocationNode];
+        final map =
+            inferrer.types.allocatedMaps[allocationNode] as MapTypeInformation;
         mapsToAnalyze.add(map);
       } else {
         // The [mask] is a union. See comment for [mask] above.
@@ -461,9 +466,10 @@
       }
     }
 
+    final arguments = info.arguments;
     if (info.targetsIncludeComplexNoSuchMethod(inferrer) &&
-        info.arguments != null &&
-        info.arguments.contains(currentUser)) {
+        arguments != null &&
+        arguments.contains(currentUser)) {
       bailout('Passed to noSuchMethod');
     }
 
@@ -485,7 +491,7 @@
         inferrer.closedWorld.commonElements.jsArrayClass) {
       return false;
     }
-    String name = parameterInfo.method.name;
+    final name = parameterInfo.method.name;
     return (name == '[]=') || (name == 'add') || (name == 'insert');
   }
 
@@ -498,7 +504,7 @@
         inferrer.closedWorld.commonElements.mapLiteralClass) {
       return false;
     }
-    String name = parameterInfo.method.name;
+    final name = parameterInfo.method.name;
     return (name == '[]=');
   }
 
@@ -513,7 +519,7 @@
     if (element.isInstanceMember && element.name == Identifiers.call) {
       return true;
     }
-    ClassEntity cls = element.enclosingClass;
+    final cls = element.enclosingClass;
     return cls != null && cls.isClosure;
   }
 
@@ -525,8 +531,10 @@
     if (isClosure(info.member)) {
       bailout('Returned from a closure');
     }
-    if (info.member.isField &&
-        !inferrer.canFieldBeUsedForGlobalOptimizations(info.member)) {
+
+    final member = info.member;
+    if (member is FieldEntity &&
+        !inferrer.canFieldBeUsedForGlobalOptimizations(member)) {
       bailout('Escape to code that has special backend treatment');
     }
     addNewEscapeInformation(info);
diff --git a/pkg/compiler/lib/src/inferrer/powersets/powersets.dart b/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
index 998b848..8b53761 100644
--- a/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
+++ b/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import '../../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
 import '../../elements/entities.dart';
 import '../../elements/names.dart';
@@ -13,7 +11,7 @@
 import '../../universe/selector.dart';
 import '../../universe/world_builder.dart';
 import '../../universe/use.dart';
-import '../../world.dart';
+import '../../world_interfaces.dart';
 import '../abstract_value_domain.dart';
 import '../abstract_value_strategy.dart';
 import 'powerset_bits.dart';
@@ -30,10 +28,8 @@
   bool operator ==(var other) {
     if (identical(this, other)) return true;
     if (other is! PowersetValue) return false;
-    PowersetValue otherPowerset = other;
-    return other is PowersetValue &&
-        _abstractValue == otherPowerset._abstractValue &&
-        _powersetBits == otherPowerset._powersetBits;
+    return _abstractValue == other._abstractValue &&
+        _powersetBits == other._powersetBits;
   }
 
   @override
@@ -47,11 +43,11 @@
       '${_abstractValue}';
 }
 
-AbstractValue unwrapOrNull(PowersetValue powerset) {
+AbstractValue? unwrapOrNull(PowersetValue? powerset) {
   return powerset?._abstractValue;
 }
 
-PowersetValue wrapOrNull(AbstractValue abstractValue, int powersetBits) {
+PowersetValue? wrapOrNull(AbstractValue? abstractValue, int powersetBits) {
   return abstractValue == null
       ? null
       : PowersetValue(abstractValue, powersetBits);
@@ -115,7 +111,7 @@
           : _abstractValueDomain.isJsIndexable(value._abstractValue);
 
   @override
-  MemberEntity locateSingleMember(
+  MemberEntity? locateSingleMember(
           covariant PowersetValue receiver, Selector selector) =>
       _abstractValueDomain.locateSingleMember(
           receiver._abstractValue, selector);
@@ -155,7 +151,7 @@
   }
 
   @override
-  PrimitiveConstantValue getPrimitiveValue(covariant PowersetValue value) =>
+  PrimitiveConstantValue? getPrimitiveValue(covariant PowersetValue value) =>
       _powersetBitsDomain.getPrimitiveValue(value.powersetBits) ??
       _abstractValueDomain.getPrimitiveValue(value._abstractValue);
 
@@ -174,18 +170,18 @@
       _abstractValueDomain.isPrimitiveValue(value._abstractValue);
 
   @override
-  MemberEntity getAllocationElement(covariant PowersetValue value) =>
+  MemberEntity? getAllocationElement(covariant PowersetValue value) =>
       _abstractValueDomain.getAllocationElement(value._abstractValue);
 
   @override
-  Object getAllocationNode(covariant PowersetValue value) =>
+  Object? getAllocationNode(covariant PowersetValue value) =>
       _abstractValueDomain.getAllocationNode(value._abstractValue);
 
   @override
   AbstractValue getGeneralization(covariant PowersetValue value) {
     int powersetBits = _powersetBitsDomain.powersetTop;
-    AbstractValue abstractValue =
-        _abstractValueDomain.getGeneralization(unwrapOrNull(value));
+    final abstractValue =
+        _abstractValueDomain.getGeneralization(unwrapOrNull(value))!;
     return PowersetValue(abstractValue, powersetBits);
   }
 
@@ -214,12 +210,12 @@
   @override
   AbstractValue createDictionaryValue(
       covariant PowersetValue originalValue,
-      Object allocationNode,
-      MemberEntity allocationElement,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
       covariant PowersetValue key,
       covariant PowersetValue value,
       covariant Map<String, AbstractValue> mappings) {
-    int powersetBits = originalValue._powersetBits;
+    final powersetBits = originalValue._powersetBits;
     AbstractValue abstractValue = _abstractValueDomain.createDictionaryValue(
         originalValue._abstractValue,
         allocationNode,
@@ -260,8 +256,8 @@
   @override
   AbstractValue createMapValue(
       covariant PowersetValue originalValue,
-      Object allocationNode,
-      MemberEntity allocationElement,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
       covariant PowersetValue key,
       covariant PowersetValue value) {
     int powersetBits = originalValue._powersetBits;
@@ -292,8 +288,8 @@
   @override
   AbstractValue createSetValue(
       covariant PowersetValue originalValue,
-      Object allocationNode,
-      MemberEntity allocationElement,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
       covariant PowersetValue elementType) {
     int powersetBits = originalValue._powersetBits;
     AbstractValue abstractValue = _abstractValueDomain.createSetValue(
@@ -310,7 +306,7 @@
       _abstractValueDomain.isSet(value._abstractValue);
 
   @override
-  int getContainerLength(covariant PowersetValue value) =>
+  int? getContainerLength(covariant PowersetValue value) =>
       _powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse
           ? null
           : _abstractValueDomain.getContainerLength(value._abstractValue);
@@ -328,10 +324,10 @@
   @override
   AbstractValue createContainerValue(
       covariant PowersetValue originalValue,
-      Object allocationNode,
-      MemberEntity allocationElement,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
       covariant PowersetValue elementType,
-      int length) {
+      int? length) {
     int powersetBits = originalValue._powersetBits;
     AbstractValue abstractValue = _abstractValueDomain.createContainerValue(
         originalValue._abstractValue,
@@ -359,9 +355,9 @@
   }
 
   @override
-  AbstractValue getAbstractValueForNativeMethodParameterType(DartType type) {
+  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) {
     int powersetBits = _powersetBitsDomain.powersetTop;
-    AbstractValue abstractValue =
+    final abstractValue =
         _abstractValueDomain.getAbstractValueForNativeMethodParameterType(type);
     return wrapOrNull(abstractValue, powersetBits);
   }
@@ -389,17 +385,17 @@
   }
 
   @override
-  AbstractValue unionOfMany(covariant Iterable<AbstractValue> values) {
+  AbstractValue unionOfMany(Iterable<AbstractValue> values) {
     PowersetValue result = PowersetValue(
         _abstractValueDomain.emptyType, _powersetBitsDomain.powersetBottom);
-    for (PowersetValue value in values) {
-      result = union(result, value);
+    for (final value in values) {
+      result = union(result, value as PowersetValue);
     }
     return result;
   }
 
   @override
-  AbstractValue union(covariant PowersetValue a, covariant PowersetValue b) {
+  PowersetValue union(covariant PowersetValue a, covariant PowersetValue b) {
     int powersetBits =
         _powersetBitsDomain.union(a._powersetBits, b._powersetBits);
     AbstractValue abstractValue =
@@ -563,7 +559,7 @@
           _abstractValueDomain.isLateSentinel(value._abstractValue));
 
   @override
-  ClassEntity getExactClass(covariant PowersetValue value) =>
+  ClassEntity? getExactClass(covariant PowersetValue value) =>
       _abstractValueDomain.getExactClass(value._abstractValue);
 
   @override
@@ -688,7 +684,8 @@
 
   @override
   AbstractValueWithPrecision createFromStaticType(DartType type,
-      {ClassRelation classRelation = ClassRelation.subtype, bool nullable}) {
+      {ClassRelation classRelation = ClassRelation.subtype,
+      required bool nullable}) {
     int powersetBits = _powersetBitsDomain.createFromStaticType(type,
         classRelation: classRelation, nullable: nullable);
     var unwrapped = _abstractValueDomain.createFromStaticType(type,
@@ -833,7 +830,7 @@
 
   @override
   UniverseSelectorConstraints createSelectorConstraints(
-      Selector selector, Object initialConstraint) {
+      Selector selector, Object? initialConstraint) {
     return PowersetsUniverseSelectorConstraints(
         _selectorConstraintsStrategy.createSelectorConstraints(
             selector,
@@ -847,7 +844,7 @@
       covariant JClosedWorld world) {
     return _selectorConstraintsStrategy.appliedUnnamed(
         dynamicUse.withReceiverConstraint(
-            unwrapOrNull(dynamicUse.receiverConstraint)),
+            unwrapOrNull(dynamicUse.receiverConstraint as PowersetValue?)),
         member,
         world);
   }
@@ -859,7 +856,7 @@
   const PowersetsUniverseSelectorConstraints(this._universeSelectorConstraints);
 
   @override
-  bool addReceiverConstraint(Object constraint) =>
+  bool addReceiverConstraint(Object? constraint) =>
       _universeSelectorConstraints.addReceiverConstraint(constraint == null
           ? null
           : (constraint as PowersetValue)._abstractValue);
diff --git a/pkg/compiler/lib/src/inferrer/set_tracer.dart b/pkg/compiler/lib/src/inferrer/set_tracer.dart
index 47e38ae..817a346 100644
--- a/pkg/compiler/lib/src/inferrer/set_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/set_tracer.dart
@@ -2,13 +2,10 @@
 // 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.10
-
 library compiler.src.inferrer.set_tracer;
 
 import '../common/names.dart';
 import '../elements/entities.dart';
-import '../universe/selector.dart' show Selector;
 import 'node_tracer.dart';
 import 'type_graph_nodes.dart';
 
@@ -69,19 +66,19 @@
 class SetTracerVisitor extends TracerVisitor {
   List<TypeInformation> inputs = <TypeInformation>[];
 
-  SetTracerVisitor(tracedType, inferrer) : super(tracedType, inferrer);
+  SetTracerVisitor(super.tracedType, super.inferrer);
 
   /// Returns [true] if the analysis completed successfully, [false] if it
   /// bailed out. In the former case, [inputs] holds a list of
   /// [TypeInformation] nodes that flow into the element type of this set.
   bool run() {
     analyze();
-    SetTypeInformation set = tracedType;
+    final set = tracedType as SetTypeInformation;
     if (continueAnalyzing) {
       set.addFlowsIntoTargets(flowsInto);
       return true;
     }
-    inputs = null;
+    inputs.clear();
     return false;
   }
 
@@ -103,14 +100,15 @@
   @override
   visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
     super.visitDynamicCallSiteTypeInformation(info);
-    Selector selector = info.selector;
-    String selectorName = selector.name;
+    final selector = info.selector!;
+    final selectorName = selector.name;
+    final arguments = info.arguments;
     if (currentUser == info.receiver) {
       if (!okSetSelectorSet.contains(selectorName)) {
         if (selector.isCall) {
           switch (selectorName) {
             case 'add':
-              inputs.add(info.arguments.positional[0]);
+              inputs.add(arguments!.positional[0]);
               break;
             case 'addAll':
               // TODO(fishythefish): Extract type argument from type
diff --git a/pkg/compiler/lib/src/inferrer/trivial.dart b/pkg/compiler/lib/src/inferrer/trivial.dart
index fd2d10b..61dbb61 100644
--- a/pkg/compiler/lib/src/inferrer/trivial.dart
+++ b/pkg/compiler/lib/src/inferrer/trivial.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
 import '../elements/entities.dart';
 import '../elements/names.dart';
@@ -13,7 +11,7 @@
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
 import '../universe/use.dart';
-import '../world.dart';
+import '../world_interfaces.dart';
 import 'abstract_value_domain.dart';
 import 'abstract_value_strategy.dart';
 
@@ -55,7 +53,7 @@
   AbstractBool isJsIndexable(AbstractValue value) => AbstractBool.Maybe;
 
   @override
-  MemberEntity locateSingleMember(AbstractValue receiver, Selector selector) =>
+  MemberEntity? locateSingleMember(AbstractValue receiver, Selector selector) =>
       null;
 
   @override
@@ -77,7 +75,7 @@
       const TrivialAbstractValue();
 
   @override
-  PrimitiveConstantValue getPrimitiveValue(AbstractValue value) => null;
+  PrimitiveConstantValue? getPrimitiveValue(AbstractValue value) => null;
 
   @override
   AbstractValue createPrimitiveValue(
@@ -88,13 +86,13 @@
   bool isPrimitiveValue(AbstractValue value) => false;
 
   @override
-  MemberEntity getAllocationElement(AbstractValue value) => null;
+  MemberEntity? getAllocationElement(AbstractValue value) => null;
 
   @override
-  Object getAllocationNode(AbstractValue value) => null;
+  Object? getAllocationNode(AbstractValue value) => null;
 
   @override
-  AbstractValue getGeneralization(AbstractValue value) =>
+  AbstractValue getGeneralization(AbstractValue? value) =>
       const TrivialAbstractValue();
 
   @override
@@ -115,9 +113,9 @@
 
   @override
   AbstractValue createDictionaryValue(
-          AbstractValue originalValue,
-          Object allocationNode,
-          MemberEntity allocationElement,
+          AbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
           AbstractValue key,
           AbstractValue value,
           Map<String, AbstractValue> mappings) =>
@@ -138,9 +136,9 @@
 
   @override
   AbstractValue createMapValue(
-          AbstractValue originalValue,
-          Object allocationNode,
-          MemberEntity allocationElement,
+          AbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
           AbstractValue key,
           AbstractValue value) =>
       const TrivialAbstractValue();
@@ -155,9 +153,9 @@
 
   @override
   AbstractValue createSetValue(
-          AbstractValue originalValue,
-          Object allocationNode,
-          MemberEntity allocationElement,
+          AbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
           AbstractValue elementType) =>
       const TrivialAbstractValue();
 
@@ -165,7 +163,7 @@
   bool isSet(AbstractValue value) => false;
 
   @override
-  int getContainerLength(AbstractValue value) => null;
+  int? getContainerLength(AbstractValue value) => null;
 
   @override
   AbstractValue getContainerElementType(AbstractValue value) {
@@ -175,11 +173,11 @@
 
   @override
   AbstractValue createContainerValue(
-          AbstractValue originalValue,
-          Object allocationNode,
-          MemberEntity allocationElement,
+          AbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
           AbstractValue elementType,
-          int length) =>
+          int? length) =>
       const TrivialAbstractValue();
 
   @override
@@ -190,7 +188,7 @@
       const TrivialAbstractValue();
 
   @override
-  AbstractValue getAbstractValueForNativeMethodParameterType(DartType type) =>
+  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) =>
       null;
 
   @override
@@ -295,7 +293,7 @@
   AbstractBool isLateSentinel(AbstractValue value) => AbstractBool.Maybe;
 
   @override
-  ClassEntity getExactClass(AbstractValue value) => null;
+  ClassEntity? getExactClass(AbstractValue value) => null;
 
   @override
   AbstractBool isExact(AbstractValue value) => AbstractBool.Maybe;
@@ -363,8 +361,8 @@
 
   @override
   AbstractValueWithPrecision createFromStaticType(DartType type,
-      {ClassRelation classRelation = ClassRelation.subtype, bool nullable}) {
-    assert(nullable != null);
+      {ClassRelation classRelation = ClassRelation.subtype,
+      required bool nullable}) {
     return const AbstractValueWithPrecision(TrivialAbstractValue(), false);
   }
 
@@ -466,7 +464,7 @@
 
   @override
   UniverseSelectorConstraints createSelectorConstraints(
-      Selector selector, Object initialConstraint) {
+      Selector selector, Object? initialConstraint) {
     return const TrivialUniverseSelectorConstraints();
   }
 
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 5dc9a94..ab20cd2 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -17,8 +17,8 @@
 import '../world_interfaces.dart' show JClosedWorld;
 import 'abstract_value_domain.dart';
 import 'debug.dart' as debug;
-import 'locals_handler.dart' show ArgumentsTypes;
 import 'engine_interfaces.dart';
+import 'locals_handler.dart' show ArgumentsTypes;
 import 'type_system.dart';
 
 /// Common class for all nodes in the graph. The current nodes are:
@@ -753,23 +753,27 @@
   bool _isTearOffClosureParameter = false;
 
   ParameterTypeInformation.localFunction(
-      AbstractValueDomain abstractValueDomain,
-      MemberTypeInformation context,
+      super.abstractValueDomain,
+      MemberTypeInformation super.context,
       this._parameter,
       this._type,
       this._method)
       : _isInstanceMemberParameter = false,
         _isClosureParameter = true,
         _isInitializingFormal = false,
-        super._internal(abstractValueDomain, context);
+        super._internal();
 
-  ParameterTypeInformation.static(AbstractValueDomain abstractValueDomain,
-      MemberTypeInformation context, this._parameter, this._type, this._method,
+  ParameterTypeInformation.static(
+      super.abstractValueDomain,
+      MemberTypeInformation super.context,
+      this._parameter,
+      this._type,
+      this._method,
       {bool isInitializingFormal = false})
       : _isInstanceMemberParameter = false,
         _isClosureParameter = false,
         _isInitializingFormal = isInitializingFormal,
-        super._internal(abstractValueDomain, context);
+        super._internal();
 
   ParameterTypeInformation.instanceMember(
       AbstractValueDomain abstractValueDomain,
@@ -1314,7 +1318,7 @@
             inferrer.returnsMapValueType(localSelector, typeMask)) {
           if (abstractValueDomain.isDictionary(typeMask)) {
             AbstractValue arg = arguments!.positional[0].type;
-            ConstantValue value = abstractValueDomain.getPrimitiveValue(arg);
+            final value = abstractValueDomain.getPrimitiveValue(arg);
             if (value is StringConstantValue) {
               String key = value.stringValue;
               if (abstractValueDomain.containsDictionaryKey(typeMask, key)) {
@@ -1483,7 +1487,7 @@
 /// because we know such node will never be refined to a different
 /// type.
 class ConcreteTypeInformation extends TypeInformation {
-  ConcreteTypeInformation(AbstractValue type) : super.untracked(type) {
+  ConcreteTypeInformation(super.type) : super.untracked() {
     this.isStable = true;
   }
 
@@ -1660,7 +1664,7 @@
   final int? originalLength;
 
   /// The length after the container has been traced.
-  late int inferredLength;
+  int? inferredLength;
 
   ListTypeInformation(
       AbstractValueDomain abstractValueDomain,
@@ -1717,9 +1721,8 @@
 /// An [ElementInContainerTypeInformation] holds the common type of the
 /// elements in a [ListTypeInformation].
 class ElementInContainerTypeInformation extends InferredTypeInformation {
-  ElementInContainerTypeInformation(AbstractValueDomain abstractValueDomain,
-      MemberTypeInformation? context, elementType)
-      : super(abstractValueDomain, context, elementType);
+  ElementInContainerTypeInformation(
+      super.abstractValueDomain, super.context, super.elementType);
 
   @override
   String toString() => 'Element in container $type';
@@ -1784,9 +1787,8 @@
 /// An [ElementInSetTypeInformation] holds the common type of the elements in a
 /// [SetTypeInformation].
 class ElementInSetTypeInformation extends InferredTypeInformation {
-  ElementInSetTypeInformation(AbstractValueDomain abstractValueDomain,
-      MemberTypeInformation? context, elementType)
-      : super(abstractValueDomain, context, elementType);
+  ElementInSetTypeInformation(
+      super.abstractValueDomain, super.context, super.elementType);
 
   @override
   String toString() => 'Element in set $type';
@@ -1966,9 +1968,8 @@
 /// A [KeyInMapTypeInformation] holds the common type
 /// for the keys in a [MapTypeInformation]
 class KeyInMapTypeInformation extends InferredTypeInformation {
-  KeyInMapTypeInformation(AbstractValueDomain abstractValueDomain,
-      MemberTypeInformation? context, TypeInformation keyType)
-      : super(abstractValueDomain, context, keyType);
+  KeyInMapTypeInformation(
+      super.abstractValueDomain, super.context, TypeInformation super.keyType);
 
   @override
   accept(TypeInformationVisitor visitor) {
@@ -1987,10 +1988,9 @@
   // mode can ever be marked as [nonNull].
   final bool nonNull;
 
-  ValueInMapTypeInformation(AbstractValueDomain abstractValueDomain,
-      MemberTypeInformation? context, TypeInformation? valueType,
-      [this.nonNull = false])
-      : super(abstractValueDomain, context, valueType);
+  ValueInMapTypeInformation(
+      super.abstractValueDomain, super.context, super.valueType,
+      [this.nonNull = false]);
 
   @override
   accept(TypeInformationVisitor visitor) {
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/constants.dart b/pkg/compiler/lib/src/inferrer/typemasks/constants.dart
index 7684c46..7dea399 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/constants.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/constants.dart
@@ -2,13 +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.
 
-// @dart = 2.10
-
 library types.constants;
 
 import '../../constants/constant_system.dart' as constant_system;
 import '../../constants/values.dart';
-import '../../world.dart' show JClosedWorld;
+import '../../world_interfaces.dart' show JClosedWorld;
 import 'masks.dart';
 
 /// Computes the [TypeMask] for the constant [value].
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/container_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/container_type_mask.dart
index b6dca48..df9ff1b 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/container_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/container_type_mask.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 part of masks;
 
 /// A [TypeMask] for a specific allocation site of a container (currently only
@@ -17,18 +15,18 @@
   @override
   final TypeMask forwardTo;
 
-  final ir.Node /*?*/ _allocationNode;
+  final ir.Node? _allocationNode;
   @override
-  ir.Node get allocationNode => _allocationNode /*!*/;
+  ir.Node? get allocationNode => _allocationNode;
 
   @override
-  final MemberEntity allocationElement;
+  final MemberEntity? allocationElement;
 
   // The element type of this container.
   final TypeMask elementType;
 
   // The length of the container.
-  final int length;
+  final int? length;
 
   const ContainerTypeMask(this.forwardTo, this._allocationNode,
       this.allocationElement, this.elementType, this.length);
@@ -37,10 +35,10 @@
   factory ContainerTypeMask.readFromDataSource(
       DataSourceReader source, CommonMasks domain) {
     source.begin(tag);
-    TypeMask forwardTo = TypeMask.readFromDataSource(source, domain);
-    MemberEntity allocationElement = source.readMemberOrNull();
-    TypeMask elementType = TypeMask.readFromDataSource(source, domain);
-    int length = source.readIntOrNull();
+    final forwardTo = TypeMask.readFromDataSource(source, domain);
+    final allocationElement = source.readMemberOrNull();
+    final elementType = TypeMask.readFromDataSource(source, domain);
+    final length = source.readIntOrNull();
     source.end(tag);
     return ContainerTypeMask(
         forwardTo, null, allocationElement, elementType, length);
@@ -59,7 +57,7 @@
   }
 
   @override
-  ContainerTypeMask withFlags({bool isNullable, bool hasLateSentinel}) {
+  ContainerTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
     isNullable ??= this.isNullable;
     hasLateSentinel ??= this.hasLateSentinel;
     if (isNullable == this.isNullable &&
@@ -76,21 +74,15 @@
   }
 
   @override
-  bool get isContainer => true;
-  @override
   bool get isExact => true;
 
   @override
-  TypeMask _unionSpecialCases(TypeMask other, CommonMasks domain,
-      {bool isNullable, bool hasLateSentinel}) {
-    assert(isNullable != null);
-    assert(hasLateSentinel != null);
-    if (other is ContainerTypeMask &&
-        elementType != null &&
-        other.elementType != null) {
-      TypeMask newElementType = elementType.union(other.elementType, domain);
-      int newLength = (length == other.length) ? length : null;
-      TypeMask newForwardTo = forwardTo.union(other.forwardTo, domain);
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+      {required bool isNullable, required bool hasLateSentinel}) {
+    if (other is ContainerTypeMask) {
+      final newElementType = elementType.union(other.elementType, domain);
+      final newLength = (length == other.length) ? length : null;
+      final newForwardTo = forwardTo.union(other.forwardTo, domain);
       return ContainerTypeMask(
           newForwardTo,
           allocationNode == other.allocationNode ? allocationNode : null,
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/dictionary_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/dictionary_type_mask.dart
index c2a4730..31563bd 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/dictionary_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/dictionary_type_mask.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 part of masks;
 
 /// A [DictionaryTypeMask] is a [TypeMask] for a specific allocation
@@ -20,25 +18,19 @@
   // The underlying key/value map of this dictionary.
   final Map<String, TypeMask> _typeMap;
 
-  const DictionaryTypeMask(
-      TypeMask forwardTo,
-      ir.Node allocationNode,
-      MemberEntity allocationElement,
-      TypeMask keyType,
-      TypeMask valueType,
-      this._typeMap)
-      : super(forwardTo, allocationNode, allocationElement, keyType, valueType);
+  const DictionaryTypeMask(super.forwardTo, super._allocationNode,
+      super.allocationElement, super.keyType, super.valueType, this._typeMap);
 
   /// Deserializes a [DictionaryTypeMask] object from [source].
   factory DictionaryTypeMask.readFromDataSource(
       DataSourceReader source, CommonMasks domain) {
     source.begin(tag);
-    TypeMask forwardTo = TypeMask.readFromDataSource(source, domain);
-    MemberEntity allocationElement = source.readMemberOrNull();
-    TypeMask keyType = TypeMask.readFromDataSource(source, domain);
-    TypeMask valueType = TypeMask.readFromDataSource(source, domain);
-    Map<String, TypeMask> typeMap =
-        source.readStringMap(() => TypeMask.readFromDataSource(source, domain));
+    final forwardTo = TypeMask.readFromDataSource(source, domain);
+    final allocationElement = source.readMemberOrNull();
+    final keyType = TypeMask.readFromDataSource(source, domain);
+    final valueType = TypeMask.readFromDataSource(source, domain);
+    final typeMap = source
+        .readStringMap(() => TypeMask.readFromDataSource(source, domain))!;
     source.end(tag);
     return DictionaryTypeMask(
         forwardTo, null, allocationElement, keyType, valueType, typeMap);
@@ -60,7 +52,7 @@
   }
 
   @override
-  DictionaryTypeMask withFlags({bool isNullable, bool hasLateSentinel}) {
+  DictionaryTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
     isNullable ??= this.isNullable;
     hasLateSentinel ??= this.hasLateSentinel;
     if (isNullable == this.isNullable &&
@@ -78,19 +70,15 @@
   }
 
   @override
-  bool get isDictionary => true;
-  @override
   bool get isExact => true;
 
   bool containsKey(String key) => _typeMap.containsKey(key);
 
-  TypeMask getValueForKey(String key) => _typeMap[key];
+  TypeMask? getValueForKey(String key) => _typeMap[key];
 
   @override
-  TypeMask _unionSpecialCases(TypeMask other, CommonMasks domain,
-      {bool isNullable, bool hasLateSentinel}) {
-    assert(isNullable != null);
-    assert(hasLateSentinel != null);
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+      {required bool isNullable, required bool hasLateSentinel}) {
     if (other is DictionaryTypeMask) {
       TypeMask newForwardTo = forwardTo.union(other.forwardTo, domain);
       TypeMask newKeyType = keyType.union(other.keyType, domain);
@@ -103,7 +91,7 @@
       });
       other._typeMap.forEach((k, v) {
         if (_typeMap.containsKey(k)) {
-          mappings[k] = v.union(_typeMap[k], domain);
+          mappings[k] = v.union(_typeMap[k]!, domain);
         } else {
           mappings[k] = v.nullable();
         }
@@ -111,9 +99,7 @@
       return DictionaryTypeMask(
           newForwardTo, null, null, newKeyType, newValueType, mappings);
     }
-    if (other is MapTypeMask &&
-        (other.keyType != null) &&
-        (other.valueType != null)) {
+    if (other is MapTypeMask) {
       TypeMask newForwardTo = forwardTo.union(other.forwardTo, domain);
       TypeMask newKeyType = keyType.union(other.keyType, domain);
       TypeMask newValueType = valueType.union(other.valueType, domain);
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/flat_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/flat_type_mask.dart
index 5611b25..9e0d7a2 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/flat_type_mask.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 part of masks;
 
 enum _FlatTypeMaskKind { empty, exact, subclass, subtype }
@@ -24,7 +22,7 @@
   static const int _LATE_SENTINEL_MASK = 1 << _LATE_SENTINEL_INDEX;
   static const int _ALL_MASK = (1 << _USED_INDICES) - 1;
 
-  final ClassEntity base;
+  final ClassEntity? base;
   final int flags;
 
   static int _computeFlags(_FlatTypeMaskKind kind,
@@ -98,7 +96,7 @@
   /// Ensures that the generated mask is normalized, i.e., a call to
   /// [TypeMask.assertIsNormalized] with the factory's result returns `true`.
   factory FlatTypeMask.normalized(
-      ClassEntity base, int flags, CommonMasks domain) {
+      ClassEntity? base, int flags, CommonMasks domain) {
     bool isNullable = _hasNullableFlag(flags);
     bool hasLateSentinel = _hasLateSentinelFlag(flags);
     if (base == domain.commonElements.nullClass) {
@@ -109,14 +107,14 @@
       return FlatTypeMask._(base, flags);
     }
     if (kind == _FlatTypeMaskKind.subtype) {
-      if (!domain._closedWorld.classHierarchy.hasAnyStrictSubtype(base) ||
+      if (!domain._closedWorld.classHierarchy.hasAnyStrictSubtype(base!) ||
           domain._closedWorld.classHierarchy.hasOnlySubclasses(base)) {
         flags = _computeFlags(_FlatTypeMaskKind.subclass,
             isNullable: isNullable, hasLateSentinel: hasLateSentinel);
       }
     }
     if (kind == _FlatTypeMaskKind.subclass &&
-        !domain._closedWorld.classHierarchy.hasAnyStrictSubclass(base)) {
+        !domain._closedWorld.classHierarchy.hasAnyStrictSubclass(base!)) {
       flags = _computeFlags(_FlatTypeMaskKind.exact,
           isNullable: isNullable, hasLateSentinel: hasLateSentinel);
     }
@@ -127,7 +125,7 @@
   factory FlatTypeMask.readFromDataSource(
       DataSourceReader source, CommonMasks domain) {
     source.begin(tag);
-    ClassEntity base = source.readClassOrNull();
+    final base = source.readClassOrNull();
     int flags = source.readInt();
     source.end(tag);
     return domain.getCachedMask(base, flags, () => FlatTypeMask._(base, flags));
@@ -172,21 +170,6 @@
     return AbstractBool.Maybe;
   }
 
-  @override
-  bool get isUnion => false;
-  @override
-  bool get isContainer => false;
-  @override
-  bool get isSet => false;
-  @override
-  bool get isMap => false;
-  @override
-  bool get isDictionary => false;
-  @override
-  bool get isForwarding => false;
-  @override
-  bool get isValue => false;
-
   // TODO(kasperl): Get rid of these. They should not be a visible
   // part of the implementation because they make it hard to add
   // proper union types if we ever want to.
@@ -194,7 +177,7 @@
   bool get isSubtype => _kind == _FlatTypeMaskKind.subtype;
 
   @override
-  FlatTypeMask withFlags({bool isNullable, bool hasLateSentinel}) {
+  FlatTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
     int newFlags = _computeFlags(_kind,
         isNullable: isNullable ?? this.isNullable,
         hasLateSentinel: hasLateSentinel ?? this.hasLateSentinel);
@@ -211,10 +194,10 @@
     } else if (isExact) {
       return false;
     } else if (isSubclass) {
-      return closedWorld.classHierarchy.isSubclassOf(other, base);
+      return closedWorld.classHierarchy.isSubclassOf(other, base!);
     } else {
       assert(isSubtype);
-      return closedWorld.classHierarchy.isSubtypeOf(other, base);
+      return closedWorld.classHierarchy.isSubtypeOf(other, base!);
     }
   }
 
@@ -258,12 +241,12 @@
     if (other is! FlatTypeMask) return other.containsMask(this, closedWorld);
     // The other must be flat, so compare base and flags.
     FlatTypeMask flatOther = other;
-    ClassEntity otherBase = flatOther.base;
+    final otherBase = flatOther.base;
     // If other is exact, it only contains its base.
     // TODO(herhut): Get rid of _isSingleImplementationOf.
     if (flatOther.isExact) {
       return (isExact && base == otherBase) ||
-          _isSingleImplementationOf(otherBase, closedWorld);
+          _isSingleImplementationOf(otherBase!, closedWorld);
     }
     // If other is subclass, this has to be subclass, as well. Unless
     // flatOther.base covers all subtypes of this. Currently, we only
@@ -273,11 +256,11 @@
     if (flatOther.isSubclass) {
       if (isSubtype)
         return (otherBase == closedWorld.commonElements.objectClass);
-      return closedWorld.classHierarchy.isSubclassOf(base, otherBase);
+      return closedWorld.classHierarchy.isSubclassOf(base!, otherBase!);
     }
     assert(flatOther.isSubtype);
     // Check whether this TypeMask satisfies otherBase's interface.
-    return satisfies(otherBase, closedWorld);
+    return satisfies(otherBase!, closedWorld);
   }
 
   @override
@@ -324,19 +307,19 @@
   @override
   bool satisfies(ClassEntity cls, JClosedWorld closedWorld) {
     if (isEmptyOrFlagged) return false;
-    if (closedWorld.classHierarchy.isSubtypeOf(base, cls)) return true;
+    if (closedWorld.classHierarchy.isSubtypeOf(base!, cls)) return true;
     return false;
   }
 
   @override
-  ClassEntity singleClass(JClosedWorld closedWorld) {
+  ClassEntity? singleClass(JClosedWorld closedWorld) {
     if (isEmptyOrFlagged) return null;
     if (isNullable) return null; // It is Null and some other class.
     if (hasLateSentinel) return null;
     if (isExact) {
       return base;
     } else if (isSubclass) {
-      return closedWorld.classHierarchy.hasAnyStrictSubclass(base)
+      return closedWorld.classHierarchy.hasAnyStrictSubclass(base!)
           ? null
           : base;
     } else {
@@ -354,7 +337,6 @@
   @override
   TypeMask union(TypeMask other, CommonMasks domain) {
     JClosedWorld closedWorld = domain._closedWorld;
-    assert(other != null);
     assert(TypeMask.assertIsNormalized(this, closedWorld));
     assert(TypeMask.assertIsNormalized(other, closedWorld));
     if (other is! FlatTypeMask) return other.union(this, domain);
@@ -369,18 +351,21 @@
           isNullable: isNullable, hasLateSentinel: hasLateSentinel);
     } else if (base == flatOther.base) {
       return unionSame(flatOther, domain);
-    } else if (closedWorld.classHierarchy.isSubclassOf(flatOther.base, base)) {
+    } else if (closedWorld.classHierarchy
+        .isSubclassOf(flatOther.base!, base!)) {
       return unionStrictSubclass(flatOther, domain);
-    } else if (closedWorld.classHierarchy.isSubclassOf(base, flatOther.base)) {
+    } else if (closedWorld.classHierarchy
+        .isSubclassOf(base!, flatOther.base!)) {
       return flatOther.unionStrictSubclass(this, domain);
-    } else if (closedWorld.classHierarchy.isSubtypeOf(flatOther.base, base)) {
+    } else if (closedWorld.classHierarchy.isSubtypeOf(flatOther.base!, base!)) {
       return unionStrictSubtype(flatOther, domain);
-    } else if (closedWorld.classHierarchy.isSubtypeOf(base, flatOther.base)) {
+    } else if (closedWorld.classHierarchy.isSubtypeOf(base!, flatOther.base!)) {
       return flatOther.unionStrictSubtype(this, domain);
     } else {
-      return UnionTypeMask._internal(
-          <FlatTypeMask>[withoutFlags(), flatOther.withoutFlags()],
-          isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+      return UnionTypeMask._internal([
+        withoutFlags() as FlatTypeMask,
+        flatOther.withoutFlags() as FlatTypeMask
+      ], isNullable: isNullable, hasLateSentinel: hasLateSentinel);
     }
   }
 
@@ -399,13 +384,13 @@
     } else if (other.flags == combined) {
       return other;
     } else {
-      return FlatTypeMask.normalized(base, combined, domain);
+      return FlatTypeMask.normalized(base!, combined, domain);
     }
   }
 
   TypeMask unionStrictSubclass(FlatTypeMask other, CommonMasks domain) {
     assert(base != other.base);
-    assert(domain._closedWorld.classHierarchy.isSubclassOf(other.base, base));
+    assert(domain._closedWorld.classHierarchy.isSubclassOf(other.base!, base!));
     assert(TypeMask.assertIsNormalized(this, domain._closedWorld));
     assert(TypeMask.assertIsNormalized(other, domain._closedWorld));
     int combined;
@@ -432,8 +417,9 @@
 
   TypeMask unionStrictSubtype(FlatTypeMask other, CommonMasks domain) {
     assert(base != other.base);
-    assert(!domain._closedWorld.classHierarchy.isSubclassOf(other.base, base));
-    assert(domain._closedWorld.classHierarchy.isSubtypeOf(other.base, base));
+    assert(
+        !domain._closedWorld.classHierarchy.isSubclassOf(other.base!, base!));
+    assert(domain._closedWorld.classHierarchy.isSubtypeOf(other.base!, base!));
     assert(TypeMask.assertIsNormalized(this, domain._closedWorld));
     assert(TypeMask.assertIsNormalized(other, domain._closedWorld));
     // Since the other mask is a subtype of this mask, we need the
@@ -450,13 +436,12 @@
 
   @override
   TypeMask intersection(TypeMask other, CommonMasks domain) {
-    assert(other != null);
     if (other is! FlatTypeMask) return other.intersection(this, domain);
     assert(TypeMask.assertIsNormalized(this, domain._closedWorld));
     assert(TypeMask.assertIsNormalized(other, domain._closedWorld));
     FlatTypeMask flatOther = other;
 
-    ClassEntity otherBase = flatOther.base;
+    final otherBase = flatOther.base;
 
     bool includeNull = isNullable && flatOther.isNullable;
     bool includeLateSentinel = hasLateSentinel && flatOther.hasLateSentinel;
@@ -469,8 +454,8 @@
           isNullable: includeNull, hasLateSentinel: includeLateSentinel);
     }
 
-    SubclassResult result = domain._closedWorld.classHierarchy
-        .commonSubclasses(base, _classQuery, otherBase, flatOther._classQuery);
+    SubclassResult result = domain._closedWorld.classHierarchy.commonSubclasses(
+        base!, _classQuery, otherBase!, flatOther._classQuery);
 
     switch (result.kind) {
       case SubclassResultKind.EMPTY:
@@ -540,16 +525,18 @@
     if (base == flatOther.base) return false;
     if (isExact && flatOther.isExact) return true;
 
-    if (isExact) return !flatOther.contains(base, closedWorld);
-    if (flatOther.isExact) return !contains(flatOther.base, closedWorld);
+    if (isExact) return !flatOther.contains(base!, closedWorld);
+    if (flatOther.isExact) return !contains(flatOther.base!, closedWorld);
+    final thisBase = base!;
+    final otherBase = flatOther.base!;
 
     // Normalization guarantees that isExact === !isSubclass && !isSubtype.
     // Both are subclass or subtype masks, so if there is a subclass
     // relationship, they are not disjoint.
-    if (closedWorld.classHierarchy.isSubclassOf(flatOther.base, base)) {
+    if (closedWorld.classHierarchy.isSubclassOf(otherBase, thisBase)) {
       return false;
     }
-    if (closedWorld.classHierarchy.isSubclassOf(base, flatOther.base)) {
+    if (closedWorld.classHierarchy.isSubclassOf(thisBase, otherBase)) {
       return false;
     }
 
@@ -567,11 +554,14 @@
     }
     assert(a.isSubclass || a.isSubtype);
     assert(b.isSubtype);
+    final aBase = a.base!;
     var elements = a.isSubclass
-        ? closedWorld.classHierarchy.strictSubclassesOf(a.base)
-        : closedWorld.classHierarchy.strictSubtypesOf(a.base);
+        ? closedWorld.classHierarchy.strictSubclassesOf(aBase)
+        : closedWorld.classHierarchy.strictSubtypesOf(aBase);
     for (var element in elements) {
-      if (closedWorld.classHierarchy.isSubtypeOf(element, b.base)) return false;
+      if (closedWorld.classHierarchy.isSubtypeOf(element, b.base!)) {
+        return false;
+      }
     }
     return true;
   }
@@ -596,7 +586,7 @@
 
   TypeMask intersectionStrictSubclass(FlatTypeMask other, CommonMasks domain) {
     assert(base != other.base);
-    assert(domain._closedWorld.classHierarchy.isSubclassOf(other.base, base));
+    assert(domain._closedWorld.classHierarchy.isSubclassOf(other.base!, base!));
     // If this mask isn't at least a subclass mask, then the
     // intersection with the other mask is empty.
     if (isExact) return intersectionEmpty(other);
@@ -630,25 +620,26 @@
           closedWorld.hasElementIn(commonElements.jsNullClass, name, element);
     }
 
-    ClassEntity other = element.enclosingClass;
+    final other = element.enclosingClass;
+    final thisBase = base!;
     if (other == commonElements.jsNullClass) {
       return isNullable;
     } else if (isExact) {
-      return closedWorld.hasElementIn(base, name, element);
+      return closedWorld.hasElementIn(thisBase, name, element);
     } else if (isSubclass) {
-      return closedWorld.hasElementIn(base, name, element) ||
-          closedWorld.classHierarchy.isSubclassOf(other, base) ||
-          closedWorld.hasAnySubclassThatMixes(base, other);
+      return closedWorld.hasElementIn(thisBase, name, element) ||
+          closedWorld.classHierarchy.isSubclassOf(other!, thisBase) ||
+          closedWorld.hasAnySubclassThatMixes(thisBase, other);
     } else {
       assert(isSubtype);
-      bool result = closedWorld.hasElementIn(base, name, element) ||
-          closedWorld.classHierarchy.isSubtypeOf(other, base) ||
-          closedWorld.hasAnySubclassThatImplements(other, base) ||
-          closedWorld.hasAnySubclassOfMixinUseThatImplements(other, base);
+      bool result = closedWorld.hasElementIn(thisBase, name, element) ||
+          closedWorld.classHierarchy.isSubtypeOf(other!, thisBase) ||
+          closedWorld.hasAnySubclassThatImplements(other, thisBase) ||
+          closedWorld.hasAnySubclassOfMixinUseThatImplements(other, thisBase);
       if (result) return true;
       // If the class is used as a mixin, we have to check if the element
       // can be hit from any of the mixin applications.
-      Iterable<ClassEntity> mixinUses = closedWorld.mixinUsesOf(base);
+      Iterable<ClassEntity> mixinUses = closedWorld.mixinUsesOf(thisBase);
       return mixinUses.any((mixinApplication) =>
           closedWorld.hasElementIn(mixinApplication, name, element) ||
           closedWorld.classHierarchy.isSubclassOf(other, mixinApplication) ||
@@ -666,13 +657,14 @@
     // TODO(johnniwinther): A type mask cannot be abstract. Remove the need
     // for this noise (currently used for super-calls in inference and mirror
     // usage).
-    if (isExact && base.isAbstract) return false;
+    final thisBase = base!;
+    if (isExact && thisBase.isAbstract) return false;
 
-    return closedWorld.needsNoSuchMethod(base, selector, _classQuery);
+    return closedWorld.needsNoSuchMethod(thisBase, selector, _classQuery);
   }
 
   @override
-  MemberEntity locateSingleMember(Selector selector, CommonMasks domain) {
+  MemberEntity? locateSingleMember(Selector selector, CommonMasks domain) {
     if (isEmptyOrFlagged) return null;
     JClosedWorld closedWorld = domain._closedWorld;
     if (closedWorld.includesClosureCallInDomain(selector, this, domain))
@@ -681,23 +673,26 @@
         closedWorld.locateMembersInDomain(selector, this, domain);
     if (targets.length != 1) return null;
     MemberEntity result = targets.first;
-    ClassEntity enclosing = result.enclosingClass;
+    final enclosing = result.enclosingClass!;
+    final thisBase = base!;
     // We only return the found element if it is guaranteed to be implemented on
     // all classes in the receiver type [this]. It could be found only in a
     // subclass or in an inheritance-wise unrelated class in case of subtype
     // selectors.
     if (isSubtype) {
       // if (closedWorld.isUsedAsMixin(enclosing)) {
-      if (closedWorld.everySubtypeIsSubclassOfOrMixinUseOf(base, enclosing)) {
+      if (closedWorld.everySubtypeIsSubclassOfOrMixinUseOf(
+          thisBase, enclosing)) {
         return result;
       }
       //}
       return null;
     } else {
-      if (closedWorld.classHierarchy.isSubclassOf(base, enclosing)) {
+      if (closedWorld.classHierarchy.isSubclassOf(thisBase, enclosing)) {
         return result;
       }
-      if (closedWorld.isSubclassOfMixinUseOf(base, enclosing)) return result;
+      if (closedWorld.isSubclassOfMixinUseOf(thisBase, enclosing))
+        return result;
     }
     return null;
   }
@@ -722,9 +717,9 @@
       if (isEmpty) 'empty',
       if (isNullable) 'null',
       if (hasLateSentinel) 'sentinel',
-      if (isExact) 'exact=${base.name}',
-      if (isSubclass) 'subclass=${base.name}',
-      if (isSubtype) 'subtype=${base.name}',
+      if (isExact) 'exact=${base!.name}',
+      if (isSubclass) 'subclass=${base!.name}',
+      if (isSubtype) 'subtype=${base!.name}',
     ], '|');
     buffer.write(']');
     return buffer.toString();
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/forwarding_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/forwarding_type_mask.dart
index 16e1cff..7cd26d5 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/forwarding_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/forwarding_type_mask.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 part of masks;
 
 /// A type mask that wraps another one, and delegates all its
@@ -29,21 +27,6 @@
   bool get isExact => forwardTo.isExact;
 
   @override
-  bool get isUnion => false;
-  @override
-  bool get isContainer => false;
-  @override
-  bool get isSet => false;
-  @override
-  bool get isMap => false;
-  @override
-  bool get isDictionary => false;
-  @override
-  bool get isValue => false;
-  @override
-  bool get isForwarding => true;
-
-  @override
   bool isInMask(TypeMask other, JClosedWorld closedWorld) {
     return forwardTo.isInMask(other, closedWorld);
   }
@@ -94,7 +77,7 @@
   }
 
   @override
-  ClassEntity singleClass(JClosedWorld closedWorld) {
+  ClassEntity? singleClass(JClosedWorld closedWorld) {
     return forwardTo.singleClass(closedWorld);
   }
 
@@ -118,8 +101,8 @@
         forwardTo.union(other, domain);
   }
 
-  TypeMask _unionSpecialCases(TypeMask other, CommonMasks domain,
-          {bool isNullable, bool hasLateSentinel}) =>
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+          {required bool isNullable, required bool hasLateSentinel}) =>
       null;
 
   @override
@@ -148,7 +131,7 @@
   }
 
   @override
-  MemberEntity locateSingleMember(Selector selector, CommonMasks domain) {
+  MemberEntity? locateSingleMember(Selector selector, CommonMasks domain) {
     return forwardTo.locateSingleMember(selector, domain);
   }
 
@@ -168,12 +151,11 @@
 
   // The [ir.Node] where this type mask was created. This value is not used
   // after type inference and therefore does not need to be serialized by
-  // subclasses. Using it outside of type inference may cause an exception to be
-  // thrown.
-  ir.Node /*?*/ get allocationNode;
+  // subclasses. It will always be null outside of the global inference phase.
+  ir.Node? get allocationNode;
 
   // The [Entity] where this type mask was created.
-  MemberEntity get allocationElement;
+  MemberEntity? get allocationElement;
 
   @override
   bool operator ==(other) {
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/map_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/map_type_mask.dart
index 20f5caa..cc71161 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/map_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/map_type_mask.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 part of masks;
 
 /// A [MapTypeMask] is a [TypeMask] for a specific allocation
@@ -17,12 +15,12 @@
   @override
   final TypeMask forwardTo;
 
-  final ir.Node /*?*/ _allocationNode;
+  final ir.Node? _allocationNode;
   @override
-  ir.Node get allocationNode => _allocationNode /*!*/;
+  ir.Node? get allocationNode => _allocationNode;
 
   @override
-  final MemberEntity allocationElement;
+  final MemberEntity? allocationElement;
 
   // The value type of this map.
   final TypeMask valueType;
@@ -37,10 +35,10 @@
   factory MapTypeMask.readFromDataSource(
       DataSourceReader source, CommonMasks domain) {
     source.begin(tag);
-    TypeMask forwardTo = TypeMask.readFromDataSource(source, domain);
-    MemberEntity allocationElement = source.readMemberOrNull();
-    TypeMask keyType = TypeMask.readFromDataSource(source, domain);
-    TypeMask valueType = TypeMask.readFromDataSource(source, domain);
+    final forwardTo = TypeMask.readFromDataSource(source, domain);
+    final allocationElement = source.readMemberOrNull();
+    final keyType = TypeMask.readFromDataSource(source, domain);
+    final valueType = TypeMask.readFromDataSource(source, domain);
     source.end(tag);
     return MapTypeMask(forwardTo, null, allocationElement, keyType, valueType);
   }
@@ -58,7 +56,7 @@
   }
 
   @override
-  MapTypeMask withFlags({bool isNullable, bool hasLateSentinel}) {
+  MapTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
     isNullable ??= this.isNullable;
     hasLateSentinel ??= this.hasLateSentinel;
     if (isNullable == this.isNullable &&
@@ -75,22 +73,12 @@
   }
 
   @override
-  bool get isContainer => false;
-  @override
-  bool get isMap => true;
-  @override
   bool get isExact => true;
 
   @override
-  TypeMask _unionSpecialCases(TypeMask other, CommonMasks domain,
-      {bool isNullable, bool hasLateSentinel}) {
-    assert(isNullable != null);
-    assert(hasLateSentinel != null);
-    if (other is MapTypeMask &&
-        keyType != null &&
-        other.keyType != null &&
-        valueType != null &&
-        other.valueType != null) {
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+      {required bool isNullable, required bool hasLateSentinel}) {
+    if (other is MapTypeMask) {
       TypeMask newKeyType = keyType.union(other.keyType, domain);
       TypeMask newValueType = valueType.union(other.valueType, domain);
       TypeMask newForwardTo = forwardTo.union(other.forwardTo, domain);
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
index b2f8896..b12d9c3 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 library masks;
 
 import 'package:kernel/ast.dart' as ir;
@@ -22,10 +20,9 @@
 import '../../universe/world_builder.dart'
     show UniverseSelectorConstraints, SelectorConstraintsStrategy;
 import '../../util/util.dart';
-import '../../world.dart' show JClosedWorld;
+import '../../world_interfaces.dart' show JClosedWorld;
 import '../abstract_value_domain.dart';
 import '../abstract_value_strategy.dart';
-import '../type_graph_inferrer.dart' show TypeGraphInferrer;
 import 'constants.dart';
 
 part 'container_type_mask.dart';
@@ -48,150 +45,121 @@
   CommonElements get commonElements => _closedWorld.commonElements;
   DartTypes get dartTypes => _closedWorld.dartTypes;
 
-  TypeMask _internalTopType;
-  TypeMask _dynamicType;
-  TypeMask _nonNullType;
-  TypeMask _nullType;
-  TypeMask _intType;
-  TypeMask _uint32Type;
-  TypeMask _uint31Type;
-  TypeMask _positiveIntType;
-  TypeMask _numNotIntType;
-  TypeMask _numType;
-  TypeMask _boolType;
-  TypeMask _functionType;
-  TypeMask _listType;
-  TypeMask _constListType;
-  TypeMask _fixedListType;
-  TypeMask _growableListType;
-  TypeMask _setType;
-  TypeMask _constSetType;
-  TypeMask _mapType;
-  TypeMask _constMapType;
-  TypeMask _stringType;
-  TypeMask _typeType;
-  TypeMask _syncStarIterableType;
-  TypeMask _asyncFutureType;
-  TypeMask _asyncStarStreamType;
-  TypeMask _indexablePrimitiveType;
-  TypeMask _readableArrayType;
-  TypeMask _mutableArrayType;
-  TypeMask _unmodifiableArrayType;
-  TypeMask _interceptorType;
-
   /// Cache of [FlatTypeMask]s grouped by the possible values of the
   /// `FlatTypeMask.flags` property.
-  final List<Map<ClassEntity, TypeMask>> _canonicalizedTypeMasks = List.filled(
+  final List<Map<ClassEntity, TypeMask>?> _canonicalizedTypeMasks = List.filled(
       _FlatTypeMaskKind.values.length << FlatTypeMask._USED_INDICES, null);
 
   /// Return the cached mask for [base] with the given flags, or
   /// calls [createMask] to create the mask and cache it.
-  TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) {
-    Map<ClassEntity, TypeMask> cachedMasks =
-        _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{};
-    return cachedMasks.putIfAbsent(base, createMask);
+  T getCachedMask<T extends TypeMask>(
+      ClassEntity? base, int flags, T createMask()) {
+    // `null` is a valid base so we allow it as a key in the map.
+    final Map<ClassEntity?, TypeMask> cachedMasks =
+        _canonicalizedTypeMasks[flags] ??= {};
+    return cachedMasks.putIfAbsent(base, createMask) as T;
   }
 
   @override
-  TypeMask get internalTopType => _internalTopType ??= TypeMask.subclass(
+  late final TypeMask internalTopType = TypeMask.subclass(
       _closedWorld.commonElements.objectClass, _closedWorld,
       hasLateSentinel: true);
 
   @override
-  TypeMask get dynamicType => _dynamicType ??=
+  late final TypeMask dynamicType =
       TypeMask.subclass(_closedWorld.commonElements.objectClass, _closedWorld);
 
   @override
-  TypeMask get nonNullType => _nonNullType ??= TypeMask.nonNullSubclass(
+  late final TypeMask nonNullType = TypeMask.nonNullSubclass(
       _closedWorld.commonElements.objectClass, _closedWorld);
 
   @override
-  TypeMask get intType => _intType ??=
+  late final TypeMask intType =
       TypeMask.nonNullSubclass(commonElements.jsIntClass, _closedWorld);
 
   @override
-  TypeMask get uint32Type => _uint32Type ??=
+  late final TypeMask uint32Type =
       TypeMask.nonNullSubclass(commonElements.jsUInt32Class, _closedWorld);
 
   @override
-  TypeMask get uint31Type => _uint31Type ??=
+  late final TypeMask uint31Type =
       TypeMask.nonNullExact(commonElements.jsUInt31Class, _closedWorld);
 
   @override
-  TypeMask get positiveIntType => _positiveIntType ??=
+  late final TypeMask positiveIntType =
       TypeMask.nonNullSubclass(commonElements.jsPositiveIntClass, _closedWorld);
 
   @override
-  TypeMask get numNotIntType => _numNotIntType ??=
+  late final TypeMask numNotIntType =
       TypeMask.nonNullExact(commonElements.jsNumNotIntClass, _closedWorld);
 
   @override
-  TypeMask get numType => _numType ??=
+  late final TypeMask numType =
       TypeMask.nonNullSubclass(commonElements.jsNumberClass, _closedWorld);
 
   @override
-  TypeMask get boolType => _boolType ??=
+  late final TypeMask boolType =
       TypeMask.nonNullExact(commonElements.jsBoolClass, _closedWorld);
 
   @override
-  TypeMask get functionType => _functionType ??=
+  late final TypeMask functionType =
       TypeMask.nonNullSubtype(commonElements.functionClass, _closedWorld);
 
   @override
-  TypeMask get listType => _listType ??=
+  late final TypeMask listType =
       TypeMask.nonNullSubtype(commonElements.jsArrayClass, _closedWorld);
 
   @override
-  TypeMask get constListType => _constListType ??= TypeMask.nonNullExact(
+  late final TypeMask constListType = TypeMask.nonNullExact(
       commonElements.jsUnmodifiableArrayClass, _closedWorld);
 
   @override
-  TypeMask get fixedListType => _fixedListType ??=
+  late final TypeMask fixedListType =
       TypeMask.nonNullExact(commonElements.jsFixedArrayClass, _closedWorld);
 
   @override
-  TypeMask get growableListType => _growableListType ??= TypeMask.nonNullExact(
+  late final TypeMask growableListType = TypeMask.nonNullExact(
       commonElements.jsExtendableArrayClass, _closedWorld);
 
   @override
-  TypeMask get setType => _setType ??=
+  late final TypeMask setType =
       TypeMask.nonNullSubtype(commonElements.setLiteralClass, _closedWorld);
 
   @override
-  TypeMask get constSetType => _constSetType ??= TypeMask.nonNullSubtype(
+  late final TypeMask constSetType = TypeMask.nonNullSubtype(
       commonElements.constSetLiteralClass, _closedWorld);
 
   @override
-  TypeMask get mapType => _mapType ??=
+  late final TypeMask mapType =
       TypeMask.nonNullSubtype(commonElements.mapLiteralClass, _closedWorld);
 
   @override
-  TypeMask get constMapType => _constMapType ??= TypeMask.nonNullSubtype(
+  late final TypeMask constMapType = TypeMask.nonNullSubtype(
       commonElements.constMapLiteralClass, _closedWorld);
 
   @override
-  TypeMask get stringType => _stringType ??=
+  late final TypeMask stringType =
       TypeMask.nonNullExact(commonElements.jsStringClass, _closedWorld);
 
   @override
-  TypeMask get typeType => _typeType ??=
+  late final TypeMask typeType =
       TypeMask.nonNullExact(commonElements.typeLiteralClass, _closedWorld);
 
   @override
-  TypeMask get syncStarIterableType => _syncStarIterableType ??=
+  late final TypeMask syncStarIterableType =
       TypeMask.nonNullExact(commonElements.syncStarIterable, _closedWorld);
 
   @override
-  TypeMask get asyncFutureType => _asyncFutureType ??=
+  late final TypeMask asyncFutureType =
       TypeMask.nonNullExact(commonElements.futureImplementation, _closedWorld);
 
   @override
-  TypeMask get asyncStarStreamType => _asyncStarStreamType ??=
+  late final TypeMask asyncStarStreamType =
       TypeMask.nonNullExact(commonElements.controllerStream, _closedWorld);
 
   // TODO(johnniwinther): Assert that the null type has been resolved.
   @override
-  TypeMask get nullType => _nullType ??= TypeMask.empty();
+  late final TypeMask nullType = TypeMask.empty();
 
   @override
   TypeMask get lateSentinelType => TypeMask.nonNullEmpty(hasLateSentinel: true);
@@ -199,22 +167,20 @@
   @override
   TypeMask get emptyType => TypeMask.nonNullEmpty();
 
-  TypeMask get indexablePrimitiveType => _indexablePrimitiveType ??=
+  late final TypeMask indexablePrimitiveType =
       TypeMask.nonNullSubtype(commonElements.jsIndexableClass, _closedWorld);
 
-  TypeMask get readableArrayType => _readableArrayType ??=
+  late final TypeMask readableArrayType =
       TypeMask.nonNullSubclass(commonElements.jsArrayClass, _closedWorld);
 
   @override
-  TypeMask get mutableArrayType =>
-      _mutableArrayType ??= TypeMask.nonNullSubclass(
-          commonElements.jsMutableArrayClass, _closedWorld);
+  late final TypeMask mutableArrayType = TypeMask.nonNullSubclass(
+      commonElements.jsMutableArrayClass, _closedWorld);
 
-  TypeMask get unmodifiableArrayType =>
-      _unmodifiableArrayType ??= TypeMask.nonNullExact(
-          commonElements.jsUnmodifiableArrayClass, _closedWorld);
+  late final TypeMask unmodifiableArrayType = TypeMask.nonNullExact(
+      commonElements.jsUnmodifiableArrayClass, _closedWorld);
 
-  TypeMask get interceptorType => _interceptorType ??=
+  late final TypeMask interceptorType =
       TypeMask.nonNullSubclass(commonElements.jsInterceptorClass, _closedWorld);
 
   @override
@@ -223,11 +189,12 @@
     // class any user-defined class can implement. So we also check for the
     // interface `JavaScriptIndexingBehavior`.
     ClassEntity typedDataClass = _closedWorld.commonElements.typedDataClass;
-    return AbstractBool.trueOrMaybe(typedDataClass != null &&
+    return AbstractBool.trueOrMaybe(
         _closedWorld.classHierarchy.isInstantiated(typedDataClass) &&
-        mask.satisfies(typedDataClass, _closedWorld) &&
-        mask.satisfies(_closedWorld.commonElements.jsIndexingBehaviorInterface,
-            _closedWorld));
+            mask.satisfies(typedDataClass, _closedWorld) &&
+            mask.satisfies(
+                _closedWorld.commonElements.jsIndexingBehaviorInterface,
+                _closedWorld));
   }
 
   @override
@@ -237,14 +204,14 @@
     // TODO(herhut): Maybe cache the TypeMask for typedDataClass and
     //               jsIndexingBehaviourInterface.
     ClassEntity typedDataClass = _closedWorld.commonElements.typedDataClass;
-    return AbstractBool.maybeOrFalse(typedDataClass != null &&
+    return AbstractBool.maybeOrFalse(
         _closedWorld.classHierarchy.isInstantiated(typedDataClass) &&
-        intersects(mask, TypeMask.subtype(typedDataClass, _closedWorld)) &&
-        intersects(
-            mask,
-            TypeMask.subtype(
-                _closedWorld.commonElements.jsIndexingBehaviorInterface,
-                _closedWorld)));
+            intersects(mask, TypeMask.subtype(typedDataClass, _closedWorld)) &&
+            intersects(
+                mask,
+                TypeMask.subtype(
+                    _closedWorld.commonElements.jsIndexingBehaviorInterface,
+                    _closedWorld)));
   }
 
   @override
@@ -274,9 +241,8 @@
 
   @override
   AbstractValueWithPrecision createFromStaticType(DartType type,
-      {ClassRelation classRelation = ClassRelation.subtype, bool nullable}) {
-    assert(nullable != null);
-
+      {ClassRelation classRelation = ClassRelation.subtype,
+      required bool nullable}) {
     if ((classRelation == ClassRelation.subtype ||
             classRelation == ClassRelation.thisExpression) &&
         dartTypes.isTopType(type)) {
@@ -312,8 +278,6 @@
 
   AbstractValueWithPrecision _createFromStaticType(
       DartType type, ClassRelation classRelation, bool nullable) {
-    assert(nullable != null);
-
     AbstractValueWithPrecision finish(TypeMask value, bool isPrecise) {
       return AbstractValueWithPrecision(
           nullable ? value.nullable() : value, isPrecise);
@@ -441,7 +405,7 @@
   @override
   AbstractBool isInstanceOf(
       covariant TypeMask expressionMask, ClassEntity cls) {
-    AbstractValue typeMask = (cls == commonElements.nullClass)
+    final typeMask = (cls == commonElements.nullClass)
         ? nullType
         : createNonNullSubtype(cls);
     if (expressionMask.union(typeMask, this) == typeMask) {
@@ -462,18 +426,17 @@
       value.isExact && !value.isNullable && !value.hasLateSentinel);
 
   @override
-  ClassEntity getExactClass(TypeMask mask) {
+  ClassEntity? getExactClass(TypeMask mask) {
     return mask.singleClass(_closedWorld);
   }
 
   @override
-  bool isPrimitiveValue(TypeMask value) => value.isValue;
+  bool isPrimitiveValue(TypeMask value) => value is ValueTypeMask;
 
   @override
-  PrimitiveConstantValue getPrimitiveValue(TypeMask mask) {
-    if (mask.isValue) {
-      ValueTypeMask valueMask = mask;
-      return valueMask.value;
+  PrimitiveConstantValue? getPrimitiveValue(TypeMask mask) {
+    if (mask is ValueTypeMask) {
+      return mask.value;
     }
     return null;
   }
@@ -719,42 +682,35 @@
 
   @override
   AbstractValue getMapValueType(AbstractValue value) {
-    if (value is MapTypeMask) {
-      // TODO(johnniwinther): Assert the `value.valueType` is not null.
-      return value.valueType ?? dynamicType;
-    }
-    return dynamicType;
+    return value is MapTypeMask ? value.valueType : dynamicType;
   }
 
   @override
   AbstractValue getContainerElementType(AbstractValue value) {
-    if (value is ContainerTypeMask) {
-      return value.elementType ?? dynamicType;
-    }
-    return dynamicType;
+    return value is ContainerTypeMask ? value.elementType : dynamicType;
   }
 
   @override
-  int getContainerLength(AbstractValue value) {
+  int? getContainerLength(AbstractValue value) {
     return value is ContainerTypeMask ? value.length : null;
   }
 
   @override
   AbstractValue createContainerValue(
-      AbstractValue forwardTo,
-      Object allocationNode,
-      MemberEntity allocationElement,
-      AbstractValue elementType,
-      int length) {
+      covariant TypeMask forwardTo,
+      covariant ir.Node? allocationNode,
+      MemberEntity? allocationElement,
+      covariant TypeMask elementType,
+      int? length) {
     return ContainerTypeMask(
         forwardTo, allocationNode, allocationElement, elementType, length);
   }
 
   @override
   AbstractValue unionOfMany(Iterable<AbstractValue> values) {
-    TypeMask result = TypeMask.nonNullEmpty();
-    for (TypeMask value in values) {
-      result = result.union(value, this);
+    var result = TypeMask.nonNullEmpty();
+    for (final value in values) {
+      result = result.union(value as TypeMask, this);
     }
     return result;
   }
@@ -765,7 +721,7 @@
         .hasAnyStrictSubclass(_closedWorld.commonElements.objectClass));
     return TypeMask.unionOf(
         members.expand((MemberEntity element) {
-          ClassEntity cls = element.enclosingClass;
+          final cls = element.enclosingClass!;
           return [cls]..addAll(_closedWorld.mixinUsesOf(cls));
         }).map((cls) {
           if (_closedWorld.commonElements.jsNullClass == cls) {
@@ -800,7 +756,7 @@
   }
 
   @override
-  MemberEntity locateSingleMember(
+  MemberEntity? locateSingleMember(
       covariant TypeMask receiver, Selector selector) {
     return receiver.locateSingleMember(selector, this);
   }
@@ -822,7 +778,7 @@
 
   @override
   AbstractBool isFixedLengthJsIndexable(covariant TypeMask mask) {
-    if (mask.isContainer && (mask as ContainerTypeMask).length != null) {
+    if (mask is ContainerTypeMask && mask.length != null) {
       // A container on which we have inferred the length.
       return AbstractBool.True;
     }
@@ -862,24 +818,16 @@
   Map<TypeMask, AbstractBool> _isInterceptorCacheSecondChance = {};
 
   @override
-  bool isMap(TypeMask value) {
-    return value.isMap;
-  }
+  bool isMap(TypeMask value) => value is MapTypeMask;
 
   @override
-  bool isSet(TypeMask value) {
-    return value.isSet;
-  }
+  bool isSet(TypeMask value) => value is SetTypeMask;
 
   @override
-  bool isContainer(TypeMask value) {
-    return value.isContainer;
-  }
+  bool isContainer(TypeMask value) => value is ContainerTypeMask;
 
   @override
-  bool isDictionary(TypeMask value) {
-    return value.isDictionary;
-  }
+  bool isDictionary(TypeMask value) => value is DictionaryTypeMask;
 
   @override
   bool containsDictionaryKey(AbstractValue value, String key) {
@@ -888,42 +836,48 @@
 
   @override
   AbstractValue getDictionaryValueForKey(AbstractValue value, String key) {
-    if (value is DictionaryTypeMask) return value.getValueForKey(key);
-    return dynamicType;
+    final result =
+        value is DictionaryTypeMask ? value.getValueForKey(key) : null;
+    return result ?? dynamicType;
   }
 
   @override
-  AbstractValue createMapValue(AbstractValue forwardTo, Object allocationNode,
-      MemberEntity allocationElement, AbstractValue key, AbstractValue value) {
+  AbstractValue createMapValue(
+      covariant TypeMask forwardTo,
+      covariant ir.Node? allocationNode,
+      MemberEntity? allocationElement,
+      covariant TypeMask key,
+      covariant TypeMask value) {
     return MapTypeMask(
         forwardTo, allocationNode, allocationElement, key, value);
   }
 
   @override
   AbstractValue createDictionaryValue(
-      AbstractValue forwardTo,
-      Object allocationNode,
-      MemberEntity allocationElement,
-      AbstractValue key,
-      AbstractValue value,
+      covariant TypeMask forwardTo,
+      covariant ir.Node? allocationNode,
+      MemberEntity? allocationElement,
+      covariant TypeMask key,
+      covariant TypeMask value,
       Map<String, AbstractValue> mappings) {
     return DictionaryTypeMask(forwardTo, allocationNode, allocationElement, key,
         value, Map.from(mappings));
   }
 
   @override
-  AbstractValue createSetValue(AbstractValue forwardTo, Object allocationNode,
-      MemberEntity allocationElement, AbstractValue elementType) {
+  AbstractValue createSetValue(
+      covariant TypeMask forwardTo,
+      covariant ir.Node? allocationNode,
+      MemberEntity? allocationElement,
+      covariant TypeMask elementType) {
     return SetTypeMask(
         forwardTo, allocationNode, allocationElement, elementType);
   }
 
   @override
   AbstractValue getSetElementType(AbstractValue value) {
-    if (value is SetTypeMask) {
-      return value.elementType ?? dynamicType;
-    }
-    return dynamicType;
+    final result = value is SetTypeMask ? value.elementType : null;
+    return result ?? dynamicType;
   }
 
   @override
@@ -934,31 +888,22 @@
   }
 
   @override
-  Object getAllocationNode(AbstractValue value) {
-    if (value is AllocationTypeMask) {
-      return value.allocationNode;
-    }
-    return null;
+  Object? getAllocationNode(AbstractValue value) {
+    return value is AllocationTypeMask ? value.allocationNode : null;
   }
 
   @override
-  MemberEntity getAllocationElement(AbstractValue value) {
-    if (value is AllocationTypeMask) {
-      return value.allocationElement;
-    }
-    return null;
+  MemberEntity? getAllocationElement(AbstractValue value) {
+    return value is AllocationTypeMask ? value.allocationElement : null;
   }
 
   @override
-  AbstractValue getGeneralization(AbstractValue value) {
-    if (value is AllocationTypeMask) {
-      return value.forwardTo;
-    }
-    return null;
+  AbstractValue? getGeneralization(AbstractValue? value) {
+    return value is AllocationTypeMask ? value.forwardTo : null;
   }
 
   @override
-  AbstractValue getAbstractValueForNativeMethodParameterType(DartType type) {
+  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) {
     if (type is InterfaceType) {
       if (type.typeArguments.isNotEmpty) return null;
       // TODO(sra): Consider using a strengthened type check to avoid passing
@@ -972,7 +917,7 @@
   }
 
   @override
-  String getCompactText(AbstractValue value) {
+  String getCompactText(covariant TypeMask value) {
     return formatType(dartTypes, value);
   }
 
@@ -1015,7 +960,7 @@
             ? '+'
             : '*';
     String sentinelFlag = type.hasLateSentinel ? '\$' : '';
-    return '${type.base.name}$nullFlag$subFlag$sentinelFlag';
+    return '${type.base!.name}$nullFlag$subFlag$sentinelFlag';
   }
   if (type is UnionTypeMask) {
     return type.disjointMasks.map((m) => formatType(dartTypes, m)).join(' | ');
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/set_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/set_type_mask.dart
index 2e83741..905d817 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/set_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/set_type_mask.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 part of masks;
 
 /// A [SetTypeMask] is a [TypeMask] for a specific allocation site of a set
@@ -17,12 +15,12 @@
   @override
   final TypeMask forwardTo;
 
-  final ir.Node /*?*/ _allocationNode;
+  final ir.Node? _allocationNode;
   @override
-  ir.Node get allocationNode => _allocationNode /*!*/;
+  ir.Node? get allocationNode => _allocationNode;
 
   @override
-  final MemberEntity allocationElement;
+  final MemberEntity? allocationElement;
 
   // The element type of this set.
   final TypeMask elementType;
@@ -34,9 +32,9 @@
   factory SetTypeMask.readFromDataSource(
       DataSourceReader source, CommonMasks domain) {
     source.begin(tag);
-    TypeMask forwardTo = TypeMask.readFromDataSource(source, domain);
-    MemberEntity allocationElement = source.readMemberOrNull();
-    TypeMask elementType = TypeMask.readFromDataSource(source, domain);
+    final forwardTo = TypeMask.readFromDataSource(source, domain);
+    final allocationElement = source.readMemberOrNull();
+    final elementType = TypeMask.readFromDataSource(source, domain);
     source.end(tag);
     return SetTypeMask(forwardTo, null, allocationElement, elementType);
   }
@@ -53,7 +51,7 @@
   }
 
   @override
-  SetTypeMask withFlags({bool isNullable, bool hasLateSentinel}) {
+  SetTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
     isNullable ??= this.isNullable;
     hasLateSentinel ??= this.hasLateSentinel;
     if (isNullable == this.isNullable &&
@@ -69,19 +67,12 @@
   }
 
   @override
-  bool get isSet => true;
-
-  @override
   bool get isExact => true;
 
   @override
-  TypeMask _unionSpecialCases(TypeMask other, CommonMasks domain,
-      {bool isNullable, bool hasLateSentinel}) {
-    assert(isNullable != null);
-    assert(hasLateSentinel != null);
-    if (other is SetTypeMask &&
-        elementType != null &&
-        other.elementType != null) {
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+      {required bool isNullable, required bool hasLateSentinel}) {
+    if (other is SetTypeMask) {
       TypeMask newElementType = elementType.union(other.elementType, domain);
       TypeMask newForwardTo = forwardTo.union(other.forwardTo, domain);
       return SetTypeMask(newForwardTo, null, null, newElementType);
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart
index 816833c..0d14836 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 part of masks;
 
 /// An implementation of a [UniverseSelectorConstraints] that is consists if an
@@ -11,13 +9,13 @@
 /// be removed.
 class IncreasingTypeMaskSet extends UniverseSelectorConstraints {
   bool isAll = false;
-  Set<TypeMask> _masks;
+  Set<TypeMask>? _masks;
 
   @override
   bool canHit(MemberEntity element, Name name, JClosedWorld world) {
     if (isAll) return true;
     if (_masks == null) return false;
-    for (TypeMask mask in _masks) {
+    for (TypeMask mask in _masks!) {
       if (mask.canHit(element, name, world)) return true;
     }
     return false;
@@ -30,7 +28,7 @@
           TypeMask.subclass(world.commonElements.objectClass, world);
       return mask.needsNoSuchMethodHandling(selector, world);
     }
-    for (TypeMask mask in _masks) {
+    for (TypeMask mask in _masks!) {
       if (mask.needsNoSuchMethodHandling(selector, world)) {
         return true;
       }
@@ -39,15 +37,14 @@
   }
 
   @override
-  bool addReceiverConstraint(TypeMask mask) {
+  bool addReceiverConstraint(TypeMask? mask) {
     if (isAll) return false;
     if (mask == null) {
       isAll = true;
       _masks = null;
       return true;
     }
-    _masks ??= {};
-    return _masks.add(mask);
+    return (_masks ??= {}).add(mask);
   }
 
   @override
@@ -81,7 +78,7 @@
 
   @override
   UniverseSelectorConstraints createSelectorConstraints(
-      Selector selector, Object initialConstraint) {
+      Selector selector, covariant TypeMask? initialConstraint) {
     return IncreasingTypeMaskSet()..addReceiverConstraint(initialConstraint);
   }
 
@@ -89,7 +86,7 @@
   bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member,
       covariant JClosedWorld world) {
     Selector selector = dynamicUse.selector;
-    TypeMask mask = dynamicUse.receiverConstraint;
+    final mask = dynamicUse.receiverConstraint as TypeMask?;
     return selector.appliesUnnamed(member) &&
         (mask == null || mask.canHit(member, selector.memberName, world));
   }
@@ -120,7 +117,7 @@
     assert(
         closedWorld.classHierarchy.isInstantiated(base),
         failedAt(
-            base ?? CURRENT_ELEMENT_SPANNABLE,
+            base,
             "Cannot create exact type mask for uninstantiated "
             "class $base.\n${closedWorld.classHierarchy.dump(base)}"));
     return FlatTypeMask.exact(base, closedWorld,
@@ -141,10 +138,10 @@
     assert(
         closedWorld.classHierarchy.isInstantiated(base),
         failedAt(
-            base ?? CURRENT_ELEMENT_SPANNABLE,
+            base,
             "Cannot create subclass type mask for uninstantiated "
             "class $base.\n${closedWorld.classHierarchy.dump(base)}"));
-    ClassEntity topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
+    final topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
     if (topmost == null) {
       return TypeMask.empty(hasLateSentinel: hasLateSentinel);
     } else if (closedWorld.classHierarchy.hasAnyStrictSubclass(topmost)) {
@@ -158,7 +155,7 @@
 
   factory TypeMask.subtype(ClassEntity base, JClosedWorld closedWorld,
       {bool hasLateSentinel = false}) {
-    ClassEntity topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
+    final topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
     if (topmost == null) {
       return TypeMask.empty(hasLateSentinel: hasLateSentinel);
     }
@@ -183,7 +180,7 @@
     assert(
         closedWorld.classHierarchy.isInstantiated(base),
         failedAt(
-            base ?? CURRENT_ELEMENT_SPANNABLE,
+            base,
             "Cannot create exact type mask for uninstantiated "
             "class $base.\n${closedWorld.classHierarchy.dump(base)}"));
     return FlatTypeMask.nonNullExact(base, closedWorld,
@@ -205,10 +202,10 @@
     assert(
         closedWorld.classHierarchy.isInstantiated(base),
         failedAt(
-            base ?? CURRENT_ELEMENT_SPANNABLE,
+            base,
             "Cannot create subclass type mask for uninstantiated "
             "class $base.\n${closedWorld.classHierarchy.dump(base)}"));
-    ClassEntity topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
+    final topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
     if (topmost == null) {
       return TypeMask.nonNullEmpty(hasLateSentinel: hasLateSentinel);
     } else if (closedWorld.classHierarchy.hasAnyStrictSubclass(topmost)) {
@@ -222,7 +219,7 @@
 
   factory TypeMask.nonNullSubtype(ClassEntity base, JClosedWorld closedWorld,
       {bool hasLateSentinel = false}) {
-    ClassEntity topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
+    final topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
     if (topmost == null) {
       return TypeMask.nonNullEmpty(hasLateSentinel: hasLateSentinel);
     }
@@ -263,7 +260,6 @@
       case TypeMaskKind.value:
         return ValueTypeMask.readFromDataSource(source, domain);
     }
-    throw UnsupportedError("Unexpected TypeMaskKind $kind.");
   }
 
   /// Serializes this [TypeMask] to [sink].
@@ -271,8 +267,8 @@
 
   /// If [mask] is forwarding, returns the first non-forwarding [TypeMask] in
   /// [mask]'s forwarding chain.
-  static TypeMask nonForwardingMask(mask) {
-    while (mask.isForwarding) {
+  static TypeMask nonForwardingMask(TypeMask mask) {
+    while (mask is ForwardingTypeMask) {
       mask = mask.forwardTo;
     }
     return mask;
@@ -284,13 +280,13 @@
   /// subclasses exist. We also normalize exact to empty if the corresponding
   /// baseclass was never instantiated.
   static bool assertIsNormalized(TypeMask mask, JClosedWorld closedWorld) {
-    String reason = getNotNormalizedReason(mask, closedWorld);
+    final reason = getNotNormalizedReason(mask, closedWorld);
     assert(reason == null,
         failedAt(NO_LOCATION_SPANNABLE, '$mask is not normalized: $reason'));
     return true;
   }
 
-  static String getNotNormalizedReason(
+  static String? getNotNormalizedReason(
       TypeMask mask, JClosedWorld closedWorld) {
     mask = nonForwardingMask(mask);
     if (mask is FlatTypeMask) {
@@ -299,28 +295,28 @@
         return 'The class ${mask.base} is not canonicalized.';
       }
       if (mask.isExact) {
-        if (!closedWorld.classHierarchy.isInstantiated(mask.base)) {
+        if (!closedWorld.classHierarchy.isInstantiated(mask.base!)) {
           return 'Exact ${mask.base} is not instantiated.';
         }
         return null;
       }
       if (mask.isSubclass) {
-        if (!closedWorld.classHierarchy.hasAnyStrictSubclass(mask.base)) {
+        if (!closedWorld.classHierarchy.hasAnyStrictSubclass(mask.base!)) {
           return 'Subclass ${mask.base} does not have any subclasses.';
         }
         return null;
       }
       assert(mask.isSubtype);
-      if (!closedWorld.classHierarchy.hasAnyStrictSubtype(mask.base)) {
+      if (!closedWorld.classHierarchy.hasAnyStrictSubtype(mask.base!)) {
         return 'Subtype ${mask.base} does not have any subclasses.';
       }
-      if (closedWorld.classHierarchy.hasOnlySubclasses(mask.base)) {
+      if (closedWorld.classHierarchy.hasOnlySubclasses(mask.base!)) {
         return 'Subtype ${mask.base} only has subclasses.';
       }
       return null;
     } else if (mask is UnionTypeMask) {
       for (TypeMask submask in mask.disjointMasks) {
-        String submaskReason = getNotNormalizedReason(submask, closedWorld);
+        final submaskReason = getNotNormalizedReason(submask, closedWorld);
         if (submaskReason != null) {
           return 'Submask $submask in $mask: $submaskReason.';
         }
@@ -341,7 +337,7 @@
   TypeMask withoutFlags() =>
       withFlags(isNullable: false, hasLateSentinel: false);
 
-  TypeMask withFlags({bool isNullable, bool hasLateSentinel});
+  TypeMask withFlags({bool? isNullable, bool? hasLateSentinel});
 
   /// Whether nothing matches this mask, not even null.
   bool get isEmpty;
@@ -366,30 +362,6 @@
   /// it's subclasses or subtypes.
   bool get isExact;
 
-  /// Returns true if this mask is a union type.
-  bool get isUnion;
-
-  /// Returns `true` if this mask is a [ContainerTypeMask].
-  bool get isContainer;
-
-  /// Returns `true` if this mask is a [SetTypeMask].
-  bool get isSet;
-
-  /// Returns `true` if this mask is a [MapTypeMask].
-  bool get isMap;
-
-  /// Returns `true` if this mask is a [MapTypeMask] in dictionary mode, i.e.,
-  /// all keys are known string values and we have specific type information for
-  /// corresponding values.
-  bool get isDictionary;
-
-  /// Returns `true` if this mask is wrapping another mask for the purpose of
-  /// tracing.
-  bool get isForwarding;
-
-  /// Returns `true` if this mask holds encodes an exact value within a type.
-  bool get isValue;
-
   bool containsOnlyInt(JClosedWorld closedWorld);
   bool containsOnlyNum(JClosedWorld closedWorld);
   bool containsOnlyBool(JClosedWorld closedWorld);
@@ -426,7 +398,7 @@
 
   /// Returns the [ClassEntity] if this type represents a single class,
   /// otherwise returns `null`.  This method is conservative.
-  ClassEntity singleClass(JClosedWorld closedWorld);
+  ClassEntity? singleClass(JClosedWorld closedWorld);
 
   /// Returns a type mask representing the union of [this] and [other].
   TypeMask union(TypeMask other, CommonMasks domain);
@@ -450,5 +422,5 @@
 
   /// Returns the [element] that is known to always be hit at runtime
   /// on this mask. Returns null if there is none.
-  MemberEntity locateSingleMember(Selector selector, CommonMasks domain);
+  MemberEntity? locateSingleMember(Selector selector, CommonMasks domain);
 }
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/union_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/union_type_mask.dart
index a20afb8..d79436e 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/union_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/union_type_mask.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 part of masks;
 
 class UnionTypeMask extends TypeMask {
@@ -31,11 +29,9 @@
   AbstractBool get isLateSentinel => AbstractBool.maybeOrFalse(hasLateSentinel);
 
   UnionTypeMask._internal(this.disjointMasks,
-      {this.isNullable, this.hasLateSentinel})
-      : assert(isNullable != null),
-        assert(hasLateSentinel != null),
-        assert(disjointMasks.length > 1),
-        assert(disjointMasks.every((TypeMask mask) => !mask.isUnion)),
+      {required this.isNullable, required this.hasLateSentinel})
+      : assert(disjointMasks.length > 1),
+        assert(disjointMasks.every((TypeMask mask) => mask is! UnionTypeMask)),
         assert(disjointMasks.every((TypeMask mask) => !mask.isNullable)),
         assert(disjointMasks.every((TypeMask mask) => !mask.hasLateSentinel));
 
@@ -43,8 +39,8 @@
   factory UnionTypeMask.readFromDataSource(
       DataSourceReader source, CommonMasks domain) {
     source.begin(tag);
-    List<FlatTypeMask> disjointMasks =
-        source.readList(() => TypeMask.readFromDataSource(source, domain));
+    List<FlatTypeMask> disjointMasks = source.readList(
+        () => TypeMask.readFromDataSource(source, domain) as FlatTypeMask);
     bool isNullable = source.readBool();
     bool hasLateSentinel = source.readBool();
     source.end(tag);
@@ -94,13 +90,12 @@
     // are preferred to subtype masks.
     for (TypeMask mask in masks) {
       mask = TypeMask.nonForwardingMask(mask).withoutFlags();
-      if (mask.isUnion) {
-        UnionTypeMask union = mask;
-        unionOfHelper(union.disjointMasks, disjoint, domain);
+      if (mask is UnionTypeMask) {
+        unionOfHelper(mask.disjointMasks, disjoint, domain);
       } else if (mask.isEmpty) {
         continue;
       } else {
-        FlatTypeMask flatMask = mask;
+        var flatMask = mask as FlatTypeMask;
         int inListIndex = -1;
         bool covered = false;
 
@@ -108,10 +103,10 @@
         // already covers [mask].
         for (int i = 0; i < disjoint.length; i++) {
           FlatTypeMask current = disjoint[i];
-          if (current == null) continue;
           TypeMask newMask = flatMask.union(current, domain);
           // If we have found a disjoint union, continue iterating.
-          if (newMask.isUnion) continue;
+          if (newMask is UnionTypeMask) continue;
+          newMask as FlatTypeMask;
           covered = true;
           // We found a mask that is either equal to [mask] or is a
           // supertype of [mask].
@@ -142,10 +137,7 @@
   }
 
   static TypeMask flatten(List<FlatTypeMask> masks, CommonMasks domain,
-      {bool includeNull, bool includeLateSentinel}) {
-    assert(includeNull != null);
-    assert(includeLateSentinel != null);
-
+      {required bool includeNull, required bool includeLateSentinel}) {
     // TODO(johnniwinther): Move this computation to [ClosedWorld] and use the
     // class set structures.
     if (masks.isEmpty) throw ArgumentError.value(masks, 'masks');
@@ -153,14 +145,14 @@
     // subclass type mask to represent their union.
     bool useSubclass = masks.every((e) => !e.isSubtype);
 
-    List<ClassEntity> masksBases = masks.map((mask) => mask.base).toList();
+    final masksBases = masks.map((mask) => mask.base!).toList();
     Iterable<ClassEntity> candidates =
         domain._closedWorld.commonSupertypesOf(masksBases);
 
     // Compute the best candidate and its kind.
-    ClassEntity bestElement;
-    _FlatTypeMaskKind bestKind;
-    int bestSize;
+    ClassEntity? bestElement;
+    late _FlatTypeMaskKind bestKind;
+    late int bestSize;
     for (ClassEntity candidate in candidates) {
       bool isInstantiatedStrictSubclass(cls) =>
           cls != candidate &&
@@ -195,7 +187,7 @@
     }
     int flags = FlatTypeMask._computeFlags(bestKind,
         isNullable: includeNull, hasLateSentinel: includeLateSentinel);
-    return FlatTypeMask.normalized(bestElement, flags, domain);
+    return FlatTypeMask.normalized(bestElement!, flags, domain);
   }
 
   @override
@@ -223,7 +215,7 @@
     if (other is UnionTypeMask) {
       newList.addAll(other.disjointMasks);
     } else {
-      newList.add(other);
+      newList.add(other as FlatTypeMask);
     }
     TypeMask newMask = TypeMask.unionOf(newList, domain);
     return newMask.withFlags(
@@ -281,7 +273,7 @@
   }
 
   @override
-  UnionTypeMask withFlags({bool isNullable, bool hasLateSentinel}) {
+  UnionTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
     isNullable ??= this.isNullable;
     hasLateSentinel ??= this.hasLateSentinel;
     if (isNullable == this.isNullable &&
@@ -301,20 +293,6 @@
   bool get isNull => false;
   @override
   bool get isExact => false;
-  @override
-  bool get isUnion => true;
-  @override
-  bool get isContainer => false;
-  @override
-  bool get isSet => false;
-  @override
-  bool get isMap => false;
-  @override
-  bool get isDictionary => false;
-  @override
-  bool get isForwarding => false;
-  @override
-  bool get isValue => false;
 
   /// Checks whether [other] is contained in this union.
   ///
@@ -324,7 +302,7 @@
   ///   must have failed.
   bool _slowContainsCheck(TypeMask other, JClosedWorld closedWorld) {
     // Unions should never make it here.
-    assert(!other.isUnion);
+    assert(other is! UnionTypeMask);
     // Likewise, nullness should be covered.
     assert(isNullable || !other.isNullable);
     assert(hasLateSentinel || !other.hasLateSentinel);
@@ -339,16 +317,16 @@
     if (other.contains(closedWorld.commonElements.objectClass, closedWorld)) {
       return false;
     }
-    FlatTypeMask flat = TypeMask.nonForwardingMask(other);
+    final flat = TypeMask.nonForwardingMask(other) as FlatTypeMask;
     // Check we cover the base class.
-    if (!contains(flat.base, closedWorld)) return false;
+    if (!contains(flat.base!, closedWorld)) return false;
     // Check for other members.
     Iterable<ClassEntity> members;
     if (flat.isSubclass) {
-      members = closedWorld.classHierarchy.strictSubclassesOf(flat.base);
+      members = closedWorld.classHierarchy.strictSubclassesOf(flat.base!);
     } else {
       assert(flat.isSubtype);
-      members = closedWorld.classHierarchy.strictSubtypesOf(flat.base);
+      members = closedWorld.classHierarchy.strictSubtypesOf(flat.base!);
     }
     return members.every((ClassEntity cls) => this.contains(cls, closedWorld));
   }
@@ -358,8 +336,8 @@
     other = TypeMask.nonForwardingMask(other);
     if (isNullable && !other.isNullable) return false;
     if (hasLateSentinel && !other.hasLateSentinel) return false;
-    if (other.isUnion) {
-      UnionTypeMask union = other;
+    if (other is UnionTypeMask) {
+      final union = other;
       return disjointMasks.every((FlatTypeMask disjointMask) {
         bool contained = union.disjointMasks.any((FlatTypeMask other) =>
             other.containsMask(disjointMask, closedWorld));
@@ -379,7 +357,7 @@
     other = TypeMask.nonForwardingMask(other);
     if (other.isNullable && !isNullable) return false;
     if (other.hasLateSentinel && !hasLateSentinel) return false;
-    if (other.isUnion) return other.isInMask(this, closedWorld);
+    if (other is UnionTypeMask) return other.isInMask(this, closedWorld);
     other = other.withoutFlags();
     bool contained =
         disjointMasks.any((mask) => mask.containsMask(other, closedWorld));
@@ -434,7 +412,7 @@
   }
 
   @override
-  ClassEntity singleClass(JClosedWorld closedWorld) => null;
+  ClassEntity? singleClass(JClosedWorld closedWorld) => null;
 
   @override
   bool needsNoSuchMethodHandling(Selector selector, JClosedWorld closedWorld) {
@@ -454,12 +432,12 @@
   }
 
   @override
-  MemberEntity locateSingleMember(Selector selector, CommonMasks domain) {
-    MemberEntity candidate;
+  MemberEntity? locateSingleMember(Selector selector, CommonMasks domain) {
+    MemberEntity? candidate;
     for (FlatTypeMask mask in disjointMasks) {
       mask = mask.withFlags(
           isNullable: isNullable, hasLateSentinel: hasLateSentinel);
-      MemberEntity current = mask.locateSingleMember(selector, domain);
+      final current = mask.locateSingleMember(selector, domain);
       if (current == null) {
         return null;
       } else if (candidate == null) {
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/value_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/value_type_mask.dart
index 68c8c69..b788e7e 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/value_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/value_type_mask.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 part of masks;
 
 class ValueTypeMask extends ForwardingTypeMask {
@@ -22,7 +20,7 @@
       DataSourceReader source, CommonMasks domain) {
     source.begin(tag);
     TypeMask forwardTo = TypeMask.readFromDataSource(source, domain);
-    ConstantValue constant = source.readConstant();
+    final constant = source.readConstant() as PrimitiveConstantValue;
     source.end(tag);
     return ValueTypeMask(forwardTo, constant);
   }
@@ -38,7 +36,7 @@
   }
 
   @override
-  ValueTypeMask withFlags({bool isNullable, bool hasLateSentinel}) {
+  ValueTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
     isNullable ??= this.isNullable;
     hasLateSentinel ??= this.hasLateSentinel;
     if (isNullable == this.isNullable &&
@@ -52,13 +50,8 @@
   }
 
   @override
-  bool get isValue => true;
-
-  @override
-  TypeMask _unionSpecialCases(TypeMask other, CommonMasks domain,
-      {bool isNullable, bool hasLateSentinel}) {
-    assert(isNullable != null);
-    assert(hasLateSentinel != null);
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+      {required bool isNullable, required bool hasLateSentinel}) {
     if (other is ValueTypeMask &&
         forwardTo.withoutFlags() == other.forwardTo.withoutFlags() &&
         value == other.value) {
diff --git a/pkg/compiler/lib/src/inferrer/wrapped.dart b/pkg/compiler/lib/src/inferrer/wrapped.dart
index 21717cb..455c84f 100644
--- a/pkg/compiler/lib/src/inferrer/wrapped.dart
+++ b/pkg/compiler/lib/src/inferrer/wrapped.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
 import '../elements/entities.dart';
 import '../elements/names.dart';
@@ -13,7 +11,7 @@
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
 import '../universe/use.dart';
-import '../world.dart';
+import '../world_interfaces.dart';
 import 'abstract_value_domain.dart';
 import 'abstract_value_strategy.dart';
 
@@ -25,9 +23,7 @@
   bool operator ==(var other) {
     if (identical(this, other)) return true;
     if (other is! WrappedAbstractValue) return false;
-    WrappedAbstractValue otherWrapped = other;
-    return other is WrappedAbstractValue &&
-        _abstractValue == otherWrapped._abstractValue;
+    return _abstractValue == other._abstractValue;
   }
 
   @override
@@ -39,11 +35,11 @@
   String toString() => _abstractValue.toString();
 }
 
-AbstractValue unwrapOrNull(WrappedAbstractValue wrapped) {
+AbstractValue? unwrapOrNull(WrappedAbstractValue? wrapped) {
   return wrapped?._abstractValue;
 }
 
-WrappedAbstractValue wrapOrNull(AbstractValue abstractValue) {
+WrappedAbstractValue? wrapOrNull(AbstractValue? abstractValue) {
   return abstractValue == null ? null : WrappedAbstractValue(abstractValue);
 }
 
@@ -88,7 +84,7 @@
       _abstractValueDomain.isJsIndexable(value._abstractValue);
 
   @override
-  MemberEntity locateSingleMember(
+  MemberEntity? locateSingleMember(
           covariant WrappedAbstractValue receiver, Selector selector) =>
       _abstractValueDomain.locateSingleMember(
           receiver._abstractValue, selector);
@@ -115,7 +111,7 @@
       WrappedAbstractValue(_abstractValueDomain.computeReceiver(members));
 
   @override
-  PrimitiveConstantValue getPrimitiveValue(
+  PrimitiveConstantValue? getPrimitiveValue(
           covariant WrappedAbstractValue value) =>
       _abstractValueDomain.getPrimitiveValue(value._abstractValue);
 
@@ -131,17 +127,17 @@
       _abstractValueDomain.isPrimitiveValue(value._abstractValue);
 
   @override
-  MemberEntity getAllocationElement(covariant WrappedAbstractValue value) =>
+  MemberEntity? getAllocationElement(covariant WrappedAbstractValue value) =>
       _abstractValueDomain.getAllocationElement(value._abstractValue);
 
   @override
-  Object getAllocationNode(covariant WrappedAbstractValue value) =>
+  Object? getAllocationNode(covariant WrappedAbstractValue value) =>
       _abstractValueDomain.getAllocationNode(value._abstractValue);
 
   @override
   AbstractValue getGeneralization(covariant WrappedAbstractValue value) =>
       WrappedAbstractValue(
-          _abstractValueDomain.getGeneralization(unwrapOrNull(value)));
+          _abstractValueDomain.getGeneralization(unwrapOrNull(value))!);
 
   @override
   bool isSpecializationOf(covariant WrappedAbstractValue specialization,
@@ -162,14 +158,14 @@
 
   @override
   AbstractValue createDictionaryValue(
-      covariant WrappedAbstractValue originalValue,
-      Object allocationNode,
-      MemberEntity allocationElement,
+      covariant WrappedAbstractValue? originalValue,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
       covariant WrappedAbstractValue key,
       covariant WrappedAbstractValue value,
       covariant Map<String, AbstractValue> mappings) {
     return WrappedAbstractValue(_abstractValueDomain.createDictionaryValue(
-        originalValue._abstractValue,
+        originalValue?._abstractValue,
         allocationNode,
         allocationElement,
         key._abstractValue,
@@ -195,13 +191,13 @@
 
   @override
   AbstractValue createMapValue(
-          covariant WrappedAbstractValue originalValue,
-          Object allocationNode,
-          MemberEntity allocationElement,
+          covariant WrappedAbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
           covariant WrappedAbstractValue key,
           covariant WrappedAbstractValue value) =>
       WrappedAbstractValue(_abstractValueDomain.createMapValue(
-          originalValue._abstractValue,
+          originalValue?._abstractValue,
           allocationNode,
           allocationElement,
           key._abstractValue,
@@ -218,12 +214,12 @@
 
   @override
   AbstractValue createSetValue(
-          covariant WrappedAbstractValue originalValue,
-          Object allocationNode,
-          MemberEntity allocationElement,
+          covariant WrappedAbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
           covariant WrappedAbstractValue elementType) =>
       WrappedAbstractValue(_abstractValueDomain.createSetValue(
-          originalValue._abstractValue,
+          originalValue?._abstractValue,
           allocationNode,
           allocationElement,
           elementType._abstractValue));
@@ -233,7 +229,7 @@
       _abstractValueDomain.isSet(value._abstractValue);
 
   @override
-  int getContainerLength(covariant WrappedAbstractValue value) =>
+  int? getContainerLength(covariant WrappedAbstractValue value) =>
       _abstractValueDomain.getContainerLength(value._abstractValue);
 
   @override
@@ -243,13 +239,13 @@
 
   @override
   AbstractValue createContainerValue(
-          covariant WrappedAbstractValue originalValue,
-          Object allocationNode,
-          MemberEntity allocationElement,
+          covariant WrappedAbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
           covariant WrappedAbstractValue elementType,
-          int length) =>
+          int? length) =>
       WrappedAbstractValue(_abstractValueDomain.createContainerValue(
-          originalValue._abstractValue,
+          originalValue?._abstractValue,
           allocationNode,
           allocationElement,
           elementType._abstractValue,
@@ -266,7 +262,7 @@
           _abstractValueDomain.computeAbstractValueForConstant(value));
 
   @override
-  AbstractValue getAbstractValueForNativeMethodParameterType(DartType type) {
+  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) {
     return wrapOrNull(_abstractValueDomain
         .getAbstractValueForNativeMethodParameterType(type));
   }
@@ -410,7 +406,7 @@
       _abstractValueDomain.isLateSentinel(value._abstractValue);
 
   @override
-  ClassEntity getExactClass(covariant WrappedAbstractValue value) =>
+  ClassEntity? getExactClass(covariant WrappedAbstractValue value) =>
       _abstractValueDomain.getExactClass(value._abstractValue);
 
   @override
@@ -491,7 +487,8 @@
 
   @override
   AbstractValueWithPrecision createFromStaticType(DartType type,
-      {ClassRelation classRelation = ClassRelation.subtype, bool nullable}) {
+      {ClassRelation classRelation = ClassRelation.subtype,
+      required bool nullable}) {
     var unwrapped = _abstractValueDomain.createFromStaticType(type,
         classRelation: classRelation, nullable: nullable);
     return AbstractValueWithPrecision(
@@ -626,7 +623,7 @@
 
   @override
   UniverseSelectorConstraints createSelectorConstraints(
-      Selector selector, Object initialConstraint) {
+      Selector selector, Object? initialConstraint) {
     return WrappedUniverseSelectorConstraints(
         _selectorConstraintsStrategy.createSelectorConstraints(
             selector,
@@ -639,8 +636,8 @@
   bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member,
       covariant JClosedWorld world) {
     return _selectorConstraintsStrategy.appliedUnnamed(
-        dynamicUse.withReceiverConstraint(
-            unwrapOrNull(dynamicUse.receiverConstraint)),
+        dynamicUse.withReceiverConstraint(unwrapOrNull(
+            dynamicUse.receiverConstraint as WrappedAbstractValue?)),
         member,
         world);
   }
@@ -652,7 +649,7 @@
   const WrappedUniverseSelectorConstraints(this._universeSelectorConstraints);
 
   @override
-  bool addReceiverConstraint(Object constraint) =>
+  bool addReceiverConstraint(Object? constraint) =>
       _universeSelectorConstraints.addReceiverConstraint(constraint == null
           ? null
           : (constraint as WrappedAbstractValue)._abstractValue);
diff --git a/pkg/compiler/lib/src/inferrer_experimental/builder.dart b/pkg/compiler/lib/src/inferrer_experimental/builder.dart
new file mode 100644
index 0000000..059a3bc
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/builder.dart
@@ -0,0 +1,2581 @@
+// Copyright (c) 2017, 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.10
+
+import 'package:kernel/ast.dart' as ir;
+
+import '../closure.dart';
+import '../common.dart';
+import '../common/names.dart';
+import '../constants/constant_system.dart' as constant_system;
+import '../constants/values.dart';
+import '../elements/entities.dart';
+import '../elements/jumps.dart';
+import '../elements/types.dart';
+import '../inferrer/abstract_value_domain.dart';
+import '../inferrer_experimental/types.dart';
+import '../ir/constants.dart';
+import '../ir/static_type_provider.dart';
+import '../ir/util.dart';
+import '../js_backend/field_analysis.dart';
+import '../js_model/element_map.dart';
+import '../js_model/locals.dart' show JumpVisitor;
+import '../js_model/js_world.dart';
+import '../native/behavior.dart';
+import '../options.dart';
+import '../universe/selector.dart';
+import '../universe/side_effects.dart';
+import '../util/util.dart';
+import 'engine.dart';
+import 'locals_handler.dart';
+import 'type_graph_nodes.dart';
+import 'type_system.dart';
+
+/// [KernelTypeGraphBuilder] constructs a type-inference graph for a particular
+/// element.
+///
+/// Calling [run] will start the work of visiting the body of the code to
+/// construct a set of inference-nodes that abstractly represent what the code
+/// is doing.
+class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation>
+    with ir.VisitorNullMixin<TypeInformation> {
+  final CompilerOptions _options;
+  final JsClosedWorld _closedWorld;
+  final InferrerEngine _inferrer;
+  final TypeSystem _types;
+  final MemberEntity _analyzedMember;
+  final ir.Node _analyzedNode;
+  final KernelToLocalsMap _localsMap;
+  final GlobalTypeInferenceElementData _memberData;
+  final bool _inGenerativeConstructor;
+
+  DartTypes get _dartTypes => _closedWorld.dartTypes;
+
+  LocalState _stateInternal;
+  LocalState _stateAfterWhenTrueInternal;
+  LocalState _stateAfterWhenFalseInternal;
+
+  /// Returns the current local state for when the boolean value of the most
+  /// recently visited node is not taken into account
+  LocalState get _state {
+    return _stateInternal;
+  }
+
+  /// Sets the current local state for when the boolean value of the most
+  /// recently visited node is not taken into account
+  ///
+  /// This used for when the most recently visited node is not a boolean
+  /// expression and there for also resets [_stateAfterWhenTrue] and
+  /// [_stateAfterWhenFalse] to the same value.
+  void set _state(LocalState value) {
+    _stateInternal = value;
+    _stateAfterWhenTrueInternal = _stateAfterWhenFalseInternal = null;
+  }
+
+  /// Returns the current local state for when the most recently visited node
+  /// has evaluated to `true`.
+  ///
+  /// If the most recently visited node is not a boolean expression then this is
+  /// the same as [_state].
+  LocalState get _stateAfterWhenTrue =>
+      _stateAfterWhenTrueInternal ?? _stateInternal;
+
+  /// Returns the current local state for when the most recently visited node
+  /// has evaluated to `false`.
+  ///
+  /// If the most recently visited node is not a boolean expression then this is
+  /// the same as [_state].
+  LocalState get _stateAfterWhenFalse =>
+      _stateAfterWhenFalseInternal ?? _stateInternal;
+
+  /// Sets the current local state. [base] is the local state for when the
+  /// boolean value of the most recently visited node is not taken into account.
+  /// [whenTrue] and [whenFalse] are the local state for when the boolean value
+  /// of the most recently visited node is `true` or `false`, respectively.
+  void _setStateAfter(
+      LocalState base, LocalState whenTrue, LocalState whenFalse) {
+    _stateInternal = base;
+    _stateAfterWhenTrueInternal = whenTrue;
+    _stateAfterWhenFalseInternal = whenFalse;
+  }
+
+  /// Removes from the current [_state] any data from the boolean value of the
+  /// most recently visited node.
+  void _clearConditionalStateAfter() {
+    _stateAfterWhenTrueInternal = _stateAfterWhenFalseInternal = null;
+  }
+
+  final SideEffectsBuilder _sideEffectsBuilder;
+  final Map<JumpTarget, List<LocalState>> _breaksFor =
+      <JumpTarget, List<LocalState>>{};
+  final Map<JumpTarget, List<LocalState>> _continuesFor =
+      <JumpTarget, List<LocalState>>{};
+  TypeInformation _returnType;
+  final Set<Local> _capturedVariables = Set<Local>();
+  final Map<Local, FieldEntity> _capturedAndBoxed;
+
+  final StaticTypeProvider _staticTypeProvider;
+
+  /// Whether we currently taken the boolean result of is-checks or null-checks
+  /// into account in the local state.
+  bool _accumulateIsChecks = false;
+
+  KernelTypeGraphBuilder(
+      this._options,
+      this._closedWorld,
+      this._inferrer,
+      this._analyzedMember,
+      this._analyzedNode,
+      this._localsMap,
+      this._staticTypeProvider,
+      [this._stateInternal,
+      Map<Local, FieldEntity> capturedAndBoxed])
+      : this._types = _inferrer.types,
+        this._memberData = _inferrer.dataOfMember(_analyzedMember),
+        // TODO(johnniwinther): Should side effects also be tracked for field
+        // initializers?
+        this._sideEffectsBuilder = _analyzedMember is FunctionEntity
+            ? _inferrer.inferredDataBuilder
+                .getSideEffectsBuilder(_analyzedMember)
+            : SideEffectsBuilder.free(_analyzedMember),
+        this._inGenerativeConstructor = _analyzedNode is ir.Constructor,
+        this._capturedAndBoxed = capturedAndBoxed != null
+            ? Map<Local, FieldEntity>.from(capturedAndBoxed)
+            : <Local, FieldEntity>{} {
+    if (_state != null) return;
+
+    _state =
+        LocalState.initial(inGenerativeConstructor: _inGenerativeConstructor);
+  }
+
+  JsToElementMap get _elementMap => _closedWorld.elementMap;
+
+  ClosureData get _closureDataLookup => _closedWorld.closureDataLookup;
+
+  DartType _getStaticType(ir.Expression node) {
+    return _elementMap.getDartType(_staticTypeProvider.getStaticType(node));
+  }
+
+  int _loopLevel = 0;
+
+  bool get inLoop => _loopLevel > 0;
+
+  /// Returns `true` if [member] is defined in a subclass of the current this
+  /// type.
+  bool _isInClassOrSubclass(MemberEntity member) {
+    ClassEntity cls = _elementMap.getMemberThisType(_analyzedMember)?.element;
+    if (cls == null) return false;
+    return _closedWorld.classHierarchy.isSubclassOf(member.enclosingClass, cls);
+  }
+
+  /// Checks whether the access or update of [selector] on [mask] potentially
+  /// exposes `this`.
+  ///
+  /// If all matching members are instance fields on the current `this`
+  /// class or subclasses, `this` is not considered to be exposed.
+  ///
+  /// If an instance field matched with a [selector] that is _not_ a setter, the
+  /// field is considered to have been read before initialization and the field
+  /// is assumed to be potentially `null`.
+  void _checkIfExposesThis(Selector selector, AbstractValue mask) {
+    if (_state.isThisExposed) {
+      // We already consider `this` to have been exposed.
+      return;
+    }
+    if (_inferrer.closedWorld.includesClosureCall(selector, mask)) {
+      // TODO(ngeoffray): We could do better here if we knew what we
+      // are calling does not expose this.
+      _state.markThisAsExposed();
+    } else {
+      _inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
+        if (element != null && element.isField) {
+          FieldEntity field = element;
+          if (!selector.isSetter &&
+              _isInClassOrSubclass(field) &&
+              field.isAssignable &&
+              _state.readField(field) == null &&
+              getFieldInitializer(_elementMap, field) == null) {
+            // If the field is being used before this constructor
+            // actually had a chance to initialize it, say it can be
+            // null.
+            _inferrer.recordTypeOfField(field, _types.nullType);
+          }
+          // Accessing a field does not expose `this`.
+          return true;
+        }
+        // TODO(ngeoffray): We could do better here if we knew what we
+        // are calling does not expose this.
+        _state.markThisAsExposed();
+        return false;
+      });
+    }
+  }
+
+  TypeInformation run() {
+    if (_analyzedMember.isField) {
+      if (_analyzedNode == null || isNullLiteral(_analyzedNode)) {
+        // Eagerly bailout, because computing the closure data only
+        // works for functions and field assignments.
+        return _types.nullType;
+      }
+    }
+
+    // Update the locals that are boxed in [locals]. These locals will
+    // be handled specially, in that we are computing their LUB at
+    // each update, and reading them yields the type that was found in a
+    // previous analysis of [outermostElement].
+    ScopeInfo scopeInfo = _closureDataLookup.getScopeInfo(_analyzedMember);
+    scopeInfo.forEachBoxedVariable(_localsMap, (variable, field) {
+      _capturedAndBoxed[variable] = field;
+    });
+
+    return visit(_analyzedNode);
+  }
+
+  bool isIncompatibleInvoke(FunctionEntity function, ArgumentsTypes arguments) {
+    ParameterStructure parameterStructure = function.parameterStructure;
+
+    return arguments.positional.length <
+            parameterStructure.requiredPositionalParameters ||
+        arguments.positional.length > parameterStructure.positionalParameters ||
+        arguments.named.keys
+            .any((name) => !parameterStructure.namedParameters.contains(name));
+  }
+
+  void recordReturnType(TypeInformation type) {
+    FunctionEntity analyzedMethod = _analyzedMember;
+    _returnType =
+        _inferrer.addReturnTypeForMethod(analyzedMethod, _returnType, type);
+  }
+
+  TypeInformation _thisType;
+  TypeInformation get thisType {
+    if (_thisType != null) return _thisType;
+    ClassEntity cls = _elementMap.getMemberThisType(_analyzedMember)?.element;
+    if (_closedWorld.isUsedAsMixin(cls)) {
+      return _thisType = _types.nonNullSubtype(cls);
+    } else {
+      return _thisType = _types.nonNullSubclass(cls);
+    }
+  }
+
+  TypeInformation visit(ir.Node node, {bool conditionContext = false}) {
+    var oldAccumulateIsChecks = _accumulateIsChecks;
+    _accumulateIsChecks = conditionContext;
+    var result = node?.accept(this);
+
+    // Clear the conditional state to ensure we don't accidentally carry over
+    // conclusions from a nested condition into an outer condition. For example:
+    //
+    //   if (methodCall(x is T && true)) { /* don't assume x is T here. */ }
+    if (!conditionContext) _clearConditionalStateAfter();
+    _accumulateIsChecks = oldAccumulateIsChecks;
+    return result;
+  }
+
+  void handleParameter(ir.VariableDeclaration node, {bool isOptional}) {
+    Local local = _localsMap.getLocalVariable(node);
+    DartType type = _localsMap.getLocalType(_elementMap, local);
+    _state.updateLocal(_inferrer, _capturedAndBoxed, local,
+        _inferrer.typeOfParameter(local), type);
+    if (isOptional) {
+      TypeInformation type;
+      if (node.initializer != null) {
+        type = visit(node.initializer);
+      } else {
+        type = _types.nullType;
+      }
+      _inferrer.setDefaultTypeOfParameter(local, type);
+    }
+  }
+
+  @override
+  TypeInformation visitConstructor(ir.Constructor node) {
+    handleParameters(node.function);
+    node.initializers.forEach(visit);
+    visit(node.function.body);
+
+    ClassEntity cls = _analyzedMember.enclosingClass;
+    if (!(node.initializers.isNotEmpty &&
+        node.initializers.first is ir.RedirectingInitializer)) {
+      // Iterate over all instance fields, and give a null type to
+      // fields that we haven't initialized for sure.
+      _elementMap.elementEnvironment.forEachLocalClassMember(cls,
+          (MemberEntity member) {
+        if (member.isField && member.isInstanceMember && member.isAssignable) {
+          TypeInformation type = _state.readField(member);
+          MemberDefinition definition = _elementMap.getMemberDefinition(member);
+          assert(definition.kind == MemberKind.regular);
+          ir.Field node = definition.node;
+          if (type == null &&
+              (node.initializer == null || isNullLiteral(node.initializer))) {
+            _inferrer.recordTypeOfField(member, _types.nullType);
+          }
+        }
+      });
+    }
+    _inferrer.recordExposesThis(_analyzedMember, _state.isThisExposed);
+
+    if (cls.isAbstract) {
+      if (_closedWorld.classHierarchy.isInstantiated(cls)) {
+        _returnType = _types.nonNullSubclass(cls);
+      } else {
+        // TODO(johnniwinther): Avoid analyzing [_analyzedMember] in this
+        // case; it's never called.
+        _returnType = _types.nonNullEmpty();
+      }
+    } else {
+      _returnType = _types.nonNullExact(cls);
+    }
+    assert(_breaksFor.isEmpty);
+    assert(_continuesFor.isEmpty);
+    return _returnType;
+  }
+
+  @override
+  visitFieldInitializer(ir.FieldInitializer node) {
+    TypeInformation rhsType = visit(node.value);
+    FieldEntity field = _elementMap.getField(node.field);
+    _state.updateField(field, rhsType);
+    _inferrer.recordTypeOfField(field, rhsType);
+    return null;
+  }
+
+  @override
+  visitSuperInitializer(ir.SuperInitializer node) {
+    ConstructorEntity constructor = _elementMap.getConstructor(node.target);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    Selector selector = Selector(SelectorKind.CALL, constructor.memberName,
+        _elementMap.getCallStructure(node.arguments));
+    handleConstructorInvoke(
+        node, node.arguments, selector, constructor, arguments);
+
+    _inferrer.analyze(constructor);
+    if (_inferrer.checkIfExposesThis(constructor)) {
+      _state.markThisAsExposed();
+    }
+    return null;
+  }
+
+  @override
+  visitRedirectingInitializer(ir.RedirectingInitializer node) {
+    ConstructorEntity constructor = _elementMap.getConstructor(node.target);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    Selector selector = Selector(SelectorKind.CALL, constructor.memberName,
+        _elementMap.getCallStructure(node.arguments));
+    handleConstructorInvoke(
+        node, node.arguments, selector, constructor, arguments);
+
+    _inferrer.analyze(constructor);
+    if (_inferrer.checkIfExposesThis(constructor)) {
+      _state.markThisAsExposed();
+    }
+    return null;
+  }
+
+  @override
+  visitLocalInitializer(ir.LocalInitializer node) {
+    visit(node.variable);
+    return null;
+  }
+
+  void handleParameters(ir.FunctionNode node) {
+    int position = 0;
+    for (ir.VariableDeclaration parameter in node.positionalParameters) {
+      handleParameter(parameter,
+          isOptional: position >= node.requiredParameterCount);
+      position++;
+    }
+    for (ir.VariableDeclaration parameter in node.namedParameters) {
+      handleParameter(parameter, isOptional: true);
+    }
+  }
+
+  @override
+  TypeInformation visitFunctionNode(ir.FunctionNode node) {
+    handleParameters(node);
+
+    if (_closedWorld.nativeData.isNativeMember(_analyzedMember)) {
+      // Native methods do not have a body, and we currently just say
+      // they return dynamic and may contain all side-effects.
+      NativeBehavior nativeBehavior =
+          _closedWorld.nativeData.getNativeMethodBehavior(_analyzedMember);
+      _sideEffectsBuilder.add(nativeBehavior.sideEffects);
+      return _types.dynamicType;
+    }
+
+    visit(node.body);
+    switch (node.asyncMarker) {
+      case ir.AsyncMarker.Sync:
+        if (_returnType == null) {
+          // No return in the body.
+          _returnType = _state.seenReturnOrThrow
+              ? _types.nonNullEmpty() // Body always throws.
+              : _types.nullType;
+        } else if (!_state.seenReturnOrThrow) {
+          // We haven'TypeInformation seen returns on all branches. So the
+          // method may also return null.
+          recordReturnType(_types.nullType);
+        }
+        break;
+
+      case ir.AsyncMarker.SyncStar:
+        // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type
+        //               contained is the method body's return type.
+        recordReturnType(_types.syncStarIterableType);
+        break;
+
+      case ir.AsyncMarker.Async:
+        recordReturnType(_types.asyncFutureType);
+        break;
+
+      case ir.AsyncMarker.AsyncStar:
+        recordReturnType(_types.asyncStarStreamType);
+        break;
+    }
+    assert(_breaksFor.isEmpty);
+    assert(_continuesFor.isEmpty);
+    return _returnType;
+  }
+
+  @override
+  TypeInformation visitInstantiation(ir.Instantiation node) {
+    return createInstantiationTypeInformation(visit(node.expression));
+  }
+
+  TypeInformation createInstantiationTypeInformation(
+      TypeInformation expressionType) {
+    // TODO(sra): Add a TypeInformation for Instantiations.  Instantiated
+    // generic methods will need to be traced separately, and have the
+    // information gathered in tracing reflected back to the generic method. For
+    // now, pass along the uninstantiated method.
+    return expressionType;
+  }
+
+  @override
+  TypeInformation defaultExpression(ir.Expression node) {
+    throw UnimplementedError(
+        'Unhandled expression: ${node} (${node.runtimeType})');
+  }
+
+  @override
+  defaultStatement(ir.Statement node) {
+    throw UnimplementedError(
+        'Unhandled statement: ${node} (${node.runtimeType})');
+  }
+
+  @override
+  TypeInformation visitNullLiteral(ir.NullLiteral literal) {
+    return createNullTypeInformation();
+  }
+
+  TypeInformation createNullTypeInformation() {
+    return _types.nullType;
+  }
+
+  @override
+  visitBlock(ir.Block block) {
+    for (ir.Statement statement in block.statements) {
+      visit(statement);
+      if (_state.aborts) break;
+    }
+    return null;
+  }
+
+  @override
+  visitExpressionStatement(ir.ExpressionStatement node) {
+    visit(node.expression);
+    return null;
+  }
+
+  @override
+  visitEmptyStatement(ir.EmptyStatement node) {
+    // Nothing to do.
+    return null;
+  }
+
+  TypeInformation _handleAssertStatement(ir.AssertStatement node) {
+    // Avoid pollution from assert statement unless enabled.
+    if (!_options.enableUserAssertions) {
+      return null;
+    }
+    // TODO(johnniwinther): Should assert be used with --trust-type-annotations?
+    // TODO(johnniwinther): Track reachable for assertions known to fail.
+    LocalState stateBefore = _state;
+    handleCondition(node.condition);
+    LocalState afterConditionWhenTrue = _stateAfterWhenTrue;
+    LocalState afterConditionWhenFalse = _stateAfterWhenFalse;
+    _state = LocalState.childPath(afterConditionWhenFalse);
+    visit(node.message);
+    LocalState stateAfterMessage = _state;
+    stateAfterMessage.seenReturnOrThrow = true;
+    _state = stateBefore.mergeDiamondFlow(
+        _inferrer, afterConditionWhenTrue, stateAfterMessage);
+    return null;
+  }
+
+  @override
+  visitAssertInitializer(ir.AssertInitializer node) {
+    return _handleAssertStatement(node.statement);
+  }
+
+  @override
+  visitAssertStatement(ir.AssertStatement node) {
+    return _handleAssertStatement(node);
+  }
+
+  @override
+  visitBreakStatement(ir.BreakStatement node) {
+    JumpTarget target = _localsMap.getJumpTargetForBreak(node);
+    _state.seenBreakOrContinue = true;
+    // Do a deep-copy of the locals, because the code following the
+    // break will change them.
+    if (_localsMap.generateContinueForBreak(node)) {
+      _continuesFor[target].add(LocalState.deepCopyOf(_state));
+    } else {
+      _breaksFor[target].add(LocalState.deepCopyOf(_state));
+    }
+    return null;
+  }
+
+  @override
+  visitLabeledStatement(ir.LabeledStatement node) {
+    ir.Statement body = node.body;
+    if (JumpVisitor.canBeBreakTarget(body)) {
+      // Loops and switches handle their own labels.
+      visit(body);
+    } else {
+      LocalState stateBefore = _state;
+      JumpTarget jumpTarget = _localsMap.getJumpTargetForLabel(node);
+      _setupBreaksAndContinues(jumpTarget);
+      _state = LocalState.childPath(stateBefore);
+      visit(body);
+      _state = stateBefore.mergeAfterBreaks(_inferrer, _getBreaks(jumpTarget),
+          keepOwnLocals: false);
+      _clearBreaksAndContinues(jumpTarget);
+    }
+    return null;
+  }
+
+  @override
+  visitSwitchStatement(ir.SwitchStatement node) {
+    visit(node.expression);
+
+    JumpTarget jumpTarget = _localsMap.getJumpTargetForSwitch(node);
+    _setupBreaksAndContinues(jumpTarget);
+
+    List<JumpTarget> continueTargets = <JumpTarget>[];
+    bool hasDefaultCase = false;
+    for (ir.SwitchCase switchCase in node.cases) {
+      JumpTarget continueTarget =
+          _localsMap.getJumpTargetForSwitchCase(switchCase);
+      if (continueTarget != null) {
+        continueTargets.add(continueTarget);
+      }
+      if (switchCase.isDefault) {
+        hasDefaultCase = true;
+      }
+    }
+    LocalState stateBefore = _state;
+    if (continueTargets.isNotEmpty) {
+      continueTargets.forEach(_setupBreaksAndContinues);
+
+      // If the switch statement has a continue, we conservatively
+      // visit all cases and update [locals] until we have reached a
+      // fixed point.
+      bool changed;
+      stateBefore.startLoop(_inferrer, node);
+      do {
+        changed = false;
+        // We first visit every case and collect the updated continue states.
+        // We must do a full pass as the jumps may be to earlier cases.
+        _visitCasesForSwitch(node, stateBefore);
+
+        // We then pass back over the cases and update the state of any continue
+        // targets with the states we collected in the last pass.
+        for (ir.SwitchCase switchCase in node.cases) {
+          final continueTarget =
+              _localsMap.getJumpTargetForSwitchCase(switchCase);
+          if (continueTarget != null) {
+            changed |= stateBefore.mergeAll(
+                _inferrer, _getLoopBackEdges(continueTarget));
+          }
+        }
+      } while (changed);
+      stateBefore.endLoop(_inferrer, node);
+
+      continueTargets.forEach(_clearBreaksAndContinues);
+    } else {
+      // Gather the termination states of each case by visiting all the breaks.
+      _visitCasesForSwitch(node, stateBefore);
+    }
+
+    // Combine all the termination states accumulated from all the visited
+    // breaks that target this switch.
+    _state = stateBefore.mergeAfterBreaks(_inferrer, _getBreaks(jumpTarget),
+        keepOwnLocals: !hasDefaultCase);
+    _clearBreaksAndContinues(jumpTarget);
+    return null;
+  }
+
+  _visitCasesForSwitch(ir.SwitchStatement node, LocalState stateBefore) {
+    for (ir.SwitchCase switchCase in node.cases) {
+      _state = LocalState.childPath(stateBefore);
+      visit(switchCase);
+    }
+  }
+
+  @override
+  visitSwitchCase(ir.SwitchCase node) {
+    visit(node.body);
+    return null;
+  }
+
+  @override
+  visitContinueSwitchStatement(ir.ContinueSwitchStatement node) {
+    JumpTarget target = _localsMap.getJumpTargetForContinueSwitch(node);
+    _state.seenBreakOrContinue = true;
+    // Do a deep-copy of the locals, because the code following the
+    // break will change them.
+    _continuesFor[target].add(LocalState.deepCopyOf(_state));
+    return null;
+  }
+
+  @override
+  TypeInformation visitListLiteral(ir.ListLiteral node) {
+    return createListTypeInformation(
+        node, node.expressions.map((e) => visit(e)),
+        isConst: node.isConst);
+  }
+
+  TypeInformation createListTypeInformation(
+      ir.TreeNode node, Iterable<TypeInformation> elementTypes,
+      {bool isConst}) {
+    // We only set the type once. We don't need to re-visit the children
+    // when re-analyzing the node.
+    return _inferrer.concreteTypes.putIfAbsent(node, () {
+      TypeInformation elementType;
+      int length = 0;
+      for (TypeInformation type in elementTypes) {
+        elementType = elementType == null
+            ? _types.allocatePhi(null, null, type, isTry: false)
+            : _types.addPhiInput(null, elementType, type);
+        length++;
+      }
+      elementType = elementType == null
+          ? _types.nonNullEmpty()
+          : _types.simplifyPhi(null, null, elementType);
+      TypeInformation containerType =
+          isConst ? _types.constListType : _types.growableListType;
+      return _types.allocateList(
+          containerType, node, _analyzedMember, elementType, length);
+    });
+  }
+
+  @override
+  TypeInformation visitSetLiteral(ir.SetLiteral node) {
+    return createSetTypeInformation(node, node.expressions.map((e) => visit(e)),
+        isConst: node.isConst);
+  }
+
+  TypeInformation createSetTypeInformation(
+      ir.TreeNode node, Iterable<TypeInformation> elementTypes,
+      {bool isConst}) {
+    return _inferrer.concreteTypes.putIfAbsent(node, () {
+      TypeInformation elementType;
+      for (TypeInformation type in elementTypes) {
+        elementType = elementType == null
+            ? _types.allocatePhi(null, null, type, isTry: false)
+            : _types.addPhiInput(null, elementType, type);
+      }
+      elementType = elementType == null
+          ? _types.nonNullEmpty()
+          : _types.simplifyPhi(null, null, elementType);
+      TypeInformation containerType =
+          isConst ? _types.constSetType : _types.setType;
+      return _types.allocateSet(
+          containerType, node, _analyzedMember, elementType);
+    });
+  }
+
+  @override
+  TypeInformation visitMapLiteral(ir.MapLiteral node) {
+    return createMapTypeInformation(
+        node, node.entries.map((e) => Pair(visit(e.key), visit(e.value))),
+        isConst: node.isConst);
+  }
+
+  TypeInformation createMapTypeInformation(ir.TreeNode node,
+      Iterable<Pair<TypeInformation, TypeInformation>> entryTypes,
+      {bool isConst}) {
+    return _inferrer.concreteTypes.putIfAbsent(node, () {
+      List keyTypes = <TypeInformation>[];
+      List valueTypes = <TypeInformation>[];
+
+      for (Pair<TypeInformation, TypeInformation> entryType in entryTypes) {
+        keyTypes.add(entryType.a);
+        valueTypes.add(entryType.b);
+      }
+
+      TypeInformation type = isConst ? _types.constMapType : _types.mapType;
+      return _types.allocateMap(
+          type, node, _analyzedMember, keyTypes, valueTypes);
+    });
+  }
+
+  @override
+  TypeInformation visitRecordLiteral(ir.RecordLiteral node) {
+    return defaultExpression(node);
+  }
+
+  @override
+  TypeInformation visitReturnStatement(ir.ReturnStatement node) {
+    ir.Node expression = node.expression;
+    recordReturnType(expression == null ? _types.nullType : visit(expression));
+    _state.seenReturnOrThrow = true;
+    _state.markInitializationAsIndefinite();
+    return null;
+  }
+
+  @override
+  TypeInformation visitBoolLiteral(ir.BoolLiteral node) {
+    return createBoolTypeInformation(node.value);
+  }
+
+  TypeInformation createBoolTypeInformation(bool value) {
+    return _types.boolLiteralType(value);
+  }
+
+  @override
+  TypeInformation visitIntLiteral(ir.IntLiteral node) {
+    return createIntTypeInformation(node.value);
+  }
+
+  TypeInformation createIntTypeInformation(int value) {
+    // The JavaScript backend may turn this literal into a double at
+    // runtime.
+    return _types.getConcreteTypeFor(_closedWorld.abstractValueDomain
+        .computeAbstractValueForConstant(
+            constant_system.createIntFromInt(value)));
+  }
+
+  @override
+  TypeInformation visitDoubleLiteral(ir.DoubleLiteral node) {
+    return createDoubleTypeInformation(node.value);
+  }
+
+  TypeInformation createDoubleTypeInformation(double value) {
+    // The JavaScript backend may turn this literal into a double at
+    // runtime.
+    return _types.getConcreteTypeFor(_closedWorld.abstractValueDomain
+        .computeAbstractValueForConstant(constant_system.createDouble(value)));
+  }
+
+  @override
+  TypeInformation visitStringLiteral(ir.StringLiteral node) {
+    return createStringTypeInformation(node.value);
+  }
+
+  TypeInformation createStringTypeInformation(String value) {
+    return _types.stringLiteralType(value);
+  }
+
+  @override
+  TypeInformation visitStringConcatenation(ir.StringConcatenation node) {
+    // Interpolation could have any effects since it could call any toString()
+    // method.
+    // TODO(sra): This could be modelled by a call to toString() but with a
+    // guaranteed String return type.  Interpolation of known types would get
+    // specialized effects.  This would not currently be effective since the JS
+    // code in the toString methods for intercepted primitive types is assumed
+    // to have all effects.  Effect annotations on JS code would be needed to
+    // get the benefit.
+    _sideEffectsBuilder.setAllSideEffects();
+
+    node.visitChildren(this);
+    return _types.stringType;
+  }
+
+  @override
+  TypeInformation visitSymbolLiteral(ir.SymbolLiteral node) {
+    return createSymbolLiteralTypeInformation();
+  }
+
+  TypeInformation createSymbolLiteralTypeInformation() {
+    return _types
+        .nonNullSubtype(_closedWorld.commonElements.symbolImplementationClass);
+  }
+
+  @override
+  TypeInformation visitTypeLiteral(ir.TypeLiteral node) {
+    return createTypeLiteralInformation();
+  }
+
+  TypeInformation createTypeLiteralInformation() {
+    return _types.typeType;
+  }
+
+  @override
+  TypeInformation visitVariableDeclaration(ir.VariableDeclaration node) {
+    assert(
+        node.parent is! ir.FunctionNode, "Unexpected parameter declaration.");
+    Local local = _localsMap.getLocalVariable(node);
+    DartType type = _localsMap.getLocalType(_elementMap, local);
+    if (node.initializer == null) {
+      _state.updateLocal(
+          _inferrer, _capturedAndBoxed, local, _types.nullType, type);
+    } else {
+      _state.updateLocal(
+          _inferrer, _capturedAndBoxed, local, visit(node.initializer), type);
+    }
+    if (node.initializer is ir.ThisExpression) {
+      _state.markThisAsExposed();
+    }
+    return null;
+  }
+
+  @override
+  TypeInformation visitVariableGet(ir.VariableGet node) {
+    Local local = _localsMap.getLocalVariable(node.variable);
+    TypeInformation type =
+        _state.readLocal(_inferrer, _capturedAndBoxed, local);
+    assert(type != null, "Missing type information for $local.");
+    return type;
+  }
+
+  @override
+  TypeInformation visitVariableSet(ir.VariableSet node) {
+    TypeInformation rhsType = visit(node.value);
+    if (node.value is ir.ThisExpression) {
+      _state.markThisAsExposed();
+    }
+    Local local = _localsMap.getLocalVariable(node.variable);
+    DartType type = _localsMap.getLocalType(_elementMap, local);
+    _state.updateLocal(_inferrer, _capturedAndBoxed, local, rhsType, type);
+    return rhsType;
+  }
+
+  ArgumentsTypes analyzeArguments(ir.Arguments arguments) {
+    List<TypeInformation> positional = <TypeInformation>[];
+    Map<String, TypeInformation> named;
+    for (ir.Expression argument in arguments.positional) {
+      // TODO(ngeoffray): We could do better here if we knew what we
+      // are calling does not expose this.
+      if (argument is ir.ThisExpression) {
+        _state.markThisAsExposed();
+      }
+      positional.add(visit(argument));
+    }
+    for (ir.NamedExpression argument in arguments.named) {
+      named ??= <String, TypeInformation>{};
+      ir.Expression value = argument.value;
+      // TODO(ngeoffray): We could do better here if we knew what we
+      // are calling does not expose this.
+      if (value is ir.ThisExpression) {
+        _state.markThisAsExposed();
+      }
+      named[argument.name] = visit(value);
+    }
+
+    return ArgumentsTypes(positional, named);
+  }
+
+  AbstractValue _typeOfReceiver(ir.TreeNode node, ir.TreeNode receiver) {
+    KernelGlobalTypeInferenceElementData data = _memberData;
+    AbstractValue mask = data.typeOfReceiver(node);
+    if (mask != null) return mask;
+    // TODO(sigmund): ensure that this is only called once per node.
+    DartType staticType = _getStaticType(receiver);
+    bool includeNull =
+        _dartTypes.useLegacySubtyping || staticType is NullableType;
+    staticType = staticType.withoutNullability;
+    if (staticType is InterfaceType) {
+      ClassEntity cls = staticType.element;
+      if (receiver is ir.ThisExpression && !_closedWorld.isUsedAsMixin(cls)) {
+        mask = _closedWorld.abstractValueDomain.createNonNullSubclass(cls);
+      } else if (includeNull) {
+        mask = _closedWorld.abstractValueDomain.createNullableSubtype(cls);
+      } else {
+        mask = _closedWorld.abstractValueDomain.createNonNullSubtype(cls);
+      }
+      data.setReceiverTypeMask(node, mask);
+      return mask;
+    }
+    // TODO(sigmund): consider also extracting the bound of type parameters.
+    return null;
+  }
+
+  TypeInformation _handleLocalFunctionInvocation(
+      ir.Expression node,
+      ir.FunctionDeclaration function,
+      ir.Arguments arguments,
+      Selector selector) {
+    ArgumentsTypes argumentsTypes = analyzeArguments(arguments);
+    ClosureRepresentationInfo info =
+        _closureDataLookup.getClosureInfo(function);
+    if (isIncompatibleInvoke(info.callMethod, argumentsTypes)) {
+      return _types.dynamicType;
+    }
+
+    TypeInformation type =
+        handleStaticInvoke(node, selector, info.callMethod, argumentsTypes);
+    FunctionType functionType =
+        _elementMap.elementEnvironment.getFunctionType(info.callMethod);
+    if (functionType.returnType.containsFreeTypeVariables) {
+      // The return type varies with the call site so we narrow the static
+      // return type.
+      type = _types.narrowType(type, _getStaticType(node));
+    }
+    return type;
+  }
+
+  @override
+  TypeInformation visitLocalFunctionInvocation(
+      ir.LocalFunctionInvocation node) {
+    Selector selector = _elementMap.getSelector(node);
+    return _handleLocalFunctionInvocation(
+        node, node.variable.parent, node.arguments, selector);
+  }
+
+  @override
+  TypeInformation visitEqualsNull(ir.EqualsNull node) {
+    visit(node.expression);
+    // TODO(johnniwinther). This triggers the computation of the mask for the
+    // receiver of the call to `==`, which doesn't happen in this case. Remove
+    // this when the ssa builder recognizes `== null` directly.
+    _typeOfReceiver(node, node.expression);
+    _potentiallyAddNullCheck(node.expression);
+    return _types.boolType;
+  }
+
+  TypeInformation _handleMethodInvocation(
+      ir.Expression node,
+      ir.Expression receiver,
+      TypeInformation receiverType,
+      Selector selector,
+      ArgumentsTypes arguments,
+      ir.Member interfaceTarget) {
+    AbstractValue mask = _typeOfReceiver(node, receiver);
+    if (receiver is ir.ThisExpression) {
+      _checkIfExposesThis(
+          selector, _types.newTypedSelector(receiverType, mask));
+    }
+    TypeInformation type = handleDynamicInvoke(CallType.access, node, selector,
+        mask, receiverType, arguments, _getVariableDeclaration(receiver));
+    if (interfaceTarget != null) {
+      if (interfaceTarget is ir.Procedure &&
+          (interfaceTarget.kind == ir.ProcedureKind.Method ||
+              interfaceTarget.kind == ir.ProcedureKind.Operator)) {
+        // Pull the type from kernel (instead of from the J-model) because the
+        // interface target might be abstract and therefore not part of the
+        // J-model.
+        ir.DartType returnType = interfaceTarget.function.returnType;
+        // The return type varies with the call site so we narrow the static
+        // return type.
+        if (containsFreeVariables(returnType)) {
+          type = _types.narrowType(type, _getStaticType(node));
+        }
+      } else {
+        // The return type is thrown away when using [TypeMask]s; narrow to the
+        // static return type.
+        type = _types.narrowType(type, _getStaticType(node));
+      }
+    } else {
+      // We don't have a known target but the static type hold some information
+      // if it is a function type.
+      type = _types.narrowType(type, _getStaticType(node));
+    }
+    return type;
+  }
+
+  TypeInformation _handleEqualsCall(
+      ir.Expression node,
+      ir.Expression left,
+      TypeInformation leftType,
+      ir.Expression right,
+      TypeInformation rightType) {
+    // TODO(johnniwinther). This triggers the computation of the mask for the
+    // receiver of the call to `==`, which might not happen in this case. Remove
+    // this when the ssa builder recognizes `== null` directly.
+    _typeOfReceiver(node, left);
+    bool leftIsNull = _types.isNull(leftType);
+    bool rightIsNull = _types.isNull(rightType);
+    if (leftIsNull) {
+      // [right] is `null` if [node] evaluates to `true`.
+      _potentiallyAddNullCheck(right);
+    }
+    if (rightIsNull) {
+      // [left] is `null` if [node] evaluates to `true`.
+      _potentiallyAddNullCheck(left);
+    }
+    if (leftIsNull || rightIsNull) {
+      // `left == right` where `left` and/or `right` is known to have type
+      // `Null` so we have no invocation to register.
+      return _types.boolType;
+    }
+    Selector selector = Selector.binaryOperator('==');
+    ArgumentsTypes arguments = ArgumentsTypes([rightType], null);
+    return _handleMethodInvocation(
+        node, left, leftType, selector, arguments, null);
+  }
+
+  @override
+  TypeInformation visitEqualsCall(ir.EqualsCall node) {
+    TypeInformation leftType = visit(node.left);
+    TypeInformation rightType = visit(node.right);
+    return _handleEqualsCall(node, node.left, leftType, node.right, rightType);
+  }
+
+  @override
+  TypeInformation visitInstanceInvocation(ir.InstanceInvocation node) {
+    Selector selector = _elementMap.getSelector(node);
+    ir.Expression receiver = node.receiver;
+    TypeInformation receiverType = visit(receiver);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    return _handleMethodInvocation(node, node.receiver, receiverType, selector,
+        arguments, node.interfaceTarget);
+  }
+
+  @override
+  TypeInformation visitInstanceGetterInvocation(
+      ir.InstanceGetterInvocation node) {
+    Selector selector = _elementMap.getSelector(node);
+    ir.Expression receiver = node.receiver;
+    TypeInformation receiverType = visit(receiver);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    return _handleMethodInvocation(node, node.receiver, receiverType, selector,
+        arguments, node.interfaceTarget);
+  }
+
+  @override
+  TypeInformation visitDynamicInvocation(ir.DynamicInvocation node) {
+    Selector selector = _elementMap.getSelector(node);
+    ir.Expression receiver = node.receiver;
+    TypeInformation receiverType = visit(receiver);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    return _handleMethodInvocation(
+        node, node.receiver, receiverType, selector, arguments, null);
+  }
+
+  @override
+  TypeInformation visitFunctionInvocation(ir.FunctionInvocation node) {
+    Selector selector = _elementMap.getSelector(node);
+    ir.Expression receiver = node.receiver;
+    TypeInformation receiverType = visit(receiver);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    return _handleMethodInvocation(
+        node, node.receiver, receiverType, selector, arguments, null);
+  }
+
+  ir.VariableDeclaration _getVariableDeclaration(ir.Expression node) {
+    return node is ir.VariableGet ? node.variable : null;
+  }
+
+  TypeInformation _handleDynamic(
+      CallType callType,
+      ir.Node node,
+      Selector selector,
+      AbstractValue mask,
+      TypeInformation receiverType,
+      ArgumentsTypes arguments,
+      ir.VariableDeclaration variable) {
+    assert(receiverType != null);
+    if (_types.selectorNeedsUpdate(receiverType, mask)) {
+      mask = receiverType == _types.dynamicType
+          ? null
+          : _types.newTypedSelector(receiverType, mask);
+      _inferrer.updateSelectorInMember(
+          _analyzedMember, callType, node, selector, mask);
+    }
+
+    if (variable != null) {
+      Local local = _localsMap.getLocalVariable(variable);
+      if (!_capturedVariables.contains(local)) {
+        // Receiver strengthening to non-null.
+        DartType type = _localsMap.getLocalType(_elementMap, local);
+        _state.updateLocal(
+            _inferrer, _capturedAndBoxed, local, receiverType, type,
+            excludeNull: !selector.appliesToNullWithoutThrow());
+      }
+    }
+
+    return _inferrer.registerCalledSelector(callType, node, selector, mask,
+        receiverType, _analyzedMember, arguments, _sideEffectsBuilder,
+        inLoop: inLoop, isConditional: false);
+  }
+
+  TypeInformation handleDynamicGet(
+      ir.Node node,
+      Selector selector,
+      AbstractValue mask,
+      TypeInformation receiverType,
+      ir.VariableDeclaration variable) {
+    return _handleDynamic(
+        CallType.access, node, selector, mask, receiverType, null, variable);
+  }
+
+  TypeInformation handleDynamicSet(
+      ir.Node node,
+      Selector selector,
+      AbstractValue mask,
+      TypeInformation receiverType,
+      TypeInformation rhsType,
+      ir.VariableDeclaration variable) {
+    ArgumentsTypes arguments = ArgumentsTypes([rhsType], null);
+    return _handleDynamic(CallType.access, node, selector, mask, receiverType,
+        arguments, variable);
+  }
+
+  TypeInformation handleDynamicInvoke(
+      CallType callType,
+      ir.Node node,
+      Selector selector,
+      AbstractValue mask,
+      TypeInformation receiverType,
+      ArgumentsTypes arguments,
+      ir.VariableDeclaration variable) {
+    return _handleDynamic(
+        callType, node, selector, mask, receiverType, arguments, variable);
+  }
+
+  @override
+  TypeInformation visitLet(ir.Let node) {
+    visit(node.variable);
+    return visit(node.body);
+  }
+
+  @override
+  TypeInformation visitBlockExpression(ir.BlockExpression node) {
+    visit(node.body);
+    return visit(node.value);
+  }
+
+  @override
+  TypeInformation visitForInStatement(ir.ForInStatement node) {
+    if (node.iterable is ir.ThisExpression) {
+      // Any reasonable implementation of an iterator would expose
+      // this, so we play it safe and assume it will.
+      _state.markThisAsExposed();
+    }
+
+    AbstractValue currentMask;
+    AbstractValue moveNextMask;
+    TypeInformation iteratorType;
+    if (node.isAsync) {
+      TypeInformation expressionType = visit(node.iterable);
+
+      currentMask = _memberData.typeOfIteratorCurrent(node);
+      moveNextMask = _memberData.typeOfIteratorMoveNext(node);
+
+      ConstructorEntity constructor =
+          _closedWorld.commonElements.streamIteratorConstructor;
+
+      /// Synthesize a call to the [StreamIterator] constructor.
+      iteratorType = handleStaticInvoke(
+          node, null, constructor, ArgumentsTypes([expressionType], null));
+    } else {
+      TypeInformation expressionType = visit(node.iterable);
+      Selector iteratorSelector = Selectors.iterator;
+      AbstractValue iteratorMask = _memberData.typeOfIterator(node);
+      currentMask = _memberData.typeOfIteratorCurrent(node);
+      moveNextMask = _memberData.typeOfIteratorMoveNext(node);
+
+      iteratorType = handleDynamicInvoke(CallType.forIn, node, iteratorSelector,
+          iteratorMask, expressionType, ArgumentsTypes.empty(), null);
+    }
+
+    handleDynamicInvoke(CallType.forIn, node, Selectors.moveNext, moveNextMask,
+        iteratorType, ArgumentsTypes.empty(), null);
+    TypeInformation currentType = handleDynamicInvoke(
+        CallType.forIn,
+        node,
+        Selectors.current,
+        currentMask,
+        iteratorType,
+        ArgumentsTypes.empty(),
+        null);
+
+    Local variable = _localsMap.getLocalVariable(node.variable);
+    DartType variableType = _localsMap.getLocalType(_elementMap, variable);
+    _state.updateLocal(
+        _inferrer, _capturedAndBoxed, variable, currentType, variableType);
+
+    JumpTarget target = _localsMap.getJumpTargetForForIn(node);
+    return handleLoop(node, target, () {
+      visit(node.body);
+    });
+  }
+
+  void _setupBreaksAndContinues(JumpTarget target) {
+    if (target == null) return;
+    if (target.isContinueTarget) {
+      _continuesFor[target] = <LocalState>[];
+    }
+    if (target.isBreakTarget) {
+      _breaksFor[target] = <LocalState>[];
+    }
+  }
+
+  void _clearBreaksAndContinues(JumpTarget element) {
+    _continuesFor.remove(element);
+    _breaksFor.remove(element);
+  }
+
+  List<LocalState> _getBreaks(JumpTarget target) {
+    List<LocalState> list = <LocalState>[_state];
+    if (target == null) return list;
+    if (!target.isBreakTarget) return list;
+    return list..addAll(_breaksFor[target]);
+  }
+
+  List<LocalState> _getLoopBackEdges(JumpTarget target) {
+    List<LocalState> list = <LocalState>[_state];
+    if (target == null) return list;
+    if (!target.isContinueTarget) return list;
+    return list..addAll(_continuesFor[target]);
+  }
+
+  TypeInformation handleLoop(ir.Node node, JumpTarget target, void logic()) {
+    _loopLevel++;
+    bool changed = false;
+    LocalState stateBefore = _state;
+    stateBefore.startLoop(_inferrer, node);
+    do {
+      // Setup (and clear in case of multiple iterations of the loop)
+      // the lists of breaks and continues seen in the loop.
+      _setupBreaksAndContinues(target);
+      _state = LocalState.childPath(stateBefore);
+      logic();
+      changed = stateBefore.mergeAll(_inferrer, _getLoopBackEdges(target));
+    } while (changed);
+    _loopLevel--;
+    stateBefore.endLoop(_inferrer, node);
+    bool keepOwnLocals = node is! ir.DoStatement;
+    _state = stateBefore.mergeAfterBreaks(_inferrer, _getBreaks(target),
+        keepOwnLocals: keepOwnLocals);
+    _clearBreaksAndContinues(target);
+    return null;
+  }
+
+  @override
+  TypeInformation visitConstructorInvocation(ir.ConstructorInvocation node) {
+    ConstructorEntity constructor = _elementMap.getConstructor(node.target);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    Selector selector = _elementMap.getSelector(node);
+    return handleConstructorInvoke(
+        node, node.arguments, selector, constructor, arguments);
+  }
+
+  /// Try to find the length given to a fixed array constructor call.
+  int _findLength(ir.Arguments arguments) {
+    int finish(int length) {
+      // Filter out lengths that should not be tracked.
+      if (length < 0) return null;
+      // Serialization limit.
+      if (length >= (1 << 30)) return null;
+      return length;
+    }
+
+    ir.Expression firstArgument = arguments.positional.first;
+    if (firstArgument is ir.ConstantExpression &&
+        firstArgument.constant is ir.DoubleConstant) {
+      ir.DoubleConstant constant = firstArgument.constant;
+      double doubleValue = constant.value;
+      int truncatedValue = doubleValue.truncate();
+      if (doubleValue == truncatedValue) {
+        return finish(truncatedValue);
+      }
+    } else if (firstArgument is ir.IntLiteral) {
+      return finish(firstArgument.value);
+    } else if (firstArgument is ir.StaticGet) {
+      MemberEntity member = _elementMap.getMember(firstArgument.target);
+      if (member.isField) {
+        FieldAnalysisData fieldData =
+            _closedWorld.fieldAnalysis.getFieldData(member);
+        ConstantValue constantValue = fieldData.constantValue;
+        if (fieldData.isEffectivelyConstant &&
+            constantValue is IntConstantValue) {
+          BigInt intValue = constantValue.intValue;
+          if (intValue.isValidInt) {
+            return finish(intValue.toInt());
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  /// Find the base type for a system List constructor from the value passed to
+  /// the 'growable' argument. [defaultGrowable] is the default value of the
+  /// 'growable' parameter.
+  TypeInformation _listBaseType(ir.Arguments arguments,
+      {bool defaultGrowable}) {
+    TypeInformation finish(bool /*?*/ growable) {
+      if (growable == true) return _types.growableListType;
+      if (growable == false) return _types.fixedListType;
+      return _types.mutableArrayType;
+    }
+
+    for (ir.NamedExpression named in arguments.named) {
+      if (named.name == 'growable') {
+        ir.Expression argument = named.value;
+        if (argument is ir.BoolLiteral) return finish(argument.value);
+        if (argument is ir.ConstantExpression) {
+          ir.Constant constant = argument.constant;
+          if (constant is ir.BoolConstant) return finish(constant.value);
+        }
+        // 'growable' is present, but indeterminate.
+        return finish(null);
+      }
+    }
+    // 'growable' is missing.
+    return finish(defaultGrowable);
+  }
+
+  /// Returns `true` for constructors of typed arrays.
+  bool _isConstructorOfTypedArraySubclass(ConstructorEntity constructor) {
+    ClassEntity cls = constructor.enclosingClass;
+    return cls.library.canonicalUri == Uris.dart__native_typed_data &&
+        _closedWorld.nativeData.isNativeClass(cls) &&
+        _closedWorld.classHierarchy
+            .isSubtypeOf(cls, _closedWorld.commonElements.typedDataClass) &&
+        _closedWorld.classHierarchy
+            .isSubtypeOf(cls, _closedWorld.commonElements.listClass) &&
+        constructor.name == '';
+  }
+
+  TypeInformation handleConstructorInvoke(
+      ir.Node node,
+      ir.Arguments arguments,
+      Selector selector,
+      ConstructorEntity constructor,
+      ArgumentsTypes argumentsTypes) {
+    TypeInformation returnType =
+        handleStaticInvoke(node, selector, constructor, argumentsTypes);
+
+    // See if we can replace the returned type with one that better describes
+    // the operation. For system List constructors we can treat this as the
+    // allocation point of a new collection. The static invoke above ensures
+    // that the implementation of the constructor sees the arguments.
+
+    var commonElements = _elementMap.commonElements;
+
+    if (commonElements.isUnnamedListConstructor(constructor)) {
+      // We have `new List(...)`.
+      if (arguments.positional.isEmpty && arguments.named.isEmpty) {
+        // We have `new List()`.
+        return _inferrer.concreteTypes.putIfAbsent(
+            node,
+            () => _types.allocateList(_types.growableListType, node,
+                _analyzedMember, _types.nonNullEmpty(), 0));
+      } else {
+        // We have `new List(len)`.
+        int length = _findLength(arguments);
+        return _inferrer.concreteTypes.putIfAbsent(
+            node,
+            () => _types.allocateList(_types.fixedListType, node,
+                _analyzedMember, _types.nullType, length));
+      }
+    }
+
+    if (commonElements.isNamedListConstructor('filled', constructor)) {
+      // We have something like `List.filled(len, fill)`.
+      int length = _findLength(arguments);
+      TypeInformation elementType = argumentsTypes.positional[1];
+      TypeInformation baseType =
+          _listBaseType(arguments, defaultGrowable: false);
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(
+              baseType, node, _analyzedMember, elementType, length));
+    }
+
+    if (commonElements.isNamedListConstructor('generate', constructor)) {
+      // We have something like `List.generate(len, generator)`.
+      int length = _findLength(arguments);
+      TypeInformation baseType =
+          _listBaseType(arguments, defaultGrowable: true);
+      TypeInformation closureArgumentInfo = argumentsTypes.positional[1];
+      // If the argument is an immediate closure, the element type is that
+      // returned by the closure.
+      TypeInformation elementType;
+      if (closureArgumentInfo is ClosureTypeInformation) {
+        FunctionEntity closure = closureArgumentInfo.closure;
+        elementType = _types.getInferredTypeOfMember(closure);
+      }
+      elementType ??= _types.dynamicType;
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(
+              baseType, node, _analyzedMember, elementType, length));
+    }
+
+    if (commonElements.isNamedListConstructor('empty', constructor)) {
+      // We have something like `List.empty(growable: true)`.
+      TypeInformation baseType =
+          _listBaseType(arguments, defaultGrowable: false);
+      TypeInformation elementType = _types.nonNullEmpty(); // No elements!
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(
+              baseType, node, _analyzedMember, elementType, 0));
+    }
+    if (commonElements.isNamedListConstructor('of', constructor) ||
+        commonElements.isNamedListConstructor('from', constructor)) {
+      // We have something like `List.of(elements)`.
+      TypeInformation baseType =
+          _listBaseType(arguments, defaultGrowable: true);
+      // TODO(sra): Use static type to bound the element type, preferably as a
+      // narrowing of all inputs.
+      TypeInformation elementType = _types.dynamicType;
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(
+              baseType, node, _analyzedMember, elementType));
+    }
+
+    // `JSArray.fixed` corresponds to `new Array(length)`, which is a list
+    // filled with `null`.
+    if (commonElements.isNamedJSArrayConstructor('fixed', constructor)) {
+      int length = _findLength(arguments);
+      TypeInformation elementType = _types.nullType;
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(_types.fixedListType, node, _analyzedMember,
+              elementType, length));
+    }
+
+    // `JSArray.allocateFixed` creates an array with 'no elements'. The contract
+    // is that the caller will assign a value to each member before any element
+    // is accessed. We can start tracking the element type as 'bottom'.
+    if (commonElements.isNamedJSArrayConstructor(
+        'allocateFixed', constructor)) {
+      int length = _findLength(arguments);
+      TypeInformation elementType = _types.nonNullEmpty();
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(_types.fixedListType, node, _analyzedMember,
+              elementType, length));
+    }
+
+    // `JSArray.allocateGrowable` creates an array with 'no elements'. The
+    // contract is that the caller will assign a value to each member before any
+    // element is accessed. We can start tracking the element type as 'bottom'.
+    if (commonElements.isNamedJSArrayConstructor(
+        'allocateGrowable', constructor)) {
+      int length = _findLength(arguments);
+      TypeInformation elementType = _types.nonNullEmpty();
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(_types.growableListType, node,
+              _analyzedMember, elementType, length));
+    }
+
+    if (_isConstructorOfTypedArraySubclass(constructor)) {
+      // We have something like `Uint32List(len)`.
+      int length = _findLength(arguments);
+      MemberEntity member = _elementMap.elementEnvironment
+          .lookupClassMember(constructor.enclosingClass, Names.INDEX_NAME);
+      TypeInformation elementType = _inferrer.returnTypeOfMember(member);
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(
+              _types.nonNullExact(constructor.enclosingClass),
+              node,
+              _analyzedMember,
+              elementType,
+              length));
+    }
+
+    return returnType;
+  }
+
+  TypeInformation handleStaticInvoke(ir.Node node, Selector selector,
+      MemberEntity element, ArgumentsTypes arguments) {
+    return _inferrer.registerCalledMember(node, selector, _analyzedMember,
+        element, arguments, _sideEffectsBuilder, inLoop);
+  }
+
+  TypeInformation handleClosureCall(ir.Node node, Selector selector,
+      MemberEntity member, ArgumentsTypes arguments) {
+    return _inferrer.registerCalledClosure(
+        node,
+        selector,
+        _inferrer.typeOfMember(member),
+        _analyzedMember,
+        arguments,
+        _sideEffectsBuilder,
+        inLoop: inLoop);
+  }
+
+  TypeInformation handleForeignInvoke(ir.StaticInvocation node,
+      FunctionEntity function, ArgumentsTypes arguments, Selector selector) {
+    String name = function.name;
+    handleStaticInvoke(node, selector, function, arguments);
+    if (name == Identifiers.JS) {
+      NativeBehavior nativeBehavior =
+          _elementMap.getNativeBehaviorForJsCall(node);
+      _sideEffectsBuilder.add(nativeBehavior.sideEffects);
+      return _inferrer.typeOfNativeBehavior(nativeBehavior);
+    } else if (name == Identifiers.JS_EMBEDDED_GLOBAL) {
+      NativeBehavior nativeBehavior =
+          _elementMap.getNativeBehaviorForJsEmbeddedGlobalCall(node);
+      _sideEffectsBuilder.add(nativeBehavior.sideEffects);
+      return _inferrer.typeOfNativeBehavior(nativeBehavior);
+    } else if (name == Identifiers.JS_BUILTIN) {
+      NativeBehavior nativeBehavior =
+          _elementMap.getNativeBehaviorForJsBuiltinCall(node);
+      _sideEffectsBuilder.add(nativeBehavior.sideEffects);
+      return _inferrer.typeOfNativeBehavior(nativeBehavior);
+    } else if (name == Identifiers.JS_STRING_CONCAT) {
+      return _types.stringType;
+    } else if (_closedWorld.commonElements.isCreateJsSentinel(function)) {
+      return _types.lateSentinelType;
+    } else if (_closedWorld.commonElements.isIsJsSentinel(function)) {
+      return _types.boolType;
+    } else {
+      _sideEffectsBuilder.setAllSideEffects();
+      return _types.dynamicType;
+    }
+  }
+
+  @override
+  TypeInformation visitStaticInvocation(ir.StaticInvocation node) {
+    MemberEntity member = _elementMap.getMember(node.target);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    Selector selector = _elementMap.getSelector(node);
+    if (_closedWorld.commonElements.isForeign(member)) {
+      return handleForeignInvoke(node, member, arguments, selector);
+    } else if (_closedWorld.commonElements.isLateReadCheck(member)) {
+      // `_lateReadCheck` is essentially a narrowing to exclude the sentinel
+      // value. In order to avoid poor inference resulting from a large
+      // fan-in/fan-out, we perform the narrowing directly instead of creating a
+      // [TypeInformation] for this member.
+      handleStaticInvoke(node, selector, member, arguments);
+      return _types.narrowType(arguments.positional[0],
+          _elementMap.getDartType(node.arguments.types.single),
+          excludeLateSentinel: true);
+    } else if (_closedWorld.commonElements.isCreateSentinel(member)) {
+      handleStaticInvoke(node, selector, member, arguments);
+      return _types.lateSentinelType;
+    } else if (_closedWorld.commonElements.isIsSentinel(member)) {
+      handleStaticInvoke(node, selector, member, arguments);
+
+      // Calls to `isSentinel` can only come from the late lowering kernel
+      // transformation.
+      final value = node.arguments.positional.single as ir.VariableGet;
+
+      Local local = _localsMap.getLocalVariable(value.variable);
+      DartType localType = _localsMap.getLocalType(_elementMap, local);
+      LocalState stateWhenSentinel = LocalState.childPath(_state);
+      LocalState stateWhenNotSentinel = LocalState.childPath(_state);
+
+      // Narrow tested variable to late sentinel on true branch.
+      stateWhenSentinel.updateLocal(_inferrer, _capturedAndBoxed, local,
+          _types.lateSentinelType, localType);
+
+      // Narrow tested variable to not late sentinel on false branch.
+      TypeInformation currentTypeInformation =
+          stateWhenNotSentinel.readLocal(_inferrer, _capturedAndBoxed, local);
+      stateWhenNotSentinel.updateLocal(_inferrer, _capturedAndBoxed, local,
+          currentTypeInformation, localType,
+          excludeLateSentinel: true);
+
+      _setStateAfter(_state, stateWhenSentinel, stateWhenNotSentinel);
+
+      return _types.boolType;
+    } else if (member.isConstructor) {
+      return handleConstructorInvoke(
+          node, node.arguments, selector, member, arguments);
+    } else {
+      assert(member.isFunction, "Unexpected static invocation target: $member");
+      TypeInformation type =
+          handleStaticInvoke(node, selector, member, arguments);
+      FunctionType functionType =
+          _elementMap.elementEnvironment.getFunctionType(member);
+      if (functionType.returnType.containsFreeTypeVariables) {
+        // The return type varies with the call site so we narrow the static
+        // return type.
+        type = _types.narrowType(type, _getStaticType(node));
+      }
+      return type;
+    }
+  }
+
+  @override
+  TypeInformation visitLoadLibrary(ir.LoadLibrary node) {
+    // TODO(johnniwinther): Improve this by returning a Future type instead.
+    return _types.dynamicType;
+  }
+
+  @override
+  TypeInformation visitStaticGet(ir.StaticGet node) {
+    return createStaticGetTypeInformation(node, node.target);
+  }
+
+  @override
+  TypeInformation visitStaticTearOff(ir.StaticTearOff node) {
+    return createStaticGetTypeInformation(node, node.target);
+  }
+
+  TypeInformation createStaticGetTypeInformation(
+      ir.Node node, ir.Member target) {
+    MemberEntity member = _elementMap.getMember(target);
+    return handleStaticInvoke(
+        node, Selector.getter(member.memberName), member, null);
+  }
+
+  @override
+  TypeInformation visitStaticSet(ir.StaticSet node) {
+    TypeInformation rhsType = visit(node.value);
+    if (node.value is ir.ThisExpression) {
+      _state.markThisAsExposed();
+    }
+    MemberEntity member = _elementMap.getMember(node.target);
+    handleStaticInvoke(node, Selector.setter(member.memberName), member,
+        ArgumentsTypes([rhsType], null));
+    return rhsType;
+  }
+
+  TypeInformation _handlePropertyGet(ir.Expression node, ir.Expression receiver,
+      {ir.Member interfaceTarget}) {
+    TypeInformation receiverType = visit(receiver);
+    Selector selector = _elementMap.getSelector(node);
+    AbstractValue mask = _typeOfReceiver(node, receiver);
+    if (receiver is ir.ThisExpression) {
+      _checkIfExposesThis(
+          selector, _types.newTypedSelector(receiverType, mask));
+    }
+    TypeInformation type = handleDynamicGet(
+        node, selector, mask, receiverType, _getVariableDeclaration(receiver));
+    if (interfaceTarget != null) {
+      // Pull the type from kernel (instead of from the J-model) because the
+      // interface target might be abstract and therefore not part of the
+      // J-model.
+      ir.DartType resultType = interfaceTarget.getterType;
+      // The result type varies with the call site so we narrow the static
+      // result type.
+      if (containsFreeVariables(resultType)) {
+        type = _types.narrowType(type, _getStaticType(node));
+      }
+    }
+    return type;
+  }
+
+  @override
+  TypeInformation visitInstanceGet(ir.InstanceGet node) {
+    return _handlePropertyGet(node, node.receiver,
+        interfaceTarget: node.interfaceTarget);
+  }
+
+  @override
+  TypeInformation visitInstanceTearOff(ir.InstanceTearOff node) {
+    return _handlePropertyGet(node, node.receiver,
+        interfaceTarget: node.interfaceTarget);
+  }
+
+  @override
+  TypeInformation visitDynamicGet(ir.DynamicGet node) {
+    return _handlePropertyGet(node, node.receiver);
+  }
+
+  @override
+  TypeInformation visitFunctionTearOff(ir.FunctionTearOff node) {
+    return _handlePropertyGet(node, node.receiver);
+  }
+
+  TypeInformation _handlePropertySet(
+      ir.Expression node, ir.Expression receiver, ir.Expression value,
+      {ir.Member interfaceTarget}) {
+    TypeInformation receiverType = visit(receiver);
+    Selector selector = _elementMap.getSelector(node);
+    AbstractValue mask = _typeOfReceiver(node, receiver);
+
+    TypeInformation rhsType = visit(value);
+    if (value is ir.ThisExpression) {
+      _state.markThisAsExposed();
+    }
+
+    if (_inGenerativeConstructor && receiver is ir.ThisExpression) {
+      AbstractValue typedMask = _types.newTypedSelector(receiverType, mask);
+      if (!_closedWorld.includesClosureCall(selector, typedMask)) {
+        Iterable<MemberEntity> targets =
+            _closedWorld.locateMembers(selector, typedMask);
+        // We just recognized a field initialization of the form:
+        // `this.foo = 42`. If there is only one target, we can update
+        // its type.
+        if (targets.length == 1) {
+          MemberEntity single = targets.first;
+          if (single.isField) {
+            FieldEntity field = single;
+            _state.updateField(field, rhsType);
+          }
+        }
+      }
+    }
+    if (receiver is ir.ThisExpression) {
+      _checkIfExposesThis(
+          selector, _types.newTypedSelector(receiverType, mask));
+    }
+    handleDynamicSet(node, selector, mask, receiverType, rhsType,
+        _getVariableDeclaration(receiver));
+    return rhsType;
+  }
+
+  @override
+  TypeInformation visitInstanceSet(ir.InstanceSet node) {
+    return _handlePropertySet(node, node.receiver, node.value,
+        interfaceTarget: node.interfaceTarget);
+  }
+
+  @override
+  TypeInformation visitDynamicSet(ir.DynamicSet node) {
+    return _handlePropertySet(node, node.receiver, node.value);
+  }
+
+  @override
+  TypeInformation visitThisExpression(ir.ThisExpression node) {
+    return thisType;
+  }
+
+  TypeInformation handleCondition(ir.Node node) {
+    return visit(node, conditionContext: true);
+  }
+
+  void _potentiallyAddIsCheck(ir.IsExpression node) {
+    if (!_accumulateIsChecks) return;
+    ir.Expression operand = node.operand;
+    if (operand is ir.VariableGet) {
+      Local local = _localsMap.getLocalVariable(operand.variable);
+      DartType localType = _elementMap.getDartType(node.type);
+      LocalState stateAfterCheckWhenTrue = LocalState.childPath(_state);
+      LocalState stateAfterCheckWhenFalse = LocalState.childPath(_state);
+
+      // Narrow variable to tested type on true branch.
+      TypeInformation currentTypeInformation = stateAfterCheckWhenTrue
+          .readLocal(_inferrer, _capturedAndBoxed, local);
+      stateAfterCheckWhenTrue.updateLocal(_inferrer, _capturedAndBoxed, local,
+          currentTypeInformation, localType,
+          isCast: false);
+      _setStateAfter(_state, stateAfterCheckWhenTrue, stateAfterCheckWhenFalse);
+    }
+  }
+
+  void _potentiallyAddNullCheck(ir.Expression receiver) {
+    if (!_accumulateIsChecks) return;
+    if (receiver is ir.VariableGet) {
+      Local local = _localsMap.getLocalVariable(receiver.variable);
+      DartType localType = _localsMap.getLocalType(_elementMap, local);
+      LocalState stateAfterCheckWhenNull = LocalState.childPath(_state);
+      LocalState stateAfterCheckWhenNotNull = LocalState.childPath(_state);
+
+      // Narrow tested variable to 'Null' on true branch.
+      stateAfterCheckWhenNull.updateLocal(
+          _inferrer, _capturedAndBoxed, local, _types.nullType, localType);
+
+      // Narrow tested variable to 'not null' on false branch.
+      TypeInformation currentTypeInformation = stateAfterCheckWhenNotNull
+          .readLocal(_inferrer, _capturedAndBoxed, local);
+      stateAfterCheckWhenNotNull.updateLocal(_inferrer, _capturedAndBoxed,
+          local, currentTypeInformation, _closedWorld.commonElements.objectType,
+          excludeNull: true);
+      _setStateAfter(
+          _state, stateAfterCheckWhenNull, stateAfterCheckWhenNotNull);
+    }
+  }
+
+  @override
+  TypeInformation visitIfStatement(ir.IfStatement node) {
+    LocalState stateBefore = _state;
+    handleCondition(node.condition);
+    LocalState stateAfterConditionWhenTrue = _stateAfterWhenTrue;
+    LocalState stateAfterConditionWhenFalse = _stateAfterWhenFalse;
+    _state = LocalState.childPath(stateAfterConditionWhenTrue);
+    visit(node.then);
+    LocalState stateAfterThen = _state;
+    _state = LocalState.childPath(stateAfterConditionWhenFalse);
+    visit(node.otherwise);
+    LocalState stateAfterElse = _state;
+    _state =
+        stateBefore.mergeDiamondFlow(_inferrer, stateAfterThen, stateAfterElse);
+    return null;
+  }
+
+  @override
+  TypeInformation visitIsExpression(ir.IsExpression node) {
+    visit(node.operand);
+    _potentiallyAddIsCheck(node);
+    return _types.boolType;
+  }
+
+  @override
+  TypeInformation visitNot(ir.Not node) {
+    visit(node.operand, conditionContext: _accumulateIsChecks);
+    LocalState stateAfterOperandWhenTrue = _stateAfterWhenTrue;
+    LocalState stateAfterOperandWhenFalse = _stateAfterWhenFalse;
+    _setStateAfter(
+        _state, stateAfterOperandWhenFalse, stateAfterOperandWhenTrue);
+    // TODO(sra): Improve precision on constant and bool-conversion-to-constant
+    // inputs.
+    return _types.boolType;
+  }
+
+  @override
+  TypeInformation visitLogicalExpression(ir.LogicalExpression node) {
+    if (node.operatorEnum == ir.LogicalExpressionOperator.AND) {
+      LocalState stateBefore = _state;
+      _state = LocalState.childPath(stateBefore);
+      TypeInformation leftInfo = handleCondition(node.left);
+      LocalState stateAfterLeftWhenTrue = _stateAfterWhenTrue;
+      LocalState stateAfterLeftWhenFalse = _stateAfterWhenFalse;
+      _state = LocalState.childPath(stateAfterLeftWhenTrue);
+      TypeInformation rightInfo = handleCondition(node.right);
+      LocalState stateAfterRightWhenTrue = _stateAfterWhenTrue;
+      LocalState stateAfterRightWhenFalse = _stateAfterWhenFalse;
+      LocalState stateAfterWhenTrue = stateAfterRightWhenTrue;
+      LocalState stateAfterWhenFalse = LocalState.childPath(stateBefore)
+          .mergeDiamondFlow(
+              _inferrer, stateAfterLeftWhenFalse, stateAfterRightWhenFalse);
+      LocalState after = stateBefore.mergeDiamondFlow(
+          _inferrer, stateAfterWhenTrue, stateAfterWhenFalse);
+      _setStateAfter(after, stateAfterWhenTrue, stateAfterWhenFalse);
+      // Constant-fold result.
+      if (_types.isLiteralFalse(leftInfo)) return leftInfo;
+      if (_types.isLiteralTrue(leftInfo)) {
+        if (_types.isLiteralFalse(rightInfo)) return rightInfo;
+        if (_types.isLiteralTrue(rightInfo)) return rightInfo;
+      }
+      // TODO(sra): Add a selector/mux node to improve precision.
+      return _types.boolType;
+    } else if (node.operatorEnum == ir.LogicalExpressionOperator.OR) {
+      LocalState stateBefore = _state;
+      _state = LocalState.childPath(stateBefore);
+      TypeInformation leftInfo = handleCondition(node.left);
+      LocalState stateAfterLeftWhenTrue = _stateAfterWhenTrue;
+      LocalState stateAfterLeftWhenFalse = _stateAfterWhenFalse;
+      _state = LocalState.childPath(stateAfterLeftWhenFalse);
+      TypeInformation rightInfo = handleCondition(node.right);
+      LocalState stateAfterRightWhenTrue = _stateAfterWhenTrue;
+      LocalState stateAfterRightWhenFalse = _stateAfterWhenFalse;
+      LocalState stateAfterWhenTrue = LocalState.childPath(stateBefore)
+          .mergeDiamondFlow(
+              _inferrer, stateAfterLeftWhenTrue, stateAfterRightWhenTrue);
+      LocalState stateAfterWhenFalse = stateAfterRightWhenFalse;
+      LocalState stateAfter = stateBefore.mergeDiamondFlow(
+          _inferrer, stateAfterWhenTrue, stateAfterWhenFalse);
+      _setStateAfter(stateAfter, stateAfterWhenTrue, stateAfterWhenFalse);
+      // Constant-fold result.
+      if (_types.isLiteralTrue(leftInfo)) return leftInfo;
+      if (_types.isLiteralFalse(leftInfo)) {
+        if (_types.isLiteralTrue(rightInfo)) return rightInfo;
+        if (_types.isLiteralFalse(rightInfo)) return rightInfo;
+      }
+      // TODO(sra): Add a selector/mux node to improve precision.
+      return _types.boolType;
+    }
+    failedAt(CURRENT_ELEMENT_SPANNABLE,
+        "Unexpected logical operator '${node.operatorEnum}'.");
+  }
+
+  @override
+  TypeInformation visitConditionalExpression(ir.ConditionalExpression node) {
+    LocalState stateBefore = _state;
+    handleCondition(node.condition);
+    LocalState stateAfterWhenTrue = _stateAfterWhenTrue;
+    LocalState stateAfterWhenFalse = _stateAfterWhenFalse;
+    _state = LocalState.childPath(stateAfterWhenTrue);
+    TypeInformation firstType = visit(node.then);
+    LocalState stateAfterThen = _state;
+    _state = LocalState.childPath(stateAfterWhenFalse);
+    TypeInformation secondType = visit(node.otherwise);
+    LocalState stateAfterElse = _state;
+    _state =
+        stateBefore.mergeDiamondFlow(_inferrer, stateAfterThen, stateAfterElse);
+    return _types.allocateDiamondPhi(firstType, secondType);
+  }
+
+  TypeInformation handleLocalFunction(
+      ir.TreeNode node, ir.FunctionNode functionNode,
+      [ir.VariableDeclaration variable]) {
+    // We loose track of [this] in closures (see issue 20840). To be on
+    // the safe side, we mark [this] as exposed here. We could do better by
+    // analyzing the closure.
+    // TODO(herhut): Analyze whether closure exposes this. Possibly using
+    // whether the created closure as a `thisLocal`.
+    _state.markThisAsExposed();
+
+    ClosureRepresentationInfo info = _closureDataLookup.getClosureInfo(node);
+
+    // Record the types of captured non-boxed variables. Types of
+    // these variables may already be there, because of an analysis of
+    // a previous closure.
+    info.forEachFreeVariable(_localsMap, (Local variable, FieldEntity field) {
+      if (!info.isBoxedVariable(_localsMap, variable)) {
+        if (variable == info.thisLocal) {
+          _inferrer.recordTypeOfField(field, thisType);
+        }
+        TypeInformation localType =
+            _state.readLocal(_inferrer, _capturedAndBoxed, variable);
+        // The type is null for type parameters.
+        if (localType != null) {
+          _inferrer.recordTypeOfField(field, localType);
+        }
+      }
+      _capturedVariables.add(variable);
+    });
+
+    TypeInformation localFunctionType =
+        _inferrer.concreteTypes.putIfAbsent(node, () {
+      return _types.allocateClosure(info.callMethod);
+    });
+    if (variable != null) {
+      Local local = _localsMap.getLocalVariable(variable);
+      DartType type = _localsMap.getLocalType(_elementMap, local);
+      _state.updateLocal(
+          _inferrer, _capturedAndBoxed, local, localFunctionType, type,
+          excludeNull: true);
+    }
+
+    // We don't put the closure in the work queue of the
+    // inferrer, because it will share information with its enclosing
+    // method, like for example the types of local variables.
+    LocalState closureState = LocalState.closure(_state);
+    KernelTypeGraphBuilder visitor = KernelTypeGraphBuilder(
+        _options,
+        _closedWorld,
+        _inferrer,
+        info.callMethod,
+        functionNode,
+        _localsMap,
+        _staticTypeProvider,
+        closureState,
+        _capturedAndBoxed);
+    visitor.run();
+    _inferrer.recordReturnType(info.callMethod, visitor._returnType);
+
+    return localFunctionType;
+  }
+
+  @override
+  TypeInformation visitFunctionDeclaration(ir.FunctionDeclaration node) {
+    return handleLocalFunction(node, node.function, node.variable);
+  }
+
+  @override
+  TypeInformation visitFunctionExpression(ir.FunctionExpression node) {
+    return handleLocalFunction(node, node.function);
+  }
+
+  @override
+  visitWhileStatement(ir.WhileStatement node) {
+    return handleLoop(node, _localsMap.getJumpTargetForWhile(node), () {
+      handleCondition(node.condition);
+      _state = LocalState.childPath(_stateAfterWhenTrue);
+      visit(node.body);
+    });
+  }
+
+  @override
+  visitDoStatement(ir.DoStatement node) {
+    return handleLoop(node, _localsMap.getJumpTargetForDo(node), () {
+      visit(node.body);
+      handleCondition(node.condition);
+      // TODO(29309): This condition appears to strengthen both the back-edge
+      // and exit-edge. For now, avoid strengthening on the condition until the
+      // proper fix is found.
+      //
+      //     _state = new LocalState.childPath(_stateAfterWhenTrue, node.body);
+    });
+  }
+
+  @override
+  visitForStatement(ir.ForStatement node) {
+    for (ir.VariableDeclaration variable in node.variables) {
+      visit(variable);
+    }
+    return handleLoop(node, _localsMap.getJumpTargetForFor(node), () {
+      handleCondition(node.condition);
+      _state = LocalState.childPath(_stateAfterWhenTrue);
+      visit(node.body);
+      for (ir.Expression update in node.updates) {
+        visit(update);
+      }
+    });
+  }
+
+  @override
+  visitTryCatch(ir.TryCatch node) {
+    LocalState stateBefore = _state;
+    _state = LocalState.tryBlock(stateBefore, node);
+    _state.markInitializationAsIndefinite();
+    visit(node.body);
+    LocalState stateAfterBody = _state;
+    // If the try block contains a throw, then `stateAfterBody.aborts` will be
+    // true. The catch needs to be aware of the results of inference from the
+    // try block since we may get there via the abortive control flow:
+    //
+    // dynamic x = "bad";
+    // try {
+    //   ...
+    //   x = 0;
+    //   throw ...;
+    // } catch (_) {
+    //   print(x + 42); <-- x may be 0 here.
+    // }
+    //
+    // Note that this will also cause us to ignore aborts due to breaks,
+    // returns, and continues. Since these control flow constructs will not jump
+    // to a catch block, this may cause some types flowing into the catch block
+    // to be wider than necessary:
+    //
+    // dynamic x = "bad";
+    // try {
+    //   x = 0;
+    //   return;
+    // } catch (_) {
+    //   print(x + 42); <-- x cannot be 0 here.
+    // }
+    _state =
+        stateBefore.mergeFlow(_inferrer, stateAfterBody, ignoreAborts: true);
+    for (ir.Catch catchBlock in node.catches) {
+      LocalState stateBeforeCatch = _state;
+      _state = LocalState.childPath(stateBeforeCatch);
+      visit(catchBlock);
+      LocalState stateAfterCatch = _state;
+      _state = stateBeforeCatch.mergeFlow(_inferrer, stateAfterCatch);
+    }
+    return null;
+  }
+
+  @override
+  visitTryFinally(ir.TryFinally node) {
+    LocalState stateBefore = _state;
+    _state = LocalState.tryBlock(stateBefore, node);
+    _state.markInitializationAsIndefinite();
+    visit(node.body);
+    LocalState stateAfterBody = _state;
+    // Even if the try block contains abortive control flow, the finally block
+    // needs to be aware of the results of inference from the try block since we
+    // still reach the finally after abortive control flow:
+    //
+    // dynamic x = "bad";
+    // try {
+    //   ...
+    //   x = 0;
+    //   return;
+    // } finally {
+    //   print(x + 42); <-- x may be 0 here.
+    // }
+    _state =
+        stateBefore.mergeFlow(_inferrer, stateAfterBody, ignoreAborts: true);
+    visit(node.finalizer);
+    return null;
+  }
+
+  @override
+  visitCatch(ir.Catch node) {
+    ir.VariableDeclaration exception = node.exception;
+    if (exception != null) {
+      TypeInformation mask;
+      DartType type = node.guard != null
+          ? _elementMap.getDartType(node.guard).withoutNullability
+          : _dartTypes.dynamicType();
+      if (type is InterfaceType) {
+        InterfaceType interfaceType = type;
+        mask = _types.nonNullSubtype(interfaceType.element);
+      } else {
+        mask = _types.dynamicType;
+      }
+      Local local = _localsMap.getLocalVariable(exception);
+      _state.updateLocal(
+          _inferrer, _capturedAndBoxed, local, mask, _dartTypes.dynamicType(),
+          excludeNull: true /* `throw null` produces a NullThrownError */);
+    }
+    ir.VariableDeclaration stackTrace = node.stackTrace;
+    if (stackTrace != null) {
+      Local local = _localsMap.getLocalVariable(stackTrace);
+      // TODO(johnniwinther): Use a mask based on [StackTrace].
+      // Note: stack trace may be null if users omit a stack in
+      // `completer.completeError`.
+      _state.updateLocal(_inferrer, _capturedAndBoxed, local,
+          _types.dynamicType, _dartTypes.dynamicType());
+    }
+    visit(node.body);
+    return null;
+  }
+
+  @override
+  TypeInformation visitThrow(ir.Throw node) {
+    visit(node.expression);
+    _state.seenReturnOrThrow = true;
+    return _types.nonNullEmpty();
+  }
+
+  @override
+  TypeInformation visitRethrow(ir.Rethrow node) {
+    _state.seenReturnOrThrow = true;
+    return _types.nonNullEmpty();
+  }
+
+  TypeInformation handleSuperNoSuchMethod(
+      ir.Node node, Selector selector, ArgumentsTypes arguments) {
+    // Ensure we create a node, to make explicit the call to the
+    // `noSuchMethod` handler.
+    FunctionEntity noSuchMethod =
+        _elementMap.getSuperNoSuchMethod(_analyzedMember.enclosingClass);
+    return handleStaticInvoke(node, selector, noSuchMethod, arguments);
+  }
+
+  @override
+  TypeInformation visitSuperPropertyGet(ir.SuperPropertyGet node) {
+    // TODO(herhut): We could do better here if we knew what we
+    // are calling does not expose this.
+    _state.markThisAsExposed();
+
+    ir.Member target = getEffectiveSuperTarget(node.interfaceTarget);
+    Selector selector = Selector.getter(_elementMap.getName(node.name));
+    if (target == null) {
+      // TODO(johnniwinther): Remove this when the CFE checks for missing
+      //  concrete super targets.
+      // TODO(48820): If this path is infeasible, update types on
+      //  getEffectiveSuperTarget.
+      return handleSuperNoSuchMethod(node, selector, null);
+    }
+    MemberEntity member = _elementMap.getMember(target);
+    assert(member != null, "No member found for super property get: $node");
+    TypeInformation type = handleStaticInvoke(node, selector, member, null);
+    if (member.isGetter) {
+      FunctionType functionType =
+          _elementMap.elementEnvironment.getFunctionType(member);
+      if (functionType.returnType.containsFreeTypeVariables) {
+        // The result type varies with the call site so we narrow the static
+        // result type.
+        type = _types.narrowType(type, _getStaticType(node));
+      }
+    } else if (member.isField) {
+      DartType fieldType = _elementMap.elementEnvironment.getFieldType(member);
+      if (fieldType.containsFreeTypeVariables) {
+        // The result type varies with the call site so we narrow the static
+        // result type.
+        type = _types.narrowType(type, _getStaticType(node));
+      }
+    }
+    return type;
+  }
+
+  @override
+  TypeInformation visitSuperPropertySet(ir.SuperPropertySet node) {
+    // TODO(herhut): We could do better here if we knew what we
+    // are calling does not expose this.
+    _state.markThisAsExposed();
+
+    TypeInformation rhsType = visit(node.value);
+    ir.Member target = getEffectiveSuperTarget(node.interfaceTarget);
+    Selector selector = Selector.setter(_elementMap.getName(node.name));
+    ArgumentsTypes arguments = ArgumentsTypes([rhsType], null);
+    if (target == null) {
+      // TODO(johnniwinther): Remove this when the CFE checks for missing
+      //  concrete super targets.
+      return handleSuperNoSuchMethod(node, selector, arguments);
+    }
+    MemberEntity member = _elementMap.getMember(target);
+    assert(member != null, "No member found for super property set: $node");
+    handleStaticInvoke(node, selector, member, arguments);
+    return rhsType;
+  }
+
+  @override
+  TypeInformation visitSuperMethodInvocation(ir.SuperMethodInvocation node) {
+    // TODO(herhut): We could do better here if we knew what we
+    // are calling does not expose this.
+    _state.markThisAsExposed();
+
+    ir.Member target = getEffectiveSuperTarget(node.interfaceTarget);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    Selector selector = _elementMap.getSelector(node);
+    if (target == null) {
+      // TODO(johnniwinther): Remove this when the CFE checks for missing
+      //  concrete super targets.
+      return handleSuperNoSuchMethod(node, selector, arguments);
+    }
+    MemberEntity member = _elementMap.getMember(target);
+    assert(member.isFunction, "Unexpected super invocation target: $member");
+    if (isIncompatibleInvoke(member, arguments)) {
+      return handleSuperNoSuchMethod(node, selector, arguments);
+    } else {
+      TypeInformation type =
+          handleStaticInvoke(node, selector, member, arguments);
+      FunctionType functionType =
+          _elementMap.elementEnvironment.getFunctionType(member);
+      if (functionType.returnType.containsFreeTypeVariables) {
+        // The return type varies with the call site so we narrow the static
+        // return type.
+        type = _types.narrowType(type, _getStaticType(node));
+      }
+      return type;
+    }
+  }
+
+  @override
+  TypeInformation visitAsExpression(ir.AsExpression node) {
+    TypeInformation operandType = visit(node.operand);
+    return _types.narrowType(operandType, _elementMap.getDartType(node.type));
+  }
+
+  @override
+  TypeInformation visitNullCheck(ir.NullCheck node) {
+    TypeInformation operandType = visit(node.operand);
+    return _types.narrowType(operandType, _getStaticType(node));
+  }
+
+  @override
+  TypeInformation visitAwaitExpression(ir.AwaitExpression node) {
+    TypeInformation futureType = visit(node.operand);
+    return _inferrer.registerAwait(node, futureType);
+  }
+
+  @override
+  TypeInformation visitYieldStatement(ir.YieldStatement node) {
+    TypeInformation operandType = visit(node.expression);
+    return _inferrer.registerYield(node, operandType);
+  }
+
+  @override
+  TypeInformation visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded node) {
+    return _types.nonNullEmpty();
+  }
+
+  @override
+  TypeInformation visitInvalidExpression(ir.InvalidExpression node) {
+    // TODO(johnniwinther): Maybe this should be [empty] instead?
+    return _types.dynamicType;
+  }
+
+  @override
+  TypeInformation visitConstantExpression(ir.ConstantExpression node) {
+    return TypeInformationConstantVisitor(this, node)
+        .visitConstant(node.constant);
+  }
+}
+
+class TypeInformationConstantVisitor
+    extends ir.ComputeOnceConstantVisitor<TypeInformation> {
+  final KernelTypeGraphBuilder builder;
+  final ir.ConstantExpression expression;
+
+  TypeInformationConstantVisitor(this.builder, this.expression);
+
+  @override
+  TypeInformation defaultConstant(ir.Constant node) {
+    throw UnsupportedError("Unexpected constant: "
+        "${node} (${node.runtimeType})");
+  }
+
+  @override
+  TypeInformation visitNullConstant(ir.NullConstant node) {
+    return builder.createNullTypeInformation();
+  }
+
+  @override
+  TypeInformation visitBoolConstant(ir.BoolConstant node) {
+    return builder.createBoolTypeInformation(node.value);
+  }
+
+  @override
+  TypeInformation visitIntConstant(ir.IntConstant node) {
+    return builder.createIntTypeInformation(node.value);
+  }
+
+  @override
+  TypeInformation visitDoubleConstant(ir.DoubleConstant node) {
+    return builder.createDoubleTypeInformation(node.value);
+  }
+
+  @override
+  TypeInformation visitStringConstant(ir.StringConstant node) {
+    return builder.createStringTypeInformation(node.value);
+  }
+
+  @override
+  TypeInformation visitSymbolConstant(ir.SymbolConstant node) {
+    return builder.createSymbolLiteralTypeInformation();
+  }
+
+  @override
+  TypeInformation visitMapConstant(ir.MapConstant node) {
+    return builder.createMapTypeInformation(
+        ConstantReference(expression, node),
+        node.entries
+            .map((e) => Pair(visitConstant(e.key), visitConstant(e.value))),
+        isConst: true);
+  }
+
+  @override
+  TypeInformation visitListConstant(ir.ListConstant node) {
+    return builder.createListTypeInformation(
+        ConstantReference(expression, node),
+        node.entries.map((e) => visitConstant(e)),
+        isConst: true);
+  }
+
+  @override
+  TypeInformation visitSetConstant(ir.SetConstant node) {
+    return builder.createSetTypeInformation(ConstantReference(expression, node),
+        node.entries.map((e) => visitConstant(e)),
+        isConst: true);
+  }
+
+  @override
+  TypeInformation visitRecordConstant(ir.RecordConstant node) {
+    return defaultConstant(node);
+  }
+
+  @override
+  TypeInformation visitInstanceConstant(ir.InstanceConstant node) {
+    node.fieldValues.forEach((ir.Reference reference, ir.Constant value) {
+      builder._inferrer.recordTypeOfField(
+          builder._elementMap.getField(reference.asField),
+          visitConstant(value));
+    });
+    return builder._types.getConcreteTypeFor(builder
+        ._closedWorld.abstractValueDomain
+        .createNonNullExact(builder._elementMap.getClass(node.classNode)));
+  }
+
+  @override
+  TypeInformation visitInstantiationConstant(ir.InstantiationConstant node) {
+    return builder.createInstantiationTypeInformation(
+        visitConstant(node.tearOffConstant));
+  }
+
+  @override
+  TypeInformation visitStaticTearOffConstant(ir.StaticTearOffConstant node) {
+    return builder.createStaticGetTypeInformation(node, node.target);
+  }
+
+  @override
+  TypeInformation visitTypeLiteralConstant(ir.TypeLiteralConstant node) {
+    return builder.createTypeLiteralInformation();
+  }
+
+  @override
+  TypeInformation visitUnevaluatedConstant(ir.UnevaluatedConstant node) {
+    assert(false, "Unexpected unevaluated constant: $node");
+    return builder._types.dynamicType;
+  }
+}
+
+class Refinement {
+  final Selector selector;
+  final AbstractValue mask;
+
+  Refinement(this.selector, this.mask);
+}
+
+class LocalState {
+  final LocalsHandler _locals;
+  final FieldInitializationScope _fields;
+  bool seenReturnOrThrow = false;
+  bool seenBreakOrContinue = false;
+  LocalsHandler _tryBlock;
+
+  LocalState.initial({bool inGenerativeConstructor})
+      : this.internal(LocalsHandler(),
+            inGenerativeConstructor ? FieldInitializationScope() : null, null,
+            seenReturnOrThrow: false, seenBreakOrContinue: false);
+
+  LocalState.childPath(LocalState other)
+      : this.internal(LocalsHandler.from(other._locals),
+            FieldInitializationScope.from(other._fields), other._tryBlock,
+            seenReturnOrThrow: false, seenBreakOrContinue: false);
+
+  LocalState.closure(LocalState other)
+      : this.internal(LocalsHandler.from(other._locals),
+            FieldInitializationScope.from(other._fields), null,
+            seenReturnOrThrow: false, seenBreakOrContinue: false);
+
+  factory LocalState.tryBlock(LocalState other, ir.TreeNode node) {
+    LocalsHandler locals = LocalsHandler.tryBlock(other._locals, node);
+    FieldInitializationScope fieldScope =
+        FieldInitializationScope.from(other._fields);
+    LocalsHandler tryBlock = locals;
+    return LocalState.internal(locals, fieldScope, tryBlock,
+        seenReturnOrThrow: false, seenBreakOrContinue: false);
+  }
+
+  LocalState.deepCopyOf(LocalState other)
+      : _locals = LocalsHandler.deepCopyOf(other._locals),
+        _tryBlock = other._tryBlock,
+        _fields = other._fields;
+
+  LocalState.internal(this._locals, this._fields, this._tryBlock,
+      {this.seenReturnOrThrow, this.seenBreakOrContinue});
+
+  bool get aborts {
+    return seenReturnOrThrow || seenBreakOrContinue;
+  }
+
+  bool get isThisExposed {
+    return _fields == null || _fields.isThisExposed;
+  }
+
+  void markThisAsExposed() {
+    _fields?.isThisExposed = true;
+  }
+
+  void markInitializationAsIndefinite() {
+    _fields?.isIndefinite = true;
+  }
+
+  TypeInformation readField(FieldEntity field) {
+    return _fields.readField(field);
+  }
+
+  void updateField(FieldEntity field, TypeInformation type) {
+    _fields.updateField(field, type);
+  }
+
+  TypeInformation readLocal(InferrerEngine inferrer,
+      Map<Local, FieldEntity> capturedAndBoxed, Local local) {
+    FieldEntity field = capturedAndBoxed[local];
+    if (field != null) {
+      return inferrer.typeOfMember(field);
+    } else {
+      return _locals.use(local);
+    }
+  }
+
+  void updateLocal(
+      InferrerEngine inferrer,
+      Map<Local, FieldEntity> capturedAndBoxed,
+      Local local,
+      TypeInformation type,
+      DartType staticType,
+      {isCast = true,
+      excludeNull = false,
+      excludeLateSentinel = false}) {
+    assert(type != null);
+    type = inferrer.types.narrowType(type, staticType,
+        isCast: isCast,
+        excludeNull: excludeNull,
+        excludeLateSentinel: excludeLateSentinel);
+
+    FieldEntity field = capturedAndBoxed[local];
+    if (field != null) {
+      inferrer.recordTypeOfField(field, type);
+    } else {
+      _locals.update(inferrer, local, type, _tryBlock);
+    }
+  }
+
+  LocalState mergeFlow(InferrerEngine inferrer, LocalState other,
+      {bool ignoreAborts = false}) {
+    seenReturnOrThrow = false;
+    seenBreakOrContinue = false;
+
+    if (!ignoreAborts && other.aborts) {
+      return this;
+    }
+    LocalsHandler locals = _locals.mergeFlow(inferrer, other._locals);
+    return LocalState.internal(locals, _fields, _tryBlock,
+        seenReturnOrThrow: seenReturnOrThrow,
+        seenBreakOrContinue: seenBreakOrContinue);
+  }
+
+  LocalState mergeDiamondFlow(
+      InferrerEngine inferrer, LocalState thenBranch, LocalState elseBranch) {
+    seenReturnOrThrow =
+        thenBranch.seenReturnOrThrow && elseBranch.seenReturnOrThrow;
+    seenBreakOrContinue =
+        thenBranch.seenBreakOrContinue && elseBranch.seenBreakOrContinue;
+
+    LocalsHandler locals;
+    if (aborts) {
+      locals = _locals;
+    } else if (thenBranch.aborts) {
+      locals = _locals.mergeFlow(inferrer, elseBranch._locals, inPlace: true);
+    } else if (elseBranch.aborts) {
+      locals = _locals.mergeFlow(inferrer, thenBranch._locals, inPlace: true);
+    } else {
+      locals = _locals.mergeDiamondFlow(
+          inferrer, thenBranch._locals, elseBranch._locals);
+    }
+
+    FieldInitializationScope fieldScope = _fields?.mergeDiamondFlow(
+        inferrer, thenBranch._fields, elseBranch._fields);
+    return LocalState.internal(locals, fieldScope, _tryBlock,
+        seenReturnOrThrow: seenReturnOrThrow,
+        seenBreakOrContinue: seenBreakOrContinue);
+  }
+
+  LocalState mergeAfterBreaks(InferrerEngine inferrer, List<LocalState> states,
+      {bool keepOwnLocals = true}) {
+    bool allBranchesAbort = true;
+    for (LocalState state in states) {
+      allBranchesAbort = allBranchesAbort && state.seenReturnOrThrow;
+    }
+
+    keepOwnLocals = keepOwnLocals && !seenReturnOrThrow;
+
+    LocalsHandler locals = _locals.mergeAfterBreaks(
+        inferrer,
+        states
+            .where((LocalState state) => !state.seenReturnOrThrow)
+            .map((LocalState state) => state._locals),
+        keepOwnLocals: keepOwnLocals);
+    seenReturnOrThrow = allBranchesAbort && !keepOwnLocals;
+    return LocalState.internal(locals, _fields, _tryBlock,
+        seenReturnOrThrow: seenReturnOrThrow,
+        seenBreakOrContinue: seenBreakOrContinue);
+  }
+
+  bool mergeAll(InferrerEngine inferrer, List<LocalState> states) {
+    assert(!seenReturnOrThrow);
+    return _locals.mergeAll(
+        inferrer,
+        states
+            .where((LocalState state) => !state.seenReturnOrThrow)
+            .map((LocalState state) => state._locals));
+  }
+
+  void startLoop(InferrerEngine inferrer, ir.Node loop) {
+    _locals.startLoop(inferrer, loop);
+  }
+
+  void endLoop(InferrerEngine inferrer, ir.Node loop) {
+    _locals.endLoop(inferrer, loop);
+  }
+
+  String toStructuredText(String indent) {
+    StringBuffer sb = StringBuffer();
+    _toStructuredText(sb, indent);
+    return sb.toString();
+  }
+
+  void _toStructuredText(StringBuffer sb, String indent) {
+    sb.write('LocalState($hashCode) [');
+    sb.write('\n${indent}  locals:');
+    sb.write(_locals.toStructuredText('${indent}    '));
+    sb.write('\n]');
+  }
+
+  @override
+  String toString() {
+    StringBuffer sb = StringBuffer();
+    sb.write('LocalState(');
+    sb.write('locals=$_locals');
+    if (_fields != null) {
+      sb.write(',fields=$_fields');
+    }
+    if (seenReturnOrThrow) {
+      sb.write(',seenReturnOrThrow');
+    }
+    if (seenBreakOrContinue) {
+      sb.write(',seenBreakOrContinue');
+    }
+    sb.write(')');
+    return sb.toString();
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/closure_tracer.dart b/pkg/compiler/lib/src/inferrer_experimental/closure_tracer.dart
new file mode 100644
index 0000000..93938d9
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/closure_tracer.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library compiler.src.inferrer.closure_tracer;
+
+import '../common/names.dart' show Identifiers, Names;
+import '../elements/entities.dart';
+import 'debug.dart' as debug;
+import 'engine_interfaces.dart';
+import 'node_tracer.dart';
+import 'type_graph_nodes.dart';
+
+class ClosureTracerVisitor extends TracerVisitor {
+  final Iterable<FunctionEntity> tracedElements;
+  final List<CallSiteTypeInformation> _callsToAnalyze =
+      <CallSiteTypeInformation>[];
+
+  ClosureTracerVisitor(this.tracedElements, ApplyableTypeInformation tracedType,
+      InferrerEngine inferrer)
+      : super(tracedType, inferrer) {
+    assert(
+        tracedElements.every((f) => !f.isAbstract),
+        "Tracing abstract methods: "
+        "${tracedElements.where((f) => f.isAbstract)}");
+  }
+
+  @override
+  ApplyableTypeInformation get tracedType =>
+      super.tracedType as ApplyableTypeInformation;
+
+  void run() {
+    analyze();
+    if (!continueAnalyzing) return;
+    _callsToAnalyze.forEach(_analyzeCall);
+    for (FunctionEntity element in tracedElements) {
+      inferrer.types.strategy.forEachParameter(element, (Local parameter) {
+        ElementTypeInformation info =
+            inferrer.types.getInferredTypeOfParameter(parameter);
+        info.disableInferenceForClosures = false;
+      });
+    }
+  }
+
+  void _tagAsFunctionApplyTarget([String? reason]) {
+    tracedType.mightBePassedToFunctionApply = true;
+    if (debug.VERBOSE) {
+      print("Closure $tracedType might be passed to apply: $reason");
+    }
+  }
+
+  void _registerCallForLaterAnalysis(CallSiteTypeInformation info) {
+    _callsToAnalyze.add(info);
+  }
+
+  void _analyzeCall(CallSiteTypeInformation info) {
+    final selector = info.selector!;
+    tracedElements.forEach((FunctionEntity functionElement) {
+      if (!selector.callStructure
+          .signatureApplies(functionElement.parameterStructure)) {
+        return;
+      }
+      inferrer.updateParameterInputs(
+          info, functionElement, info.arguments, selector,
+          remove: false, addToQueue: false);
+    });
+  }
+
+  @override
+  visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
+    super.visitClosureCallSiteTypeInformation(info);
+    if (info.closure == currentUser) {
+      _registerCallForLaterAnalysis(info);
+    } else {
+      bailout('Passed to a closure');
+    }
+  }
+
+  @override
+  visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+    super.visitStaticCallSiteTypeInformation(info);
+    MemberEntity called = info.calledElement;
+    if (inferrer.closedWorld.commonElements.isForeign(called)) {
+      final name = called.name!;
+      if (name == Identifiers.JS || name == Identifiers.DART_CLOSURE_TO_JS) {
+        bailout('Used in JS ${info.debugName}');
+      } else if (name == Identifiers.RAW_DART_FUNCTION_REF) {
+        bailout('Escaped raw function reference');
+      }
+    }
+
+    final selector = info.selector;
+    if (called.isGetter &&
+        selector != null &&
+        selector.isCall &&
+        inferrer.types.getInferredTypeOfMember(called) == currentUser) {
+      // This node can be a closure call as well. For example, `foo()`
+      // where `foo` is a getter.
+      _registerCallForLaterAnalysis(info);
+    }
+
+    final arguments = info.arguments;
+    if (_checkIfFunctionApply(called) &&
+        arguments != null &&
+        arguments.contains(currentUser)) {
+      _tagAsFunctionApplyTarget("static call");
+    }
+  }
+
+  bool _checkIfCurrentUser(MemberEntity element) =>
+      inferrer.types.getInferredTypeOfMember(element) == currentUser;
+
+  bool _checkIfFunctionApply(MemberEntity element) {
+    return inferrer.closedWorld.commonElements.isFunctionApplyMethod(element);
+  }
+
+  @override
+  visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
+    super.visitDynamicCallSiteTypeInformation(info);
+    final selector = info.selector!;
+    if (selector.isCall) {
+      if (info.arguments!.contains(currentUser)) {
+        if (info.hasClosureCallTargets ||
+            info.concreteTargets.any((element) => !element.isFunction)) {
+          bailout('Passed to a closure');
+        }
+        if (info.concreteTargets.any(_checkIfFunctionApply)) {
+          _tagAsFunctionApplyTarget("dynamic call");
+        }
+      } else if (info.concreteTargets.any(_checkIfCurrentUser)) {
+        _registerCallForLaterAnalysis(info);
+      }
+    } else if (selector.isGetter && selector.memberName == Names.call) {
+      // We are potentially tearing off ourself here
+      addNewEscapeInformation(info);
+    }
+  }
+}
+
+class StaticTearOffClosureTracerVisitor extends ClosureTracerVisitor {
+  StaticTearOffClosureTracerVisitor(
+      FunctionEntity tracedElement, tracedType, inferrer)
+      : super([tracedElement], tracedType, inferrer);
+
+  @override
+  visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+    super.visitStaticCallSiteTypeInformation(info);
+
+    final selector = info.selector;
+    if (info.calledElement == tracedElements.first &&
+        selector != null &&
+        selector.isGetter) {
+      addNewEscapeInformation(info);
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/debug.dart b/pkg/compiler/lib/src/inferrer_experimental/debug.dart
new file mode 100644
index 0000000..def9a7d
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/debug.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2015, 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.
+
+/// Values used only for debugging type inference.
+library compiler.src.inferrer.debug;
+
+const bool VERBOSE = false;
+const bool PRINT_SUMMARY = false;
+const bool ANOMALY_WARN = false;
+bool PRINT_GRAPH = false;
+bool PRINT_GRAPH_ALL_NODES = false; // Include useless nodes?
diff --git a/pkg/compiler/lib/src/inferrer_experimental/engine.dart b/pkg/compiler/lib/src/inferrer_experimental/engine.dart
new file mode 100644
index 0000000..e84c869
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/engine.dart
@@ -0,0 +1,1447 @@
+// Copyright (c) 2017, 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.10
+
+import 'package:kernel/ast.dart' as ir;
+
+import '../../compiler_api.dart' as api;
+import '../closure.dart';
+import '../common.dart';
+import '../common/elements.dart';
+import '../common/metrics.dart';
+import '../common/names.dart';
+import '../compiler.dart';
+import '../constants/values.dart';
+import '../elements/entities.dart';
+import '../elements/names.dart';
+import '../elements/types.dart';
+import '../js_backend/inferred_data.dart';
+import '../js_backend/no_such_method_registry.dart';
+import '../js_model/element_map.dart';
+import '../js_model/js_world.dart';
+import '../js_model/locals.dart';
+import '../native/behavior.dart';
+import '../options.dart';
+import '../serialization/serialization.dart';
+import '../universe/call_structure.dart';
+import '../universe/selector.dart';
+import '../universe/side_effects.dart';
+import '../world.dart';
+import '../inferrer/abstract_value_domain.dart';
+import 'builder.dart';
+import 'closure_tracer.dart';
+import 'debug.dart' as debug;
+import 'engine_interfaces.dart' as interfaces;
+import 'locals_handler.dart';
+import 'list_tracer.dart';
+import 'map_tracer.dart';
+import 'set_tracer.dart';
+import 'type_graph_dump.dart';
+import 'type_graph_inferrer.dart';
+import 'type_graph_nodes.dart';
+import 'type_system.dart';
+import 'types.dart';
+
+/// An inferencing engine that computes a call graph of [TypeInformation] nodes
+/// by visiting the AST of the application, and then does the inferencing on the
+/// graph.
+class InferrerEngine implements interfaces.InferrerEngine {
+  /// A set of selector names that [List] implements, that we know return their
+  /// element type.
+  @override
+  final Set<Selector> returnsListElementTypeSet = Set<Selector>.from(<Selector>[
+    Selector.getter(const PublicName('first')),
+    Selector.getter(const PublicName('last')),
+    Selector.getter(const PublicName('single')),
+    Selector.call(const PublicName('singleWhere'), CallStructure.ONE_ARG),
+    Selector.call(const PublicName('elementAt'), CallStructure.ONE_ARG),
+    Selector.index(),
+    Selector.call(const PublicName('removeAt'), CallStructure.ONE_ARG),
+    Selector.call(const PublicName('removeLast'), CallStructure.NO_ARGS)
+  ]);
+
+  /// The [JClosedWorld] on which inference reasoning is based.
+  @override
+  final JsClosedWorld closedWorld;
+
+  @override
+  final TypeSystem types;
+  final Map<ir.TreeNode, TypeInformation> concreteTypes = {};
+  final GlobalLocalsMap globalLocalsMap;
+  @override
+  final InferredDataBuilder inferredDataBuilder;
+
+  @override
+  final FunctionEntity mainElement;
+
+  final Map<Local, TypeInformation> _defaultTypeOfParameter = {};
+
+  final WorkQueue _workQueue = WorkQueue();
+
+  final _InferrerEngineMetrics metrics = _InferrerEngineMetrics();
+
+  final Set<MemberEntity> _analyzedElements = {};
+
+  /// The maximum number of times we allow a node in the graph to
+  /// change types. If a node reaches that limit, we give up
+  /// inferencing on it and give it the dynamic type.
+  final int _MAX_CHANGE_COUNT = 6;
+
+  int _overallRefineCount = 0;
+  int _addedInGraph = 0;
+
+  final CompilerOptions _options;
+  final Progress _progress;
+  final DiagnosticReporter _reporter;
+  final api.CompilerOutput _compilerOutput;
+
+  final Set<ConstructorEntity> _generativeConstructorsExposingThis =
+      Set<ConstructorEntity>();
+
+  /// Data computed internally within elements, like the type-mask of a send a
+  /// list allocation, or a for-in loop.
+  final Map<MemberEntity, GlobalTypeInferenceElementData> _memberData =
+      Map<MemberEntity, GlobalTypeInferenceElementData>();
+
+  ElementEnvironment get _elementEnvironment => closedWorld.elementEnvironment;
+
+  @override
+  AbstractValueDomain get abstractValueDomain =>
+      closedWorld.abstractValueDomain;
+  @override
+  CommonElements get commonElements => closedWorld.commonElements;
+
+  // TODO(johnniwinther): This should be part of [ClosedWorld] or
+  // [ClosureWorldRefiner].
+  @override
+  NoSuchMethodData get noSuchMethodData => closedWorld.noSuchMethodData;
+
+  InferrerEngine(
+      this._options,
+      this._progress,
+      this._reporter,
+      this._compilerOutput,
+      this.closedWorld,
+      this.mainElement,
+      this.globalLocalsMap,
+      this.inferredDataBuilder)
+      : this.types = TypeSystem(closedWorld,
+            KernelTypeSystemStrategy(closedWorld, globalLocalsMap));
+
+  /// Applies [f] to all elements in the universe that match [selector] and
+  /// [mask]. If [f] returns false, aborts the iteration.
+  void forEachElementMatching(
+      Selector selector, AbstractValue mask, bool f(MemberEntity element)) {
+    Iterable<MemberEntity> elements = closedWorld.locateMembers(selector, mask);
+    for (MemberEntity e in elements) {
+      if (!f(e)) return;
+    }
+  }
+
+  // TODO(johnniwinther): Make this private again.
+  GlobalTypeInferenceElementData dataOfMember(MemberEntity element) =>
+      _memberData[element] ??= KernelGlobalTypeInferenceElementData();
+
+  /// Update [sideEffects] with the side effects of [callee] being
+  /// called with [selector].
+  void _updateSideEffects(SideEffectsBuilder sideEffectsBuilder,
+      Selector selector, MemberEntity callee) {
+    if (callee.isField) {
+      if (callee.isInstanceMember) {
+        if (selector.isSetter) {
+          sideEffectsBuilder.setChangesInstanceProperty();
+        } else if (selector.isGetter) {
+          sideEffectsBuilder.setDependsOnInstancePropertyStore();
+        } else {
+          sideEffectsBuilder.setAllSideEffectsAndDependsOnSomething();
+        }
+      } else {
+        if (selector.isSetter) {
+          sideEffectsBuilder.setChangesStaticProperty();
+        } else if (selector.isGetter) {
+          sideEffectsBuilder.setDependsOnStaticPropertyStore();
+        } else {
+          sideEffectsBuilder.setAllSideEffectsAndDependsOnSomething();
+        }
+      }
+    } else if (callee.isGetter && !selector.isGetter) {
+      sideEffectsBuilder.setAllSideEffectsAndDependsOnSomething();
+    } else {
+      sideEffectsBuilder
+          .addInput(inferredDataBuilder.getSideEffectsBuilder(callee));
+    }
+  }
+
+  /// Returns the type for [nativeBehavior]. See documentation on
+  /// [NativeBehavior].
+  @override
+  TypeInformation typeOfNativeBehavior(NativeBehavior nativeBehavior) {
+    if (nativeBehavior == null) return types.dynamicType;
+    List<Object> typesReturned = nativeBehavior.typesReturned;
+    if (typesReturned.isEmpty) return types.dynamicType;
+    TypeInformation returnType;
+    for (var type in typesReturned) {
+      TypeInformation mappedType;
+      if (type == SpecialType.JsObject) {
+        mappedType = types.nonNullExact(commonElements.objectClass);
+      } else if (type == commonElements.stringType) {
+        mappedType = types.stringType;
+      } else if (type == commonElements.intType) {
+        mappedType = types.intType;
+      } else if (type == commonElements.numType ||
+          type == commonElements.doubleType) {
+        // Note: the backend double class is specifically for non-integer
+        // doubles, and a native behavior returning 'double' does not guarantee
+        // a non-integer return type, so we return the number type for those.
+        mappedType = types.numType;
+      } else if (type == commonElements.boolType) {
+        mappedType = types.boolType;
+      } else if (type == commonElements.nullType) {
+        mappedType = types.nullType;
+      } else if (type is VoidType) {
+        mappedType = types.nullType;
+      } else if (type is DynamicType) {
+        return types.dynamicType;
+      } else if (type is InterfaceType) {
+        mappedType = types.nonNullSubtype(type.element);
+      } else {
+        mappedType = types.dynamicType;
+      }
+      returnType = types.computeLUB(returnType, mappedType);
+      if (returnType == types.dynamicType) {
+        break;
+      }
+    }
+    return returnType;
+  }
+
+  @override
+  void updateSelectorInMember(MemberEntity owner, CallType callType,
+      ir.Node node, Selector selector, AbstractValue mask) {
+    KernelGlobalTypeInferenceElementData data = dataOfMember(owner);
+    assert(validCallType(callType, node, selector));
+    switch (callType) {
+      case CallType.access:
+        data.setReceiverTypeMask(node, mask);
+        break;
+      case CallType.forIn:
+        if (selector == Selectors.iterator) {
+          data.setIteratorTypeMask(node, mask);
+        } else if (selector == Selectors.current) {
+          data.setCurrentTypeMask(node, mask);
+        } else {
+          assert(selector == Selectors.moveNext);
+          data.setMoveNextTypeMask(node, mask);
+        }
+        break;
+    }
+  }
+
+  bool checkIfExposesThis(ConstructorEntity element) {
+    return _generativeConstructorsExposingThis.contains(element);
+  }
+
+  void recordExposesThis(ConstructorEntity element, bool exposesThis) {
+    if (exposesThis) {
+      _generativeConstructorsExposingThis.add(element);
+    }
+  }
+
+  @override
+  bool returnsListElementType(Selector selector, AbstractValue mask) {
+    assert(mask != null);
+    return abstractValueDomain.isContainer(mask) &&
+        returnsListElementTypeSet.contains(selector);
+  }
+
+  @override
+  bool returnsMapValueType(Selector selector, AbstractValue mask) {
+    assert(mask != null);
+    return abstractValueDomain.isMap(mask) && selector.isIndex;
+  }
+
+  @override
+  void analyzeListAndEnqueue(ListTypeInformation info) {
+    if (info.analyzed) return;
+    info.analyzed = true;
+
+    ListTracerVisitor tracer = ListTracerVisitor(info, this);
+    bool succeeded = tracer.run();
+    if (!succeeded) return;
+
+    info.bailedOut = false;
+    info.elementType.inferred = true;
+    tracer.inputs.forEach(info.elementType.addInput);
+    // Enqueue the list for later refinement
+    _workQueue.add(info);
+    _workQueue.add(info.elementType);
+  }
+
+  @override
+  void analyzeSetAndEnqueue(SetTypeInformation info) {
+    if (info.analyzed) return;
+    info.analyzed = true;
+
+    SetTracerVisitor tracer = SetTracerVisitor(info, this);
+    bool succeeded = tracer.run();
+    if (!succeeded) return;
+
+    info.bailedOut = false;
+    info.elementType.inferred = true;
+
+    tracer.inputs.forEach(info.elementType.addInput);
+    // Enqueue the set for later refinement.
+    _workQueue.add(info);
+    _workQueue.add(info.elementType);
+  }
+
+  @override
+  void analyzeMapAndEnqueue(MapTypeInformation info) {
+    if (info.analyzed) return;
+    info.analyzed = true;
+    MapTracerVisitor tracer = MapTracerVisitor(info, this);
+
+    bool succeeded = tracer.run();
+    if (!succeeded) return;
+
+    info.bailedOut = false;
+    for (int i = 0; i < tracer.keyInputs.length; ++i) {
+      TypeInformation newType = info.addEntryInput(
+          abstractValueDomain, tracer.keyInputs[i], tracer.valueInputs[i]);
+      if (newType != null) _workQueue.add(newType);
+    }
+    for (TypeInformation map in tracer.mapInputs) {
+      _workQueue.addAll(info.addMapInput(abstractValueDomain, map));
+    }
+
+    info.markAsInferred();
+    _workQueue.add(info.keyType);
+    _workQueue.add(info.valueType);
+    _workQueue.addAll(info.typeInfoMap.values);
+    _workQueue.add(info);
+  }
+
+  void runOverAllElements() {
+    metrics.time.measure(_runOverAllElements);
+  }
+
+  void _runOverAllElements() {
+    metrics.analyze.measure(_analyzeAllElements);
+    TypeGraphDump dump =
+        debug.PRINT_GRAPH ? TypeGraphDump(_compilerOutput, this) : null;
+
+    dump?.beforeAnalysis();
+    _buildWorkQueue();
+    metrics.refine1.measure(_refine);
+
+    // Try to infer element types of lists and compute their escape information.
+    types.allocatedLists.values.forEach((TypeInformation info) {
+      analyzeListAndEnqueue(info);
+    });
+
+    // Try to infer element types of sets and compute their escape information.
+    types.allocatedSets.values.forEach((TypeInformation info) {
+      analyzeSetAndEnqueue(info);
+    });
+
+    // Try to infer the key and value types for maps and compute the values'
+    // escape information.
+    types.allocatedMaps.values.forEach((TypeInformation info) {
+      analyzeMapAndEnqueue(info);
+    });
+
+    Set<FunctionEntity> bailedOutOn = Set<FunctionEntity>();
+
+    // Trace closures to potentially infer argument types.
+    types.allocatedClosures.forEach((dynamic info) {
+      void trace(
+          Iterable<FunctionEntity> elements, ClosureTracerVisitor tracer) {
+        tracer.run();
+        if (!tracer.continueAnalyzing) {
+          elements.forEach((FunctionEntity element) {
+            inferredDataBuilder.registerMightBePassedToApply(element);
+            if (debug.VERBOSE) {
+              print("traced closure $element as ${true} (bail)");
+            }
+            types.strategy.forEachParameter(element, (Local parameter) {
+              types
+                  .getInferredTypeOfParameter(parameter)
+                  .giveUp(this, clearInputs: false);
+            });
+          });
+          bailedOutOn.addAll(elements);
+          return;
+        }
+        elements
+            .where((e) => !bailedOutOn.contains(e))
+            .forEach((FunctionEntity element) {
+          types.strategy.forEachParameter(element, (Local parameter) {
+            ParameterTypeInformation info =
+                types.getInferredTypeOfParameter(parameter);
+            info.maybeResume();
+            _workQueue.add(info);
+          });
+          if (tracer.tracedType.mightBePassedToFunctionApply) {
+            inferredDataBuilder.registerMightBePassedToApply(element);
+          }
+          if (debug.VERBOSE) {
+            print("traced closure $element as "
+                "${inferredDataBuilder.getCurrentlyKnownMightBePassedToApply(element)}");
+          }
+        });
+      }
+
+      if (info is ClosureTypeInformation) {
+        Iterable<FunctionEntity> elements = [info.closure];
+        trace(elements, ClosureTracerVisitor(elements, info, this));
+      } else if (info is CallSiteTypeInformation) {
+        if (info is StaticCallSiteTypeInformation &&
+            info.selector != null &&
+            info.selector.isCall) {
+          // This is a constructor call to a class with a call method. So we
+          // need to trace the call method here.
+          FunctionEntity calledElement = info.calledElement;
+          assert(calledElement is ConstructorEntity &&
+              calledElement.isGenerativeConstructor);
+          ClassEntity cls = calledElement.enclosingClass;
+          FunctionEntity callMethod = _lookupCallMethod(cls);
+          assert(callMethod != null, failedAt(cls));
+          Iterable<FunctionEntity> elements = [callMethod];
+          trace(elements, ClosureTracerVisitor(elements, info, this));
+        } else {
+          // We only are interested in functions here, as other targets
+          // of this closure call are not a root to trace but an intermediate
+          // for some other function.
+          Iterable<FunctionEntity> elements = List<FunctionEntity>.from(
+              info.callees.where((e) => e.isFunction));
+          trace(elements, ClosureTracerVisitor(elements, info, this));
+        }
+      } else if (info is MemberTypeInformation) {
+        trace(<FunctionEntity>[info.member],
+            StaticTearOffClosureTracerVisitor(info.member, info, this));
+      } else if (info is ParameterTypeInformation) {
+        failedAt(
+            NO_LOCATION_SPANNABLE, 'Unexpected closure allocation info $info');
+      }
+    });
+
+    dump?.beforeTracing();
+
+    // Reset all nodes that use lists/maps that have been inferred, as well
+    // as nodes that use elements fetched from these lists/maps. The
+    // workset for a new run of the analysis will be these nodes.
+    Set<TypeInformation> seenTypes = Set<TypeInformation>();
+    while (!_workQueue.isEmpty) {
+      TypeInformation info = _workQueue.remove();
+      if (seenTypes.contains(info)) continue;
+      // If the node cannot be reset, we do not need to update its users either.
+      if (!info.reset(this)) continue;
+      seenTypes.add(info);
+      _workQueue.addAll(info.users);
+    }
+
+    _workQueue.addAll(seenTypes);
+    metrics.refine2.measure(_refine);
+
+    if (debug.PRINT_SUMMARY) {
+      types.allocatedLists.values.forEach((_info) {
+        ListTypeInformation info = _info;
+        print('${info.type} '
+            'for ${abstractValueDomain.getAllocationNode(info.originalType)} '
+            'at ${abstractValueDomain.getAllocationElement(info.originalType)}'
+            'after ${info.refineCount}');
+      });
+      types.allocatedSets.values.forEach((_info) {
+        SetTypeInformation info = _info;
+        print('${info.type} '
+            'for ${abstractValueDomain.getAllocationNode(info.originalType)} '
+            'at ${abstractValueDomain.getAllocationElement(info.originalType)} '
+            'after ${info.refineCount}');
+      });
+      types.allocatedMaps.values.forEach((_info) {
+        MapTypeInformation info = _info;
+        print('${info.type} '
+            'for ${abstractValueDomain.getAllocationNode(info.originalType)} '
+            'at ${abstractValueDomain.getAllocationElement(info.originalType)}'
+            'after ${info.refineCount}');
+      });
+      types.allocatedClosures.forEach((TypeInformation info) {
+        if (info is ElementTypeInformation) {
+          print('${info.getInferredSignature(types)} for '
+              '${info.debugName}');
+        } else if (info is ClosureTypeInformation) {
+          print('${info.getInferredSignature(types)} for '
+              '${info.debugName}');
+        } else if (info is DynamicCallSiteTypeInformation) {
+          if (info.hasClosureCallTargets) {
+            print('<Closure.call>');
+          }
+          for (MemberEntity target in info.concreteTargets) {
+            if (target is FunctionEntity) {
+              print('${types.getInferredSignatureOfMethod(target)} '
+                  'for ${target}');
+            } else {
+              print('${types.getInferredTypeOfMember(target).type} '
+                  'for ${target}');
+            }
+          }
+        } else if (info is StaticCallSiteTypeInformation) {
+          ClassEntity cls = info.calledElement.enclosingClass;
+          FunctionEntity callMethod = _lookupCallMethod(cls);
+          print('${types.getInferredSignatureOfMethod(callMethod)} for ${cls}');
+        } else {
+          print('${info.type} for some unknown kind of closure');
+        }
+      });
+      _analyzedElements.forEach((MemberEntity elem) {
+        TypeInformation type = types.getInferredTypeOfMember(elem);
+        print('${elem} :: ${type} from ${type.inputs} ');
+      });
+    }
+    dump?.afterAnalysis();
+
+    metrics.overallRefineCount.add(_overallRefineCount);
+    _reporter.log('Inferred $_overallRefineCount types.');
+
+    _processLoopInformation();
+  }
+
+  /// Call [analyze] for all live members.
+  void _analyzeAllElements() {
+    Iterable<MemberEntity> processedMembers = closedWorld.processedMembers
+        .where((MemberEntity member) => !member.isAbstract);
+
+    _progress.startPhase();
+    processedMembers.forEach((MemberEntity member) {
+      _progress.showProgress(
+          'Added ', _addedInGraph, ' elements in inferencing graph.');
+      // This also forces the creation of the [ElementTypeInformation] to ensure
+      // it is in the graph.
+      types.withMember(member, () => analyze(member));
+    });
+    metrics.elementsInGraph.add(_addedInGraph);
+    _reporter.log('Added $_addedInGraph elements in inferencing graph.');
+    metrics.allTypesCount.add(types.allTypes.length);
+  }
+
+  /// Returns the body node for [member].
+  ir.Node _computeMemberBody(MemberEntity member) {
+    MemberDefinition definition =
+        closedWorld.elementMap.getMemberDefinition(member);
+    switch (definition.kind) {
+      case MemberKind.regular:
+        ir.Member node = definition.node;
+        if (node is ir.Field) {
+          return getFieldInitializer(closedWorld.elementMap, member);
+        } else if (node is ir.Procedure) {
+          return node.function;
+        }
+        break;
+      case MemberKind.constructor:
+        return definition.node;
+      case MemberKind.constructorBody:
+        ir.Member node = definition.node;
+        if (node is ir.Constructor) {
+          return node.function;
+        } else if (node is ir.Procedure) {
+          return node.function;
+        }
+        break;
+      case MemberKind.closureCall:
+        ir.LocalFunction node = definition.node;
+        return node.function;
+      case MemberKind.closureField:
+      case MemberKind.signature:
+      case MemberKind.generatorBody:
+        break;
+    }
+    failedAt(member, 'Unexpected member definition: $definition.');
+  }
+
+  /// Returns the `call` method on [cls] or the `noSuchMethod` if [cls] doesn't
+  /// implement `call`.
+  FunctionEntity _lookupCallMethod(ClassEntity cls) {
+    FunctionEntity function =
+        _elementEnvironment.lookupClassMember(cls, Names.call);
+    if (function == null || function.isAbstract) {
+      function =
+          _elementEnvironment.lookupClassMember(cls, Names.noSuchMethod_);
+    }
+    return function;
+  }
+
+  void analyze(MemberEntity element) {
+    if (_analyzedElements.contains(element)) return;
+    _analyzedElements.add(element);
+
+    ir.Node body = _computeMemberBody(element);
+
+    TypeInformation type;
+    _reporter.withCurrentElement(element, () {
+      type = _computeMemberTypeInformation(element, body);
+    });
+    _addedInGraph++;
+
+    if (element.isField) {
+      FieldEntity field = element;
+      if (!field.isAssignable) {
+        // If [element] is final and has an initializer, we record
+        // the inferred type.
+        if (body != null) {
+          if (type is! ListTypeInformation && type is! MapTypeInformation) {
+            // For non-container types, the constant handler does
+            // constant folding that could give more precise results.
+            ConstantValue value = _getFieldConstant(field);
+            if (value != null) {
+              if (value is FunctionConstantValue) {
+                type = types.allocateClosure(value.element);
+              } else {
+                // Although we might find a better type, we have to keep
+                // the old type around to ensure that we get a complete view
+                // of the type graph and do not drop any flow edges.
+                AbstractValue refinedType =
+                    abstractValueDomain.computeAbstractValueForConstant(value);
+                type = NarrowTypeInformation(
+                    abstractValueDomain, type, refinedType);
+                types.allocatedTypes.add(type);
+              }
+            }
+          }
+          recordTypeOfField(field, type);
+        } else if (!element.isInstanceMember) {
+          recordTypeOfField(field, types.nullType);
+        }
+      } else if (body == null) {
+        // Only update types of static fields if there is no
+        // assignment. Instance fields are dealt with in the constructor.
+        if (element.isStatic || element.isTopLevel) {
+          recordTypeOfField(field, type);
+        }
+      } else {
+        recordTypeOfField(field, type);
+      }
+      if ((element.isStatic || element.isTopLevel) &&
+          body != null &&
+          !element.isConst) {
+        if (_isFieldInitializerPotentiallyNull(element, body)) {
+          recordTypeOfField(field, types.nullType);
+        }
+      }
+    } else {
+      FunctionEntity method = element;
+      recordReturnType(method, type);
+    }
+  }
+
+  /// Visits [body] to compute the [TypeInformation] node for [member].
+  TypeInformation _computeMemberTypeInformation(
+      MemberEntity member, ir.Node body) {
+    KernelTypeGraphBuilder visitor = KernelTypeGraphBuilder(
+        _options,
+        closedWorld,
+        this,
+        member,
+        body,
+        globalLocalsMap.getLocalsMap(member),
+        closedWorld.elementMap.getStaticTypeProvider(member));
+    return visitor.run();
+  }
+
+  /// Returns `true` if the [initializer] of the non-const static or top-level
+  /// [field] is potentially `null`.
+  bool _isFieldInitializerPotentiallyNull(
+      FieldEntity field, ir.Node initializer) {
+    // TODO(13429): We could do better here by using the
+    // constant handler to figure out if it's a lazy field or not.
+    // TODO(johnniwinther): Implement the ad-hoc check in ast inferrer? This
+    // mimicks that ast inferrer which return `true` for [ast.Send] and
+    // non-const [ast.NewExpression].
+    if (initializer is ir.InstanceInvocation ||
+        initializer is ir.InstanceGetterInvocation ||
+        initializer is ir.DynamicInvocation ||
+        initializer is ir.FunctionInvocation ||
+        initializer is ir.LocalFunctionInvocation ||
+        initializer is ir.EqualsNull ||
+        initializer is ir.EqualsCall ||
+        initializer is ir.InstanceGet ||
+        initializer is ir.DynamicGet ||
+        initializer is ir.InstanceTearOff ||
+        initializer is ir.FunctionTearOff ||
+        initializer is ir.InstanceSet ||
+        initializer is ir.DynamicSet ||
+        initializer is ir.StaticInvocation ||
+        initializer is ir.StaticGet ||
+        initializer is ir.StaticTearOff ||
+        initializer is ir.StaticSet ||
+        initializer is ir.Let ||
+        initializer is ir.ConstructorInvocation && !initializer.isConst) {
+      return true;
+    }
+    return false;
+  }
+
+  /// Returns the [ConstantValue] for the initial value of [field], or
+  /// `null` if the initializer is not a constant value.
+  ConstantValue _getFieldConstant(FieldEntity field) {
+    return closedWorld.fieldAnalysis.getFieldData(field).initialValue;
+  }
+
+  /// Returns `true` if [cls] has a 'call' method.
+  bool _hasCallType(ClassEntity cls) {
+    return closedWorld.dartTypes
+            .getCallType(closedWorld.elementEnvironment.getThisType(cls)) !=
+        null;
+  }
+
+  void _processLoopInformation() {
+    types.allocatedCalls.forEach((CallSiteTypeInformation info) {
+      if (!info.inLoop) return;
+      // We can't compute the callees of closures, no new information to add.
+      if (info is ClosureCallSiteTypeInformation) {
+        return;
+      }
+      if (info is StaticCallSiteTypeInformation) {
+        MemberEntity member = info.calledElement;
+        inferredDataBuilder.addFunctionCalledInLoop(member);
+      } else if (info is DynamicCallSiteTypeInformation &&
+          info.mask != null &&
+          abstractValueDomain.containsAll(info.mask).isDefinitelyFalse) {
+        // For instance methods, we only register a selector called in a
+        // loop if it is a typed selector, to avoid marking too many
+        // methods as being called from within a loop. This cuts down
+        // on the code bloat.
+        info.callees.forEach((MemberEntity element) {
+          inferredDataBuilder.addFunctionCalledInLoop(element);
+        });
+      }
+    });
+  }
+
+  void _refine() {
+    _progress.startPhase();
+    while (!_workQueue.isEmpty) {
+      _progress.showProgress('Inferred ', _overallRefineCount, ' types.');
+      TypeInformation info = _workQueue.remove();
+      AbstractValue oldType = info.type;
+      AbstractValue newType = info.refine(this);
+      // Check that refinement has not accidentally changed the type.
+      assert(oldType == info.type);
+      if (info.abandonInferencing) info.doNotEnqueue = true;
+      if ((info.type = newType) != oldType) {
+        _overallRefineCount++;
+        info.refineCount++;
+        if (info.refineCount > _MAX_CHANGE_COUNT) {
+          metrics.exceededMaxChangeCount.add();
+          if (debug.ANOMALY_WARN) {
+            print("ANOMALY WARNING: max refinement reached for $info");
+          }
+          info.giveUp(this);
+          info.type = info.refine(this);
+          info.doNotEnqueue = true;
+        }
+        _workQueue.addAll(info.users);
+        if (info.hasStableType(this)) {
+          info.stabilize(this);
+        }
+      }
+    }
+  }
+
+  void _buildWorkQueue() {
+    _workQueue.addAll(types.orderedTypeInformations);
+    _workQueue.addAll(types.allocatedTypes);
+    _workQueue.addAll(types.allocatedClosures);
+    _workQueue.addAll(types.allocatedCalls);
+  }
+
+  /// Update the inputs to parameters in the graph. [remove] tells whether
+  /// inputs must be added or removed. If [init] is false, parameters are
+  /// added to the work queue.
+  @override
+  void updateParameterInputs(TypeInformation caller, MemberEntity callee,
+      ArgumentsTypes arguments, Selector selector,
+      {bool remove, bool addToQueue = true}) {
+    if (callee.name == Identifiers.noSuchMethod_) return;
+    if (callee.isField) {
+      if (selector.isSetter) {
+        ElementTypeInformation info = types.getInferredTypeOfMember(callee);
+        if (remove) {
+          info.removeInput(arguments.positional[0]);
+        } else {
+          info.addInput(arguments.positional[0]);
+        }
+        if (addToQueue) _workQueue.add(info);
+      }
+    } else if (callee.isGetter) {
+      return;
+    } else if (selector != null && selector.isGetter) {
+      // We are tearing a function off and thus create a closure.
+      assert(callee.isFunction);
+      MemberTypeInformation info = types.getInferredTypeOfMember(callee);
+      if (remove) {
+        info.closurizedCount--;
+      } else {
+        info.closurizedCount++;
+        if (callee.isStatic || callee.isTopLevel) {
+          types.allocatedClosures.add(info);
+        } else {
+          // We add the call-site type information here so that we
+          // can benefit from further refinement of the selector.
+          types.allocatedClosures.add(caller);
+        }
+        types.strategy.forEachParameter(callee, (Local parameter) {
+          ParameterTypeInformation info =
+              types.getInferredTypeOfParameter(parameter);
+          info.tagAsTearOffClosureParameter(this);
+          if (addToQueue) _workQueue.add(info);
+        });
+      }
+    } else {
+      FunctionEntity method = callee;
+      ParameterStructure parameterStructure = method.parameterStructure;
+      int parameterIndex = 0;
+      types.strategy.forEachParameter(callee, (Local parameter) {
+        TypeInformation type;
+        if (parameterIndex < parameterStructure.requiredPositionalParameters) {
+          type = arguments.positional[parameterIndex];
+        } else if (parameterStructure.namedParameters.isNotEmpty) {
+          type = arguments.named[parameter.name];
+        } else if (parameterIndex < arguments.positional.length) {
+          type = arguments.positional[parameterIndex];
+        }
+        if (type == null) type = getDefaultTypeOfParameter(parameter);
+        TypeInformation info = types.getInferredTypeOfParameter(parameter);
+        if (remove) {
+          info.removeInput(type);
+        } else {
+          info.addInput(type);
+        }
+        parameterIndex++;
+        if (addToQueue) _workQueue.add(info);
+      });
+    }
+  }
+
+  /// Sets the type of a parameter's default value to [type]. If the global
+  /// mapping in `_defaultTypeOfParameter` already contains a type, it must be
+  /// a [PlaceholderTypeInformation], which will be replaced. All its uses are
+  /// updated.
+  void setDefaultTypeOfParameter(Local parameter, TypeInformation type) {
+    assert(
+        type != null, failedAt(parameter, "No default type for $parameter."));
+    TypeInformation existing = _defaultTypeOfParameter[parameter];
+    _defaultTypeOfParameter[parameter] = type;
+    TypeInformation info = types.getInferredTypeOfParameter(parameter);
+    if (existing != null && existing is PlaceholderTypeInformation) {
+      // Replace references to [existing] to use [type] instead.
+      info.inputs.replace(existing, type);
+      // Also forward all users.
+      type.addUsersOf(existing);
+    } else {
+      assert(existing == null);
+    }
+  }
+
+  /// Returns the [TypeInformation] node for the default value of a parameter.
+  /// If this is queried before it is set by [setDefaultTypeOfParameter], a
+  /// [PlaceholderTypeInformation] is returned, which will later be replaced
+  /// by the actual node when [setDefaultTypeOfParameter] is called.
+  ///
+  /// Invariant: After graph construction, no [PlaceholderTypeInformation] nodes
+  /// should be present and a default type for each parameter should exist.
+  @override
+  TypeInformation getDefaultTypeOfParameter(Local parameter) {
+    return _defaultTypeOfParameter.putIfAbsent(parameter, () {
+      return PlaceholderTypeInformation(
+          abstractValueDomain, types.currentMember);
+    });
+  }
+
+  /// Returns the type of [element].
+  TypeInformation typeOfParameter(Local element) {
+    return types.getInferredTypeOfParameter(element);
+  }
+
+  /// Returns the type of [element].
+  TypeInformation typeOfMember(MemberEntity element) {
+    if (element is FunctionEntity) return types.functionType;
+    return types.getInferredTypeOfMember(element);
+  }
+
+  /// Returns the return type of [element].
+  TypeInformation returnTypeOfMember(MemberEntity element) {
+    if (element is! FunctionEntity) return types.dynamicType;
+    return types.getInferredTypeOfMember(element);
+  }
+
+  /// Records that [element] is of type [type].
+  void recordTypeOfField(FieldEntity element, TypeInformation type) {
+    types.getInferredTypeOfMember(element).addInput(type);
+  }
+
+  /// Records that the return type [element] is of type [type].
+  void recordReturnType(FunctionEntity element, TypeInformation type) {
+    TypeInformation info = types.getInferredTypeOfMember(element);
+    if (element.name == '==') {
+      // Even if x.== doesn't return a bool, 'x == null' evaluates to 'false'.
+      info.addInput(types.boolType);
+    }
+    // TODO(ngeoffray): Clean up. We do these checks because
+    // [SimpleTypesInferrer] deals with two different inferrers.
+    if (type == null) return;
+    if (info.inputs.isEmpty) info.addInput(type);
+  }
+
+  /// Notifies to the inferrer that [analyzedElement] can have return type
+  /// [newType]. [currentType] is the type the inference has currently found.
+  ///
+  /// Returns the new type for [analyzedElement].
+  TypeInformation addReturnTypeForMethod(
+      FunctionEntity element, TypeInformation unused, TypeInformation newType) {
+    TypeInformation type = types.getInferredTypeOfMember(element);
+    // TODO(ngeoffray): Clean up. We do this check because
+    // [SimpleTypesInferrer] deals with two different inferrers.
+    if (element is ConstructorEntity && element.isGenerativeConstructor) {
+      return type;
+    }
+    type.addInput(newType);
+    return type;
+  }
+
+  /// Registers that [caller] calls [callee] at location [node], with
+  /// [selector], and [arguments]. Note that [selector] is null for forwarding
+  /// constructors.
+  ///
+  /// [sideEffectsBuilder] will be updated to incorporate [callee]'s side
+  /// effects.
+  ///
+  /// [inLoop] tells whether the call happens in a loop.
+  TypeInformation registerCalledMember(
+      Object node,
+      Selector selector,
+      MemberEntity caller,
+      MemberEntity callee,
+      ArgumentsTypes arguments,
+      SideEffectsBuilder sideEffectsBuilder,
+      bool inLoop) {
+    CallSiteTypeInformation info = StaticCallSiteTypeInformation(
+        abstractValueDomain,
+        types.currentMember,
+        node,
+        caller,
+        callee,
+        selector,
+        arguments,
+        inLoop);
+    // If this class has a 'call' method then we have essentially created a
+    // closure here. Register it as such so that it is traced.
+    // Note: we exclude factory constructors because they don't always create an
+    // instance of the type. They are static methods that delegate to some other
+    // generative constructor to do the actual creation of the object.
+    if (selector != null &&
+        selector.isCall &&
+        callee is ConstructorEntity &&
+        callee.isGenerativeConstructor) {
+      ClassEntity cls = callee.enclosingClass;
+      if (_hasCallType(cls)) {
+        types.allocatedClosures.add(info);
+      }
+    }
+    info.addToGraph(this);
+    types.allocatedCalls.add(info);
+    _updateSideEffects(sideEffectsBuilder, selector, callee);
+    return info;
+  }
+
+  /// Registers that [caller] calls [selector] with [receiverType] as receiver,
+  /// and [arguments].
+  ///
+  /// [sideEffectsBuilder] will be updated to incorporate the potential callees'
+  /// side effects.
+  ///
+  /// [inLoop] tells whether the call happens in a loop.
+  TypeInformation registerCalledSelector(
+      CallType callType,
+      ir.Node node,
+      Selector selector,
+      AbstractValue mask,
+      TypeInformation receiverType,
+      MemberEntity caller,
+      ArgumentsTypes arguments,
+      SideEffectsBuilder sideEffectsBuilder,
+      {bool inLoop,
+      bool isConditional}) {
+    if (selector.isClosureCall) {
+      return registerCalledClosure(
+          node, selector, receiverType, caller, arguments, sideEffectsBuilder,
+          inLoop: inLoop);
+    }
+
+    if (closedWorld.includesClosureCall(selector, mask)) {
+      sideEffectsBuilder.setAllSideEffectsAndDependsOnSomething();
+    }
+
+    closedWorld.locateMembers(selector, mask).forEach((callee) {
+      _updateSideEffects(sideEffectsBuilder, selector, callee);
+    });
+
+    CallSiteTypeInformation info = DynamicCallSiteTypeInformation(
+        abstractValueDomain,
+        types.currentMember,
+        callType,
+        node,
+        caller,
+        selector,
+        mask,
+        receiverType,
+        arguments,
+        inLoop,
+        isConditional);
+    info.addToGraph(this);
+    types.allocatedCalls.add(info);
+    return info;
+  }
+
+  /// Registers a call to await with an expression of type [argumentType] as
+  /// argument.
+  TypeInformation registerAwait(ir.Node node, TypeInformation argument) {
+    AwaitTypeInformation info =
+        AwaitTypeInformation(abstractValueDomain, types.currentMember, node);
+    info.addInput(argument);
+    types.allocatedTypes.add(info);
+    return info;
+  }
+
+  /// Registers a call to yield with an expression of type [argumentType] as
+  /// argument.
+  TypeInformation registerYield(ir.Node node, TypeInformation argument) {
+    YieldTypeInformation info =
+        YieldTypeInformation(abstractValueDomain, types.currentMember, node);
+    info.addInput(argument);
+    types.allocatedTypes.add(info);
+    return info;
+  }
+
+  /// Registers that [caller] calls [closure] with [arguments].
+  ///
+  /// [sideEffectsBuilder] will be updated to incorporate the potential callees'
+  /// side effects.
+  ///
+  /// [inLoop] tells whether the call happens in a loop.
+  TypeInformation registerCalledClosure(
+      ir.Node node,
+      Selector selector,
+      TypeInformation closure,
+      MemberEntity caller,
+      ArgumentsTypes arguments,
+      SideEffectsBuilder sideEffectsBuilder,
+      {bool inLoop}) {
+    sideEffectsBuilder.setAllSideEffectsAndDependsOnSomething();
+    CallSiteTypeInformation info = ClosureCallSiteTypeInformation(
+        abstractValueDomain,
+        types.currentMember,
+        node,
+        caller,
+        selector,
+        closure,
+        arguments,
+        inLoop);
+    info.addToGraph(this);
+    types.allocatedCalls.add(info);
+    return info;
+  }
+
+  void close() {
+    for (MemberTypeInformation typeInformation
+        in types.memberTypeInformations.values) {
+      typeInformation.computeIsCalledOnce();
+    }
+  }
+
+  void clear() {
+    if (retainDataForTesting) return;
+
+    void cleanup(TypeInformation info) {
+      info.cleanup();
+    }
+
+    types.allocatedCalls.forEach(cleanup);
+    types.allocatedCalls.clear();
+
+    _defaultTypeOfParameter.clear();
+
+    types.parameterTypeInformations.values.forEach(cleanup);
+    types.memberTypeInformations.values.forEach(cleanup);
+
+    types.allocatedTypes.forEach(cleanup);
+    types.allocatedTypes.clear();
+
+    types.concreteTypes.clear();
+
+    types.allocatedClosures.forEach(cleanup);
+    types.allocatedClosures.clear();
+
+    _analyzedElements.clear();
+    _generativeConstructorsExposingThis.clear();
+
+    types.allocatedMaps.values.forEach(cleanup);
+    types.allocatedSets.values.forEach(cleanup);
+    types.allocatedLists.values.forEach(cleanup);
+
+    _memberData.clear();
+  }
+
+  Iterable<MemberEntity> getCallersOfForTesting(MemberEntity element) {
+    MemberTypeInformation info = types.getInferredTypeOfMember(element);
+    return info.callersForTesting;
+  }
+
+  /// Returns the type of [element] when being called with [selector].
+  @override
+  TypeInformation typeOfMemberWithSelector(
+      MemberEntity element, Selector selector) {
+    if (element.name == Identifiers.noSuchMethod_ &&
+        selector.name != element.name) {
+      // An invocation can resolve to a [noSuchMethod], in which case
+      // we get the return type of [noSuchMethod].
+      return returnTypeOfMember(element);
+    } else if (selector.isGetter) {
+      if (element.isFunction) {
+        // [functionType] is null if the inferrer did not run.
+        return types.functionType ?? types.dynamicType;
+      } else if (element.isField) {
+        return typeOfMember(element);
+      } else if (element.isGetter) {
+        return returnTypeOfMember(element);
+      } else {
+        assert(false, failedAt(element, "Unexpected member $element"));
+        return types.dynamicType;
+      }
+    } else if (element.isGetter || element.isField) {
+      assert(selector.isCall || selector.isSetter);
+      return types.dynamicType;
+    } else {
+      return returnTypeOfMember(element);
+    }
+  }
+
+  /// Returns true if global optimizations such as type inferencing can apply to
+  /// the field [element].
+  ///
+  /// One category of elements that do not apply is runtime helpers that the
+  /// backend calls, but the optimizations don't see those calls.
+  @override
+  bool canFieldBeUsedForGlobalOptimizations(FieldEntity element) {
+    if (closedWorld.backendUsage.isFieldUsedByBackend(element)) {
+      return false;
+    }
+    if ((element.isTopLevel || element.isStatic) && !element.isAssignable) {
+      return true;
+    }
+    return true;
+  }
+
+  /// Returns true if global optimizations such as type inferencing can apply to
+  /// the parameter [element].
+  ///
+  /// One category of elements that do not apply is runtime helpers that the
+  /// backend calls, but the optimizations don't see those calls.
+  @override
+  bool canFunctionParametersBeUsedForGlobalOptimizations(
+      FunctionEntity function) {
+    return !closedWorld.backendUsage.isFunctionUsedByBackend(function);
+  }
+
+  /// Returns `true` if inference of parameter types is disabled for [member].
+  @override
+  bool assumeDynamic(MemberEntity member) {
+    return closedWorld.annotationsData.hasAssumeDynamic(member);
+  }
+}
+
+class _InferrerEngineMetrics extends MetricsBase {
+  final time = DurationMetric('time');
+  final analyze = DurationMetric('time.analyze');
+  final refine1 = DurationMetric('time.refine1');
+  final refine2 = DurationMetric('time.refine2');
+  final elementsInGraph = CountMetric('count.elementsInGraph');
+  final allTypesCount = CountMetric('count.allTypes');
+  final exceededMaxChangeCount = CountMetric('count.exceededMaxChange');
+  final overallRefineCount = CountMetric('count.overallRefines');
+
+  _InferrerEngineMetrics() {
+    primary = [time];
+    secondary = [
+      analyze,
+      refine1,
+      refine2,
+      elementsInGraph,
+      allTypesCount,
+      exceededMaxChangeCount,
+      overallRefineCount
+    ];
+  }
+}
+
+class KernelTypeSystemStrategy implements TypeSystemStrategy {
+  final JsClosedWorld _closedWorld;
+  final GlobalLocalsMap _globalLocalsMap;
+
+  KernelTypeSystemStrategy(this._closedWorld, this._globalLocalsMap);
+
+  JElementEnvironment get _elementEnvironment =>
+      _closedWorld.elementEnvironment;
+
+  @override
+  bool checkClassEntity(ClassEntity cls) => true;
+
+  @override
+  bool checkMapNode(ir.Node node) => true;
+
+  @override
+  bool checkSetNode(ir.Node node) => true;
+
+  @override
+  bool checkListNode(ir.Node node) => true;
+
+  @override
+  bool checkLoopPhiNode(ir.Node node) => true;
+
+  @override
+  bool checkPhiNode(ir.Node node) =>
+      node == null || node is ir.TryCatch || node is ir.TryFinally;
+
+  @override
+  void forEachParameter(FunctionEntity function, void f(Local parameter)) {
+    forEachOrderedParameterAsLocal(
+        _globalLocalsMap, _closedWorld.elementMap, function, (Local parameter,
+            {bool isElided}) {
+      f(parameter);
+    });
+  }
+
+  @override
+  ParameterTypeInformation createParameterTypeInformation(
+      AbstractValueDomain abstractValueDomain,
+      covariant JLocal parameter,
+      TypeSystem types) {
+    MemberEntity context = parameter.memberContext;
+    KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(context);
+    ir.FunctionNode functionNode =
+        localsMap.getFunctionNodeForParameter(parameter);
+    DartType type = localsMap.getLocalType(_closedWorld.elementMap, parameter);
+    MemberEntity member;
+    bool isClosure = false;
+    if (functionNode.parent is ir.Member) {
+      member = _closedWorld.elementMap.getMember(functionNode.parent);
+    } else if (functionNode.parent is ir.LocalFunction) {
+      ClosureRepresentationInfo info =
+          _closedWorld.closureDataLookup.getClosureInfo(functionNode.parent);
+      member = info.callMethod;
+      isClosure = true;
+    }
+    MemberTypeInformation memberTypeInformation =
+        types.getInferredTypeOfMember(member);
+    if (isClosure) {
+      return ParameterTypeInformation.localFunction(
+          abstractValueDomain, memberTypeInformation, parameter, type, member);
+    } else if (member.isInstanceMember) {
+      return ParameterTypeInformation.instanceMember(
+          abstractValueDomain,
+          memberTypeInformation,
+          parameter,
+          type,
+          member,
+          ParameterInputs.instanceMember());
+    } else {
+      return ParameterTypeInformation.static(
+          abstractValueDomain, memberTypeInformation, parameter, type, member);
+    }
+  }
+
+  @override
+  MemberTypeInformation createMemberTypeInformation(
+      AbstractValueDomain abstractValueDomain, MemberEntity member) {
+    if (member.isField) {
+      FieldEntity field = member;
+      DartType type = _elementEnvironment.getFieldType(field);
+      return FieldTypeInformation(abstractValueDomain, field, type);
+    } else if (member.isGetter) {
+      FunctionEntity getter = member;
+      DartType type = _elementEnvironment.getFunctionType(getter);
+      return GetterTypeInformation(abstractValueDomain, getter, type);
+    } else if (member.isSetter) {
+      FunctionEntity setter = member;
+      return SetterTypeInformation(abstractValueDomain, setter);
+    } else if (member.isFunction) {
+      FunctionEntity method = member;
+      DartType type = _elementEnvironment.getFunctionType(method);
+      return MethodTypeInformation(abstractValueDomain, method, type);
+    } else {
+      ConstructorEntity constructor = member;
+      if (constructor.isFactoryConstructor) {
+        DartType type = _elementEnvironment.getFunctionType(constructor);
+        return FactoryConstructorTypeInformation(
+            abstractValueDomain, constructor, type);
+      } else {
+        return GenerativeConstructorTypeInformation(
+            abstractValueDomain, constructor);
+      }
+    }
+  }
+}
+
+class KernelGlobalTypeInferenceElementData
+    implements GlobalTypeInferenceElementData {
+  /// Tag used for identifying serialized [GlobalTypeInferenceElementData]
+  /// objects in a debugging data stream.
+  static const String tag = 'global-type-inference-element-data';
+
+  Map<ir.TreeNode, AbstractValue> _receiverMap;
+
+  Map<ir.ForInStatement, AbstractValue> _iteratorMap;
+  Map<ir.ForInStatement, AbstractValue> _currentMap;
+  Map<ir.ForInStatement, AbstractValue> _moveNextMap;
+
+  KernelGlobalTypeInferenceElementData();
+
+  KernelGlobalTypeInferenceElementData.internal(this._receiverMap,
+      this._iteratorMap, this._currentMap, this._moveNextMap);
+
+  /// Deserializes a [GlobalTypeInferenceElementData] object from [source].
+  factory KernelGlobalTypeInferenceElementData.readFromDataSource(
+      DataSourceReader source,
+      ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
+    return source.inMemberContext(context, () {
+      source.begin(tag);
+      Map<ir.TreeNode, AbstractValue> sendMap =
+          source.readTreeNodeMapInContextOrNull(() =>
+              abstractValueDomain.readAbstractValueFromDataSource(source));
+      Map<ir.ForInStatement, AbstractValue> iteratorMap =
+          source.readTreeNodeMapInContextOrNull(() =>
+              abstractValueDomain.readAbstractValueFromDataSource(source));
+      Map<ir.ForInStatement, AbstractValue> currentMap =
+          source.readTreeNodeMapInContextOrNull(() =>
+              abstractValueDomain.readAbstractValueFromDataSource(source));
+      Map<ir.ForInStatement, AbstractValue> moveNextMap =
+          source.readTreeNodeMapInContextOrNull(() =>
+              abstractValueDomain.readAbstractValueFromDataSource(source));
+      source.end(tag);
+      return KernelGlobalTypeInferenceElementData.internal(
+          sendMap, iteratorMap, currentMap, moveNextMap);
+    });
+  }
+
+  @override
+  void writeToDataSink(DataSinkWriter sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
+    sink.inMemberContext(context, () {
+      sink.begin(tag);
+      sink.writeTreeNodeMapInContext(
+          _receiverMap,
+          (AbstractValue value) =>
+              abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+          allowNull: true);
+      sink.writeTreeNodeMapInContext(
+          _iteratorMap,
+          (AbstractValue value) =>
+              abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+          allowNull: true);
+      sink.writeTreeNodeMapInContext(
+          _currentMap,
+          (AbstractValue value) =>
+              abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+          allowNull: true);
+      sink.writeTreeNodeMapInContext(
+          _moveNextMap,
+          (AbstractValue value) =>
+              abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+          allowNull: true);
+      sink.end(tag);
+    });
+  }
+
+  @override
+  GlobalTypeInferenceElementData compress() {
+    if (_receiverMap != null) {
+      _receiverMap.removeWhere(_mapsToNull);
+      if (_receiverMap.isEmpty) {
+        _receiverMap = null;
+      }
+    }
+    if (_iteratorMap != null) {
+      _iteratorMap.removeWhere(_mapsToNull);
+      if (_iteratorMap.isEmpty) {
+        _iteratorMap = null;
+      }
+    }
+    if (_currentMap != null) {
+      _currentMap.removeWhere(_mapsToNull);
+      if (_currentMap.isEmpty) {
+        _currentMap = null;
+      }
+    }
+    if (_moveNextMap != null) {
+      _moveNextMap.removeWhere(_mapsToNull);
+      if (_moveNextMap.isEmpty) {
+        _moveNextMap = null;
+      }
+    }
+    if (_receiverMap == null &&
+        _iteratorMap == null &&
+        _currentMap == null &&
+        _moveNextMap == null) {
+      return null;
+    }
+    return this;
+  }
+
+  @override
+  AbstractValue typeOfReceiver(ir.TreeNode node) {
+    if (_receiverMap == null) return null;
+    return _receiverMap[node];
+  }
+
+  void setCurrentTypeMask(ir.ForInStatement node, AbstractValue mask) {
+    _currentMap ??= <ir.ForInStatement, AbstractValue>{};
+    _currentMap[node] = mask;
+  }
+
+  void setMoveNextTypeMask(ir.ForInStatement node, AbstractValue mask) {
+    _moveNextMap ??= <ir.ForInStatement, AbstractValue>{};
+    _moveNextMap[node] = mask;
+  }
+
+  void setIteratorTypeMask(ir.ForInStatement node, AbstractValue mask) {
+    _iteratorMap ??= <ir.ForInStatement, AbstractValue>{};
+    _iteratorMap[node] = mask;
+  }
+
+  @override
+  AbstractValue typeOfIteratorCurrent(covariant ir.ForInStatement node) {
+    if (_currentMap == null) return null;
+    return _currentMap[node];
+  }
+
+  @override
+  AbstractValue typeOfIteratorMoveNext(covariant ir.ForInStatement node) {
+    if (_moveNextMap == null) return null;
+    return _moveNextMap[node];
+  }
+
+  @override
+  AbstractValue typeOfIterator(covariant ir.ForInStatement node) {
+    if (_iteratorMap == null) return null;
+    return _iteratorMap[node];
+  }
+
+  void setReceiverTypeMask(ir.TreeNode node, AbstractValue mask) {
+    _receiverMap ??= <ir.TreeNode, AbstractValue>{};
+    _receiverMap[node] = mask;
+  }
+}
+
+bool _mapsToNull(ir.TreeNode node, AbstractValue value) => value == null;
diff --git a/pkg/compiler/lib/src/inferrer_experimental/engine_interfaces.dart b/pkg/compiler/lib/src/inferrer_experimental/engine_interfaces.dart
new file mode 100644
index 0000000..7965466
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/engine_interfaces.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2022, 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' as ir;
+
+import '../common/elements.dart';
+import '../elements/entities.dart';
+import '../js_backend/inferred_data.dart';
+import '../js_backend/no_such_method_registry_interfaces.dart';
+import '../native/behavior.dart';
+import '../universe/selector.dart';
+import '../world_interfaces.dart';
+import '../inferrer/abstract_value_domain.dart';
+import 'locals_handler.dart';
+import 'type_graph_nodes.dart';
+import 'type_system.dart';
+
+abstract class InferrerEngine {
+  AbstractValueDomain get abstractValueDomain;
+  TypeSystem get types;
+  JClosedWorld get closedWorld;
+  CommonElements get commonElements;
+  InferredDataBuilder get inferredDataBuilder;
+  FunctionEntity get mainElement;
+  NoSuchMethodData get noSuchMethodData;
+  Set<Selector> get returnsListElementTypeSet;
+
+  TypeInformation typeOfNativeBehavior(NativeBehavior nativeBehavior);
+  bool canFieldBeUsedForGlobalOptimizations(FieldEntity element);
+  bool assumeDynamic(MemberEntity member);
+  TypeInformation getDefaultTypeOfParameter(Local parameter);
+  bool canFunctionParametersBeUsedForGlobalOptimizations(
+      FunctionEntity function);
+  TypeInformation typeOfMemberWithSelector(
+      MemberEntity element, Selector? selector);
+  void updateSelectorInMember(MemberEntity owner, CallType callType,
+      ir.Node? node, Selector? selector, AbstractValue? mask);
+  void updateParameterInputs(TypeInformation caller, MemberEntity callee,
+      ArgumentsTypes? arguments, Selector? selector,
+      {required bool remove, bool addToQueue = true});
+  bool returnsListElementType(Selector selector, AbstractValue mask);
+  bool returnsMapValueType(Selector selector, AbstractValue mask);
+  void analyzeListAndEnqueue(ListTypeInformation info);
+  void analyzeSetAndEnqueue(SetTypeInformation info);
+  void analyzeMapAndEnqueue(MapTypeInformation info);
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/list_tracer.dart b/pkg/compiler/lib/src/inferrer_experimental/list_tracer.dart
new file mode 100644
index 0000000..6124abf
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/list_tracer.dart
@@ -0,0 +1,221 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library compiler.src.inferrer.list_tracer;
+
+import '../common/names.dart';
+import '../elements/entities.dart';
+import '../native/behavior.dart';
+import '../util/util.dart' show Setlet;
+import 'node_tracer.dart';
+import 'type_graph_nodes.dart';
+
+/// A set of selector names that [List] implements, that we know do not
+/// change the element type of the list, or let the list escape to code
+/// that might change the element type.
+Set<String> okListSelectorsSet = Set<String>.from(const <String>[
+  // From Object.
+  '==',
+  'hashCode',
+  'toString',
+  'noSuchMethod',
+  'runtimeType',
+
+  // From Iterable.
+  'iterator',
+  'map',
+  'where',
+  'expand',
+  'contains',
+  'forEach',
+  'reduce',
+  'fold',
+  'every',
+  'join',
+  'any',
+  'toList',
+  'toSet',
+  'length',
+  'isEmpty',
+  'isNotEmpty',
+  'take',
+  'takeWhile',
+  'skip',
+  'skipWhile',
+  'first',
+  'last',
+  'single',
+  'firstWhere',
+  'lastWhere',
+  'singleWhere',
+  'elementAt',
+
+  // From List.
+  '[]',
+  'length',
+  'reversed',
+  'sort',
+  'indexOf',
+  'lastIndexOf',
+  'clear',
+  'remove',
+  'removeAt',
+  'removeLast',
+  'removeWhere',
+  'retainWhere',
+  'sublist',
+  'getRange',
+  'removeRange',
+  'asMap',
+
+  // From JSArray.
+  'checkMutable',
+  'checkGrowable',
+]);
+
+Set<String> doNotChangeLengthSelectorsSet = Set<String>.from(const <String>[
+  // From Object.
+  '==',
+  'hashCode',
+  'toString',
+  'noSuchMethod',
+  'runtimeType',
+
+  // From Iterable.
+  'iterator',
+  'map',
+  'where',
+  'expand',
+  'contains',
+  'forEach',
+  'reduce',
+  'fold',
+  'every',
+  'join',
+  'any',
+  'toList',
+  'toSet',
+  'length',
+  'isEmpty',
+  'isNotEmpty',
+  'take',
+  'takeWhile',
+  'skip',
+  'skipWhile',
+  'first',
+  'last',
+  'single',
+  'firstWhere',
+  'lastWhere',
+  'singleWhere',
+  'elementAt',
+
+  // From List.
+  '[]',
+  '[]=',
+  'length',
+  'reversed',
+  'sort',
+  'indexOf',
+  'lastIndexOf',
+  'sublist',
+  'getRange',
+  'asMap',
+
+  // From JSArray.
+  'checkMutable',
+  'checkGrowable',
+]);
+
+class ListTracerVisitor extends TracerVisitor {
+  // The [Set] of found assignments to the list.
+  Set<TypeInformation> inputs = Setlet<TypeInformation>();
+  bool callsGrowableMethod = false;
+
+  ListTracerVisitor(super.tracedType, super.inferrer);
+
+  /// Returns [true] if the analysis completed successfully, [false] if it
+  /// bailed out. In the former case, [inputs] holds a list of
+  /// [TypeInformation] nodes that flow into the element type of this list.
+  bool run() {
+    analyze();
+    final list = tracedType as ListTypeInformation;
+    if (continueAnalyzing) {
+      if (!callsGrowableMethod && list.inferredLength == null) {
+        list.inferredLength = list.originalLength;
+      }
+      list.addFlowsIntoTargets(flowsInto);
+      return true;
+    } else {
+      callsGrowableMethod = true;
+      inputs.clear();
+      return false;
+    }
+  }
+
+  @override
+  visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
+    bailout('Passed to a closure');
+  }
+
+  @override
+  visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+    super.visitStaticCallSiteTypeInformation(info);
+    final commonElements = inferrer.closedWorld.commonElements;
+    MemberEntity called = info.calledElement;
+    if (commonElements.isForeign(called) && called.name == Identifiers.JS) {
+      NativeBehavior nativeBehavior = inferrer.closedWorld.elementMap
+          .getNativeBehaviorForJsCall(info.invocationNode);
+      // Assume side-effects means that the list has escaped to some unknown
+      // location.
+      if (nativeBehavior.sideEffects.hasSideEffects()) {
+        bailout('Used in JS ${info.debugName}');
+      }
+    }
+  }
+
+  @override
+  visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
+    super.visitDynamicCallSiteTypeInformation(info);
+    final selector = info.selector!;
+    String selectorName = selector.name;
+    final arguments = info.arguments;
+    if (currentUser == info.receiver) {
+      if (!okListSelectorsSet.contains(selectorName)) {
+        if (selector.isCall) {
+          int positionalLength = arguments!.positional.length;
+          if (selectorName == 'add') {
+            if (positionalLength == 1) {
+              inputs.add(arguments.positional[0]);
+            }
+          } else if (selectorName == 'insert') {
+            if (positionalLength == 2) {
+              inputs.add(arguments.positional[1]);
+            }
+          } else {
+            bailout('Used in a not-ok selector');
+            return;
+          }
+        } else if (selector.isIndexSet) {
+          inputs.add(arguments!.positional[1]);
+        } else if (!selector.isIndex) {
+          bailout('Used in a not-ok selector');
+          return;
+        }
+      }
+      if (!doNotChangeLengthSelectorsSet.contains(selectorName)) {
+        callsGrowableMethod = true;
+      }
+      if (selectorName == 'length' && selector.isSetter) {
+        callsGrowableMethod = true;
+        inputs.add(inferrer.types.nullType);
+      }
+    } else if (selector.isCall &&
+        (info.hasClosureCallTargets ||
+            info.concreteTargets.any((element) => !element.isFunction))) {
+      bailout('Passed to a closure');
+      return;
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/locals_handler.dart b/pkg/compiler/lib/src/inferrer_experimental/locals_handler.dart
new file mode 100644
index 0000000..a9c0265
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/locals_handler.dart
@@ -0,0 +1,607 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library locals_handler;
+
+import 'dart:collection' show IterableMixin;
+import 'package:kernel/ast.dart' as ir;
+import '../elements/entities.dart';
+import '../ir/util.dart';
+import '../util/util.dart';
+import 'engine_interfaces.dart';
+import 'type_graph_nodes.dart';
+
+/// A variable scope holds types for variables. It has a link to a
+/// parent scope, but never changes the types in that parent. Instead,
+/// updates to locals of a parent scope are put in the current scope.
+/// The inferrer makes sure updates get merged into the parent scope,
+/// once the control flow block has been visited.
+class VariableScope {
+  /// The number of parent scopes of this scope.
+  ///
+  /// This is used for computing common parents efficiently.
+  final int _level;
+
+  Map<Local, TypeInformation>? variables;
+
+  /// The parent of this scope. Null for the root scope.
+  final VariableScope? parent;
+
+  /// The [ir.Node] that created this scope.
+  final ir.Node? tryBlock;
+
+  final VariableScope? copyOf;
+
+  VariableScope({this.parent})
+      : this.variables = null,
+        this.copyOf = null,
+        this.tryBlock = null,
+        _level = (parent?._level ?? -1) + 1;
+
+  VariableScope.tryBlock(this.tryBlock, {this.parent})
+      : this.variables = null,
+        this.copyOf = null,
+        _level = (parent?._level ?? -1) + 1 {
+    assert(tryBlock is ir.TryCatch || tryBlock is ir.TryFinally,
+        "Unexpected block $tryBlock for VariableScope.tryBlock");
+  }
+
+  VariableScope.deepCopyOf(VariableScope other)
+      : variables = other.variables == null
+            ? null
+            : Map<Local, TypeInformation>.from(other.variables!),
+        tryBlock = other.tryBlock,
+        copyOf = other.copyOf ?? other,
+        _level = other._level,
+        parent = other.parent == null
+            ? null
+            : VariableScope.deepCopyOf(other.parent!);
+
+  /// `true` if this scope is for a try block.
+  bool get isTry => tryBlock != null;
+
+  /// Returns the [VariableScope] that defines the identity of this scope.
+  ///
+  /// If this scope is a copy of another scope, the identity is the identity
+  /// of the other scope, otherwise the identity is the scope itself.
+  VariableScope get identity => copyOf ?? this;
+
+  /// Returns the common parent between this and [other] based on [identity].
+  VariableScope? commonParent(VariableScope other) {
+    if (identity == other.identity) {
+      return identity;
+    } else if (_level > other._level) {
+      return parent!.commonParent(other);
+    } else if (_level < other._level) {
+      return commonParent(other.parent!);
+    } else if (_level > 0) {
+      return parent!.commonParent(other.parent!);
+    } else {
+      return null;
+    }
+  }
+
+  TypeInformation? operator [](Local variable) {
+    TypeInformation? result;
+    if (variables == null || (result = variables![variable]) == null) {
+      return parent == null ? null : parent![variable];
+    }
+    return result;
+  }
+
+  void operator []=(Local variable, TypeInformation mask) {
+    assert((mask as dynamic) != null); // TODO(48820): Remove when sound.
+    (variables ??= <Local, TypeInformation>{})[variable] = mask;
+  }
+
+  /// Calls [f] for all variables in this and parent scopes until and including
+  /// [scope]. [f] is called at most once for each variable.
+  void forEachLocalUntilScope(
+      VariableScope? scope, void f(Local variable, TypeInformation type)) {
+    _forEachLocalUntilScope(scope, f, Setlet<Local>(), this);
+  }
+
+  void _forEachLocalUntilScope(
+      VariableScope? scope,
+      void f(Local variable, TypeInformation type),
+      Setlet<Local> seenLocals,
+      VariableScope origin) {
+    if (variables != null) {
+      variables!.forEach((variable, type) {
+        if (seenLocals.contains(variable)) return;
+        seenLocals.add(variable);
+        f(variable, type);
+      });
+    }
+    if (scope?.identity == identity) {
+      return;
+    }
+    if (parent != null) {
+      parent!._forEachLocalUntilScope(scope, f, seenLocals, origin);
+    } else {
+      assert(
+          scope == null,
+          "Scope not found: \n"
+          "origin=${origin.toStructuredText('')}\n"
+          "scope=${scope.toStructuredText('')}");
+    }
+  }
+
+  void forEachLocal(void f(Local variable, TypeInformation type)) {
+    forEachLocalUntilScope(null, f);
+  }
+
+  bool updates(Local variable) {
+    if (variables == null) return false;
+    return variables!.containsKey(variable);
+  }
+
+  String toStructuredText(String indent) {
+    StringBuffer sb = StringBuffer();
+    _toStructuredText(sb, indent);
+    return sb.toString();
+  }
+
+  void _toStructuredText(StringBuffer sb, String indent) {
+    sb.write('VariableScope($hashCode) [');
+    sb.write('\n${indent}  level:$_level');
+    if (copyOf != null) {
+      sb.write('\n${indent}  copyOf:VariableScope(${copyOf.hashCode})');
+    }
+    if (tryBlock != null) {
+      sb.write('\n${indent}  tryBlock: ${nodeToDebugString(tryBlock!)}');
+    }
+    if (variables != null) {
+      sb.write('\n${indent}  variables:');
+      variables!.forEach((Local local, TypeInformation type) {
+        sb.write('\n${indent}    $local: ');
+        sb.write(type.toStructuredText('${indent}      '));
+      });
+    }
+    if (parent != null) {
+      sb.write('\n${indent}  parent:');
+      parent!._toStructuredText(sb, '${indent}     ');
+    }
+    sb.write(']');
+  }
+
+  @override
+  String toString() {
+    String rest = parent == null ? "null" : parent.toString();
+    return '{$variables} $rest';
+  }
+}
+
+/// Tracks initializers via initializations and assignments.
+class FieldInitializationScope {
+  Map<FieldEntity, TypeInformation>? fields;
+  bool isThisExposed;
+
+  /// `true` when control flow prevents accumulating definite assignments,
+  /// e.g. an early return or caught exception.
+  bool isIndefinite;
+
+  FieldInitializationScope()
+      : isThisExposed = false,
+        isIndefinite = false;
+
+  FieldInitializationScope.internalFrom(FieldInitializationScope other)
+      : isThisExposed = other.isThisExposed,
+        isIndefinite = other.isIndefinite;
+
+  static FieldInitializationScope? from(FieldInitializationScope? other) {
+    if (other == null) return null;
+    return FieldInitializationScope.internalFrom(other);
+  }
+
+  void updateField(FieldEntity field, TypeInformation type) {
+    if (isThisExposed) return;
+    if (isIndefinite) return;
+    (fields ??= <FieldEntity, TypeInformation>{})[field] = type;
+  }
+
+  TypeInformation? readField(FieldEntity field) {
+    return fields == null ? null : fields![field];
+  }
+
+  void forEach(void f(FieldEntity element, TypeInformation type)) {
+    fields?.forEach(f);
+  }
+
+  /// Returns the join between [thenScope] and [elseScope] which models the
+  /// flow through either [thenScope] or [elseScope].
+  FieldInitializationScope mergeDiamondFlow(InferrerEngine inferrer,
+      FieldInitializationScope thenScope, FieldInitializationScope elseScope) {
+    assert((elseScope as dynamic) != null); // TODO(48820): Remove when sound.
+
+    // Quick bailout check. If [isThisExposed] or [isIndefinite] is true, we
+    // know the code following won't do anything.
+    if (isThisExposed) return this;
+    if (isIndefinite) return this;
+
+    FieldInitializationScope otherScope =
+        elseScope.fields == null ? this : elseScope;
+
+    thenScope.forEach((FieldEntity field, TypeInformation type) {
+      final otherType = otherScope.readField(field);
+      if (otherType == null) return;
+      updateField(field, inferrer.types.allocateDiamondPhi(type, otherType));
+    });
+
+    isThisExposed = thenScope.isThisExposed || elseScope.isThisExposed;
+    isIndefinite = thenScope.isIndefinite || elseScope.isIndefinite;
+    return this;
+  }
+}
+
+/// Placeholder for inferred arguments types on sends.
+class ArgumentsTypes extends IterableMixin<TypeInformation> {
+  final List<TypeInformation> positional;
+  final Map<String, TypeInformation> named;
+
+  ArgumentsTypes(this.positional, Map<String, TypeInformation>? named)
+      : this.named = (named == null || named.isEmpty) ? const {} : named {
+    assert(this.positional.every((TypeInformation? type) => type != null));
+    assert(this.named.values.every((TypeInformation? type) => type != null));
+  }
+
+  ArgumentsTypes.empty()
+      : positional = const [],
+        named = const {};
+
+  @override
+  int get length => positional.length + named.length;
+
+  @override
+  Iterator<TypeInformation> get iterator => ArgumentsTypesIterator(this);
+
+  @override
+  String toString() => "{ positional = $positional, named = $named }";
+
+  @override
+  bool operator ==(Object? other) {
+    if (other is! ArgumentsTypes) return false;
+    if (positional.length != other.positional.length) return false;
+    if (named.length != other.named.length) return false;
+    for (int i = 0; i < positional.length; i++) {
+      if (positional[i] != other.positional[i]) return false;
+    }
+    var result = true;
+    named.forEach((name, type) {
+      if (other.named[name] != type) result = false;
+    });
+    return result;
+  }
+
+  @override
+  int get hashCode => throw UnsupportedError('ArgumentsTypes.hashCode');
+
+  bool hasNoArguments() => positional.isEmpty && named.isEmpty;
+
+  @override
+  void forEach(void f(TypeInformation type)) {
+    positional.forEach(f);
+    named.values.forEach(f);
+  }
+
+  @override
+  bool every(bool f(TypeInformation type)) {
+    return positional.every(f) && named.values.every(f);
+  }
+
+  @override
+  bool contains(Object? type) {
+    return positional.contains(type) || named.containsValue(type);
+  }
+}
+
+class ArgumentsTypesIterator implements Iterator<TypeInformation> {
+  final Iterator<TypeInformation> positional;
+  final Iterator<TypeInformation> named;
+  bool _iteratePositional = true;
+
+  ArgumentsTypesIterator(ArgumentsTypes iteratee)
+      : positional = iteratee.positional.iterator,
+        named = iteratee.named.values.iterator;
+
+  Iterator<TypeInformation> get _currentIterator =>
+      _iteratePositional ? positional : named;
+
+  @override
+  TypeInformation get current => _currentIterator.current;
+
+  @override
+  bool moveNext() {
+    if (_iteratePositional && positional.moveNext()) {
+      return true;
+    }
+    _iteratePositional = false;
+    return named.moveNext();
+  }
+}
+
+/// Placeholder for inferred types of local variables.
+class LocalsHandler {
+  final VariableScope _locals;
+
+  LocalsHandler() : _locals = VariableScope();
+
+  LocalsHandler.from(LocalsHandler other)
+      : _locals = VariableScope(parent: other._locals);
+
+  LocalsHandler.tryBlock(LocalsHandler other, ir.TreeNode block)
+      : _locals = VariableScope.tryBlock(block, parent: other._locals);
+
+  LocalsHandler.deepCopyOf(LocalsHandler other)
+      : _locals = VariableScope.deepCopyOf(other._locals);
+
+  TypeInformation? use(Local local) {
+    return _locals[local];
+  }
+
+  void update(InferrerEngine inferrer, Local local, TypeInformation type,
+      LocalsHandler? tryBlock) {
+    if (tryBlock != null) {
+      // We don't know if an assignment in a try block
+      // will be executed, so all assignments in that block are
+      // potential types after we have left it. We update the parent
+      // of the try block so that, at exit of the try block, we get
+      // the right phi for it.
+      final existing = tryBlock._locals.parent![local];
+      if (existing != null) {
+        final phiType = inferrer.types.allocatePhi(
+            tryBlock._locals.tryBlock, local, existing,
+            isTry: tryBlock._locals.isTry);
+        final inputType = inferrer.types.addPhiInput(local, phiType, type);
+        tryBlock._locals.parent![local] = inputType;
+      }
+      // Update the current handler unconditionally with the new
+      // type.
+      _locals[local] = type;
+    } else {
+      _locals[local] = type;
+    }
+  }
+
+  /// Returns the join between this locals handler and [other] which models the
+  /// flow through either this or [other].
+  ///
+  /// If [inPlace] is `true`, the variable types in this locals handler are
+  /// replaced by the variables types in [other]. Otherwise the variable types
+  /// from both are merged with a phi type.
+  LocalsHandler mergeFlow(InferrerEngine inferrer, LocalsHandler other,
+      {bool inPlace = false}) {
+    final common = _locals.commonParent(other._locals);
+    assert(
+        common != null,
+        "No common parent for\n"
+        "1:${_locals.toStructuredText('  ')}\n"
+        "2:${other._locals.toStructuredText('  ')}");
+    assert(
+        common == _locals || _locals.variables == null,
+        "Non-empty common parent for\n"
+        "1:${common?.toStructuredText('  ')}\n"
+        "2:${_locals.toStructuredText('  ')}");
+    other._locals.forEachLocalUntilScope(common,
+        (Local local, TypeInformation type) {
+      final myType = _locals[local];
+      if (myType == null) return; // Variable is only defined in [other].
+      if (type == myType) return;
+      _locals[local] =
+          inPlace ? type : inferrer.types.allocateDiamondPhi(myType, type);
+    });
+    return this;
+  }
+
+  /// Returns the join between [thenBranch] and [elseBranch] which models the
+  /// flow through either [thenBranch] or [elseBranch].
+  LocalsHandler mergeDiamondFlow(InferrerEngine inferrer,
+      LocalsHandler thenBranch, LocalsHandler elseBranch) {
+    assert((elseBranch as dynamic) != null); // TODO(48820): Remove when sound.
+
+    void mergeLocal(Local local) {
+      final myType = _locals[local];
+      if (myType == null) return;
+      final elseType = elseBranch._locals[local]!;
+      final thenType = thenBranch._locals[local]!;
+      if (thenType == elseType) {
+        _locals[local] = thenType;
+      } else {
+        _locals[local] = inferrer.types.allocateDiamondPhi(thenType, elseType);
+      }
+    }
+
+    final common = _locals.commonParent(thenBranch._locals);
+    assert(
+        common != null,
+        "No common parent for\n"
+        "1:${_locals.toStructuredText('  ')}\n"
+        "2:${thenBranch._locals.toStructuredText('  ')}");
+    assert(
+        _locals.commonParent(elseBranch._locals) == common,
+        "Diff common parent for\n"
+        "1:${common?.toStructuredText('  ')}\n2:"
+        "${_locals.commonParent(elseBranch._locals)?.toStructuredText('  ')}");
+    assert(
+        common == _locals || _locals.variables == null,
+        "Non-empty common parent for\n"
+        "common:${common?.toStructuredText('  ')}\n"
+        "1:${_locals.toStructuredText('  ')}\n"
+        "2:${thenBranch._locals.toStructuredText('  ')}");
+    thenBranch._locals.forEachLocalUntilScope(common, (Local local, _) {
+      mergeLocal(local);
+    });
+    elseBranch._locals.forEachLocalUntilScope(common, (Local local, _) {
+      // Discard locals we already processed when iterating over
+      // [thenBranch]'s locals.
+      if (!thenBranch._locals.updates(local)) mergeLocal(local);
+    });
+    return this;
+  }
+
+  /// Merge all [LocalsHandler] in [handlers] into [:this:].
+  ///
+  /// If [keepOwnLocals] is true, the types of locals in this
+  /// [LocalsHandler] are being used in the merge. [keepOwnLocals]
+  /// should be true if this [LocalsHandler], the dominator of
+  /// all [handlers], also directly flows into the join point,
+  /// that is the code after all [handlers]. For example, consider:
+  ///
+  /// [: switch (...) {
+  ///      case 1: ...; break;
+  ///    }
+  /// :]
+  ///
+  /// The [LocalsHandler] at entry of the switch also flows into the
+  /// exit of the switch, because there is no default case. So the
+  /// types of locals at entry of the switch have to take part to the
+  /// merge.
+  ///
+  /// The above situation is also true for labeled statements like
+  ///
+  /// [: L: {
+  ///      if (...) break;
+  ///      ...
+  ///    }
+  /// :]
+  ///
+  /// where [:this:] is the [LocalsHandler] for the paths through the
+  /// labeled statement that do not break out.
+  LocalsHandler mergeAfterBreaks(
+      InferrerEngine inferrer, Iterable<LocalsHandler> handlers,
+      {bool keepOwnLocals = true}) {
+    final tryBlock = _locals.tryBlock;
+    // Use a separate locals handler to perform the merge in, so that Phi
+    // creation does not invalidate previous type knowledge while we might
+    // still look it up.
+    VariableScope merged = tryBlock != null
+        ? VariableScope.tryBlock(tryBlock, parent: _locals)
+        : VariableScope(parent: _locals);
+    Set<Local> seenLocals = Setlet<Local>();
+    // Merge all other handlers.
+    for (LocalsHandler handler in handlers) {
+      final common = _locals.commonParent(handler._locals);
+      assert(
+          common != null,
+          "No common parent for\n"
+          "1:${_locals.toStructuredText('  ')}\n"
+          "2:${handler._locals.toStructuredText('  ')}");
+      assert(
+          common == _locals || _locals.variables == null,
+          "Non-empty common parent for\n"
+          "common:${common?.toStructuredText('  ')}\n"
+          "1:${_locals.toStructuredText('  ')}\n"
+          "2:${handler._locals.toStructuredText('  ')}");
+      handler._locals.forEachLocalUntilScope(common, (local, otherType) {
+        final myType = merged[local];
+        if (myType == null) return;
+        TypeInformation newType;
+        if (!seenLocals.contains(local)) {
+          newType = inferrer.types.allocatePhi(
+              merged.tryBlock, local, otherType,
+              isTry: merged.isTry);
+          seenLocals.add(local);
+        } else {
+          newType = inferrer.types.addPhiInput(
+              local, myType as PhiElementTypeInformation, otherType);
+        }
+        if (newType != myType) {
+          merged[local] = newType;
+        }
+      });
+    }
+    // If we want to keep own locals, we merge [seenLocals] from [this] into
+    // [merged] to update the Phi nodes with original values.
+    if (keepOwnLocals) {
+      for (Local variable in seenLocals) {
+        final originalType = _locals[variable];
+        if (originalType != null) {
+          merged[variable] = inferrer.types.addPhiInput(variable,
+              merged[variable] as PhiElementTypeInformation, originalType);
+        }
+      }
+    }
+    // Clean up Phi nodes with single input and store back result into
+    // actual locals handler.
+    merged.forEachLocalUntilScope(merged,
+        (Local variable, TypeInformation type) {
+      _locals[variable] = inferrer.types
+          .simplifyPhi(tryBlock, variable, type as PhiElementTypeInformation);
+    });
+    return this;
+  }
+
+  /// Merge all [LocalsHandler] in [handlers] into this handler.
+  /// Returns whether a local in this handler has changed.
+  bool mergeAll(InferrerEngine inferrer, Iterable<LocalsHandler> handlers) {
+    bool changed = false;
+    handlers.forEach((LocalsHandler other) {
+      final common = _locals.commonParent(other._locals);
+      assert(
+          common != null,
+          "No common parent for\n"
+          "1:${_locals.toStructuredText('  ')}\n"
+          "2:${other._locals.toStructuredText('  ')}");
+      assert(
+          common == _locals || _locals.variables == null,
+          "Non-empty common parent for\n"
+          "common:${common?.toStructuredText('  ')}\n"
+          "1:${_locals.toStructuredText('  ')}\n"
+          "2:${other._locals.toStructuredText('  ')}");
+      other._locals.forEachLocalUntilScope(common, (local, otherType) {
+        final myType = _locals[local];
+        if (myType == null) return;
+        TypeInformation newType = inferrer.types
+            .addPhiInput(local, myType as PhiElementTypeInformation, otherType);
+        if (newType != myType) {
+          changed = true;
+          _locals[local] = newType;
+        }
+      });
+    });
+    return changed;
+  }
+
+  void startLoop(InferrerEngine inferrer, ir.Node loop) {
+    _locals.forEachLocal((Local variable, TypeInformation type) {
+      TypeInformation newType =
+          inferrer.types.allocateLoopPhi(loop, variable, type, isTry: false);
+      if (newType != type) {
+        _locals[variable] = newType;
+      }
+    });
+  }
+
+  void endLoop(InferrerEngine inferrer, ir.Node loop) {
+    _locals.forEachLocal((Local variable, TypeInformation type) {
+      final newType = inferrer.types
+          .simplifyPhi(loop, variable, type as PhiElementTypeInformation);
+      if (newType != type) {
+        _locals[variable] = newType;
+      }
+    });
+  }
+
+  String toStructuredText(String indent) {
+    StringBuffer sb = StringBuffer();
+    _toStructuredText(sb, indent);
+    return sb.toString();
+  }
+
+  void _toStructuredText(StringBuffer sb, String indent) {
+    sb.write('LocalsHandler($hashCode) [');
+    sb.write('\n${indent}  locals:');
+    _locals._toStructuredText(sb, '${indent}    ');
+    sb.write('\n]');
+  }
+
+  @override
+  String toString() {
+    StringBuffer sb = StringBuffer();
+    sb.write('LocalsHandler(');
+    sb.write('locals=$_locals');
+    sb.write(')');
+    return sb.toString();
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/map_tracer.dart b/pkg/compiler/lib/src/inferrer_experimental/map_tracer.dart
new file mode 100644
index 0000000..fe3bf6b
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/map_tracer.dart
@@ -0,0 +1,134 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library compiler.src.inferrer.map_tracer;
+
+import '../common/names.dart';
+import '../elements/entities.dart';
+import 'node_tracer.dart';
+import 'type_graph_nodes.dart';
+
+Set<String> okMapSelectorsSet = Set.from(const <String>[
+  // From Object.
+  "==",
+  "hashCode",
+  "toString",
+  "noSuchMethod",
+  "runtimeType",
+  // From Map
+  "[]",
+  "isEmpty",
+  "isNotEmpty",
+  "keys",
+  "length",
+  "values",
+  "clear",
+  "containsKey",
+  "containsValue",
+  "forEach",
+  "remove"
+]);
+
+class MapTracerVisitor extends TracerVisitor {
+  // These lists are used to keep track of newly discovered assignments to
+  // the map. Note that elements at corresponding indices are expected to
+  // belong to the same assignment operation.
+  List<TypeInformation> keyInputs = <TypeInformation>[];
+  List<TypeInformation> valueInputs = <TypeInformation>[];
+  // This list is used to keep track of assignments of entire maps to
+  // this map.
+  List<MapTypeInformation> mapInputs = <MapTypeInformation>[];
+
+  MapTracerVisitor(super.tracedType, super.inferrer);
+
+  /// Returns [true] if the analysis completed successfully, [false]
+  /// if it bailed out. In the former case, [keyInputs] and
+  /// [valueInputs] hold a list of [TypeInformation] nodes that
+  /// flow into the key and value types of this map.
+  bool run() {
+    analyze();
+    final map = tracedType as MapTypeInformation;
+    if (continueAnalyzing) {
+      map.addFlowsIntoTargets(flowsInto);
+      return true;
+    }
+    keyInputs.clear();
+    valueInputs.clear();
+    mapInputs.clear();
+    return false;
+  }
+
+  @override
+  visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
+    bailout('Passed to a closure');
+  }
+
+  @override
+  visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+    super.visitStaticCallSiteTypeInformation(info);
+    MemberEntity called = info.calledElement;
+    if (inferrer.closedWorld.commonElements.isForeign(called) &&
+        called.name == Identifiers.JS) {
+      bailout('Used in JS ${info.debugName}');
+    }
+  }
+
+  @override
+  visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
+    super.visitDynamicCallSiteTypeInformation(info);
+    final selector = info.selector!;
+    final selectorName = selector.name;
+    final arguments = info.arguments;
+    if (currentUser == info.receiver) {
+      if (!okMapSelectorsSet.contains(selectorName)) {
+        if (selector.isCall) {
+          if (selectorName == 'addAll') {
+            // All keys and values from the argument flow into
+            // the map.
+            TypeInformation map = arguments!.positional[0];
+            if (map is MapTypeInformation) {
+              inferrer.analyzeMapAndEnqueue(map);
+              mapInputs.add(map);
+            } else {
+              // If we could select a component from a [TypeInformation],
+              // like the keytype or valuetype in this case, we could
+              // propagate more here.
+              // TODO(herhut): implement selection on [TypeInformation].
+              bailout('Adding map with unknown typeinfo to current map');
+            }
+          } else if (selectorName == 'putIfAbsent') {
+            // The first argument is a new key, the result type of
+            // the second argument becomes a new value.
+            // Unfortunately, the type information does not
+            // explicitly track the return type, yet, so we have
+            // to go to dynamic.
+            // TODO(herhut,16507): Use return type of closure in
+            // Map.putIfAbsent.
+            keyInputs.add(arguments!.positional[0]);
+            valueInputs.add(inferrer.types.dynamicType);
+          } else {
+            // It would be nice to handle [Map.keys] and [Map.values], too.
+            // However, currently those calls do not trigger the creation
+            // of a [ListTypeInformation], so I have nowhere to propagate
+            // that information.
+            // TODO(herhut): add support for Map.keys and Map.values.
+            bailout('Map used in a not-ok selector [$selectorName]');
+            return;
+          }
+        } else if (selector.isIndexSet) {
+          keyInputs.add(arguments!.positional[0]);
+          valueInputs.add(arguments.positional[1]);
+        } else if (!selector.isIndex) {
+          bailout('Map used in a not-ok selector [$selectorName]');
+          return;
+        }
+      }
+    } else if (selector.isCall &&
+        (info.hasClosureCallTargets ||
+            info.concreteTargets.any((element) => !element.isFunction))) {
+      bailout('Passed to a closure');
+      return;
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/node_tracer.dart b/pkg/compiler/lib/src/inferrer_experimental/node_tracer.dart
new file mode 100644
index 0000000..84b3059
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/node_tracer.dart
@@ -0,0 +1,560 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library compiler.src.inferrer.node_tracer;
+
+import '../common/names.dart' show Identifiers;
+import '../elements/entities.dart';
+import '../util/util.dart' show Setlet;
+import '../inferrer/abstract_value_domain.dart';
+import 'debug.dart' as debug;
+import 'engine_interfaces.dart';
+import 'type_graph_nodes.dart';
+
+// A set of selectors we know do not escape the elements inside the
+// list.
+Set<String> doesNotEscapeListSet = Set<String>.from(const <String>[
+  // From Object.
+  '==',
+  'hashCode',
+  'toString',
+  'noSuchMethod',
+  'runtimeType',
+
+  // From Iterable.
+  'isEmpty',
+  'isNotEmpty',
+  'length',
+  'contains',
+  'join',
+
+  // From List.
+  'add',
+  'addAll',
+  'clear',
+  'fillRange',
+  'indexOf',
+  'insert',
+  'insertAll',
+  'lastIndexOf',
+  'remove',
+  'removeRange',
+  'replaceRange',
+  'setAll',
+  'setRange',
+  'shuffle',
+  '[]=',
+
+  // From JSArray.
+  'checkMutable',
+  'checkGrowable',
+]);
+
+Set<String> doesNotEscapeSetSet = Set<String>.from(const <String>[
+  // From Object.
+  '==',
+  'hashCode',
+  'toString',
+  'noSuchMethod',
+  'runtimeType',
+
+  // From Iterable.
+  'isEmpty',
+  'isNotEmpty',
+  'length',
+  'contains',
+  'join',
+
+  // From Set.
+  'add',
+  'addAll',
+  'clear',
+  'containsAll',
+  'remove',
+  'removeAll',
+  'retainAll',
+]);
+
+Set<String> doesNotEscapeMapSet = Set<String>.from(const <String>[
+  // From Object.
+  '==',
+  'hashCode',
+  'toString',
+  'noSuchMethod',
+  'runtimeType',
+  // from Map.
+  'isEmpty',
+  'isNotEmpty',
+  'length',
+  'clear',
+  'containsKey',
+  'containsValue',
+  '[]=',
+  // [keys] only allows key values to escape, which we do not track.
+  'keys'
+]);
+
+/// Common logic to trace a value through the type inference graph nodes.
+abstract class TracerVisitor implements TypeInformationVisitor {
+  final TypeInformation tracedType;
+  final InferrerEngine inferrer;
+
+  static const int MAX_ANALYSIS_COUNT =
+      int.fromEnvironment('dart2js.tracing.limit', defaultValue: 32);
+  // TODO(natebiggs): We allow null here to maintain current functionality
+  // but we should verify we actually need to allow it.
+  final Setlet<MemberEntity> analyzedElements = Setlet<MemberEntity>();
+
+  TracerVisitor(this.tracedType, this.inferrer);
+
+  /// Work list that gets populated with [TypeInformation] that could
+  /// contain the container.
+  final List<TypeInformation> workList = <TypeInformation>[];
+
+  /// Work list of lists to analyze after analyzing the users of a
+  /// [TypeInformation]. We know the [tracedType] has been stored in these
+  /// lists and we must check how it escapes from these lists.
+  final List<ListTypeInformation> listsToAnalyze = <ListTypeInformation>[];
+
+  /// Work list of sets to analyze after analyzing the users of a
+  /// [TypeInformation]. We know the [tracedType] has been stored in these sets
+  /// and we must check how it escapes from these sets.
+  final List<SetTypeInformation> setsToAnalyze = <SetTypeInformation>[];
+
+  /// Work list of maps to analyze after analyzing the users of a
+  /// [TypeInformation]. We know the [tracedType] has been stored in these
+  /// maps and we must check how it escapes from these maps.
+  final List<MapTypeInformation> mapsToAnalyze = <MapTypeInformation>[];
+
+  final Setlet<TypeInformation> flowsInto = Setlet<TypeInformation>();
+
+  // The current [TypeInformation] in the analysis.
+  TypeInformation? currentUser;
+  bool continueAnalyzing = true;
+
+  void addNewEscapeInformation(TypeInformation info) {
+    if (flowsInto.contains(info)) return;
+    flowsInto.add(info);
+    workList.add(info);
+  }
+
+  bool _wouldBeTooManyUsers(Set users) {
+    int seenSoFar = analyzedElements.length;
+    if (seenSoFar + users.length <= MAX_ANALYSIS_COUNT) return false;
+    int actualWork = 0;
+    for (TypeInformation user in users) {
+      if (!analyzedElements.contains(user.owner)) {
+        actualWork++;
+        if (actualWork > MAX_ANALYSIS_COUNT - seenSoFar) return true;
+      }
+    }
+    return false;
+  }
+
+  void analyze() {
+    // Collect the [TypeInformation] where the list can flow in,
+    // as well as the operations done on all these [TypeInformation]s.
+    addNewEscapeInformation(tracedType);
+    while (!workList.isEmpty) {
+      final user = currentUser = workList.removeLast();
+      if (_wouldBeTooManyUsers(user.users)) {
+        bailout('Too many users');
+        break;
+      }
+      for (final info in user.users) {
+        analyzedElements.add(info.owner!);
+        info.accept(this);
+      }
+      while (!listsToAnalyze.isEmpty) {
+        analyzeStoredIntoList(listsToAnalyze.removeLast());
+      }
+      while (setsToAnalyze.isNotEmpty) {
+        analyzeStoredIntoSet(setsToAnalyze.removeLast());
+      }
+      while (!mapsToAnalyze.isEmpty) {
+        analyzeStoredIntoMap(mapsToAnalyze.removeLast());
+      }
+      if (!continueAnalyzing) break;
+    }
+  }
+
+  void bailout(String reason) {
+    if (debug.VERBOSE) {
+      print('Bailing out on $tracedType because: $reason');
+    }
+    continueAnalyzing = false;
+  }
+
+  @override
+  void visitAwaitTypeInformation(AwaitTypeInformation info) {
+    bailout("Passed through await");
+  }
+
+  @override
+  void visitYieldTypeInformation(YieldTypeInformation info) {
+    // TODO(29344): The enclosing sync*/async/async* method could have a
+    // tracable TypeInformation for the Iterable / Future / Stream with an
+    // element TypeInformation. Then YieldTypeInformation could connect the
+    // source type information to the tracable element.
+    bailout("Passed through yield");
+  }
+
+  @override
+  void visitNarrowTypeInformation(NarrowTypeInformation info) {
+    addNewEscapeInformation(info);
+  }
+
+  @override
+  void visitPhiElementTypeInformation(PhiElementTypeInformation info) {
+    addNewEscapeInformation(info);
+  }
+
+  @override
+  void visitElementInContainerTypeInformation(
+      ElementInContainerTypeInformation info) {
+    addNewEscapeInformation(info);
+  }
+
+  @override
+  void visitElementInSetTypeInformation(ElementInSetTypeInformation info) {
+    addNewEscapeInformation(info);
+  }
+
+  @override
+  void visitKeyInMapTypeInformation(KeyInMapTypeInformation info) {
+    // We do not track the use of keys from a map, so we have to bail.
+    bailout('Used as key in Map');
+  }
+
+  @override
+  void visitValueInMapTypeInformation(ValueInMapTypeInformation info) {
+    addNewEscapeInformation(info);
+  }
+
+  @override
+  void visitListTypeInformation(ListTypeInformation info) {
+    listsToAnalyze.add(info);
+  }
+
+  @override
+  void visitSetTypeInformation(SetTypeInformation info) {
+    setsToAnalyze.add(info);
+  }
+
+  @override
+  void visitMapTypeInformation(MapTypeInformation info) {
+    mapsToAnalyze.add(info);
+  }
+
+  @override
+  void visitConcreteTypeInformation(ConcreteTypeInformation info) {}
+
+  @override
+  void visitStringLiteralTypeInformation(StringLiteralTypeInformation info) {}
+
+  @override
+  void visitBoolLiteralTypeInformation(BoolLiteralTypeInformation info) {}
+
+  @override
+  void visitClosureTypeInformation(ClosureTypeInformation info) {}
+
+  @override
+  void visitClosureCallSiteTypeInformation(
+      ClosureCallSiteTypeInformation info) {}
+
+  @override
+  visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+    MemberEntity called = info.calledElement;
+    TypeInformation inferred = inferrer.types.getInferredTypeOfMember(called);
+    if (inferred == currentUser) {
+      addNewEscapeInformation(info);
+    }
+  }
+
+  void analyzeStoredIntoList(ListTypeInformation list) {
+    inferrer.analyzeListAndEnqueue(list);
+    if (list.bailedOut) {
+      bailout('Stored in a list that bailed out');
+    } else {
+      list.flowsInto.forEach((TypeInformation flow) {
+        flow.users.forEach((TypeInformation user) {
+          if (user is DynamicCallSiteTypeInformation) {
+            if (user.receiver != flow) return;
+            if (inferrer.returnsListElementTypeSet.contains(user.selector)) {
+              addNewEscapeInformation(user);
+            } else if (!doesNotEscapeListSet.contains(user.selector?.name)) {
+              bailout('Escape from a list via [${user.selector?.name}]');
+            }
+          }
+        });
+      });
+    }
+  }
+
+  void analyzeStoredIntoSet(SetTypeInformation set) {
+    inferrer.analyzeSetAndEnqueue(set);
+    if (set.bailedOut) {
+      bailout('Stored in a set that bailed out');
+    } else {
+      set.flowsInto.forEach((TypeInformation flow) {
+        flow.users.forEach((TypeInformation user) {
+          if (user is DynamicCallSiteTypeInformation) {
+            if (user.receiver != flow) return;
+            final selector = user.selector!;
+            if (selector.isIndex) {
+              addNewEscapeInformation(user);
+            } else if (!doesNotEscapeSetSet.contains(selector.name)) {
+              bailout('Escape from a set via [${selector.name}]');
+            }
+          }
+        });
+      });
+    }
+  }
+
+  void analyzeStoredIntoMap(MapTypeInformation map) {
+    inferrer.analyzeMapAndEnqueue(map);
+    if (map.bailedOut) {
+      bailout('Stored in a map that bailed out');
+    } else {
+      map.flowsInto.forEach((TypeInformation flow) {
+        flow.users.forEach((TypeInformation user) {
+          if (user is DynamicCallSiteTypeInformation) {
+            if (user.receiver != flow) return;
+            final selector = user.selector!;
+            if (selector.isIndex) {
+              addNewEscapeInformation(user);
+            } else if (!doesNotEscapeMapSet.contains(selector.name)) {
+              bailout('Escape from a map via [${selector.name}]');
+            }
+          }
+        });
+      });
+    }
+  }
+
+  /// Checks whether this is a call to a list adding method. The definition of
+  /// what list adding means has to stay in sync with
+  /// [isParameterOfListAddingMethod].
+  bool mightAddToContainer(DynamicCallSiteTypeInformation info) {
+    final arguments = info.arguments;
+    if (arguments == null) return false;
+    if (arguments.named.isNotEmpty) return false;
+    String selectorName = info.selector!.name;
+    List<TypeInformation> positionalArguments = arguments.positional;
+    if (positionalArguments.length == 1) {
+      return (selectorName == 'add' && currentUser == positionalArguments[0]);
+    } else if (arguments.length == 2) {
+      return (selectorName == 'insert' &&
+          currentUser == positionalArguments[1]);
+    }
+    return false;
+  }
+
+  bool isIndexSetArgument(DynamicCallSiteTypeInformation info, int index) {
+    final selectorName = info.selector!.name;
+    if (selectorName != '[]=') return false;
+    assert(info.arguments!.length == 2);
+    List<TypeInformation> arguments = info.arguments!.positional;
+    return currentUser == arguments[index];
+  }
+
+  /// Checks whether the call site flows the currentUser to the key argument of
+  /// an indexing setter. This must be kept in sync with
+  /// [isParameterOfMapAddingMethod].
+  bool isIndexSetKey(DynamicCallSiteTypeInformation info) {
+    return isIndexSetArgument(info, 0);
+  }
+
+  /// Checks whether the call site flows the currentUser to the value argument
+  /// of an indexing setter. This must be kept in sync with
+  /// [isParameterOfListAddingMethod] and [isParameterOfMapAddingMethod].
+  bool isIndexSetValue(DynamicCallSiteTypeInformation info) {
+    return isIndexSetArgument(info, 1);
+  }
+
+  void bailoutIfReaches(bool predicate(ParameterTypeInformation e)) {
+    for (var user in currentUser!.users) {
+      if (user is ParameterTypeInformation) {
+        if (predicate(user)) {
+          bailout('Reached suppressed parameter without precise receiver');
+          break;
+        }
+      }
+    }
+  }
+
+  @override
+  void visitDynamicCallSiteTypeInformation(
+      DynamicCallSiteTypeInformation info) {
+    void addsToContainer(AbstractValue mask) {
+      final allocationNode =
+          inferrer.abstractValueDomain.getAllocationNode(mask);
+      if (allocationNode != null) {
+        final list = inferrer.types.allocatedLists[allocationNode]
+            as ListTypeInformation;
+        listsToAnalyze.add(list);
+      } else {
+        // The [mask] is a union of two containers, and we lose track of where
+        // these containers have been allocated at this point.
+        bailout('Stored in too many containers');
+      }
+    }
+
+    void addsToMapValue(AbstractValue mask) {
+      final allocationNode =
+          inferrer.abstractValueDomain.getAllocationNode(mask);
+      if (allocationNode != null) {
+        final map =
+            inferrer.types.allocatedMaps[allocationNode] as MapTypeInformation;
+        mapsToAnalyze.add(map);
+      } else {
+        // The [mask] is a union. See comment for [mask] above.
+        bailout('Stored in too many maps');
+      }
+    }
+
+    void addsToMapKey(AbstractValue mask) {
+      // We do not track the use of keys from a map, so we have to bail.
+      bailout('Used as key in Map');
+    }
+
+    // "a[...] = x" could be a list (container) or map assignemnt.
+    if (isIndexSetValue(info)) {
+      var receiverType = info.receiver.type;
+      if (inferrer.abstractValueDomain.isContainer(receiverType)) {
+        addsToContainer(receiverType);
+      } else if (inferrer.abstractValueDomain.isMap(receiverType)) {
+        addsToMapValue(receiverType);
+      } else {
+        // Not a container or map, so the targets could be any methods. There
+        // are edges from the [currentUser] to the parameters of the targets, so
+        // tracing will continue into the targets.  Tracing stops at parameters
+        // that match the targets corresponding to the receiverTypes above (to
+        // prevent imprecise results from tracing the implementation), so we
+        // need compensate if one of the targets is in the target set. If there
+        // is an edge to a parameter matching [isParameterOfListAddingMethod] or
+        // [isParameterOfMapAddingMethod] then the traced value is being stored
+        // into an untraced list or map.
+
+        // TODO(sra): It would be more precise to specifically match the `value'
+        // parameters of "operator []=".
+        bailoutIfReaches(isParameterOfListAddingMethod);
+        bailoutIfReaches(isParameterOfMapAddingMethod);
+      }
+    }
+
+    // Could be:  m[x] = ...;
+    if (isIndexSetKey(info)) {
+      var receiverType = info.receiver.type;
+      if (inferrer.abstractValueDomain.isMap(receiverType)) {
+        addsToMapKey(receiverType);
+      } else {
+        bailoutIfReaches(isParameterOfListAddingMethod);
+        bailoutIfReaches(isParameterOfMapAddingMethod);
+      }
+    }
+
+    if (mightAddToContainer(info)) {
+      var receiverType = info.receiver.type;
+      if (inferrer.abstractValueDomain.isContainer(receiverType)) {
+        addsToContainer(receiverType);
+      } else {
+        // Not a container, see note above.
+        bailoutIfReaches(isParameterOfListAddingMethod);
+      }
+    }
+
+    final arguments = info.arguments;
+    if (info.targetsIncludeComplexNoSuchMethod(inferrer) &&
+        arguments != null &&
+        arguments.contains(currentUser)) {
+      bailout('Passed to noSuchMethod');
+    }
+
+    Iterable<TypeInformation> inferredTargetTypes =
+        info.concreteTargets.map((MemberEntity entity) {
+      return inferrer.types.getInferredTypeOfMember(entity);
+    });
+    if (inferredTargetTypes.any((user) => user == currentUser)) {
+      addNewEscapeInformation(info);
+    }
+  }
+
+  /// Check whether element is the parameter of a list adding method.
+  /// The definition of what a list adding method is has to stay in sync with
+  /// [mightAddToContainer].
+  bool isParameterOfListAddingMethod(ParameterTypeInformation parameterInfo) {
+    if (!parameterInfo.isRegularParameter) return false;
+    if (parameterInfo.method.enclosingClass !=
+        inferrer.closedWorld.commonElements.jsArrayClass) {
+      return false;
+    }
+    final name = parameterInfo.method.name;
+    return (name == '[]=') || (name == 'add') || (name == 'insert');
+  }
+
+  /// Check whether element is the parameter of a list adding method.
+  /// The definition of what a list adding method is has to stay in sync with
+  /// [isIndexSetKey] and [isIndexSetValue].
+  bool isParameterOfMapAddingMethod(ParameterTypeInformation parameterInfo) {
+    if (!parameterInfo.isRegularParameter) return false;
+    if (parameterInfo.method.enclosingClass !=
+        inferrer.closedWorld.commonElements.mapLiteralClass) {
+      return false;
+    }
+    final name = parameterInfo.method.name;
+    return (name == '[]=');
+  }
+
+  bool isClosure(MemberEntity element) {
+    if (!element.isFunction) return false;
+
+    /// Creating an instance of a class that implements [Function] also
+    /// closurizes the corresponding [call] member. We do not currently
+    /// track these, thus the check for [isClosurized] on such a method will
+    /// return false. Instead we catch that case here for now.
+    // TODO(herhut): Handle creation of closures from instances of Function.
+    if (element.isInstanceMember && element.name == Identifiers.call) {
+      return true;
+    }
+    final cls = element.enclosingClass;
+    return cls != null && cls.isClosure;
+  }
+
+  @override
+  void visitMemberTypeInformation(MemberTypeInformation info) {
+    if (info.isClosurized) {
+      bailout('Returned from a closurized method');
+    }
+    if (isClosure(info.member)) {
+      bailout('Returned from a closure');
+    }
+
+    final member = info.member;
+    if (member is FieldEntity &&
+        !inferrer.canFieldBeUsedForGlobalOptimizations(member)) {
+      bailout('Escape to code that has special backend treatment');
+    }
+    addNewEscapeInformation(info);
+  }
+
+  @override
+  void visitParameterTypeInformation(ParameterTypeInformation info) {
+    if (inferrer.closedWorld.nativeData.isNativeMember(info.method)) {
+      bailout('Passed to a native method');
+    }
+    if (!inferrer
+        .canFunctionParametersBeUsedForGlobalOptimizations(info.method)) {
+      bailout('Escape to code that has special backend treatment');
+    }
+    if (isParameterOfListAddingMethod(info) ||
+        isParameterOfMapAddingMethod(info)) {
+      // These elements are being handled in
+      // [visitDynamicCallSiteTypeInformation].
+      return;
+    }
+    addNewEscapeInformation(info);
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/powersets/powerset_bits.dart b/pkg/compiler/lib/src/inferrer_experimental/powersets/powerset_bits.dart
new file mode 100644
index 0000000..7eb0dce
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/powersets/powerset_bits.dart
@@ -0,0 +1,628 @@
+// 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 '../../common/elements.dart' show CommonElements;
+import '../../constants/values.dart';
+import '../../elements/entities.dart';
+import '../../elements/names.dart';
+import '../../elements/types.dart';
+import '../../ir/class_relation.dart';
+import '../../universe/selector.dart';
+import '../../world_interfaces.dart';
+import '../../inferrer/abstract_value_domain.dart';
+
+/// This class is used to store bits information about class entities.
+class ClassInfo {
+  final int exactBits;
+  final int strictSubtypeBits;
+  final int strictSubclassBits;
+
+  const ClassInfo(
+      this.exactBits, this.strictSubtypeBits, this.strictSubclassBits);
+}
+
+/// This class is used as an API by the powerset abstract value domain to help
+/// implement some queries. It stores the bitmasks as integers and has the
+/// advantage that the operations needed are relatively fast. This will pack
+/// multiple powerset domains into a single integer.
+class PowersetBitsDomain {
+  final JClosedWorld _closedWorld;
+  final Map<ClassEntity, ClassInfo> _storedClassInfo = {};
+
+  static const int _trueIndex = 0;
+  static const int _falseIndex = 1;
+  static const int _nullIndex = 2;
+  static const int _otherIndex = 3;
+
+  static const int _interceptorIndex = 4;
+  static const int _notInterceptorIndex = 5;
+  static const int _nullInterceptorIndex = 6;
+
+  static const int _maxIndex = _nullInterceptorIndex;
+  static const List<int> _singletonIndices = [
+    _trueIndex,
+    _falseIndex,
+    _nullIndex,
+  ];
+
+  static const List<String> _bitNames = [
+    'true',
+    'false',
+    'null',
+    'other',
+    'interceptor',
+    'notInterceptor',
+    'null'
+  ];
+
+  PowersetBitsDomain(this._closedWorld);
+
+  CommonElements get commonElements => _closedWorld.commonElements;
+
+  DartTypes get dartTypes => _closedWorld.dartTypes;
+
+  int get trueMask => 1 << _trueIndex;
+  int get falseMask => 1 << _falseIndex;
+  int get nullMask => 1 << _nullIndex;
+  int get otherMask => 1 << _otherIndex;
+  int get boolMask => trueMask | falseMask;
+  int get boolOrNullMask => boolMask | nullMask;
+  int get nullOrOtherMask => nullMask | otherMask;
+  int get boolNullOtherMask => boolOrNullMask | otherMask;
+  int get preciseMask => _singletonIndices.fold(
+      powersetBottom, (mask, index) => mask | 1 << index);
+
+  int get interceptorMask => 1 << _interceptorIndex;
+  int get notInterceptorMask => 1 << _notInterceptorIndex;
+  int get nullInterceptorMask => 1 << _nullInterceptorIndex;
+  int get interceptorDomainMask =>
+      interceptorMask | notInterceptorMask | nullInterceptorMask;
+
+  int get powersetBottom => 0;
+  int get powersetTop => (1 << _maxIndex + 1) - 1;
+
+  int get trueValue => trueMask | interceptorMask;
+  int get falseValue => falseMask | interceptorMask;
+  int get boolValue => boolMask | interceptorMask;
+  int get nullValue => nullMask | nullInterceptorMask;
+  int get otherValue => otherMask | interceptorMask | notInterceptorMask;
+  int get interceptorOtherValue => otherMask | interceptorMask;
+
+  bool isPotentiallyBoolean(int value) => (value & boolMask) != 0;
+  bool isPotentiallyNull(int value) => (value & nullMask) != 0;
+  bool isPotentiallyOther(int value) => (value & otherMask) != 0;
+  bool isPotentiallyInterceptor(int value) => (value & interceptorMask) != 0;
+  bool isPotentiallyNotInterceptor(int value) =>
+      (value & notInterceptorMask) != 0;
+  bool isPotentiallyNullInterceptor(int value) =>
+      (value & notInterceptorMask) != 0;
+
+  bool isDefinitelyTrue(int value) => value == trueValue;
+  bool isDefinitelyFalse(int value) => value == falseValue;
+  bool isDefinitelyNull(int value) => value == nullValue;
+
+  bool isSingleton(int value) =>
+      isDefinitelyTrue(value) ||
+      isDefinitelyFalse(value) ||
+      isDefinitelyNull(value);
+
+  /// Returns `true` if only singleton bits are set and `false` otherwise.
+  bool isPrecise(int value) => value & ~preciseMask == 0;
+
+  AbstractBool isOther(int value) =>
+      AbstractBool.maybeOrFalse(isPotentiallyOther(value));
+
+  /// Returns a descriptive string for [bits]
+  static String toText(int bits, {bool omitIfTop = false}) {
+    int boolNullOtherMask = (1 << _otherIndex + 1) - 1;
+    int interceptorDomainMask =
+        (1 << _nullInterceptorIndex + 1) - (1 << _interceptorIndex);
+    return _toTextDomain(bits, interceptorDomainMask, omitIfTop) +
+        _toTextDomain(bits, boolNullOtherMask, omitIfTop);
+  }
+
+  /// Returns a descriptive string for a subset of [bits] defined by
+  /// [domainMask]. If [omitIfTop] is `true` and all the bits in the
+  /// [domainMask] are set, an empty string is returned.
+  static String _toTextDomain(int bits, int domainMask, bool omitIfTop) {
+    bits &= domainMask;
+    if (bits == domainMask && omitIfTop) return '';
+    final sb = StringBuffer();
+    sb.write('{');
+    String comma = '';
+    while (bits != 0) {
+      int lowestBit = bits & ~(bits - 1);
+      int index = lowestBit.bitLength - 1;
+      sb.write(comma);
+      sb.write(_bitNames[index]);
+      comma = ',';
+      bits &= ~lowestBit;
+    }
+    sb.write('}');
+    return '$sb';
+  }
+
+  AbstractBool _isIn(int subset, int superset) {
+    if (union(subset, superset) == superset) {
+      if (isPrecise(superset)) return AbstractBool.True;
+    } else {
+      if (isPrecise(subset)) return AbstractBool.False;
+    }
+    return AbstractBool.Maybe;
+  }
+
+  AbstractBool isIn(int subset, int superset) {
+    // TODO(coam): We can also take advantage of other bits to be more precise
+    return _isIn(subset & boolNullOtherMask, superset & boolNullOtherMask);
+  }
+
+  AbstractBool needsNoSuchMethodHandling(int receiver, Selector selector) =>
+      AbstractBool.Maybe;
+
+  AbstractBool isTargetingMember(
+          int receiver, MemberEntity member, Name name) =>
+      AbstractBool.Maybe;
+
+  int computeReceiver(Iterable<MemberEntity> members) {
+    return powersetTop;
+  }
+
+  // TODO(coam): This currently returns null if we are not sure if it's a primitive.
+  // It could be improved because we can also tell when we're certain it's not a primitive.
+  PrimitiveConstantValue? getPrimitiveValue(int value) {
+    if (isDefinitelyTrue(value)) {
+      return TrueConstantValue();
+    }
+    if (isDefinitelyFalse(value)) {
+      return FalseConstantValue();
+    }
+    if (isDefinitelyNull(value)) {
+      return NullConstantValue();
+    }
+    return null;
+  }
+
+  int createPrimitiveValue(PrimitiveConstantValue value) {
+    return computeAbstractValueForConstant(value);
+  }
+
+  // TODO(coam): Same as getPrimitiveValue above.
+  bool isPrimitiveValue(int value) => isSingleton(value);
+
+  int computeAbstractValueForConstant(ConstantValue value) {
+    if (value is TrueConstantValue) {
+      return trueValue;
+    }
+    if (value is FalseConstantValue) {
+      return falseValue;
+    }
+    if (value is NullConstantValue) {
+      return nullValue;
+    }
+
+    // TODO(coam): We could be more precise if we implement a visitor to
+    // ConstantValue
+    // TODO(fishythefish): Naively calling `getType` on
+    // [LateSentinelConstantValue] will produce Never.
+    return createFromStaticType(value.getType(commonElements), nullable: false);
+  }
+
+  AbstractBool areDisjoint(int a, int b) {
+    int overlap = intersection(a, b);
+    if (overlap & interceptorDomainMask == powersetBottom) {
+      return AbstractBool.True;
+    }
+    if (overlap & boolNullOtherMask == powersetBottom) return AbstractBool.True;
+    if (isPrecise(overlap)) return AbstractBool.False;
+    return AbstractBool.Maybe;
+  }
+
+  int intersection(int a, int b) {
+    return a & b;
+  }
+
+  int union(int a, int b) {
+    return a | b;
+  }
+
+  AbstractBool isPrimitiveOrNull(int value) => isPrimitive(excludeNull(value));
+
+  AbstractBool isStringOrNull(int value) => isString(excludeNull(value));
+
+  AbstractBool isString(int value) => isOther(value);
+
+  AbstractBool isBooleanOrNull(int value) => isBoolean(excludeNull(value));
+
+  AbstractBool isBoolean(int value) {
+    if (!isPotentiallyBoolean(value)) return AbstractBool.False;
+    if (value & ~boolMask == 0) return AbstractBool.True;
+    return AbstractBool.Maybe;
+  }
+
+  AbstractBool isTruthy(int value) {
+    if (value & ~trueMask == 0) return AbstractBool.True;
+    if (value & ~(falseMask | nullMask) == 0) return AbstractBool.False;
+    return AbstractBool.Maybe;
+  }
+
+  AbstractBool isNumberOrNull(int value) => isNumber(excludeNull(value));
+
+  AbstractBool isNumber(int value) => isOther(value);
+
+  AbstractBool isIntegerOrNull(int value) => isInteger(excludeNull(value));
+
+  AbstractBool isPositiveIntegerOrNull(int value) =>
+      isPositiveInteger(excludeNull(value));
+
+  AbstractBool isPositiveInteger(int value) => isOther(value);
+
+  AbstractBool isUInt31(int value) => isOther(value);
+
+  AbstractBool isUInt32(int value) => isOther(value);
+
+  AbstractBool isInteger(int value) => isOther(value);
+
+  AbstractBool isInterceptor(int value) {
+    if (!isPotentiallyInterceptor(value)) return AbstractBool.False;
+    if (isPotentiallyNotInterceptor(value)) return AbstractBool.Maybe;
+    return AbstractBool.True;
+  }
+
+  AbstractBool isPrimitiveString(int value) => isOther(value);
+
+  AbstractBool isArray(int value) => isOther(value);
+
+  AbstractBool isMutableIndexable(int value) => isOther(value);
+
+  AbstractBool isMutableArray(int value) => isOther(value);
+
+  AbstractBool isExtendableArray(int value) => isOther(value);
+
+  AbstractBool isFixedArray(int value) => isOther(value);
+
+  AbstractBool isIndexablePrimitive(int value) => isOther(value);
+
+  AbstractBool isPrimitiveBoolean(int value) {
+    if (isDefinitelyTrue(value) || isDefinitelyFalse(value)) {
+      return AbstractBool.True;
+    }
+    if (!isPotentiallyBoolean(value)) return AbstractBool.False;
+    return AbstractBool.Maybe;
+  }
+
+  AbstractBool isPrimitiveNumber(int value) => isOther(value);
+
+  AbstractBool isPrimitive(int value) =>
+      AbstractBool.trueOrMaybe(isSingleton(value));
+
+  AbstractBool isNull(int value) => isDefinitelyNull(value)
+      ? AbstractBool.True
+      : (isPotentiallyNull(value) ? AbstractBool.Maybe : AbstractBool.False);
+
+  // TODO(fishythefish): Support tracking late sentinels in the powerset domain.
+  AbstractBool isLateSentinel(int value) => AbstractBool.Maybe;
+
+  AbstractBool isExact(int value) => AbstractBool.Maybe;
+
+  AbstractBool isEmpty(int value) {
+    if (value & interceptorDomainMask == powersetBottom)
+      return AbstractBool.True;
+    if (value & boolNullOtherMask == powersetBottom) return AbstractBool.True;
+    if (isPrecise(value)) return AbstractBool.False;
+    return AbstractBool.Maybe;
+  }
+
+  AbstractBool isInstanceOf(int value, ClassEntity cls) => AbstractBool.Maybe;
+
+  AbstractBool isInstanceOfOrNull(int value, ClassEntity cls) =>
+      AbstractBool.Maybe;
+
+  AbstractBool containsAll(int value) =>
+      AbstractBool.maybeOrFalse(value == powersetTop);
+
+  AbstractBool containsOnlyType(int value, ClassEntity cls) =>
+      AbstractBool.Maybe;
+
+  AbstractBool containsType(int value, ClassEntity cls) => AbstractBool.Maybe;
+
+  int includeNull(int value) {
+    return value | nullValue;
+  }
+
+  int excludeNull(int value) {
+    return value & ~nullValue;
+  }
+
+  // TODO(fishythefish): Support tracking late sentinels in the powerset domain.
+  int includeLateSentinel(int value) => value;
+
+  // TODO(fishythefish): Support tracking late sentinels in the powerset domain.
+  int excludeLateSentinel(int value) => value;
+
+  AbstractBool couldBeTypedArray(int value) => isOther(value);
+
+  AbstractBool isTypedArray(int value) => AbstractBool.Maybe;
+
+  bool _isBoolSubtype(ClassEntity cls) {
+    return cls == commonElements.jsBoolClass || cls == commonElements.boolClass;
+  }
+
+  bool _isNullSubtype(ClassEntity cls) {
+    return cls == commonElements.jsNullClass || cls == commonElements.nullClass;
+  }
+
+  ClassInfo _computeClassInfo(ClassEntity cls) {
+    ClassInfo? classInfo = _storedClassInfo[cls];
+    if (classInfo != null) {
+      return classInfo;
+    }
+
+    // Handle null case specially
+    if (_isNullSubtype(cls)) {
+      classInfo = ClassInfo(nullValue, powersetBottom, powersetBottom);
+      _storedClassInfo[cls] = classInfo;
+      return classInfo;
+    }
+
+    // Handle bool and JSBool specially. Both appear to be 'instantiated' but
+    // only JSBool is really instantiated.
+    if (_isBoolSubtype(cls)) {
+      int exactBits = boolMask | interceptorMask;
+      classInfo = ClassInfo(exactBits, powersetBottom, powersetBottom);
+      _storedClassInfo[cls] = classInfo;
+      return classInfo;
+    }
+
+    // Compute interceptor and notInterceptor bits first
+    int interceptorBits = powersetBottom;
+    if (_closedWorld.classHierarchy.isInstantiated(cls)) {
+      if (_closedWorld.classHierarchy
+          .isSubclassOf(cls, commonElements.jsInterceptorClass)) {
+        interceptorBits |= interceptorMask;
+      } else {
+        interceptorBits |= notInterceptorMask;
+      }
+    }
+
+    int exactBits = interceptorBits;
+    if (_closedWorld.classHierarchy.isInstantiated(cls)) {
+      // If cls is instantiated or live by default the 'other' bit should be set to 1.
+      exactBits |= otherMask;
+    }
+
+    int strictSubtypeBits = powersetBottom;
+    for (ClassEntity strictSubtype
+        in _closedWorld.classHierarchy.strictSubtypesOf(cls)) {
+      // Currently null is a subtype of Object in the class hierarchy but we don't
+      // want to consider it as a subtype of a nonnull class
+      if (!_isNullSubtype(strictSubtype)) {
+        strictSubtypeBits |= _computeClassInfo(strictSubtype).exactBits;
+      }
+    }
+
+    int strictSubclassBits = powersetBottom;
+    for (ClassEntity strictSubclass
+        in _closedWorld.classHierarchy.strictSubclassesOf(cls)) {
+      // Currently null is a subtype of Object in the class hierarchy but we don't
+      // want to consider it as a subtype of a nonnull class
+      if (!_isNullSubtype(strictSubclass)) {
+        strictSubclassBits |= _computeClassInfo(strictSubclass).exactBits;
+      }
+    }
+
+    classInfo = ClassInfo(exactBits, strictSubtypeBits, strictSubclassBits);
+    _storedClassInfo[cls] = classInfo;
+    return classInfo;
+  }
+
+  int createNullableSubtype(ClassEntity cls) {
+    return includeNull(createNonNullSubtype(cls));
+  }
+
+  int createNonNullSubtype(ClassEntity cls) {
+    ClassInfo classInfo = _computeClassInfo(cls);
+    return classInfo.exactBits | classInfo.strictSubtypeBits;
+  }
+
+  int createNonNullSubclass(ClassEntity cls) {
+    ClassInfo classInfo = _computeClassInfo(cls);
+    return classInfo.exactBits | classInfo.strictSubclassBits;
+  }
+
+  int createNullableExact(ClassEntity cls) {
+    return includeNull(createNonNullExact(cls));
+  }
+
+  int createNonNullExact(ClassEntity cls) {
+    ClassInfo classInfo = _computeClassInfo(cls);
+    return classInfo.exactBits;
+  }
+
+  int createFromStaticType(DartType type,
+      {ClassRelation classRelation = ClassRelation.subtype,
+      required bool nullable}) {
+    // TODO(48820): Remove after sound null safety is enabled.
+    // ignore: unnecessary_null_comparison
+    assert(nullable != null);
+
+    if ((classRelation == ClassRelation.subtype ||
+            classRelation == ClassRelation.thisExpression) &&
+        dartTypes.isTopType(type)) {
+      // A cone of a top type includes all values. This would be 'precise' if we
+      // tracked that.
+      return dynamicType;
+    }
+
+    if (type is NullableType) {
+      return _createFromStaticType(type.baseType, classRelation, true);
+    }
+
+    if (type is LegacyType) {
+      DartType baseType = type.baseType;
+      if (baseType is NeverType) {
+        // Never* is same as Null, for both 'is' and 'as'.
+        return nullMask;
+      }
+
+      // Object* is a top type for both 'is' and 'as'. This is handled in the
+      // 'cone of top type' case above.
+
+      return _createFromStaticType(baseType, classRelation, nullable);
+    }
+
+    if (dartTypes.useLegacySubtyping) {
+      // In legacy and weak mode, `String` is nullable depending on context.
+      return _createFromStaticType(type, classRelation, nullable);
+    } else {
+      // In strong mode nullability comes from explicit NullableType.
+      return _createFromStaticType(type, classRelation, false);
+    }
+  }
+
+  int _createFromStaticType(
+      DartType type, ClassRelation classRelation, bool nullable) {
+    int finish(int value, bool isPrecise) {
+      // [isPrecise] is ignored since we only treat singleton partitions as
+      // precise.
+      // TODO(sra): Each bit that represents more that one concrete value could
+      // have an 'isPrecise' bit.
+      return nullable ? includeNull(value) : value;
+    }
+
+    bool isPrecise = true;
+    while (type is TypeVariableType) {
+      TypeVariableType typeVariable = type;
+      type = _closedWorld.elementEnvironment
+          .getTypeVariableBound(typeVariable.element);
+      classRelation = ClassRelation.subtype;
+      isPrecise = false;
+      if (type is NullableType) {
+        // <A extends B?, B extends num>  ...  null is A --> can be `true`.
+        // <A extends B, B extends num?>  ...  null is A --> can be `true`.
+        nullable = true;
+        type = type.withoutNullability;
+      }
+    }
+
+    if ((classRelation == ClassRelation.thisExpression ||
+            classRelation == ClassRelation.subtype) &&
+        dartTypes.isTopType(type)) {
+      // A cone of a top type includes all values. Since we already tested this
+      // in [createFromStaticType], we get here only for type parameter bounds.
+      return finish(dynamicType, isPrecise);
+    }
+
+    if (type is InterfaceType) {
+      ClassEntity cls = type.element;
+      List<DartType> arguments = type.typeArguments;
+      if (isPrecise && arguments.isNotEmpty) {
+        // Can we ignore the type arguments?
+        //
+        // For legacy covariance, if the interface type is a generic interface
+        // type and is maximal (i.e. instantiated to bounds), the typemask,
+        // which is based on the class element, is still precise. We check
+        // against Top for the parameter arguments since we don't have a
+        // convenient check for instantiation to bounds.
+        //
+        // TODO(sra): Check arguments against bounds.
+        // TODO(sra): Handle other variances.
+        List<Variance> variances = dartTypes.getTypeVariableVariances(cls);
+        for (int i = 0; i < arguments.length; i++) {
+          Variance variance = variances[i];
+          DartType argument = arguments[i];
+          if (variance == Variance.legacyCovariant &&
+              dartTypes.isTopType(argument)) {
+            continue;
+          }
+          isPrecise = false;
+        }
+      }
+      switch (classRelation) {
+        case ClassRelation.exact:
+          return finish(createNonNullExact(cls), isPrecise);
+        case ClassRelation.thisExpression:
+          if (!_closedWorld.isUsedAsMixin(cls)) {
+            return finish(createNonNullSubclass(cls), isPrecise);
+          }
+          break;
+        case ClassRelation.subtype:
+          break;
+      }
+      return finish(createNonNullSubtype(cls), isPrecise);
+    }
+
+    if (type is FunctionType) {
+      return finish(createNonNullSubtype(commonElements.functionClass), false);
+    }
+
+    if (type is NeverType) {
+      return finish(emptyType, isPrecise);
+    }
+
+    return finish(dynamicType, false);
+  }
+
+  int get internalTopType => powersetTop;
+
+  int get dynamicType => powersetTop;
+
+  int get asyncStarStreamType => powersetTop;
+
+  int get asyncFutureType => powersetTop;
+
+  int get syncStarIterableType => powersetTop;
+
+  int get emptyType => powersetBottom;
+
+  late final int constMapType =
+      createNonNullSubtype(commonElements.constMapLiteralClass);
+
+  int get constSetType => otherValue;
+
+  late final int constListType =
+      createNonNullExact(commonElements.jsUnmodifiableArrayClass);
+
+  late final int fixedListType =
+      createNonNullExact(commonElements.jsFixedArrayClass);
+
+  late final int growableListType =
+      createNonNullExact(commonElements.jsExtendableArrayClass);
+
+  late final int mutableArrayType =
+      createNonNullSubtype(commonElements.jsMutableArrayClass);
+
+  int get nullType => nullValue;
+
+  int get nonNullType => powersetTop & ~nullValue;
+
+  // TODO(fishythefish): Support tracking late sentinels in the powerset domain.
+  int get lateSentinelType => powersetBottom;
+
+  late final int mapType = createNonNullSubtype(commonElements.mapLiteralClass);
+
+  late final int setType = createNonNullSubtype(commonElements.setLiteralClass);
+
+  late final int listType = createNonNullExact(commonElements.jsArrayClass);
+
+  late final int stringType =
+      createNonNullSubtype(commonElements.jsStringClass);
+
+  late final int numType = createNonNullSubclass(commonElements.jsNumberClass);
+
+  late final int numNotIntType =
+      createNonNullExact(commonElements.jsNumNotIntClass);
+
+  late final int intType = createNonNullSubtype(commonElements.jsIntClass);
+
+  int get positiveIntType => intType;
+  int get uint32Type => intType;
+  int get uint31Type => intType;
+
+  int get boolType => boolValue;
+
+  late final int functionType =
+      createNonNullSubtype(commonElements.functionClass);
+
+  int get typeType => otherValue;
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/powersets/powersets.dart b/pkg/compiler/lib/src/inferrer_experimental/powersets/powersets.dart
new file mode 100644
index 0000000..86bad4e
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/powersets/powersets.dart
@@ -0,0 +1,874 @@
+// Copyright (c) 2018, 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 '../../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
+import '../../elements/entities.dart';
+import '../../elements/names.dart';
+import '../../elements/types.dart' show DartType;
+import '../../ir/class_relation.dart';
+import '../../serialization/serialization.dart';
+import '../../universe/selector.dart';
+import '../../universe/world_builder.dart';
+import '../../universe/use.dart';
+import '../../world_interfaces.dart';
+import '../../inferrer/abstract_value_domain.dart';
+import '../../inferrer/abstract_value_strategy.dart';
+import 'powerset_bits.dart';
+
+class PowersetValue implements AbstractValue {
+  final AbstractValue _abstractValue;
+  final int _powersetBits;
+  PowersetValue(this._abstractValue, this._powersetBits);
+
+  AbstractValue get abstractValue => _abstractValue;
+  int get powersetBits => _powersetBits;
+
+  @override
+  bool operator ==(var other) {
+    if (identical(this, other)) return true;
+    if (other is! PowersetValue) return false;
+    return _abstractValue == other._abstractValue &&
+        _powersetBits == other._powersetBits;
+  }
+
+  @override
+  int get hashCode {
+    return _abstractValue.hashCode * _powersetBits.hashCode;
+  }
+
+  @override
+  String toString() =>
+      '${PowersetBitsDomain.toText(_powersetBits, omitIfTop: true)}'
+      '${_abstractValue}';
+}
+
+AbstractValue? unwrapOrNull(PowersetValue? powerset) {
+  return powerset?._abstractValue;
+}
+
+PowersetValue? wrapOrNull(AbstractValue? abstractValue, int powersetBits) {
+  return abstractValue == null
+      ? null
+      : PowersetValue(abstractValue, powersetBits);
+}
+
+class PowersetDomain implements AbstractValueDomain {
+  final AbstractValueDomain _abstractValueDomain;
+  final PowersetBitsDomain _powersetBitsDomain;
+
+  const PowersetDomain(this._abstractValueDomain, this._powersetBitsDomain);
+
+  PowersetBitsDomain get powersetBitsDomain => _powersetBitsDomain;
+
+  @override
+  AbstractValue get internalTopType => PowersetValue(
+      _abstractValueDomain.internalTopType,
+      _powersetBitsDomain.internalTopType);
+
+  @override
+  AbstractValue get dynamicType => PowersetValue(
+      _abstractValueDomain.dynamicType, _powersetBitsDomain.dynamicType);
+
+  //TODO(coam)
+  @override
+  void writeAbstractValueToDataSink(
+      DataSinkWriter sink, covariant PowersetValue value) {
+    _abstractValueDomain.writeAbstractValueToDataSink(
+        sink, value._abstractValue);
+  }
+
+  //TODO(coam)
+  @override
+  AbstractValue readAbstractValueFromDataSource(DataSourceReader source) {
+    int powersetBits = _powersetBitsDomain.powersetTop;
+    AbstractValue abstractValue =
+        _abstractValueDomain.readAbstractValueFromDataSource(source);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  //TODO(coam)
+  @override
+  String getCompactText(covariant PowersetValue value) =>
+      _abstractValueDomain.getCompactText(value._abstractValue);
+
+  @override
+  AbstractBool isFixedLengthJsIndexable(covariant PowersetValue value) =>
+      _powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse
+          ? AbstractBool.False
+          : _abstractValueDomain.isFixedLengthJsIndexable(value._abstractValue);
+
+  @override
+  AbstractBool isJsIndexableAndIterable(covariant PowersetValue value) =>
+      _powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse
+          ? AbstractBool.False
+          : _abstractValueDomain.isJsIndexableAndIterable(value._abstractValue);
+
+  @override
+  AbstractBool isJsIndexable(covariant PowersetValue value) =>
+      _powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse
+          ? AbstractBool.False
+          : _abstractValueDomain.isJsIndexable(value._abstractValue);
+
+  @override
+  MemberEntity? locateSingleMember(
+          covariant PowersetValue receiver, Selector selector) =>
+      _abstractValueDomain.locateSingleMember(
+          receiver._abstractValue, selector);
+
+  @override
+  AbstractBool isIn(
+          covariant PowersetValue subset, covariant PowersetValue superset) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isIn(
+              subset._powersetBits, superset._powersetBits),
+          _abstractValueDomain.isIn(
+              subset._abstractValue, superset._abstractValue));
+
+  @override
+  AbstractBool needsNoSuchMethodHandling(
+          covariant PowersetValue receiver, Selector selector) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.needsNoSuchMethodHandling(
+              receiver._powersetBits, selector),
+          _abstractValueDomain.needsNoSuchMethodHandling(
+              receiver._abstractValue, selector));
+
+  @override
+  AbstractBool isTargetingMember(
+          covariant PowersetValue receiver, MemberEntity member, Name name) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isTargetingMember(
+              receiver._powersetBits, member, name),
+          _abstractValueDomain.isTargetingMember(
+              receiver._abstractValue, member, name));
+
+  @override
+  AbstractValue computeReceiver(Iterable<MemberEntity> members) {
+    int powersetBits = _powersetBitsDomain.computeReceiver(members);
+    AbstractValue abstractValue = _abstractValueDomain.computeReceiver(members);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  PrimitiveConstantValue? getPrimitiveValue(covariant PowersetValue value) =>
+      _powersetBitsDomain.getPrimitiveValue(value.powersetBits) ??
+      _abstractValueDomain.getPrimitiveValue(value._abstractValue);
+
+  @override
+  AbstractValue createPrimitiveValue(
+      covariant PowersetValue originalValue, PrimitiveConstantValue value) {
+    int powersetBits = _powersetBitsDomain.createPrimitiveValue(value);
+    AbstractValue abstractValue = _abstractValueDomain.createPrimitiveValue(
+        originalValue._abstractValue, value);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  bool isPrimitiveValue(covariant PowersetValue value) =>
+      _powersetBitsDomain.isPrimitiveValue(value.powersetBits) ||
+      _abstractValueDomain.isPrimitiveValue(value._abstractValue);
+
+  @override
+  MemberEntity? getAllocationElement(covariant PowersetValue value) =>
+      _abstractValueDomain.getAllocationElement(value._abstractValue);
+
+  @override
+  Object? getAllocationNode(covariant PowersetValue value) =>
+      _abstractValueDomain.getAllocationNode(value._abstractValue);
+
+  @override
+  AbstractValue getGeneralization(covariant PowersetValue value) {
+    int powersetBits = _powersetBitsDomain.powersetTop;
+    final abstractValue =
+        _abstractValueDomain.getGeneralization(unwrapOrNull(value))!;
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  bool isSpecializationOf(covariant PowersetValue specialization,
+          covariant PowersetValue generalization) =>
+      _abstractValueDomain.isSpecializationOf(
+          specialization._abstractValue, generalization._abstractValue);
+
+  @override
+  AbstractValue getDictionaryValueForKey(
+      covariant PowersetValue value, String key) {
+    if (_powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse) {
+      return dynamicType;
+    }
+    AbstractValue abstractValue = _abstractValueDomain.getDictionaryValueForKey(
+        value._abstractValue, key);
+    return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop);
+  }
+
+  @override
+  bool containsDictionaryKey(covariant PowersetValue value, String key) =>
+      _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue &&
+      _abstractValueDomain.containsDictionaryKey(value._abstractValue, key);
+
+  @override
+  AbstractValue createDictionaryValue(
+      covariant PowersetValue originalValue,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
+      covariant PowersetValue key,
+      covariant PowersetValue value,
+      covariant Map<String, AbstractValue> mappings) {
+    final powersetBits = originalValue._powersetBits;
+    AbstractValue abstractValue = _abstractValueDomain.createDictionaryValue(
+        originalValue._abstractValue,
+        allocationNode,
+        allocationElement,
+        key._abstractValue,
+        value._abstractValue, {
+      for (var entry in mappings.entries)
+        entry.key: (entry.value as PowersetValue)._abstractValue
+    });
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  bool isDictionary(covariant PowersetValue value) =>
+      _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue &&
+      _abstractValueDomain.isDictionary(value._abstractValue);
+
+  @override
+  AbstractValue getMapValueType(covariant PowersetValue value) {
+    if (_powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse) {
+      return dynamicType;
+    }
+    AbstractValue abstractValue =
+        _abstractValueDomain.getMapValueType(value._abstractValue);
+    return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop);
+  }
+
+  @override
+  AbstractValue getMapKeyType(covariant PowersetValue value) {
+    if (_powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse) {
+      return dynamicType;
+    }
+    AbstractValue abstractValue =
+        _abstractValueDomain.getMapValueType(value._abstractValue);
+    return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop);
+  }
+
+  @override
+  AbstractValue createMapValue(
+      covariant PowersetValue originalValue,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
+      covariant PowersetValue key,
+      covariant PowersetValue value) {
+    int powersetBits = originalValue._powersetBits;
+    AbstractValue abstractValue = _abstractValueDomain.createMapValue(
+        originalValue._abstractValue,
+        allocationNode,
+        allocationElement,
+        key._abstractValue,
+        value._abstractValue);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  bool isMap(covariant PowersetValue value) =>
+      _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue &&
+      _abstractValueDomain.isMap(value._abstractValue);
+
+  @override
+  AbstractValue getSetElementType(covariant PowersetValue value) {
+    if (_powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse) {
+      return dynamicType;
+    }
+    AbstractValue abstractValue =
+        _abstractValueDomain.getSetElementType(value._abstractValue);
+    return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop);
+  }
+
+  @override
+  AbstractValue createSetValue(
+      covariant PowersetValue originalValue,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
+      covariant PowersetValue elementType) {
+    int powersetBits = originalValue._powersetBits;
+    AbstractValue abstractValue = _abstractValueDomain.createSetValue(
+        originalValue._abstractValue,
+        allocationNode,
+        allocationElement,
+        elementType._abstractValue);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  bool isSet(covariant PowersetValue value) =>
+      _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue &&
+      _abstractValueDomain.isSet(value._abstractValue);
+
+  @override
+  int? getContainerLength(covariant PowersetValue value) =>
+      _powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse
+          ? null
+          : _abstractValueDomain.getContainerLength(value._abstractValue);
+
+  @override
+  AbstractValue getContainerElementType(covariant PowersetValue value) {
+    if (_powersetBitsDomain.isOther(value._powersetBits).isDefinitelyFalse) {
+      return dynamicType;
+    }
+    AbstractValue abstractValue =
+        _abstractValueDomain.getContainerElementType(value._abstractValue);
+    return PowersetValue(abstractValue, _powersetBitsDomain.powersetTop);
+  }
+
+  @override
+  AbstractValue createContainerValue(
+      covariant PowersetValue originalValue,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
+      covariant PowersetValue elementType,
+      int? length) {
+    int powersetBits = originalValue._powersetBits;
+    AbstractValue abstractValue = _abstractValueDomain.createContainerValue(
+        originalValue._abstractValue,
+        allocationNode,
+        allocationElement,
+        elementType._abstractValue,
+        length);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  bool isContainer(covariant PowersetValue value) =>
+      _powersetBitsDomain.isOther(value._powersetBits).isPotentiallyTrue &&
+      _abstractValueDomain.isContainer(value._abstractValue);
+
+  // TODO(coam): this can be more precise if we build a ConstantValue visitor
+  // that can tell us information about the bits given a ConstantValue
+  @override
+  AbstractValue computeAbstractValueForConstant(covariant ConstantValue value) {
+    int powersetBits =
+        _powersetBitsDomain.computeAbstractValueForConstant(value);
+    AbstractValue abstractValue =
+        _abstractValueDomain.computeAbstractValueForConstant(value);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) {
+    int powersetBits = _powersetBitsDomain.powersetTop;
+    final abstractValue =
+        _abstractValueDomain.getAbstractValueForNativeMethodParameterType(type);
+    return wrapOrNull(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractBool containsAll(covariant PowersetValue a) =>
+      AbstractBool.strengthen(_powersetBitsDomain.containsAll(a._powersetBits),
+          _abstractValueDomain.containsAll(a._abstractValue));
+
+  @override
+  AbstractBool areDisjoint(
+          covariant PowersetValue a, covariant PowersetValue b) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.areDisjoint(a._powersetBits, b._powersetBits),
+          _abstractValueDomain.areDisjoint(a._abstractValue, b._abstractValue));
+
+  @override
+  AbstractValue intersection(
+      covariant PowersetValue a, covariant PowersetValue b) {
+    int powersetBits =
+        _powersetBitsDomain.intersection(a._powersetBits, b._powersetBits);
+    AbstractValue abstractValue =
+        _abstractValueDomain.intersection(a._abstractValue, b._abstractValue);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractValue unionOfMany(covariant Iterable<PowersetValue> values) {
+    PowersetValue result = PowersetValue(
+        _abstractValueDomain.emptyType, _powersetBitsDomain.powersetBottom);
+    for (final value in values) {
+      result = union(result, value) as PowersetValue;
+    }
+    return result;
+  }
+
+  @override
+  AbstractValue union(covariant PowersetValue a, covariant PowersetValue b) {
+    int powersetBits =
+        _powersetBitsDomain.union(a._powersetBits, b._powersetBits);
+    AbstractValue abstractValue =
+        _abstractValueDomain.union(a._abstractValue, b._abstractValue);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractBool isPrimitiveOrNull(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isPrimitiveOrNull(value._powersetBits),
+          _abstractValueDomain.isPrimitiveOrNull(value._abstractValue));
+
+  @override
+  AbstractBool isStringOrNull(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isStringOrNull(value._powersetBits),
+          _abstractValueDomain.isStringOrNull(value._abstractValue));
+
+  @override
+  AbstractBool isString(covariant PowersetValue value) =>
+      AbstractBool.strengthen(_powersetBitsDomain.isString(value._powersetBits),
+          _abstractValueDomain.isString(value._abstractValue));
+
+  @override
+  AbstractBool isBooleanOrNull(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isBooleanOrNull(value._powersetBits),
+          _abstractValueDomain.isBooleanOrNull(value._abstractValue));
+
+  @override
+  AbstractBool isBoolean(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isBoolean(value._powersetBits),
+          _abstractValueDomain.isBoolean(value._abstractValue));
+
+  @override
+  AbstractBool isTruthy(covariant PowersetValue value) =>
+      AbstractBool.strengthen(_powersetBitsDomain.isTruthy(value._powersetBits),
+          _abstractValueDomain.isTruthy(value._abstractValue));
+
+  @override
+  AbstractBool isNumberOrNull(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isNumberOrNull(value._powersetBits),
+          _abstractValueDomain.isNumberOrNull(value._abstractValue));
+
+  @override
+  AbstractBool isNumber(covariant PowersetValue value) =>
+      AbstractBool.strengthen(_powersetBitsDomain.isNumber(value._powersetBits),
+          _abstractValueDomain.isNumber(value._abstractValue));
+
+  @override
+  AbstractBool isIntegerOrNull(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isIntegerOrNull(value._powersetBits),
+          _abstractValueDomain.isIntegerOrNull(value._abstractValue));
+
+  @override
+  AbstractBool isPositiveIntegerOrNull(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isPositiveIntegerOrNull(value._powersetBits),
+          _abstractValueDomain.isPositiveIntegerOrNull(value._abstractValue));
+
+  @override
+  AbstractBool isPositiveInteger(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isPositiveInteger(value._powersetBits),
+          _abstractValueDomain.isPositiveInteger(value._abstractValue));
+
+  @override
+  AbstractBool isUInt31(covariant PowersetValue value) =>
+      AbstractBool.strengthen(_powersetBitsDomain.isUInt31(value._powersetBits),
+          _abstractValueDomain.isUInt31(value._abstractValue));
+
+  @override
+  AbstractBool isUInt32(covariant PowersetValue value) =>
+      AbstractBool.strengthen(_powersetBitsDomain.isUInt32(value._powersetBits),
+          _abstractValueDomain.isUInt32(value._abstractValue));
+
+  @override
+  AbstractBool isInteger(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isInteger(value._powersetBits),
+          _abstractValueDomain.isInteger(value._abstractValue));
+
+  @override
+  AbstractBool isInterceptor(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isInterceptor(value._powersetBits),
+          _abstractValueDomain.isInterceptor(value._abstractValue));
+
+  @override
+  AbstractBool isPrimitiveString(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isPrimitiveString(value._powersetBits),
+          _abstractValueDomain.isPrimitiveString(value._abstractValue));
+
+  @override
+  AbstractBool isArray(covariant PowersetValue value) =>
+      AbstractBool.strengthen(_powersetBitsDomain.isArray(value._powersetBits),
+          _abstractValueDomain.isArray(value._abstractValue));
+
+  @override
+  AbstractBool isMutableIndexable(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isMutableIndexable(value._powersetBits),
+          _abstractValueDomain.isMutableIndexable(value._abstractValue));
+
+  @override
+  AbstractBool isMutableArray(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isMutableArray(value._powersetBits),
+          _abstractValueDomain.isMutableArray(value._abstractValue));
+
+  @override
+  AbstractBool isExtendableArray(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isExtendableArray(value._powersetBits),
+          _abstractValueDomain.isExtendableArray(value._abstractValue));
+
+  @override
+  AbstractBool isFixedArray(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isFixedArray(value._powersetBits),
+          _abstractValueDomain.isFixedArray(value._abstractValue));
+
+  @override
+  AbstractBool isIndexablePrimitive(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isIndexablePrimitive(value._powersetBits),
+          _abstractValueDomain.isIndexablePrimitive(value._abstractValue));
+
+  @override
+  AbstractBool isPrimitiveBoolean(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isPrimitiveBoolean(value._powersetBits),
+          _abstractValueDomain.isPrimitiveBoolean(value._abstractValue));
+
+  @override
+  AbstractBool isPrimitiveNumber(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isPrimitiveNumber(value._powersetBits),
+          _abstractValueDomain.isPrimitiveNumber(value._abstractValue));
+
+  @override
+  AbstractBool isPrimitive(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isPrimitive(value._powersetBits),
+          _abstractValueDomain.isPrimitive(value._abstractValue));
+
+  @override
+  AbstractBool isNull(covariant PowersetValue value) => AbstractBool.strengthen(
+      _powersetBitsDomain.isNull(value._powersetBits),
+      _abstractValueDomain.isNull(value._abstractValue));
+
+  @override
+  AbstractBool isLateSentinel(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isLateSentinel(value._powersetBits),
+          _abstractValueDomain.isLateSentinel(value._abstractValue));
+
+  @override
+  ClassEntity? getExactClass(covariant PowersetValue value) =>
+      _abstractValueDomain.getExactClass(value._abstractValue);
+
+  @override
+  AbstractBool isExact(covariant PowersetValue value) =>
+      AbstractBool.strengthen(_powersetBitsDomain.isExact(value._powersetBits),
+          _abstractValueDomain.isExact(value._abstractValue));
+
+  @override
+  AbstractBool isEmpty(covariant PowersetValue value) =>
+      AbstractBool.strengthen(_powersetBitsDomain.isEmpty(value._powersetBits),
+          _abstractValueDomain.isEmpty(value._abstractValue));
+
+  @override
+  AbstractBool isInstanceOf(covariant PowersetValue value, ClassEntity cls) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isInstanceOf(value._powersetBits, cls),
+          _abstractValueDomain.isInstanceOf(value._abstractValue, cls));
+
+  @override
+  AbstractBool isInstanceOfOrNull(
+          covariant PowersetValue value, ClassEntity cls) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isInstanceOfOrNull(value._powersetBits, cls),
+          _abstractValueDomain.isInstanceOfOrNull(value._abstractValue, cls));
+
+  @override
+  AbstractBool containsOnlyType(
+          covariant PowersetValue value, ClassEntity cls) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.containsOnlyType(value._powersetBits, cls),
+          _abstractValueDomain.containsOnlyType(value._abstractValue, cls));
+
+  @override
+  AbstractBool containsType(covariant PowersetValue value, ClassEntity cls) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.containsType(value._powersetBits, cls),
+          _abstractValueDomain.containsType(value._abstractValue, cls));
+
+  @override
+  AbstractValue includeNull(covariant PowersetValue value) {
+    int powersetBits = _powersetBitsDomain.includeNull(value._powersetBits);
+    AbstractValue abstractValue =
+        _abstractValueDomain.includeNull(value._abstractValue);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractValue excludeNull(covariant PowersetValue value) {
+    int powersetBits = _powersetBitsDomain.excludeNull(value._powersetBits);
+    AbstractValue abstractValue =
+        _abstractValueDomain.excludeNull(value._abstractValue);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractValue includeLateSentinel(covariant PowersetValue value) {
+    int powersetBits =
+        _powersetBitsDomain.includeLateSentinel(value._powersetBits);
+    AbstractValue abstractValue =
+        _abstractValueDomain.includeLateSentinel(value._abstractValue);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractValue excludeLateSentinel(covariant PowersetValue value) {
+    int powersetBits =
+        _powersetBitsDomain.excludeLateSentinel(value._powersetBits);
+    AbstractValue abstractValue =
+        _abstractValueDomain.excludeLateSentinel(value._abstractValue);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractBool couldBeTypedArray(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.couldBeTypedArray(value._powersetBits),
+          _abstractValueDomain.couldBeTypedArray(value._abstractValue));
+
+  @override
+  AbstractBool isTypedArray(covariant PowersetValue value) =>
+      AbstractBool.strengthen(
+          _powersetBitsDomain.isTypedArray(value._powersetBits),
+          _abstractValueDomain.isTypedArray(value._abstractValue));
+
+  @override
+  AbstractValue createNullableSubtype(ClassEntity cls) {
+    int powersetBits = _powersetBitsDomain.createNullableSubtype(cls);
+    AbstractValue abstractValue =
+        _abstractValueDomain.createNullableSubtype(cls);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractValue createNonNullSubtype(ClassEntity cls) {
+    int powersetBits = _powersetBitsDomain.createNonNullSubtype(cls);
+    AbstractValue abstractValue =
+        _abstractValueDomain.createNonNullSubtype(cls);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractValue createNonNullSubclass(ClassEntity cls) {
+    int powersetBits = _powersetBitsDomain.createNonNullSubclass(cls);
+    AbstractValue abstractValue =
+        _abstractValueDomain.createNonNullSubclass(cls);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractValue createNullableExact(ClassEntity cls) {
+    int powersetBits = _powersetBitsDomain.createNullableExact(cls);
+    AbstractValue abstractValue = _abstractValueDomain.createNullableExact(cls);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractValue createNonNullExact(ClassEntity cls) {
+    int powersetBits = _powersetBitsDomain.createNonNullExact(cls);
+    AbstractValue abstractValue = _abstractValueDomain.createNonNullExact(cls);
+    return PowersetValue(abstractValue, powersetBits);
+  }
+
+  @override
+  AbstractValueWithPrecision createFromStaticType(DartType type,
+      {ClassRelation classRelation = ClassRelation.subtype,
+      required bool nullable}) {
+    int powersetBits = _powersetBitsDomain.createFromStaticType(type,
+        classRelation: classRelation, nullable: nullable);
+    var unwrapped = _abstractValueDomain.createFromStaticType(type,
+        classRelation: classRelation, nullable: nullable);
+    return AbstractValueWithPrecision(
+        PowersetValue(unwrapped.abstractValue, powersetBits),
+        unwrapped.isPrecise);
+  }
+
+  @override
+  AbstractValue get asyncStarStreamType => PowersetValue(
+      _abstractValueDomain.asyncStarStreamType,
+      _powersetBitsDomain.asyncStarStreamType);
+
+  @override
+  AbstractValue get asyncFutureType => PowersetValue(
+      _abstractValueDomain.asyncFutureType,
+      _powersetBitsDomain.asyncFutureType);
+
+  @override
+  AbstractValue get syncStarIterableType => PowersetValue(
+      _abstractValueDomain.syncStarIterableType,
+      _powersetBitsDomain.syncStarIterableType);
+
+  @override
+  AbstractValue get emptyType => PowersetValue(
+      _abstractValueDomain.emptyType, _powersetBitsDomain.emptyType);
+
+  @override
+  AbstractValue get constMapType => PowersetValue(
+      _abstractValueDomain.constMapType, _powersetBitsDomain.constMapType);
+
+  @override
+  AbstractValue get constSetType => PowersetValue(
+      _abstractValueDomain.constSetType, _powersetBitsDomain.constSetType);
+
+  @override
+  AbstractValue get constListType => PowersetValue(
+      _abstractValueDomain.constListType, _powersetBitsDomain.constListType);
+
+  @override
+  AbstractValue get positiveIntType => PowersetValue(
+      _abstractValueDomain.positiveIntType,
+      _powersetBitsDomain.positiveIntType);
+
+  @override
+  AbstractValue get uint32Type => PowersetValue(
+      _abstractValueDomain.uint32Type, _powersetBitsDomain.uint32Type);
+
+  @override
+  AbstractValue get uint31Type => PowersetValue(
+      _abstractValueDomain.uint31Type, _powersetBitsDomain.uint31Type);
+
+  @override
+  AbstractValue get fixedListType => PowersetValue(
+      _abstractValueDomain.fixedListType, _powersetBitsDomain.fixedListType);
+
+  @override
+  AbstractValue get growableListType => PowersetValue(
+      _abstractValueDomain.growableListType,
+      _powersetBitsDomain.growableListType);
+
+  @override
+  AbstractValue get mutableArrayType => PowersetValue(
+      _abstractValueDomain.mutableArrayType,
+      _powersetBitsDomain.mutableArrayType);
+
+  @override
+  AbstractValue get nullType => PowersetValue(
+      _abstractValueDomain.nullType, _powersetBitsDomain.nullType);
+
+  @override
+  AbstractValue get nonNullType => PowersetValue(
+      _abstractValueDomain.nonNullType, _powersetBitsDomain.nonNullType);
+
+  @override
+  AbstractValue get lateSentinelType => PowersetValue(
+      _abstractValueDomain.lateSentinelType,
+      _powersetBitsDomain.lateSentinelType);
+
+  @override
+  AbstractValue get mapType =>
+      PowersetValue(_abstractValueDomain.mapType, _powersetBitsDomain.mapType);
+
+  @override
+  AbstractValue get setType =>
+      PowersetValue(_abstractValueDomain.setType, _powersetBitsDomain.setType);
+
+  @override
+  AbstractValue get listType => PowersetValue(
+      _abstractValueDomain.listType, _powersetBitsDomain.listType);
+
+  @override
+  AbstractValue get stringType => PowersetValue(
+      _abstractValueDomain.stringType, _powersetBitsDomain.stringType);
+
+  @override
+  AbstractValue get numType =>
+      PowersetValue(_abstractValueDomain.numType, _powersetBitsDomain.numType);
+
+  @override
+  AbstractValue get numNotIntType => PowersetValue(
+      _abstractValueDomain.numNotIntType, _powersetBitsDomain.numNotIntType);
+
+  @override
+  AbstractValue get intType =>
+      PowersetValue(_abstractValueDomain.intType, _powersetBitsDomain.intType);
+
+  @override
+  AbstractValue get boolType => PowersetValue(
+      _abstractValueDomain.boolType, _powersetBitsDomain.boolType);
+
+  @override
+  AbstractValue get functionType => PowersetValue(
+      _abstractValueDomain.functionType, _powersetBitsDomain.functionType);
+
+  @override
+  AbstractValue get typeType => PowersetValue(
+      _abstractValueDomain.typeType, _powersetBitsDomain.typeType);
+}
+
+class PowersetStrategy implements AbstractValueStrategy {
+  final AbstractValueStrategy _abstractValueStrategy;
+  const PowersetStrategy(this._abstractValueStrategy);
+
+  @override
+  AbstractValueDomain createDomain(JClosedWorld closedWorld) {
+    return PowersetDomain(_abstractValueStrategy.createDomain(closedWorld),
+        PowersetBitsDomain(closedWorld));
+  }
+
+  @override
+  SelectorConstraintsStrategy createSelectorStrategy() {
+    return PowersetsSelectorStrategy(
+        _abstractValueStrategy.createSelectorStrategy());
+  }
+}
+
+class PowersetsSelectorStrategy implements SelectorConstraintsStrategy {
+  final SelectorConstraintsStrategy _selectorConstraintsStrategy;
+  const PowersetsSelectorStrategy(this._selectorConstraintsStrategy);
+
+  @override
+  UniverseSelectorConstraints createSelectorConstraints(
+      Selector selector, Object? initialConstraint) {
+    return PowersetsUniverseSelectorConstraints(
+        _selectorConstraintsStrategy.createSelectorConstraints(
+            selector,
+            initialConstraint == null
+                ? null
+                : (initialConstraint as PowersetValue)._abstractValue));
+  }
+
+  @override
+  bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member,
+      covariant JClosedWorld world) {
+    return _selectorConstraintsStrategy.appliedUnnamed(
+        dynamicUse.withReceiverConstraint(
+            unwrapOrNull(dynamicUse.receiverConstraint as PowersetValue?)),
+        member,
+        world);
+  }
+}
+
+class PowersetsUniverseSelectorConstraints
+    implements UniverseSelectorConstraints {
+  final UniverseSelectorConstraints _universeSelectorConstraints;
+  const PowersetsUniverseSelectorConstraints(this._universeSelectorConstraints);
+
+  @override
+  bool addReceiverConstraint(Object? constraint) =>
+      _universeSelectorConstraints.addReceiverConstraint(constraint == null
+          ? null
+          : (constraint as PowersetValue)._abstractValue);
+
+  @override
+  bool needsNoSuchMethodHandling(Selector selector, World world) =>
+      _universeSelectorConstraints.needsNoSuchMethodHandling(selector, world);
+
+  @override
+  bool canHit(MemberEntity element, Name name, World world) =>
+      _universeSelectorConstraints.canHit(element, name, world);
+
+  @override
+  String toString() => 'PowersetsUniverseSelectorConstraints:$hashCode';
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/set_tracer.dart b/pkg/compiler/lib/src/inferrer_experimental/set_tracer.dart
new file mode 100644
index 0000000..817a346
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/set_tracer.dart
@@ -0,0 +1,131 @@
+// 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.
+
+library compiler.src.inferrer.set_tracer;
+
+import '../common/names.dart';
+import '../elements/entities.dart';
+import 'node_tracer.dart';
+import 'type_graph_nodes.dart';
+
+/// A set of selector names that [Set] implements and which we know do not
+/// change the element type of the set or let the set escape to code that might
+/// change the element type.
+Set<String> okSetSelectorSet = Set<String>.from(const <String>[
+  // From Object.
+  '==',
+  'hashCode',
+  'toString',
+  'noSuchMethod',
+  'runtimeType',
+
+  // From Iterable.
+  'iterator',
+  'map',
+  'where',
+  'expand',
+  'contains',
+  'forEach',
+  'reduce',
+  'fold',
+  'every',
+  'join',
+  'any',
+  'toList',
+  'toSet',
+  'length',
+  'isEmpty',
+  'isNotEmpty',
+  'take',
+  'takeWhile',
+  'skip',
+  'skipWhile',
+  'first',
+  'last',
+  'single',
+  'firstWhere',
+  'lastWhere',
+  'singleWhere',
+  'elementAt',
+
+  // From Set.
+  'clear',
+  'containsAll',
+  'difference',
+  'intersection',
+  'lookup',
+  'remove',
+  'removeAll',
+  'removeWhere',
+  'retainAll',
+  'retainWhere',
+  'union',
+]);
+
+class SetTracerVisitor extends TracerVisitor {
+  List<TypeInformation> inputs = <TypeInformation>[];
+
+  SetTracerVisitor(super.tracedType, super.inferrer);
+
+  /// Returns [true] if the analysis completed successfully, [false] if it
+  /// bailed out. In the former case, [inputs] holds a list of
+  /// [TypeInformation] nodes that flow into the element type of this set.
+  bool run() {
+    analyze();
+    final set = tracedType as SetTypeInformation;
+    if (continueAnalyzing) {
+      set.addFlowsIntoTargets(flowsInto);
+      return true;
+    }
+    inputs.clear();
+    return false;
+  }
+
+  @override
+  visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
+    bailout('Passed to a closure');
+  }
+
+  @override
+  visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+    super.visitStaticCallSiteTypeInformation(info);
+    MemberEntity called = info.calledElement;
+    if (inferrer.closedWorld.commonElements.isForeign(called) &&
+        called.name == Identifiers.JS) {
+      bailout('Used in JS ${info.debugName}');
+    }
+  }
+
+  @override
+  visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
+    super.visitDynamicCallSiteTypeInformation(info);
+    final selector = info.selector!;
+    final selectorName = selector.name;
+    final arguments = info.arguments;
+    if (currentUser == info.receiver) {
+      if (!okSetSelectorSet.contains(selectorName)) {
+        if (selector.isCall) {
+          switch (selectorName) {
+            case 'add':
+              inputs.add(arguments!.positional[0]);
+              break;
+            case 'addAll':
+              // TODO(fishythefish): Extract type argument from type
+              // information.
+              bailout('Adding iterable with unknown typeinfo to current set');
+              break;
+            default:
+              bailout('Set used in a not-ok selector [$selectorName]');
+          }
+          return;
+        }
+      }
+    } else if (selector.isCall &&
+        (info.hasClosureCallTargets ||
+            info.concreteTargets.any((element) => !element.isFunction))) {
+      bailout('Passed to a closure');
+      return;
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/trivial.dart b/pkg/compiler/lib/src/inferrer_experimental/trivial.dart
new file mode 100644
index 0000000..ba3e67e
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/trivial.dart
@@ -0,0 +1,493 @@
+// Copyright (c) 2018, 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 '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
+import '../elements/entities.dart';
+import '../elements/names.dart';
+import '../elements/types.dart' show DartType;
+import '../ir/class_relation.dart';
+import '../serialization/serialization.dart';
+import '../universe/selector.dart';
+import '../universe/world_builder.dart';
+import '../universe/use.dart';
+import '../world_interfaces.dart';
+import '../inferrer/abstract_value_domain.dart';
+import '../inferrer/abstract_value_strategy.dart';
+
+class TrivialAbstractValue implements AbstractValue {
+  const TrivialAbstractValue();
+
+  @override
+  String toString() => '?';
+}
+
+class TrivialAbstractValueDomain implements AbstractValueDomain {
+  const TrivialAbstractValueDomain();
+
+  @override
+  AbstractValue get internalTopType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get dynamicType => const TrivialAbstractValue();
+
+  @override
+  void writeAbstractValueToDataSink(DataSinkWriter sink, AbstractValue value) {}
+
+  @override
+  AbstractValue readAbstractValueFromDataSource(DataSourceReader source) =>
+      const TrivialAbstractValue();
+
+  @override
+  String getCompactText(AbstractValue value) => '?';
+
+  @override
+  AbstractBool isFixedLengthJsIndexable(AbstractValue value) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractBool isJsIndexableAndIterable(AbstractValue value) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractBool isJsIndexable(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  MemberEntity? locateSingleMember(AbstractValue receiver, Selector selector) =>
+      null;
+
+  @override
+  AbstractBool isIn(AbstractValue subset, AbstractValue superset) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractBool needsNoSuchMethodHandling(
+          AbstractValue receiver, Selector selector) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractBool isTargetingMember(
+          AbstractValue receiver, MemberEntity member, Name name) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractValue computeReceiver(Iterable<MemberEntity> members) =>
+      const TrivialAbstractValue();
+
+  @override
+  PrimitiveConstantValue? getPrimitiveValue(AbstractValue value) => null;
+
+  @override
+  AbstractValue createPrimitiveValue(
+          AbstractValue originalValue, PrimitiveConstantValue value) =>
+      const TrivialAbstractValue();
+
+  @override
+  bool isPrimitiveValue(AbstractValue value) => false;
+
+  @override
+  MemberEntity? getAllocationElement(AbstractValue value) => null;
+
+  @override
+  Object? getAllocationNode(AbstractValue value) => null;
+
+  @override
+  AbstractValue getGeneralization(AbstractValue? value) =>
+      const TrivialAbstractValue();
+
+  @override
+  bool isSpecializationOf(
+          AbstractValue specialization, AbstractValue generalization) =>
+      false;
+
+  @override
+  AbstractValue getDictionaryValueForKey(AbstractValue value, String key) {
+    throw UnsupportedError(
+        "TrivialAbstractValueDomain.getDictionaryValueForKey");
+  }
+
+  @override
+  bool containsDictionaryKey(AbstractValue value, String key) {
+    throw UnsupportedError("TrivialAbstractValueDomain.containsDictionaryKey");
+  }
+
+  @override
+  AbstractValue createDictionaryValue(
+          AbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
+          AbstractValue key,
+          AbstractValue value,
+          Map<String, AbstractValue> mappings) =>
+      const TrivialAbstractValue();
+
+  @override
+  bool isDictionary(AbstractValue value) => false;
+
+  @override
+  AbstractValue getMapValueType(AbstractValue value) {
+    throw UnsupportedError("TrivialAbstractValueDomain.getMapValueType");
+  }
+
+  @override
+  AbstractValue getMapKeyType(AbstractValue value) {
+    throw UnsupportedError("TrivialAbstractValueDomain.getMapKeyType");
+  }
+
+  @override
+  AbstractValue createMapValue(
+          AbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
+          AbstractValue key,
+          AbstractValue value) =>
+      const TrivialAbstractValue();
+
+  @override
+  bool isMap(AbstractValue value) => false;
+
+  @override
+  AbstractValue getSetElementType(AbstractValue value) {
+    throw UnsupportedError("TrivialAbstractValueDomain.getSetElementType");
+  }
+
+  @override
+  AbstractValue createSetValue(
+          AbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
+          AbstractValue elementType) =>
+      const TrivialAbstractValue();
+
+  @override
+  bool isSet(AbstractValue value) => false;
+
+  @override
+  int? getContainerLength(AbstractValue value) => null;
+
+  @override
+  AbstractValue getContainerElementType(AbstractValue value) {
+    throw UnsupportedError(
+        "TrivialAbstractValueDomain.getContainerElementType");
+  }
+
+  @override
+  AbstractValue createContainerValue(
+          AbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
+          AbstractValue elementType,
+          int? length) =>
+      const TrivialAbstractValue();
+
+  @override
+  bool isContainer(AbstractValue value) => false;
+
+  @override
+  AbstractValue computeAbstractValueForConstant(ConstantValue value) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) =>
+      null;
+
+  @override
+  AbstractBool containsAll(AbstractValue a) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool areDisjoint(AbstractValue a, AbstractValue b) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractValue intersection(AbstractValue a, AbstractValue b) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValue unionOfMany(Iterable<AbstractValue> values) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValue union(AbstractValue a, AbstractValue b) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractBool isPrimitiveOrNull(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isStringOrNull(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isString(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isBooleanOrNull(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isBoolean(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isTruthy(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isNumberOrNull(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isNumber(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isIntegerOrNull(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isPositiveIntegerOrNull(AbstractValue value) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractBool isPositiveInteger(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isUInt31(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isUInt32(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isInteger(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isInterceptor(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isPrimitiveString(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isArray(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isMutableIndexable(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isMutableArray(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isExtendableArray(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isFixedArray(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isIndexablePrimitive(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isPrimitiveBoolean(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isPrimitiveNumber(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isPrimitive(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isNull(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isLateSentinel(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  ClassEntity? getExactClass(AbstractValue value) => null;
+
+  @override
+  AbstractBool isExact(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isEmpty(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isInstanceOf(AbstractValue value, ClassEntity cls) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractBool isInstanceOfOrNull(AbstractValue value, ClassEntity cls) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractBool containsOnlyType(AbstractValue value, ClassEntity cls) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractBool containsType(AbstractValue value, ClassEntity cls) =>
+      AbstractBool.Maybe;
+
+  @override
+  AbstractValue includeNull(AbstractValue value) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValue excludeNull(AbstractValue value) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValue includeLateSentinel(AbstractValue value) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValue excludeLateSentinel(AbstractValue value) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractBool couldBeTypedArray(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractBool isTypedArray(AbstractValue value) => AbstractBool.Maybe;
+
+  @override
+  AbstractValue createNullableSubtype(ClassEntity cls) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValue createNonNullSubtype(ClassEntity cls) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValue createNonNullSubclass(ClassEntity cls) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValue createNullableExact(ClassEntity cls) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValue createNonNullExact(ClassEntity cls) =>
+      const TrivialAbstractValue();
+
+  @override
+  AbstractValueWithPrecision createFromStaticType(DartType type,
+      {ClassRelation classRelation = ClassRelation.subtype,
+      required bool nullable}) {
+    return const AbstractValueWithPrecision(TrivialAbstractValue(), false);
+  }
+
+  @override
+  AbstractValue get asyncStarStreamType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get asyncFutureType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get syncStarIterableType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get emptyType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get constMapType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get constSetType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get constListType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get positiveIntType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get uint32Type => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get uint31Type => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get fixedListType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get growableListType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get mutableArrayType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get nullType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get nonNullType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get lateSentinelType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get mapType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get setType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get listType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get stringType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get numType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get numNotIntType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get intType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get boolType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get functionType => const TrivialAbstractValue();
+
+  @override
+  AbstractValue get typeType => const TrivialAbstractValue();
+}
+
+class TrivialAbstractValueStrategy implements AbstractValueStrategy {
+  const TrivialAbstractValueStrategy();
+
+  @override
+  AbstractValueDomain createDomain(JClosedWorld closedWorld) {
+    return const TrivialAbstractValueDomain();
+  }
+
+  @override
+  SelectorConstraintsStrategy createSelectorStrategy() {
+    return const TrivialSelectorStrategy();
+  }
+}
+
+class TrivialSelectorStrategy implements SelectorConstraintsStrategy {
+  const TrivialSelectorStrategy();
+
+  @override
+  UniverseSelectorConstraints createSelectorConstraints(
+      Selector selector, Object? initialConstraint) {
+    return const TrivialUniverseSelectorConstraints();
+  }
+
+  @override
+  bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member,
+      covariant JClosedWorld world) {
+    return dynamicUse.selector.appliesUnnamed(member);
+  }
+}
+
+class TrivialUniverseSelectorConstraints
+    implements UniverseSelectorConstraints {
+  const TrivialUniverseSelectorConstraints();
+
+  @override
+  bool addReceiverConstraint(Object constraint) => false;
+
+  @override
+  bool needsNoSuchMethodHandling(Selector selector, World world) => true;
+
+  @override
+  bool canHit(MemberEntity element, Name name, World world) => true;
+
+  @override
+  String toString() => 'TrivialUniverseSelectorConstraints:$hashCode';
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer_experimental/type_graph_dump.dart
new file mode 100644
index 0000000..50a18a9
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/type_graph_dump.dart
@@ -0,0 +1,451 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.10
+
+library dart2js.inferrer.type_graph_dump;
+
+import '../../compiler_api.dart' as api;
+import '../elements/entities.dart';
+import '../elements/entity_utils.dart' as utils;
+import '../inferrer/abstract_value_domain.dart';
+import 'engine.dart';
+import 'type_graph_nodes.dart';
+import 'debug.dart';
+
+/// Dumps the type inference graph in Graphviz Dot format into the `typegraph`
+/// subfolder of the current working directory. Each function body is dumped in
+/// a separate file.
+///
+/// The resulting .dot files must be processed using the Graphviz `dot` command,
+/// which can be obtained from `http://www.graphviz.org`, or installed using
+/// most package managers (search for `graphviz` or `dot`).
+///
+/// Example commands:
+///
+///     dot -Tpng -O typegraph/main.dot
+///     open typegraph/main.dot.png
+///
+///     dot -Tpng -O typegraph/dart._internal.Sort._dualPivotQuicksort.dot
+///     open typegraph/dart._internal.Sort._dualPivotQuicksort.dot.png
+///
+class TypeGraphDump {
+  static const String outputDir = 'typegraph';
+
+  final api.CompilerOutput compilerOutput;
+  final InferrerEngine inferrer;
+  final Map<TypeInformation, Set<TypeInformation>> assignmentsBeforeAnalysis =
+      <TypeInformation, Set<TypeInformation>>{};
+  final Map<TypeInformation, Set<TypeInformation>> assignmentsBeforeTracing =
+      <TypeInformation, Set<TypeInformation>>{};
+  final Set<String> usedFilenames = Set<String>();
+
+  TypeGraphDump(this.compilerOutput, this.inferrer);
+
+  /// Take a copy of the assignment set for each node, since that may change
+  /// during the analysis.
+  void beforeAnalysis() {
+    for (TypeInformation node in inferrer.types.allTypes) {
+      Set<TypeInformation> copy = node.inputs.toSet();
+      if (!copy.isEmpty) {
+        assignmentsBeforeAnalysis[node] = copy;
+      }
+    }
+  }
+
+  /// Like [beforeAnalysis], takes a copy of the assignment sets.
+  void beforeTracing() {
+    for (TypeInformation node in inferrer.types.allTypes) {
+      Set<TypeInformation> copy = node.inputs.toSet();
+      if (!copy.isEmpty) {
+        assignmentsBeforeTracing[node] = copy;
+      }
+    }
+  }
+
+  /// Dumps the entire graph.
+  void afterAnalysis() {
+    // Group all the type nodes by their context member.
+    Map<MemberEntity, List<TypeInformation>> nodes =
+        <MemberEntity, List<TypeInformation>>{};
+    for (TypeInformation node in inferrer.types.allTypes) {
+      if (node.contextMember != null) {
+        nodes
+            .putIfAbsent(node.contextMember, () => <TypeInformation>[])
+            .add(node);
+      }
+    }
+    // Print every group separately.
+    for (MemberEntity element in nodes.keys) {
+      api.OutputSink output;
+      try {
+        String name = filenameFromElement(element);
+        output = compilerOutput.createOutputSink(
+            '$outputDir/$name', 'dot', api.OutputType.debug);
+        _GraphGenerator visitor = _GraphGenerator(
+            this, element, output, inferrer.abstractValueDomain.getCompactText);
+        for (TypeInformation node in nodes[element]) {
+          visitor.visit(node);
+        }
+        visitor.addMissingNodes();
+        visitor.finish();
+      } finally {
+        if (output != null) {
+          output.close();
+        }
+      }
+    }
+  }
+
+  /// Returns the filename (without extension) in which to dump the type
+  /// graph for [element].
+  ///
+  /// Will never return the a given filename more than once, even if called with
+  /// the same element.
+  String filenameFromElement(MemberEntity element) {
+    // The toString method of elements include characters that are unsuitable
+    // for URIs and file systems.
+    List<String> parts = <String>[];
+    parts.add(element.library.canonicalUri.pathSegments.last);
+    parts.add(element.enclosingClass?.name);
+    if (element.isGetter) {
+      parts.add('get-${element.name}');
+    } else if (element.isSetter) {
+      parts.add('set-${element.name}');
+    } else if (element.isConstructor) {
+      if (element.name.isEmpty) {
+        parts.add('-constructor');
+      } else {
+        parts.add(element.name);
+      }
+    } else {
+      parts.add(
+          utils.operatorNameToIdentifier(element.name).replaceAll(r'$', '-'));
+    }
+    String filename = parts.where((x) => x != null && x != '').join('.');
+    if (usedFilenames.add(filename)) return filename;
+    // The filename has already been used by another method. Append a serial
+    // number to ensure we don't overwrite it.
+    int serialNumber = 2;
+    while (!usedFilenames.add('$filename-$serialNumber')) {
+      ++serialNumber;
+    }
+    return '$filename-$serialNumber';
+  }
+}
+
+/// Builds the Graphviz Dot file for one function body.
+class _GraphGenerator extends TypeInformationVisitor {
+  final TypeGraphDump global;
+  final Set<TypeInformation> seen = Set<TypeInformation>();
+  final List<TypeInformation> worklist = <TypeInformation>[];
+  final Map<TypeInformation, int> nodeId = <TypeInformation, int>{};
+  final String Function(AbstractValue) formatType;
+  int usedIds = 0;
+  final api.OutputSink output;
+  final MemberEntity element;
+  TypeInformation returnValue;
+
+  _GraphGenerator(this.global, this.element, this.output, this.formatType) {
+    returnValue = global.inferrer.types.getInferredTypeOfMember(element);
+    getNode(returnValue); // Ensure return value is part of graph.
+    append('digraph {');
+  }
+
+  void finish() {
+    append('}');
+  }
+
+  /// Ensures that all nodes which have been referenced are generated.
+  ///
+  /// Sometimes an input to a TypeInformation node does not belong to the same
+  /// function body, and the graph looks confusing if they are missing.
+  void addMissingNodes() {
+    while (worklist.isNotEmpty) {
+      TypeInformation node = worklist.removeLast();
+      assert(nodeId.containsKey(node));
+      visit(node);
+    }
+  }
+
+  void visit(TypeInformation info) {
+    if (seen.contains(info)) return;
+    info.accept(this);
+  }
+
+  void append(String string) {
+    output
+      ..add(string)
+      ..add('\n');
+  }
+
+  String shorten(String text) {
+    if (text.length > 40) {
+      return text.substring(0, 19) + '...' + text.substring(text.length - 18);
+    }
+    return text;
+  }
+
+  int getFreshId() => ++usedIds;
+
+  /// Obtains a unique ID for the node representing [info].
+  String getNode(TypeInformation info) {
+    int id = nodeId.putIfAbsent(info, () {
+      worklist.add(info); // Ensure that the referenced node is generated.
+      return getFreshId();
+    });
+    return '$id';
+  }
+
+  final RegExp escapeRegexp = RegExp('["{}<>|]');
+
+  /// Escapes characters in [text] so it can be used as part of a label.
+  String escapeLabel(String text) {
+    return text.replaceAllMapped(escapeRegexp, (m) => '\\${m.group(0)}');
+  }
+
+  /// Creates an edge from [src] to [dst].
+  ///
+  /// If [dst] is a record type node, [port] may refer to one of the fields
+  /// defined in that record (e.g. `obj`, `arg0`, `arg1`, etc)
+  void addEdge(TypeInformation src, TypeInformation dst,
+      {String port, String color = 'black'}) {
+    if (isExternal(src) && isExternal(dst)) {
+      return; // Do not add edges between external nodes.
+    }
+    String dstText = getNode(dst);
+    if (port != null) {
+      dstText += ':$port';
+    }
+    if (src is ConcreteTypeInformation) {
+      // Concrete types can have a huge number of uses which will flood the
+      // graph with very long hard-to-follow edges. Copy the concrete nodes
+      // for every use to enhance readability.
+      int id = getFreshId();
+      String type = escapeLabel('${formatType(src.type)}');
+      String text = 'Concrete';
+      String label = '{$text|<returnType> $type}';
+      append('$id [shape=record,style=dotted,label="$label"]');
+      append('$id -> $dstText [color="$color"]');
+    } else {
+      append('${getNode(src)}:returnType -> $dstText [color="$color"]');
+    }
+  }
+
+  // Some graphs are flooded by a huge number of phi and narrow nodes.
+  // We color the nodes so the "interesting" nodes stand out more.
+  static const String defaultNodeColor = '#eeffee';
+  static const String phiColor = '#eeffff';
+  static const String narrowColor = phiColor;
+  static const String callColor = '#ffffee';
+
+  // Colors for edges based on whether they were added or removed during the
+  // analysis.
+  static const String unchangedEdge = 'black';
+  static const String addedEdge = 'green4';
+  static const String removedEdge = 'red3';
+  static const String temporaryEdge = 'orange'; // Added and then removed again.
+
+  bool isExternal(TypeInformation node) {
+    return node != returnValue && node.contextMember != element;
+  }
+
+  String getStyleForNode(TypeInformation node, String color) {
+    return isExternal(node)
+        ? 'style=dotted'
+        : 'style=filled,fillcolor="$color"';
+  }
+
+  /// Adds details that are not specific to a subclass of [TypeInformation].
+  String appendDetails(TypeInformation node, String text) {
+    if (node == returnValue) {
+      return '$text\n(return value)';
+    }
+    if (node.contextMember != null && node.contextMember != element) {
+      return '$text\n(from ${node.contextMember})';
+    }
+    return text;
+  }
+
+  /// Creates a node for [node] displaying the given [text] in its box.
+  ///
+  /// [inputs] specify named inputs to the node. If omitted, edges will be
+  /// based on [node.inputs].
+  void addNode(TypeInformation node, String text,
+      {String color = defaultNodeColor, Map<String, TypeInformation> inputs}) {
+    seen.add(node);
+    String style = getStyleForNode(node, color);
+    text = appendDetails(node, text);
+    text = escapeLabel(text);
+    String id = getNode(node);
+    String returnType = escapeLabel(formatType(node.type));
+    if (inputs != null) {
+      Iterable<String> keys = inputs.keys.where((key) => inputs[key] != null);
+      String header = keys.map((key) => '<a$key> $key').join('|');
+      String label = '{{$header}|$text|<returnType> $returnType}';
+      append('$id [shape=record,label="$label",$style]');
+      for (String key in keys) {
+        addEdge(inputs[key], node, port: 'a$key');
+      }
+    } else {
+      String label = '{$text|<returnType> $returnType}';
+      append('$id [shape=record,label="$label",$style]');
+      // Add assignment edges. Color the edges based on whether they were
+      // added, removed, temporary, or unchanged.
+      dynamic originalSet = global.assignmentsBeforeAnalysis[node] ?? const [];
+      var tracerSet = global.assignmentsBeforeTracing[node] ?? const [];
+      var currentSet = node.inputs.toSet();
+      for (TypeInformation assignment in currentSet) {
+        String color =
+            originalSet.contains(assignment) ? unchangedEdge : addedEdge;
+        addEdge(assignment, node, color: color);
+      }
+      for (TypeInformation assignment in originalSet) {
+        if (!currentSet.contains(assignment)) {
+          addEdge(assignment, node, color: removedEdge);
+        }
+      }
+      for (TypeInformation assignment in tracerSet) {
+        if (!currentSet.contains(assignment) &&
+            !originalSet.contains(assignment)) {
+          addEdge(assignment, node, color: temporaryEdge);
+        }
+      }
+    }
+    if (PRINT_GRAPH_ALL_NODES) {
+      for (TypeInformation user in node.users) {
+        if (!isExternal(user)) {
+          visit(user);
+        }
+      }
+    }
+  }
+
+  @override
+  void visitNarrowTypeInformation(NarrowTypeInformation info) {
+    // Omit unused Narrows.
+    if (!PRINT_GRAPH_ALL_NODES && info.users.isEmpty) return;
+    addNode(info, 'Narrow\n${formatType(info.typeAnnotation)}',
+        color: narrowColor);
+  }
+
+  @override
+  void visitPhiElementTypeInformation(PhiElementTypeInformation info) {
+    // Omit unused Phis.
+    if (!PRINT_GRAPH_ALL_NODES && info.users.isEmpty) return;
+    addNode(info, 'Phi ${info.variable?.name ?? ''}', color: phiColor);
+  }
+
+  @override
+  void visitElementInContainerTypeInformation(
+      ElementInContainerTypeInformation info) {
+    addNode(info, 'ElementInContainer');
+  }
+
+  @override
+  void visitElementInSetTypeInformation(ElementInSetTypeInformation info) {
+    addNode(info, 'ElementInSet');
+  }
+
+  @override
+  void visitKeyInMapTypeInformation(KeyInMapTypeInformation info) {
+    addNode(info, 'KeyInMap');
+  }
+
+  @override
+  void visitValueInMapTypeInformation(ValueInMapTypeInformation info) {
+    addNode(info, 'ValueInMap');
+  }
+
+  @override
+  void visitListTypeInformation(ListTypeInformation info) {
+    addNode(info, 'List');
+  }
+
+  @override
+  void visitSetTypeInformation(SetTypeInformation info) {
+    addNode(info, 'Set');
+  }
+
+  @override
+  void visitMapTypeInformation(MapTypeInformation info) {
+    addNode(info, 'Map');
+  }
+
+  @override
+  void visitConcreteTypeInformation(ConcreteTypeInformation info) {
+    addNode(info, 'Concrete');
+  }
+
+  @override
+  void visitStringLiteralTypeInformation(StringLiteralTypeInformation info) {
+    String text = shorten(info.value).replaceAll('\n', '\\n');
+    addNode(info, 'StringLiteral\n"$text"');
+  }
+
+  @override
+  void visitBoolLiteralTypeInformation(BoolLiteralTypeInformation info) {
+    addNode(info, 'BoolLiteral\n${info.value}');
+  }
+
+  void handleCall(CallSiteTypeInformation info, String text,
+      Map<String, TypeInformation> inputs) {
+    String sourceCode = shorten('${info.debugName}');
+    text = '$text\n$sourceCode';
+    if (info.arguments != null) {
+      for (int i = 0; i < info.arguments.positional.length; ++i) {
+        inputs['arg$i'] = info.arguments.positional[i];
+      }
+      for (String argName in info.arguments.named.keys) {
+        inputs[argName] = info.arguments.named[argName];
+      }
+    }
+    addNode(info, text, color: callColor, inputs: inputs);
+  }
+
+  @override
+  void visitClosureCallSiteTypeInformation(
+      ClosureCallSiteTypeInformation info) {
+    handleCall(info, 'ClosureCallSite', {});
+  }
+
+  @override
+  void visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+    handleCall(info, 'StaticCallSite', {});
+  }
+
+  @override
+  void visitDynamicCallSiteTypeInformation(
+      DynamicCallSiteTypeInformation info) {
+    handleCall(info, 'DynamicCallSite', {'obj': info.receiver});
+  }
+
+  @override
+  void visitMemberTypeInformation(MemberTypeInformation info) {
+    addNode(info, 'Member\n${info.debugName}');
+  }
+
+  @override
+  void visitParameterTypeInformation(ParameterTypeInformation info) {
+    addNode(info, 'Parameter ${info.debugName}');
+  }
+
+  @override
+  void visitClosureTypeInformation(ClosureTypeInformation info) {
+    String text = shorten('${info.debugName}');
+    addNode(info, 'Closure\n$text');
+  }
+
+  @override
+  void visitAwaitTypeInformation(AwaitTypeInformation info) {
+    String text = shorten('${info.debugName}');
+    addNode(info, 'Await\n$text');
+  }
+
+  @override
+  void visitYieldTypeInformation(YieldTypeInformation info) {
+    String text = shorten('${info.debugName}');
+    addNode(info, 'Yield\n$text');
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer_experimental/type_graph_inferrer.dart
new file mode 100644
index 0000000..84e8575
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/type_graph_inferrer.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2013, 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.10
+
+library type_graph_inferrer;
+
+import 'dart:collection' show Queue;
+
+import 'package:kernel/ast.dart' as ir;
+import '../closure.dart';
+import '../common/metrics.dart' show Metrics;
+import '../compiler.dart';
+import '../elements/entities.dart';
+import '../js_backend/inferred_data.dart';
+import '../js_model/elements.dart' show JClosureCallMethod;
+import '../js_model/locals.dart';
+import '../world.dart';
+import '../inferrer/abstract_value_domain.dart';
+import 'engine.dart';
+import 'type_graph_nodes.dart';
+import 'types.dart';
+
+/// A work queue for the inferrer. It filters out nodes that are tagged as
+/// [TypeInformation.doNotEnqueue], as well as ensures through
+/// [TypeInformation.inQueue] that a node is in the queue only once at
+/// a time.
+class WorkQueue {
+  final Queue<TypeInformation> queue = Queue<TypeInformation>();
+
+  void add(TypeInformation element) {
+    if (element.doNotEnqueue) return;
+    if (element.inQueue) return;
+    queue.addLast(element);
+    element.inQueue = true;
+  }
+
+  void addAll(Iterable<TypeInformation> all) {
+    all.forEach(add);
+  }
+
+  TypeInformation remove() {
+    TypeInformation element = queue.removeFirst();
+    element.inQueue = false;
+    return element;
+  }
+
+  bool get isEmpty => queue.isEmpty;
+
+  int get length => queue.length;
+}
+
+class TypeGraphInferrer implements TypesInferrer {
+  InferrerEngine inferrer;
+  final JClosedWorld closedWorld;
+
+  final Compiler _compiler;
+  final GlobalLocalsMap _globalLocalsMap;
+  final InferredDataBuilder _inferredDataBuilder;
+  Metrics _metrics = Metrics.none();
+
+  TypeGraphInferrer(this._compiler, this.closedWorld, this._globalLocalsMap,
+      this._inferredDataBuilder);
+
+  String get name => 'Graph inferrer';
+
+  Metrics get metrics => _metrics;
+
+  AbstractValueDomain get abstractValueDomain =>
+      closedWorld.abstractValueDomain;
+
+  @override
+  GlobalTypeInferenceResults analyzeMain(FunctionEntity main) {
+    inferrer = createInferrerEngineFor(main);
+    inferrer.runOverAllElements();
+    _metrics = inferrer.metrics;
+    return buildResults();
+  }
+
+  InferrerEngine createInferrerEngineFor(FunctionEntity main) {
+    return InferrerEngine(
+        _compiler.options,
+        _compiler.progress,
+        _compiler.reporter,
+        _compiler.outputProvider,
+        closedWorld,
+        main,
+        _globalLocalsMap,
+        _inferredDataBuilder);
+  }
+
+  Iterable<MemberEntity> getCallersOfForTesting(MemberEntity element) {
+    return inferrer.getCallersOfForTesting(element);
+  }
+
+  GlobalTypeInferenceResults buildResults() {
+    inferrer.close();
+
+    Map<MemberEntity, GlobalTypeInferenceMemberResult> memberResults =
+        <MemberEntity, GlobalTypeInferenceMemberResult>{};
+    Map<Local, AbstractValue> parameterResults = <Local, AbstractValue>{};
+
+    void createMemberResults(
+        MemberEntity member, MemberTypeInformation typeInformation) {
+      GlobalTypeInferenceElementData data =
+          inferrer.dataOfMember(member).compress();
+      bool isJsInterop = closedWorld.nativeData.isJsInteropMember(member);
+
+      AbstractValue returnType;
+      AbstractValue type;
+
+      if (isJsInterop) {
+        returnType = type = abstractValueDomain.dynamicType;
+      } else if (member is FunctionEntity) {
+        returnType = typeInformation.type;
+        type = abstractValueDomain.functionType;
+      } else {
+        returnType = abstractValueDomain.dynamicType;
+        type = typeInformation.type;
+      }
+
+      bool throwsAlways =
+          // Always throws if the return type was inferred to be non-null empty.
+          returnType != null &&
+              abstractValueDomain.isEmpty(returnType).isDefinitelyTrue;
+
+      bool isCalledOnce = typeInformation.isCalledOnce();
+
+      memberResults[member] = GlobalTypeInferenceMemberResultImpl(
+          data, returnType, type,
+          throwsAlways: throwsAlways, isCalledOnce: isCalledOnce);
+    }
+
+    Set<FieldEntity> freeVariables = Set<FieldEntity>();
+    inferrer.types.forEachMemberType(
+        (MemberEntity member, MemberTypeInformation typeInformation) {
+      createMemberResults(member, typeInformation);
+      if (member is JClosureCallMethod) {
+        ClosureRepresentationInfo info =
+            closedWorld.closureDataLookup.getScopeInfo(member);
+        info.forEachFreeVariable(_globalLocalsMap.getLocalsMap(member),
+            (Local from, FieldEntity to) {
+          freeVariables.add(to);
+        });
+      }
+    });
+    for (FieldEntity field in freeVariables) {
+      if (!memberResults.containsKey(field)) {
+        MemberTypeInformation typeInformation =
+            inferrer.types.getInferredTypeOfMember(field);
+        typeInformation.computeIsCalledOnce();
+        createMemberResults(field, typeInformation);
+      }
+    }
+
+    inferrer.types.forEachParameterType(
+        (Local parameter, ParameterTypeInformation typeInformation) {
+      AbstractValue type = typeInformation.type;
+      parameterResults[parameter] = type;
+    });
+
+    Map<ir.TreeNode, AbstractValue> allocatedLists = {};
+    inferrer.types.allocatedLists
+        .forEach((ir.TreeNode node, ListTypeInformation typeInformation) {
+      allocatedLists[node] = typeInformation.type;
+    });
+
+    GlobalTypeInferenceResults results = GlobalTypeInferenceResultsImpl(
+        closedWorld,
+        _globalLocalsMap,
+        _inferredDataBuilder.close(closedWorld),
+        memberResults,
+        parameterResults,
+        inferrer.returnsListElementTypeSet,
+        allocatedLists);
+
+    inferrer.clear();
+
+    return results;
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer_experimental/type_graph_nodes.dart
new file mode 100644
index 0000000..cfd56d8
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/type_graph_nodes.dart
@@ -0,0 +1,2219 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library compiler.src.inferrer.type_graph_nodes;
+
+import 'dart:collection' show IterableBase;
+
+import 'package:kernel/ast.dart' as ir;
+
+import '../common/names.dart' show Identifiers;
+import '../constants/values.dart';
+import '../elements/entities.dart';
+import '../elements/types.dart';
+import '../universe/selector.dart' show Selector;
+import '../util/util.dart' show Setlet;
+import '../world_interfaces.dart' show JClosedWorld;
+import '../inferrer/abstract_value_domain.dart';
+import 'debug.dart' as debug;
+import 'engine_interfaces.dart';
+import 'locals_handler.dart' show ArgumentsTypes;
+import 'type_system.dart';
+
+/// Common class for all nodes in the graph. The current nodes are:
+///
+/// - Concrete types
+/// - Elements
+/// - Call sites
+/// - Narrowing instructions
+/// - Phi instructions
+/// - Containers (for lists)
+/// - Type of the element in a container
+///
+/// A node has a set of inputs and users. Inputs are used to
+/// compute the type of the node ([TypeInformation.computeType]). Users are
+/// added to the inferrer's work queue when the type of the node
+/// changes.
+abstract class TypeInformation {
+  Set<TypeInformation> users;
+  ParameterInputs _inputs;
+
+  /// The type the inferrer has found for this [TypeInformation].
+  /// Initially empty.
+  AbstractValue type;
+
+  /// The graph node of the member this [TypeInformation] node belongs to.
+  final MemberTypeInformation? context;
+
+  /// The element this [TypeInformation] node belongs to.
+  MemberEntity? get contextMember => context?.member;
+
+  ParameterInputs get inputs => _inputs;
+
+  /// We abandon inference in certain cases (complex cyclic flow, native
+  /// behaviours, etc.). In some case, we might resume inference in the
+  /// closure tracer, which is handled by checking whether [inputs] has
+  /// been set to [STOP_TRACKING_INPUTS_MARKER].
+  bool abandonInferencing = false;
+  bool get mightResume => !identical(inputs, STOP_TRACKING_INPUTS_MARKER);
+
+  /// Number of times this [TypeInformation] has changed type.
+  int refineCount = 0;
+
+  /// Whether this [TypeInformation] is currently in the inferrer's
+  /// work queue.
+  bool inQueue = false;
+
+  /// Used to disable enqueueing of type informations where we know that their
+  /// type will not change for other reasons than being stable. For example,
+  /// if inference is disabled for a type and it is hardwired to dynamic, this
+  /// is set to true to spare recomputing dynamic again and again. Changing this
+  /// to false should never change inference outcome, just make is slower.
+  bool doNotEnqueue = false;
+
+  /// Whether this [TypeInformation] has a stable [type] that will not
+  /// change.
+  bool isStable = false;
+
+  // TypeInformations are unique. Store an arbitrary identity hash code.
+  static int _staticHashCode = 0;
+  @override
+  final int hashCode = _staticHashCode = (_staticHashCode + 1).toUnsigned(30);
+
+  bool get isConcrete => false;
+
+  TypeInformation(this.type, this.context)
+      : _inputs = _BasicParameterInputs([]),
+        users = Setlet<TypeInformation>();
+
+  TypeInformation.noInputs(this.type, this.context)
+      : _inputs = const _BasicParameterInputs([]),
+        users = Setlet<TypeInformation>();
+
+  TypeInformation.untracked(this.type)
+      : _inputs = const _BasicParameterInputs([]),
+        users = const {},
+        context = null;
+
+  TypeInformation.withInputs(this.type, this.context, this._inputs)
+      : users = Setlet<TypeInformation>();
+
+  void addUser(TypeInformation user) {
+    assert(!user.isConcrete);
+    users.add(user);
+  }
+
+  void addUsersOf(TypeInformation other) {
+    users.addAll(other.users);
+  }
+
+  void removeUser(TypeInformation user) {
+    assert(!user.isConcrete);
+    users.remove(user);
+  }
+
+  // The below is not a compile time constant to make it differentiable
+  // from other empty lists of [TypeInformation].
+  static final STOP_TRACKING_INPUTS_MARKER =
+      _BasicParameterInputs(List.empty());
+
+  bool areInputsTracked() {
+    return inputs != STOP_TRACKING_INPUTS_MARKER;
+  }
+
+  void addInput(TypeInformation input) {
+    // Cheap one-level cycle detection.
+    if (input == this) return;
+    if (areInputsTracked()) {
+      _inputs.add(input);
+    }
+    // Even if we abandon inferencing on this [TypeInformation] we
+    // need to collect the users, so that phases that track where
+    // elements flow in still work.
+    input.addUser(this);
+  }
+
+  void removeInput(TypeInformation input) {
+    if (!abandonInferencing || mightResume) {
+      _inputs.remove(input);
+    }
+    // We can have multiple inputs of the same [TypeInformation].
+    if (!inputs.contains(input)) {
+      input.removeUser(this);
+    }
+  }
+
+  AbstractValue refine(InferrerEngine inferrer) {
+    return abandonInferencing ? safeType(inferrer) : computeType(inferrer);
+  }
+
+  /// Computes a new type for this [TypeInformation] node depending on its
+  /// potentially updated inputs.
+  AbstractValue computeType(InferrerEngine inferrer);
+
+  /// Returns an approximation for this [TypeInformation] node that is always
+  /// safe to use. Used when abandoning inference on a node.
+  AbstractValue safeType(InferrerEngine inferrer) {
+    return inferrer.types.dynamicType.type;
+  }
+
+  void giveUp(InferrerEngine inferrer, {bool clearInputs = true}) {
+    abandonInferencing = true;
+    // Do not remove [this] as a user of nodes in [inputs],
+    // because our tracing analysis could be interested in tracing
+    // this node.
+    if (clearInputs) _inputs = STOP_TRACKING_INPUTS_MARKER;
+    // Do not remove users because our tracing analysis could be
+    // interested in tracing the users of this node.
+  }
+
+  void clear() {
+    _inputs = STOP_TRACKING_INPUTS_MARKER;
+    users = const {};
+  }
+
+  /// Reset the analysis of this node by making its type empty.
+
+  bool reset(InferrerEngine inferrer) {
+    if (abandonInferencing) return false;
+    type = inferrer.abstractValueDomain.emptyType;
+    refineCount = 0;
+    return true;
+  }
+
+  accept(TypeInformationVisitor visitor);
+
+  /// The [Element] where this [TypeInformation] was created. May be `null`
+  /// for some [TypeInformation] nodes, where we do not need to store
+  /// the information.
+  MemberEntity? get owner => (context != null) ? context?.member : null;
+
+  /// Returns whether the type cannot change after it has been
+  /// inferred.
+  bool hasStableType(InferrerEngine inferrer) {
+    return !mightResume && inputs.every((e) => e.isStable);
+  }
+
+  void removeAndClearReferences(InferrerEngine inferrer) {
+    inputs.forEach((info) {
+      info.removeUser(this);
+    });
+  }
+
+  void stabilize(InferrerEngine inferrer) {
+    removeAndClearReferences(inferrer);
+    // Do not remove users because the tracing analysis could be interested
+    // in tracing the users of this node.
+    _inputs = STOP_TRACKING_INPUTS_MARKER;
+    abandonInferencing = true;
+    isStable = true;
+  }
+
+  void maybeResume() {
+    if (!mightResume) return;
+    abandonInferencing = false;
+    doNotEnqueue = false;
+  }
+
+  /// Destroys information not needed after type inference.
+  void cleanup() {
+    users = const {};
+    _inputs = const _BasicParameterInputs([]);
+  }
+
+  String toStructuredText(String indent) {
+    StringBuffer sb = StringBuffer();
+    _toStructuredText(sb, indent, Set<TypeInformation>());
+    return sb.toString();
+  }
+
+  void _toStructuredText(
+      StringBuffer sb, String indent, Set<TypeInformation> seen) {
+    sb.write(toString());
+  }
+}
+
+abstract class ApplyableTypeInformation implements TypeInformation {
+  bool mightBePassedToFunctionApply = false;
+}
+
+/// Marker node used only during tree construction but not during actual type
+/// refinement.
+///
+/// Currently, this is used to give a type to an optional parameter even before
+/// the corresponding default expression has been analyzed. See
+/// [getDefaultTypeOfParameter] and [setDefaultTypeOfParameter] for details.
+class PlaceholderTypeInformation extends TypeInformation {
+  PlaceholderTypeInformation(
+      AbstractValueDomain abstractValueDomain, MemberTypeInformation context)
+      : super(abstractValueDomain.emptyType, context);
+
+  @override
+  void accept(TypeInformationVisitor visitor) {
+    throw UnsupportedError("Cannot visit placeholder");
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    throw UnsupportedError("Cannot refine placeholder");
+  }
+
+  @override
+  toString() => "Placeholder [$hashCode]";
+}
+
+abstract class ParameterInputs implements Iterable<TypeInformation> {
+  factory ParameterInputs.instanceMember() => _InstanceMemberParameterInputs();
+  void add(TypeInformation input);
+  void remove(TypeInformation input);
+  void replace(TypeInformation old, TypeInformation replacement);
+}
+
+class _BasicParameterInputs extends IterableBase<TypeInformation>
+    implements ParameterInputs {
+  final List<TypeInformation> _baseList;
+
+  const _BasicParameterInputs(this._baseList);
+
+  @override
+  void replace(TypeInformation old, TypeInformation replacement) {
+    for (int i = 0; i < length; i++) {
+      if (_baseList[i] == old) {
+        _baseList[i] = replacement;
+      }
+    }
+  }
+
+  @override
+  void add(TypeInformation input) => _baseList.add(input);
+
+  @override
+  Iterator<TypeInformation> get iterator => _baseList.iterator;
+
+  @override
+  void remove(TypeInformation input) => _baseList.remove(input);
+}
+
+/// Parameters of instance functions behave differently than other
+/// elements because the inferrer may remove inputs. This happens
+/// when the receiver of a dynamic call site can be refined
+/// to a type where we know more about which instance method is being
+/// called.
+class _InstanceMemberParameterInputs extends IterableBase<TypeInformation>
+    implements ParameterInputs {
+  final Map<TypeInformation, int> _inputs = Map<TypeInformation, int>();
+
+  @override
+  void remove(TypeInformation info) {
+    final existing = _inputs[info];
+    if (existing == null) return;
+    if (existing == 1) {
+      _inputs.remove(info);
+    } else {
+      _inputs[info] = existing - 1;
+    }
+  }
+
+  @override
+  void add(TypeInformation info) {
+    final existing = _inputs[info];
+    if (existing == null) {
+      _inputs[info] = 1;
+    } else {
+      _inputs[info] = existing + 1;
+    }
+  }
+
+  @override
+  void replace(TypeInformation old, TypeInformation replacement) {
+    var existing = _inputs[old];
+    if (existing != null) {
+      final other = _inputs[replacement];
+      if (other != null) existing += other;
+      _inputs[replacement] = existing;
+      _inputs.remove(old);
+    }
+  }
+
+  @override
+  Iterator<TypeInformation> get iterator => _inputs.keys.iterator;
+  @override
+  Iterable<TypeInformation> where(bool Function(TypeInformation) f) =>
+      _inputs.keys.where(f);
+
+  @override
+  bool contains(Object? info) => _inputs.containsKey(info);
+
+  @override
+  String toString() => _inputs.keys.toList().toString();
+}
+
+/// A node representing a resolved element of the component. The kind of
+/// elements that need an [ElementTypeInformation] are:
+///
+/// - Functions (including getters and setters)
+/// - Constructors (factory or generative)
+/// - Fields
+/// - Parameters
+/// - Local variables mutated in closures
+///
+/// The [ElementTypeInformation] of a function and a constructor is its
+/// return type.
+///
+/// Note that a few elements of these kinds must be treated specially,
+/// and they are dealt in [ElementTypeInformation.handleSpecialCases]:
+///
+/// - Parameters of closures, `noSuchMethod` and `call` instance
+///   methods: we currently do not infer types for those.
+///
+/// - Fields and parameters being assigned by synthesized calls done by
+///   the backend: we do not know what types the backend will use.
+///
+/// - Native functions and fields: because native methods contain no Dart
+///   code, and native fields do not have Dart assignments, we just
+///   trust their type annotation.
+///
+abstract class ElementTypeInformation extends TypeInformation {
+  /// Marker to disable inference for closures in [handleSpecialCases].
+  bool disableInferenceForClosures = true;
+
+  ElementTypeInformation._internal(
+      AbstractValueDomain abstractValueDomain, MemberTypeInformation? context)
+      : super(abstractValueDomain.emptyType, context);
+  ElementTypeInformation._withInputs(AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation? context, ParameterInputs inputs)
+      : super.withInputs(abstractValueDomain.emptyType, context, inputs);
+
+  String getInferredSignature(TypeSystem types);
+
+  String get debugName;
+}
+
+/// A node representing members in the broadest sense:
+///
+/// - Functions
+/// - Constructors
+/// - Fields (also synthetic ones due to closures)
+/// - Local functions (closures)
+///
+/// These should never be created directly but instead are constructed by
+/// the [ElementTypeInformation] factory.
+abstract class MemberTypeInformation extends ElementTypeInformation
+    with ApplyableTypeInformation {
+  final MemberEntity _member;
+
+  /// If [element] is a function, [closurizedCount] is the number of
+  /// times it is closurized. The value gets updated while inferring.
+  int closurizedCount = 0;
+
+  // Strict `bool` value is computed in cleanup(). Also used as a flag to see if
+  // cleanup has been called.
+  bool? _isCalledOnce = null;
+
+  /// This map contains the callers of [element]. It stores all unique call
+  /// sites to enable counting the global number of call sites of [element].
+  ///
+  /// A call site is an [ir.Node].
+  ///
+  /// The global information is summarized in [cleanup], after which [_callers]
+  /// is set to `null`.
+  Map<MemberEntity, Setlet<ir.Node?>>? _callers;
+
+  MemberTypeInformation._internal(
+      AbstractValueDomain abstractValueDomain, this._member)
+      : super._internal(abstractValueDomain, null);
+
+  MemberEntity get member => _member;
+
+  @override
+  String get debugName => '$member';
+
+  void addCall(MemberEntity caller, ir.Node? node) {
+    (_callers ??= <MemberEntity, Setlet<ir.Node?>>{})
+        .putIfAbsent(caller, () => Setlet())
+        .add(node);
+  }
+
+  void removeCall(MemberEntity caller, Object node) {
+    final callers = _callers;
+    if (callers == null) return;
+    final calls = callers[caller];
+    if (calls == null) return;
+    calls.remove(node);
+    if (calls.isEmpty) {
+      callers.remove(caller);
+    }
+  }
+
+  Iterable<MemberEntity>? get callersForTesting {
+    return _callers?.keys;
+  }
+
+  bool isCalledOnce() {
+    // If this assert fires it means that this MemberTypeInformation for the
+    // element was not part of type inference. This happens for
+    // ConstructorBodyElements, so guard the call with a test for
+    // ConstructorBodyElement. For other elements, investigate why the element
+    // was not present for type inference.
+    assert(_isCalledOnce != null);
+    return _isCalledOnce ?? false;
+  }
+
+  bool _computeIsCalledOnce() {
+    final callers = _callers;
+    if (callers == null) return false;
+    int count = 0;
+    for (var set in callers.values) {
+      count += set.length;
+      if (count > 1) return false;
+    }
+    return count == 1;
+  }
+
+  void computeIsCalledOnce() {
+    assert(_isCalledOnce == null, "isCalledOnce has already been computed.");
+    _isCalledOnce = _computeIsCalledOnce();
+  }
+
+  bool get isClosurized => closurizedCount > 0;
+
+  // Closurized methods never become stable to ensure that the information in
+  // [users] is accurate. The inference stops tracking users for stable types.
+  // Note that we only override the getter, the setter will still modify the
+  // state of the [isStable] field inherited from [TypeInformation].
+  @override
+  bool get isStable => super.isStable && !isClosurized;
+
+  AbstractValue? handleSpecialCases(InferrerEngine inferrer);
+
+  AbstractValue? _handleFunctionCase(
+      FunctionEntity function, InferrerEngine inferrer) {
+    if (inferrer.closedWorld.nativeData.isNativeMember(function)) {
+      // Use the type annotation as the type for native elements. We
+      // also give up on inferring to make sure this element never
+      // goes in the work queue.
+      giveUp(inferrer);
+      return inferrer
+          .typeOfNativeBehavior(
+              inferrer.closedWorld.nativeData.getNativeMethodBehavior(function))
+          .type;
+    }
+
+    if (inferrer.commonElements.isIsJsSentinel(function)) {
+      giveUp(inferrer);
+      return inferrer.abstractValueDomain.boolType;
+    }
+
+    if (inferrer.commonElements.isCreateSentinel(function) ||
+        inferrer.commonElements.isCreateJsSentinel(function)) {
+      giveUp(inferrer);
+      return inferrer.abstractValueDomain.lateSentinelType;
+    }
+
+    return null;
+  }
+
+  AbstractValue potentiallyNarrowType(
+      AbstractValue mask, InferrerEngine inferrer) {
+    return _potentiallyNarrowType(mask, inferrer);
+  }
+
+  AbstractValue _potentiallyNarrowType(
+      AbstractValue mask, InferrerEngine inferrer);
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    final special = handleSpecialCases(inferrer);
+    if (special != null) return potentiallyNarrowType(special, inferrer);
+    return potentiallyNarrowType(
+        inferrer.types.computeTypeMask(inputs), inferrer);
+  }
+
+  @override
+  AbstractValue safeType(InferrerEngine inferrer) {
+    return potentiallyNarrowType(super.safeType(inferrer), inferrer);
+  }
+
+  @override
+  String toString() => 'Member $_member $type';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitMemberTypeInformation(this);
+  }
+
+  @override
+  void cleanup() {
+    _callers = null;
+    super.cleanup();
+  }
+
+  @override
+  String getInferredSignature(TypeSystem types) {
+    return types.getInferredSignatureOfMethod(_member as FunctionEntity);
+  }
+}
+
+class FieldTypeInformation extends MemberTypeInformation {
+  @override
+  final FieldEntity _member;
+  final DartType _type;
+
+  FieldTypeInformation(
+      AbstractValueDomain abstractValueDomain, this._member, this._type)
+      : super._internal(abstractValueDomain, _member);
+
+  @override
+  AbstractValue? handleSpecialCases(InferrerEngine inferrer) {
+    if (!inferrer.canFieldBeUsedForGlobalOptimizations(_member) ||
+        inferrer.assumeDynamic(_member)) {
+      // Do not infer types for fields that have a corresponding annotation or
+      // are assigned by synthesized calls
+
+      giveUp(inferrer);
+      return safeType(inferrer);
+    }
+    if (inferrer.closedWorld.nativeData.isNativeMember(_member)) {
+      // Use the type annotation as the type for native elements. We
+      // also give up on inferring to make sure this element never
+      // goes in the work queue.
+      giveUp(inferrer);
+      return inferrer
+          .typeOfNativeBehavior(inferrer.closedWorld.nativeData
+              .getNativeFieldLoadBehavior(_member))
+          .type;
+    }
+    return null;
+  }
+
+  @override
+  AbstractValue _potentiallyNarrowType(
+      AbstractValue mask, InferrerEngine inferrer) {
+    return _narrowType(inferrer.closedWorld, mask, _type);
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    // The number of inputs of non-final fields is
+    // not stable. Therefore such a field cannot be stable.
+    if (!_member.isAssignable) {
+      return false;
+    }
+    return super.hasStableType(inferrer);
+  }
+}
+
+class GetterTypeInformation extends MemberTypeInformation {
+  @override
+  final FunctionEntity _member;
+  final FunctionType _type;
+
+  GetterTypeInformation(
+      AbstractValueDomain abstractValueDomain, this._member, this._type)
+      : super._internal(abstractValueDomain, _member);
+
+  @override
+  AbstractValue? handleSpecialCases(InferrerEngine inferrer) {
+    return _handleFunctionCase(_member, inferrer);
+  }
+
+  @override
+  AbstractValue _potentiallyNarrowType(
+      AbstractValue mask, InferrerEngine inferrer) {
+    return _narrowType(inferrer.closedWorld, mask, _type.returnType);
+  }
+}
+
+class SetterTypeInformation extends MemberTypeInformation {
+  @override
+  final FunctionEntity _member;
+
+  SetterTypeInformation(AbstractValueDomain abstractValueDomain, this._member)
+      : super._internal(abstractValueDomain, _member);
+
+  @override
+  AbstractValue? handleSpecialCases(InferrerEngine inferrer) {
+    return _handleFunctionCase(_member, inferrer);
+  }
+
+  @override
+  AbstractValue _potentiallyNarrowType(
+      AbstractValue mask, InferrerEngine inferrer) {
+    return mask;
+  }
+}
+
+class MethodTypeInformation extends MemberTypeInformation {
+  @override
+  final FunctionEntity _member;
+  final FunctionType _type;
+
+  MethodTypeInformation(
+      AbstractValueDomain abstractValueDomain, this._member, this._type)
+      : super._internal(abstractValueDomain, _member);
+
+  @override
+  AbstractValue? handleSpecialCases(InferrerEngine inferrer) {
+    return _handleFunctionCase(_member, inferrer);
+  }
+
+  @override
+  AbstractValue _potentiallyNarrowType(
+      AbstractValue mask, InferrerEngine inferrer) {
+    if (inferrer.commonElements.isLateReadCheck(_member)) {
+      mask = inferrer.abstractValueDomain.excludeLateSentinel(mask);
+    }
+    return _narrowType(inferrer.closedWorld, mask, _type.returnType);
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) => false;
+}
+
+class FactoryConstructorTypeInformation extends MemberTypeInformation {
+  @override
+  final ConstructorEntity _member;
+  final FunctionType _type;
+
+  FactoryConstructorTypeInformation(
+      AbstractValueDomain abstractValueDomain, this._member, this._type)
+      : super._internal(abstractValueDomain, _member);
+
+  @override
+  AbstractValue? handleSpecialCases(InferrerEngine inferrer) {
+    AbstractValueDomain abstractValueDomain = inferrer.abstractValueDomain;
+    if (_member.isFromEnvironmentConstructor) {
+      if (_member.enclosingClass == inferrer.commonElements.intClass) {
+        giveUp(inferrer);
+        return abstractValueDomain.includeNull(abstractValueDomain.intType);
+      } else if (_member.enclosingClass == inferrer.commonElements.boolClass) {
+        giveUp(inferrer);
+        return abstractValueDomain.includeNull(abstractValueDomain.boolType);
+      } else if (_member.enclosingClass ==
+          inferrer.commonElements.stringClass) {
+        giveUp(inferrer);
+        return abstractValueDomain.includeNull(abstractValueDomain.stringType);
+      }
+    }
+    return _handleFunctionCase(_member, inferrer);
+  }
+
+  @override
+  AbstractValue _potentiallyNarrowType(
+      AbstractValue mask, InferrerEngine inferrer) {
+    return _narrowType(inferrer.closedWorld, mask, _type.returnType);
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    return super.hasStableType(inferrer);
+  }
+}
+
+class GenerativeConstructorTypeInformation extends MemberTypeInformation {
+  @override
+  final FunctionEntity _member;
+
+  GenerativeConstructorTypeInformation(
+      AbstractValueDomain abstractValueDomain, this._member)
+      : super._internal(abstractValueDomain, _member);
+
+  @override
+  AbstractValue? handleSpecialCases(InferrerEngine inferrer) {
+    return _handleFunctionCase(_member, inferrer);
+  }
+
+  @override
+  AbstractValue _potentiallyNarrowType(
+      AbstractValue mask, InferrerEngine inferrer) {
+    return mask;
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    return super.hasStableType(inferrer);
+  }
+}
+
+/// A node representing parameters:
+///
+/// - Parameters
+/// - Initializing formals
+///
+/// These should never be created directly but instead are constructed by
+/// the [ElementTypeInformation] factory.
+class ParameterTypeInformation extends ElementTypeInformation {
+  final Local _parameter;
+  final DartType _type;
+  final FunctionEntity _method;
+  final bool _isInstanceMemberParameter;
+  final bool _isClosureParameter;
+  final bool _isInitializingFormal;
+  bool _isTearOffClosureParameter = false;
+
+  ParameterTypeInformation.localFunction(
+      super.abstractValueDomain,
+      MemberTypeInformation super.context,
+      this._parameter,
+      this._type,
+      this._method)
+      : _isInstanceMemberParameter = false,
+        _isClosureParameter = true,
+        _isInitializingFormal = false,
+        super._internal();
+
+  ParameterTypeInformation.static(
+      super.abstractValueDomain,
+      MemberTypeInformation super.context,
+      this._parameter,
+      this._type,
+      this._method,
+      {bool isInitializingFormal = false})
+      : _isInstanceMemberParameter = false,
+        _isClosureParameter = false,
+        _isInitializingFormal = isInitializingFormal,
+        super._internal();
+
+  ParameterTypeInformation.instanceMember(
+      AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation context,
+      this._parameter,
+      this._type,
+      this._method,
+      ParameterInputs inputs)
+      : _isInstanceMemberParameter = true,
+        _isClosureParameter = false,
+        _isInitializingFormal = false,
+        super._withInputs(abstractValueDomain, context, inputs);
+
+  FunctionEntity get method => _method;
+
+  Local get parameter => _parameter;
+
+  bool get isRegularParameter => !_isInitializingFormal;
+
+  @override
+  String get debugName => '$parameter';
+
+  void tagAsTearOffClosureParameter(InferrerEngine inferrer) {
+    assert(!_isInitializingFormal);
+    _isTearOffClosureParameter = true;
+    // We have to add a flow-edge for the default value (if it exists), as we
+    // might not see all call-sites and thus miss the use of it.
+    final defaultType = inferrer.getDefaultTypeOfParameter(_parameter);
+    defaultType.addUser(this);
+  }
+
+  // TODO(herhut): Cleanup into one conditional.
+  AbstractValue? handleSpecialCases(InferrerEngine inferrer) {
+    if (!inferrer.canFunctionParametersBeUsedForGlobalOptimizations(_method) ||
+        inferrer.assumeDynamic(_method)) {
+      // Do not infer types for parameters that have a corresponding annotation
+      // or that are assigned by synthesized calls.
+      giveUp(inferrer);
+      return safeType(inferrer);
+    }
+
+    // The below do not apply to parameters of constructors, so skip
+    // initializing formals.
+    if (_isInitializingFormal) return null;
+
+    if ((_isTearOffClosureParameter || _isClosureParameter) &&
+        disableInferenceForClosures) {
+      // Do not infer types for parameters of closures. We do not
+      // clear the inputs in case the closure is successfully
+      // traced.
+      giveUp(inferrer, clearInputs: false);
+      return safeType(inferrer);
+    }
+    if (_isInstanceMemberParameter &&
+        (_method.name == Identifiers.noSuchMethod_ ||
+            (_method.name == Identifiers.call &&
+                disableInferenceForClosures))) {
+      // Do not infer types for parameters of [noSuchMethod] and [call] instance
+      // methods.
+      giveUp(inferrer);
+      return safeType(inferrer);
+    }
+    if (inferrer.inferredDataBuilder
+        .getCurrentlyKnownMightBePassedToApply(_method)) {
+      giveUp(inferrer);
+      return safeType(inferrer);
+    }
+    if (_method == inferrer.mainElement) {
+      // The implicit call to main is not seen by the inferrer,
+      // therefore we explicitly set the type of its parameters as
+      // dynamic.
+      // TODO(14566): synthesize a call instead to get the exact
+      // types.
+      giveUp(inferrer);
+      return safeType(inferrer);
+    }
+
+    return null;
+  }
+
+  AbstractValue potentiallyNarrowType(
+      AbstractValue mask, InferrerEngine inferrer) {
+    if (inferrer.closedWorld.annotationsData
+        .getParameterCheckPolicy(method)
+        .isTrusted) {
+      // In checked or strong mode we don't trust the types of the arguments
+      // passed to a parameter. The means that the checking of a parameter is
+      // based on the actual arguments.
+      //
+      // With --trust-type-annotations or --omit-implicit-checks we _do_ trust
+      // the arguments passed to a parameter - and we never check them.
+      //
+      // In all these cases we _do_ trust the static type of a parameter within
+      // the method itself. For instance:
+      //
+      //     method(int i) => i;
+      //     main() {
+      //       dynamic f = method;
+      //       f(0); // valid call
+      //       f(''); // invalid call
+      //     }
+      //
+      // Here, in all cases, we infer the returned value of `method` to be an
+      // `int`. In checked and strong mode we infer the parameter of `method` to
+      // be either `int` or `String` and therefore insert a check at the entry
+      // of 'method'. With --trust-type-annotations or --omit-implicit-checks we
+      // (unsoundly) infer the parameter to be `int` and leave the parameter
+      // unchecked, and `method` will at runtime actually return a `String` from
+      // the second invocation.
+      //
+      // The trusting of the parameter types within the body of the method is
+      // is done through `LocalsHandler.update` called in
+      // `KernelTypeGraphBuilder.handleParameter`.
+      return _narrowType(inferrer.closedWorld, mask, _type);
+    }
+    return mask;
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    final special = handleSpecialCases(inferrer);
+    if (special != null) return special;
+    return potentiallyNarrowType(
+        inferrer.types.computeTypeMask(inputs), inferrer);
+  }
+
+  @override
+  AbstractValue safeType(InferrerEngine inferrer) {
+    return potentiallyNarrowType(super.safeType(inferrer), inferrer);
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    // The number of inputs of parameters of instance methods is
+    // not stable. Therefore such a parameter cannot be stable.
+    if (_isInstanceMemberParameter) {
+      return false;
+    }
+    return super.hasStableType(inferrer);
+  }
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitParameterTypeInformation(this);
+  }
+
+  @override
+  String toString() => 'Parameter $_parameter $type';
+
+  @override
+  String getInferredSignature(TypeSystem types) {
+    throw UnsupportedError('ParameterTypeInformation.getInferredSignature');
+  }
+}
+
+enum CallType {
+  access,
+  forIn,
+}
+
+bool validCallType(CallType callType, ir.Node? call, Selector selector) {
+  switch (callType) {
+    case CallType.access:
+      return call is ir.Node;
+    case CallType.forIn:
+      return call is ir.ForInStatement;
+  }
+}
+
+/// A [CallSiteTypeInformation] is a call found in the AST, or a
+/// synthesized call for implicit calls in Dart (such as forwarding
+/// factories). The [_call] field is a [ast.Node] for the former, and an
+/// [Element] for the latter.
+///
+/// In the inferrer graph, [CallSiteTypeInformation] nodes do not have
+/// any assignment. They rely on the [caller] field for static calls,
+/// and [selector] and [receiver] fields for dynamic calls.
+abstract class CallSiteTypeInformation extends TypeInformation
+    with ApplyableTypeInformation {
+  final ir.Node? _call;
+  final MemberEntity caller;
+  final Selector? selector;
+  final ArgumentsTypes? arguments;
+  final bool inLoop;
+
+  CallSiteTypeInformation(
+      AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation context,
+      this._call,
+      this.caller,
+      this.selector,
+      this.arguments,
+      this.inLoop)
+      : super.noInputs(abstractValueDomain.emptyType, context) {
+    assert(_call is ir.Node || (_call == null && selector?.name == '=='));
+  }
+
+  @override
+  String toString() => 'Call site $debugName $type';
+
+  /// Add [this] to the graph being computed by [engine].
+  void addToGraph(InferrerEngine engine);
+
+  /// Return an iterable over the targets of this call.
+  Iterable<MemberEntity> get callees;
+
+  String get debugName => '$_call';
+}
+
+class StaticCallSiteTypeInformation extends CallSiteTypeInformation {
+  final MemberEntity calledElement;
+
+  StaticCallSiteTypeInformation(
+      AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation context,
+      ir.Node? call,
+      MemberEntity enclosing,
+      this.calledElement,
+      Selector selector,
+      ArgumentsTypes arguments,
+      bool inLoop)
+      : super(abstractValueDomain, context, call, enclosing, selector,
+            arguments, inLoop);
+
+  ir.StaticInvocation get invocationNode => _call as ir.StaticInvocation;
+
+  MemberTypeInformation _getCalledTypeInfo(InferrerEngine inferrer) {
+    return inferrer.types.getInferredTypeOfMember(calledElement);
+  }
+
+  @override
+  void addToGraph(InferrerEngine inferrer) {
+    MemberTypeInformation callee = _getCalledTypeInfo(inferrer);
+    callee.addCall(caller, _call!);
+    callee.addUser(this);
+    if (arguments != null) {
+      arguments!.forEach((info) => info.addUser(this));
+    }
+    inferrer.updateParameterInputs(this, calledElement, arguments, selector,
+        remove: false, addToQueue: false);
+  }
+
+  bool get isSynthesized {
+    // Some calls do not have a corresponding selector, for example
+    // forwarding factory constructors, or synthesized super
+    // constructor calls. We synthesize these calls but do
+    // not create a selector for them.
+    return selector == null;
+  }
+
+  TypeInformation _getCalledTypeInfoWithSelector(InferrerEngine inferrer) {
+    return inferrer.typeOfMemberWithSelector(calledElement, selector);
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    if (isSynthesized) {
+      assert(arguments != null);
+      return _getCalledTypeInfo(inferrer).type;
+    } else {
+      return _getCalledTypeInfoWithSelector(inferrer).type;
+    }
+  }
+
+  @override
+  Iterable<MemberEntity> get callees => [calledElement];
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitStaticCallSiteTypeInformation(this);
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    bool isStable = _getCalledTypeInfo(inferrer).isStable;
+    return isStable &&
+        (arguments == null || arguments!.every((info) => info.isStable)) &&
+        super.hasStableType(inferrer);
+  }
+
+  @override
+  void removeAndClearReferences(InferrerEngine inferrer) {
+    ElementTypeInformation callee = _getCalledTypeInfo(inferrer);
+    callee.removeUser(this);
+    if (arguments != null) {
+      arguments!.forEach((info) => info.removeUser(this));
+    }
+    super.removeAndClearReferences(inferrer);
+  }
+}
+
+class DynamicCallSiteTypeInformation<T extends ir.Node>
+    extends CallSiteTypeInformation {
+  final CallType _callType;
+  final TypeInformation receiver;
+  final AbstractValue mask;
+  final bool isConditional;
+  bool? _hasClosureCallTargets;
+
+  /// Cached concrete targets of this call.
+  Iterable<MemberEntity>? _concreteTargets;
+
+  DynamicCallSiteTypeInformation(
+      AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation context,
+      this._callType,
+      T? call,
+      MemberEntity enclosing,
+      Selector selector,
+      this.mask,
+      this.receiver,
+      ArgumentsTypes arguments,
+      bool inLoop,
+      this.isConditional)
+      : super(abstractValueDomain, context, call, enclosing, selector,
+            arguments, inLoop) {
+    assert(validCallType(_callType, _call, selector));
+  }
+
+  void _addCall(MemberTypeInformation callee) {
+    callee.addCall(caller, _call!);
+  }
+
+  void _removeCall(MemberTypeInformation callee) {
+    callee.removeCall(caller, _call!);
+  }
+
+  @override
+  void addToGraph(InferrerEngine inferrer) {
+    assert((receiver as dynamic) != null); // TODO(48820): Remove when sound.
+    final typeMask = computeTypedSelector(inferrer);
+    _hasClosureCallTargets =
+        inferrer.closedWorld.includesClosureCall(selector!, typeMask);
+    final concreteTargets = _concreteTargets =
+        inferrer.closedWorld.locateMembers(selector!, typeMask);
+    receiver.addUser(this);
+    if (arguments != null) {
+      arguments!.forEach((info) => info.addUser(this));
+    }
+    for (MemberEntity element in concreteTargets) {
+      MemberTypeInformation callee =
+          inferrer.types.getInferredTypeOfMember(element);
+      _addCall(callee);
+      callee.addUser(this);
+      inferrer.updateParameterInputs(this, element, arguments, selector,
+          remove: false, addToQueue: false);
+    }
+  }
+
+  /// `true` if this invocation can hit a 'call' method on a closure.
+  bool get hasClosureCallTargets => _hasClosureCallTargets!;
+
+  /// All concrete targets of this invocation. If [hasClosureCallTargets] is
+  /// `true` the invocation can additional target an unknown set of 'call'
+  /// methods on closures.
+  Iterable<MemberEntity> get concreteTargets => _concreteTargets!;
+
+  @override
+  Iterable<MemberEntity> get callees => _concreteTargets!;
+
+  AbstractValue? computeTypedSelector(InferrerEngine inferrer) {
+    AbstractValue receiverType = receiver.type;
+    if (mask != receiverType) {
+      return receiverType == inferrer.abstractValueDomain.dynamicType
+          ? null
+          : receiverType;
+    } else {
+      return mask;
+    }
+  }
+
+  bool targetsIncludeComplexNoSuchMethod(InferrerEngine inferrer) {
+    return _concreteTargets!.any((MemberEntity e) {
+      return e.isFunction &&
+          e.isInstanceMember &&
+          e.name == Identifiers.noSuchMethod_ &&
+          inferrer.noSuchMethodData.isComplex(e as FunctionEntity);
+    });
+  }
+
+  /// We optimize certain operations on the [int] class because we know more
+  /// about their return type than the actual Dart code. For example, we know
+  /// int + int returns an int. The Dart library code for [int.operator+] only
+  /// says it returns a [num].
+  ///
+  /// Returns the more precise TypeInformation, or `null` to defer to the
+  /// library code.
+  TypeInformation? handleIntrisifiedSelector(
+      Selector selector, AbstractValue? mask, InferrerEngine inferrer) {
+    AbstractValueDomain abstractValueDomain = inferrer.abstractValueDomain;
+    if (mask == null) return null;
+    if (abstractValueDomain.isIntegerOrNull(mask).isPotentiallyFalse) {
+      return null;
+    }
+    if (!selector.isCall && !selector.isOperator) return null;
+    final args = arguments!;
+    if (!args.named.isEmpty) return null;
+    if (args.positional.length > 1) return null;
+
+    bool isInt(TypeInformation info) =>
+        abstractValueDomain.isIntegerOrNull(info.type).isDefinitelyTrue;
+    bool isEmpty(TypeInformation info) =>
+        abstractValueDomain.isEmpty(info.type).isDefinitelyTrue;
+    bool isUInt31(TypeInformation info) => abstractValueDomain
+        .isUInt31(abstractValueDomain.excludeNull(info.type))
+        .isDefinitelyTrue;
+    bool isPositiveInt(TypeInformation info) =>
+        abstractValueDomain.isPositiveIntegerOrNull(info.type).isDefinitelyTrue;
+
+    TypeInformation tryLater() => inferrer.types.nonNullEmptyType;
+
+    final argument = args.isEmpty ? null : args.positional.first;
+
+    String name = selector.name;
+    // These are type inference rules only for useful cases that are not
+    // expressed in the library code, for example:
+    //
+    //     int + int        ->  int
+    //     uint31 | uint31  ->  uint31
+    //
+    switch (name) {
+      case '*':
+      case '+':
+      case '%':
+      case 'remainder':
+      case '~/':
+        if (isEmpty(argument!)) return tryLater();
+        if (isPositiveInt(receiver) && isPositiveInt(argument)) {
+          // uint31 + uint31 -> uint32
+          if (name == '+' && isUInt31(receiver) && isUInt31(argument)) {
+            return inferrer.types.uint32Type;
+          }
+          return inferrer.types.positiveIntType;
+        }
+        if (isInt(argument)) {
+          return inferrer.types.intType;
+        }
+        return null;
+
+      case '|':
+      case '^':
+        if (isEmpty(argument!)) return tryLater();
+        if (isUInt31(receiver) && isUInt31(argument)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
+      case '>>':
+        if (isEmpty(argument!)) return tryLater();
+        if (isUInt31(receiver)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
+      case '>>>':
+        if (isEmpty(argument!)) return tryLater();
+        if (isUInt31(receiver)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
+      case '&':
+        if (isEmpty(argument!)) return tryLater();
+        if (isUInt31(receiver) || isUInt31(argument)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
+      case '-':
+        if (isEmpty(argument!)) return tryLater();
+        if (isInt(argument)) {
+          return inferrer.types.intType;
+        }
+        return null;
+
+      case 'unary-':
+        // The receiver being an int, the return value will also be an int.
+        return inferrer.types.intType;
+
+      case 'abs':
+        return args.hasNoArguments() ? inferrer.types.positiveIntType : null;
+
+      default:
+        return null;
+    }
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    JClosedWorld closedWorld = inferrer.closedWorld;
+    AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
+    final oldTargets = _concreteTargets!;
+    final typeMask = computeTypedSelector(inferrer);
+    final localSelector = selector!;
+    inferrer.updateSelectorInMember(
+        caller, _callType, _call, localSelector, typeMask);
+
+    _hasClosureCallTargets =
+        closedWorld.includesClosureCall(localSelector, typeMask);
+    final concreteTargets =
+        _concreteTargets = closedWorld.locateMembers(localSelector, typeMask);
+
+    // Update the call graph if the targets could have changed.
+    if (!identical(concreteTargets, oldTargets)) {
+      // Add calls to new targets to the graph.
+      concreteTargets
+          .where((target) => !oldTargets.contains(target))
+          .forEach((MemberEntity element) {
+        MemberTypeInformation callee =
+            inferrer.types.getInferredTypeOfMember(element);
+        _addCall(callee);
+        callee.addUser(this);
+        inferrer.updateParameterInputs(this, element, arguments, selector,
+            remove: false, addToQueue: true);
+      });
+
+      // Walk over the old targets, and remove calls that cannot happen anymore.
+      oldTargets
+          .where((target) => !concreteTargets.contains(target))
+          .forEach((MemberEntity element) {
+        MemberTypeInformation callee =
+            inferrer.types.getInferredTypeOfMember(element);
+        _removeCall(callee);
+        callee.removeUser(this);
+        inferrer.updateParameterInputs(this, element, arguments, selector,
+            remove: true, addToQueue: true);
+      });
+    }
+
+    // Walk over the found targets, and compute the joined union type mask
+    // for all these targets.
+    AbstractValue result;
+    if (_hasClosureCallTargets!) {
+      result = abstractValueDomain.dynamicType;
+    } else {
+      result = inferrer.types
+          .joinTypeMasks(concreteTargets.map((MemberEntity element) {
+        if (typeMask != null &&
+            inferrer.returnsListElementType(localSelector, typeMask)) {
+          return abstractValueDomain.getContainerElementType(receiver.type);
+        } else if (typeMask != null &&
+            inferrer.returnsMapValueType(localSelector, typeMask)) {
+          if (abstractValueDomain.isDictionary(typeMask)) {
+            AbstractValue arg = arguments!.positional[0].type;
+            final value = abstractValueDomain.getPrimitiveValue(arg);
+            if (value is StringConstantValue) {
+              String key = value.stringValue;
+              if (abstractValueDomain.containsDictionaryKey(typeMask, key)) {
+                if (debug.VERBOSE) {
+                  print("Dictionary lookup for $key yields "
+                      "${abstractValueDomain.getDictionaryValueForKey(typeMask, key)}.");
+                }
+                return abstractValueDomain.getDictionaryValueForKey(
+                    typeMask, key);
+              } else {
+                // The typeMap is precise, so if we do not find the key, the
+                // lookup will be [null] at runtime.
+                if (debug.VERBOSE) {
+                  print("Dictionary lookup for $key yields [null].");
+                }
+                return inferrer.types.nullType.type;
+              }
+            }
+          }
+          assert(abstractValueDomain.isMap(typeMask));
+          if (debug.VERBOSE) {
+            print("Map lookup for $selector yields "
+                "${abstractValueDomain.getMapValueType(typeMask)}.");
+          }
+          return abstractValueDomain.getMapValueType(typeMask);
+        } else {
+          final info =
+              handleIntrisifiedSelector(localSelector, typeMask, inferrer);
+          if (info != null) return info.type;
+          return inferrer.typeOfMemberWithSelector(element, selector).type;
+        }
+      }));
+    }
+    if (isConditional &&
+        abstractValueDomain.isNull(receiver.type).isPotentiallyTrue) {
+      // Conditional call sites (e.g. `a?.b`) may be null if the receiver is
+      // null.
+      result = abstractValueDomain.includeNull(result);
+    }
+    return result;
+  }
+
+  @override
+  void giveUp(InferrerEngine inferrer, {bool clearInputs = true}) {
+    if (!abandonInferencing) {
+      final call = _call!;
+      inferrer.updateSelectorInMember(caller, _callType, call, selector, mask);
+      final oldTargets = concreteTargets;
+      final localSelector = selector!;
+      _hasClosureCallTargets =
+          inferrer.closedWorld.includesClosureCall(localSelector, mask);
+      final newConcreteTargets = _concreteTargets =
+          inferrer.closedWorld.locateMembers(localSelector, mask);
+      for (MemberEntity element in newConcreteTargets) {
+        if (!oldTargets.contains(element)) {
+          MemberTypeInformation callee =
+              inferrer.types.getInferredTypeOfMember(element);
+          callee.addCall(caller, call);
+          inferrer.updateParameterInputs(this, element, arguments, selector,
+              remove: false, addToQueue: true);
+        }
+      }
+    }
+    super.giveUp(inferrer, clearInputs: clearInputs);
+  }
+
+  @override
+  void removeAndClearReferences(InferrerEngine inferrer) {
+    for (MemberEntity element in concreteTargets) {
+      MemberTypeInformation callee =
+          inferrer.types.getInferredTypeOfMember(element);
+      callee.removeUser(this);
+    }
+    if (arguments != null) {
+      arguments!.forEach((info) => info.removeUser(this));
+    }
+    super.removeAndClearReferences(inferrer);
+  }
+
+  @override
+  String toString() => 'Call site $debugName on ${receiver.type} $type';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitDynamicCallSiteTypeInformation(this);
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    return receiver.isStable &&
+        concreteTargets.every((MemberEntity element) =>
+            inferrer.types.getInferredTypeOfMember(element).isStable) &&
+        (arguments == null || arguments!.every((info) => info.isStable)) &&
+        super.hasStableType(inferrer);
+  }
+}
+
+class ClosureCallSiteTypeInformation extends CallSiteTypeInformation {
+  final TypeInformation closure;
+
+  ClosureCallSiteTypeInformation(
+      AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation context,
+      ir.Node? call,
+      MemberEntity enclosing,
+      Selector selector,
+      this.closure,
+      ArgumentsTypes arguments,
+      bool inLoop)
+      : super(abstractValueDomain, context, call, enclosing, selector,
+            arguments, inLoop);
+
+  @override
+  void addToGraph(InferrerEngine inferrer) {
+    arguments!.forEach((info) => info.addUser(this));
+    closure.addUser(this);
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    AbstractValueDomain abstractValueDomain = inferrer.abstractValueDomain;
+    AbstractValue closureType = closure.type;
+    // We are not tracking closure calls, but if the receiver is not callable,
+    // the call will fail. The abstract value domain does not have a convenient
+    // method for detecting callable types, but we know `null` and unreachable
+    // code have no result type.  This is helpful for propagating
+    // unreachability, i.e. tree-shaking.
+    if (abstractValueDomain.isEmpty(closureType).isDefinitelyTrue ||
+        abstractValueDomain.isNull(closureType).isDefinitelyTrue) {
+      return abstractValueDomain.emptyType;
+    }
+    return safeType(inferrer);
+  }
+
+  @override
+  Iterable<MemberEntity> get callees {
+    throw UnsupportedError("Cannot compute callees of a closure call.");
+  }
+
+  @override
+  String toString() => 'Closure call $debugName on $closure';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitClosureCallSiteTypeInformation(this);
+  }
+
+  @override
+  void removeAndClearReferences(InferrerEngine inferrer) {
+    // This method is a placeholder for the following comment:
+    // We should maintain the information that the closure is a user
+    // of its arguments because we do not check that the arguments
+    // have a stable type for a closure call to be stable; our tracing
+    // analysis want to know whether an (non-stable) argument is
+    // passed to a closure.
+    return super.removeAndClearReferences(inferrer);
+  }
+}
+
+/// A [ConcreteTypeInformation] represents a type that needed
+/// to be materialized during the creation of the graph. For example,
+/// literals, [:this:] or [:super:] need a [ConcreteTypeInformation].
+///
+/// [ConcreteTypeInformation] nodes have no assignment. Also, to save
+/// on memory, we do not add users to [ConcreteTypeInformation] nodes,
+/// because we know such node will never be refined to a different
+/// type.
+class ConcreteTypeInformation extends TypeInformation {
+  ConcreteTypeInformation(super.type) : super.untracked() {
+    this.isStable = true;
+  }
+
+  @override
+  bool get isConcrete => true;
+
+  @override
+  void addUser(TypeInformation user) {
+    // Nothing to do, a concrete type does not get updated so never
+    // needs to notify its users.
+  }
+
+  @override
+  void addUsersOf(TypeInformation other) {
+    // Nothing to do, a concrete type does not get updated so never
+    // needs to notify its users.
+  }
+
+  @override
+  void removeUser(TypeInformation user) {}
+
+  @override
+  void addInput(TypeInformation assignment) {
+    throw "Not supported";
+  }
+
+  @override
+  void removeInput(TypeInformation assignment) {
+    throw "Not supported";
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) => type;
+
+  @override
+  bool reset(InferrerEngine inferrer) {
+    throw "Not supported";
+  }
+
+  @override
+  String toString() => 'Type $type';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitConcreteTypeInformation(this);
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) => true;
+}
+
+class StringLiteralTypeInformation extends ConcreteTypeInformation {
+  final String value;
+
+  StringLiteralTypeInformation(
+      AbstractValueDomain abstractValueDomain, this.value, AbstractValue mask)
+      : super(abstractValueDomain.createPrimitiveValue(
+            mask, StringConstantValue(value)));
+
+  String asString() => value;
+  @override
+  String toString() => 'Type $type value ${value}';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitStringLiteralTypeInformation(this);
+  }
+}
+
+class BoolLiteralTypeInformation extends ConcreteTypeInformation {
+  final bool value;
+
+  BoolLiteralTypeInformation(
+      AbstractValueDomain abstractValueDomain, this.value, AbstractValue mask)
+      : super(abstractValueDomain.createPrimitiveValue(
+            mask, value ? TrueConstantValue() : FalseConstantValue()));
+
+  @override
+  String toString() => 'Type $type value ${value}';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitBoolLiteralTypeInformation(this);
+  }
+}
+
+/// A [NarrowTypeInformation] narrows a [TypeInformation] to a type,
+/// represented in [typeAnnotation].
+///
+/// A [NarrowTypeInformation] node has only one assignment: the
+/// [TypeInformation] it narrows.
+///
+/// [NarrowTypeInformation] nodes are created for:
+///
+/// - Code after `is` and `as` checks, where we have more information
+///   on the type of the right hand side of the expression.
+///
+/// - Code after a dynamic call, where we have more information on the
+///   type of the receiver: it can only be of a class that holds a
+///   potential target of this dynamic call.
+///
+/// - In checked mode, after a type annotation, we have more
+///   information on the type of a local.
+class NarrowTypeInformation extends TypeInformation {
+  final AbstractValue typeAnnotation;
+
+  NarrowTypeInformation(AbstractValueDomain abstractValueDomain,
+      TypeInformation narrowedType, this.typeAnnotation)
+      : super(abstractValueDomain.emptyType, narrowedType.context) {
+    addInput(narrowedType);
+  }
+
+  @override
+  addInput(TypeInformation info) {
+    super.addInput(info);
+    assert(inputs.length == 1);
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    AbstractValueDomain abstractValueDomain = inferrer.abstractValueDomain;
+    AbstractValue input = inputs.first.type;
+    AbstractValue intersection =
+        abstractValueDomain.intersection(input, typeAnnotation);
+    return intersection;
+  }
+
+  @override
+  String toString() {
+    return 'Narrow to $typeAnnotation $type';
+  }
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitNarrowTypeInformation(this);
+  }
+}
+
+/// An [InferredTypeInformation] is a [TypeInformation] that
+/// defaults to the dynamic type until it is marked as being
+/// inferred, at which point it computes its type based on
+/// its inputs.
+abstract class InferredTypeInformation extends TypeInformation {
+  /// Whether the element type in that container has been inferred.
+  bool inferred = false;
+
+  InferredTypeInformation(AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation? context, TypeInformation? parentType)
+      : super(abstractValueDomain.emptyType, context) {
+    if (parentType != null) addInput(parentType);
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    if (!inferred) return safeType(inferrer);
+    return inferrer.types.computeTypeMask(inputs);
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    return inferred && super.hasStableType(inferrer);
+  }
+}
+
+/// A [ListTypeInformation] is a [TypeInformation] created
+/// for each `List` instantiations.
+class ListTypeInformation extends TypeInformation with TracedTypeInformation {
+  final ElementInContainerTypeInformation elementType;
+
+  /// The container type before it is inferred.
+  final AbstractValue originalType;
+
+  /// The length at the allocation site.
+  final int? originalLength;
+
+  /// The length after the container has been traced.
+  int? inferredLength;
+
+  ListTypeInformation(
+      AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation? context,
+      this.originalType,
+      this.elementType,
+      this.originalLength)
+      : super(originalType, context) {
+    inferredLength = abstractValueDomain.getContainerLength(originalType);
+    elementType.addUser(this);
+  }
+
+  @override
+  String toString() => 'List type $type';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitListTypeInformation(this);
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    return elementType.isStable && super.hasStableType(inferrer);
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    AbstractValueDomain abstractValueDomain = inferrer.abstractValueDomain;
+    AbstractValue mask = type;
+    if (!abstractValueDomain.isContainer(type) ||
+        abstractValueDomain.getContainerElementType(type) != elementType.type ||
+        abstractValueDomain.getContainerLength(type) != inferredLength) {
+      return abstractValueDomain.createContainerValue(
+          abstractValueDomain.getGeneralization(originalType),
+          abstractValueDomain.getAllocationNode(originalType),
+          abstractValueDomain.getAllocationElement(originalType),
+          elementType.type,
+          inferredLength);
+    }
+    return mask;
+  }
+
+  @override
+  AbstractValue safeType(InferrerEngine inferrer) => originalType;
+
+  @override
+  void cleanup() {
+    super.cleanup();
+    elementType.cleanup();
+    _flowsInto = null;
+  }
+}
+
+/// An [ElementInContainerTypeInformation] holds the common type of the
+/// elements in a [ListTypeInformation].
+class ElementInContainerTypeInformation extends InferredTypeInformation {
+  ElementInContainerTypeInformation(
+      super.abstractValueDomain, super.context, super.elementType);
+
+  @override
+  String toString() => 'Element in container $type';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitElementInContainerTypeInformation(this);
+  }
+}
+
+/// A [SetTypeInformation] is a [TypeInformation] created for sets.
+class SetTypeInformation extends TypeInformation with TracedTypeInformation {
+  final ElementInSetTypeInformation elementType;
+
+  final AbstractValue originalType;
+
+  SetTypeInformation(
+      MemberTypeInformation? context, this.originalType, this.elementType)
+      : super(originalType, context) {
+    elementType.addUser(this);
+  }
+
+  @override
+  String toString() => 'Set type $type';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitSetTypeInformation(this);
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    AbstractValueDomain abstractValueDomain = inferrer.abstractValueDomain;
+    AbstractValue mask = type;
+    if (!abstractValueDomain.isSet(type) ||
+        abstractValueDomain.getSetElementType(type) != elementType.type) {
+      return abstractValueDomain.createSetValue(
+          abstractValueDomain.getGeneralization(originalType),
+          abstractValueDomain.getAllocationNode(originalType),
+          abstractValueDomain.getAllocationElement(originalType),
+          elementType.type);
+    }
+    return mask;
+  }
+
+  @override
+  AbstractValue safeType(InferrerEngine inferrer) => originalType;
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    return elementType.isStable && super.hasStableType(inferrer);
+  }
+
+  @override
+  void cleanup() {
+    super.cleanup();
+    elementType.cleanup();
+    _flowsInto = null;
+  }
+}
+
+/// An [ElementInSetTypeInformation] holds the common type of the elements in a
+/// [SetTypeInformation].
+class ElementInSetTypeInformation extends InferredTypeInformation {
+  ElementInSetTypeInformation(
+      super.abstractValueDomain, super.context, super.elementType);
+
+  @override
+  String toString() => 'Element in set $type';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitElementInSetTypeInformation(this);
+  }
+}
+
+/// A [MapTypeInformation] is a [TypeInformation] created
+/// for maps.
+class MapTypeInformation extends TypeInformation with TracedTypeInformation {
+  // When in Dictionary mode, this map tracks the type of the values that
+  // have been assigned to a specific [String] key.
+  final Map<String, ValueInMapTypeInformation> typeInfoMap = {};
+  // These fields track the overall type of the keys/values in the map.
+  final KeyInMapTypeInformation keyType;
+  final ValueInMapTypeInformation valueType;
+  final AbstractValue originalType;
+
+  // Set to false if a statically unknown key flows into this map.
+  bool _allKeysAreStrings = true;
+
+  bool get inDictionaryMode => !bailedOut && _allKeysAreStrings;
+
+  MapTypeInformation(MemberTypeInformation? context, this.originalType,
+      this.keyType, this.valueType)
+      : super(originalType, context) {
+    keyType.addUser(this);
+    valueType.addUser(this);
+  }
+
+  TypeInformation? addEntryInput(AbstractValueDomain abstractValueDomain,
+      TypeInformation key, TypeInformation value,
+      [bool nonNull = false]) {
+    ValueInMapTypeInformation? newInfo = null;
+    if (_allKeysAreStrings && key is StringLiteralTypeInformation) {
+      String keyString = key.asString();
+      typeInfoMap.putIfAbsent(keyString, () {
+        newInfo = ValueInMapTypeInformation(
+            abstractValueDomain, context, null, nonNull);
+        return newInfo!;
+      });
+      typeInfoMap[keyString]!.addInput(value);
+    } else {
+      _allKeysAreStrings = false;
+      typeInfoMap.clear();
+    }
+    keyType.addInput(key);
+    valueType.addInput(value);
+    newInfo?.addUser(this);
+
+    return newInfo;
+  }
+
+  List<TypeInformation> addMapInput(
+      AbstractValueDomain abstractValueDomain, MapTypeInformation other) {
+    List<TypeInformation> newInfos = <TypeInformation>[];
+    if (_allKeysAreStrings && other.inDictionaryMode) {
+      other.typeInfoMap.forEach((keyString, value) {
+        typeInfoMap.putIfAbsent(keyString, () {
+          final newInfo = ValueInMapTypeInformation(
+              abstractValueDomain, context, null, false);
+          newInfos.add(newInfo);
+          return newInfo;
+        });
+        typeInfoMap[keyString]!.addInput(value);
+      });
+    } else {
+      _allKeysAreStrings = false;
+      typeInfoMap.clear();
+    }
+    keyType.addInput(other.keyType);
+    valueType.addInput(other.valueType);
+
+    return newInfos;
+  }
+
+  markAsInferred() {
+    keyType.inferred = valueType.inferred = true;
+    typeInfoMap.values.forEach((v) => v.inferred = true);
+  }
+
+  @override
+  addInput(TypeInformation other) {
+    throw "not supported";
+  }
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitMapTypeInformation(this);
+  }
+
+  AbstractValue toTypeMask(InferrerEngine inferrer) {
+    AbstractValueDomain abstractValueDomain = inferrer.abstractValueDomain;
+    if (inDictionaryMode) {
+      Map<String, AbstractValue> mappings = Map<String, AbstractValue>();
+      for (var key in typeInfoMap.keys) {
+        mappings[key] = typeInfoMap[key]!.type;
+      }
+      return inferrer.abstractValueDomain.createDictionaryValue(
+          abstractValueDomain.getGeneralization(originalType),
+          abstractValueDomain.getAllocationNode(originalType),
+          abstractValueDomain.getAllocationElement(originalType),
+          keyType.type,
+          valueType.type,
+          mappings);
+    } else {
+      return inferrer.abstractValueDomain.createMapValue(
+          abstractValueDomain.getGeneralization(originalType),
+          abstractValueDomain.getAllocationNode(originalType),
+          abstractValueDomain.getAllocationElement(originalType),
+          keyType.type,
+          valueType.type);
+    }
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    AbstractValueDomain abstractValueDomain = inferrer.abstractValueDomain;
+    if (abstractValueDomain.isDictionary(type) != inDictionaryMode) {
+      return toTypeMask(inferrer);
+    } else if (abstractValueDomain.isDictionary(type)) {
+      assert(inDictionaryMode);
+      for (String key in typeInfoMap.keys) {
+        final value = typeInfoMap[key]!;
+        if (!abstractValueDomain.containsDictionaryKey(type, key) &&
+            abstractValueDomain.containsAll(value.type).isDefinitelyFalse &&
+            abstractValueDomain.isNull(value.type).isDefinitelyFalse) {
+          return toTypeMask(inferrer);
+        }
+        if (abstractValueDomain.getDictionaryValueForKey(type, key) !=
+            typeInfoMap[key]!.type) {
+          return toTypeMask(inferrer);
+        }
+      }
+    } else if (abstractValueDomain.isMap(type)) {
+      if (abstractValueDomain.getMapKeyType(type) != keyType.type ||
+          abstractValueDomain.getMapValueType(type) != valueType.type) {
+        return toTypeMask(inferrer);
+      }
+    } else {
+      return toTypeMask(inferrer);
+    }
+
+    return type;
+  }
+
+  @override
+  AbstractValue safeType(InferrerEngine inferrer) => originalType;
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    return keyType.isStable &&
+        valueType.isStable &&
+        super.hasStableType(inferrer);
+  }
+
+  @override
+  void cleanup() {
+    super.cleanup();
+    keyType.cleanup();
+    valueType.cleanup();
+    for (TypeInformation info in typeInfoMap.values) {
+      info.cleanup();
+    }
+    _flowsInto = null;
+  }
+
+  @override
+  String toString() {
+    return 'Map $type (K:$keyType, V:$valueType) contents $typeInfoMap';
+  }
+}
+
+/// A [KeyInMapTypeInformation] holds the common type
+/// for the keys in a [MapTypeInformation]
+class KeyInMapTypeInformation extends InferredTypeInformation {
+  KeyInMapTypeInformation(
+      super.abstractValueDomain, super.context, TypeInformation super.keyType);
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitKeyInMapTypeInformation(this);
+  }
+
+  @override
+  String toString() => 'Key in Map $type';
+}
+
+/// A [ValueInMapTypeInformation] holds the common type
+/// for the values in a [MapTypeInformation]
+class ValueInMapTypeInformation extends InferredTypeInformation {
+  // [nonNull] is set to true if this value is known to be part of the map.
+  // Note that only values assigned to a specific key value in dictionary
+  // mode can ever be marked as [nonNull].
+  final bool nonNull;
+
+  ValueInMapTypeInformation(
+      super.abstractValueDomain, super.context, super.valueType,
+      [this.nonNull = false]);
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitValueInMapTypeInformation(this);
+  }
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    return nonNull
+        ? super.computeType(inferrer)
+        : inferrer.abstractValueDomain.includeNull(super.computeType(inferrer));
+  }
+
+  @override
+  String toString() => 'Value in Map $type';
+}
+
+/// A [PhiElementTypeInformation] is an union of
+/// [ElementTypeInformation], that is local to a method.
+class PhiElementTypeInformation extends TypeInformation {
+  final ir.Node? branchNode;
+  final Local? variable;
+  final bool isTry;
+
+  PhiElementTypeInformation(AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation? context, this.branchNode, this.variable,
+      {required this.isTry})
+      : super(abstractValueDomain.emptyType, context);
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) {
+    return inferrer.types.computeTypeMask(inputs);
+  }
+
+  @override
+  String toString() => 'Phi($hashCode) $variable $type';
+
+  @override
+  void _toStructuredText(
+      StringBuffer sb, String indent, Set<TypeInformation> seen) {
+    if (seen.add(this)) {
+      sb.write('${toString()} [');
+      for (TypeInformation assignment in inputs) {
+        sb.write('\n$indent  ');
+        assignment._toStructuredText(sb, '$indent  ', seen);
+      }
+      sb.write(' ]');
+    } else {
+      sb.write('${toString()} [ ... ]');
+    }
+  }
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitPhiElementTypeInformation(this);
+  }
+}
+
+class ClosureTypeInformation extends TypeInformation
+    with ApplyableTypeInformation {
+  final FunctionEntity _element;
+
+  ClosureTypeInformation(AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation? context, this._element)
+      : super(abstractValueDomain.emptyType, context);
+
+  FunctionEntity get closure => _element;
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) => safeType(inferrer);
+
+  @override
+  AbstractValue safeType(InferrerEngine inferrer) {
+    return inferrer.types.functionType.type;
+  }
+
+  String get debugName => '$closure';
+
+  @override
+  String toString() => 'Closure $_element';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitClosureTypeInformation(this);
+  }
+
+  @override
+  bool hasStableType(InferrerEngine inferrer) {
+    return false;
+  }
+
+  String getInferredSignature(TypeSystem types) {
+    return types.getInferredSignatureOfMethod(_element);
+  }
+}
+
+/// Mixin for [TypeInformation] nodes that can bail out during tracing.
+abstract class TracedTypeInformation implements TypeInformation {
+  /// Set to false once analysis has succeeded.
+  bool bailedOut = true;
+
+  /// Set to true once analysis is completed.
+  bool analyzed = false;
+
+  Set<TypeInformation>? _flowsInto;
+
+  /// The set of [TypeInformation] nodes where values from the traced node could
+  /// flow in.
+  Set<TypeInformation> get flowsInto {
+    return _flowsInto ?? const {};
+  }
+
+  /// Adds [nodes] to the sets of values this [TracedTypeInformation] flows
+  /// into.
+  void addFlowsIntoTargets(Iterable<TypeInformation> nodes) {
+    if (_flowsInto == null) {
+      _flowsInto = nodes.toSet();
+    } else {
+      _flowsInto!.addAll(nodes);
+    }
+  }
+}
+
+class AwaitTypeInformation extends TypeInformation {
+  final ir.Node _node;
+
+  AwaitTypeInformation(AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation context, this._node)
+      : super(abstractValueDomain.emptyType, context);
+
+  // TODO(22894): Compute a better type here.
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) => safeType(inferrer);
+
+  String get debugName => '$_node';
+
+  @override
+  String toString() => 'Await';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitAwaitTypeInformation(this);
+  }
+}
+
+class YieldTypeInformation extends TypeInformation {
+  final ir.Node _node;
+
+  YieldTypeInformation(AbstractValueDomain abstractValueDomain,
+      MemberTypeInformation context, this._node)
+      : super(abstractValueDomain.emptyType, context);
+
+  @override
+  AbstractValue computeType(InferrerEngine inferrer) => safeType(inferrer);
+
+  String get debugName => '$_node';
+
+  @override
+  String toString() => 'Yield';
+
+  @override
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitYieldTypeInformation(this);
+  }
+}
+
+abstract class TypeInformationVisitor<T> {
+  T visitNarrowTypeInformation(NarrowTypeInformation info);
+  T visitPhiElementTypeInformation(PhiElementTypeInformation info);
+  T visitElementInContainerTypeInformation(
+      ElementInContainerTypeInformation info);
+  T visitElementInSetTypeInformation(ElementInSetTypeInformation info);
+  T visitKeyInMapTypeInformation(KeyInMapTypeInformation info);
+  T visitValueInMapTypeInformation(ValueInMapTypeInformation info);
+  T visitListTypeInformation(ListTypeInformation info);
+  T visitSetTypeInformation(SetTypeInformation info);
+  T visitMapTypeInformation(MapTypeInformation info);
+  T visitConcreteTypeInformation(ConcreteTypeInformation info);
+  T visitStringLiteralTypeInformation(StringLiteralTypeInformation info);
+  T visitBoolLiteralTypeInformation(BoolLiteralTypeInformation info);
+  T visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info);
+  T visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info);
+  T visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info);
+  T visitMemberTypeInformation(MemberTypeInformation info);
+  T visitParameterTypeInformation(ParameterTypeInformation info);
+  T visitClosureTypeInformation(ClosureTypeInformation info);
+  T visitAwaitTypeInformation(AwaitTypeInformation info);
+  T visitYieldTypeInformation(YieldTypeInformation info);
+}
+
+AbstractValue _narrowType(
+    JClosedWorld closedWorld, AbstractValue type, DartType annotation,
+    {bool isNullable = true}) {
+  AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
+
+  AbstractValue _intersectionWith(AbstractValue otherType) {
+    if (isNullable) {
+      otherType = abstractValueDomain.includeNull(otherType);
+    }
+    assert((type as dynamic) != null); // TODO(48820): Remove when sound.
+    AbstractValue newType = abstractValueDomain.intersection(type, otherType);
+    return abstractValueDomain.isLateSentinel(type).isPotentiallyTrue
+        ? abstractValueDomain.includeLateSentinel(newType)
+        : newType;
+  }
+
+  // TODO(joshualitt): FutureOrType, TypeVariableType, and FunctionTypeVariable
+  // can be narrowed.
+  // TODO(fishythefish): Use nullability.
+  annotation = annotation.withoutNullability;
+  if (closedWorld.dartTypes.isTopType(annotation) ||
+      annotation is FutureOrType ||
+      annotation is TypeVariableType ||
+      annotation is FunctionTypeVariable) {
+    return type;
+  } else if (annotation is NeverType) {
+    return _intersectionWith(abstractValueDomain.emptyType);
+  } else if (annotation is InterfaceType) {
+    return _intersectionWith(
+        abstractValueDomain.createNonNullSubtype(annotation.element));
+  } else if (annotation is FunctionType) {
+    return _intersectionWith(abstractValueDomain.functionType);
+  } else {
+    throw 'Unexpected annotation type $annotation';
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/type_system.dart b/pkg/compiler/lib/src/inferrer_experimental/type_system.dart
new file mode 100644
index 0000000..ea81a79
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/type_system.dart
@@ -0,0 +1,640 @@
+// Copyright (c) 2017, 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' as ir;
+import '../common.dart';
+import '../constants/values.dart' show BoolConstantValue;
+import '../elements/entities.dart';
+import '../elements/types.dart';
+import '../world_interfaces.dart';
+import '../inferrer/abstract_value_domain.dart';
+import 'type_graph_nodes.dart';
+
+/// Strategy for creating type information from members and parameters and type
+/// information for nodes.
+abstract class TypeSystemStrategy {
+  /// Creates [MemberTypeInformation] for [member].
+  MemberTypeInformation createMemberTypeInformation(
+      AbstractValueDomain abstractValueDomain, MemberEntity member);
+
+  /// Creates [ParameterTypeInformation] for [parameter].
+  ParameterTypeInformation createParameterTypeInformation(
+      AbstractValueDomain abstractValueDomain,
+      Local parameter,
+      TypeSystem types);
+
+  /// Calls [f] for each parameter in [function].
+  void forEachParameter(FunctionEntity function, void f(Local parameter));
+
+  /// Returns whether [node] is valid as a general phi node.
+  bool checkPhiNode(ir.Node? node);
+
+  /// Returns whether [node] is valid as a loop phi node.
+  bool checkLoopPhiNode(ir.Node node);
+
+  /// Returns whether [node] is valid as a list allocation node.
+  bool checkListNode(ir.Node node);
+
+  /// Returns whether [node] is valid as a set allocation node.
+  bool checkSetNode(ir.Node node);
+
+  /// Returns whether [node] is valid as a map allocation node.
+  bool checkMapNode(ir.Node node);
+
+  /// Returns whether [cls] is valid as a type mask base class.
+  bool checkClassEntity(ClassEntity cls);
+}
+
+/// The class [SimpleInferrerVisitor] will use when working on types.
+class TypeSystem {
+  final JClosedWorld _closedWorld;
+  final TypeSystemStrategy strategy;
+
+  /// [parameterTypeInformations] and [memberTypeInformations] ordered by
+  /// creation time. This is used as the inference enqueueing order.
+  final List<TypeInformation> _orderedTypeInformations = <TypeInformation>[];
+
+  /// [ParameterTypeInformation]s for parameters.
+  final Map<Local, ParameterTypeInformation> parameterTypeInformations =
+      Map<Local, ParameterTypeInformation>();
+
+  /// [MemberTypeInformation]s for members.
+  final Map<MemberEntity, MemberTypeInformation> memberTypeInformations =
+      Map<MemberEntity, MemberTypeInformation>();
+
+  /// [ListTypeInformation] for allocated lists.
+  final Map<ir.TreeNode, ListTypeInformation> allocatedLists =
+      Map<ir.TreeNode, ListTypeInformation>();
+
+  /// [SetTypeInformation] for allocated Sets.
+  final Map<ir.TreeNode, SetTypeInformation> allocatedSets =
+      Map<ir.TreeNode, SetTypeInformation>();
+
+  /// [MapTypeInformation] for allocated Maps.
+  final Map<ir.TreeNode, TypeInformation> allocatedMaps =
+      Map<ir.TreeNode, TypeInformation>();
+
+  /// Closures found during the analysis.
+  final Set<TypeInformation> allocatedClosures = Set<TypeInformation>();
+
+  /// Cache of [ConcreteTypeInformation].
+  final Map<AbstractValue, ConcreteTypeInformation> concreteTypes = {};
+
+  /// Cache of some primitive constant types.
+  final Map<Object, TypeInformation> primitiveConstantTypes = {};
+
+  /// List of [TypeInformation]s for calls inside method bodies.
+  final List<CallSiteTypeInformation> allocatedCalls =
+      <CallSiteTypeInformation>[];
+
+  /// List of [TypeInformation]s allocated inside method bodies (narrowing,
+  /// phis, and containers).
+  final List<TypeInformation> allocatedTypes = <TypeInformation>[];
+
+  /// [parameterTypeInformations] and [memberTypeInformations] ordered by
+  /// creation time. This is used as the inference enqueueing order.
+  Iterable<TypeInformation> get orderedTypeInformations =>
+      _orderedTypeInformations;
+
+  Iterable<TypeInformation> get allTypes => [
+        parameterTypeInformations.values,
+        memberTypeInformations.values,
+        allocatedLists.values,
+        allocatedSets.values,
+        allocatedMaps.values,
+        allocatedClosures,
+        concreteTypes.values,
+        primitiveConstantTypes.values,
+        allocatedCalls,
+        allocatedTypes,
+      ].expand((x) => x);
+
+  TypeSystem(this._closedWorld, this.strategy);
+
+  AbstractValueDomain get _abstractValueDomain =>
+      _closedWorld.abstractValueDomain;
+
+  /// Used to group [TypeInformation] nodes by the element that triggered their
+  /// creation.
+  MemberTypeInformation? _currentMember = null;
+  MemberTypeInformation? get currentMember => _currentMember;
+
+  void withMember(MemberEntity element, void action()) {
+    assert(_currentMember == null,
+        failedAt(element, "Already constructing graph for $_currentMember."));
+    _currentMember = getInferredTypeOfMember(element);
+    action();
+    _currentMember = null;
+  }
+
+  late final TypeInformation nullType =
+      getConcreteTypeFor(_abstractValueDomain.nullType);
+
+  late final TypeInformation intType =
+      getConcreteTypeFor(_abstractValueDomain.intType);
+
+  late final TypeInformation uint32Type =
+      getConcreteTypeFor(_abstractValueDomain.uint32Type);
+
+  late final TypeInformation uint31Type =
+      getConcreteTypeFor(_abstractValueDomain.uint31Type);
+
+  late final TypeInformation positiveIntType =
+      getConcreteTypeFor(_abstractValueDomain.positiveIntType);
+
+  late final TypeInformation numType =
+      getConcreteTypeFor(_abstractValueDomain.numType);
+
+  late final TypeInformation boolType =
+      getConcreteTypeFor(_abstractValueDomain.boolType);
+
+  late final TypeInformation functionType =
+      getConcreteTypeFor(_abstractValueDomain.functionType);
+
+  late final TypeInformation listType =
+      getConcreteTypeFor(_abstractValueDomain.listType);
+
+  late final TypeInformation constListType =
+      getConcreteTypeFor(_abstractValueDomain.constListType);
+
+  late final TypeInformation fixedListType =
+      getConcreteTypeFor(_abstractValueDomain.fixedListType);
+
+  late final TypeInformation growableListType =
+      getConcreteTypeFor(_abstractValueDomain.growableListType);
+
+  late final TypeInformation mutableArrayType =
+      getConcreteTypeFor(_abstractValueDomain.mutableArrayType);
+
+  late final TypeInformation setType =
+      getConcreteTypeFor(_abstractValueDomain.setType);
+
+  late final TypeInformation constSetType =
+      getConcreteTypeFor(_abstractValueDomain.constSetType);
+
+  late final TypeInformation mapType =
+      getConcreteTypeFor(_abstractValueDomain.mapType);
+
+  late final TypeInformation constMapType =
+      getConcreteTypeFor(_abstractValueDomain.constMapType);
+
+  late final TypeInformation stringType =
+      getConcreteTypeFor(_abstractValueDomain.stringType);
+
+  late final TypeInformation typeType =
+      getConcreteTypeFor(_abstractValueDomain.typeType);
+
+  late final TypeInformation dynamicType =
+      getConcreteTypeFor(_abstractValueDomain.dynamicType);
+
+  // Subtype of Future returned by async methods.
+  late final TypeInformation asyncFutureType =
+      getConcreteTypeFor(_abstractValueDomain.asyncFutureType);
+
+  late final TypeInformation syncStarIterableType =
+      getConcreteTypeFor(_abstractValueDomain.syncStarIterableType);
+
+  late final TypeInformation asyncStarStreamType =
+      getConcreteTypeFor(_abstractValueDomain.asyncStarStreamType);
+
+  late final TypeInformation lateSentinelType =
+      getConcreteTypeFor(_abstractValueDomain.lateSentinelType);
+
+  late final TypeInformation nonNullEmptyType =
+      getConcreteTypeFor(_abstractValueDomain.emptyType);
+
+  TypeInformation stringLiteralType(String value) {
+    return StringLiteralTypeInformation(
+        _abstractValueDomain, value, _abstractValueDomain.stringType);
+  }
+
+  TypeInformation boolLiteralType(bool value) {
+    return primitiveConstantTypes[value] ??= _boolLiteralType(value);
+  }
+
+  TypeInformation _boolLiteralType(bool value) {
+    AbstractValue abstractValue = _abstractValueDomain
+        .computeAbstractValueForConstant(BoolConstantValue(value));
+    return BoolLiteralTypeInformation(
+        _abstractValueDomain, value, abstractValue);
+  }
+
+  bool isLiteralTrue(TypeInformation info) {
+    return info is BoolLiteralTypeInformation && info.value == true;
+  }
+
+  bool isLiteralFalse(TypeInformation info) {
+    return info is BoolLiteralTypeInformation && info.value == false;
+  }
+
+  /// Returns the least upper bound between [firstType] and
+  /// [secondType].
+  TypeInformation computeLUB(
+      TypeInformation? firstType, TypeInformation secondType) {
+    if (firstType == null) return secondType;
+    if (firstType == secondType) return firstType;
+    if (firstType == nonNullEmptyType) return secondType;
+    if (secondType == nonNullEmptyType) return firstType;
+    if (firstType == dynamicType || secondType == dynamicType) {
+      return dynamicType;
+    }
+    return getConcreteTypeFor(
+        _abstractValueDomain.union(firstType.type, secondType.type));
+  }
+
+  /// Returns `true` if `selector` should be updated to reflect the new
+  /// `receiverType`.
+  bool selectorNeedsUpdate(TypeInformation info, AbstractValue mask) {
+    return info.type != mask;
+  }
+
+  bool _isNonNullNarrow(TypeInformation type) =>
+      type is NarrowTypeInformation &&
+      _abstractValueDomain.isNull(type.typeAnnotation).isDefinitelyFalse;
+
+  /// Returns the intersection between [type] and [annotation].
+  ///
+  /// [isCast] indicates whether narrowing comes from a cast or parameter check
+  /// rather than an 'is' test. (In legacy semantics these differ on whether
+  /// `null` is accepted).
+  ///
+  /// If [excludeNull] is true, the intersection excludes `null` even if the
+  /// Dart type implies `null`.
+  ///
+  /// [narrowType] will not exclude the late sentinel value by default, only if
+  /// [excludeLateSentinel] is `true`.
+  TypeInformation narrowType(TypeInformation type, DartType annotation,
+      {bool isCast = true,
+      bool excludeNull = false,
+      bool excludeLateSentinel = false}) {
+    AbstractValue inferredType = type.type;
+
+    TypeInformation _excludeLateSentinel() {
+      if (!excludeLateSentinel) return type;
+      final newType = NarrowTypeInformation(
+          _abstractValueDomain, type, _abstractValueDomain.dynamicType);
+      allocatedTypes.add(newType);
+      return newType;
+    }
+
+    // Avoid refining an input with an exact type, since we are almost always
+    // adding a narrowing to a subtype of the same class or a superclass.
+    if (_abstractValueDomain.isExact(inferredType).isDefinitelyTrue) {
+      return _excludeLateSentinel();
+    }
+
+    AbstractValue narrowing = _abstractValueDomain
+        .createFromStaticType(annotation, nullable: isCast)
+        .abstractValue;
+
+    if (excludeNull) {
+      narrowing = _abstractValueDomain.excludeNull(narrowing);
+    }
+
+    if (!excludeLateSentinel) {
+      // Narrowing is an intersection of [AbstractValue]s. Unless
+      // [excludeLateSentinel] is `true`, we include the late sentinel here so
+      // that it is preserved by the intersection.
+      narrowing = _abstractValueDomain.includeLateSentinel(narrowing);
+    }
+
+    if (_abstractValueDomain.containsAll(narrowing).isPotentiallyTrue) {
+      // Top, or non-nullable Top.
+      if (_abstractValueDomain.isNull(narrowing).isPotentiallyTrue) {
+        return _excludeLateSentinel();
+      }
+      // If the input is already narrowed to be non-null, there is no value in
+      // adding another non-null narrowing node.
+      if (_isNonNullNarrow(type)) return _excludeLateSentinel();
+    }
+
+    TypeInformation newType =
+        NarrowTypeInformation(_abstractValueDomain, type, narrowing);
+    allocatedTypes.add(newType);
+    return newType;
+  }
+
+  ParameterTypeInformation getInferredTypeOfParameter(Local parameter) {
+    return parameterTypeInformations.putIfAbsent(parameter, () {
+      ParameterTypeInformation typeInformation =
+          strategy.createParameterTypeInformation(
+              _abstractValueDomain, parameter, this);
+      _orderedTypeInformations.add(typeInformation);
+      return typeInformation;
+    });
+  }
+
+  void forEachParameterType(
+      void f(Local parameter, ParameterTypeInformation typeInformation)) {
+    parameterTypeInformations.forEach(f);
+  }
+
+  MemberTypeInformation getInferredTypeOfMember(MemberEntity member) {
+    assert(!member.isAbstract,
+        failedAt(member, "Unexpected abstract member $member."));
+    return memberTypeInformations[member] ??= _getInferredTypeOfMember(member);
+  }
+
+  void forEachMemberType(
+      void f(MemberEntity member, MemberTypeInformation typeInformation)) {
+    memberTypeInformations.forEach(f);
+  }
+
+  MemberTypeInformation _getInferredTypeOfMember(MemberEntity member) {
+    MemberTypeInformation typeInformation =
+        strategy.createMemberTypeInformation(_abstractValueDomain, member);
+    _orderedTypeInformations.add(typeInformation);
+    return typeInformation;
+  }
+
+  /// Returns the internal inferrer representation for [mask].
+  ConcreteTypeInformation getConcreteTypeFor(AbstractValue mask) {
+    assert((mask as dynamic) != null); // TODO(48820): Remove when sound.
+    return concreteTypes.putIfAbsent(mask, () {
+      return ConcreteTypeInformation(mask);
+    });
+  }
+
+  String getInferredSignatureOfMethod(FunctionEntity function) {
+    ElementTypeInformation info = getInferredTypeOfMember(function);
+    var res = "";
+    strategy.forEachParameter(function, (Local parameter) {
+      TypeInformation type = getInferredTypeOfParameter(parameter);
+      res += "${res.isEmpty ? '(' : ', '}${type.type} ${parameter.name}";
+    });
+    res += ") -> ${info.type}";
+    return res;
+  }
+
+  TypeInformation nonNullSubtype(ClassEntity cls) {
+    assert(strategy.checkClassEntity(cls));
+    return getConcreteTypeFor(_abstractValueDomain.createNonNullSubtype(cls));
+  }
+
+  TypeInformation nonNullSubclass(ClassEntity cls) {
+    assert(strategy.checkClassEntity(cls));
+    return getConcreteTypeFor(_abstractValueDomain.createNonNullSubclass(cls));
+  }
+
+  TypeInformation nonNullExact(ClassEntity cls) {
+    assert(strategy.checkClassEntity(cls));
+    return getConcreteTypeFor(_abstractValueDomain.createNonNullExact(cls));
+  }
+
+  TypeInformation nonNullEmpty() {
+    return nonNullEmptyType;
+  }
+
+  bool isNull(TypeInformation type) {
+    return type == nullType;
+  }
+
+  TypeInformation allocateList(TypeInformation type, ir.TreeNode node,
+      MemberEntity enclosing, TypeInformation elementType,
+      [int? length]) {
+    assert(strategy.checkListNode(node));
+    final typedDataClass = _closedWorld.commonElements.typedDataClass;
+    bool isTypedArray =
+        _closedWorld.classHierarchy.isInstantiated(typedDataClass) &&
+            _abstractValueDomain
+                .isInstanceOfOrNull(type.type, typedDataClass)
+                .isDefinitelyTrue;
+    bool isConst = (type.type == _abstractValueDomain.constListType);
+    bool isFixed = (type.type == _abstractValueDomain.fixedListType) ||
+        isConst ||
+        isTypedArray;
+    bool isElementInferred = isConst || isTypedArray;
+
+    final inferredLength = isFixed ? length : null;
+    final elementTypeMask =
+        isElementInferred ? elementType.type : dynamicType.type;
+    AbstractValue mask = _abstractValueDomain.createContainerValue(
+        type.type, node, enclosing, elementTypeMask, inferredLength);
+    ElementInContainerTypeInformation element =
+        ElementInContainerTypeInformation(
+            _abstractValueDomain, currentMember, elementType);
+    element.inferred = isElementInferred;
+
+    allocatedTypes.add(element);
+    return allocatedLists[node] = ListTypeInformation(
+        _abstractValueDomain, currentMember, mask, element, length);
+  }
+
+  /// Creates a [TypeInformation] object either for the closurization of a
+  /// static or top-level method [element] used as a function constant or for
+  /// the synthesized 'call' method [element] created for a local function.
+  TypeInformation allocateClosure(FunctionEntity element) {
+    TypeInformation result =
+        ClosureTypeInformation(_abstractValueDomain, currentMember, element);
+    allocatedClosures.add(result);
+    return result;
+  }
+
+  TypeInformation allocateSet(TypeInformation type, ir.TreeNode node,
+      MemberEntity enclosing, TypeInformation elementType) {
+    assert(strategy.checkSetNode(node));
+    bool isConst = type.type == _abstractValueDomain.constSetType;
+
+    AbstractValue elementTypeMask =
+        isConst ? elementType.type : dynamicType.type;
+    AbstractValue mask = _abstractValueDomain.createSetValue(
+        type.type, node, enclosing, elementTypeMask);
+    ElementInSetTypeInformation element = ElementInSetTypeInformation(
+        _abstractValueDomain, currentMember, elementType);
+    element.inferred = isConst;
+
+    allocatedTypes.add(element);
+    return allocatedSets[node] =
+        SetTypeInformation(currentMember, mask, element);
+  }
+
+  TypeInformation allocateMap(
+      ConcreteTypeInformation type,
+      ir.TreeNode node,
+      MemberEntity element,
+      List<TypeInformation> keyTypes,
+      List<TypeInformation> valueTypes) {
+    assert(strategy.checkMapNode(node));
+    assert(keyTypes.length == valueTypes.length);
+    bool isFixed = (type.type == _abstractValueDomain.constMapType);
+
+    PhiElementTypeInformation? keyType, valueType;
+    for (int i = 0; i < keyTypes.length; ++i) {
+      final typeForKey = keyTypes[i];
+      keyType = keyType == null
+          ? allocatePhi(null, null, typeForKey, isTry: false)
+          : addPhiInput(null, keyType, typeForKey);
+
+      final typeForValue = valueTypes[i];
+      valueType = valueType == null
+          ? allocatePhi(null, null, typeForValue, isTry: false)
+          : addPhiInput(null, valueType, typeForValue);
+    }
+
+    final simplifiedKeyType =
+        keyType == null ? nonNullEmpty() : simplifyPhi(null, null, keyType);
+    final simplifiedValueType =
+        valueType == null ? nonNullEmpty() : simplifyPhi(null, null, valueType);
+
+    AbstractValue keyTypeMask, valueTypeMask;
+    if (isFixed) {
+      keyTypeMask = simplifiedKeyType.type;
+      valueTypeMask = simplifiedValueType.type;
+    } else {
+      keyTypeMask = valueTypeMask = dynamicType.type;
+    }
+    AbstractValue mask = _abstractValueDomain.createMapValue(
+        type.type, node, element, keyTypeMask, valueTypeMask);
+
+    final keyTypeInfo = KeyInMapTypeInformation(
+        _abstractValueDomain, currentMember, simplifiedKeyType);
+    final valueTypeInfo = ValueInMapTypeInformation(
+        _abstractValueDomain, currentMember, simplifiedValueType);
+    allocatedTypes.add(keyTypeInfo);
+    allocatedTypes.add(valueTypeInfo);
+
+    MapTypeInformation map =
+        MapTypeInformation(currentMember, mask, keyTypeInfo, valueTypeInfo);
+
+    for (int i = 0; i < keyTypes.length; ++i) {
+      final newType = map.addEntryInput(
+          _abstractValueDomain, keyTypes[i], valueTypes[i], true);
+      if (newType != null) allocatedTypes.add(newType);
+    }
+
+    // Shortcut: If we already have a first approximation of the key/value type,
+    // start propagating it early.
+    if (isFixed) map.markAsInferred();
+
+    allocatedMaps[node] = map;
+    return map;
+  }
+
+  AbstractValue newTypedSelector(TypeInformation info, AbstractValue mask) {
+    // Only type the selector if [info] is concrete, because the other
+    // kinds of [TypeInformation] have the empty type at this point of
+    // analysis.
+    return info.isConcrete ? info.type : mask;
+  }
+
+  /// Returns a new type that unions [firstInput] and [secondInput].
+  TypeInformation allocateDiamondPhi(
+      TypeInformation firstInput, TypeInformation secondInput) {
+    PhiElementTypeInformation result = PhiElementTypeInformation(
+        _abstractValueDomain, currentMember, null, null,
+        isTry: false);
+    result.addInput(firstInput);
+    result.addInput(secondInput);
+    allocatedTypes.add(result);
+    return result;
+  }
+
+  PhiElementTypeInformation _addPhi(
+      ir.Node? node, Local? variable, TypeInformation inputType, bool isTry) {
+    PhiElementTypeInformation result = PhiElementTypeInformation(
+        _abstractValueDomain, currentMember, node, variable,
+        isTry: isTry);
+    allocatedTypes.add(result);
+    result.addInput(inputType);
+    return result;
+  }
+
+  /// Returns a new type for holding the potential types of [element].
+  /// [inputType] is the first incoming type of the phi.
+  PhiElementTypeInformation allocatePhi(
+      ir.Node? node, Local? variable, TypeInformation inputType,
+      {required bool isTry}) {
+    assert(strategy.checkPhiNode(node));
+    // Check if [inputType] is a phi for a local updated in
+    // the try/catch block [node]. If it is, no need to allocate a new
+    // phi.
+    if (inputType is PhiElementTypeInformation &&
+        inputType.branchNode == node &&
+        inputType.isTry) {
+      return inputType;
+    }
+    return _addPhi(node, variable, inputType, isTry);
+  }
+
+  /// Returns a new type for holding the potential types of [element].
+  /// [inputType] is the first incoming type of the phi. [allocateLoopPhi]
+  /// only differs from [allocatePhi] in that it allows the underlying
+  /// implementation of [TypeSystem] to differentiate Phi nodes due to loops
+  /// from other merging uses.
+  PhiElementTypeInformation allocateLoopPhi(
+      ir.Node node, Local variable, TypeInformation inputType,
+      {required bool isTry}) {
+    assert(strategy.checkLoopPhiNode(node));
+    return _addPhi(node, variable, inputType, isTry);
+  }
+
+  /// Simplifies the phi representing [element] and of the type
+  /// [phiType]. For example, if this phi has one incoming input, an
+  /// implementation of this method could just return that incoming
+  /// input type.
+  TypeInformation simplifyPhi(
+      ir.Node? node, Local? variable, PhiElementTypeInformation phiType) {
+    assert(phiType.branchNode == node);
+    if (phiType.inputs.length == 1) return phiType.inputs.first;
+    return phiType;
+  }
+
+  /// Adds [newType] as an input of [phiType].
+  PhiElementTypeInformation addPhiInput(Local? variable,
+      PhiElementTypeInformation phiType, TypeInformation newType) {
+    phiType.addInput(newType);
+    return phiType;
+  }
+
+  AbstractValue computeTypeMask(Iterable<TypeInformation> assignments) {
+    return joinTypeMasks(assignments.map((e) => e.type));
+  }
+
+  AbstractValue joinTypeMasks(Iterable<AbstractValue> masks) {
+    var topType = _abstractValueDomain.internalTopType;
+    // Optimization: we are iterating over masks twice, but because `masks` is a
+    // mapped iterable, we save the intermediate results to avoid computing them
+    // again.
+    var list = [];
+    bool isTopIgnoringFlags = false;
+    bool mayBeNull = false;
+    bool mayBeLateSentinel = false;
+    for (AbstractValue mask in masks) {
+      // Don't do any work on computing unions if we know that after all that
+      // work the result will be `dynamic`.
+      // TODO(sigmund): change to `mask == internalTopType` so we can continue
+      // to track the non-nullable and late sentinel bits.
+      if (_abstractValueDomain.containsAll(mask).isPotentiallyTrue) {
+        isTopIgnoringFlags = true;
+      }
+      if (_abstractValueDomain.isNull(mask).isPotentiallyTrue) {
+        mayBeNull = true;
+      }
+      if (_abstractValueDomain.isLateSentinel(mask).isPotentiallyTrue) {
+        mayBeLateSentinel = true;
+      }
+      if (isTopIgnoringFlags && mayBeNull && mayBeLateSentinel) return topType;
+      list.add(mask);
+    }
+
+    AbstractValue? newType;
+    for (AbstractValue mask in list) {
+      newType =
+          newType == null ? mask : _abstractValueDomain.union(newType, mask);
+      // Likewise - stop early if we already reach dynamic.
+      if (_abstractValueDomain.containsAll(newType).isPotentiallyTrue) {
+        isTopIgnoringFlags = true;
+      }
+      if (_abstractValueDomain.isNull(newType).isPotentiallyTrue) {
+        mayBeNull = true;
+      }
+      if (_abstractValueDomain.isLateSentinel(newType).isPotentiallyTrue) {
+        mayBeLateSentinel = true;
+      }
+      if (isTopIgnoringFlags && mayBeNull && mayBeLateSentinel) return topType;
+    }
+
+    return newType ?? _abstractValueDomain.emptyType;
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/constants.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/constants.dart
new file mode 100644
index 0000000..7dea399
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/constants.dart
@@ -0,0 +1,139 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library types.constants;
+
+import '../../constants/constant_system.dart' as constant_system;
+import '../../constants/values.dart';
+import '../../world_interfaces.dart' show JClosedWorld;
+import 'masks.dart';
+
+/// Computes the [TypeMask] for the constant [value].
+TypeMask computeTypeMask(CommonMasks abstractValueDomain,
+    JClosedWorld closedWorld, ConstantValue value) {
+  return value.accept(ConstantValueTypeMasks(abstractValueDomain), closedWorld);
+}
+
+class ConstantValueTypeMasks
+    extends ConstantValueVisitor<TypeMask, JClosedWorld> {
+  final CommonMasks _abstractValueDomain;
+  const ConstantValueTypeMasks(this._abstractValueDomain);
+
+  @override
+  TypeMask visitConstructed(
+      ConstructedConstantValue constant, JClosedWorld closedWorld) {
+    if (closedWorld.interceptorData.isInterceptedClass(constant.type.element)) {
+      return _abstractValueDomain.nonNullType;
+    }
+    return TypeMask.nonNullExact(constant.type.element, closedWorld);
+  }
+
+  @override
+  TypeMask visitDeferredGlobal(
+      DeferredGlobalConstantValue constant, JClosedWorld closedWorld) {
+    return constant.referenced.accept(this, closedWorld);
+  }
+
+  @override
+  TypeMask visitDouble(DoubleConstantValue constant, JClosedWorld closedWorld) {
+    // We have to recognize double constants that are 'is int'.
+    if (constant_system.isInt(constant)) {
+      if (constant.isMinusZero) {
+        return _abstractValueDomain.uint31Type;
+      }
+      assert(constant.isPositiveInfinity || constant.isNegativeInfinity);
+      return _abstractValueDomain.intType;
+    }
+    return _abstractValueDomain.numNotIntType;
+  }
+
+  @override
+  TypeMask visitDummyInterceptor(
+      DummyInterceptorConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.dynamicType;
+  }
+
+  @override
+  TypeMask visitLateSentinel(
+          LateSentinelConstantValue constant, JClosedWorld closedWorld) =>
+      _abstractValueDomain.lateSentinelType;
+
+  @override
+  TypeMask visitUnreachable(
+      UnreachableConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.emptyType;
+  }
+
+  @override
+  TypeMask visitJsName(JsNameConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.stringType;
+  }
+
+  @override
+  TypeMask visitBool(BoolConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.boolType;
+  }
+
+  @override
+  TypeMask visitFunction(
+      FunctionConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.functionType;
+  }
+
+  @override
+  TypeMask visitInstantiation(
+      InstantiationConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.functionType;
+  }
+
+  @override
+  TypeMask visitInt(IntConstantValue constant, JClosedWorld closedWorld) {
+    if (constant.isUInt31()) return _abstractValueDomain.uint31Type;
+    if (constant.isUInt32()) return _abstractValueDomain.uint32Type;
+    if (constant.isPositive()) return _abstractValueDomain.positiveIntType;
+    return _abstractValueDomain.intType;
+  }
+
+  @override
+  TypeMask visitInterceptor(
+      InterceptorConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.nonNullType;
+  }
+
+  @override
+  TypeMask visitList(ListConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.constListType;
+  }
+
+  @override
+  TypeMask visitSet(SetConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.constSetType;
+  }
+
+  @override
+  TypeMask visitMap(MapConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.constMapType;
+  }
+
+  @override
+  TypeMask visitNull(NullConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.nullType;
+  }
+
+  @override
+  TypeMask visitNonConstant(
+      NonConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.nullType;
+  }
+
+  @override
+  TypeMask visitString(StringConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.stringType;
+  }
+
+  @override
+  TypeMask visitType(TypeConstantValue constant, JClosedWorld closedWorld) {
+    return _abstractValueDomain.typeType;
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/container_type_mask.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/container_type_mask.dart
new file mode 100644
index 0000000..df9ff1b
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/container_type_mask.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2013, 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.
+
+part of masks;
+
+/// A [TypeMask] for a specific allocation site of a container (currently only
+/// List) that will get specialized once the [TypeGraphInferrer] phase finds an
+/// element type for it.
+class ContainerTypeMask extends AllocationTypeMask {
+  /// Tag used for identifying serialized [ContainerTypeMask] objects in a
+  /// debugging data stream.
+  static const String tag = 'container-type-mask';
+
+  @override
+  final TypeMask forwardTo;
+
+  final ir.Node? _allocationNode;
+  @override
+  ir.Node? get allocationNode => _allocationNode;
+
+  @override
+  final MemberEntity? allocationElement;
+
+  // The element type of this container.
+  final TypeMask elementType;
+
+  // The length of the container.
+  final int? length;
+
+  const ContainerTypeMask(this.forwardTo, this._allocationNode,
+      this.allocationElement, this.elementType, this.length);
+
+  /// Deserializes a [ContainerTypeMask] object from [source].
+  factory ContainerTypeMask.readFromDataSource(
+      DataSourceReader source, CommonMasks domain) {
+    source.begin(tag);
+    final forwardTo = TypeMask.readFromDataSource(source, domain);
+    final allocationElement = source.readMemberOrNull();
+    final elementType = TypeMask.readFromDataSource(source, domain);
+    final length = source.readIntOrNull();
+    source.end(tag);
+    return ContainerTypeMask(
+        forwardTo, null, allocationElement, elementType, length);
+  }
+
+  /// Serializes this [ContainerTypeMask] to [sink].
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(TypeMaskKind.container);
+    sink.begin(tag);
+    forwardTo.writeToDataSink(sink);
+    sink.writeMemberOrNull(allocationElement);
+    elementType.writeToDataSink(sink);
+    sink.writeIntOrNull(length);
+    sink.end(tag);
+  }
+
+  @override
+  ContainerTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
+    isNullable ??= this.isNullable;
+    hasLateSentinel ??= this.hasLateSentinel;
+    if (isNullable == this.isNullable &&
+        hasLateSentinel == this.hasLateSentinel) {
+      return this;
+    }
+    return ContainerTypeMask(
+        forwardTo.withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel),
+        allocationNode,
+        allocationElement,
+        elementType,
+        length);
+  }
+
+  @override
+  bool get isExact => true;
+
+  @override
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+      {required bool isNullable, required bool hasLateSentinel}) {
+    if (other is ContainerTypeMask) {
+      final newElementType = elementType.union(other.elementType, domain);
+      final newLength = (length == other.length) ? length : null;
+      final newForwardTo = forwardTo.union(other.forwardTo, domain);
+      return ContainerTypeMask(
+          newForwardTo,
+          allocationNode == other.allocationNode ? allocationNode : null,
+          allocationElement == other.allocationElement
+              ? allocationElement
+              : null,
+          newElementType,
+          newLength);
+    }
+    return null;
+  }
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! ContainerTypeMask) return false;
+    return super == other &&
+        elementType == other.elementType &&
+        length == other.length;
+  }
+
+  @override
+  int get hashCode => Hashing.objectHash(
+      length, Hashing.objectHash(elementType, super.hashCode));
+
+  @override
+  String toString() {
+    return 'Container($forwardTo, element: $elementType, length: $length)';
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/dictionary_type_mask.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/dictionary_type_mask.dart
new file mode 100644
index 0000000..31563bd
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/dictionary_type_mask.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2014, 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.
+
+part of masks;
+
+/// A [DictionaryTypeMask] is a [TypeMask] for a specific allocation
+/// site of a map (currently only internal Map class) that is used as
+/// a dictionary, i.e. a mapping from a set of statically known strings
+/// to values. These typemasks only come into existence after the
+/// [TypeGraphInferrer] has successfully identified such a usage. Otherwise,
+/// the more general [MapTypeMask] is used.
+class DictionaryTypeMask extends MapTypeMask {
+  /// Tag used for identifying serialized [DictionaryTypeMask] objects in a
+  /// debugging data stream.
+  static const String tag = 'dictionary-type-mask';
+
+  // The underlying key/value map of this dictionary.
+  final Map<String, TypeMask> _typeMap;
+
+  const DictionaryTypeMask(super.forwardTo, super._allocationNode,
+      super.allocationElement, super.keyType, super.valueType, this._typeMap);
+
+  /// Deserializes a [DictionaryTypeMask] object from [source].
+  factory DictionaryTypeMask.readFromDataSource(
+      DataSourceReader source, CommonMasks domain) {
+    source.begin(tag);
+    final forwardTo = TypeMask.readFromDataSource(source, domain);
+    final allocationElement = source.readMemberOrNull();
+    final keyType = TypeMask.readFromDataSource(source, domain);
+    final valueType = TypeMask.readFromDataSource(source, domain);
+    final typeMap = source
+        .readStringMap(() => TypeMask.readFromDataSource(source, domain))!;
+    source.end(tag);
+    return DictionaryTypeMask(
+        forwardTo, null, allocationElement, keyType, valueType, typeMap);
+  }
+
+  /// Serializes this [DictionaryTypeMask] to [sink].
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(TypeMaskKind.dictionary);
+    sink.begin(tag);
+    forwardTo.writeToDataSink(sink);
+    sink.writeMemberOrNull(allocationElement);
+    keyType.writeToDataSink(sink);
+    valueType.writeToDataSink(sink);
+    sink.writeStringMap(_typeMap, (TypeMask typeMask) {
+      typeMask.writeToDataSink(sink);
+    });
+    sink.end(tag);
+  }
+
+  @override
+  DictionaryTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
+    isNullable ??= this.isNullable;
+    hasLateSentinel ??= this.hasLateSentinel;
+    if (isNullable == this.isNullable &&
+        hasLateSentinel == this.hasLateSentinel) {
+      return this;
+    }
+    return DictionaryTypeMask(
+        forwardTo.withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel),
+        allocationNode,
+        allocationElement,
+        keyType,
+        valueType,
+        _typeMap);
+  }
+
+  @override
+  bool get isExact => true;
+
+  bool containsKey(String key) => _typeMap.containsKey(key);
+
+  TypeMask? getValueForKey(String key) => _typeMap[key];
+
+  @override
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+      {required bool isNullable, required bool hasLateSentinel}) {
+    if (other is DictionaryTypeMask) {
+      TypeMask newForwardTo = forwardTo.union(other.forwardTo, domain);
+      TypeMask newKeyType = keyType.union(other.keyType, domain);
+      TypeMask newValueType = valueType.union(other.valueType, domain);
+      Map<String, TypeMask> mappings = {};
+      _typeMap.forEach((k, v) {
+        if (!other._typeMap.containsKey(k)) {
+          mappings[k] = v.nullable();
+        }
+      });
+      other._typeMap.forEach((k, v) {
+        if (_typeMap.containsKey(k)) {
+          mappings[k] = v.union(_typeMap[k]!, domain);
+        } else {
+          mappings[k] = v.nullable();
+        }
+      });
+      return DictionaryTypeMask(
+          newForwardTo, null, null, newKeyType, newValueType, mappings);
+    }
+    if (other is MapTypeMask) {
+      TypeMask newForwardTo = forwardTo.union(other.forwardTo, domain);
+      TypeMask newKeyType = keyType.union(other.keyType, domain);
+      TypeMask newValueType = valueType.union(other.valueType, domain);
+      return MapTypeMask(newForwardTo, null, null, newKeyType, newValueType);
+    }
+    return null;
+  }
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! DictionaryTypeMask) return false;
+    return super == other &&
+        _typeMap.keys.every((k) => other._typeMap.containsKey(k)) &&
+        other._typeMap.keys.every(
+            (k) => _typeMap.containsKey(k) && _typeMap[k] == other._typeMap[k]);
+  }
+
+  @override
+  int get hashCode => Hashing.objectHash(_typeMap, super.hashCode);
+
+  @override
+  String toString() {
+    return 'Dictionary($forwardTo, key: $keyType, '
+        'value: $valueType, map: $_typeMap)';
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/flat_type_mask.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/flat_type_mask.dart
new file mode 100644
index 0000000..9e0d7a2
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/flat_type_mask.dart
@@ -0,0 +1,727 @@
+// Copyright (c) 2013, 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.
+
+part of masks;
+
+enum _FlatTypeMaskKind { empty, exact, subclass, subtype }
+
+/// A flat type mask is a type mask that has been flattened to contain a
+/// base type.
+class FlatTypeMask extends TypeMask {
+  /// Tag used for identifying serialized [FlatTypeMask] objects in a
+  /// debugging data stream.
+  static const String tag = 'flat-type-mask';
+
+  static const int _NULL_INDEX = 0;
+  static const int _LATE_SENTINEL_INDEX = 1;
+  static const int _USED_INDICES = 2;
+
+  static const int _NONE_MASK = 0;
+  static const int _NULL_MASK = 1 << _NULL_INDEX;
+  static const int _LATE_SENTINEL_MASK = 1 << _LATE_SENTINEL_INDEX;
+  static const int _ALL_MASK = (1 << _USED_INDICES) - 1;
+
+  final ClassEntity? base;
+  final int flags;
+
+  static int _computeFlags(_FlatTypeMaskKind kind,
+      {bool isNullable = false, bool hasLateSentinel = false}) {
+    int mask = _NONE_MASK;
+    if (isNullable) mask |= _NULL_MASK;
+    if (hasLateSentinel) mask |= _LATE_SENTINEL_MASK;
+    return _computeFlagsRaw(kind.index, mask);
+  }
+
+  static int _computeFlagsRaw(int kind, int mask) =>
+      kind << _USED_INDICES | mask;
+
+  static _FlatTypeMaskKind _lookupKind(int flags) =>
+      _FlatTypeMaskKind.values[flags >> _USED_INDICES];
+
+  static bool _hasNullableFlag(int flags) => flags & _NULL_MASK != _NONE_MASK;
+
+  static bool _hasLateSentinelFlag(int flags) =>
+      flags & _LATE_SENTINEL_MASK != _NONE_MASK;
+
+  factory FlatTypeMask.exact(ClassEntity base, JClosedWorld world,
+          {bool hasLateSentinel = false}) =>
+      FlatTypeMask._canonicalize(base, _FlatTypeMaskKind.exact, world,
+          isNullable: true, hasLateSentinel: hasLateSentinel);
+  factory FlatTypeMask.subclass(ClassEntity base, JClosedWorld world,
+          {bool hasLateSentinel = false}) =>
+      FlatTypeMask._canonicalize(base, _FlatTypeMaskKind.subclass, world,
+          isNullable: true, hasLateSentinel: hasLateSentinel);
+  factory FlatTypeMask.subtype(ClassEntity base, JClosedWorld world,
+          {bool hasLateSentinel = false}) =>
+      FlatTypeMask._canonicalize(base, _FlatTypeMaskKind.subtype, world,
+          isNullable: true, hasLateSentinel: hasLateSentinel);
+
+  factory FlatTypeMask.nonNullEmpty({bool hasLateSentinel = false}) =>
+      hasLateSentinel
+          ? const FlatTypeMask._(null, _LATE_SENTINEL_MASK)
+          : const FlatTypeMask._(null, _NONE_MASK);
+
+  factory FlatTypeMask.empty({bool hasLateSentinel = false}) => hasLateSentinel
+      ? const FlatTypeMask._(null, _NULL_MASK | _LATE_SENTINEL_MASK)
+      : const FlatTypeMask._(null, _NULL_MASK);
+
+  factory FlatTypeMask.nonNullExact(ClassEntity base, JClosedWorld world,
+          {bool hasLateSentinel = false}) =>
+      FlatTypeMask._canonicalize(base, _FlatTypeMaskKind.exact, world,
+          hasLateSentinel: hasLateSentinel);
+  factory FlatTypeMask.nonNullSubclass(ClassEntity base, JClosedWorld world,
+          {bool hasLateSentinel = false}) =>
+      FlatTypeMask._canonicalize(base, _FlatTypeMaskKind.subclass, world,
+          hasLateSentinel: hasLateSentinel);
+  factory FlatTypeMask.nonNullSubtype(ClassEntity base, JClosedWorld world,
+          {bool hasLateSentinel = false}) =>
+      FlatTypeMask._canonicalize(base, _FlatTypeMaskKind.subtype, world,
+          hasLateSentinel: hasLateSentinel);
+
+  factory FlatTypeMask._canonicalize(
+      ClassEntity base, _FlatTypeMaskKind kind, JClosedWorld world,
+      {bool isNullable = false, bool hasLateSentinel = false}) {
+    if (base == world.commonElements.nullClass) {
+      return FlatTypeMask.empty(hasLateSentinel: hasLateSentinel);
+    }
+    return FlatTypeMask._(
+        base,
+        _computeFlags(kind,
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel));
+  }
+
+  const FlatTypeMask._(this.base, this.flags);
+
+  /// Ensures that the generated mask is normalized, i.e., a call to
+  /// [TypeMask.assertIsNormalized] with the factory's result returns `true`.
+  factory FlatTypeMask.normalized(
+      ClassEntity? base, int flags, CommonMasks domain) {
+    bool isNullable = _hasNullableFlag(flags);
+    bool hasLateSentinel = _hasLateSentinelFlag(flags);
+    if (base == domain.commonElements.nullClass) {
+      return FlatTypeMask.empty(hasLateSentinel: hasLateSentinel);
+    }
+    _FlatTypeMaskKind kind = _lookupKind(flags);
+    if (kind == _FlatTypeMaskKind.empty || kind == _FlatTypeMaskKind.exact) {
+      return FlatTypeMask._(base, flags);
+    }
+    if (kind == _FlatTypeMaskKind.subtype) {
+      if (!domain._closedWorld.classHierarchy.hasAnyStrictSubtype(base!) ||
+          domain._closedWorld.classHierarchy.hasOnlySubclasses(base)) {
+        flags = _computeFlags(_FlatTypeMaskKind.subclass,
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+      }
+    }
+    if (kind == _FlatTypeMaskKind.subclass &&
+        !domain._closedWorld.classHierarchy.hasAnyStrictSubclass(base!)) {
+      flags = _computeFlags(_FlatTypeMaskKind.exact,
+          isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+    }
+    return domain.getCachedMask(base, flags, () => FlatTypeMask._(base, flags));
+  }
+
+  /// Deserializes a [FlatTypeMask] object from [source].
+  factory FlatTypeMask.readFromDataSource(
+      DataSourceReader source, CommonMasks domain) {
+    source.begin(tag);
+    final base = source.readClassOrNull();
+    int flags = source.readInt();
+    source.end(tag);
+    return domain.getCachedMask(base, flags, () => FlatTypeMask._(base, flags));
+  }
+
+  /// Serializes this [FlatTypeMask] to [sink].
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(TypeMaskKind.flat);
+    sink.begin(tag);
+    sink.writeClassOrNull(base);
+    sink.writeInt(flags);
+    sink.end(tag);
+  }
+
+  _FlatTypeMaskKind get _kind => _lookupKind(flags);
+
+  int get _mask => flags & _ALL_MASK;
+
+  ClassQuery get _classQuery => isExact
+      ? ClassQuery.EXACT
+      : (isSubclass ? ClassQuery.SUBCLASS : ClassQuery.SUBTYPE);
+
+  @override
+  bool get isEmpty => isEmptyOrFlagged && _mask == _NONE_MASK;
+  @override
+  bool get isNull => isEmptyOrFlagged && _mask == _NULL_MASK;
+  @override
+  bool get isEmptyOrFlagged => _kind == _FlatTypeMaskKind.empty;
+  @override
+  bool get isExact => _kind == _FlatTypeMaskKind.exact;
+  @override
+  bool get isNullable => _hasNullableFlag(flags);
+  @override
+  bool get hasLateSentinel => _hasLateSentinelFlag(flags);
+  @override
+  AbstractBool get isLateSentinel {
+    if (!hasLateSentinel) return AbstractBool.False;
+    if (isEmptyOrFlagged && _mask == _LATE_SENTINEL_MASK) {
+      return AbstractBool.True;
+    }
+    return AbstractBool.Maybe;
+  }
+
+  // TODO(kasperl): Get rid of these. They should not be a visible
+  // part of the implementation because they make it hard to add
+  // proper union types if we ever want to.
+  bool get isSubclass => _kind == _FlatTypeMaskKind.subclass;
+  bool get isSubtype => _kind == _FlatTypeMaskKind.subtype;
+
+  @override
+  FlatTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
+    int newFlags = _computeFlags(_kind,
+        isNullable: isNullable ?? this.isNullable,
+        hasLateSentinel: hasLateSentinel ?? this.hasLateSentinel);
+    if (newFlags == flags) return this;
+    return FlatTypeMask._(base, newFlags);
+  }
+
+  @override
+  bool contains(ClassEntity other, JClosedWorld closedWorld) {
+    if (isEmptyOrFlagged) {
+      return false;
+    } else if (identical(base, other)) {
+      return true;
+    } else if (isExact) {
+      return false;
+    } else if (isSubclass) {
+      return closedWorld.classHierarchy.isSubclassOf(other, base!);
+    } else {
+      assert(isSubtype);
+      return closedWorld.classHierarchy.isSubtypeOf(other, base!);
+    }
+  }
+
+  bool _isSingleImplementationOf(ClassEntity cls, JClosedWorld closedWorld) {
+    // Special case basic types so that, for example, JSString is the
+    // single implementation of String.
+    // The general optimization is to realize there is only one class that
+    // implements [base] and [base] is not instantiated. We however do
+    // not track correctly the list of truly instantiated classes.
+    CommonElements commonElements = closedWorld.commonElements;
+    if (containsOnlyString(closedWorld)) {
+      return cls == closedWorld.commonElements.stringClass ||
+          cls == commonElements.jsStringClass;
+    }
+    if (containsOnlyBool(closedWorld)) {
+      return cls == closedWorld.commonElements.boolClass ||
+          cls == commonElements.jsBoolClass;
+    }
+    if (containsOnlyInt(closedWorld)) {
+      return cls == closedWorld.commonElements.intClass ||
+          cls == commonElements.jsIntClass ||
+          cls == commonElements.jsPositiveIntClass ||
+          cls == commonElements.jsUInt32Class ||
+          cls == commonElements.jsUInt31Class;
+    }
+    return false;
+  }
+
+  @override
+  bool isInMask(TypeMask other, JClosedWorld closedWorld) {
+    // Quick check whether to handle null.
+    if (isNullable && !other.isNullable) return false;
+    if (hasLateSentinel && !other.hasLateSentinel) {
+      return false;
+    }
+    // The empty type contains no classes.
+    if (isEmptyOrFlagged) return true;
+    if (other.isEmptyOrFlagged) return false;
+    other = TypeMask.nonForwardingMask(other);
+    // If other is union, delegate to UnionTypeMask.containsMask.
+    if (other is! FlatTypeMask) return other.containsMask(this, closedWorld);
+    // The other must be flat, so compare base and flags.
+    FlatTypeMask flatOther = other;
+    final otherBase = flatOther.base;
+    // If other is exact, it only contains its base.
+    // TODO(herhut): Get rid of _isSingleImplementationOf.
+    if (flatOther.isExact) {
+      return (isExact && base == otherBase) ||
+          _isSingleImplementationOf(otherBase!, closedWorld);
+    }
+    // If other is subclass, this has to be subclass, as well. Unless
+    // flatOther.base covers all subtypes of this. Currently, we only
+    // consider object to behave that way.
+    // TODO(herhut): Add check whether flatOther.base is superclass of
+    //               all subclasses of this.base.
+    if (flatOther.isSubclass) {
+      if (isSubtype)
+        return (otherBase == closedWorld.commonElements.objectClass);
+      return closedWorld.classHierarchy.isSubclassOf(base!, otherBase!);
+    }
+    assert(flatOther.isSubtype);
+    // Check whether this TypeMask satisfies otherBase's interface.
+    return satisfies(otherBase!, closedWorld);
+  }
+
+  @override
+  bool containsMask(TypeMask other, JClosedWorld closedWorld) {
+    return other.isInMask(this, closedWorld);
+  }
+
+  @override
+  bool containsOnlyInt(JClosedWorld closedWorld) {
+    CommonElements commonElements = closedWorld.commonElements;
+    return base == commonElements.intClass ||
+        base == commonElements.jsIntClass ||
+        base == commonElements.jsPositiveIntClass ||
+        base == commonElements.jsUInt31Class ||
+        base == commonElements.jsUInt32Class;
+  }
+
+  @override
+  bool containsOnlyNum(JClosedWorld closedWorld) {
+    return containsOnlyInt(closedWorld) ||
+        base == closedWorld.commonElements.doubleClass ||
+        base == closedWorld.commonElements.jsNumNotIntClass ||
+        base == closedWorld.commonElements.numClass ||
+        base == closedWorld.commonElements.jsNumberClass;
+  }
+
+  @override
+  bool containsOnlyBool(JClosedWorld closedWorld) {
+    return base == closedWorld.commonElements.boolClass ||
+        base == closedWorld.commonElements.jsBoolClass;
+  }
+
+  @override
+  bool containsOnlyString(JClosedWorld closedWorld) {
+    return base == closedWorld.commonElements.stringClass ||
+        base == closedWorld.commonElements.jsStringClass;
+  }
+
+  @override
+  bool containsOnly(ClassEntity cls) {
+    return base == cls;
+  }
+
+  @override
+  bool satisfies(ClassEntity cls, JClosedWorld closedWorld) {
+    if (isEmptyOrFlagged) return false;
+    if (closedWorld.classHierarchy.isSubtypeOf(base!, cls)) return true;
+    return false;
+  }
+
+  @override
+  ClassEntity? singleClass(JClosedWorld closedWorld) {
+    if (isEmptyOrFlagged) return null;
+    if (isNullable) return null; // It is Null and some other class.
+    if (hasLateSentinel) return null;
+    if (isExact) {
+      return base;
+    } else if (isSubclass) {
+      return closedWorld.classHierarchy.hasAnyStrictSubclass(base!)
+          ? null
+          : base;
+    } else {
+      assert(isSubtype);
+      return null;
+    }
+  }
+
+  @override
+  bool containsAll(JClosedWorld closedWorld) {
+    if (isEmptyOrFlagged || isExact) return false;
+    return identical(base, closedWorld.commonElements.objectClass);
+  }
+
+  @override
+  TypeMask union(TypeMask other, CommonMasks domain) {
+    JClosedWorld closedWorld = domain._closedWorld;
+    assert(TypeMask.assertIsNormalized(this, closedWorld));
+    assert(TypeMask.assertIsNormalized(other, closedWorld));
+    if (other is! FlatTypeMask) return other.union(this, domain);
+    FlatTypeMask flatOther = other;
+    bool isNullable = this.isNullable || flatOther.isNullable;
+    bool hasLateSentinel = this.hasLateSentinel || flatOther.hasLateSentinel;
+    if (isEmptyOrFlagged) {
+      return flatOther.withFlags(
+          isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+    } else if (flatOther.isEmptyOrFlagged) {
+      return withFlags(
+          isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+    } else if (base == flatOther.base) {
+      return unionSame(flatOther, domain);
+    } else if (closedWorld.classHierarchy
+        .isSubclassOf(flatOther.base!, base!)) {
+      return unionStrictSubclass(flatOther, domain);
+    } else if (closedWorld.classHierarchy
+        .isSubclassOf(base!, flatOther.base!)) {
+      return flatOther.unionStrictSubclass(this, domain);
+    } else if (closedWorld.classHierarchy.isSubtypeOf(flatOther.base!, base!)) {
+      return unionStrictSubtype(flatOther, domain);
+    } else if (closedWorld.classHierarchy.isSubtypeOf(base!, flatOther.base!)) {
+      return flatOther.unionStrictSubtype(this, domain);
+    } else {
+      return UnionTypeMask._internal([
+        withoutFlags() as FlatTypeMask,
+        flatOther.withoutFlags() as FlatTypeMask
+      ], isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+    }
+  }
+
+  TypeMask unionSame(FlatTypeMask other, CommonMasks domain) {
+    assert(base == other.base);
+    assert(TypeMask.assertIsNormalized(this, domain._closedWorld));
+    assert(TypeMask.assertIsNormalized(other, domain._closedWorld));
+    // The two masks share the base type, so we must chose the least
+    // constraining kind (the highest) of the two. If either one of
+    // the masks are nullable the result should be nullable too.
+    // As both masks are normalized, the result will be, too.
+    int combined =
+        (flags > other.flags) ? flags | other._mask : other.flags | _mask;
+    if (flags == combined) {
+      return this;
+    } else if (other.flags == combined) {
+      return other;
+    } else {
+      return FlatTypeMask.normalized(base!, combined, domain);
+    }
+  }
+
+  TypeMask unionStrictSubclass(FlatTypeMask other, CommonMasks domain) {
+    assert(base != other.base);
+    assert(domain._closedWorld.classHierarchy.isSubclassOf(other.base!, base!));
+    assert(TypeMask.assertIsNormalized(this, domain._closedWorld));
+    assert(TypeMask.assertIsNormalized(other, domain._closedWorld));
+    int combined;
+    if ((isExact && other.isExact) ||
+        base == domain.commonElements.objectClass) {
+      // Since the other mask is a subclass of this mask, we need the
+      // resulting union to be a subclass too. If either one of the
+      // masks are nullable the result should be nullable too.
+      combined = _computeFlagsRaw(
+          _FlatTypeMaskKind.subclass.index, _mask | other._mask);
+    } else {
+      // Both masks are at least subclass masks, so we pick the least
+      // constraining kind (the highest) of the two. If either one of
+      // the masks are nullable the result should be nullable too.
+      combined =
+          (flags > other.flags) ? flags | other._mask : other.flags | _mask;
+    }
+    // If we weaken the constraint on this type, we have to make sure that
+    // the result is normalized.
+    return flags != combined
+        ? FlatTypeMask.normalized(base, combined, domain)
+        : this;
+  }
+
+  TypeMask unionStrictSubtype(FlatTypeMask other, CommonMasks domain) {
+    assert(base != other.base);
+    assert(
+        !domain._closedWorld.classHierarchy.isSubclassOf(other.base!, base!));
+    assert(domain._closedWorld.classHierarchy.isSubtypeOf(other.base!, base!));
+    assert(TypeMask.assertIsNormalized(this, domain._closedWorld));
+    assert(TypeMask.assertIsNormalized(other, domain._closedWorld));
+    // Since the other mask is a subtype of this mask, we need the
+    // resulting union to be a subtype too. If either one of the masks
+    // are nullable the result should be nullable too.
+    int combined =
+        _computeFlagsRaw(_FlatTypeMaskKind.subtype.index, _mask | other._mask);
+    // We know there is at least one subtype, [other.base], so no need
+    // to normalize.
+    return flags != combined
+        ? FlatTypeMask.normalized(base, combined, domain)
+        : this;
+  }
+
+  @override
+  TypeMask intersection(TypeMask other, CommonMasks domain) {
+    if (other is! FlatTypeMask) return other.intersection(this, domain);
+    assert(TypeMask.assertIsNormalized(this, domain._closedWorld));
+    assert(TypeMask.assertIsNormalized(other, domain._closedWorld));
+    FlatTypeMask flatOther = other;
+
+    final otherBase = flatOther.base;
+
+    bool includeNull = isNullable && flatOther.isNullable;
+    bool includeLateSentinel = hasLateSentinel && flatOther.hasLateSentinel;
+
+    if (isEmptyOrFlagged) {
+      return withFlags(
+          isNullable: includeNull, hasLateSentinel: includeLateSentinel);
+    } else if (flatOther.isEmptyOrFlagged) {
+      return other.withFlags(
+          isNullable: includeNull, hasLateSentinel: includeLateSentinel);
+    }
+
+    SubclassResult result = domain._closedWorld.classHierarchy.commonSubclasses(
+        base!, _classQuery, otherBase!, flatOther._classQuery);
+
+    switch (result.kind) {
+      case SubclassResultKind.EMPTY:
+        return includeNull
+            ? TypeMask.empty(hasLateSentinel: includeLateSentinel)
+            : TypeMask.nonNullEmpty(hasLateSentinel: includeLateSentinel);
+      case SubclassResultKind.EXACT1:
+        assert(isExact);
+        return withFlags(
+            isNullable: includeNull, hasLateSentinel: includeLateSentinel);
+      case SubclassResultKind.EXACT2:
+        assert(other.isExact);
+        return other.withFlags(
+            isNullable: includeNull, hasLateSentinel: includeLateSentinel);
+      case SubclassResultKind.SUBCLASS1:
+        assert(isSubclass);
+        return withFlags(
+            isNullable: includeNull, hasLateSentinel: includeLateSentinel);
+      case SubclassResultKind.SUBCLASS2:
+        assert(flatOther.isSubclass);
+        return other.withFlags(
+            isNullable: includeNull, hasLateSentinel: includeLateSentinel);
+      case SubclassResultKind.SUBTYPE1:
+        assert(isSubtype);
+        return withFlags(
+            isNullable: includeNull, hasLateSentinel: includeLateSentinel);
+      case SubclassResultKind.SUBTYPE2:
+        assert(flatOther.isSubtype);
+        return other.withFlags(
+            isNullable: includeNull, hasLateSentinel: includeLateSentinel);
+      case SubclassResultKind.SET:
+      default:
+        if (result.classes.isEmpty) {
+          return includeNull
+              ? TypeMask.empty(hasLateSentinel: includeLateSentinel)
+              : TypeMask.nonNullEmpty(hasLateSentinel: includeLateSentinel);
+        } else if (result.classes.length == 1) {
+          ClassEntity cls = result.classes.first;
+          return includeNull
+              ? TypeMask.subclass(cls, domain._closedWorld,
+                  hasLateSentinel: includeLateSentinel)
+              : TypeMask.nonNullSubclass(cls, domain._closedWorld,
+                  hasLateSentinel: includeLateSentinel);
+        }
+
+        List<FlatTypeMask> masks = List.from(result.classes.map(
+            (ClassEntity cls) =>
+                TypeMask.nonNullSubclass(cls, domain._closedWorld)));
+        if (masks.length > UnionTypeMask.MAX_UNION_LENGTH) {
+          return UnionTypeMask.flatten(masks, domain,
+              includeNull: includeNull,
+              includeLateSentinel: includeLateSentinel);
+        }
+        return UnionTypeMask._internal(masks,
+            isNullable: includeNull, hasLateSentinel: includeLateSentinel);
+    }
+  }
+
+  @override
+  bool isDisjoint(TypeMask other, JClosedWorld closedWorld) {
+    if (other is! FlatTypeMask) return other.isDisjoint(this, closedWorld);
+    FlatTypeMask flatOther = other;
+
+    if (isNullable && flatOther.isNullable) return false;
+    if (hasLateSentinel && flatOther.hasLateSentinel) return false;
+    if (isEmptyOrFlagged || flatOther.isEmptyOrFlagged) return true;
+    if (base == flatOther.base) return false;
+    if (isExact && flatOther.isExact) return true;
+
+    if (isExact) return !flatOther.contains(base!, closedWorld);
+    if (flatOther.isExact) return !contains(flatOther.base!, closedWorld);
+    final thisBase = base!;
+    final otherBase = flatOther.base!;
+
+    // Normalization guarantees that isExact === !isSubclass && !isSubtype.
+    // Both are subclass or subtype masks, so if there is a subclass
+    // relationship, they are not disjoint.
+    if (closedWorld.classHierarchy.isSubclassOf(otherBase, thisBase)) {
+      return false;
+    }
+    if (closedWorld.classHierarchy.isSubclassOf(thisBase, otherBase)) {
+      return false;
+    }
+
+    // Two different base classes have no common subclass unless one is a
+    // subclass of the other (checked above).
+    if (isSubclass && flatOther.isSubclass) return true;
+
+    return _isDisjointHelper(this, flatOther, closedWorld);
+  }
+
+  static bool _isDisjointHelper(
+      FlatTypeMask a, FlatTypeMask b, JClosedWorld closedWorld) {
+    if (!a.isSubclass && b.isSubclass) {
+      return _isDisjointHelper(b, a, closedWorld);
+    }
+    assert(a.isSubclass || a.isSubtype);
+    assert(b.isSubtype);
+    final aBase = a.base!;
+    var elements = a.isSubclass
+        ? closedWorld.classHierarchy.strictSubclassesOf(aBase)
+        : closedWorld.classHierarchy.strictSubtypesOf(aBase);
+    for (var element in elements) {
+      if (closedWorld.classHierarchy.isSubtypeOf(element, b.base!)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  TypeMask intersectionSame(FlatTypeMask other, CommonMasks domain) {
+    assert(base == other.base);
+    // The two masks share the base type, so we must chose the most
+    // constraining kind (the lowest) of the two. Only if both masks
+    // are nullable, will the result be nullable too.
+    // The result will be normalized, as the two inputs are normalized, too.
+    int combined = (flags < other.flags)
+        ? flags & (other._mask | ~_ALL_MASK)
+        : other.flags & (_mask | ~_ALL_MASK);
+    if (flags == combined) {
+      return this;
+    } else if (other.flags == combined) {
+      return other;
+    } else {
+      return FlatTypeMask.normalized(base, combined, domain);
+    }
+  }
+
+  TypeMask intersectionStrictSubclass(FlatTypeMask other, CommonMasks domain) {
+    assert(base != other.base);
+    assert(domain._closedWorld.classHierarchy.isSubclassOf(other.base!, base!));
+    // If this mask isn't at least a subclass mask, then the
+    // intersection with the other mask is empty.
+    if (isExact) return intersectionEmpty(other);
+    // Only the other mask puts constraints on the intersection mask,
+    // so base the combined flags on the other mask. Only if both
+    // masks are nullable, will the result be nullable too.
+    // The result is guaranteed to be normalized, as the other type
+    // was normalized.
+    int combined = other.flags & (_mask | ~_ALL_MASK);
+    if (other.flags == combined) {
+      return other;
+    } else {
+      return FlatTypeMask.normalized(other.base, combined, domain);
+    }
+  }
+
+  TypeMask intersectionEmpty(FlatTypeMask other) {
+    bool isNullable = this.isNullable && other.isNullable;
+    bool hasLateSentinel = this.hasLateSentinel && other.hasLateSentinel;
+    return isNullable
+        ? TypeMask.empty(hasLateSentinel: hasLateSentinel)
+        : TypeMask.nonNullEmpty(hasLateSentinel: hasLateSentinel);
+  }
+
+  @override
+  bool canHit(MemberEntity element, Name name, JClosedWorld closedWorld) {
+    CommonElements commonElements = closedWorld.commonElements;
+    assert(element.name == name.text);
+    if (isEmptyOrFlagged) {
+      return isNullable &&
+          closedWorld.hasElementIn(commonElements.jsNullClass, name, element);
+    }
+
+    final other = element.enclosingClass;
+    final thisBase = base!;
+    if (other == commonElements.jsNullClass) {
+      return isNullable;
+    } else if (isExact) {
+      return closedWorld.hasElementIn(thisBase, name, element);
+    } else if (isSubclass) {
+      return closedWorld.hasElementIn(thisBase, name, element) ||
+          closedWorld.classHierarchy.isSubclassOf(other!, thisBase) ||
+          closedWorld.hasAnySubclassThatMixes(thisBase, other);
+    } else {
+      assert(isSubtype);
+      bool result = closedWorld.hasElementIn(thisBase, name, element) ||
+          closedWorld.classHierarchy.isSubtypeOf(other!, thisBase) ||
+          closedWorld.hasAnySubclassThatImplements(other, thisBase) ||
+          closedWorld.hasAnySubclassOfMixinUseThatImplements(other, thisBase);
+      if (result) return true;
+      // If the class is used as a mixin, we have to check if the element
+      // can be hit from any of the mixin applications.
+      Iterable<ClassEntity> mixinUses = closedWorld.mixinUsesOf(thisBase);
+      return mixinUses.any((mixinApplication) =>
+          closedWorld.hasElementIn(mixinApplication, name, element) ||
+          closedWorld.classHierarchy.isSubclassOf(other, mixinApplication) ||
+          closedWorld.hasAnySubclassThatMixes(mixinApplication, other));
+    }
+  }
+
+  @override
+  bool needsNoSuchMethodHandling(
+      Selector selector, covariant JClosedWorld closedWorld) {
+    // A call on an empty type mask is either dead code, or a call on
+    // `null`.
+    if (isEmptyOrFlagged) return false;
+    // A call on an exact mask for an abstract class is dead code.
+    // TODO(johnniwinther): A type mask cannot be abstract. Remove the need
+    // for this noise (currently used for super-calls in inference and mirror
+    // usage).
+    final thisBase = base!;
+    if (isExact && thisBase.isAbstract) return false;
+
+    return closedWorld.needsNoSuchMethod(thisBase, selector, _classQuery);
+  }
+
+  @override
+  MemberEntity? locateSingleMember(Selector selector, CommonMasks domain) {
+    if (isEmptyOrFlagged) return null;
+    JClosedWorld closedWorld = domain._closedWorld;
+    if (closedWorld.includesClosureCallInDomain(selector, this, domain))
+      return null;
+    Iterable<MemberEntity> targets =
+        closedWorld.locateMembersInDomain(selector, this, domain);
+    if (targets.length != 1) return null;
+    MemberEntity result = targets.first;
+    final enclosing = result.enclosingClass!;
+    final thisBase = base!;
+    // We only return the found element if it is guaranteed to be implemented on
+    // all classes in the receiver type [this]. It could be found only in a
+    // subclass or in an inheritance-wise unrelated class in case of subtype
+    // selectors.
+    if (isSubtype) {
+      // if (closedWorld.isUsedAsMixin(enclosing)) {
+      if (closedWorld.everySubtypeIsSubclassOfOrMixinUseOf(
+          thisBase, enclosing)) {
+        return result;
+      }
+      //}
+      return null;
+    } else {
+      if (closedWorld.classHierarchy.isSubclassOf(thisBase, enclosing)) {
+        return result;
+      }
+      if (closedWorld.isSubclassOfMixinUseOf(thisBase, enclosing))
+        return result;
+    }
+    return null;
+  }
+
+  @override
+  bool operator ==(var other) {
+    if (identical(this, other)) return true;
+    if (other is! FlatTypeMask) return false;
+    FlatTypeMask otherMask = other;
+    return (flags == otherMask.flags) && (base == otherMask.base);
+  }
+
+  @override
+  int get hashCode {
+    return (base == null ? 0 : base.hashCode) + 31 * flags.hashCode;
+  }
+
+  @override
+  String toString() {
+    StringBuffer buffer = StringBuffer('[');
+    buffer.writeAll([
+      if (isEmpty) 'empty',
+      if (isNullable) 'null',
+      if (hasLateSentinel) 'sentinel',
+      if (isExact) 'exact=${base!.name}',
+      if (isSubclass) 'subclass=${base!.name}',
+      if (isSubtype) 'subtype=${base!.name}',
+    ], '|');
+    buffer.write(']');
+    return buffer.toString();
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/forwarding_type_mask.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/forwarding_type_mask.dart
new file mode 100644
index 0000000..5349382
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/forwarding_type_mask.dart
@@ -0,0 +1,169 @@
+// Copyright (c) 2013, 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.
+
+part of masks;
+
+/// A type mask that wraps another one, and delegates all its
+/// implementation methods to it.
+abstract class ForwardingTypeMask extends TypeMask {
+  TypeMask get forwardTo;
+
+  const ForwardingTypeMask();
+
+  @override
+  bool get isEmptyOrFlagged => forwardTo.isEmptyOrFlagged;
+  @override
+  bool get isEmpty => forwardTo.isEmpty;
+  @override
+  bool get isNullable => forwardTo.isNullable;
+  @override
+  bool get isNull => forwardTo.isNull;
+  @override
+  bool get hasLateSentinel => forwardTo.hasLateSentinel;
+  @override
+  AbstractBool get isLateSentinel => forwardTo.isLateSentinel;
+  @override
+  bool get isExact => forwardTo.isExact;
+
+  @override
+  bool isInMask(TypeMask other, JClosedWorld closedWorld) {
+    return forwardTo.isInMask(other, closedWorld);
+  }
+
+  @override
+  bool containsMask(TypeMask other, JClosedWorld closedWorld) {
+    return forwardTo.containsMask(other, closedWorld);
+  }
+
+  @override
+  bool containsOnlyInt(JClosedWorld closedWorld) {
+    return forwardTo.containsOnlyInt(closedWorld);
+  }
+
+  @override
+  bool containsOnlyNum(JClosedWorld closedWorld) {
+    return forwardTo.containsOnlyNum(closedWorld);
+  }
+
+  @override
+  bool containsOnlyBool(JClosedWorld closedWorld) {
+    return forwardTo.containsOnlyBool(closedWorld);
+  }
+
+  @override
+  bool containsOnlyString(JClosedWorld closedWorld) {
+    return forwardTo.containsOnlyString(closedWorld);
+  }
+
+  @override
+  bool containsOnly(ClassEntity cls) {
+    return forwardTo.containsOnly(cls);
+  }
+
+  @override
+  bool satisfies(ClassEntity cls, JClosedWorld closedWorld) {
+    return forwardTo.satisfies(cls, closedWorld);
+  }
+
+  @override
+  bool contains(ClassEntity cls, JClosedWorld closedWorld) {
+    return forwardTo.contains(cls, closedWorld);
+  }
+
+  @override
+  bool containsAll(JClosedWorld closedWorld) {
+    return forwardTo.containsAll(closedWorld);
+  }
+
+  @override
+  ClassEntity? singleClass(JClosedWorld closedWorld) {
+    return forwardTo.singleClass(closedWorld);
+  }
+
+  @override
+  TypeMask union(TypeMask other, CommonMasks domain) {
+    if (this == other) {
+      return this;
+    }
+    bool isNullable = this.isNullable || other.isNullable;
+    bool hasLateSentinel = this.hasLateSentinel || other.hasLateSentinel;
+    if (isEmptyOrFlagged) {
+      return other.withFlags(
+          isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+    }
+    if (other.isEmptyOrFlagged) {
+      return withFlags(
+          isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+    }
+    return _unionSpecialCases(other, domain,
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel) ??
+        forwardTo.union(other, domain);
+  }
+
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+          {required bool isNullable, required bool hasLateSentinel}) =>
+      null;
+
+  @override
+  bool isDisjoint(TypeMask other, JClosedWorld closedWorld) {
+    return forwardTo.isDisjoint(other, closedWorld);
+  }
+
+  @override
+  TypeMask intersection(TypeMask other, CommonMasks domain) {
+    TypeMask forwardIntersection = forwardTo.intersection(other, domain);
+    if (forwardIntersection.isEmptyOrFlagged) return forwardIntersection;
+    return withFlags(
+        isNullable: forwardIntersection.isNullable,
+        hasLateSentinel: forwardIntersection.hasLateSentinel);
+  }
+
+  @override
+  bool needsNoSuchMethodHandling(
+      Selector selector, covariant JClosedWorld closedWorld) {
+    return forwardTo.needsNoSuchMethodHandling(selector, closedWorld);
+  }
+
+  @override
+  bool canHit(MemberEntity element, Name name, JClosedWorld closedWorld) {
+    return forwardTo.canHit(element, name, closedWorld);
+  }
+
+  @override
+  MemberEntity? locateSingleMember(Selector selector, CommonMasks domain) {
+    return forwardTo.locateSingleMember(selector, domain);
+  }
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! ForwardingTypeMask) return false;
+    return forwardTo == other.forwardTo;
+  }
+
+  @override
+  int get hashCode => forwardTo.hashCode;
+}
+
+abstract class AllocationTypeMask extends ForwardingTypeMask {
+  const AllocationTypeMask();
+
+  // The [ir.Node] where this type mask was created. This value is not used
+  // after type inference and therefore does not need to be serialized by
+  // subclasses.  It will always be null outside of the global inference phase.
+  ir.Node? get allocationNode;
+
+  // The [Entity] where this type mask was created.
+  MemberEntity? get allocationElement;
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! AllocationTypeMask) return false;
+    return super == other && allocationNode == other.allocationNode;
+  }
+
+  @override
+  int get hashCode => Hashing.objectHash(allocationNode, super.hashCode);
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/map_type_mask.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/map_type_mask.dart
new file mode 100644
index 0000000..cc71161
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/map_type_mask.dart
@@ -0,0 +1,127 @@
+// Copyright (c) 2014, 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.
+
+part of masks;
+
+/// A [MapTypeMask] is a [TypeMask] for a specific allocation
+/// site of a map (currently only internal Map class) that will get specialized
+/// once the [TypeGraphInferrer] phase finds a key and/or value type for it.
+class MapTypeMask extends AllocationTypeMask {
+  /// Tag used for identifying serialized [MapTypeMask] objects in a
+  /// debugging data stream.
+  static const String tag = 'map-type-mask';
+
+  @override
+  final TypeMask forwardTo;
+
+  final ir.Node? _allocationNode;
+  @override
+  ir.Node? get allocationNode => _allocationNode;
+
+  @override
+  final MemberEntity? allocationElement;
+
+  // The value type of this map.
+  final TypeMask valueType;
+
+  // The key type of this map.
+  final TypeMask keyType;
+
+  const MapTypeMask(this.forwardTo, this._allocationNode,
+      this.allocationElement, this.keyType, this.valueType);
+
+  /// Deserializes a [MapTypeMask] object from [source].
+  factory MapTypeMask.readFromDataSource(
+      DataSourceReader source, CommonMasks domain) {
+    source.begin(tag);
+    final forwardTo = TypeMask.readFromDataSource(source, domain);
+    final allocationElement = source.readMemberOrNull();
+    final keyType = TypeMask.readFromDataSource(source, domain);
+    final valueType = TypeMask.readFromDataSource(source, domain);
+    source.end(tag);
+    return MapTypeMask(forwardTo, null, allocationElement, keyType, valueType);
+  }
+
+  /// Serializes this [MapTypeMask] to [sink].
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(TypeMaskKind.map);
+    sink.begin(tag);
+    forwardTo.writeToDataSink(sink);
+    sink.writeMemberOrNull(allocationElement);
+    keyType.writeToDataSink(sink);
+    valueType.writeToDataSink(sink);
+    sink.end(tag);
+  }
+
+  @override
+  MapTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
+    isNullable ??= this.isNullable;
+    hasLateSentinel ??= this.hasLateSentinel;
+    if (isNullable == this.isNullable &&
+        hasLateSentinel == this.hasLateSentinel) {
+      return this;
+    }
+    return MapTypeMask(
+        forwardTo.withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel),
+        allocationNode,
+        allocationElement,
+        keyType,
+        valueType);
+  }
+
+  @override
+  bool get isExact => true;
+
+  @override
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+      {required bool isNullable, required bool hasLateSentinel}) {
+    if (other is MapTypeMask) {
+      TypeMask newKeyType = keyType.union(other.keyType, domain);
+      TypeMask newValueType = valueType.union(other.valueType, domain);
+      TypeMask newForwardTo = forwardTo.union(other.forwardTo, domain);
+      return MapTypeMask(newForwardTo, null, null, newKeyType, newValueType);
+    }
+    if (other is DictionaryTypeMask) {
+      // TODO(johnniwinther): Find another way to check this invariant that
+      // doesn't need the compiler.
+      assert(other.keyType ==
+          TypeMask.nonNullExact(
+              domain.commonElements.jsStringClass, domain._closedWorld));
+      TypeMask newKeyType = keyType.union(other.keyType, domain);
+      TypeMask newValueType =
+          other._typeMap.values.fold(keyType, (p, n) => p.union(n, domain));
+      TypeMask newForwardTo = forwardTo.union(other.forwardTo, domain);
+      MapTypeMask newMapTypeMask = MapTypeMask(
+          newForwardTo,
+          allocationNode == other.allocationNode ? allocationNode : null,
+          allocationElement == other.allocationElement
+              ? allocationElement
+              : null,
+          newKeyType,
+          newValueType);
+      return newMapTypeMask;
+    }
+    return null;
+  }
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! MapTypeMask) return false;
+    return super == other &&
+        keyType == other.keyType &&
+        valueType == other.valueType;
+  }
+
+  @override
+  int get hashCode => Hashing.objectHash(
+      valueType, Hashing.objectHash(keyType, super.hashCode));
+
+  @override
+  String toString() {
+    return 'Map($forwardTo, key: $keyType, value: $valueType)';
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/masks.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/masks.dart
new file mode 100644
index 0000000..209aa06
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/masks.dart
@@ -0,0 +1,985 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library masks;
+
+import 'package:kernel/ast.dart' as ir;
+
+import '../../common.dart';
+import '../../common/elements.dart' show CommonElements;
+import '../../constants/values.dart';
+import '../../elements/entities.dart';
+import '../../elements/names.dart';
+import '../../elements/types.dart';
+import '../../ir/class_relation.dart';
+import '../../serialization/serialization.dart';
+import '../../universe/class_hierarchy.dart';
+import '../../universe/selector.dart' show Selector;
+import '../../universe/use.dart' show DynamicUse;
+import '../../universe/world_builder.dart'
+    show UniverseSelectorConstraints, SelectorConstraintsStrategy;
+import '../../util/util.dart';
+import '../../world_interfaces.dart' show JClosedWorld;
+import '../../inferrer/abstract_value_domain.dart';
+import '../../inferrer/abstract_value_strategy.dart';
+import 'constants.dart';
+
+part 'container_type_mask.dart';
+part 'dictionary_type_mask.dart';
+part 'flat_type_mask.dart';
+part 'forwarding_type_mask.dart';
+part 'map_type_mask.dart';
+part 'set_type_mask.dart';
+part 'type_mask.dart';
+part 'union_type_mask.dart';
+part 'value_type_mask.dart';
+
+class CommonMasks implements AbstractValueDomain {
+  // TODO(sigmund): once we split out the backend common elements, depend
+  // directly on those instead.
+  final JClosedWorld _closedWorld;
+
+  CommonMasks(this._closedWorld);
+
+  CommonElements get commonElements => _closedWorld.commonElements;
+  DartTypes get dartTypes => _closedWorld.dartTypes;
+
+  /// Cache of [FlatTypeMask]s grouped by the possible values of the
+  /// `FlatTypeMask.flags` property.
+  final List<Map<ClassEntity, TypeMask>?> _canonicalizedTypeMasks = List.filled(
+      _FlatTypeMaskKind.values.length << FlatTypeMask._USED_INDICES, null);
+
+  /// Return the cached mask for [base] with the given flags, or
+  /// calls [createMask] to create the mask and cache it.
+  T getCachedMask<T extends TypeMask>(
+      ClassEntity? base, int flags, T createMask()) {
+    // `null` is a valid base so we allow it as a key in the map.
+    final Map<ClassEntity?, TypeMask> cachedMasks =
+        _canonicalizedTypeMasks[flags] ??= {};
+    return cachedMasks.putIfAbsent(base, createMask) as T;
+  }
+
+  @override
+  late final TypeMask internalTopType = TypeMask.subclass(
+      _closedWorld.commonElements.objectClass, _closedWorld,
+      hasLateSentinel: true);
+
+  @override
+  late final TypeMask dynamicType =
+      TypeMask.subclass(_closedWorld.commonElements.objectClass, _closedWorld);
+
+  @override
+  late final TypeMask nonNullType = TypeMask.nonNullSubclass(
+      _closedWorld.commonElements.objectClass, _closedWorld);
+
+  @override
+  late final TypeMask intType =
+      TypeMask.nonNullSubclass(commonElements.jsIntClass, _closedWorld);
+
+  @override
+  late final TypeMask uint32Type =
+      TypeMask.nonNullSubclass(commonElements.jsUInt32Class, _closedWorld);
+
+  @override
+  late final TypeMask uint31Type =
+      TypeMask.nonNullExact(commonElements.jsUInt31Class, _closedWorld);
+
+  @override
+  late final TypeMask positiveIntType =
+      TypeMask.nonNullSubclass(commonElements.jsPositiveIntClass, _closedWorld);
+
+  @override
+  late final TypeMask numNotIntType =
+      TypeMask.nonNullExact(commonElements.jsNumNotIntClass, _closedWorld);
+
+  @override
+  late final TypeMask numType =
+      TypeMask.nonNullSubclass(commonElements.jsNumberClass, _closedWorld);
+
+  @override
+  late final TypeMask boolType =
+      TypeMask.nonNullExact(commonElements.jsBoolClass, _closedWorld);
+
+  @override
+  late final TypeMask functionType =
+      TypeMask.nonNullSubtype(commonElements.functionClass, _closedWorld);
+
+  @override
+  late final TypeMask listType =
+      TypeMask.nonNullSubtype(commonElements.jsArrayClass, _closedWorld);
+
+  @override
+  late final TypeMask constListType = TypeMask.nonNullExact(
+      commonElements.jsUnmodifiableArrayClass, _closedWorld);
+
+  @override
+  late final TypeMask fixedListType =
+      TypeMask.nonNullExact(commonElements.jsFixedArrayClass, _closedWorld);
+
+  @override
+  late final TypeMask growableListType = TypeMask.nonNullExact(
+      commonElements.jsExtendableArrayClass, _closedWorld);
+
+  @override
+  late final TypeMask setType =
+      TypeMask.nonNullSubtype(commonElements.setLiteralClass, _closedWorld);
+
+  @override
+  late final TypeMask constSetType = TypeMask.nonNullSubtype(
+      commonElements.constSetLiteralClass, _closedWorld);
+
+  @override
+  late final TypeMask mapType =
+      TypeMask.nonNullSubtype(commonElements.mapLiteralClass, _closedWorld);
+
+  @override
+  late final TypeMask constMapType = TypeMask.nonNullSubtype(
+      commonElements.constMapLiteralClass, _closedWorld);
+
+  @override
+  late final TypeMask stringType =
+      TypeMask.nonNullExact(commonElements.jsStringClass, _closedWorld);
+
+  @override
+  late final TypeMask typeType =
+      TypeMask.nonNullExact(commonElements.typeLiteralClass, _closedWorld);
+
+  @override
+  late final TypeMask syncStarIterableType =
+      TypeMask.nonNullExact(commonElements.syncStarIterable, _closedWorld);
+
+  @override
+  late final TypeMask asyncFutureType =
+      TypeMask.nonNullExact(commonElements.futureImplementation, _closedWorld);
+
+  @override
+  late final TypeMask asyncStarStreamType =
+      TypeMask.nonNullExact(commonElements.controllerStream, _closedWorld);
+
+  // TODO(johnniwinther): Assert that the null type has been resolved.
+  @override
+  late final TypeMask nullType = TypeMask.empty();
+
+  @override
+  TypeMask get lateSentinelType => TypeMask.nonNullEmpty(hasLateSentinel: true);
+
+  @override
+  TypeMask get emptyType => TypeMask.nonNullEmpty();
+
+  late final TypeMask indexablePrimitiveType =
+      TypeMask.nonNullSubtype(commonElements.jsIndexableClass, _closedWorld);
+
+  late final TypeMask readableArrayType =
+      TypeMask.nonNullSubclass(commonElements.jsArrayClass, _closedWorld);
+
+  @override
+  late final TypeMask mutableArrayType = TypeMask.nonNullSubclass(
+      commonElements.jsMutableArrayClass, _closedWorld);
+
+  late final TypeMask unmodifiableArrayType = TypeMask.nonNullExact(
+      commonElements.jsUnmodifiableArrayClass, _closedWorld);
+
+  late final TypeMask interceptorType =
+      TypeMask.nonNullSubclass(commonElements.jsInterceptorClass, _closedWorld);
+
+  @override
+  AbstractBool isTypedArray(TypeMask mask) {
+    // Just checking for `TypedData` is not sufficient, as it is an abstract
+    // class any user-defined class can implement. So we also check for the
+    // interface `JavaScriptIndexingBehavior`.
+    ClassEntity typedDataClass = _closedWorld.commonElements.typedDataClass;
+    return AbstractBool.trueOrMaybe(
+        _closedWorld.classHierarchy.isInstantiated(typedDataClass) &&
+            mask.satisfies(typedDataClass, _closedWorld) &&
+            mask.satisfies(
+                _closedWorld.commonElements.jsIndexingBehaviorInterface,
+                _closedWorld));
+  }
+
+  @override
+  AbstractBool couldBeTypedArray(TypeMask mask) {
+    bool intersects(TypeMask type1, TypeMask type2) =>
+        !type1.intersection(type2, this).isEmpty;
+    // TODO(herhut): Maybe cache the TypeMask for typedDataClass and
+    //               jsIndexingBehaviourInterface.
+    ClassEntity typedDataClass = _closedWorld.commonElements.typedDataClass;
+    return AbstractBool.maybeOrFalse(
+        _closedWorld.classHierarchy.isInstantiated(typedDataClass) &&
+            intersects(mask, TypeMask.subtype(typedDataClass, _closedWorld)) &&
+            intersects(
+                mask,
+                TypeMask.subtype(
+                    _closedWorld.commonElements.jsIndexingBehaviorInterface,
+                    _closedWorld)));
+  }
+
+  @override
+  TypeMask createNonNullExact(ClassEntity cls) {
+    return TypeMask.nonNullExact(cls, _closedWorld);
+  }
+
+  @override
+  TypeMask createNullableExact(ClassEntity cls) {
+    return TypeMask.exact(cls, _closedWorld);
+  }
+
+  @override
+  TypeMask createNonNullSubclass(ClassEntity cls) {
+    return TypeMask.nonNullSubclass(cls, _closedWorld);
+  }
+
+  @override
+  TypeMask createNonNullSubtype(ClassEntity cls) {
+    return TypeMask.nonNullSubtype(cls, _closedWorld);
+  }
+
+  @override
+  TypeMask createNullableSubtype(ClassEntity cls) {
+    return TypeMask.subtype(cls, _closedWorld);
+  }
+
+  @override
+  AbstractValueWithPrecision createFromStaticType(DartType type,
+      {ClassRelation classRelation = ClassRelation.subtype,
+      required bool nullable}) {
+    if ((classRelation == ClassRelation.subtype ||
+            classRelation == ClassRelation.thisExpression) &&
+        dartTypes.isTopType(type)) {
+      // A cone of a top type includes all values.
+      return AbstractValueWithPrecision(dynamicType, true);
+    }
+
+    if (type is NullableType) {
+      return _createFromStaticType(type.baseType, classRelation, true);
+    }
+
+    if (type is LegacyType) {
+      DartType baseType = type.baseType;
+      if (baseType is NeverType) {
+        // Never* is same as Null, for both 'is' and 'as'.
+        return AbstractValueWithPrecision(nullType, true);
+      }
+
+      // Object* is a top type for both 'is' and 'as'. This is handled in the
+      // 'cone of top type' case above.
+
+      return _createFromStaticType(baseType, classRelation, nullable);
+    }
+
+    if (dartTypes.useLegacySubtyping) {
+      // In legacy and weak mode, `String` is nullable depending on context.
+      return _createFromStaticType(type, classRelation, nullable);
+    } else {
+      // In strong mode nullability comes from explicit NullableType.
+      return _createFromStaticType(type, classRelation, false);
+    }
+  }
+
+  AbstractValueWithPrecision _createFromStaticType(
+      DartType type, ClassRelation classRelation, bool nullable) {
+    AbstractValueWithPrecision finish(TypeMask value, bool isPrecise) {
+      return AbstractValueWithPrecision(
+          nullable ? value.nullable() : value, isPrecise);
+    }
+
+    bool isPrecise = true;
+    while (type is TypeVariableType) {
+      TypeVariableType typeVariable = type;
+      type = _closedWorld.elementEnvironment
+          .getTypeVariableBound(typeVariable.element);
+      classRelation = ClassRelation.subtype;
+      isPrecise = false;
+      if (type is NullableType) {
+        // <A extends B?, B extends num>  ...  null is A --> can be `true`.
+        // <A extends B, B extends num?>  ...  null is A --> can be `true`.
+        nullable = true;
+        type = type.withoutNullability;
+      }
+    }
+
+    if ((classRelation == ClassRelation.thisExpression ||
+            classRelation == ClassRelation.subtype) &&
+        dartTypes.isTopType(type)) {
+      // A cone of a top type includes all values. Since we already tested this
+      // in [createFromStaticType], we get here only for type parameter bounds.
+      return AbstractValueWithPrecision(dynamicType, isPrecise);
+    }
+
+    if (type is InterfaceType) {
+      ClassEntity cls = type.element;
+      List<DartType> arguments = type.typeArguments;
+      if (isPrecise && arguments.isNotEmpty) {
+        // Can we ignore the type arguments?
+        //
+        // For legacy covariance, if the interface type is a generic interface
+        // type and is maximal (i.e. instantiated to bounds), the typemask,
+        // which is based on the class element, is still precise. We check
+        // against Top for the parameter arguments since we don't have a
+        // convenient check for instantiation to bounds.
+        //
+        // TODO(sra): Check arguments against bounds.
+        // TODO(sra): Handle other variances.
+        List<Variance> variances = dartTypes.getTypeVariableVariances(cls);
+        for (int i = 0; i < arguments.length; i++) {
+          Variance variance = variances[i];
+          DartType argument = arguments[i];
+          if (variance == Variance.legacyCovariant &&
+              dartTypes.isTopType(argument)) {
+            continue;
+          }
+          isPrecise = false;
+        }
+      }
+      switch (classRelation) {
+        case ClassRelation.exact:
+          return finish(TypeMask.nonNullExact(cls, _closedWorld), isPrecise);
+        case ClassRelation.thisExpression:
+          if (!_closedWorld.isUsedAsMixin(cls)) {
+            return finish(
+                TypeMask.nonNullSubclass(cls, _closedWorld), isPrecise);
+          }
+          break;
+        case ClassRelation.subtype:
+          break;
+      }
+      return finish(TypeMask.nonNullSubtype(cls, _closedWorld), isPrecise);
+    }
+
+    if (type is FunctionType) {
+      return finish(
+          TypeMask.nonNullSubtype(commonElements.functionClass, _closedWorld),
+          false);
+    }
+
+    if (type is NeverType) {
+      return finish(emptyType, isPrecise);
+    }
+
+    return AbstractValueWithPrecision(dynamicType, false);
+  }
+
+  @override
+  TypeMask excludeNull(TypeMask mask) => mask.nonNullable();
+
+  @override
+  TypeMask includeNull(TypeMask mask) => mask.nullable();
+
+  @override
+  TypeMask excludeLateSentinel(TypeMask mask) =>
+      mask.withFlags(hasLateSentinel: false);
+
+  @override
+  TypeMask includeLateSentinel(TypeMask mask) =>
+      mask.withFlags(hasLateSentinel: true);
+
+  @override
+  AbstractBool containsType(TypeMask typeMask, ClassEntity cls) {
+    return AbstractBool.trueOrFalse(_containsType(typeMask, cls));
+  }
+
+  bool _containsType(TypeMask typeMask, ClassEntity cls) {
+    return _closedWorld.classHierarchy.isInstantiated(cls) &&
+        typeMask.contains(cls, _closedWorld);
+  }
+
+  @override
+  AbstractBool containsOnlyType(TypeMask typeMask, ClassEntity cls) {
+    return AbstractBool.trueOrMaybe(_containsOnlyType(typeMask, cls));
+  }
+
+  bool _containsOnlyType(TypeMask typeMask, ClassEntity cls) {
+    return _closedWorld.classHierarchy.isInstantiated(cls) &&
+        typeMask.containsOnly(cls);
+  }
+
+  @override
+  AbstractBool isInstanceOfOrNull(TypeMask typeMask, ClassEntity cls) =>
+      AbstractBool.trueOrMaybe(_isInstanceOfOrNull(typeMask, cls));
+
+  bool _isInstanceOfOrNull(TypeMask typeMask, ClassEntity cls) {
+    return _closedWorld.isImplemented(cls) &&
+        typeMask.satisfies(cls, _closedWorld);
+  }
+
+  @override
+  AbstractBool isInstanceOf(
+      covariant TypeMask expressionMask, ClassEntity cls) {
+    final typeMask = (cls == commonElements.nullClass)
+        ? nullType
+        : createNonNullSubtype(cls);
+    if (expressionMask.union(typeMask, this) == typeMask) {
+      return AbstractBool.True;
+    } else if (expressionMask.isDisjoint(typeMask, _closedWorld)) {
+      return AbstractBool.False;
+    } else {
+      return AbstractBool.Maybe;
+    }
+  }
+
+  @override
+  AbstractBool isEmpty(TypeMask value) =>
+      AbstractBool.trueOrMaybe(value.isEmpty);
+
+  @override
+  AbstractBool isExact(TypeMask value) => AbstractBool.trueOrMaybe(
+      value.isExact && !value.isNullable && !value.hasLateSentinel);
+
+  @override
+  ClassEntity? getExactClass(TypeMask mask) {
+    return mask.singleClass(_closedWorld);
+  }
+
+  @override
+  bool isPrimitiveValue(TypeMask value) => value is ValueTypeMask;
+
+  @override
+  PrimitiveConstantValue? getPrimitiveValue(TypeMask mask) {
+    if (mask is ValueTypeMask) {
+      return mask.value;
+    }
+    return null;
+  }
+
+  @override
+  AbstractValue createPrimitiveValue(
+      covariant TypeMask originalValue, PrimitiveConstantValue value) {
+    return ValueTypeMask(originalValue, value);
+  }
+
+  @override
+  AbstractBool isNull(TypeMask value) {
+    if (value.isNull) {
+      return AbstractBool.True;
+    } else if (value.isNullable) {
+      return AbstractBool.Maybe;
+    } else {
+      return AbstractBool.False;
+    }
+  }
+
+  @override
+  AbstractBool isLateSentinel(TypeMask value) => value.isLateSentinel;
+
+  @override
+  AbstractBool isPrimitive(TypeMask value) {
+    return AbstractBool.maybeOrFalse(_canBePrimitiveNumber(value) ||
+        _canBePrimitiveArray(value) ||
+        _canBePrimitiveBoolean(value) ||
+        _canBePrimitiveString(value) ||
+        value.isNull);
+  }
+
+  @override
+  AbstractBool isPrimitiveNumber(TypeMask value) =>
+      AbstractBool.maybeOrFalse(_canBePrimitiveNumber(value));
+
+  bool _canBePrimitiveNumber(TypeMask value) {
+    // TODO(sra): It should be possible to test only jsNumNotIntClass and
+    // jsUInt31Class, since all others are superclasses of these two.
+    return _containsType(value, commonElements.jsNumberClass) ||
+        _containsType(value, commonElements.jsIntClass) ||
+        _containsType(value, commonElements.jsPositiveIntClass) ||
+        _containsType(value, commonElements.jsUInt32Class) ||
+        _containsType(value, commonElements.jsUInt31Class) ||
+        _containsType(value, commonElements.jsNumNotIntClass);
+  }
+
+  @override
+  AbstractBool isPrimitiveBoolean(TypeMask value) =>
+      AbstractBool.maybeOrFalse(_canBePrimitiveBoolean(value));
+
+  bool _canBePrimitiveBoolean(TypeMask value) {
+    return _containsType(value, commonElements.jsBoolClass);
+  }
+
+  bool _canBePrimitiveArray(TypeMask value) {
+    return _containsType(value, commonElements.jsArrayClass) ||
+        _containsType(value, commonElements.jsFixedArrayClass) ||
+        _containsType(value, commonElements.jsExtendableArrayClass) ||
+        _containsType(value, commonElements.jsUnmodifiableArrayClass);
+  }
+
+  @override
+  AbstractBool isIndexablePrimitive(TypeMask value) =>
+      AbstractBool.trueOrMaybe(_isIndexablePrimitive(value));
+
+  bool _isIndexablePrimitive(TypeMask value) {
+    return value.containsOnlyString(_closedWorld) ||
+        _isInstanceOfOrNull(value, commonElements.jsIndexableClass);
+  }
+
+  @override
+  AbstractBool isFixedArray(TypeMask value) {
+    // TODO(sra): Recognize the union of these types as well.
+    return AbstractBool.trueOrMaybe(
+        _containsOnlyType(value, commonElements.jsFixedArrayClass) ||
+            _containsOnlyType(value, commonElements.jsUnmodifiableArrayClass));
+  }
+
+  @override
+  AbstractBool isExtendableArray(TypeMask value) {
+    return AbstractBool.trueOrMaybe(
+        _containsOnlyType(value, commonElements.jsExtendableArrayClass));
+  }
+
+  @override
+  AbstractBool isMutableArray(TypeMask value) {
+    return AbstractBool.trueOrMaybe(
+        _isInstanceOfOrNull(value, commonElements.jsMutableArrayClass));
+  }
+
+  @override
+  AbstractBool isMutableIndexable(TypeMask value) {
+    return AbstractBool.trueOrMaybe(
+        _isInstanceOfOrNull(value, commonElements.jsMutableIndexableClass));
+  }
+
+  @override
+  AbstractBool isArray(TypeMask value) {
+    return AbstractBool.trueOrMaybe(
+        _isInstanceOfOrNull(value, commonElements.jsArrayClass));
+  }
+
+  @override
+  AbstractBool isPrimitiveString(TypeMask value) =>
+      AbstractBool.maybeOrFalse(_canBePrimitiveString(value));
+
+  bool _canBePrimitiveString(TypeMask value) {
+    return _containsType(value, commonElements.jsStringClass);
+  }
+
+  @override
+  AbstractBool isInteger(TypeMask value) {
+    return AbstractBool.trueOrMaybe(value.containsOnlyInt(_closedWorld) &&
+        !value.isNullable &&
+        !value.hasLateSentinel);
+  }
+
+  @override
+  AbstractBool isUInt32(TypeMask value) {
+    return AbstractBool.trueOrMaybe(!value.isNullable &&
+        !value.hasLateSentinel &&
+        _isInstanceOfOrNull(value, commonElements.jsUInt32Class));
+  }
+
+  @override
+  AbstractBool isUInt31(TypeMask value) {
+    return AbstractBool.trueOrMaybe(!value.isNullable &&
+        !value.hasLateSentinel &&
+        _isInstanceOfOrNull(value, commonElements.jsUInt31Class));
+  }
+
+  @override
+  AbstractBool isPositiveInteger(TypeMask value) {
+    return AbstractBool.trueOrMaybe(!value.isNullable &&
+        !value.hasLateSentinel &&
+        _isInstanceOfOrNull(value, commonElements.jsPositiveIntClass));
+  }
+
+  @override
+  AbstractBool isPositiveIntegerOrNull(TypeMask value) {
+    return AbstractBool.trueOrMaybe(
+        _isInstanceOfOrNull(value, commonElements.jsPositiveIntClass));
+  }
+
+  @override
+  AbstractBool isIntegerOrNull(TypeMask value) {
+    return AbstractBool.trueOrMaybe(value.containsOnlyInt(_closedWorld));
+  }
+
+  @override
+  AbstractBool isNumber(TypeMask value) {
+    return AbstractBool.trueOrMaybe(value.containsOnlyNum(_closedWorld) &&
+        !value.isNullable &&
+        !value.hasLateSentinel);
+  }
+
+  @override
+  AbstractBool isNumberOrNull(TypeMask value) =>
+      AbstractBool.trueOrMaybe(_isNumberOrNull(value));
+
+  bool _isNumberOrNull(TypeMask value) {
+    return value.containsOnlyNum(_closedWorld);
+  }
+
+  @override
+  AbstractBool isBoolean(TypeMask value) {
+    return AbstractBool.trueOrMaybe(value.containsOnlyBool(_closedWorld) &&
+        !value.isNullable &&
+        !value.hasLateSentinel);
+  }
+
+  @override
+  AbstractBool isBooleanOrNull(TypeMask value) =>
+      AbstractBool.trueOrMaybe(_isBooleanOrNull(value));
+
+  bool _isBooleanOrNull(TypeMask value) {
+    return value.containsOnlyBool(_closedWorld);
+  }
+
+  @override
+  AbstractBool isTruthy(TypeMask value) {
+    if (value is ValueTypeMask && !value.isNullable && !value.hasLateSentinel) {
+      PrimitiveConstantValue constant = value.value;
+      if (constant is BoolConstantValue) {
+        return constant.boolValue ? AbstractBool.True : AbstractBool.False;
+      }
+    }
+    // TODO(sra): Non-intercepted types are generally JavaScript falsy values.
+    return AbstractBool.Maybe;
+  }
+
+  @override
+  AbstractBool isString(TypeMask value) {
+    return AbstractBool.trueOrMaybe(value.containsOnlyString(_closedWorld) &&
+        !value.isNullable &&
+        !value.hasLateSentinel);
+  }
+
+  @override
+  AbstractBool isStringOrNull(TypeMask value) {
+    return AbstractBool.trueOrMaybe(value.containsOnlyString(_closedWorld));
+  }
+
+  @override
+  AbstractBool isPrimitiveOrNull(TypeMask value) =>
+      AbstractBool.trueOrMaybe(_isPrimitiveOrNull(value));
+
+  bool _isPrimitiveOrNull(TypeMask value) {
+    return _isIndexablePrimitive(value) ||
+        _isNumberOrNull(value) ||
+        _isBooleanOrNull(value) ||
+        value.isNull;
+  }
+
+  @override
+  TypeMask union(TypeMask a, TypeMask b) => a.union(b, this);
+
+  @override
+  TypeMask intersection(TypeMask a, TypeMask b) => a.intersection(b, this);
+
+  @override
+  AbstractBool areDisjoint(TypeMask a, TypeMask b) =>
+      AbstractBool.trueOrMaybe(a.isDisjoint(b, _closedWorld));
+
+  @override
+  AbstractBool containsAll(TypeMask a) =>
+      AbstractBool.maybeOrFalse(a.containsAll(_closedWorld));
+
+  @override
+  AbstractValue computeAbstractValueForConstant(ConstantValue value) {
+    return computeTypeMask(this, _closedWorld, value);
+  }
+
+  @override
+  AbstractValue getMapKeyType(AbstractValue value) {
+    if (value is MapTypeMask) {
+      return value.keyType;
+    }
+    return dynamicType;
+  }
+
+  @override
+  AbstractValue getMapValueType(AbstractValue value) {
+    return value is MapTypeMask ? value.valueType : dynamicType;
+  }
+
+  @override
+  AbstractValue getContainerElementType(AbstractValue value) {
+    return value is ContainerTypeMask ? value.elementType : dynamicType;
+  }
+
+  @override
+  int? getContainerLength(AbstractValue value) {
+    return value is ContainerTypeMask ? value.length : null;
+  }
+
+  @override
+  AbstractValue createContainerValue(
+      covariant TypeMask forwardTo,
+      covariant ir.Node? allocationNode,
+      MemberEntity? allocationElement,
+      covariant TypeMask elementType,
+      int? length) {
+    return ContainerTypeMask(
+        forwardTo, allocationNode, allocationElement, elementType, length);
+  }
+
+  @override
+  AbstractValue unionOfMany(Iterable<AbstractValue> values) {
+    var result = TypeMask.nonNullEmpty();
+    for (final value in values) {
+      result = result.union(value as TypeMask, this);
+    }
+    return result;
+  }
+
+  @override
+  AbstractValue computeReceiver(Iterable<MemberEntity> members) {
+    assert(_closedWorld.classHierarchy
+        .hasAnyStrictSubclass(_closedWorld.commonElements.objectClass));
+    return TypeMask.unionOf(
+        members.expand((MemberEntity element) {
+          final cls = element.enclosingClass!;
+          return [cls]..addAll(_closedWorld.mixinUsesOf(cls));
+        }).map((cls) {
+          if (_closedWorld.commonElements.jsNullClass == cls) {
+            return TypeMask.empty();
+          } else if (_closedWorld.classHierarchy.isInstantiated(cls)) {
+            return TypeMask.nonNullSubclass(cls, _closedWorld);
+          } else {
+            // TODO(johnniwinther): Avoid the need for this case.
+            return TypeMask.empty();
+          }
+        }),
+        this);
+  }
+
+  @override
+  AbstractBool isTargetingMember(
+      covariant TypeMask receiver, MemberEntity member, Name name) {
+    return AbstractBool.maybeOrFalse(
+        receiver.canHit(member, name, _closedWorld));
+  }
+
+  @override
+  AbstractBool needsNoSuchMethodHandling(
+      covariant TypeMask receiver, Selector selector) {
+    return AbstractBool.trueOrFalse(
+        receiver.needsNoSuchMethodHandling(selector, _closedWorld));
+  }
+
+  @override
+  AbstractBool isIn(covariant TypeMask subset, covariant TypeMask superset) {
+    return AbstractBool.trueOrMaybe(subset.isInMask(superset, _closedWorld));
+  }
+
+  @override
+  MemberEntity? locateSingleMember(
+      covariant TypeMask receiver, Selector selector) {
+    return receiver.locateSingleMember(selector, this);
+  }
+
+  @override
+  AbstractBool isJsIndexable(TypeMask mask) {
+    return AbstractBool.trueOrMaybe(mask.satisfies(
+        _closedWorld.commonElements.jsIndexableClass, _closedWorld));
+  }
+
+  @override
+  AbstractBool isJsIndexableAndIterable(covariant TypeMask mask) {
+    return AbstractBool.trueOrMaybe(mask.satisfies(
+            _closedWorld.commonElements.jsIndexableClass, _closedWorld) &&
+        // String is indexable but not iterable.
+        !mask.satisfies(
+            _closedWorld.commonElements.jsStringClass, _closedWorld));
+  }
+
+  @override
+  AbstractBool isFixedLengthJsIndexable(covariant TypeMask mask) {
+    if (mask is ContainerTypeMask && mask.length != null) {
+      // A container on which we have inferred the length.
+      return AbstractBool.True;
+    }
+    // TODO(sra): Recognize any combination of fixed length indexables.
+    if (mask.containsOnly(_closedWorld.commonElements.jsFixedArrayClass) ||
+        mask.containsOnly(
+            _closedWorld.commonElements.jsUnmodifiableArrayClass) ||
+        mask.containsOnlyString(_closedWorld) ||
+        isTypedArray(mask).isDefinitelyTrue) {
+      return AbstractBool.True;
+    }
+    return AbstractBool.Maybe;
+  }
+
+  @override
+  AbstractBool isInterceptor(TypeMask value) {
+    // TODO(39874): Remove cache when [TypeMask.isDisjoint] is faster.
+    var result = _isInterceptorCache[value];
+    if (result == null) {
+      result = _isInterceptorCacheSecondChance[value] ?? _isInterceptor(value);
+      if (_isInterceptorCache.length >= _kIsInterceptorCacheLimit) {
+        _isInterceptorCacheSecondChance = _isInterceptorCache;
+        _isInterceptorCache = {};
+      }
+      _isInterceptorCache[value] = result;
+    }
+    return result;
+  }
+
+  AbstractBool _isInterceptor(TypeMask value) {
+    return AbstractBool.maybeOrFalse(
+        !interceptorType.isDisjoint(value, _closedWorld));
+  }
+
+  static const _kIsInterceptorCacheLimit = 500;
+  Map<TypeMask, AbstractBool> _isInterceptorCache = {};
+  Map<TypeMask, AbstractBool> _isInterceptorCacheSecondChance = {};
+
+  @override
+  bool isMap(TypeMask value) => value is MapTypeMask;
+
+  @override
+  bool isSet(TypeMask value) => value is SetTypeMask;
+
+  @override
+  bool isContainer(TypeMask value) => value is ContainerTypeMask;
+
+  @override
+  bool isDictionary(TypeMask value) => value is DictionaryTypeMask;
+
+  @override
+  bool containsDictionaryKey(AbstractValue value, String key) {
+    return value is DictionaryTypeMask && value.containsKey(key);
+  }
+
+  @override
+  AbstractValue getDictionaryValueForKey(AbstractValue value, String key) {
+    final result =
+        value is DictionaryTypeMask ? value.getValueForKey(key) : null;
+    return result ?? dynamicType;
+  }
+
+  @override
+  AbstractValue createMapValue(
+      covariant TypeMask forwardTo,
+      covariant ir.Node? allocationNode,
+      MemberEntity? allocationElement,
+      covariant TypeMask key,
+      covariant TypeMask value) {
+    return MapTypeMask(
+        forwardTo, allocationNode, allocationElement, key, value);
+  }
+
+  @override
+  AbstractValue createDictionaryValue(
+      covariant TypeMask forwardTo,
+      covariant ir.Node? allocationNode,
+      MemberEntity? allocationElement,
+      covariant TypeMask key,
+      covariant TypeMask value,
+      Map<String, AbstractValue> mappings) {
+    return DictionaryTypeMask(forwardTo, allocationNode, allocationElement, key,
+        value, Map.from(mappings));
+  }
+
+  @override
+  AbstractValue createSetValue(
+      covariant TypeMask forwardTo,
+      covariant ir.Node? allocationNode,
+      MemberEntity? allocationElement,
+      covariant TypeMask elementType) {
+    return SetTypeMask(
+        forwardTo, allocationNode, allocationElement, elementType);
+  }
+
+  @override
+  AbstractValue getSetElementType(AbstractValue value) {
+    final result = value is SetTypeMask ? value.elementType : null;
+    return result ?? dynamicType;
+  }
+
+  @override
+  bool isSpecializationOf(
+      AbstractValue specialization, AbstractValue generalization) {
+    return specialization is ForwardingTypeMask &&
+        specialization.forwardTo == generalization;
+  }
+
+  @override
+  Object? getAllocationNode(AbstractValue value) {
+    return value is AllocationTypeMask ? value.allocationNode : null;
+  }
+
+  @override
+  MemberEntity? getAllocationElement(AbstractValue value) {
+    return value is AllocationTypeMask ? value.allocationElement : null;
+  }
+
+  @override
+  AbstractValue? getGeneralization(AbstractValue? value) {
+    return value is AllocationTypeMask ? value.forwardTo : null;
+  }
+
+  @override
+  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) {
+    if (type is InterfaceType) {
+      if (type.typeArguments.isNotEmpty) return null;
+      // TODO(sra): Consider using a strengthened type check to avoid passing
+      // `null` to primitive types since the native methods usually have
+      // non-nullable primitive parameter types.
+      return createNullableSubtype(type.element);
+    }
+    if (type is DynamicType) return dynamicType;
+    // TODO(sra): Convert other [DartType]s to [AbstractValue]s
+    return null;
+  }
+
+  @override
+  String getCompactText(covariant TypeMask value) {
+    return formatType(dartTypes, value);
+  }
+
+  @override
+  TypeMask readAbstractValueFromDataSource(DataSourceReader source) {
+    return source
+        .readCached<TypeMask>(() => TypeMask.readFromDataSource(source, this));
+  }
+
+  @override
+  void writeAbstractValueToDataSink(
+      DataSinkWriter sink, covariant TypeMask value) {
+    sink.writeCached<TypeMask>(
+        value, (TypeMask value) => value.writeToDataSink(sink));
+  }
+}
+
+/// Convert the given TypeMask to a compact string format.
+///
+/// The default format is too verbose for the graph format since long strings
+/// create oblong nodes that obstruct the graph layout.
+String formatType(DartTypes dartTypes, TypeMask type) {
+  if (type is FlatTypeMask) {
+    // TODO(asgerf): Disambiguate classes whose name is not unique. Using the
+    //     library name for all classes is not a good idea, since library names
+    //     can be really long and mess up the layout.
+    // Capitalize Null to emphasize that it's the null type mask and not
+    // a null value we accidentally printed out.
+    if (type.isEmpty) return 'Empty';
+    if (type.isEmptyOrFlagged) {
+      return [
+        if (type.isNullable) 'Null',
+        if (type.hasLateSentinel) '\$',
+      ].join('');
+    }
+    String nullFlag = type.isNullable ? '?' : '';
+    String subFlag = type.isExact
+        ? ''
+        : type.isSubclass
+            ? '+'
+            : '*';
+    String sentinelFlag = type.hasLateSentinel ? '\$' : '';
+    return '${type.base!.name}$nullFlag$subFlag$sentinelFlag';
+  }
+  if (type is UnionTypeMask) {
+    return type.disjointMasks.map((m) => formatType(dartTypes, m)).join(' | ');
+  }
+  if (type is ContainerTypeMask) {
+    String container = formatType(dartTypes, type.forwardTo);
+    String member = formatType(dartTypes, type.elementType);
+    return '$container<$member>';
+  }
+  if (type is MapTypeMask) {
+    String container = formatType(dartTypes, type.forwardTo);
+    String key = formatType(dartTypes, type.keyType);
+    String value = formatType(dartTypes, type.valueType);
+    return '$container<$key,$value>';
+  }
+  if (type is ValueTypeMask) {
+    String baseType = formatType(dartTypes, type.forwardTo);
+    String value = type.value.toStructuredText(dartTypes);
+    return '$baseType=$value';
+  }
+  return '$type'; // Fall back on toString if not supported here.
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/set_type_mask.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/set_type_mask.dart
new file mode 100644
index 0000000..905d817
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/set_type_mask.dart
@@ -0,0 +1,95 @@
+// 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.
+
+part of masks;
+
+/// A [SetTypeMask] is a [TypeMask] for a specific allocation site of a set
+/// (currently only the internal Set class) that will get specialized once the
+/// [TypeGraphInferrer] phase finds an element type for it.
+class SetTypeMask extends AllocationTypeMask {
+  /// Tag used for identifying serialized [SetTypeMask] objects in a debugging
+  /// data stream.
+  static const String tag = 'set-type-mask';
+
+  @override
+  final TypeMask forwardTo;
+
+  final ir.Node? _allocationNode;
+  @override
+  ir.Node? get allocationNode => _allocationNode;
+
+  @override
+  final MemberEntity? allocationElement;
+
+  // The element type of this set.
+  final TypeMask elementType;
+
+  const SetTypeMask(this.forwardTo, this._allocationNode,
+      this.allocationElement, this.elementType);
+
+  /// Deserializes a [SetTypeMask] object from [source].
+  factory SetTypeMask.readFromDataSource(
+      DataSourceReader source, CommonMasks domain) {
+    source.begin(tag);
+    final forwardTo = TypeMask.readFromDataSource(source, domain);
+    final allocationElement = source.readMemberOrNull();
+    final elementType = TypeMask.readFromDataSource(source, domain);
+    source.end(tag);
+    return SetTypeMask(forwardTo, null, allocationElement, elementType);
+  }
+
+  /// Serializes this [SetTypeMask] to [sink].
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(TypeMaskKind.set);
+    sink.begin(tag);
+    forwardTo.writeToDataSink(sink);
+    sink.writeMemberOrNull(allocationElement);
+    elementType.writeToDataSink(sink);
+    sink.end(tag);
+  }
+
+  @override
+  SetTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
+    isNullable ??= this.isNullable;
+    hasLateSentinel ??= this.hasLateSentinel;
+    if (isNullable == this.isNullable &&
+        hasLateSentinel == this.hasLateSentinel) {
+      return this;
+    }
+    return SetTypeMask(
+        forwardTo.withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel),
+        allocationNode,
+        allocationElement,
+        elementType);
+  }
+
+  @override
+  bool get isExact => true;
+
+  @override
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+      {required bool isNullable, required bool hasLateSentinel}) {
+    if (other is SetTypeMask) {
+      TypeMask newElementType = elementType.union(other.elementType, domain);
+      TypeMask newForwardTo = forwardTo.union(other.forwardTo, domain);
+      return SetTypeMask(newForwardTo, null, null, newElementType);
+    }
+    return null;
+  }
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! SetTypeMask) return false;
+    return super == other && elementType == other.elementType;
+  }
+
+  @override
+  int get hashCode => Hashing.objectHash(elementType, super.hashCode);
+
+  @override
+  String toString() => 'Set($forwardTo, element: $elementType)';
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/type_mask.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/type_mask.dart
new file mode 100644
index 0000000..0d14836
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/type_mask.dart
@@ -0,0 +1,426 @@
+// Copyright (c) 2013, 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.
+
+part of masks;
+
+/// An implementation of a [UniverseSelectorConstraints] that is consists if an
+/// only increasing set of [TypeMask]s, that is, once a mask is added it cannot
+/// be removed.
+class IncreasingTypeMaskSet extends UniverseSelectorConstraints {
+  bool isAll = false;
+  Set<TypeMask>? _masks;
+
+  @override
+  bool canHit(MemberEntity element, Name name, JClosedWorld world) {
+    if (isAll) return true;
+    if (_masks == null) return false;
+    for (TypeMask mask in _masks!) {
+      if (mask.canHit(element, name, world)) return true;
+    }
+    return false;
+  }
+
+  @override
+  bool needsNoSuchMethodHandling(Selector selector, JClosedWorld world) {
+    if (isAll) {
+      TypeMask mask =
+          TypeMask.subclass(world.commonElements.objectClass, world);
+      return mask.needsNoSuchMethodHandling(selector, world);
+    }
+    for (TypeMask mask in _masks!) {
+      if (mask.needsNoSuchMethodHandling(selector, world)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool addReceiverConstraint(TypeMask? mask) {
+    if (isAll) return false;
+    if (mask == null) {
+      isAll = true;
+      _masks = null;
+      return true;
+    }
+    return (_masks ??= {}).add(mask);
+  }
+
+  @override
+  String toString() {
+    if (isAll) {
+      return '<all>';
+    } else if (_masks != null) {
+      return '$_masks';
+    } else {
+      return '<none>';
+    }
+  }
+}
+
+class TypeMaskStrategy implements AbstractValueStrategy {
+  const TypeMaskStrategy();
+
+  @override
+  AbstractValueDomain createDomain(JClosedWorld closedWorld) {
+    return CommonMasks(closedWorld);
+  }
+
+  @override
+  SelectorConstraintsStrategy createSelectorStrategy() {
+    return TypeMaskSelectorStrategy();
+  }
+}
+
+class TypeMaskSelectorStrategy implements SelectorConstraintsStrategy {
+  const TypeMaskSelectorStrategy();
+
+  @override
+  UniverseSelectorConstraints createSelectorConstraints(
+      Selector selector, covariant TypeMask? initialConstraint) {
+    return IncreasingTypeMaskSet()..addReceiverConstraint(initialConstraint);
+  }
+
+  @override
+  bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member,
+      covariant JClosedWorld world) {
+    Selector selector = dynamicUse.selector;
+    final mask = dynamicUse.receiverConstraint as TypeMask?;
+    return selector.appliesUnnamed(member) &&
+        (mask == null || mask.canHit(member, selector.memberName, world));
+  }
+}
+
+/// Enum used for identifying [TypeMask] subclasses in serialization.
+enum TypeMaskKind {
+  flat,
+  union,
+  container,
+  set,
+  map,
+  dictionary,
+  value,
+}
+
+/// A type mask represents a set of contained classes, but the
+/// operations on it are not guaranteed to be precise and they may
+/// yield conservative answers that contain too many classes.
+abstract class TypeMask implements AbstractValue {
+  const TypeMask();
+
+  factory TypeMask.empty({bool hasLateSentinel = false}) =>
+      FlatTypeMask.empty(hasLateSentinel: hasLateSentinel);
+
+  factory TypeMask.exact(ClassEntity base, JClosedWorld closedWorld,
+      {bool hasLateSentinel = false}) {
+    assert(
+        closedWorld.classHierarchy.isInstantiated(base),
+        failedAt(
+            base,
+            "Cannot create exact type mask for uninstantiated "
+            "class $base.\n${closedWorld.classHierarchy.dump(base)}"));
+    return FlatTypeMask.exact(base, closedWorld,
+        hasLateSentinel: hasLateSentinel);
+  }
+
+  factory TypeMask.exactOrEmpty(ClassEntity base, JClosedWorld closedWorld,
+      {bool hasLateSentinel = false}) {
+    if (closedWorld.classHierarchy.isInstantiated(base)) {
+      return FlatTypeMask.exact(base, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    }
+    return TypeMask.empty(hasLateSentinel: hasLateSentinel);
+  }
+
+  factory TypeMask.subclass(ClassEntity base, JClosedWorld closedWorld,
+      {bool hasLateSentinel = false}) {
+    assert(
+        closedWorld.classHierarchy.isInstantiated(base),
+        failedAt(
+            base,
+            "Cannot create subclass type mask for uninstantiated "
+            "class $base.\n${closedWorld.classHierarchy.dump(base)}"));
+    final topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
+    if (topmost == null) {
+      return TypeMask.empty(hasLateSentinel: hasLateSentinel);
+    } else if (closedWorld.classHierarchy.hasAnyStrictSubclass(topmost)) {
+      return FlatTypeMask.subclass(topmost, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    } else {
+      return TypeMask.exact(topmost, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    }
+  }
+
+  factory TypeMask.subtype(ClassEntity base, JClosedWorld closedWorld,
+      {bool hasLateSentinel = false}) {
+    final topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
+    if (topmost == null) {
+      return TypeMask.empty(hasLateSentinel: hasLateSentinel);
+    }
+    if (closedWorld.classHierarchy.hasOnlySubclasses(topmost)) {
+      return TypeMask.subclass(topmost, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    }
+    if (closedWorld.classHierarchy.hasAnyStrictSubtype(topmost)) {
+      return FlatTypeMask.subtype(topmost, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    } else {
+      return TypeMask.exact(topmost, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    }
+  }
+
+  factory TypeMask.nonNullEmpty({bool hasLateSentinel = false}) =>
+      FlatTypeMask.nonNullEmpty(hasLateSentinel: hasLateSentinel);
+
+  factory TypeMask.nonNullExact(ClassEntity base, JClosedWorld closedWorld,
+      {bool hasLateSentinel = false}) {
+    assert(
+        closedWorld.classHierarchy.isInstantiated(base),
+        failedAt(
+            base,
+            "Cannot create exact type mask for uninstantiated "
+            "class $base.\n${closedWorld.classHierarchy.dump(base)}"));
+    return FlatTypeMask.nonNullExact(base, closedWorld,
+        hasLateSentinel: hasLateSentinel);
+  }
+
+  factory TypeMask.nonNullExactOrEmpty(
+      ClassEntity base, JClosedWorld closedWorld,
+      {bool hasLateSentinel = false}) {
+    if (closedWorld.classHierarchy.isInstantiated(base)) {
+      return FlatTypeMask.nonNullExact(base, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    }
+    return TypeMask.nonNullEmpty(hasLateSentinel: hasLateSentinel);
+  }
+
+  factory TypeMask.nonNullSubclass(ClassEntity base, JClosedWorld closedWorld,
+      {bool hasLateSentinel = false}) {
+    assert(
+        closedWorld.classHierarchy.isInstantiated(base),
+        failedAt(
+            base,
+            "Cannot create subclass type mask for uninstantiated "
+            "class $base.\n${closedWorld.classHierarchy.dump(base)}"));
+    final topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
+    if (topmost == null) {
+      return TypeMask.nonNullEmpty(hasLateSentinel: hasLateSentinel);
+    } else if (closedWorld.classHierarchy.hasAnyStrictSubclass(topmost)) {
+      return FlatTypeMask.nonNullSubclass(topmost, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    } else {
+      return TypeMask.nonNullExact(topmost, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    }
+  }
+
+  factory TypeMask.nonNullSubtype(ClassEntity base, JClosedWorld closedWorld,
+      {bool hasLateSentinel = false}) {
+    final topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
+    if (topmost == null) {
+      return TypeMask.nonNullEmpty(hasLateSentinel: hasLateSentinel);
+    }
+    if (closedWorld.classHierarchy.hasOnlySubclasses(topmost)) {
+      return TypeMask.nonNullSubclass(topmost, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    }
+    if (closedWorld.classHierarchy.hasAnyStrictSubtype(topmost)) {
+      return FlatTypeMask.nonNullSubtype(topmost, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    } else {
+      return TypeMask.nonNullExact(topmost, closedWorld,
+          hasLateSentinel: hasLateSentinel);
+    }
+  }
+
+  factory TypeMask.unionOf(Iterable<TypeMask> masks, CommonMasks domain) {
+    return UnionTypeMask.unionOf(masks, domain);
+  }
+
+  /// Deserializes a [TypeMask] object from [source].
+  factory TypeMask.readFromDataSource(
+      DataSourceReader source, CommonMasks domain) {
+    TypeMaskKind kind = source.readEnum(TypeMaskKind.values);
+    switch (kind) {
+      case TypeMaskKind.flat:
+        return FlatTypeMask.readFromDataSource(source, domain);
+      case TypeMaskKind.union:
+        return UnionTypeMask.readFromDataSource(source, domain);
+      case TypeMaskKind.container:
+        return ContainerTypeMask.readFromDataSource(source, domain);
+      case TypeMaskKind.set:
+        return SetTypeMask.readFromDataSource(source, domain);
+      case TypeMaskKind.map:
+        return MapTypeMask.readFromDataSource(source, domain);
+      case TypeMaskKind.dictionary:
+        return DictionaryTypeMask.readFromDataSource(source, domain);
+      case TypeMaskKind.value:
+        return ValueTypeMask.readFromDataSource(source, domain);
+    }
+  }
+
+  /// Serializes this [TypeMask] to [sink].
+  void writeToDataSink(DataSinkWriter sink);
+
+  /// If [mask] is forwarding, returns the first non-forwarding [TypeMask] in
+  /// [mask]'s forwarding chain.
+  static TypeMask nonForwardingMask(TypeMask mask) {
+    while (mask is ForwardingTypeMask) {
+      mask = mask.forwardTo;
+    }
+    return mask;
+  }
+
+  /// Asserts that this mask uses the smallest possible representation for
+  /// its types. Currently, we normalize subtype and subclass to exact if no
+  /// subtypes or subclasses are present and subtype to subclass if only
+  /// subclasses exist. We also normalize exact to empty if the corresponding
+  /// baseclass was never instantiated.
+  static bool assertIsNormalized(TypeMask mask, JClosedWorld closedWorld) {
+    final reason = getNotNormalizedReason(mask, closedWorld);
+    assert(reason == null,
+        failedAt(NO_LOCATION_SPANNABLE, '$mask is not normalized: $reason'));
+    return true;
+  }
+
+  static String? getNotNormalizedReason(
+      TypeMask mask, JClosedWorld closedWorld) {
+    mask = nonForwardingMask(mask);
+    if (mask is FlatTypeMask) {
+      if (mask.isEmptyOrFlagged) return null;
+      if (mask.base == closedWorld.commonElements.nullClass) {
+        return 'The class ${mask.base} is not canonicalized.';
+      }
+      if (mask.isExact) {
+        if (!closedWorld.classHierarchy.isInstantiated(mask.base!)) {
+          return 'Exact ${mask.base} is not instantiated.';
+        }
+        return null;
+      }
+      if (mask.isSubclass) {
+        if (!closedWorld.classHierarchy.hasAnyStrictSubclass(mask.base!)) {
+          return 'Subclass ${mask.base} does not have any subclasses.';
+        }
+        return null;
+      }
+      assert(mask.isSubtype);
+      if (!closedWorld.classHierarchy.hasAnyStrictSubtype(mask.base!)) {
+        return 'Subtype ${mask.base} does not have any subclasses.';
+      }
+      if (closedWorld.classHierarchy.hasOnlySubclasses(mask.base!)) {
+        return 'Subtype ${mask.base} only has subclasses.';
+      }
+      return null;
+    } else if (mask is UnionTypeMask) {
+      for (TypeMask submask in mask.disjointMasks) {
+        final submaskReason = getNotNormalizedReason(submask, closedWorld);
+        if (submaskReason != null) {
+          return 'Submask $submask in $mask: $submaskReason.';
+        }
+      }
+      return null;
+    }
+    return 'Unknown type mask $mask.';
+  }
+
+  /// Returns a nullable variant of [this] type mask.
+  TypeMask nullable() => withFlags(isNullable: true);
+
+  /// Returns a non-nullable variant of [this] type mask.
+  TypeMask nonNullable() => withFlags(isNullable: false);
+
+  /// Returns a variant of [this] type mask whose value is neither `null` nor
+  /// the late sentinel.
+  TypeMask withoutFlags() =>
+      withFlags(isNullable: false, hasLateSentinel: false);
+
+  TypeMask withFlags({bool? isNullable, bool? hasLateSentinel});
+
+  /// Whether nothing matches this mask, not even null.
+  bool get isEmpty;
+
+  /// Whether null is a valid value of this mask.
+  bool get isNullable;
+
+  /// Whether the only possible value in this mask is Null.
+  bool get isNull;
+
+  /// Whether [this] is a sentinel for an uninitialized late variable.
+  AbstractBool get isLateSentinel;
+
+  /// Whether a late sentinel is a valid value of this mask.
+  bool get hasLateSentinel => isLateSentinel.isPotentiallyTrue;
+
+  /// Whether [this] mask is empty or only represents values tracked by flags
+  /// (i.e. `null` and the late sentinel).
+  bool get isEmptyOrFlagged;
+
+  /// Whether this mask only includes instances of an exact class, and none of
+  /// it's subclasses or subtypes.
+  bool get isExact;
+
+  bool containsOnlyInt(JClosedWorld closedWorld);
+  bool containsOnlyNum(JClosedWorld closedWorld);
+  bool containsOnlyBool(JClosedWorld closedWorld);
+  bool containsOnlyString(JClosedWorld closedWorld);
+  bool containsOnly(ClassEntity cls);
+
+  /// Compares two [TypeMask] objects for structural equality.
+  ///
+  /// Note: This may differ from semantic equality in the set containment sense.
+  ///   Use [containsMask] and [isInMask] for that, instead.
+  @override
+  bool operator ==(other);
+
+  /// If this returns `true`, [other] is guaranteed to be a supertype of this
+  /// mask, i.e., this mask is in [other]. However, the inverse does not hold.
+  /// Enable [UnionTypeMask.PERFORM_EXTRA_CONTAINS_CHECK] to be notified of
+  /// false negatives.
+  bool isInMask(TypeMask other, JClosedWorld closedWorld);
+
+  /// If this returns `true`, [other] is guaranteed to be a subtype of this
+  /// mask, i.e. this mask contains [other]. However, the inverse does not hold.
+  /// Enable [UnionTypeMask.PERFORM_EXTRA_CONTAINS_CHECK] to be notified of
+  /// false negatives.
+  bool containsMask(TypeMask other, JClosedWorld closedWorld);
+
+  /// Returns whether this type mask is an instance of [cls].
+  bool satisfies(ClassEntity cls, JClosedWorld closedWorld);
+
+  /// Returns whether or not this type mask contains the given class [cls].
+  bool contains(ClassEntity cls, JClosedWorld closedWorld);
+
+  /// Returns whether or not this type mask contains all types.
+  bool containsAll(JClosedWorld closedWorld);
+
+  /// Returns the [ClassEntity] if this type represents a single class,
+  /// otherwise returns `null`.  This method is conservative.
+  ClassEntity? singleClass(JClosedWorld closedWorld);
+
+  /// Returns a type mask representing the union of [this] and [other].
+  TypeMask union(TypeMask other, CommonMasks domain);
+
+  /// Returns whether the intersection of this and [other] is empty.
+  bool isDisjoint(TypeMask other, JClosedWorld closedWorld);
+
+  /// Returns a type mask representing the intersection of [this] and [other].
+  TypeMask intersection(TypeMask other, CommonMasks domain);
+
+  /// Returns whether [element] is a potential target when being invoked on this
+  /// type mask.
+  ///
+  ///
+  /// [name] is used to ensure library privacy is taken into account.
+  bool canHit(MemberEntity element, Name name, JClosedWorld closedWorld);
+
+  /// Returns whether this [TypeMask] applied to [selector] can hit a
+  /// [noSuchMethod].
+  bool needsNoSuchMethodHandling(Selector selector, JClosedWorld world);
+
+  /// Returns the [element] that is known to always be hit at runtime
+  /// on this mask. Returns null if there is none.
+  MemberEntity? locateSingleMember(Selector selector, CommonMasks domain);
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/union_type_mask.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/union_type_mask.dart
new file mode 100644
index 0000000..d79436e
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/union_type_mask.dart
@@ -0,0 +1,483 @@
+// Copyright (c) 2013, 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.
+
+part of masks;
+
+class UnionTypeMask extends TypeMask {
+  /// Tag used for identifying serialized [UnionTypeMask] objects in a
+  /// debugging data stream.
+  static const String tag = 'union-type-mask';
+
+  static const int MAX_UNION_LENGTH = 4;
+
+  // Set this flag to `true` to perform a set-membership based containment check
+  // instead of relying on normalized types. This is quite slow but can be
+  // helpful in debugging.
+  static const bool PERFORM_EXTRA_CONTAINS_CHECK = false;
+
+  /// Components of the union, none of which is itself a union or nullable.
+  final List<FlatTypeMask> disjointMasks;
+
+  @override
+  final bool isNullable;
+
+  @override
+  final bool hasLateSentinel;
+
+  @override
+  AbstractBool get isLateSentinel => AbstractBool.maybeOrFalse(hasLateSentinel);
+
+  UnionTypeMask._internal(this.disjointMasks,
+      {required this.isNullable, required this.hasLateSentinel})
+      : assert(disjointMasks.length > 1),
+        assert(disjointMasks.every((TypeMask mask) => mask is! UnionTypeMask)),
+        assert(disjointMasks.every((TypeMask mask) => !mask.isNullable)),
+        assert(disjointMasks.every((TypeMask mask) => !mask.hasLateSentinel));
+
+  /// Deserializes a [UnionTypeMask] object from [source].
+  factory UnionTypeMask.readFromDataSource(
+      DataSourceReader source, CommonMasks domain) {
+    source.begin(tag);
+    List<FlatTypeMask> disjointMasks = source.readList(
+        () => TypeMask.readFromDataSource(source, domain) as FlatTypeMask);
+    bool isNullable = source.readBool();
+    bool hasLateSentinel = source.readBool();
+    source.end(tag);
+    return UnionTypeMask._internal(disjointMasks,
+        isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+  }
+
+  /// Serializes this [UnionTypeMask] to [sink].
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(TypeMaskKind.union);
+    sink.begin(tag);
+    sink.writeList(
+        disjointMasks, (FlatTypeMask mask) => mask.writeToDataSink(sink));
+    sink.writeBool(isNullable);
+    sink.writeBool(hasLateSentinel);
+    sink.end(tag);
+  }
+
+  static TypeMask unionOf(Iterable<TypeMask> masks, CommonMasks domain) {
+    assert(masks.every(
+        (mask) => TypeMask.assertIsNormalized(mask, domain._closedWorld)));
+    List<FlatTypeMask> disjoint = <FlatTypeMask>[];
+    bool isNullable = masks.any((TypeMask mask) => mask.isNullable);
+    bool hasLateSentinel = masks.any((TypeMask mask) => mask.hasLateSentinel);
+    unionOfHelper(masks, disjoint, domain);
+    if (disjoint.isEmpty)
+      return isNullable
+          ? TypeMask.empty(hasLateSentinel: hasLateSentinel)
+          : TypeMask.nonNullEmpty(hasLateSentinel: hasLateSentinel);
+    if (disjoint.length > MAX_UNION_LENGTH) {
+      return flatten(disjoint, domain,
+          includeNull: isNullable, includeLateSentinel: hasLateSentinel);
+    }
+    if (disjoint.length == 1)
+      return disjoint.single
+          .withFlags(isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+    UnionTypeMask union = UnionTypeMask._internal(disjoint,
+        isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+    assert(TypeMask.assertIsNormalized(union, domain._closedWorld));
+    return union;
+  }
+
+  static void unionOfHelper(Iterable<TypeMask> masks,
+      List<FlatTypeMask> disjoint, CommonMasks domain) {
+    // TODO(johnniwinther): Impose an order on the mask to ensure subclass masks
+    // are preferred to subtype masks.
+    for (TypeMask mask in masks) {
+      mask = TypeMask.nonForwardingMask(mask).withoutFlags();
+      if (mask is UnionTypeMask) {
+        unionOfHelper(mask.disjointMasks, disjoint, domain);
+      } else if (mask.isEmpty) {
+        continue;
+      } else {
+        var flatMask = mask as FlatTypeMask;
+        int inListIndex = -1;
+        bool covered = false;
+
+        // Iterate over [disjoint] to find out if one of the mask
+        // already covers [mask].
+        for (int i = 0; i < disjoint.length; i++) {
+          FlatTypeMask current = disjoint[i];
+          TypeMask newMask = flatMask.union(current, domain);
+          // If we have found a disjoint union, continue iterating.
+          if (newMask is UnionTypeMask) continue;
+          newMask as FlatTypeMask;
+          covered = true;
+          // We found a mask that is either equal to [mask] or is a
+          // supertype of [mask].
+          if (current == newMask) break;
+
+          // [mask] is a supertype of [current], replace the [disjoint]
+          // list with [newMask] instead of [current]. Note that
+          // [newMask] may contain different information than [mask],
+          // like nullability.
+          disjoint[i] = newMask;
+          flatMask = newMask;
+
+          if (inListIndex != -1) {
+            // If the mask was already covered, we remove the previous
+            // place where it was inserted. This new mask subsumes the
+            // previously covered one.
+            disjoint.removeAt(inListIndex);
+            i--;
+          }
+          // Record where the mask was inserted.
+          inListIndex = i;
+        }
+        // If none of the masks in [disjoint] covers [mask], we just
+        // add [mask] to the list.
+        if (!covered) disjoint.add(flatMask);
+      }
+    }
+  }
+
+  static TypeMask flatten(List<FlatTypeMask> masks, CommonMasks domain,
+      {required bool includeNull, required bool includeLateSentinel}) {
+    // TODO(johnniwinther): Move this computation to [ClosedWorld] and use the
+    // class set structures.
+    if (masks.isEmpty) throw ArgumentError.value(masks, 'masks');
+    // If either type mask is a subtype type mask, we cannot use a
+    // subclass type mask to represent their union.
+    bool useSubclass = masks.every((e) => !e.isSubtype);
+
+    final masksBases = masks.map((mask) => mask.base!).toList();
+    Iterable<ClassEntity> candidates =
+        domain._closedWorld.commonSupertypesOf(masksBases);
+
+    // Compute the best candidate and its kind.
+    ClassEntity? bestElement;
+    late _FlatTypeMaskKind bestKind;
+    late int bestSize;
+    for (ClassEntity candidate in candidates) {
+      bool isInstantiatedStrictSubclass(cls) =>
+          cls != candidate &&
+          domain._closedWorld.classHierarchy.isExplicitlyInstantiated(cls) &&
+          domain._closedWorld.classHierarchy.isSubclassOf(cls, candidate);
+
+      int size;
+      _FlatTypeMaskKind kind;
+      if (useSubclass && masksBases.every(isInstantiatedStrictSubclass)) {
+        // If both [this] and [other] are subclasses of the supertype,
+        // then we prefer to construct a subclass type mask because it
+        // will always be at least as small as the corresponding
+        // subtype type mask.
+        kind = _FlatTypeMaskKind.subclass;
+        // TODO(sigmund, johnniwinther): computing length here (and below) is
+        // expensive. If we can't prevent `flatten` from being called a lot, it
+        // might be worth caching results.
+        size =
+            domain._closedWorld.classHierarchy.strictSubclassCount(candidate);
+        assert(size <=
+            domain._closedWorld.classHierarchy.strictSubtypeCount(candidate));
+      } else {
+        kind = _FlatTypeMaskKind.subtype;
+        size = domain._closedWorld.classHierarchy.strictSubtypeCount(candidate);
+      }
+      // Update the best candidate if the new one is better.
+      if (bestElement == null || size < bestSize) {
+        bestElement = candidate;
+        bestSize = size;
+        bestKind = kind;
+      }
+    }
+    int flags = FlatTypeMask._computeFlags(bestKind,
+        isNullable: includeNull, hasLateSentinel: includeLateSentinel);
+    return FlatTypeMask.normalized(bestElement!, flags, domain);
+  }
+
+  @override
+  TypeMask union(TypeMask other, CommonMasks domain) {
+    other = TypeMask.nonForwardingMask(other);
+    bool isNullable = this.isNullable || other.isNullable;
+    bool hasLateSentinel = this.hasLateSentinel || other.hasLateSentinel;
+    if (other is UnionTypeMask) {
+      if (_containsDisjointMasks(other)) {
+        return withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+      }
+      if (other._containsDisjointMasks(this)) {
+        return other.withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+      }
+    } else {
+      if (disjointMasks.contains(other.withoutFlags())) {
+        return withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+      }
+    }
+
+    List<FlatTypeMask> newList = List<FlatTypeMask>.of(disjointMasks);
+    if (other is UnionTypeMask) {
+      newList.addAll(other.disjointMasks);
+    } else {
+      newList.add(other as FlatTypeMask);
+    }
+    TypeMask newMask = TypeMask.unionOf(newList, domain);
+    return newMask.withFlags(
+        isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+  }
+
+  @override
+  TypeMask intersection(TypeMask other, CommonMasks domain) {
+    other = TypeMask.nonForwardingMask(other);
+    bool isNullable = this.isNullable && other.isNullable;
+    bool hasLateSentinel = this.hasLateSentinel && other.hasLateSentinel;
+    if (other is UnionTypeMask) {
+      if (_containsDisjointMasks(other)) {
+        return other.withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+      }
+      if (other._containsDisjointMasks(this)) {
+        return withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+      }
+    } else {
+      if (disjointMasks.contains(other.withoutFlags())) {
+        return other.withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+      }
+    }
+
+    List<TypeMask> intersections = <TypeMask>[];
+    for (TypeMask current in disjointMasks) {
+      if (other is UnionTypeMask) {
+        if (other.disjointMasks.contains(current)) {
+          intersections.add(current);
+        } else {
+          for (FlatTypeMask flatOther in other.disjointMasks) {
+            intersections.add(current.intersection(flatOther, domain));
+          }
+        }
+      } else {
+        intersections.add(current.intersection(other, domain));
+      }
+    }
+    TypeMask newMask = TypeMask.unionOf(intersections, domain);
+    return newMask.withFlags(
+        isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+  }
+
+  @override
+  bool isDisjoint(TypeMask other, JClosedWorld closedWorld) {
+    if (isNullable && other.isNullable) return false;
+    if (hasLateSentinel && other.hasLateSentinel) return false;
+    for (var current in disjointMasks) {
+      if (!current.isDisjoint(other, closedWorld)) return false;
+    }
+    return true;
+  }
+
+  @override
+  UnionTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
+    isNullable ??= this.isNullable;
+    hasLateSentinel ??= this.hasLateSentinel;
+    if (isNullable == this.isNullable &&
+        hasLateSentinel == this.hasLateSentinel) {
+      return this;
+    }
+    List<FlatTypeMask> newList = List<FlatTypeMask>.of(disjointMasks);
+    return UnionTypeMask._internal(newList,
+        isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+  }
+
+  @override
+  bool get isEmptyOrFlagged => false;
+  @override
+  bool get isEmpty => false;
+  @override
+  bool get isNull => false;
+  @override
+  bool get isExact => false;
+
+  /// Checks whether [other] is contained in this union.
+  ///
+  /// Invariants:
+  /// - [other] may not be a [UnionTypeMask] itself
+  /// - the cheap test matching against individual members of [disjointMasks]
+  ///   must have failed.
+  bool _slowContainsCheck(TypeMask other, JClosedWorld closedWorld) {
+    // Unions should never make it here.
+    assert(other is! UnionTypeMask);
+    // Likewise, nullness should be covered.
+    assert(isNullable || !other.isNullable);
+    assert(hasLateSentinel || !other.hasLateSentinel);
+    other = other.withoutFlags();
+    // Ensure the cheap test fails.
+    assert(!disjointMasks.any((mask) => mask.containsMask(other, closedWorld)));
+    // If we cover object, we should never get here.
+    assert(!contains(closedWorld.commonElements.objectClass, closedWorld));
+    // The fast test is precise for exact types.
+    if (other.isExact) return false;
+    // We cannot contain object.
+    if (other.contains(closedWorld.commonElements.objectClass, closedWorld)) {
+      return false;
+    }
+    final flat = TypeMask.nonForwardingMask(other) as FlatTypeMask;
+    // Check we cover the base class.
+    if (!contains(flat.base!, closedWorld)) return false;
+    // Check for other members.
+    Iterable<ClassEntity> members;
+    if (flat.isSubclass) {
+      members = closedWorld.classHierarchy.strictSubclassesOf(flat.base!);
+    } else {
+      assert(flat.isSubtype);
+      members = closedWorld.classHierarchy.strictSubtypesOf(flat.base!);
+    }
+    return members.every((ClassEntity cls) => this.contains(cls, closedWorld));
+  }
+
+  @override
+  bool isInMask(TypeMask other, JClosedWorld closedWorld) {
+    other = TypeMask.nonForwardingMask(other);
+    if (isNullable && !other.isNullable) return false;
+    if (hasLateSentinel && !other.hasLateSentinel) return false;
+    if (other is UnionTypeMask) {
+      final union = other;
+      return disjointMasks.every((FlatTypeMask disjointMask) {
+        bool contained = union.disjointMasks.any((FlatTypeMask other) =>
+            other.containsMask(disjointMask, closedWorld));
+        if (PERFORM_EXTRA_CONTAINS_CHECK &&
+            !contained &&
+            union._slowContainsCheck(disjointMask, closedWorld)) {
+          throw "TypeMask based containment check failed for $this and $other.";
+        }
+        return contained;
+      });
+    }
+    return disjointMasks.every((mask) => mask.isInMask(other, closedWorld));
+  }
+
+  @override
+  bool containsMask(TypeMask other, JClosedWorld closedWorld) {
+    other = TypeMask.nonForwardingMask(other);
+    if (other.isNullable && !isNullable) return false;
+    if (other.hasLateSentinel && !hasLateSentinel) return false;
+    if (other is UnionTypeMask) return other.isInMask(this, closedWorld);
+    other = other.withoutFlags();
+    bool contained =
+        disjointMasks.any((mask) => mask.containsMask(other, closedWorld));
+    if (PERFORM_EXTRA_CONTAINS_CHECK &&
+        !contained &&
+        _slowContainsCheck(other, closedWorld)) {
+      throw "TypeMask based containment check failed for $this and $other.";
+    }
+    return contained;
+  }
+
+  @override
+  bool containsOnlyInt(JClosedWorld closedWorld) {
+    return disjointMasks.every((mask) => mask.containsOnlyInt(closedWorld));
+  }
+
+  @override
+  bool containsOnlyNum(JClosedWorld closedWorld) {
+    return disjointMasks.every((mask) {
+      return mask.containsOnlyNum(closedWorld);
+    });
+  }
+
+  @override
+  bool containsOnlyBool(JClosedWorld closedWorld) {
+    return disjointMasks.every((mask) => mask.containsOnlyBool(closedWorld));
+  }
+
+  @override
+  bool containsOnlyString(JClosedWorld closedWorld) {
+    return disjointMasks.every((mask) => mask.containsOnlyString(closedWorld));
+  }
+
+  @override
+  bool containsOnly(ClassEntity element) {
+    return disjointMasks.every((mask) => mask.containsOnly(element));
+  }
+
+  @override
+  bool satisfies(ClassEntity cls, JClosedWorld closedWorld) {
+    return disjointMasks.every((mask) => mask.satisfies(cls, closedWorld));
+  }
+
+  @override
+  bool contains(ClassEntity cls, JClosedWorld closedWorld) {
+    return disjointMasks.any((e) => e.contains(cls, closedWorld));
+  }
+
+  @override
+  bool containsAll(JClosedWorld closedWorld) {
+    return disjointMasks.any((mask) => mask.containsAll(closedWorld));
+  }
+
+  @override
+  ClassEntity? singleClass(JClosedWorld closedWorld) => null;
+
+  @override
+  bool needsNoSuchMethodHandling(Selector selector, JClosedWorld closedWorld) {
+    return disjointMasks
+        .any((e) => e.needsNoSuchMethodHandling(selector, closedWorld));
+  }
+
+  @override
+  bool canHit(MemberEntity element, Name name, JClosedWorld closedWorld) {
+    if (element.enclosingClass == closedWorld.commonElements.jsNullClass) {
+      return isNullable;
+    }
+    return (isNullable &&
+            closedWorld.hasElementIn(
+                closedWorld.commonElements.jsNullClass, name, element)) ||
+        disjointMasks.any((e) => e.canHit(element, name, closedWorld));
+  }
+
+  @override
+  MemberEntity? locateSingleMember(Selector selector, CommonMasks domain) {
+    MemberEntity? candidate;
+    for (FlatTypeMask mask in disjointMasks) {
+      mask = mask.withFlags(
+          isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+      final current = mask.locateSingleMember(selector, domain);
+      if (current == null) {
+        return null;
+      } else if (candidate == null) {
+        candidate = current;
+      } else if (candidate != current) {
+        return null;
+      }
+    }
+    return candidate;
+  }
+
+  @override
+  String toString() {
+    String masksString = [
+      if (isNullable) 'null',
+      if (hasLateSentinel) 'sentinel',
+      ...disjointMasks.map((TypeMask mask) => mask.toString()).toList()..sort(),
+    ].join(", ");
+    return 'Union($masksString)';
+  }
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+
+    return other is UnionTypeMask &&
+        other.isNullable == isNullable &&
+        other.hasLateSentinel == hasLateSentinel &&
+        other.disjointMasks.length == disjointMasks.length &&
+        _containsDisjointMasks(other);
+  }
+
+  @override
+  int get hashCode {
+    // The order of the masks in [disjointMasks] must not affect the
+    // hashCode.
+    return Hashing.setHash(
+        disjointMasks, Hashing.objectsHash(isNullable, hasLateSentinel));
+  }
+
+  bool _containsDisjointMasks(UnionTypeMask other) =>
+      other.disjointMasks.every((e) => disjointMasks.contains(e));
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/typemasks/value_type_mask.dart b/pkg/compiler/lib/src/inferrer_experimental/typemasks/value_type_mask.dart
new file mode 100644
index 0000000..b788e7e
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/typemasks/value_type_mask.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2014, 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.
+
+part of masks;
+
+class ValueTypeMask extends ForwardingTypeMask {
+  /// Tag used for identifying serialized [ValueTypeMask] objects in a
+  /// debugging data stream.
+  static const String tag = 'value-type-mask';
+
+  @override
+  final TypeMask forwardTo;
+  final PrimitiveConstantValue value;
+
+  const ValueTypeMask(this.forwardTo, this.value);
+
+  /// Deserializes a [ValueTypeMask] object from [source].
+  factory ValueTypeMask.readFromDataSource(
+      DataSourceReader source, CommonMasks domain) {
+    source.begin(tag);
+    TypeMask forwardTo = TypeMask.readFromDataSource(source, domain);
+    final constant = source.readConstant() as PrimitiveConstantValue;
+    source.end(tag);
+    return ValueTypeMask(forwardTo, constant);
+  }
+
+  /// Serializes this [ValueTypeMask] to [sink].
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(TypeMaskKind.value);
+    sink.begin(tag);
+    forwardTo.writeToDataSink(sink);
+    sink.writeConstant(value);
+    sink.end(tag);
+  }
+
+  @override
+  ValueTypeMask withFlags({bool? isNullable, bool? hasLateSentinel}) {
+    isNullable ??= this.isNullable;
+    hasLateSentinel ??= this.hasLateSentinel;
+    if (isNullable == this.isNullable &&
+        hasLateSentinel == this.hasLateSentinel) {
+      return this;
+    }
+    return ValueTypeMask(
+        forwardTo.withFlags(
+            isNullable: isNullable, hasLateSentinel: hasLateSentinel),
+        value);
+  }
+
+  @override
+  TypeMask? _unionSpecialCases(TypeMask other, CommonMasks domain,
+      {required bool isNullable, required bool hasLateSentinel}) {
+    if (other is ValueTypeMask &&
+        forwardTo.withoutFlags() == other.forwardTo.withoutFlags() &&
+        value == other.value) {
+      return withFlags(
+          isNullable: isNullable, hasLateSentinel: hasLateSentinel);
+    }
+    return null;
+  }
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! ValueTypeMask) return false;
+    return super == other && value == other.value;
+  }
+
+  @override
+  int get hashCode => Hashing.objectHash(value, super.hashCode);
+
+  @override
+  String toString() {
+    return 'Value($forwardTo, value: ${value.toDartText(null)})';
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/types.dart b/pkg/compiler/lib/src/inferrer_experimental/types.dart
new file mode 100644
index 0000000..36e3932
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/types.dart
@@ -0,0 +1,679 @@
+// Copyright (c) 2012, 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.10
+
+library types;
+
+import 'package:kernel/ast.dart' as ir;
+import '../common.dart' show failedAt, retainDataForTesting;
+import '../common/metrics.dart' show Metrics;
+import '../common/names.dart';
+import '../common/tasks.dart' show CompilerTask;
+import '../compiler.dart' show Compiler;
+import '../elements/entities.dart';
+import '../inferrer_experimental/engine.dart';
+import '../inferrer_experimental/type_graph_inferrer.dart'
+    show TypeGraphInferrer;
+import '../js_backend/inferred_data.dart';
+import '../js_model/element_map.dart';
+import '../js_model/js_world.dart';
+import '../js_model/locals.dart';
+import '../serialization/deferrable.dart';
+import '../serialization/serialization.dart';
+import '../universe/selector.dart' show Selector;
+import '../world.dart' show JClosedWorld;
+import '../inferrer/abstract_value_domain.dart';
+import '../inferrer/types.dart' as baseInferrer;
+
+/// Results about a single element (e.g. a method, parameter, or field)
+/// produced by the global type-inference algorithm.
+///
+/// All queries in this class may contain results that assume whole-program
+/// closed-world semantics. Any [TypeMask] for an element or node that we return
+/// was inferred to be a "guaranteed type", that means, it is a type that we
+/// can prove to be correct for all executions of the program.  A trivial
+/// implementation would return false on all boolean properties (giving no
+/// guarantees) and the `subclass of Object or null` type mask for the type
+/// based queries (the runtime value could be anything).
+abstract class GlobalTypeInferenceMemberResult
+    implements baseInferrer.GlobalTypeInferenceMemberResult {
+  /// Deserializes a [GlobalTypeInferenceMemberResult] object from [source].
+  factory GlobalTypeInferenceMemberResult.readFromDataSource(
+          DataSourceReader source,
+          ir.Member context,
+          AbstractValueDomain abstractValueDomain) =
+      GlobalTypeInferenceMemberResultImpl.readFromDataSource;
+
+  /// Serializes this [GlobalTypeInferenceMemberResult] to [sink].
+  @override
+  void writeToDataSink(DataSinkWriter sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain);
+
+  /// The inferred type when this result belongs to a field, null otherwise.
+  @override
+  AbstractValue get type;
+
+  /// Whether the member associated with this result is only called once in one
+  /// location in the entire program.
+  @override
+  bool get isCalledOnce;
+
+  /// Whether the method element associated with this result always throws.
+  @override
+  bool get throwsAlways;
+
+  /// The inferred return type when this result belongs to a function element.
+  @override
+  AbstractValue get returnType;
+
+  /// Returns the receiver type of a node that is a property get, set, or method
+  /// invocation.
+  @override
+  AbstractValue typeOfReceiver(ir.TreeNode node);
+
+  /// Returns the type of the iterator in a [loop].
+  @override
+  AbstractValue typeOfIterator(ir.TreeNode node);
+
+  /// Returns the type of the `moveNext` call of an iterator in a [loop].
+  @override
+  AbstractValue typeOfIteratorMoveNext(ir.TreeNode node);
+
+  /// Returns the type of the `current` getter of an iterator in a [loop].
+  @override
+  AbstractValue typeOfIteratorCurrent(ir.TreeNode node);
+}
+
+/// Internal data used during type-inference to store intermediate results about
+/// a single element.
+abstract class GlobalTypeInferenceElementData {
+  /// Deserializes a [GlobalTypeInferenceElementData] object from [source].
+  factory GlobalTypeInferenceElementData.readFromDataSource(
+          DataSourceReader source,
+          ir.Member context,
+          AbstractValueDomain abstractValueDomain) =
+      KernelGlobalTypeInferenceElementData.readFromDataSource;
+
+  /// Serializes this [GlobalTypeInferenceElementData] to [sink].
+  void writeToDataSink(DataSinkWriter sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain);
+
+  /// Compresses the inner representation by removing [AbstractValue] mappings
+  /// to `null`. Returns the data object itself or `null` if the data object
+  /// was empty after compression.
+  GlobalTypeInferenceElementData compress();
+
+  // TODO(johnniwinther): Remove this. Maybe split by access/invoke.
+  AbstractValue typeOfReceiver(ir.TreeNode node);
+
+  AbstractValue typeOfIterator(ir.TreeNode node);
+
+  AbstractValue typeOfIteratorMoveNext(ir.TreeNode node);
+
+  AbstractValue typeOfIteratorCurrent(ir.TreeNode node);
+}
+
+/// API to interact with the global type-inference engine.
+abstract class TypesInferrer implements baseInferrer.TypesInferrer {
+  @override
+  GlobalTypeInferenceResults analyzeMain(FunctionEntity element);
+}
+
+/// Results produced by the global type-inference algorithm.
+///
+/// All queries in this class may contain results that assume whole-program
+/// closed-world semantics. Any [AbstractValue] for an element or node that we
+/// return was inferred to be a "guaranteed type", that means, it is a type that
+/// we can prove to be correct for all executions of the program.
+abstract class GlobalTypeInferenceResults
+    implements baseInferrer.GlobalTypeInferenceResults {
+  /// Deserializes a [GlobalTypeInferenceResults] object from [source].
+  factory GlobalTypeInferenceResults.readFromDataSource(
+      DataSourceReader source,
+      JsToElementMap elementMap,
+      JClosedWorld closedWorld,
+      GlobalLocalsMap globalLocalsMap,
+      InferredData inferredData) {
+    bool isTrivial = source.readBool();
+    if (isTrivial) {
+      return TrivialGlobalTypeInferenceResults(closedWorld, globalLocalsMap);
+    }
+    return GlobalTypeInferenceResultsImpl.readFromDataSource(
+        source, elementMap, closedWorld, globalLocalsMap, inferredData);
+  }
+
+  /// Serializes this [GlobalTypeInferenceResults] to [sink].
+  @override
+  void writeToDataSink(DataSinkWriter sink, JsToElementMap elementMap);
+
+  @override
+  JClosedWorld get closedWorld;
+
+  @override
+  GlobalLocalsMap get globalLocalsMap;
+
+  @override
+  InferredData get inferredData;
+
+  @override
+  GlobalTypeInferenceMemberResult resultOfMember(MemberEntity member);
+
+  @override
+  AbstractValue resultOfParameter(Local parameter);
+
+  /// Returns the type of the result of applying [selector] to a receiver with
+  /// the given [receiver] type.
+  @override
+  AbstractValue resultTypeOfSelector(Selector selector, AbstractValue receiver);
+
+  /// Returns the type of a list new expression [node].  Returns `null` if
+  /// [node] does not represent the construction of a new list.
+  @override
+  AbstractValue typeOfNewList(ir.TreeNode node);
+
+  /// Returns the type of a list literal [node].
+  @override
+  AbstractValue typeOfListLiteral(ir.TreeNode node);
+}
+
+/// Global analysis that infers concrete types.
+class GlobalTypeInferenceTask extends CompilerTask {
+  // TODO(sigmund): rename at the same time as our benchmarking tools.
+  @override
+  final String name = 'Type inference';
+
+  final Compiler compiler;
+
+  /// The [TypeGraphInferrer] used by the global type inference. This should by
+  /// accessed from outside this class for testing only.
+  TypeGraphInferrer typesInferrerInternal;
+
+  GlobalTypeInferenceResults resultsForTesting;
+
+  Metrics _metrics = Metrics.none();
+
+  GlobalTypeInferenceTask(Compiler compiler)
+      : compiler = compiler,
+        super(compiler.measurer);
+
+  @override
+  Metrics get metrics => _metrics;
+
+  /// Runs the global type-inference algorithm once.
+  GlobalTypeInferenceResults runGlobalTypeInference(
+      FunctionEntity mainElement,
+      JClosedWorld closedWorld,
+      GlobalLocalsMap globalLocalsMap,
+      InferredDataBuilder inferredDataBuilder) {
+    return measure(() {
+      GlobalTypeInferenceResults results;
+      if (compiler.disableTypeInference) {
+        results =
+            TrivialGlobalTypeInferenceResults(closedWorld, globalLocalsMap);
+      } else {
+        typesInferrerInternal ??= compiler.backendStrategy
+            .createExperimentalTypesInferrer(
+                closedWorld, globalLocalsMap, inferredDataBuilder);
+        results = typesInferrerInternal.analyzeMain(mainElement);
+        _metrics = typesInferrerInternal.metrics;
+      }
+      closedWorld.noSuchMethodData.categorizeComplexImplementations(results);
+      if (retainDataForTesting) {
+        resultsForTesting = results;
+      }
+      return results;
+    });
+  }
+}
+
+class GlobalTypeInferenceResultsImpl implements GlobalTypeInferenceResults {
+  /// Tag used for identifying serialized [GlobalTypeInferenceResults] objects
+  /// in a debugging data stream.
+  static const String tag = 'global-type-inference-results';
+
+  @override
+  final JClosedWorld closedWorld;
+  @override
+  final GlobalLocalsMap globalLocalsMap;
+  @override
+  final InferredData inferredData;
+  final GlobalTypeInferenceMemberResult _deadFieldResult;
+  final GlobalTypeInferenceMemberResult _deadMethodResult;
+  final AbstractValue _trivialParameterResult;
+
+  final Deferrable<Map<MemberEntity, GlobalTypeInferenceMemberResult>>
+      _memberResults;
+  final Deferrable<Map<Local, AbstractValue>> _parameterResults;
+  final Set<Selector> returnsListElementTypeSet;
+  final Deferrable<Map<ir.TreeNode, AbstractValue>> _allocatedLists;
+
+  GlobalTypeInferenceResultsImpl(
+      this.closedWorld,
+      this.globalLocalsMap,
+      this.inferredData,
+      Map<MemberEntity, GlobalTypeInferenceMemberResult> memberResults,
+      Map<Local, AbstractValue> parameterResults,
+      this.returnsListElementTypeSet,
+      Map<ir.TreeNode, AbstractValue> allocatedLists)
+      : _memberResults = Deferrable.eager(memberResults),
+        _parameterResults = Deferrable.eager(parameterResults),
+        _allocatedLists = Deferrable.eager(allocatedLists),
+        _deadFieldResult =
+            DeadFieldGlobalTypeInferenceResult(closedWorld.abstractValueDomain),
+        _deadMethodResult = DeadMethodGlobalTypeInferenceResult(
+            closedWorld.abstractValueDomain),
+        _trivialParameterResult = closedWorld.abstractValueDomain.dynamicType;
+
+  GlobalTypeInferenceResultsImpl._deserialized(
+      this.closedWorld,
+      this.globalLocalsMap,
+      this.inferredData,
+      this._memberResults,
+      this._parameterResults,
+      this.returnsListElementTypeSet,
+      this._allocatedLists)
+      : _deadFieldResult =
+            DeadFieldGlobalTypeInferenceResult(closedWorld.abstractValueDomain),
+        _deadMethodResult = DeadMethodGlobalTypeInferenceResult(
+            closedWorld.abstractValueDomain),
+        _trivialParameterResult = closedWorld.abstractValueDomain.dynamicType;
+
+  factory GlobalTypeInferenceResultsImpl.readFromDataSource(
+      DataSourceReader source,
+      JsToElementMap elementMap,
+      JClosedWorld closedWorld,
+      GlobalLocalsMap globalLocalsMap,
+      InferredData inferredData) {
+    source.registerLocalLookup(LocalLookupImpl(globalLocalsMap));
+
+    source.begin(tag);
+    Deferrable<Map<MemberEntity, GlobalTypeInferenceMemberResult>>
+        memberResults = source.readDeferrable(() => source.readMemberMap(
+            (MemberEntity member) =>
+                GlobalTypeInferenceMemberResult.readFromDataSource(
+                    source,
+                    elementMap.getMemberContextNode(member),
+                    closedWorld.abstractValueDomain)));
+    Deferrable<Map<Local, AbstractValue>> parameterResults =
+        source.readDeferrable(() => source.readLocalMap(() => closedWorld
+            .abstractValueDomain
+            .readAbstractValueFromDataSource(source)));
+    Set<Selector> returnsListElementTypeSet =
+        source.readList(() => Selector.readFromDataSource(source)).toSet();
+    Deferrable<Map<ir.TreeNode, AbstractValue>> allocatedLists =
+        source.readDeferrable(() => source.readTreeNodeMap(() => closedWorld
+            .abstractValueDomain
+            .readAbstractValueFromDataSource(source)));
+    source.end(tag);
+    return GlobalTypeInferenceResultsImpl._deserialized(
+        closedWorld,
+        globalLocalsMap,
+        inferredData,
+        memberResults,
+        parameterResults,
+        returnsListElementTypeSet,
+        allocatedLists);
+  }
+
+  @override
+  void writeToDataSink(DataSinkWriter sink, JsToElementMap elementMap) {
+    sink.writeBool(false); // Is _not_ trivial.
+    sink.begin(tag);
+    sink.writeDeferrable(() => sink.writeMemberMap(
+        _memberResults.loaded(),
+        (MemberEntity member, GlobalTypeInferenceMemberResult result) =>
+            result.writeToDataSink(
+                sink,
+                elementMap.getMemberContextNode(member),
+                closedWorld.abstractValueDomain)));
+    sink.writeDeferrable(() => sink.writeLocalMap(
+        _parameterResults.loaded(),
+        (AbstractValue value) => closedWorld.abstractValueDomain
+            .writeAbstractValueToDataSink(sink, value)));
+    sink.writeList(returnsListElementTypeSet,
+        (Selector selector) => selector.writeToDataSink(sink));
+    sink.writeDeferrable(() => sink.writeTreeNodeMap(
+        _allocatedLists.loaded(),
+        (AbstractValue value) => closedWorld.abstractValueDomain
+            .writeAbstractValueToDataSink(sink, value)));
+    sink.end(tag);
+  }
+
+  @override
+  GlobalTypeInferenceMemberResult resultOfMember(MemberEntity member) {
+    assert(
+        member is! ConstructorBodyEntity,
+        failedAt(
+            member,
+            "unexpected input: ConstructorBodyElements are created"
+            " after global type inference, no data is avaiable for them."));
+    // TODO(sigmund,johnniwinther): Make it an error to query for results that
+    // don't exist..
+    /*assert(memberResults.containsKey(member) || member is JSignatureMethod,
+        "No inference result for member $member");*/
+    return _memberResults.loaded()[member] ??
+        (member is FunctionEntity ? _deadMethodResult : _deadFieldResult);
+  }
+
+  @override
+  AbstractValue resultOfParameter(Local parameter) {
+    // TODO(sigmund,johnniwinther): Make it an error to query for results that
+    // don't exist.
+    /*assert(parameterResults.containsKey(parameter),
+        "No inference result for parameter $parameter");*/
+    return _parameterResults.loaded()[parameter] ?? _trivialParameterResult;
+  }
+
+  @override
+  AbstractValue resultTypeOfSelector(
+      Selector selector, AbstractValue receiver) {
+    AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
+
+    // Bailout for closure calls. We're not tracking types of closures.
+    if (selector.isClosureCall) {
+      // But if the receiver is not callable, the call will fail.
+      if (abstractValueDomain.isEmpty(receiver).isDefinitelyTrue ||
+          abstractValueDomain.isNull(receiver).isDefinitelyTrue) {
+        return abstractValueDomain.emptyType;
+      }
+      return abstractValueDomain.dynamicType;
+    }
+    if (selector.isSetter || selector.isIndexSet) {
+      return abstractValueDomain.dynamicType;
+    }
+    if (returnsListElementType(selector, receiver)) {
+      return abstractValueDomain.getContainerElementType(receiver);
+    }
+    if (returnsMapValueType(selector, receiver)) {
+      return abstractValueDomain.getMapValueType(receiver);
+    }
+
+    if (closedWorld.includesClosureCall(selector, receiver)) {
+      return abstractValueDomain.dynamicType;
+    } else {
+      Iterable<MemberEntity> elements =
+          closedWorld.locateMembers(selector, receiver);
+      List<AbstractValue> types = <AbstractValue>[];
+      for (MemberEntity element in elements) {
+        AbstractValue type = typeOfMemberWithSelector(element, selector);
+        types.add(type);
+      }
+      return abstractValueDomain.unionOfMany(types);
+    }
+  }
+
+  bool returnsListElementType(Selector selector, AbstractValue mask) {
+    return mask != null &&
+        closedWorld.abstractValueDomain.isContainer(mask) &&
+        returnsListElementTypeSet.contains(selector);
+  }
+
+  bool returnsMapValueType(Selector selector, AbstractValue mask) {
+    return mask != null &&
+        closedWorld.abstractValueDomain.isMap(mask) &&
+        selector.isIndex;
+  }
+
+  AbstractValue typeOfMemberWithSelector(
+      MemberEntity element, Selector selector) {
+    if (element.name == Identifiers.noSuchMethod_ &&
+        selector.name != element.name) {
+      // An invocation can resolve to a [noSuchMethod], in which case
+      // we get the return type of [noSuchMethod].
+      return resultOfMember(element).returnType;
+    } else if (selector.isGetter) {
+      if (element.isFunction) {
+        // [functionType] is null if the inferrer did not run.
+        return closedWorld.abstractValueDomain.functionType;
+      } else if (element.isField) {
+        return resultOfMember(element).type;
+      } else if (element.isGetter) {
+        return resultOfMember(element).returnType;
+      } else {
+        assert(false, failedAt(element, "Unexpected member $element"));
+        return closedWorld.abstractValueDomain.dynamicType;
+      }
+    } else if (element.isGetter || element.isField) {
+      assert(selector.isCall || selector.isSetter);
+      return closedWorld.abstractValueDomain.dynamicType;
+    } else {
+      return resultOfMember(element).returnType;
+    }
+  }
+
+  @override
+  AbstractValue typeOfNewList(ir.Node node) => _allocatedLists.loaded()[node];
+
+  @override
+  AbstractValue typeOfListLiteral(ir.Node node) =>
+      _allocatedLists.loaded()[node];
+}
+
+class GlobalTypeInferenceMemberResultImpl
+    implements GlobalTypeInferenceMemberResult {
+  /// Tag used for identifying serialized [GlobalTypeInferenceMemberResult]
+  /// objects in a debugging data stream.
+  static const String tag = 'global-type-inference-member-result';
+
+  final GlobalTypeInferenceElementData _data;
+  @override
+  final AbstractValue returnType;
+  @override
+  final AbstractValue type;
+  @override
+  final bool throwsAlways;
+  @override
+  final bool isCalledOnce;
+
+  GlobalTypeInferenceMemberResultImpl(this._data, this.returnType, this.type,
+      {this.throwsAlways, this.isCalledOnce});
+
+  factory GlobalTypeInferenceMemberResultImpl.readFromDataSource(
+      DataSourceReader source,
+      ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
+    source.begin(tag);
+    GlobalTypeInferenceElementData data = source.readValueOrNull(() {
+      return GlobalTypeInferenceElementData.readFromDataSource(
+          source, context, abstractValueDomain);
+    });
+    AbstractValue returnType =
+        abstractValueDomain.readAbstractValueFromDataSource(source);
+    AbstractValue type =
+        abstractValueDomain.readAbstractValueFromDataSource(source);
+    bool throwsAlways = source.readBool();
+    bool isCalledOnce = source.readBool();
+    source.end(tag);
+    return GlobalTypeInferenceMemberResultImpl(data, returnType, type,
+        throwsAlways: throwsAlways, isCalledOnce: isCalledOnce);
+  }
+
+  @override
+  void writeToDataSink(DataSinkWriter sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
+    sink.begin(tag);
+    sink.writeValueOrNull(_data, (GlobalTypeInferenceElementData data) {
+      data.writeToDataSink(sink, context, abstractValueDomain);
+    });
+    abstractValueDomain.writeAbstractValueToDataSink(sink, returnType);
+    abstractValueDomain.writeAbstractValueToDataSink(sink, type);
+    sink.writeBool(throwsAlways);
+    sink.writeBool(isCalledOnce);
+    sink.end(tag);
+  }
+
+  @override
+  AbstractValue typeOfReceiver(ir.Node node) => _data?.typeOfReceiver(node);
+  @override
+  AbstractValue typeOfIterator(ir.Node node) => _data?.typeOfIterator(node);
+  @override
+  AbstractValue typeOfIteratorMoveNext(ir.Node node) =>
+      _data?.typeOfIteratorMoveNext(node);
+  @override
+  AbstractValue typeOfIteratorCurrent(ir.Node node) =>
+      _data?.typeOfIteratorCurrent(node);
+}
+
+class TrivialGlobalTypeInferenceResults implements GlobalTypeInferenceResults {
+  @override
+  final JClosedWorld closedWorld;
+  final TrivialGlobalTypeInferenceMemberResult _trivialMemberResult;
+  final AbstractValue _trivialParameterResult;
+  @override
+  final InferredData inferredData = TrivialInferredData();
+  @override
+  final GlobalLocalsMap globalLocalsMap;
+
+  TrivialGlobalTypeInferenceResults(this.closedWorld, this.globalLocalsMap)
+      : _trivialMemberResult = TrivialGlobalTypeInferenceMemberResult(
+            closedWorld.abstractValueDomain.dynamicType),
+        _trivialParameterResult = closedWorld.abstractValueDomain.dynamicType;
+
+  @override
+  void writeToDataSink(DataSinkWriter sink, JsToElementMap elementMap) {
+    sink.writeBool(true); // Is trivial.
+  }
+
+  @override
+  AbstractValue resultTypeOfSelector(Selector selector, AbstractValue mask) {
+    return closedWorld.abstractValueDomain.dynamicType;
+  }
+
+  @override
+  AbstractValue resultOfParameter(Local parameter) {
+    return _trivialParameterResult;
+  }
+
+  @override
+  GlobalTypeInferenceMemberResult resultOfMember(MemberEntity member) {
+    return _trivialMemberResult;
+  }
+
+  @override
+  AbstractValue typeOfListLiteral(ir.TreeNode node) => null;
+
+  @override
+  AbstractValue typeOfNewList(ir.TreeNode node) => null;
+}
+
+class TrivialGlobalTypeInferenceMemberResult
+    implements GlobalTypeInferenceMemberResult {
+  final AbstractValue dynamicType;
+
+  TrivialGlobalTypeInferenceMemberResult(this.dynamicType);
+
+  @override
+  AbstractValue get type => dynamicType;
+
+  @override
+  AbstractValue get returnType => dynamicType;
+
+  @override
+  bool get throwsAlways => false;
+
+  @override
+  AbstractValue typeOfIteratorCurrent(ir.Node node) => null;
+
+  @override
+  AbstractValue typeOfIteratorMoveNext(ir.Node node) => null;
+
+  @override
+  AbstractValue typeOfIterator(ir.Node node) => null;
+
+  @override
+  AbstractValue typeOfReceiver(ir.Node node) => null;
+
+  @override
+  bool get isCalledOnce => false;
+
+  @override
+  void writeToDataSink(DataSinkWriter sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
+    throw UnsupportedError(
+        "TrivialGlobalTypeInferenceMemberResult.writeToDataSink");
+  }
+}
+
+class DeadFieldGlobalTypeInferenceResult
+    implements GlobalTypeInferenceMemberResult {
+  final AbstractValue dynamicType;
+  final AbstractValue emptyType;
+
+  DeadFieldGlobalTypeInferenceResult(AbstractValueDomain domain)
+      : this.dynamicType = domain.dynamicType,
+        this.emptyType = domain.emptyType;
+
+  @override
+  AbstractValue get type => emptyType;
+
+  @override
+  AbstractValue get returnType => dynamicType;
+
+  @override
+  bool get throwsAlways => false;
+
+  @override
+  AbstractValue typeOfIteratorCurrent(ir.Node node) => null;
+
+  @override
+  AbstractValue typeOfIteratorMoveNext(ir.Node node) => null;
+
+  @override
+  AbstractValue typeOfIterator(ir.Node node) => null;
+
+  @override
+  AbstractValue typeOfReceiver(ir.Node node) => null;
+
+  @override
+  bool get isCalledOnce => false;
+
+  @override
+  void writeToDataSink(DataSinkWriter sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
+    throw UnsupportedError(
+        "DeadFieldGlobalTypeInferenceResult.writeToDataSink");
+  }
+}
+
+class DeadMethodGlobalTypeInferenceResult
+    implements GlobalTypeInferenceMemberResult {
+  final AbstractValue emptyType;
+  final AbstractValue functionType;
+
+  DeadMethodGlobalTypeInferenceResult(AbstractValueDomain domain)
+      : this.functionType = domain.functionType,
+        this.emptyType = domain.emptyType;
+
+  @override
+  AbstractValue get type => functionType;
+
+  @override
+  AbstractValue get returnType => emptyType;
+
+  @override
+  bool get throwsAlways => false;
+
+  @override
+  AbstractValue typeOfIteratorCurrent(ir.Node node) => null;
+
+  @override
+  AbstractValue typeOfIteratorMoveNext(ir.Node node) => null;
+
+  @override
+  AbstractValue typeOfIterator(ir.Node node) => null;
+
+  @override
+  AbstractValue typeOfReceiver(ir.Node node) => null;
+
+  @override
+  bool get isCalledOnce => false;
+
+  @override
+  void writeToDataSink(DataSinkWriter sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
+    throw UnsupportedError(
+        "DeadFieldGlobalTypeInferenceResult.writeToDataSink");
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/wrapped.dart b/pkg/compiler/lib/src/inferrer_experimental/wrapped.dart
new file mode 100644
index 0000000..2f5f04d
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer_experimental/wrapped.dart
@@ -0,0 +1,667 @@
+// Copyright (c) 2018, 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 '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
+import '../elements/entities.dart';
+import '../elements/names.dart';
+import '../elements/types.dart' show DartType;
+import '../ir/class_relation.dart';
+import '../serialization/serialization.dart';
+import '../universe/selector.dart';
+import '../universe/world_builder.dart';
+import '../universe/use.dart';
+import '../world_interfaces.dart';
+import '../inferrer/abstract_value_domain.dart';
+import '../inferrer/abstract_value_strategy.dart';
+
+class WrappedAbstractValue implements AbstractValue {
+  final AbstractValue _abstractValue;
+  const WrappedAbstractValue(this._abstractValue);
+
+  @override
+  bool operator ==(var other) {
+    if (identical(this, other)) return true;
+    if (other is! WrappedAbstractValue) return false;
+    return _abstractValue == other._abstractValue;
+  }
+
+  @override
+  int get hashCode {
+    return _abstractValue.hashCode;
+  }
+
+  @override
+  String toString() => _abstractValue.toString();
+}
+
+AbstractValue? unwrapOrNull(WrappedAbstractValue? wrapped) {
+  return wrapped?._abstractValue;
+}
+
+WrappedAbstractValue? wrapOrNull(AbstractValue? abstractValue) {
+  return abstractValue == null ? null : WrappedAbstractValue(abstractValue);
+}
+
+class WrappedAbstractValueDomain implements AbstractValueDomain {
+  final AbstractValueDomain _abstractValueDomain;
+  const WrappedAbstractValueDomain(this._abstractValueDomain);
+
+  @override
+  AbstractValue get internalTopType =>
+      WrappedAbstractValue(_abstractValueDomain.internalTopType);
+
+  @override
+  AbstractValue get dynamicType =>
+      WrappedAbstractValue(_abstractValueDomain.dynamicType);
+
+  @override
+  void writeAbstractValueToDataSink(
+      DataSinkWriter sink, covariant WrappedAbstractValue value) {
+    _abstractValueDomain.writeAbstractValueToDataSink(
+        sink, value._abstractValue);
+  }
+
+  @override
+  AbstractValue readAbstractValueFromDataSource(DataSourceReader source) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.readAbstractValueFromDataSource(source));
+
+  @override
+  String getCompactText(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getCompactText(value._abstractValue);
+
+  @override
+  AbstractBool isFixedLengthJsIndexable(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isFixedLengthJsIndexable(value._abstractValue);
+
+  @override
+  AbstractBool isJsIndexableAndIterable(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isJsIndexableAndIterable(value._abstractValue);
+
+  @override
+  AbstractBool isJsIndexable(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isJsIndexable(value._abstractValue);
+
+  @override
+  MemberEntity? locateSingleMember(
+          covariant WrappedAbstractValue receiver, Selector selector) =>
+      _abstractValueDomain.locateSingleMember(
+          receiver._abstractValue, selector);
+
+  @override
+  AbstractBool isIn(covariant WrappedAbstractValue subset,
+          covariant WrappedAbstractValue superset) =>
+      _abstractValueDomain.isIn(subset._abstractValue, superset._abstractValue);
+
+  @override
+  AbstractBool needsNoSuchMethodHandling(
+          covariant WrappedAbstractValue receiver, Selector selector) =>
+      _abstractValueDomain.needsNoSuchMethodHandling(
+          receiver._abstractValue, selector);
+
+  @override
+  AbstractBool isTargetingMember(covariant WrappedAbstractValue receiver,
+          MemberEntity member, Name name) =>
+      _abstractValueDomain.isTargetingMember(
+          receiver._abstractValue, member, name);
+
+  @override
+  AbstractValue computeReceiver(Iterable<MemberEntity> members) =>
+      WrappedAbstractValue(_abstractValueDomain.computeReceiver(members));
+
+  @override
+  PrimitiveConstantValue? getPrimitiveValue(
+          covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getPrimitiveValue(value._abstractValue);
+
+  @override
+  AbstractValue createPrimitiveValue(
+          covariant WrappedAbstractValue originalValue,
+          PrimitiveConstantValue value) =>
+      WrappedAbstractValue(_abstractValueDomain.createPrimitiveValue(
+          originalValue._abstractValue, value));
+
+  @override
+  bool isPrimitiveValue(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveValue(value._abstractValue);
+
+  @override
+  MemberEntity? getAllocationElement(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getAllocationElement(value._abstractValue);
+
+  @override
+  Object? getAllocationNode(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getAllocationNode(value._abstractValue);
+
+  @override
+  AbstractValue getGeneralization(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.getGeneralization(unwrapOrNull(value))!);
+
+  @override
+  bool isSpecializationOf(covariant WrappedAbstractValue specialization,
+          covariant WrappedAbstractValue generalization) =>
+      _abstractValueDomain.isSpecializationOf(
+          specialization._abstractValue, generalization._abstractValue);
+
+  @override
+  AbstractValue getDictionaryValueForKey(
+          covariant WrappedAbstractValue value, String key) =>
+      WrappedAbstractValue(_abstractValueDomain.getDictionaryValueForKey(
+          value._abstractValue, key));
+
+  @override
+  bool containsDictionaryKey(
+          covariant WrappedAbstractValue value, String key) =>
+      _abstractValueDomain.containsDictionaryKey(value._abstractValue, key);
+
+  @override
+  AbstractValue createDictionaryValue(
+      covariant WrappedAbstractValue? originalValue,
+      Object? allocationNode,
+      MemberEntity? allocationElement,
+      covariant WrappedAbstractValue key,
+      covariant WrappedAbstractValue value,
+      covariant Map<String, AbstractValue> mappings) {
+    return WrappedAbstractValue(_abstractValueDomain.createDictionaryValue(
+        originalValue?._abstractValue,
+        allocationNode,
+        allocationElement,
+        key._abstractValue,
+        value._abstractValue, {
+      for (var entry in mappings.entries)
+        entry.key: (entry.value as WrappedAbstractValue)._abstractValue
+    }));
+  }
+
+  @override
+  bool isDictionary(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isDictionary(value._abstractValue);
+
+  @override
+  AbstractValue getMapValueType(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.getMapValueType(value._abstractValue));
+
+  @override
+  AbstractValue getMapKeyType(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.getMapKeyType(value._abstractValue));
+
+  @override
+  AbstractValue createMapValue(
+          covariant WrappedAbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
+          covariant WrappedAbstractValue key,
+          covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(_abstractValueDomain.createMapValue(
+          originalValue?._abstractValue,
+          allocationNode,
+          allocationElement,
+          key._abstractValue,
+          value._abstractValue));
+
+  @override
+  bool isMap(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isMap(value._abstractValue);
+
+  @override
+  AbstractValue getSetElementType(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.getSetElementType(value._abstractValue));
+
+  @override
+  AbstractValue createSetValue(
+          covariant WrappedAbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
+          covariant WrappedAbstractValue elementType) =>
+      WrappedAbstractValue(_abstractValueDomain.createSetValue(
+          originalValue?._abstractValue,
+          allocationNode,
+          allocationElement,
+          elementType._abstractValue));
+
+  @override
+  bool isSet(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isSet(value._abstractValue);
+
+  @override
+  int? getContainerLength(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getContainerLength(value._abstractValue);
+
+  @override
+  AbstractValue getContainerElementType(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.getContainerElementType(value._abstractValue));
+
+  @override
+  AbstractValue createContainerValue(
+          covariant WrappedAbstractValue? originalValue,
+          Object? allocationNode,
+          MemberEntity? allocationElement,
+          covariant WrappedAbstractValue elementType,
+          int? length) =>
+      WrappedAbstractValue(_abstractValueDomain.createContainerValue(
+          originalValue?._abstractValue,
+          allocationNode,
+          allocationElement,
+          elementType._abstractValue,
+          length));
+
+  @override
+  bool isContainer(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isContainer(value._abstractValue);
+
+  @override
+  AbstractValue computeAbstractValueForConstant(
+          covariant ConstantValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.computeAbstractValueForConstant(value));
+
+  @override
+  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type) {
+    return wrapOrNull(_abstractValueDomain
+        .getAbstractValueForNativeMethodParameterType(type));
+  }
+
+  @override
+  AbstractBool containsAll(covariant WrappedAbstractValue a) =>
+      _abstractValueDomain.containsAll(a._abstractValue);
+
+  @override
+  AbstractBool areDisjoint(
+          covariant WrappedAbstractValue a, covariant WrappedAbstractValue b) =>
+      _abstractValueDomain.areDisjoint(a._abstractValue, b._abstractValue);
+
+  @override
+  AbstractValue intersection(
+          covariant WrappedAbstractValue a, covariant WrappedAbstractValue b) =>
+      WrappedAbstractValue(_abstractValueDomain.intersection(
+          a._abstractValue, b._abstractValue));
+
+  @override
+  AbstractValue unionOfMany(covariant Iterable<AbstractValue> values) {
+    List<AbstractValue> unwrapped_Values = values
+        .map((element) => (element as WrappedAbstractValue)._abstractValue)
+        .toList();
+    return WrappedAbstractValue(
+        _abstractValueDomain.unionOfMany(unwrapped_Values));
+  }
+
+  @override
+  AbstractValue union(
+          covariant WrappedAbstractValue a, covariant WrappedAbstractValue b) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.union(a._abstractValue, b._abstractValue));
+
+  @override
+  AbstractBool isPrimitiveOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isStringOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isStringOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isString(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isString(value._abstractValue);
+
+  @override
+  AbstractBool isBooleanOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isBooleanOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isBoolean(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isBoolean(value._abstractValue);
+
+  @override
+  AbstractBool isTruthy(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isTruthy(value._abstractValue);
+
+  @override
+  AbstractBool isNumberOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isNumberOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isNumber(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isNumber(value._abstractValue);
+
+  @override
+  AbstractBool isIntegerOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isIntegerOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isPositiveIntegerOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPositiveIntegerOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isPositiveInteger(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPositiveInteger(value._abstractValue);
+
+  @override
+  AbstractBool isUInt31(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isUInt31(value._abstractValue);
+
+  @override
+  AbstractBool isUInt32(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isUInt32(value._abstractValue);
+
+  @override
+  AbstractBool isInteger(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isInteger(value._abstractValue);
+
+  @override
+  AbstractBool isInterceptor(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isInterceptor(value._abstractValue);
+
+  @override
+  AbstractBool isPrimitiveString(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveString(value._abstractValue);
+
+  @override
+  AbstractBool isArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isArray(value._abstractValue);
+
+  @override
+  AbstractBool isMutableIndexable(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isMutableIndexable(value._abstractValue);
+
+  @override
+  AbstractBool isMutableArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isMutableArray(value._abstractValue);
+
+  @override
+  AbstractBool isExtendableArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isExtendableArray(value._abstractValue);
+
+  @override
+  AbstractBool isFixedArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isFixedArray(value._abstractValue);
+
+  @override
+  AbstractBool isIndexablePrimitive(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isIndexablePrimitive(value._abstractValue);
+
+  @override
+  AbstractBool isPrimitiveBoolean(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveBoolean(value._abstractValue);
+
+  @override
+  AbstractBool isPrimitiveNumber(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveNumber(value._abstractValue);
+
+  @override
+  AbstractBool isPrimitive(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitive(value._abstractValue);
+
+  @override
+  AbstractBool isNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isNull(value._abstractValue);
+
+  @override
+  AbstractBool isLateSentinel(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isLateSentinel(value._abstractValue);
+
+  @override
+  ClassEntity? getExactClass(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getExactClass(value._abstractValue);
+
+  @override
+  AbstractBool isExact(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isExact(value._abstractValue);
+
+  @override
+  AbstractBool isEmpty(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isEmpty(value._abstractValue);
+
+  @override
+  AbstractBool isInstanceOf(
+          covariant WrappedAbstractValue value, ClassEntity cls) =>
+      _abstractValueDomain.isInstanceOf(value._abstractValue, cls);
+
+  @override
+  AbstractBool isInstanceOfOrNull(
+          covariant WrappedAbstractValue value, ClassEntity cls) =>
+      _abstractValueDomain.isInstanceOfOrNull(value._abstractValue, cls);
+
+  @override
+  AbstractBool containsOnlyType(
+          covariant WrappedAbstractValue value, ClassEntity cls) =>
+      _abstractValueDomain.containsOnlyType(value._abstractValue, cls);
+
+  @override
+  AbstractBool containsType(
+          covariant WrappedAbstractValue value, ClassEntity cls) =>
+      _abstractValueDomain.containsType(value._abstractValue, cls);
+
+  @override
+  AbstractValue includeNull(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.includeNull(value._abstractValue));
+
+  @override
+  AbstractValue excludeNull(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.excludeNull(value._abstractValue));
+
+  @override
+  AbstractValue includeLateSentinel(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.includeLateSentinel(value._abstractValue));
+
+  @override
+  AbstractValue excludeLateSentinel(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.excludeLateSentinel(value._abstractValue));
+
+  @override
+  AbstractBool couldBeTypedArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.couldBeTypedArray(value._abstractValue);
+
+  @override
+  AbstractBool isTypedArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isTypedArray(value._abstractValue);
+
+  @override
+  AbstractValue createNullableSubtype(ClassEntity cls) =>
+      WrappedAbstractValue(_abstractValueDomain.createNullableSubtype(cls));
+
+  @override
+  AbstractValue createNonNullSubtype(ClassEntity cls) =>
+      WrappedAbstractValue(_abstractValueDomain.createNonNullSubtype(cls));
+
+  @override
+  AbstractValue createNonNullSubclass(ClassEntity cls) =>
+      WrappedAbstractValue(_abstractValueDomain.createNonNullSubclass(cls));
+
+  @override
+  AbstractValue createNullableExact(ClassEntity cls) =>
+      WrappedAbstractValue(_abstractValueDomain.createNullableExact(cls));
+
+  @override
+  AbstractValue createNonNullExact(ClassEntity cls) =>
+      WrappedAbstractValue(_abstractValueDomain.createNonNullExact(cls));
+
+  @override
+  AbstractValueWithPrecision createFromStaticType(DartType type,
+      {ClassRelation classRelation = ClassRelation.subtype,
+      required bool nullable}) {
+    var unwrapped = _abstractValueDomain.createFromStaticType(type,
+        classRelation: classRelation, nullable: nullable);
+    return AbstractValueWithPrecision(
+        WrappedAbstractValue(unwrapped.abstractValue), unwrapped.isPrecise);
+  }
+
+  @override
+  AbstractValue get asyncStarStreamType =>
+      WrappedAbstractValue(_abstractValueDomain.asyncStarStreamType);
+
+  @override
+  AbstractValue get asyncFutureType =>
+      WrappedAbstractValue(_abstractValueDomain.asyncFutureType);
+
+  @override
+  AbstractValue get syncStarIterableType =>
+      WrappedAbstractValue(_abstractValueDomain.syncStarIterableType);
+
+  @override
+  AbstractValue get emptyType =>
+      WrappedAbstractValue(_abstractValueDomain.emptyType);
+
+  @override
+  AbstractValue get constMapType =>
+      WrappedAbstractValue(_abstractValueDomain.constMapType);
+
+  @override
+  AbstractValue get constSetType =>
+      WrappedAbstractValue(_abstractValueDomain.constSetType);
+
+  @override
+  AbstractValue get constListType =>
+      WrappedAbstractValue(_abstractValueDomain.constListType);
+
+  @override
+  AbstractValue get positiveIntType =>
+      WrappedAbstractValue(_abstractValueDomain.positiveIntType);
+
+  @override
+  AbstractValue get uint32Type =>
+      WrappedAbstractValue(_abstractValueDomain.uint32Type);
+
+  @override
+  AbstractValue get uint31Type =>
+      WrappedAbstractValue(_abstractValueDomain.uint31Type);
+
+  @override
+  AbstractValue get fixedListType =>
+      WrappedAbstractValue(_abstractValueDomain.fixedListType);
+
+  @override
+  AbstractValue get growableListType =>
+      WrappedAbstractValue(_abstractValueDomain.growableListType);
+
+  @override
+  AbstractValue get mutableArrayType =>
+      WrappedAbstractValue(_abstractValueDomain.mutableArrayType);
+
+  @override
+  AbstractValue get nullType =>
+      WrappedAbstractValue(_abstractValueDomain.nullType);
+
+  @override
+  AbstractValue get nonNullType =>
+      WrappedAbstractValue(_abstractValueDomain.nonNullType);
+
+  @override
+  AbstractValue get lateSentinelType =>
+      WrappedAbstractValue(_abstractValueDomain.lateSentinelType);
+
+  @override
+  AbstractValue get mapType =>
+      WrappedAbstractValue(_abstractValueDomain.mapType);
+
+  @override
+  AbstractValue get setType =>
+      WrappedAbstractValue(_abstractValueDomain.setType);
+
+  @override
+  AbstractValue get listType =>
+      WrappedAbstractValue(_abstractValueDomain.listType);
+
+  @override
+  AbstractValue get stringType =>
+      WrappedAbstractValue(_abstractValueDomain.stringType);
+
+  @override
+  AbstractValue get numType =>
+      WrappedAbstractValue(_abstractValueDomain.numType);
+
+  @override
+  AbstractValue get numNotIntType =>
+      WrappedAbstractValue(_abstractValueDomain.numNotIntType);
+
+  @override
+  AbstractValue get intType =>
+      WrappedAbstractValue(_abstractValueDomain.intType);
+
+  @override
+  AbstractValue get boolType =>
+      WrappedAbstractValue(_abstractValueDomain.boolType);
+
+  @override
+  AbstractValue get functionType =>
+      WrappedAbstractValue(_abstractValueDomain.functionType);
+
+  @override
+  AbstractValue get typeType =>
+      WrappedAbstractValue(_abstractValueDomain.typeType);
+}
+
+class WrappedAbstractValueStrategy implements AbstractValueStrategy {
+  final AbstractValueStrategy _abstractValueStrategy;
+  const WrappedAbstractValueStrategy(this._abstractValueStrategy);
+
+  @override
+  AbstractValueDomain createDomain(JClosedWorld closedWorld) {
+    return WrappedAbstractValueDomain(
+        _abstractValueStrategy.createDomain(closedWorld));
+  }
+
+  @override
+  SelectorConstraintsStrategy createSelectorStrategy() {
+    return WrappedSelectorStrategy(
+        _abstractValueStrategy.createSelectorStrategy());
+  }
+}
+
+class WrappedSelectorStrategy implements SelectorConstraintsStrategy {
+  final SelectorConstraintsStrategy _selectorConstraintsStrategy;
+  const WrappedSelectorStrategy(this._selectorConstraintsStrategy);
+
+  @override
+  UniverseSelectorConstraints createSelectorConstraints(
+      Selector selector, Object? initialConstraint) {
+    return WrappedUniverseSelectorConstraints(
+        _selectorConstraintsStrategy.createSelectorConstraints(
+            selector,
+            initialConstraint == null
+                ? null
+                : (initialConstraint as WrappedAbstractValue)._abstractValue));
+  }
+
+  @override
+  bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member,
+      covariant JClosedWorld world) {
+    return _selectorConstraintsStrategy.appliedUnnamed(
+        dynamicUse.withReceiverConstraint(unwrapOrNull(
+            dynamicUse.receiverConstraint as WrappedAbstractValue?)),
+        member,
+        world);
+  }
+}
+
+class WrappedUniverseSelectorConstraints
+    implements UniverseSelectorConstraints {
+  final UniverseSelectorConstraints _universeSelectorConstraints;
+  const WrappedUniverseSelectorConstraints(this._universeSelectorConstraints);
+
+  @override
+  bool addReceiverConstraint(Object? constraint) =>
+      _universeSelectorConstraints.addReceiverConstraint(constraint == null
+          ? null
+          : (constraint as WrappedAbstractValue)._abstractValue);
+
+  @override
+  bool needsNoSuchMethodHandling(Selector selector, World world) =>
+      _universeSelectorConstraints.needsNoSuchMethodHandling(selector, world);
+
+  @override
+  bool canHit(MemberEntity element, Name name, World world) =>
+      _universeSelectorConstraints.canHit(element, name, world);
+
+  @override
+  String toString() => 'WrappedUniverseSelectorConstraints:$hashCode';
+}
diff --git a/pkg/compiler/lib/src/io/code_output.dart b/pkg/compiler/lib/src/io/code_output.dart
index 58812cd..7dc22c0 100644
--- a/pkg/compiler/lib/src/io/code_output.dart
+++ b/pkg/compiler/lib/src/io/code_output.dart
@@ -196,7 +196,7 @@
 class CodeBuffer extends AbstractCodeOutput implements BufferedCodeOutput {
   StringBuffer buffer = StringBuffer();
 
-  CodeBuffer([List<CodeOutputListener>? listeners]) : super(listeners);
+  CodeBuffer([super.listeners]);
 
   @override
   void _addInternal(String text) {
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index a07177a..62bae4e 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -399,8 +399,7 @@
   @override
   final String sourceName;
 
-  OffsetSourceLocation(SourceFile sourceFile, this.offset, this.sourceName)
-      : super(sourceFile);
+  OffsetSourceLocation(super.sourceFile, this.offset, this.sourceName);
 
   @override
   String get shortText => '${super.shortText}:$sourceName';
diff --git a/pkg/compiler/lib/src/ir/closure.dart b/pkg/compiler/lib/src/ir/closure.dart
index d409cb6..88df3b3 100644
--- a/pkg/compiler/lib/src/ir/closure.dart
+++ b/pkg/compiler/lib/src/ir/closure.dart
@@ -83,7 +83,7 @@
   String toString() {
     StringBuffer sb = StringBuffer();
     sb.write('KernelScopeInfo(this=$hasThisLocal,');
-    sb.write('freeVriables=$freeVariables,');
+    sb.write('freeVariables=$freeVariables,');
     sb.write('localsUsedInTryOrSync={${localsUsedInTryOrSync.join(', ')}}');
     String comma = '';
     sb.write('freeVariablesForRti={');
@@ -98,24 +98,15 @@
 
 class KernelCapturedScope extends KernelScopeInfo {
   KernelCapturedScope(
-      Set<ir.VariableDeclaration> boxedVariables,
-      NodeBox? capturedVariablesAccessor,
-      Set<ir.VariableDeclaration> localsUsedInTryOrSync,
-      Set<ir.Node /* VariableDeclaration | TypeVariableTypeWithContext */ >
-          freeVariables,
-      Map<TypeVariableTypeWithContext, Set<VariableUse>> freeVariablesForRti,
-      bool thisUsedAsFreeVariable,
-      Set<VariableUse> thisUsedAsFreeVariableIfNeedsRti,
-      bool hasThisLocal)
-      : super.withBoxedVariables(
-            boxedVariables,
-            capturedVariablesAccessor,
-            localsUsedInTryOrSync,
-            freeVariables,
-            freeVariablesForRti,
-            thisUsedAsFreeVariable,
-            thisUsedAsFreeVariableIfNeedsRti,
-            hasThisLocal);
+      super.boxedVariables,
+      super.capturedVariablesAccessor,
+      super.localsUsedInTryOrSync,
+      super.freeVariables,
+      super.freeVariablesForRti,
+      super.thisUsedAsFreeVariable,
+      super.thisUsedAsFreeVariableIfNeedsRti,
+      super.hasThisLocal)
+      : super.withBoxedVariables();
 
   // Loops through the free variables of an existing KernelCapturedScope and
   // creates a new KernelCapturedScope that only captures type variables.
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index 5704733..77dd1cd 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -28,8 +28,8 @@
   final ImpactData _data = ImpactData();
   final KernelToElementMapForImpactData _elementMap;
 
-  @override
-  final VariableScopeModel variableScopeModel;
+  // Note: this may be null for builders associated with abstract methods.
+  final VariableScopeModel? _variableScopeModel;
 
   @override
   final ir.StaticTypeContext staticTypeContext;
@@ -45,12 +45,15 @@
       this.staticTypeContext,
       StaticTypeCacheImpl staticTypeCache,
       ir.ClassHierarchy classHierarchy,
-      this.variableScopeModel,
+      this._variableScopeModel,
       {this.useAsserts = false,
       this.inferEffectivelyFinalVariableTypes = true})
       : super(
             staticTypeContext.typeEnvironment, classHierarchy, staticTypeCache);
 
+  @override
+  VariableScopeModel get variableScopeModel => _variableScopeModel!;
+
   CommonElements get _commonElements => _elementMap.commonElements;
 
   DiagnosticReporter get _reporter => _elementMap.reporter;
diff --git a/pkg/compiler/lib/src/ir/modular.dart b/pkg/compiler/lib/src/ir/modular.dart
index 4713bbe..578ee2f 100644
--- a/pkg/compiler/lib/src/ir/modular.dart
+++ b/pkg/compiler/lib/src/ir/modular.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 
@@ -49,7 +47,7 @@
   // TODO(joshualitt) Support serializing ModularMemberData;
   final Map<Uri, Map<ir.Member, ImpactBuilderData>> impactData;
 
-  ModuleData([Map<Uri, Map<ir.Member, ImpactBuilderData>> impactData])
+  ModuleData([Map<Uri, Map<ir.Member, ImpactBuilderData>>? impactData])
       : this.impactData = impactData ?? {};
 
   factory ModuleData.fromImpactData(
@@ -118,7 +116,7 @@
 DiagnosticMessage _createDiagnosticMessage(
     DiagnosticReporter reporter, ir.LocatedMessage message) {
   var sourceSpan = SourceSpan(
-      message.uri, message.charOffset, message.charOffset + message.length);
+      message.uri!, message.charOffset, message.charOffset + message.length);
   return reporter.createMessage(
       sourceSpan, MessageKind.GENERIC, {'text': message.problemMessage});
 }
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 0ae7ee1..fc95444 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -69,8 +69,7 @@
   ir.Library? _currentLibrary;
 
   StaticTypeVisitor(
-      ir.TypeEnvironment typeEnvironment, this.hierarchy, this._staticTypeCache)
-      : super(typeEnvironment);
+      super.typeEnvironment, this.hierarchy, this._staticTypeCache);
 
   StaticTypeCache getStaticTypeCache() {
     return StaticTypeCache(_staticTypeCache._expressionTypes,
diff --git a/pkg/compiler/lib/src/ir/static_type_base.dart b/pkg/compiler/lib/src/ir/static_type_base.dart
index d71ba62..030c801 100644
--- a/pkg/compiler/lib/src/ir/static_type_base.dart
+++ b/pkg/compiler/lib/src/ir/static_type_base.dart
@@ -18,9 +18,7 @@
 /// Special interface type used to signal that the static type of an expression
 /// has precision of a this-expression.
 class ThisInterfaceType extends ir.InterfaceType {
-  ThisInterfaceType(ir.Class classNode, ir.Nullability nullability,
-      [List<ir.DartType>? typeArguments])
-      : super(classNode, nullability, typeArguments);
+  ThisInterfaceType(super.classNode, super.nullability, [super.typeArguments]);
 
   static from(ir.InterfaceType? type) => type != null
       ? ThisInterfaceType(type.classNode, type.nullability, type.typeArguments)
@@ -41,9 +39,7 @@
 /// Special interface type used to signal that the static type of an expression
 /// is exact, i.e. the runtime type is not a subtype or subclass of the type.
 class ExactInterfaceType extends ir.InterfaceType {
-  ExactInterfaceType(ir.Class classNode, ir.Nullability nullability,
-      [List<ir.DartType>? typeArguments])
-      : super(classNode, nullability, typeArguments);
+  ExactInterfaceType(super.classNode, super.nullability, [super.typeArguments]);
 
   static from(ir.InterfaceType? type) => type != null
       ? ExactInterfaceType(type.classNode, type.nullability, type.typeArguments)
diff --git a/pkg/compiler/lib/src/js_backend/annotations.dart b/pkg/compiler/lib/src/js_backend/annotations.dart
index 91fa09e..e5c59cb 100644
--- a/pkg/compiler/lib/src/js_backend/annotations.dart
+++ b/pkg/compiler/lib/src/js_backend/annotations.dart
@@ -401,7 +401,7 @@
   /// Pragma annotation environments for annotatable places in the Kernel
   /// AST. These annotations generated on demand and not precomputed or
   /// persisted.  This map is a cache of the pragma annotation environment and
-  /// its enclosing enviroments.
+  /// its enclosing environments.
   // TODO(49475): Periodically clear this map to release references to tree
   // nodes.
   final Map<ir.Annotatable, DirectivesContext> _nodeToContextMap = {};
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 40c830d..4046f7e 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -263,7 +263,7 @@
     String className = classElement.name;
     if (!identical(classElement, _commonElements.constSetLiteralClass)) {
       failedAt(
-          classElement, "Compiler encoutered unexpected set class $className");
+          classElement, "Compiler encountered unexpected set class $className");
     }
 
     List<jsAst.Expression> arguments = [
diff --git a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
index a5a1606..4102ce1 100644
--- a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
@@ -84,14 +84,13 @@
   final CustomElementsAnalysisJoin join;
 
   CustomElementsResolutionAnalysis(
-      ElementEnvironment elementEnvironment,
-      CommonElements commonElements,
-      NativeBasicData nativeData,
+      super.elementEnvironment,
+      super.commonElements,
+      super.nativeData,
       BackendUsageBuilder backendUsageBuilder)
       : join = CustomElementsAnalysisJoin(
             elementEnvironment, commonElements, nativeData,
-            backendUsageBuilder: backendUsageBuilder),
-        super(elementEnvironment, commonElements, nativeData) {
+            backendUsageBuilder: backendUsageBuilder) {
     // TODO(sra): Remove this work-around.  We should mark allClassesSelected in
     // both joins only when we see a construct generating an unknown [Type] but
     // we can't currently recognize all cases.  In particular, the work-around
diff --git a/pkg/compiler/lib/src/js_backend/field_analysis.dart b/pkg/compiler/lib/src/js_backend/field_analysis.dart
index 5cc3a4b..a1e742b 100644
--- a/pkg/compiler/lib/src/js_backend/field_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/field_analysis.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 
@@ -17,7 +15,7 @@
 import '../js_model/js_to_frontend_map.dart' show JsToFrontendMap;
 import '../kernel/element_map.dart' show KernelToElementMap;
 import '../kernel/kelements.dart' show KClass, KField, KConstructor;
-import '../kernel/kernel_world.dart';
+import '../kernel/kernel_world_interfaces.dart';
 import '../options.dart';
 import '../serialization/serialization.dart';
 import '../universe/member_usage.dart';
@@ -57,8 +55,8 @@
       if (!field.isInstanceMember) continue;
 
       FieldEntity fieldElement = _elementMap.getField(field);
-      ir.Expression expression = field.initializer;
-      ConstantValue value;
+      ir.Expression? expression = field.initializer;
+      ConstantValue? value;
       if (expression is ir.StaticInvocation &&
           identical(
               expression.target, _elementMap.coreTypes.createSentinelMethod)) {
@@ -69,19 +67,20 @@
             requireConstant: false, implicitNull: true);
       }
       if (value != null && value.isConstant) {
-        fieldData[fieldElement] = AllocatorData(value);
+        fieldData[fieldElement as KField] = AllocatorData(value);
       }
     }
 
     for (ir.Constructor constructor in classNode.constructors) {
-      KConstructor constructorElement = _elementMap.getConstructor(constructor);
+      KConstructor constructorElement =
+          _elementMap.getConstructor(constructor) as KConstructor;
       ir.StaticTypeContext staticTypeContext =
           _elementMap.getStaticTypeContext(constructorElement);
       constructors.add(constructorElement);
       for (ir.Initializer initializer in constructor.initializers) {
         if (initializer is ir.FieldInitializer) {
-          AllocatorData data =
-              fieldData[_elementMap.getField(initializer.field)];
+          AllocatorData? data =
+              fieldData[_elementMap.getField(initializer.field) as KField];
           if (data == null) {
             // TODO(johnniwinther): Support initializers with side-effects?
 
@@ -91,7 +90,7 @@
 
           Initializer initializerValue = const Initializer.complex();
           ir.Expression value = initializer.value;
-          ConstantValue constantValue = _elementMap.getConstantValue(
+          ConstantValue? constantValue = _elementMap.getConstantValue(
               staticTypeContext, value,
               requireConstant: false, implicitNull: true);
           if (constantValue != null && constantValue.isConstant) {
@@ -132,9 +131,9 @@
   }
 
   void registerStaticField(KField field, EvaluationComplexity complexity) {
-    ir.Field node = _elementMap.getMemberNode(field);
-    ir.Expression expression = node.initializer;
-    ConstantValue value;
+    ir.Field node = _elementMap.getMemberNode(field) as ir.Field;
+    ir.Expression? expression = node.initializer;
+    ConstantValue? value;
     if (expression is ir.StaticInvocation &&
         identical(
             expression.target, _elementMap.coreTypes.createSentinelMethod)) {
@@ -152,11 +151,11 @@
     _staticFieldData[field] = StaticFieldData(value, complexity);
   }
 
-  AllocatorData getAllocatorDataForTesting(KField field) {
-    return _classData[field.enclosingClass].fieldData[field];
+  AllocatorData? getAllocatorDataForTesting(KField field) {
+    return _classData[field.enclosingClass!]!.fieldData[field];
   }
 
-  StaticFieldData getStaticFieldDataForTesting(KField field) {
+  StaticFieldData? getStaticFieldDataForTesting(KField field) {
     return _staticFieldData[field];
   }
 }
@@ -169,16 +168,16 @@
 }
 
 class StaticFieldData {
-  final ConstantValue initialValue;
+  final ConstantValue? initialValue;
   final EvaluationComplexity complexity;
 
   StaticFieldData(this.initialValue, this.complexity);
 
-  bool get hasDependencies => complexity != null && complexity.fields != null;
+  bool get hasDependencies => complexity.fields != null;
 }
 
 class AllocatorData {
-  final ConstantValue initialValue;
+  final ConstantValue? initialValue;
   final Map<KConstructor, Initializer> initializers = {};
 
   AllocatorData(this.initialValue);
@@ -198,9 +197,9 @@
 
 class Initializer {
   final InitializerKind kind;
-  final int index;
-  final String name;
-  final ConstantValue value;
+  final int? index;
+  final String? name;
+  final ConstantValue? value;
 
   Initializer.direct(this.value)
       : kind = InitializerKind.direct,
@@ -221,18 +220,17 @@
         name = null,
         value = null;
 
-  String shortText(DartTypes dartTypes) {
+  String shortText(DartTypes? dartTypes) {
     switch (kind) {
       case InitializerKind.direct:
-        return value.toStructuredText(dartTypes);
+        return value!.toStructuredText(dartTypes);
       case InitializerKind.positional:
-        return '$index:${value.toStructuredText(dartTypes)}';
+        return '$index:${value!.toStructuredText(dartTypes)}';
       case InitializerKind.named:
-        return '$name:${value.toStructuredText(dartTypes)}';
+        return '$name:${value!.toStructuredText(dartTypes)}';
       case InitializerKind.complex:
         return '?';
     }
-    throw UnsupportedError('Unexpected kind $kind');
   }
 
   @override
@@ -282,7 +280,7 @@
     closedWorld.fieldAnalysis._classData
         .forEach((ClassEntity cls, ClassData classData) {
       classData.fieldData.forEach((KField kField, AllocatorData data) {
-        JField jField = map.toBackendMember(kField);
+        JField? jField = map.toBackendMember(kField) as JField?;
         if (jField == null) {
           return;
         }
@@ -290,7 +288,7 @@
         // TODO(johnniwinther): Should elided static fields be removed from the
         // J model? Static setters might still assign to them.
 
-        MemberUsage memberUsage = closedWorld.liveMemberUsage[kField];
+        MemberUsage memberUsage = closedWorld.liveMemberUsage[kField]!;
         if (!memberUsage.hasRead) {
           if (canBeElided(kField)) {
             fieldData[jField] = const FieldAnalysisData(isElided: true);
@@ -301,10 +299,10 @@
           // they could be.
         } else {
           if (data.initialValue != null) {
-            ConstantValue initialValue;
+            ConstantValue? initialValue;
             bool isTooComplex = false;
 
-            void includeInitialValue(ConstantValue value) {
+            void includeInitialValue(ConstantValue? value) {
               if (isTooComplex) return;
               if (initialValue == null) {
                 initialValue = value;
@@ -314,7 +312,7 @@
               }
             }
 
-            memberUsage.initialConstants.forEach(includeInitialValue);
+            memberUsage.initialConstants!.forEach(includeInitialValue);
 
             bool inAllConstructors = true;
             for (KConstructor constructor in classData.constructors) {
@@ -322,18 +320,18 @@
                 break;
               }
 
-              MemberUsage constructorUsage =
+              MemberUsage? constructorUsage =
                   closedWorld.liveMemberUsage[constructor];
               if (constructorUsage == null) {
                 // This constructor isn't called.
                 continue;
               }
-              ParameterStructure invokedParameters =
+              ParameterStructure? invokedParameters =
                   closedWorld.annotationsData.hasNoElision(constructor)
                       ? constructor.parameterStructure
                       : constructorUsage.invokedParameters;
 
-              Initializer initializer = data.initializers[constructor];
+              Initializer? initializer = data.initializers[constructor];
               if (initializer == null) {
                 inAllConstructors = false;
               } else {
@@ -342,15 +340,15 @@
                     includeInitialValue(initializer.value);
                     break;
                   case InitializerKind.positional:
-                    if (initializer.index >=
-                        invokedParameters.positionalParameters) {
+                    if (initializer.index! >=
+                        invokedParameters!.positionalParameters) {
                       includeInitialValue(initializer.value);
                     } else {
                       isTooComplex = true;
                     }
                     break;
                   case InitializerKind.named:
-                    if (!invokedParameters.namedParameters
+                    if (!invokedParameters!.namedParameters
                         .contains(initializer.name)) {
                       includeInitialValue(initializer.value);
                     } else {
@@ -367,12 +365,11 @@
               includeInitialValue(data.initialValue);
             }
             if (!isTooComplex && initialValue != null) {
-              ConstantValue value = map.toBackendConstant(initialValue);
+              ConstantValue value = map.toBackendConstant(initialValue!)!;
               bool isEffectivelyConstant = false;
               bool isAssignedOnce = false;
               bool isLateBackingField = false;
               bool isInitializedInAllocator = false;
-              assert(value != null);
               if (!memberUsage.hasWrite && canBeElided(kField)) {
                 isEffectivelyConstant = true;
               } else if (value is PrimitiveConstantValue ||
@@ -406,7 +403,7 @@
         .forEach((MemberEntity member, MemberUsage memberUsage) {
       if (member.isField && !member.isInstanceMember) {
         StaticFieldData staticFieldData =
-            closedWorld.fieldAnalysis._staticFieldData[member];
+            closedWorld.fieldAnalysis._staticFieldData[member as KField]!;
         if (staticFieldData.hasDependencies) {
           dependentFields.add(member);
         } else {
@@ -431,12 +428,12 @@
     ///
     /// If the data is currently been computed, that is, [kField] has a
     /// cyclic dependency, `null` is returned.
-    FieldAnalysisData processField(KField kField) {
-      JField jField = map.toBackendMember(kField);
+    FieldAnalysisData? processField(KField kField) {
+      JField? jField = map.toBackendMember(kField) as JField?;
       // TODO(johnniwinther): Can we assert that [jField] exists?
       if (jField == null) return null;
 
-      FieldAnalysisData data = fieldData[jField];
+      FieldAnalysisData? data = fieldData[jField];
       if (processedFields.contains(kField)) {
         // We only store data for non-trivial [FieldAnalysisData].
         return data ?? const FieldAnalysisData();
@@ -446,14 +443,14 @@
         return null;
       }
       currentFields.add(kField);
-      MemberUsage memberUsage = closedWorld.liveMemberUsage[kField];
+      MemberUsage memberUsage = closedWorld.liveMemberUsage[kField]!;
       if (!memberUsage.hasRead && canBeElided(kField)) {
         data = fieldData[jField] = const FieldAnalysisData(isElided: true);
       } else {
         bool isEffectivelyFinal = !memberUsage.hasWrite;
         StaticFieldData staticFieldData =
-            closedWorld.fieldAnalysis._staticFieldData[kField];
-        ConstantValue value = map
+            closedWorld.fieldAnalysis._staticFieldData[kField]!;
+        ConstantValue? value = map
             .toBackendConstant(staticFieldData.initialValue, allowNull: true);
 
         // If the field is effectively final with a constant initializer we
@@ -473,8 +470,8 @@
         // order indices, [eagerFieldDependencies] is non-null if the field has
         // dependencies but only hold these when [retainDataForTesting] is
         // `true`.
-        List<FieldEntity> eagerFieldDependencies;
-        int creationIndex = null;
+        List<FieldEntity>? eagerFieldDependencies;
+        int? creationIndex = null;
 
         if (isElided) {
           // If the field is elided it needs no initializer and is therefore
@@ -493,11 +490,12 @@
             // The field might be eager depending on the initializer complexity
             // and its dependencies.
             EvaluationComplexity complexity = staticFieldData.complexity;
-            isEager = complexity?.isEager ?? false;
+            isEager = complexity.isEager;
             if (isEager && complexity.fields != null) {
-              for (ir.Field node in complexity.fields) {
-                KField otherField = closedWorld.elementMap.getField(node);
-                FieldAnalysisData otherData = processField(otherField);
+              for (ir.Field node in complexity.fields!) {
+                KField otherField =
+                    closedWorld.elementMap.getField(node) as KField;
+                FieldAnalysisData? otherData = processField(otherField);
                 if (otherData == null) {
                   // Cyclic dependency on [otherField].
                   isEager = false;
@@ -518,7 +516,8 @@
                 if (!otherData.isEffectivelyConstant) {
                   eagerFieldDependencies ??= [];
                   if (retainDataForTesting) {
-                    eagerFieldDependencies.add(map.toBackendMember(otherField));
+                    eagerFieldDependencies
+                        .add(map.toBackendMember(otherField) as FieldEntity);
                   }
                 }
               }
@@ -560,8 +559,8 @@
       int result =
           compareLibrariesUris(a.library.canonicalUri, b.library.canonicalUri);
       if (result != 0) return result;
-      ir.Location aLocation = closedWorld.elementMap.getMemberNode(a).location;
-      ir.Location bLocation = closedWorld.elementMap.getMemberNode(b).location;
+      ir.Location aLocation = closedWorld.elementMap.getMemberNode(a).location!;
+      ir.Location bLocation = closedWorld.elementMap.getMemberNode(b).location!;
       result = compareSourceUris(aLocation.file, bLocation.file);
       if (result != 0) return result;
       result = aLocation.line.compareTo(bLocation.line);
@@ -586,7 +585,7 @@
 class FieldAnalysisData {
   static const String tag = 'field-analysis-data';
 
-  final ConstantValue initialValue;
+  final ConstantValue? initialValue;
   final bool isInitializedInAllocator;
   final bool isEffectivelyFinal;
   final bool isElided;
@@ -607,9 +606,9 @@
   /// Index ascribed to eager fields that depend on other fields. This is
   /// used to sort the field in emission to ensure that used fields have been
   /// initialized when read.
-  final int eagerCreationIndex;
+  final int? eagerCreationIndex;
 
-  final List<FieldEntity> eagerFieldDependenciesForTesting;
+  final List<FieldEntity>? eagerFieldDependenciesForTesting;
 
   const FieldAnalysisData(
       {this.initialValue,
@@ -625,15 +624,15 @@
   factory FieldAnalysisData.fromDataSource(DataSourceReader source) {
     source.begin(tag);
 
-    ConstantValue initialValue = source.readConstantOrNull();
+    ConstantValue? initialValue = source.readConstantOrNull();
     bool isInitializedInAllocator = source.readBool();
     bool isEffectivelyFinal = source.readBool();
     bool isElided = source.readBool();
     bool isAssignedOnce = source.readBool();
     bool isLateBackingField = source.readBool();
     bool isEager = source.readBool();
-    int eagerCreationIndex = source.readIntOrNull();
-    List<FieldEntity> eagerFieldDependencies =
+    int? eagerCreationIndex = source.readIntOrNull();
+    List<FieldEntity>? eagerFieldDependencies =
         source.readMembersOrNull<FieldEntity>();
     source.end(tag);
     return FieldAnalysisData(
@@ -669,7 +668,7 @@
   bool get isEffectivelyConstant =>
       isEffectivelyFinal && isElided && initialValue != null;
 
-  ConstantValue get constantValue => isEffectivelyFinal ? initialValue : null;
+  ConstantValue? get constantValue => isEffectivelyFinal ? initialValue : null;
 
   @override
   String toString() => 'FieldAnalysisData('
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
index f237a2b..e710d15 100644
--- a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -58,7 +58,7 @@
   // number of fields preceding the current field in its classes inheritance
   // chain.
   //
-  // The implementation assumes that names are requedsted in order, that is the
+  // The implementation assumes that names are requested in order, that is the
   // name at position i+1 is requested after the name at position i was
   // requested.
   jsAst.Name getName(int index) {
diff --git a/pkg/compiler/lib/src/js_backend/impact_transformer.dart b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
index e4f6701..8afc33f 100644
--- a/pkg/compiler/lib/src/js_backend/impact_transformer.dart
+++ b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
@@ -71,7 +71,7 @@
     }
     if (typeWithoutNullability is InterfaceType &&
         _nativeData.isNativeClass(typeWithoutNullability.element)) {
-      // We will neeed to add the "$is" and "$as" properties on the
+      // We will need to add the "$is" and "$as" properties on the
       // JavaScript object prototype, so we make sure
       // [:defineProperty:] is compiled.
       _impacts.nativeTypeCheck.registerImpact(transformed, _elementEnvironment);
@@ -152,8 +152,7 @@
     }
 
     for (Set<ClassEntity> classes in impact.specializedGetInterceptors) {
-      _oneShotInterceptorData.registerSpecializedGetInterceptor(
-          classes, _namer);
+      _oneShotInterceptorData.registerSpecializedGetInterceptor(classes);
     }
 
     if (impact.usesInterceptor) {
diff --git a/pkg/compiler/lib/src/js_backend/interceptor_data.dart b/pkg/compiler/lib/src/js_backend/interceptor_data.dart
index 299dd02..21c6f2a 100644
--- a/pkg/compiler/lib/src/js_backend/interceptor_data.dart
+++ b/pkg/compiler/lib/src/js_backend/interceptor_data.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 library js_backend.interceptor_data;
 
 import '../common/elements.dart'
@@ -16,8 +14,9 @@
 import '../serialization/serialization.dart';
 import '../universe/class_set.dart';
 import '../universe/selector.dart';
-import '../world.dart' show JClosedWorld;
-import 'namer.dart' show ModularNamer, suffixForGetInterceptor;
+import '../world_interfaces.dart' show JClosedWorld;
+import 'namer_interfaces.dart' show ModularNamer;
+import 'namer_migrated.dart' show suffixForGetInterceptor;
 import 'native_data.dart';
 
 abstract class InterceptorData {
@@ -175,18 +174,13 @@
 
   @override
   bool isInterceptedMixinSelector(
-      Selector selector, AbstractValue mask, JClosedWorld closedWorld) {
-    Set<MemberEntity> elements =
-        _interceptedMixinElements.putIfAbsent(selector.name, () {
-      Set<MemberEntity> elements = interceptedMembers[selector.name];
-      if (elements == null) return null;
-      return elements
-          .where((element) => classesMixedIntoInterceptedClasses
-              .contains(element.enclosingClass))
-          .toSet();
-    });
-
-    if (elements == null) return false;
+      Selector selector, AbstractValue? mask, JClosedWorld closedWorld) {
+    Set<MemberEntity> elements = _interceptedMixinElements[selector.name] ??=
+        (interceptedMembers[selector.name]
+                ?.where((element) => classesMixedIntoInterceptedClasses
+                    .contains(element.enclosingClass))
+                .toSet() ??
+            const {});
     if (elements.isEmpty) return false;
     return elements.any((element) {
       return selector.applies(element) &&
@@ -215,21 +209,21 @@
   @override
   Set<ClassEntity> getInterceptedClassesOn(
       String name, JClosedWorld closedWorld) {
-    Set<MemberEntity> intercepted = interceptedMembers[name];
+    final intercepted = interceptedMembers[name];
     if (intercepted == null) return _noClasses;
     return _interceptedClassesCache.putIfAbsent(name, () {
       // Populate the cache by running through all the elements and
       // determine if the given selector applies to them.
       Set<ClassEntity> result = {};
       for (MemberEntity element in intercepted) {
-        ClassEntity classElement = element.enclosingClass;
+        final classElement = element.enclosingClass!;
         if (_isCompileTimeOnlyClass(classElement)) continue;
         if (_nativeData.isNativeOrExtendsNative(classElement) ||
             interceptedClasses.contains(classElement)) {
           result.add(classElement);
         }
         if (classesMixedIntoInterceptedClasses.contains(classElement)) {
-          Set<ClassEntity> nativeSubclasses =
+          final nativeSubclasses =
               nativeSubclassesOfMixin(classElement, closedWorld);
           if (nativeSubclasses != null) result.addAll(nativeSubclasses);
         }
@@ -238,16 +232,15 @@
     });
   }
 
-  Set<ClassEntity> nativeSubclassesOfMixin(
+  Set<ClassEntity>? nativeSubclassesOfMixin(
       ClassEntity mixin, JClosedWorld closedWorld) {
     Iterable<ClassEntity> uses = closedWorld.mixinUsesOf(mixin);
-    Set<ClassEntity> result = null;
+    Set<ClassEntity>? result;
     for (ClassEntity use in uses) {
       closedWorld.classHierarchy.forEachStrictSubclassOf(use,
           (ClassEntity subclass) {
         if (_nativeData.isNativeOrExtendsNative(subclass)) {
-          if (result == null) result = {};
-          result.add(subclass);
+          (result ??= {}).add(subclass);
         }
         return IterationStep.CONTINUE;
       });
@@ -256,7 +249,7 @@
   }
 
   @override
-  bool isInterceptedClass(ClassEntity element) {
+  bool isInterceptedClass(ClassEntity? element) {
     if (element == null) return false;
     if (_nativeData.isNativeOrExtendsNative(element)) return true;
     if (interceptedClasses.contains(element)) return true;
@@ -275,7 +268,7 @@
 
     if (!closedWorld.dartTypes.treatAsRawType(type)) return false;
     if (type is FutureOrType) return false;
-    InterfaceType interfaceType = type;
+    final interfaceType = type as InterfaceType;
     ClassEntity classElement = interfaceType.element;
     if (isInterceptedClass(classElement)) return false;
     return closedWorld.classHierarchy.hasOnlySubclasses(classElement);
@@ -320,7 +313,7 @@
       if (member.name == Identifiers.call) return;
       // All methods on [Object] are shadowed by [Interceptor].
       if (cls == _commonElements.objectClass) return;
-      Set<MemberEntity> set = _interceptedElements[member.name] ??= {};
+      final set = _interceptedElements[member.name!] ??= {};
       set.add(member);
     });
 
@@ -337,7 +330,7 @@
           (ClassEntity cls, MemberEntity member) {
         // All methods on [Object] are shadowed by [Interceptor].
         if (cls == _commonElements.objectClass) return;
-        Set<MemberEntity> set = _interceptedElements[member.name] ??= {};
+        final set = _interceptedElements[member.name!] ??= {};
         set.add(member);
       });
     }
@@ -386,12 +379,11 @@
     OneShotInterceptor interceptor =
         interceptors[key] ??= OneShotInterceptor(key, selector);
     interceptor.classes.addAll(classes);
-    registerSpecializedGetInterceptor(classes, namer);
+    registerSpecializedGetInterceptor(classes);
     return namer.nameForOneShotInterceptor(selector, classes);
   }
 
-  void registerSpecializedGetInterceptor(
-      Set<ClassEntity> classes, ModularNamer namer) {
+  void registerSpecializedGetInterceptor(Iterable<ClassEntity> classes) {
     if (classes.contains(_commonElements.jsInterceptorClass)) {
       // We can't use a specialized [getInterceptorMethod], so we make
       // sure we emit the one with all checks.
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index b0f5964..877a64b 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -35,6 +35,10 @@
 import '../world.dart' show JClosedWorld;
 import 'deferred_holder_expression.dart';
 import 'native_data.dart';
+import 'namer_interfaces.dart' as interfaces;
+import 'namer_migrated.dart';
+
+export 'namer_migrated.dart' show suffixForGetInterceptor;
 
 part 'field_naming_mixin.dart';
 part 'frequency_namer.dart';
@@ -1554,38 +1558,6 @@
       'FutureOr<${_represent(type.typeArgument)}>';
 }
 
-/// Returns a unique suffix for an intercepted accesses to [classes]. This is
-/// used as the suffix for emitted interceptor methods and as the unique key
-/// used to distinguish equivalences of sets of intercepted classes.
-String suffixForGetInterceptor(CommonElements commonElements,
-    NativeData nativeData, Iterable<ClassEntity> classes) {
-  String abbreviate(ClassEntity cls) {
-    if (cls == commonElements.objectClass) return "o";
-    if (cls == commonElements.jsStringClass) return "s";
-    if (cls == commonElements.jsArrayClass) return "a";
-    if (cls == commonElements.jsNumNotIntClass) return "d";
-    if (cls == commonElements.jsIntClass) return "i";
-    if (cls == commonElements.jsNumberClass) return "n";
-    if (cls == commonElements.jsNullClass) return "u";
-    if (cls == commonElements.jsBoolClass) return "b";
-    if (cls == commonElements.jsInterceptorClass) return "I";
-    return cls.name;
-  }
-
-  List<String> names = classes
-      .where((cls) => !nativeData.isNativeOrExtendsNative(cls))
-      .map(abbreviate)
-      .toList();
-  // There is one dispatch mechanism for all native classes.
-  if (classes.any((cls) => nativeData.isNativeOrExtendsNative(cls))) {
-    names.add("x");
-  }
-  // Sort the names of the classes after abbreviating them to ensure
-  // the suffix is stable and predictable for the suggested names.
-  names.sort();
-  return names.join();
-}
-
 /// Generator of names for [ConstantValue] values.
 ///
 /// The names are stable under perturbations of the source.  The name is either
@@ -2133,7 +2105,7 @@
 }
 
 /// Namer interface that can be used in modular code generation.
-abstract class ModularNamer {
+abstract class ModularNamer implements interfaces.ModularNamer {
   FixedNames get fixedNames;
 
   /// Returns a variable use for accessing constants.
@@ -2241,6 +2213,7 @@
 
   /// Property name used for the one-shot interceptor method for the given
   /// [selector] and return-type specialization.
+  @override
   jsAst.Name nameForOneShotInterceptor(
       Selector selector, Set<ClassEntity> classes);
 
@@ -2372,6 +2345,7 @@
 
   /// Returns the string that is to be used as the result of a call to
   /// [JS_GET_NAME] at [node] with argument [name].
+  @override
   jsAst.Name getNameForJsGetName(Spannable spannable, JsGetName name) {
     switch (name) {
       case JsGetName.GETTER_PREFIX:
diff --git a/pkg/compiler/lib/src/js_backend/namer_interfaces.dart b/pkg/compiler/lib/src/js_backend/namer_interfaces.dart
new file mode 100644
index 0000000..41b211d
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/namer_interfaces.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, 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 '../common.dart';
+import '../elements/entities.dart';
+import '../js/js.dart' as jsAst;
+import '../universe/selector.dart' show Selector;
+import 'package:js_shared/synced/embedded_names.dart' show JsGetName;
+
+abstract class ModularNamer {
+  jsAst.Name nameForOneShotInterceptor(
+      Selector selector, Set<ClassEntity> classes);
+  jsAst.Name getNameForJsGetName(Spannable spannable, JsGetName name);
+}
diff --git a/pkg/compiler/lib/src/js_backend/namer_migrated.dart b/pkg/compiler/lib/src/js_backend/namer_migrated.dart
new file mode 100644
index 0000000..5638e4a
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/namer_migrated.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2022, 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 '../common/elements.dart';
+import '../elements/entities.dart';
+import '../js_backend/native_data.dart';
+
+/// Returns a unique suffix for an intercepted accesses to [classes]. This is
+/// used as the suffix for emitted interceptor methods and as the unique key
+/// used to distinguish equivalences of sets of intercepted classes.
+String suffixForGetInterceptor(CommonElements commonElements,
+    NativeData nativeData, Iterable<ClassEntity> classes) {
+  String abbreviate(ClassEntity cls) {
+    if (cls == commonElements.objectClass) return "o";
+    if (cls == commonElements.jsStringClass) return "s";
+    if (cls == commonElements.jsArrayClass) return "a";
+    if (cls == commonElements.jsNumNotIntClass) return "d";
+    if (cls == commonElements.jsIntClass) return "i";
+    if (cls == commonElements.jsNumberClass) return "n";
+    if (cls == commonElements.jsNullClass) return "u";
+    if (cls == commonElements.jsBoolClass) return "b";
+    if (cls == commonElements.jsInterceptorClass) return "I";
+    return cls.name;
+  }
+
+  List<String> names = classes
+      .where((cls) => !nativeData.isNativeOrExtendsNative(cls))
+      .map(abbreviate)
+      .toList();
+  // There is one dispatch mechanism for all native classes.
+  if (classes.any((cls) => nativeData.isNativeOrExtendsNative(cls))) {
+    names.add("x");
+  }
+  // Sort the names of the classes after abbreviating them to ensure
+  // the suffix is stable and predictable for the suggested names.
+  names.sort();
+  return names.join();
+}
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
index 31de9ed..11252e7 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -460,15 +460,22 @@
 }
 
 class Ruleset {
-  Map<ClassEntity, ClassEntity> _redirections;
-  Map<InterfaceType, _RulesetEntry> _entries;
+  final DartTypes _dartTypes;
+  final Map<ClassEntity, ClassEntity> _redirections = {};
+  final Map<InterfaceType, _RulesetEntry> _entries = {};
 
-  Ruleset(this._redirections, this._entries);
-  Ruleset.empty() : this({}, {});
+  Ruleset.empty(this._dartTypes);
+
+  CommonElements get _commonElements => _dartTypes.commonElements;
+  ClassEntity get _objectClass => _commonElements.objectClass;
 
   bool get isEmpty => _redirections.isEmpty && _entries.isEmpty;
   bool get isNotEmpty => _redirections.isNotEmpty || _entries.isNotEmpty;
 
+  bool _isObject(InterfaceType type) => identical(type.element, _objectClass);
+
+  bool _isSyntheticClosure(InterfaceType type) => type.element.isClosure;
+
   void addRedirection(ClassEntity redirectee, ClassEntity target) {
     assert(redirectee != target);
     _redirections[redirectee] = target;
@@ -476,20 +483,21 @@
 
   void addEntry(InterfaceType targetType, Iterable<InterfaceType> supertypes,
       Map<TypeVariableType, DartType> typeVariables) {
+    if (_isObject(targetType) || _isSyntheticClosure(targetType)) return;
+    supertypes = supertypes.where((supertype) =>
+        !_isObject(supertype) &&
+        !identical(targetType.element, supertype.element));
+    if (supertypes.isEmpty && typeVariables.isEmpty) return;
     _RulesetEntry entry = _entries[targetType] ??= _RulesetEntry();
     entry.addAll(supertypes, typeVariables);
   }
 }
 
 class RulesetEncoder {
-  final DartTypes _dartTypes;
   final ModularEmitter _emitter;
   final RecipeEncoder _recipeEncoder;
 
-  RulesetEncoder(this._dartTypes, this._emitter, this._recipeEncoder);
-
-  CommonElements get _commonElements => _dartTypes.commonElements;
-  ClassEntity get _objectClass => _commonElements.objectClass;
+  RulesetEncoder(this._emitter, this._recipeEncoder);
 
   final _leftBrace = js.string('{');
   final _rightBrace = js.string('}');
@@ -499,32 +507,10 @@
   final _comma = js.string(',');
   final _doubleQuote = js.string('"');
 
-  bool _isObject(InterfaceType type) => identical(type.element, _objectClass);
-
-  bool _isSyntheticClosure(InterfaceType type) => type.element.isClosure;
-
-  void _preprocessEntry(InterfaceType targetType, _RulesetEntry entry) {
-    entry._supertypes.removeWhere((InterfaceType supertype) =>
-        _isObject(supertype) ||
-        identical(targetType.element, supertype.element));
-  }
-
-  void _preprocessRuleset(Ruleset ruleset) {
-    ruleset._entries.removeWhere((InterfaceType targetType, _) =>
-        _isObject(targetType) || _isSyntheticClosure(targetType));
-    ruleset._entries.forEach(_preprocessEntry);
-    ruleset._entries.removeWhere((_, _RulesetEntry entry) => entry.isEmpty);
-  }
-
   // TODO(fishythefish): Common substring elimination.
 
   /// Produces a string readable by `JSON.parse()`.
-  jsAst.StringConcatenation encodeRuleset(Ruleset ruleset) {
-    _preprocessRuleset(ruleset);
-    return _encodeRuleset(ruleset);
-  }
-
-  jsAst.StringConcatenation _encodeRuleset(Ruleset ruleset) =>
+  jsAst.StringConcatenation encodeRuleset(Ruleset ruleset) =>
       js.concatenateStrings([
         _leftBrace,
         ...js.joinLiterals([
diff --git a/pkg/compiler/lib/src/js_backend/specialized_checks.dart b/pkg/compiler/lib/src/js_backend/specialized_checks.dart
index 0dbc18d..fd0ed95 100644
--- a/pkg/compiler/lib/src/js_backend/specialized_checks.dart
+++ b/pkg/compiler/lib/src/js_backend/specialized_checks.dart
@@ -2,15 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.10
-
 import '../common/elements.dart' show ElementEnvironment, JCommonElements;
 import '../deferred_load/output_unit.dart' show OutputUnitData;
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../js_backend/interceptor_data.dart' show InterceptorData;
 import '../universe/class_hierarchy.dart' show ClassHierarchy;
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 
 enum IsTestSpecialization {
   isNull,
@@ -24,7 +22,7 @@
 }
 
 class SpecializedChecks {
-  static IsTestSpecialization findIsTestSpecialization(
+  static IsTestSpecialization? findIsTestSpecialization(
       DartType dartType, MemberEntity compiland, JClosedWorld closedWorld) {
     if (dartType is LegacyType) {
       DartType base = dartType.baseType;
@@ -37,7 +35,7 @@
     return _findIsTestSpecialization(dartType, compiland, closedWorld);
   }
 
-  static IsTestSpecialization _findIsTestSpecialization(
+  static IsTestSpecialization? _findIsTestSpecialization(
       DartType dartType, MemberEntity compiland, JClosedWorld closedWorld) {
     if (dartType is InterfaceType) {
       ClassEntity element = dartType.element;
@@ -108,7 +106,7 @@
     return null;
   }
 
-  static MemberEntity findAsCheck(DartType dartType,
+  static MemberEntity? findAsCheck(DartType dartType,
       JCommonElements commonElements, bool useLegacySubtyping) {
     if (dartType is InterfaceType) {
       if (dartType.typeArguments.isNotEmpty) return null;
@@ -149,9 +147,9 @@
   ///     String    nullable: false  legacy: true     String    yes
   ///     String    nullable: false  legacy: false    String    no
   ///
-  static MemberEntity _findAsCheck(
+  static MemberEntity? _findAsCheck(
       ClassEntity element, JCommonElements commonElements,
-      {bool nullable, bool legacy}) {
+      {required bool nullable, required bool legacy}) {
     if (element == commonElements.jsStringClass ||
         element == commonElements.stringClass) {
       if (legacy) return commonElements.specializedAsStringLegacy;
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index fd16183..fcbdb2f 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -439,7 +439,7 @@
   // `call$1$name` (in unminified mode).
   final js.Name? callName;
 
-  DartMethod(FunctionEntity element, js.Name name, js.Expression code,
+  DartMethod(FunctionEntity super.element, super.name, super.code,
       this.parameterStubs, this.callName,
       {required this.needsTearOff,
       this.tearOffName,
@@ -447,8 +447,7 @@
       required this.requiredParameterCount,
       this.optionalParameterDefaultValues,
       this.functionType,
-      required this.applyIndex})
-      : super(element, name, code) {
+      required this.applyIndex}) {
     assert(!needsTearOff || tearOffName != null);
     assert(!canBeApplied || optionalParameterDefaultValues != null);
   }
@@ -485,31 +484,24 @@
   ///final js.Name applyName;
 
   InstanceMethod(
-    FunctionEntity element,
-    js.Name name,
-    js.Expression code,
-    List<ParameterStubMethod> parameterStubs,
-    js.Name callName, {
-    required bool needsTearOff,
-    js.Name? tearOffName,
+    super.element,
+    super.name,
+    super.code,
+    super.parameterStubs,
+    js.Name super.callName, {
+    required super.needsTearOff,
+    super.tearOffName,
     this.aliasName,
     required this.tearOffNeedsDirectAccess,
-    required bool canBeApplied,
-    required int requiredParameterCount,
-    /* List | Map */ optionalParameterDefaultValues,
+    required super.canBeApplied,
+    required super.requiredParameterCount,
+    /* List | Map */ super.optionalParameterDefaultValues,
     required this.isClosureCallMethod,
     required this.inheritsApplyMetadata,
     required this.isIntercepted,
-    js.Expression? functionType,
-    required int applyIndex,
-  }) : super(element, name, code, parameterStubs, callName,
-            needsTearOff: needsTearOff,
-            tearOffName: tearOffName,
-            canBeApplied: canBeApplied,
-            requiredParameterCount: requiredParameterCount,
-            optionalParameterDefaultValues: optionalParameterDefaultValues,
-            functionType: functionType,
-            applyIndex: applyIndex);
+    super.functionType,
+    required super.applyIndex,
+  });
 
   @override
   bool get isStatic => false;
@@ -567,23 +559,15 @@
 abstract class StaticMethod implements Method {}
 
 class StaticDartMethod extends DartMethod implements StaticMethod {
-  StaticDartMethod(FunctionEntity element, js.Name name, js.Expression code,
-      List<ParameterStubMethod> parameterStubs, js.Name callName,
-      {required bool needsTearOff,
-      js.Name? tearOffName,
-      required bool canBeApplied,
-      required int requiredParameterCount,
-      /* List | Map */ optionalParameterDefaultValues,
-      js.Expression? functionType,
-      required int applyIndex})
-      : super(element, name, code, parameterStubs, callName,
-            needsTearOff: needsTearOff,
-            tearOffName: tearOffName,
-            canBeApplied: canBeApplied,
-            requiredParameterCount: requiredParameterCount,
-            optionalParameterDefaultValues: optionalParameterDefaultValues,
-            functionType: functionType,
-            applyIndex: applyIndex);
+  StaticDartMethod(super.element, super.name, super.code, super.parameterStubs,
+      js.Name super.callName,
+      {required super.needsTearOff,
+      super.tearOffName,
+      required super.canBeApplied,
+      required super.requiredParameterCount,
+      /* List | Map */ super.optionalParameterDefaultValues,
+      super.functionType,
+      required super.applyIndex});
 
   @override
   bool get isStatic => true;
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 5da86d0..8e41ce5 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
@@ -270,7 +270,7 @@
     #tpIsStatic: isStatic,
     #tpIsIntercepted: isIntercepted,
     #tpRequiredParameterCount: requiredParameterCount,
-    #tpOptionalParamaterDefaultValues: optionalParameterDefaultValues,
+    #tpOptionalParameterDefaultValues: optionalParameterDefaultValues,
     #tpCallNames: callNames,
     #tpFunctionsOrNames: funsOrNames,
     #tpFunctionType: funType,
@@ -628,8 +628,7 @@
             : RuntimeTypesImpl(_closedWorld),
         _closedWorld.nativeData,
         _closedWorld.commonElements);
-    _rulesetEncoder =
-        RulesetEncoder(_closedWorld.dartTypes, _emitter, _recipeEncoder);
+    _rulesetEncoder = RulesetEncoder(_emitter, _recipeEncoder);
   }
 
   js.Expression generateEmbeddedGlobalAccess(String global) =>
@@ -740,7 +739,7 @@
           js.string(TearOffParametersPropertyNames.isIntercepted),
       'tpRequiredParameterCount':
           js.string(TearOffParametersPropertyNames.requiredParameterCount),
-      'tpOptionalParamaterDefaultValues': js.string(
+      'tpOptionalParameterDefaultValues': js.string(
           TearOffParametersPropertyNames.optionalParameterDefaultValues),
       'tpCallNames': js.string(TearOffParametersPropertyNames.callNames),
       'tpFunctionsOrNames':
@@ -1173,7 +1172,7 @@
   js.Statement emitInheritance(Fragment fragment) {
     List<js.Statement> inheritCalls = [];
     List<js.Statement> mixinCalls = [];
-    // local caches of functions to allow minifaction of function name in call.
+    // local caches of functions to allow minification of function name in call.
     LocalAliases locals = LocalAliases();
 
     Set<Class> classesInFragment = Set();
@@ -1184,7 +1183,7 @@
     Map<Class, List<Class>> subclasses = {};
     Set<Class> seen = Set();
 
-    void collect(cls) {
+    void collect(Class cls) {
       if (cls == null || seen.contains(cls)) return;
 
       Class superclass = cls.superclass;
@@ -1530,7 +1529,8 @@
         }
       }
       for (Class cls in library.classes) {
-        var methods = cls.methods.where((dynamic m) => m.needsTearOff).toList();
+        var methods =
+            cls.methods.where((m) => (m as DartMethod).needsTearOff).toList();
         js.Expression container = js.js("#.prototype", classReference(cls));
         js.Expression reference = container;
         if (methods.length > 1) {
@@ -1911,7 +1911,7 @@
     Map<ClassTypeData, List<ClassTypeData>> nativeRedirections =
         _nativeEmitter.typeRedirections;
 
-    Ruleset ruleset = Ruleset.empty();
+    Ruleset ruleset = Ruleset.empty(_dartTypes);
     Map<ClassEntity, int> erasedTypes = {};
     Iterable<ClassTypeData> classTypeData =
         fragment.libraries.expand((Library library) => library.classTypeData);
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
index 0c92464..70bb89e 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
@@ -101,7 +101,7 @@
 /// interleaving.
 ///
 /// Instead, when this happens we emit {a} and {c} into separate
-/// [CodeFragments], with separate top level initalization functions that are
+/// [CodeFragments], with separate top level initialization functions that are
 /// only called when the necessary dependencies for initialization are
 /// present. These [CodeFragments] end up in a single [FinalizedFragment].
 /// While this approach doesn't have the performance benefits of
@@ -672,7 +672,7 @@
           .map((fragment) =>
               deferredPartFileName(_options, fragment.canonicalOutputUnit.name))
           .toList();
-      libraryMap["imports"][importDeferName] = partFileNames;
+      (libraryMap["imports"] as Map)[importDeferName] = partFileNames;
     });
     return mapping;
   }
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 4a05706..dc2d401 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import 'package:kernel/ast.dart' as ir;
 
 import '../closure.dart';
@@ -11,19 +9,15 @@
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../ir/closure.dart';
-import '../ir/element_map.dart';
-import '../ir/static_type_cache.dart';
 import '../js_backend/annotations.dart';
-import '../js_model/class_type_variable_access.dart';
-import '../js_model/element_map.dart';
-import '../js_model/env.dart';
-import '../ordered_typeset.dart';
+import '../js_model/element_map_interfaces.dart';
+import '../js_model/element_map_migrated.dart';
 import '../serialization/deferrable.dart';
 import '../serialization/serialization.dart';
 import '../universe/selector.dart';
 import 'elements.dart';
 import 'closure_migrated.dart' as migrated;
-import 'js_world_builder.dart' show JsClosedWorldBuilder;
+import 'js_world_builder_interfaces.dart' show JsClosedWorldBuilder;
 
 export 'closure_migrated.dart'
     show AnonymousClosureLocal, JClosureField, JRecordField;
@@ -134,10 +128,7 @@
       entity = constructorBody.constructor;
     }
 
-    ScopeInfo scopeInfo = _scopeMap.loaded()[entity];
-    assert(
-        scopeInfo != null, failedAt(entity, "Missing scope info for $entity."));
-    return scopeInfo;
+    return _scopeMap.loaded()[entity]!;
   }
 
   // TODO(efortuna): Eventually capturedScopesMap[node] should always
@@ -164,17 +155,12 @@
   // TODO(efortuna): Eventually capturedScopesMap[node] should always
   // be non-null, and we should just test that with an assert.
   CapturedLoopScope getCapturedLoopScope(ir.Node loopNode) =>
-      _capturedScopesMap.loaded()[loopNode] ?? const CapturedLoopScope();
+      _capturedScopesMap.loaded()[loopNode] as CapturedLoopScope? ??
+      const CapturedLoopScope();
 
   @override
-  ClosureRepresentationInfo getClosureInfo(ir.LocalFunction node) {
-    var closure = _localClosureRepresentationMap.loaded()[node];
-    assert(
-        closure != null,
-        "Corresponding closure class not found for $node. "
-        "Closures found for ${_localClosureRepresentationMap.loaded().keys}");
-    return closure;
-  }
+  ClosureRepresentationInfo getClosureInfo(ir.LocalFunction node) =>
+      _localClosureRepresentationMap.loaded()[node]!;
 
   @override
   MemberEntity getEnclosingMember(MemberEntity member) {
@@ -221,7 +207,6 @@
         switch (usage.kind) {
           case VariableUseKind.explicit:
             return true;
-            break;
           case VariableUseKind.implicitCast:
             if (_annotationsData
                 .getImplicitDowncastCheckPolicy(outermostEntity)
@@ -233,19 +218,20 @@
             break;
           case VariableUseKind.constructorTypeArgument:
             ConstructorEntity constructor =
-                _elementMap.getConstructor(usage.member);
+                _elementMap.getConstructor(usage.member!);
             if (rtiNeed.classNeedsTypeArguments(constructor.enclosingClass)) {
               return true;
             }
             break;
           case VariableUseKind.staticTypeArgument:
-            FunctionEntity method = _elementMap.getMethod(usage.member);
+            FunctionEntity method =
+                _elementMap.getMethod(usage.member as ir.Procedure);
             if (rtiNeed.methodNeedsTypeArguments(method)) {
               return true;
             }
             break;
           case VariableUseKind.instanceTypeArgument:
-            Selector selector = _elementMap.getSelector(usage.invocation);
+            Selector selector = _elementMap.getSelector(usage.invocation!);
             if (rtiNeed.selectorNeedsTypeArguments(selector)) {
               return true;
             }
@@ -253,8 +239,8 @@
           case VariableUseKind.localTypeArgument:
             // TODO(johnniwinther): We should be able to track direct local
             // function invocations and not have to use the selector here.
-            Selector selector = _elementMap.getSelector(usage.invocation);
-            if (rtiNeed.localFunctionNeedsTypeArguments(usage.localFunction) ||
+            Selector selector = _elementMap.getSelector(usage.invocation!);
+            if (rtiNeed.localFunctionNeedsTypeArguments(usage.localFunction!) ||
                 rtiNeed.selectorNeedsTypeArguments(selector)) {
               return true;
             }
@@ -265,7 +251,8 @@
                 .isEmitted) {
               return true;
             } else {
-              FunctionEntity method = _elementMap.getMethod(usage.member);
+              FunctionEntity method =
+                  _elementMap.getMethod(usage.member as ir.Procedure);
               if (rtiNeed.methodNeedsSignature(method)) {
                 return true;
               }
@@ -277,23 +264,24 @@
                 .isEmitted) {
               return true;
             } else if (rtiNeed
-                .localFunctionNeedsSignature(usage.localFunction)) {
+                .localFunctionNeedsSignature(usage.localFunction!)) {
               return true;
             }
             break;
           case VariableUseKind.memberReturnType:
-            FunctionEntity method = _elementMap.getMethod(usage.member);
+            FunctionEntity method =
+                _elementMap.getMethod(usage.member as ir.Procedure);
             if (rtiNeed.methodNeedsSignature(method)) {
               return true;
             }
             break;
           case VariableUseKind.localReturnType:
-            if (usage.localFunction.function.asyncMarker !=
+            if (usage.localFunction!.function.asyncMarker !=
                 ir.AsyncMarker.Sync) {
               // The Future/Iterator/Stream implementation requires the type.
               return true;
             }
-            if (rtiNeed.localFunctionNeedsSignature(usage.localFunction)) {
+            if (rtiNeed.localFunctionNeedsSignature(usage.localFunction!)) {
               return true;
             }
             break;
@@ -325,7 +313,7 @@
           case VariableUseKind.instantiationTypeArgument:
             // TODO(johnniwinther): Use the static type of the expression.
             if (rtiNeed.instantiationNeedsTypeArguments(
-                null, usage.instantiation.typeArguments.length)) {
+                null, usage.instantiation!.typeArguments.length)) {
               return true;
             }
             break;
@@ -352,9 +340,9 @@
       List<FunctionEntity> callMethods) {
     void processModel(MemberEntity member, ClosureScopeModel model) {
       Map<ir.VariableDeclaration, migrated.JRecordField> allBoxedVariables =
-          _elementMap.makeRecordContainer(model.scopeInfo, member);
+          _elementMap.makeRecordContainer(model.scopeInfo!, member);
       _scopeMap[member] = JsScopeInfo.from(
-          allBoxedVariables, model.scopeInfo, member.enclosingClass);
+          allBoxedVariables, model.scopeInfo!, member.enclosingClass);
 
       model.capturedScopesMap
           .forEach((ir.Node node, KernelCapturedScope scope) {
@@ -363,10 +351,10 @@
         _updateScopeBasedOnRtiNeed(scope, rtiNeed, member);
 
         if (scope is KernelCapturedLoopScope) {
-          _capturedScopesMap[node] = JsCapturedLoopScope.from(
+          _capturedScopesMap[node as ir.TreeNode] = JsCapturedLoopScope.from(
               boxedVariables, scope, member.enclosingClass);
         } else {
-          _capturedScopesMap[node] = JsCapturedScope.from(
+          _capturedScopesMap[node as ir.TreeNode] = JsCapturedScope.from(
               boxedVariables, scope, member.enclosingClass);
         }
         allBoxedVariables.addAll(boxedVariables);
@@ -380,33 +368,34 @@
             closedWorldBuilder,
             member,
             functionNode,
-            closuresToGenerate[node],
+            closuresToGenerate[node]!,
             allBoxedVariables,
             rtiNeed,
-            createSignatureMethod:
-                rtiNeed.localFunctionNeedsSignature(functionNode.parent));
+            createSignatureMethod: rtiNeed.localFunctionNeedsSignature(
+                functionNode.parent as ir.LocalFunction));
         // Add also for the call method.
-        _scopeMap[closureClassInfo.callMethod] = closureClassInfo;
+        _scopeMap[closureClassInfo.callMethod!] = closureClassInfo;
         if (closureClassInfo.signatureMethod != null) {
-          _scopeMap[closureClassInfo.signatureMethod] = closureClassInfo;
+          _scopeMap[closureClassInfo.signatureMethod!] = closureClassInfo;
 
           // Set up capturedScope for signature method. This is distinct from
           // _capturedScopesMap because there is no corresponding ir.Node for
           // the signature.
-          if (rtiNeed.localFunctionNeedsSignature(functionNode.parent) &&
+          if (rtiNeed.localFunctionNeedsSignature(
+                  functionNode.parent as ir.LocalFunction) &&
               model.capturedScopesMap[functionNode] != null) {
             KernelCapturedScope capturedScope =
-                model.capturedScopesMap[functionNode];
+                model.capturedScopesMap[functionNode]!;
             assert(capturedScope is! KernelCapturedLoopScope);
             KernelCapturedScope signatureCapturedScope =
                 KernelCapturedScope.forSignature(capturedScope);
             _updateScopeBasedOnRtiNeed(signatureCapturedScope, rtiNeed, member);
-            _capturedScopeForSignatureMap[closureClassInfo.signatureMethod] =
+            _capturedScopeForSignatureMap[closureClassInfo.signatureMethod!] =
                 JsCapturedScope.from(
                     {}, signatureCapturedScope, member.enclosingClass);
           }
         }
-        callMethods.add(closureClassInfo.callMethod);
+        callMethods.add(closureClassInfo.callMethod!);
       }
     }
 
@@ -437,23 +426,24 @@
       KernelScopeInfo info,
       Map<ir.VariableDeclaration, migrated.JRecordField> boxedVariables,
       ClosureRtiNeed rtiNeed,
-      {bool createSignatureMethod}) {
+      {required bool createSignatureMethod}) {
     _updateScopeBasedOnRtiNeed(info, rtiNeed, member);
     JsClosureClassInfo closureClassInfo = closedWorldBuilder.buildClosureClass(
-        member, node, member.library, boxedVariables, info,
+        member, node, member.library as JLibrary, boxedVariables, info,
         createSignatureMethod: createSignatureMethod);
 
     // We want the original declaration where that function is used to point
     // to the correct closure class.
-    _enclosingMembers[closureClassInfo.callMethod] = member;
+    _enclosingMembers[closureClassInfo.callMethod!] = member;
     if (closureClassInfo.signatureMethod != null) {
-      _enclosingMembers[closureClassInfo.signatureMethod] = member;
+      _enclosingMembers[closureClassInfo.signatureMethod!] = member;
     }
     if (node.parent is ir.Member) {
-      assert(_elementMap.getMember(node.parent) == member);
+      assert(_elementMap.getMember(node.parent as ir.Member) == member);
     } else {
       assert(node.parent is ir.LocalFunction);
-      _localClosureRepresentationMap[node.parent] = closureClassInfo;
+      _localClosureRepresentationMap[node.parent as ir.LocalFunction] =
+          closureClassInfo;
     }
     return closureClassInfo;
   }
@@ -466,21 +456,21 @@
 
   final Iterable<ir.VariableDeclaration> _localsUsedInTryOrSync;
 
-  Set<Local> _localsUsedInTryOrSyncCache;
+  Set<Local>? _localsUsedInTryOrSyncCache;
 
   @override
-  final Local thisLocal;
+  final Local? thisLocal;
 
   final Map<ir.VariableDeclaration, migrated.JRecordField> _boxedVariables;
 
-  Map<Local, migrated.JRecordField> _boxedVariablesCache;
+  Map<Local, migrated.JRecordField>? _boxedVariablesCache;
 
   JsScopeInfo.internal(
       this._localsUsedInTryOrSync, this.thisLocal, this._boxedVariables);
 
   JsScopeInfo.from(
-      this._boxedVariables, KernelScopeInfo info, ClassEntity enclosingClass)
-      : this.thisLocal = info.hasThisLocal ? ThisLocal(enclosingClass) : null,
+      this._boxedVariables, KernelScopeInfo info, ClassEntity? enclosingClass)
+      : this.thisLocal = info.hasThisLocal ? ThisLocal(enclosingClass!) : null,
         this._localsUsedInTryOrSync = info.localsUsedInTryOrSync;
 
   void _ensureBoxedVariableCache(KernelToLocalsMap localsMap) {
@@ -488,11 +478,12 @@
       if (_boxedVariables.isEmpty) {
         _boxedVariablesCache = const {};
       } else {
-        _boxedVariablesCache = {};
+        final cache = <Local, migrated.JRecordField>{};
         _boxedVariables.forEach(
             (ir.VariableDeclaration node, migrated.JRecordField field) {
-          _boxedVariablesCache[localsMap.getLocalVariable(node)] = field;
+          cache[localsMap.getLocalVariable(node)] = field;
         });
+        _boxedVariablesCache = cache;
       }
     }
   }
@@ -501,7 +492,7 @@
   void forEachBoxedVariable(
       KernelToLocalsMap localsMap, f(Local local, FieldEntity field)) {
     _ensureBoxedVariableCache(localsMap);
-    _boxedVariablesCache.forEach(f);
+    _boxedVariablesCache!.forEach(f);
   }
 
   @override
@@ -512,11 +503,11 @@
       } else {
         _localsUsedInTryOrSyncCache = {};
         for (ir.VariableDeclaration node in _localsUsedInTryOrSync) {
-          _localsUsedInTryOrSyncCache.add(localsMap.getLocalVariable(node));
+          _localsUsedInTryOrSyncCache!.add(localsMap.getLocalVariable(node));
         }
       }
     }
-    return _localsUsedInTryOrSyncCache.contains(variable);
+    return _localsUsedInTryOrSyncCache!.contains(variable);
   }
 
   @override
@@ -530,17 +521,17 @@
   @override
   bool isBoxedVariable(KernelToLocalsMap localsMap, Local variable) {
     _ensureBoxedVariableCache(localsMap);
-    return _boxedVariablesCache.containsKey(variable);
+    return _boxedVariablesCache!.containsKey(variable);
   }
 
   factory JsScopeInfo.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
     Iterable<ir.VariableDeclaration> localsUsedInTryOrSync =
         source.readTreeNodes<ir.VariableDeclaration>();
-    Local thisLocal = source.readLocalOrNull();
+    Local? thisLocal = source.readLocalOrNull();
     Map<ir.VariableDeclaration, migrated.JRecordField> boxedVariables =
         source.readTreeNodeMap<ir.VariableDeclaration, migrated.JRecordField>(
-            () => source.readMember());
+            () => source.readMember() as migrated.JRecordField);
     source.end(tag);
     if (boxedVariables.isEmpty) boxedVariables = const {};
     return JsScopeInfo.internal(
@@ -564,22 +555,17 @@
   static const String tag = 'captured-scope';
 
   @override
-  final Local contextBox;
+  final Local? contextBox;
 
-  JsCapturedScope.internal(
-      Iterable<ir.VariableDeclaration> localsUsedInTryOrSync,
-      Local thisLocal,
-      Map<ir.VariableDeclaration, migrated.JRecordField> boxedVariables,
-      this.contextBox)
-      : super.internal(localsUsedInTryOrSync, thisLocal, boxedVariables);
+  JsCapturedScope.internal(super.localsUsedInTryOrSync, super.thisLocal,
+      super.boxedVariables, this.contextBox)
+      : super.internal();
 
   JsCapturedScope.from(
-      Map<ir.VariableDeclaration, migrated.JRecordField> boxedVariables,
-      KernelCapturedScope capturedScope,
-      ClassEntity enclosingClass)
+      super.boxedVariables, super.capturedScope, super.enclosingClass)
       : this.contextBox =
             boxedVariables.isNotEmpty ? boxedVariables.values.first.box : null,
-        super.from(boxedVariables, capturedScope, enclosingClass);
+        super.from();
 
   @override
   bool get requiresContextBox => _boxedVariables.isNotEmpty;
@@ -588,11 +574,11 @@
     source.begin(tag);
     Iterable<ir.VariableDeclaration> localsUsedInTryOrSync =
         source.readTreeNodes<ir.VariableDeclaration>();
-    Local thisLocal = source.readLocalOrNull();
+    Local? thisLocal = source.readLocalOrNull();
     Map<ir.VariableDeclaration, migrated.JRecordField> boxedVariables =
         source.readTreeNodeMap<ir.VariableDeclaration, migrated.JRecordField>(
-            () => source.readMember());
-    Local context = source.readLocalOrNull();
+            () => source.readMember() as migrated.JRecordField);
+    Local? context = source.readLocalOrNull();
     source.end(tag);
     return JsCapturedScope.internal(
         localsUsedInTryOrSync, thisLocal, boxedVariables, context);
@@ -617,21 +603,14 @@
 
   final List<ir.VariableDeclaration> _boxedLoopVariables;
 
-  JsCapturedLoopScope.internal(
-      Iterable<ir.VariableDeclaration> localsUsedInTryOrSync,
-      Local thisLocal,
-      Map<ir.VariableDeclaration, migrated.JRecordField> boxedVariables,
-      Local context,
-      this._boxedLoopVariables)
-      : super.internal(
-            localsUsedInTryOrSync, thisLocal, boxedVariables, context);
+  JsCapturedLoopScope.internal(super.localsUsedInTryOrSync, super.thisLocal,
+      super.boxedVariables, super.context, this._boxedLoopVariables)
+      : super.internal();
 
-  JsCapturedLoopScope.from(
-      Map<ir.VariableDeclaration, migrated.JRecordField> boxedVariables,
-      KernelCapturedLoopScope capturedScope,
-      ClassEntity enclosingClass)
+  JsCapturedLoopScope.from(super.boxedVariables,
+      KernelCapturedLoopScope super.capturedScope, super.enclosingClass)
       : this._boxedLoopVariables = capturedScope.boxedLoopVariables,
-        super.from(boxedVariables, capturedScope, enclosingClass);
+        super.from();
 
   @override
   bool get hasBoxedLoopVariables => _boxedLoopVariables.isNotEmpty;
@@ -640,11 +619,11 @@
     source.begin(tag);
     Iterable<ir.VariableDeclaration> localsUsedInTryOrSync =
         source.readTreeNodes<ir.VariableDeclaration>();
-    Local thisLocal = source.readLocalOrNull();
+    Local? thisLocal = source.readLocalOrNull();
     Map<ir.VariableDeclaration, migrated.JRecordField> boxedVariables =
         source.readTreeNodeMap<ir.VariableDeclaration, migrated.JRecordField>(
-            () => source.readMember());
-    Local context = source.readLocalOrNull();
+            () => source.readMember() as migrated.JRecordField);
+    Local? context = source.readLocalOrNull();
     List<ir.VariableDeclaration> boxedLoopVariables =
         source.readTreeNodes<ir.VariableDeclaration>();
     source.end(tag);
@@ -682,20 +661,21 @@
   static const String tag = 'closure-representation-info';
 
   @override
-  JFunction callMethod;
+  JFunction? callMethod;
+
   @override
-  JSignatureMethod signatureMethod;
+  JSignatureMethod? signatureMethod;
 
   /// The local used for this closure, if it is an anonymous closure, i.e.
   /// an `ir.FunctionExpression`.
-  final Local _closureEntity;
+  final Local? _closureEntity;
 
   /// The local variable that defines this closure, if it is a local function
   /// declaration.
-  final ir.VariableDeclaration _closureEntityVariable;
+  final ir.VariableDeclaration? _closureEntityVariable;
 
   @override
-  final Local thisLocal;
+  final Local? thisLocal;
 
   @override
   final JClass closureClassEntity;
@@ -703,7 +683,7 @@
   final Map<ir.VariableDeclaration, JField> _variableToFieldMap;
   final Map<JTypeVariable, JField> _typeVariableToFieldMap;
   final Map<Local, JField> _localToFieldMap;
-  Map<JField, Local> _fieldToLocalsMap;
+  Map<JField, Local>? _fieldToLocalsMap;
 
   JsClosureClassInfo.internal(
       Iterable<ir.VariableDeclaration> localsUsedInTryOrSync,
@@ -724,7 +704,7 @@
       ir.FunctionNode closureSourceNode,
       Map<ir.VariableDeclaration, migrated.JRecordField> boxedVariables,
       KernelScopeInfo info,
-      ClassEntity enclosingClass,
+      ClassEntity? enclosingClass,
       this._closureEntity,
       this._closureEntityVariable,
       this.thisLocal)
@@ -737,22 +717,25 @@
     source.begin(tag);
     Iterable<ir.VariableDeclaration> localsUsedInTryOrSync =
         source.readTreeNodes<ir.VariableDeclaration>();
-    Local thisLocal = source.readLocalOrNull();
+    Local? thisLocal = source.readLocalOrNull();
     Map<ir.VariableDeclaration, migrated.JRecordField> boxedVariables =
         source.readTreeNodeMap<ir.VariableDeclaration, migrated.JRecordField>(
-            () => source.readMember());
-    JFunction callMethod = source.readMember();
-    JSignatureMethod signatureMethod = source.readMemberOrNull();
-    Local closureEntity = source.readLocalOrNull();
-    ir.VariableDeclaration closureEntityVariable = source.readTreeNodeOrNull();
-    JClass closureClassEntity = source.readClass();
+            () => source.readMember() as migrated.JRecordField);
+    JFunction callMethod = source.readMember() as JFunction;
+    JSignatureMethod? signatureMethod =
+        source.readMemberOrNull() as JSignatureMethod?;
+    Local? closureEntity = source.readLocalOrNull();
+    ir.VariableDeclaration? closureEntityVariable =
+        source.readTreeNodeOrNull() as ir.VariableDeclaration?;
+    JClass closureClassEntity = source.readClass() as JClass;
     Map<ir.VariableDeclaration, JField> localToFieldMap =
         source.readTreeNodeMap<ir.VariableDeclaration, JField>(
-            () => source.readMember());
-    Map<JTypeVariable, JField> typeVariableToFieldMap = source
-        .readTypeVariableMap<JTypeVariable, JField>(() => source.readMember());
+            () => source.readMember() as JField);
+    Map<JTypeVariable, JField> typeVariableToFieldMap =
+        source.readTypeVariableMap<JTypeVariable, JField>(
+            () => source.readMember() as JField);
     Map<Local, JField> thisLocalToFieldMap =
-        source.readLocalMap(() => source.readMember());
+        source.readLocalMap(() => source.readMember() as JField);
     source.end(tag);
     if (boxedVariables.isEmpty) boxedVariables = const {};
     if (localToFieldMap.isEmpty) localToFieldMap = const {};
@@ -777,7 +760,7 @@
     sink.writeTreeNodes(_localsUsedInTryOrSync);
     sink.writeLocalOrNull(thisLocal);
     sink.writeTreeNodeMap(_boxedVariables, sink.writeMember);
-    sink.writeMember(callMethod);
+    sink.writeMember(callMethod!);
     sink.writeMemberOrNull(signatureMethod);
     sink.writeLocalOrNull(_closureEntity);
     sink.writeTreeNodeOrNull(_closureEntityVariable);
@@ -817,24 +800,24 @@
   void registerFieldForBoxedVariable(
       ir.VariableDeclaration node, JField field) {
     assert(_boxedVariablesCache == null);
-    _boxedVariables[node] = field;
+    _boxedVariables[node] = field as migrated.JRecordField;
   }
 
   void _ensureFieldToLocalsMap(KernelToLocalsMap localsMap) {
     if (_fieldToLocalsMap == null) {
       _fieldToLocalsMap = {};
       _variableToFieldMap.forEach((ir.VariableDeclaration node, JField field) {
-        _fieldToLocalsMap[field] = localsMap.getLocalVariable(node);
+        _fieldToLocalsMap![field] = localsMap.getLocalVariable(node);
       });
       _typeVariableToFieldMap
           .forEach((TypeVariableEntity typeVariable, JField field) {
-        _fieldToLocalsMap[field] =
+        _fieldToLocalsMap![field] =
             localsMap.getLocalTypeVariableEntity(typeVariable);
       });
       _localToFieldMap.forEach((Local local, JField field) {
-        _fieldToLocalsMap[field] = local;
+        _fieldToLocalsMap![field] = local;
       });
-      if (_fieldToLocalsMap.isEmpty) {
+      if (_fieldToLocalsMap!.isEmpty) {
         _fieldToLocalsMap = const {};
       }
     }
@@ -843,308 +826,40 @@
   @override
   List<Local> getCreatedFieldEntities(KernelToLocalsMap localsMap) {
     _ensureFieldToLocalsMap(localsMap);
-    return _fieldToLocalsMap.values.toList();
+    return _fieldToLocalsMap!.values.toList();
   }
 
   @override
   Local getLocalForField(KernelToLocalsMap localsMap, FieldEntity field) {
     _ensureFieldToLocalsMap(localsMap);
-    Local local = _fieldToLocalsMap[field];
-    if (local == null) {
-      failedAt(field, "No local for $field. Options: $_fieldToLocalsMap");
-    }
-    return local;
+    return _fieldToLocalsMap![field]!;
   }
 
   @override
-  FieldEntity get thisFieldEntity => _localToFieldMap[thisLocal];
+  FieldEntity? get thisFieldEntity => _localToFieldMap[thisLocal];
 
   @override
   void forEachFreeVariable(
       KernelToLocalsMap localsMap, f(Local variable, JField field)) {
     _ensureFieldToLocalsMap(localsMap);
     _ensureBoxedVariableCache(localsMap);
-    _fieldToLocalsMap.forEach((JField field, Local local) {
+    _fieldToLocalsMap!.forEach((JField field, Local local) {
       f(local, field);
     });
-    _boxedVariablesCache.forEach(f);
+    _boxedVariablesCache!.forEach(f);
   }
 
   @override
   bool get isClosure => true;
 
   @override
-  Local getClosureEntity(KernelToLocalsMap localsMap) {
+  Local? getClosureEntity(KernelToLocalsMap localsMap) {
     return _closureEntityVariable != null
-        ? localsMap.getLocalVariable(_closureEntityVariable)
+        ? localsMap.getLocalVariable(_closureEntityVariable!)
         : _closureEntity;
   }
 }
 
-class RecordClassData implements JClassData {
-  /// Tag used for identifying serialized [RecordClassData] objects in a
-  /// debugging data stream.
-  static const String tag = 'record-class-data';
-
-  @override
-  final ClassDefinition definition;
-
-  @override
-  final InterfaceType thisType;
-
-  @override
-  final OrderedTypeSet orderedTypeSet;
-
-  @override
-  final InterfaceType supertype;
-
-  RecordClassData(
-      this.definition, this.thisType, this.supertype, this.orderedTypeSet);
-
-  factory RecordClassData.readFromDataSource(DataSourceReader source) {
-    source.begin(tag);
-    ClassDefinition definition = ClassDefinition.readFromDataSource(source);
-    InterfaceType thisType = source.readDartType();
-    InterfaceType supertype = source.readDartType();
-    OrderedTypeSet orderedTypeSet = OrderedTypeSet.readFromDataSource(source);
-    source.end(tag);
-    return RecordClassData(definition, thisType, supertype, orderedTypeSet);
-  }
-
-  @override
-  void writeToDataSink(DataSinkWriter sink) {
-    sink.writeEnum(JClassDataKind.record);
-    sink.begin(tag);
-    definition.writeToDataSink(sink);
-    sink.writeDartType(thisType);
-    sink.writeDartType(supertype);
-    orderedTypeSet.writeToDataSink(sink);
-    sink.end(tag);
-  }
-
-  @override
-  bool get isMixinApplication => false;
-
-  @override
-  bool get isEnumClass => false;
-
-  @override
-  FunctionType get callType => null;
-
-  @override
-  List<InterfaceType> get interfaces => const <InterfaceType>[];
-
-  @override
-  InterfaceType get mixedInType => null;
-
-  @override
-  InterfaceType get jsInteropType => thisType;
-
-  @override
-  InterfaceType get rawType => thisType;
-
-  @override
-  InterfaceType get instantiationToBounds => thisType;
-
-  @override
-  List<Variance> getVariances() => [];
-}
-
-class ClosureClassData extends RecordClassData {
-  /// Tag used for identifying serialized [ClosureClassData] objects in a
-  /// debugging data stream.
-  static const String tag = 'closure-class-data';
-
-  @override
-  FunctionType callType;
-
-  ClosureClassData(ClassDefinition definition, InterfaceType thisType,
-      InterfaceType supertype, OrderedTypeSet orderedTypeSet)
-      : super(definition, thisType, supertype, orderedTypeSet);
-
-  factory ClosureClassData.readFromDataSource(DataSourceReader source) {
-    source.begin(tag);
-    ClassDefinition definition = ClassDefinition.readFromDataSource(source);
-    InterfaceType thisType = source.readDartType();
-    InterfaceType supertype = source.readDartType();
-    OrderedTypeSet orderedTypeSet = OrderedTypeSet.readFromDataSource(source);
-    FunctionType callType = source.readDartType();
-    source.end(tag);
-    return ClosureClassData(definition, thisType, supertype, orderedTypeSet)
-      ..callType = callType;
-  }
-
-  @override
-  void writeToDataSink(DataSinkWriter sink) {
-    sink.writeEnum(JClassDataKind.closure);
-    sink.begin(tag);
-    definition.writeToDataSink(sink);
-    sink.writeDartType(thisType);
-    sink.writeDartType(supertype);
-    orderedTypeSet.writeToDataSink(sink);
-    sink.writeDartType(callType);
-    sink.end(tag);
-  }
-}
-
-abstract class ClosureMemberData implements JMemberData {
-  @override
-  final MemberDefinition definition;
-  final InterfaceType memberThisType;
-
-  ClosureMemberData(this.definition, this.memberThisType);
-
-  @override
-  StaticTypeCache get staticTypes {
-    // The cached types are stored in the data for enclosing member.
-    throw UnsupportedError("ClosureMemberData.staticTypes");
-  }
-
-  @override
-  InterfaceType getMemberThisType(covariant JsToElementMap elementMap) {
-    return memberThisType;
-  }
-}
-
-class ClosureFunctionData extends ClosureMemberData
-    with FunctionDataTypeVariablesMixin, FunctionDataForEachParameterMixin
-    implements FunctionData {
-  /// Tag used for identifying serialized [ClosureFunctionData] objects in a
-  /// debugging data stream.
-  static const String tag = 'closure-function-data';
-
-  final FunctionType functionType;
-  @override
-  ir.FunctionNode get functionNode => _functionNode.loaded();
-  final Deferrable<ir.FunctionNode> _functionNode;
-  @override
-  final ClassTypeVariableAccess classTypeVariableAccess;
-
-  ir.Member _memberContext;
-
-  ClosureFunctionData(
-      ClosureMemberDefinition definition,
-      InterfaceType memberThisType,
-      this.functionType,
-      ir.FunctionNode functionNode,
-      this.classTypeVariableAccess)
-      : _functionNode = Deferrable.eager(functionNode),
-        super(definition, memberThisType);
-
-  ClosureFunctionData._deserialized(
-      ClosureMemberDefinition definition,
-      InterfaceType memberThisType,
-      this.functionType,
-      this._functionNode,
-      this.classTypeVariableAccess)
-      : super(definition, memberThisType);
-
-  factory ClosureFunctionData.readFromDataSource(DataSourceReader source) {
-    source.begin(tag);
-    ClosureMemberDefinition definition =
-        MemberDefinition.readFromDataSource(source);
-    InterfaceType /*?*/ memberThisType =
-        source.readDartTypeOrNull() as InterfaceType /*?*/;
-    FunctionType functionType = source.readDartType();
-    Deferrable<ir.FunctionNode> functionNode =
-        source.readDeferrable(() => source.readTreeNode());
-    ClassTypeVariableAccess classTypeVariableAccess =
-        source.readEnum(ClassTypeVariableAccess.values);
-    source.end(tag);
-    return ClosureFunctionData._deserialized(definition, memberThisType,
-        functionType, functionNode, classTypeVariableAccess);
-  }
-
-  @override
-  void writeToDataSink(DataSinkWriter sink) {
-    sink.writeEnum(JMemberDataKind.closureFunction);
-    sink.begin(tag);
-    definition.writeToDataSink(sink);
-    sink.writeDartTypeOrNull(memberThisType);
-    sink.writeDartType(functionType);
-    sink.writeDeferrable(() => sink.writeTreeNode(functionNode));
-    sink.writeEnum(classTypeVariableAccess);
-    sink.end(tag);
-  }
-
-  @override
-  ir.Member get memberContext {
-    if (_memberContext == null) {
-      ir.TreeNode parent = functionNode;
-      while (parent is! ir.Member) {
-        parent = parent.parent;
-      }
-      _memberContext = parent;
-    }
-    return _memberContext;
-  }
-
-  @override
-  FunctionType getFunctionType(IrToElementMap elementMap) {
-    return functionType;
-  }
-}
-
-class ClosureFieldData extends ClosureMemberData implements JFieldData {
-  /// Tag used for identifying serialized [ClosureFieldData] objects in a
-  /// debugging data stream.
-  static const String tag = 'closure-field-data';
-
-  DartType _type;
-
-  ClosureFieldData(MemberDefinition definition, InterfaceType memberThisType)
-      : super(definition, memberThisType);
-
-  factory ClosureFieldData.readFromDataSource(DataSourceReader source) {
-    source.begin(tag);
-    MemberDefinition definition = MemberDefinition.readFromDataSource(source);
-    InterfaceType /*?*/ memberThisType =
-        source.readDartTypeOrNull() as InterfaceType /*?*/;
-    source.end(tag);
-    return ClosureFieldData(definition, memberThisType);
-  }
-
-  @override
-  void writeToDataSink(DataSinkWriter sink) {
-    sink.writeEnum(JMemberDataKind.closureField);
-    sink.begin(tag);
-    definition.writeToDataSink(sink);
-    sink.writeDartTypeOrNull(memberThisType);
-    sink.end(tag);
-  }
-
-  @override
-  DartType getFieldType(IrToElementMap elementMap) {
-    if (_type != null) return _type;
-    ir.TreeNode sourceNode = definition.node;
-    ir.DartType type;
-    if (sourceNode is ir.Class) {
-      type = sourceNode.getThisType(
-          elementMap.coreTypes, sourceNode.enclosingLibrary.nonNullable);
-    } else if (sourceNode is ir.VariableDeclaration) {
-      type = sourceNode.type;
-    } else if (sourceNode is ir.Field) {
-      type = sourceNode.type;
-    } else if (sourceNode is ir.TypeLiteral) {
-      type = sourceNode.type;
-    } else if (sourceNode is ir.Typedef) {
-      type = sourceNode.type;
-    } else if (sourceNode is ir.TypeParameter) {
-      type = sourceNode.bound;
-    } else {
-      failedAt(
-          definition.location,
-          'Unexpected node type ${sourceNode} in '
-          'ClosureFieldData.getFieldType');
-    }
-    return _type = elementMap.getDartType(type);
-  }
-
-  @override
-  ClassTypeVariableAccess get classTypeVariableAccess =>
-      ClassTypeVariableAccess.none;
-}
-
 abstract class ClosureRtiNeed {
   bool classNeedsTypeArguments(ClassEntity cls);
 
@@ -1159,5 +874,5 @@
   bool selectorNeedsTypeArguments(Selector selector);
 
   bool instantiationNeedsTypeArguments(
-      FunctionType functionType, int typeArgumentCount);
+      FunctionType? functionType, int typeArgumentCount);
 }
diff --git a/pkg/compiler/lib/src/js_model/closure_migrated.dart b/pkg/compiler/lib/src/js_model/closure_migrated.dart
index 921fa2f..26a8c2f 100644
--- a/pkg/compiler/lib/src/js_model/closure_migrated.dart
+++ b/pkg/compiler/lib/src/js_model/closure_migrated.dart
@@ -2,14 +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:compiler/src/serialization/serialization.dart';
-
 import 'package:kernel/ast.dart' as ir;
 
 import '../closure_migrated.dart';
+import '../common.dart';
 import '../elements/entities.dart';
 import '../elements/names.dart' show Name;
+import '../elements/types.dart';
+import '../ir/element_map.dart';
+import '../ir/static_type_cache.dart';
+import '../js_model/class_type_variable_access.dart';
+import '../ordered_typeset.dart';
+import '../serialization/deferrable.dart';
+import '../serialization/serialization.dart';
+import 'element_map_interfaces.dart';
+import 'element_map_migrated.dart';
 import 'elements.dart';
+import 'env.dart';
 import 'jrecord_field_interface.dart';
 
 /// A container for variables declared in a particular scope that are accessed
@@ -99,8 +108,7 @@
   /// debugging data stream.
   static const String tag = 'closure-class';
 
-  JClosureClass(JLibrary library, String name)
-      : super(library, name, isAbstract: false);
+  JClosureClass(super.library, super.name) : super(isAbstract: false);
 
   factory JClosureClass.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
@@ -168,11 +176,10 @@
             isAssignable: isAssignable,
             isConst: isConst);
 
-  JClosureField.internal(JLibrary library, JClosureClass enclosingClass,
-      Name memberName, this.declaredName,
-      {required bool isConst, required bool isAssignable})
-      : super(library, enclosingClass, memberName,
-            isAssignable: isAssignable, isConst: isConst, isStatic: false);
+  JClosureField.internal(super.library, JClosureClass super.enclosingClass,
+      super.memberName, this.declaredName,
+      {required super.isConst, required super.isAssignable})
+      : super(isStatic: false);
 
   factory JClosureField.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
@@ -205,11 +212,11 @@
 
 abstract class JsClosureClassInfo {
   JClass get closureClassEntity;
-  Local get thisLocal;
-  JFunction get callMethod;
-  void set callMethod(JFunction value);
-  JSignatureMethod get signatureMethod;
-  void set signatureMethod(JSignatureMethod value);
+  Local? get thisLocal;
+  JFunction? get callMethod;
+  void set callMethod(JFunction? value);
+  JSignatureMethod? get signatureMethod;
+  void set signatureMethod(JSignatureMethod? value);
 
   bool hasFieldForLocal(Local local);
 
@@ -219,3 +226,250 @@
   void registerFieldForVariable(ir.VariableDeclaration node, JField field);
   void registerFieldForBoxedVariable(ir.VariableDeclaration node, JField field);
 }
+
+class RecordClassData implements JClassData {
+  /// Tag used for identifying serialized [RecordClassData] objects in a
+  /// debugging data stream.
+  static const String tag = 'record-class-data';
+
+  @override
+  final ClassDefinition definition;
+
+  @override
+  final InterfaceType? thisType;
+
+  @override
+  final OrderedTypeSet orderedTypeSet;
+
+  @override
+  final InterfaceType? supertype;
+
+  RecordClassData(
+      this.definition, this.thisType, this.supertype, this.orderedTypeSet);
+
+  factory RecordClassData.readFromDataSource(DataSourceReader source) {
+    source.begin(tag);
+    ClassDefinition definition = ClassDefinition.readFromDataSource(source);
+    InterfaceType thisType = source.readDartType() as InterfaceType;
+    InterfaceType supertype = source.readDartType() as InterfaceType;
+    OrderedTypeSet orderedTypeSet = OrderedTypeSet.readFromDataSource(source);
+    source.end(tag);
+    return RecordClassData(definition, thisType, supertype, orderedTypeSet);
+  }
+
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(JClassDataKind.record);
+    sink.begin(tag);
+    definition.writeToDataSink(sink);
+    sink.writeDartType(thisType!);
+    sink.writeDartType(supertype!);
+    orderedTypeSet.writeToDataSink(sink);
+    sink.end(tag);
+  }
+
+  @override
+  bool get isMixinApplication => false;
+
+  @override
+  bool get isEnumClass => false;
+
+  @override
+  FunctionType? get callType => null;
+
+  @override
+  List<InterfaceType> get interfaces => const <InterfaceType>[];
+
+  @override
+  InterfaceType? get mixedInType => null;
+
+  @override
+  InterfaceType? get jsInteropType => thisType;
+
+  @override
+  InterfaceType? get rawType => thisType;
+
+  @override
+  InterfaceType? get instantiationToBounds => thisType;
+
+  @override
+  List<Variance> getVariances() => [];
+}
+
+class ClosureClassData extends RecordClassData {
+  /// Tag used for identifying serialized [ClosureClassData] objects in a
+  /// debugging data stream.
+  static const String tag = 'closure-class-data';
+
+  @override
+  FunctionType? callType;
+
+  ClosureClassData(
+      super.definition, super.thisType, super.supertype, super.orderedTypeSet);
+
+  factory ClosureClassData.readFromDataSource(DataSourceReader source) {
+    source.begin(tag);
+    ClassDefinition definition = ClassDefinition.readFromDataSource(source);
+    InterfaceType thisType = source.readDartType() as InterfaceType;
+    InterfaceType supertype = source.readDartType() as InterfaceType;
+    OrderedTypeSet orderedTypeSet = OrderedTypeSet.readFromDataSource(source);
+    FunctionType callType = source.readDartType() as FunctionType;
+    source.end(tag);
+    return ClosureClassData(definition, thisType, supertype, orderedTypeSet)
+      ..callType = callType;
+  }
+
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(JClassDataKind.closure);
+    sink.begin(tag);
+    definition.writeToDataSink(sink);
+    sink.writeDartType(thisType!);
+    sink.writeDartType(supertype!);
+    orderedTypeSet.writeToDataSink(sink);
+    sink.writeDartType(callType!);
+    sink.end(tag);
+  }
+}
+
+abstract class ClosureMemberData implements JMemberData {
+  @override
+  final MemberDefinition definition;
+  final InterfaceType? memberThisType;
+
+  ClosureMemberData(this.definition, this.memberThisType);
+
+  @override
+  StaticTypeCache get staticTypes {
+    // The cached types are stored in the data for enclosing member.
+    throw UnsupportedError("ClosureMemberData.staticTypes");
+  }
+
+  @override
+  InterfaceType? getMemberThisType(covariant JsToElementMap elementMap) {
+    return memberThisType;
+  }
+}
+
+class ClosureFunctionData extends ClosureMemberData
+    with FunctionDataTypeVariablesMixin, FunctionDataForEachParameterMixin
+    implements FunctionData {
+  /// Tag used for identifying serialized [ClosureFunctionData] objects in a
+  /// debugging data stream.
+  static const String tag = 'closure-function-data';
+
+  final FunctionType functionType;
+  @override
+  ir.FunctionNode get functionNode => _functionNode.loaded();
+  final Deferrable<ir.FunctionNode> _functionNode;
+  @override
+  final ClassTypeVariableAccess classTypeVariableAccess;
+
+  ClosureFunctionData(super.definition, super.memberThisType, this.functionType,
+      ir.FunctionNode functionNode, this.classTypeVariableAccess)
+      : _functionNode = Deferrable.eager(functionNode);
+
+  ClosureFunctionData._deserialized(super.definition, super.memberThisType,
+      this.functionType, this._functionNode, this.classTypeVariableAccess);
+
+  factory ClosureFunctionData.readFromDataSource(DataSourceReader source) {
+    source.begin(tag);
+    ClosureMemberDefinition definition =
+        MemberDefinition.readFromDataSource(source) as ClosureMemberDefinition;
+    InterfaceType? memberThisType =
+        source.readDartTypeOrNull() as InterfaceType?;
+    FunctionType functionType = source.readDartType() as FunctionType;
+    Deferrable<ir.FunctionNode> functionNode =
+        source.readDeferrable(() => source.readTreeNode() as ir.FunctionNode);
+    ClassTypeVariableAccess classTypeVariableAccess =
+        source.readEnum(ClassTypeVariableAccess.values);
+    source.end(tag);
+    return ClosureFunctionData._deserialized(definition, memberThisType,
+        functionType, functionNode, classTypeVariableAccess);
+  }
+
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(JMemberDataKind.closureFunction);
+    sink.begin(tag);
+    definition.writeToDataSink(sink);
+    sink.writeDartTypeOrNull(memberThisType);
+    sink.writeDartType(functionType);
+    sink.writeDeferrable(() => sink.writeTreeNode(functionNode));
+    sink.writeEnum(classTypeVariableAccess);
+    sink.end(tag);
+  }
+
+  @override
+  late final ir.Member memberContext = (() {
+    ir.TreeNode parent = functionNode;
+    while (parent is! ir.Member) {
+      parent = parent.parent!;
+    }
+    return parent;
+  })();
+
+  @override
+  FunctionType getFunctionType(IrToElementMap elementMap) {
+    return functionType;
+  }
+}
+
+class ClosureFieldData extends ClosureMemberData implements JFieldData {
+  /// Tag used for identifying serialized [ClosureFieldData] objects in a
+  /// debugging data stream.
+  static const String tag = 'closure-field-data';
+
+  DartType? _type;
+
+  ClosureFieldData(super.definition, super.memberThisType);
+
+  factory ClosureFieldData.readFromDataSource(DataSourceReader source) {
+    source.begin(tag);
+    MemberDefinition definition = MemberDefinition.readFromDataSource(source);
+    InterfaceType /*?*/ memberThisType =
+        source.readDartTypeOrNull() as InterfaceType /*?*/;
+    source.end(tag);
+    return ClosureFieldData(definition, memberThisType);
+  }
+
+  @override
+  void writeToDataSink(DataSinkWriter sink) {
+    sink.writeEnum(JMemberDataKind.closureField);
+    sink.begin(tag);
+    definition.writeToDataSink(sink);
+    sink.writeDartTypeOrNull(memberThisType);
+    sink.end(tag);
+  }
+
+  @override
+  DartType getFieldType(IrToElementMap elementMap) {
+    if (_type != null) return _type!;
+    ir.Node sourceNode = definition.node;
+    ir.DartType type;
+    if (sourceNode is ir.Class) {
+      type = sourceNode.getThisType(
+          elementMap.coreTypes, sourceNode.enclosingLibrary.nonNullable);
+    } else if (sourceNode is ir.VariableDeclaration) {
+      type = sourceNode.type;
+    } else if (sourceNode is ir.Field) {
+      type = sourceNode.type;
+    } else if (sourceNode is ir.TypeLiteral) {
+      type = sourceNode.type;
+    } else if (sourceNode is ir.Typedef) {
+      type = sourceNode.type!;
+    } else if (sourceNode is ir.TypeParameter) {
+      type = sourceNode.bound;
+    } else {
+      failedAt(
+          definition.location,
+          'Unexpected node type ${sourceNode} in '
+          'ClosureFieldData.getFieldType');
+    }
+    return _type = elementMap.getDartType(type);
+  }
+
+  @override
+  ClassTypeVariableAccess get classTypeVariableAccess =>
+      ClassTypeVariableAccess.none;
+}
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
index 75b6a58..99d2abd 100644
--- a/pkg/compiler/lib/src/js_model/element_map.dart
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import 'package:kernel/ast.dart' as ir;
 
 import '../common.dart';
@@ -21,7 +19,7 @@
 import '../native/behavior.dart';
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
-import '../world.dart';
+import '../world_interfaces.dart';
 import 'closure.dart';
 import 'element_map_interfaces.dart' as interfaces;
 import 'element_map_migrated.dart';
@@ -32,6 +30,7 @@
 /// global type inference and building the SSA graph for members.
 abstract class JsToElementMap implements interfaces.JsToElementMap {
   /// Access to the commonly used elements and types.
+  @override
   JCommonElements get commonElements;
 
   /// Access to the [DartTypes] object.
@@ -61,6 +60,7 @@
 
   /// Returns the [Selector] corresponding to the invocation or getter/setter
   /// access of [node].
+  @override
   Selector getSelector(ir.Expression node);
 
   /// Returns the [MemberEntity] corresponding to the member [node].
@@ -68,10 +68,12 @@
   MemberEntity getMember(ir.Member node);
 
   /// Returns the [FunctionEntity] corresponding to the procedure [node].
+  @override
   FunctionEntity getMethod(ir.Procedure node);
 
   /// Returns the [ConstructorEntity] corresponding to the generative or factory
   /// constructor [node].
+  @override
   ConstructorEntity getConstructor(ir.Member node);
 
   /// Returns the [FieldEntity] corresponding to the field [node].
@@ -88,6 +90,7 @@
   Name getName(ir.Name name);
 
   /// Computes the [native.NativeBehavior] for a call to the [JS] function.
+  @override
   NativeBehavior getNativeBehaviorForJsCall(ir.StaticInvocation node);
 
   /// Computes the [native.NativeBehavior] for a call to the [JS_BUILTIN]
@@ -104,8 +107,8 @@
   //  only needed because effectively constant expressions are not replaced by
   //  constant expressions during resolution.
   @override
-  ConstantValue getConstantValue(
-      ir.Member memberContext, ir.Expression expression,
+  ConstantValue? getConstantValue(
+      ir.Member memberContext, ir.Expression? expression,
       {bool requireConstant = true, bool implicitNull = false});
 
   /// Returns the [ConstantValue] for the sentinel used to indicate that a
@@ -134,11 +137,11 @@
   MemberDefinition getMemberDefinition(MemberEntity member);
 
   /// Returns the [ir.Member] containing the definition of [member], if any.
-  ir.Member getMemberContextNode(MemberEntity member);
+  ir.Member? getMemberContextNode(MemberEntity member);
 
   /// Returns the type of `this` in [member], or `null` if member is defined in
   /// a static context.
-  InterfaceType getMemberThisType(MemberEntity member);
+  InterfaceType? getMemberThisType(MemberEntity member);
 
   /// Returns how [member] has access to type variables of the this type
   /// returned by [getMemberThisType].
@@ -160,6 +163,7 @@
 
   /// Make a record to ensure variables that are are declared in one scope and
   /// modified in another get their values updated correctly.
+  @override
   Map<ir.VariableDeclaration, JRecordField> makeRecordContainer(
       KernelScopeInfo info, MemberEntity member);
 
@@ -227,19 +231,17 @@
 
 /// Returns the [ir.FunctionNode] that defines [member] or `null` if [member]
 /// is not a constructor, method or local function.
-ir.FunctionNode getFunctionNode(
+ir.FunctionNode? getFunctionNode(
     JsToElementMap elementMap, MemberEntity member) {
   MemberDefinition definition = elementMap.getMemberDefinition(member);
   switch (definition.kind) {
     case MemberKind.regular:
-      ir.Member node = definition.node;
-      return node.function;
     case MemberKind.constructor:
     case MemberKind.constructorBody:
-      ir.Member node = definition.node;
+      ir.Member node = definition.node as ir.Member;
       return node.function;
     case MemberKind.closureCall:
-      ir.LocalFunction node = definition.node;
+      ir.LocalFunction node = definition.node as ir.LocalFunction;
       return node.function;
     default:
   }
@@ -250,13 +252,15 @@
 ///
 /// If [field] is an instance field with a null literal initializer `null` is
 /// returned, otherwise the initializer of the [ir.Field] is returned.
-ir.Node getFieldInitializer(JsToElementMap elementMap, FieldEntity field) {
+ir.Node? getFieldInitializer(JsToElementMap elementMap, FieldEntity field) {
   MemberDefinition definition = elementMap.getMemberDefinition(field);
-  ir.Field node = definition.node;
-  if (node.isInstanceMember &&
+  ir.Field node = definition.node as ir.Field;
+  ir.Expression? initializer = node.initializer;
+  if (initializer != null &&
+      node.isInstanceMember &&
       !node.isFinal &&
-      isNullLiteral(node.initializer)) {
+      isNullLiteral(initializer)) {
     return null;
   }
-  return node.initializer;
+  return initializer;
 }
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 7deb133..fe5706c 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import 'package:front_end/src/api_prototype/constant_evaluator.dart' as ir;
 import 'package:front_end/src/api_unstable/dart2js.dart' as ir;
 
@@ -40,8 +38,9 @@
 import '../js_backend/native_data.dart';
 import '../js_model/class_type_variable_access.dart';
 import '../kernel/dart2js_target.dart' show allowedNativeTest;
-import '../kernel/element_map.dart';
-import '../kernel/env.dart';
+import '../kernel/element_map_interfaces.dart';
+import '../kernel/element_map_migrated.dart';
+import '../kernel/env_interfaces.dart';
 import '../kernel/kelements.dart';
 import '../native/behavior.dart';
 import '../options.dart';
@@ -81,18 +80,14 @@
   @override
   final DiagnosticReporter reporter;
   final Environment _environment;
-  /*late final*/ JCommonElements _commonElements;
-  /*late final*/ JsElementEnvironment _elementEnvironment;
-  /*late final*/ DartTypeConverter _typeConverter;
-  /*late final*/ KernelDartTypes _types;
-  ir.CoreTypes _coreTypes;
-  ir.TypeEnvironment _typeEnvironment;
-  ir.ClassHierarchy _classHierarchy;
-  Dart2jsConstantEvaluator /*?*/ _constantEvaluator;
-  /*late final*/ ConstantValuefier _constantValuefier;
+  late final JCommonElements _commonElements;
+  late final JsElementEnvironment _elementEnvironment;
+  late final DartTypeConverter _typeConverter;
+  late final KernelDartTypes _types;
+  late final ConstantValuefier _constantValuefier;
 
   /// Library environment. Used for fast lookup.
-  JProgramEnv programEnv;
+  late final JProgramEnv programEnv;
 
   final EntityDataEnvMap<IndexedLibrary, JLibraryData, JLibraryEnv> libraries =
       EntityDataEnvMap<IndexedLibrary, JLibraryData, JLibraryEnv>();
@@ -124,18 +119,18 @@
 
   /// NativeData is need for computation of the default super class and
   /// parameter ordering.
-  NativeData nativeData;
+  late final NativeData nativeData;
 
   final Map<IndexedFunction, JGeneratorBody> _generatorBodies = {};
 
   final Map<IndexedClass, List<IndexedMember>> _injectedClassMembers = {};
 
-  LateOutputUnitDataBuilder lateOutputUnitDataBuilder;
+  late final LateOutputUnitDataBuilder lateOutputUnitDataBuilder;
 
   JsKernelToElementMap(
       this.reporter,
       this._environment,
-      KernelToElementMap _elementMap,
+      KernelToElementMapForJsModel _elementMap,
       Map<MemberEntity, MemberUsage> liveMemberUsage,
       AnnotationsData annotations)
       : this.options = _elementMap.options {
@@ -149,10 +144,11 @@
     for (int libraryIndex = 0;
         libraryIndex < _elementMap.libraries.length;
         libraryIndex++) {
-      IndexedLibrary oldLibrary = _elementMap.libraries.getEntity(libraryIndex);
+      IndexedLibrary oldLibrary =
+          _elementMap.libraries.getEntity(libraryIndex)!;
       KLibraryEnv oldEnv = _elementMap.libraries.getEnv(oldLibrary);
       KLibraryData data = _elementMap.libraries.getData(oldLibrary);
-      IndexedLibrary newLibrary = JLibrary(oldLibrary.name,
+      IndexedLibrary newLibrary = JLibrary(oldLibrary.name!,
           oldLibrary.canonicalUri, oldLibrary.isNonNullableByDefault);
       JLibraryEnv newEnv = oldEnv.convert(_elementMap, liveMemberUsage);
       libraryMap[oldEnv.library] =
@@ -165,81 +161,83 @@
     for (int classIndex = 0;
         classIndex < _elementMap.classes.length;
         classIndex++) {
-      IndexedClass oldClass = _elementMap.classes.getEntity(classIndex);
+      IndexedClass oldClass = _elementMap.classes.getEntity(classIndex)!;
       KClassEnv env = _elementMap.classes.getEnv(oldClass);
       KClassData data = _elementMap.classes.getData(oldClass);
-      IndexedLibrary oldLibrary = oldClass.library;
-      LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex);
-      IndexedClass newClass =
-          JClass(newLibrary, oldClass.name, isAbstract: oldClass.isAbstract);
+      final oldLibrary = oldClass.library as IndexedLibrary;
+      LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex)!;
+      IndexedClass newClass = JClass(newLibrary as JLibrary, oldClass.name,
+          isAbstract: oldClass.isAbstract);
       JClassEnv newEnv = env.convert(_elementMap, liveMemberUsage,
-          (ir.Library library) => libraryMap[library]);
+          (ir.Library library) => libraryMap[library]!);
       classMap[env.cls] = classes.register(newClass, data.convert(), newEnv);
       assert(newClass.classIndex == oldClass.classIndex);
-      libraries.getEnv(newClass.library).registerClass(newClass.name, newEnv);
+      libraries.getEnv(newLibrary).registerClass(newClass.name, newEnv);
     }
 
     for (int memberIndex = 0;
         memberIndex < _elementMap.members.length;
         memberIndex++) {
-      IndexedMember oldMember = _elementMap.members.getEntity(memberIndex);
-      MemberUsage memberUsage = liveMemberUsage[oldMember];
+      IndexedMember oldMember = _elementMap.members.getEntity(memberIndex)!;
+      MemberUsage? memberUsage = liveMemberUsage[oldMember];
       if (memberUsage == null) {
         members.skipIndex(oldMember.memberIndex);
         continue;
       }
       KMemberData data = _elementMap.members.getData(oldMember);
-      IndexedLibrary oldLibrary = oldMember.library;
-      IndexedClass oldClass = oldMember.enclosingClass;
-      LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex);
-      ClassEntity newClass =
-          oldClass != null ? classes.getEntity(oldClass.classIndex) : null;
+      final oldLibrary = oldMember.library as IndexedLibrary;
+      final oldClass = oldMember.enclosingClass as IndexedClass?;
+      JLibrary newLibrary =
+          libraries.getEntity(oldLibrary.libraryIndex) as JLibrary;
+      JClass? newClass = oldClass != null
+          ? classes.getEntity(oldClass.classIndex) as JClass?
+          : null;
       IndexedMember newMember;
       Name memberName = oldMember.memberName;
       if (oldMember.isField) {
-        IndexedField field = oldMember;
+        final field = oldMember as IndexedField;
         newMember = JField(newLibrary, newClass, memberName,
             isStatic: field.isStatic,
             isAssignable: field.isAssignable,
             isConst: field.isConst);
       } else if (oldMember.isConstructor) {
-        IndexedConstructor constructor = oldMember;
+        final constructor = oldMember as IndexedConstructor;
         ParameterStructure parameterStructure =
             annotations.hasNoElision(constructor)
                 ? constructor.parameterStructure
-                : memberUsage.invokedParameters /*!*/;
+                : memberUsage.invokedParameters!;
         if (constructor.isFactoryConstructor) {
           // TODO(redemption): This should be a JFunction.
           newMember = JFactoryConstructor(
-              newClass, memberName, parameterStructure,
+              newClass!, memberName, parameterStructure,
               isExternal: constructor.isExternal,
               isConst: constructor.isConst,
               isFromEnvironmentConstructor:
                   constructor.isFromEnvironmentConstructor);
         } else {
           newMember = JGenerativeConstructor(
-              newClass, memberName, parameterStructure,
+              newClass!, memberName, parameterStructure,
               isExternal: constructor.isExternal, isConst: constructor.isConst);
         }
       } else if (oldMember.isGetter) {
-        IndexedFunction getter = oldMember;
+        final getter = oldMember as IndexedFunction;
         newMember = JGetter(
             newLibrary, newClass, memberName, getter.asyncMarker,
             isStatic: getter.isStatic,
             isExternal: getter.isExternal,
             isAbstract: getter.isAbstract);
       } else if (oldMember.isSetter) {
-        IndexedFunction setter = oldMember;
+        final setter = oldMember as IndexedFunction;
         newMember = JSetter(newLibrary, newClass, memberName,
             isStatic: setter.isStatic,
             isExternal: setter.isExternal,
             isAbstract: setter.isAbstract);
       } else {
-        IndexedFunction function = oldMember;
+        final function = oldMember as IndexedFunction;
         ParameterStructure parameterStructure =
             annotations.hasNoElision(function)
                 ? function.parameterStructure
-                : memberUsage.invokedParameters /*!*/;
+                : memberUsage.invokedParameters!;
         newMember = JMethod(newLibrary, newClass, memberName,
             parameterStructure, function.asyncMarker,
             isStatic: function.isStatic,
@@ -253,27 +251,27 @@
           "Old member $oldMember has index ${oldMember.memberIndex} "
           "whereas new member $newMember has index ${newMember.memberIndex}");
       if (newMember.isField) {
-        fieldMap[data.node] = newMember;
+        fieldMap[data.node as ir.Field] = newMember as IndexedField;
       } else if (newMember.isConstructor) {
-        constructorMap[data.node] = newMember;
+        constructorMap[data.node] = newMember as IndexedConstructor;
       } else {
-        methodMap[data.node] = newMember;
+        methodMap[data.node as ir.Procedure] = newMember as IndexedFunction;
       }
     }
     for (int typeVariableIndex = 0;
         typeVariableIndex < _elementMap.typeVariables.length;
         typeVariableIndex++) {
       IndexedTypeVariable oldTypeVariable =
-          _elementMap.typeVariables.getEntity(typeVariableIndex);
+          _elementMap.typeVariables.getEntity(typeVariableIndex)!;
       KTypeVariableData oldTypeVariableData =
           _elementMap.typeVariables.getData(oldTypeVariable);
-      Entity newTypeDeclaration;
+      Entity? newTypeDeclaration;
       if (oldTypeVariable.typeDeclaration is ClassEntity) {
-        IndexedClass cls = oldTypeVariable.typeDeclaration;
+        final cls = oldTypeVariable.typeDeclaration as IndexedClass;
         newTypeDeclaration = classes.getEntity(cls.classIndex);
         // TODO(johnniwinther): Skip type variables of unused classes.
       } else if (oldTypeVariable.typeDeclaration is MemberEntity) {
-        IndexedMember member = oldTypeVariable.typeDeclaration;
+        final member = oldTypeVariable.typeDeclaration as IndexedMember;
         newTypeDeclaration = members.getEntity(member.memberIndex);
         if (newTypeDeclaration == null) {
           typeVariables.skipIndex(typeVariableIndex);
@@ -283,7 +281,8 @@
         assert(oldTypeVariable.typeDeclaration is Local);
       }
       IndexedTypeVariable newTypeVariable = createTypeVariable(
-          newTypeDeclaration, oldTypeVariable.name, oldTypeVariable.index);
+              newTypeDeclaration, oldTypeVariable.name!, oldTypeVariable.index)
+          as IndexedTypeVariable;
       typeVariableMap[oldTypeVariableData.node] =
           typeVariables.register<IndexedTypeVariable, JTypeVariableData>(
               newTypeVariable, oldTypeVariableData.copy());
@@ -364,7 +363,9 @@
       classes.preRegisterByIndex(index, cls, env);
       JClassData data = JClassData.readFromDataSource(source);
       classes.postRegisterData(cls, data);
-      classMap[env.cls] = cls;
+      if (env.cls != null) {
+        classMap[env.cls!] = cls;
+      }
       if (cls is! closureMigrated.JRecord &&
           cls is! closureMigrated.JClosureClass) {
         // Synthesized classes are not part of the library environment.
@@ -381,13 +382,13 @@
       switch (data.definition.kind) {
         case MemberKind.regular:
         case MemberKind.constructor:
-          ir.Member node = data.definition.node;
+          final node = data.definition.node as ir.Member;
           if (member.isField) {
-            fieldMap[node] = member;
+            fieldMap[node as ir.Field] = member as IndexedField;
           } else if (member.isConstructor) {
-            constructorMap[node] = member;
+            constructorMap[node] = member as IndexedConstructor;
           } else {
-            methodMap[node] = member;
+            methodMap[node as ir.Procedure] = member as IndexedFunction;
           }
           break;
         default:
@@ -423,10 +424,11 @@
   int prepareForCodegenSerialization() {
     int length = members.length;
     for (int memberIndex = 0; memberIndex < length; memberIndex++) {
-      MemberEntity member = members.getEntity(memberIndex);
+      MemberEntity? member = members.getEntity(memberIndex);
       if (member == null) continue;
       if (member is JGenerativeConstructor) {
-        getConstructorBody(members.getData(member).definition.node);
+        getConstructorBody(
+            members.getData(member).definition.node as ir.Constructor);
       }
       if (member is IndexedFunction && member.asyncMarker != AsyncMarker.SYNC) {
         getGeneratorBody(member);
@@ -522,20 +524,20 @@
   @override
   JCommonElements get commonElements => _commonElements;
 
-  FunctionEntity get _mainFunction {
+  FunctionEntity? get _mainFunction {
     return programEnv.mainMethod != null
-        ? getMethodInternal(programEnv.mainMethod)
+        ? getMethodInternal(programEnv.mainMethod as ir.Procedure)
         : null;
   }
 
-  LibraryEntity get _mainLibrary {
+  LibraryEntity? get _mainLibrary {
     return programEnv.mainMethod != null
-        ? getLibraryInternal(programEnv.mainMethod.enclosingLibrary)
+        ? getLibraryInternal(programEnv.mainMethod!.enclosingLibrary)
         : null;
   }
 
-  SourceSpan getSourceSpan(Spannable spannable, Entity currentElement) {
-    SourceSpan fromSpannable(Spannable spannable) {
+  SourceSpan getSourceSpan(Spannable? spannable, Entity? currentElement) {
+    SourceSpan fromSpannable(Spannable? spannable) {
       if (spannable is IndexedLibrary &&
           spannable.libraryIndex < libraries.length) {
         JLibraryEnv env = libraries.getEnv(spannable);
@@ -543,12 +545,10 @@
       } else if (spannable is IndexedClass &&
           spannable.classIndex < classes.length) {
         JClassData data = classes.getData(spannable);
-        assert(data != null, "No data for $spannable in $this");
         return data.definition.location;
       } else if (spannable is IndexedMember &&
           spannable.memberIndex < members.length) {
         JMemberData data = members.getData(spannable);
-        assert(data != null, "No data for $spannable in $this");
         return data.definition.location;
       } else if (spannable is JLocal) {
         return getSourceSpan(spannable.memberContext, currentElement);
@@ -561,8 +561,8 @@
     return fromSpannable(currentElement);
   }
 
-  LibraryEntity lookupLibrary(Uri uri) {
-    JLibraryEnv libraryEnv = programEnv.lookupLibrary(uri);
+  LibraryEntity? lookupLibrary(Uri uri) {
+    JLibraryEnv? libraryEnv = programEnv.lookupLibrary(uri);
     if (libraryEnv == null) return null;
     return getLibraryInternal(libraryEnv.library, libraryEnv);
   }
@@ -573,11 +573,11 @@
     return libraryEnv.library.name ?? '';
   }
 
-  MemberEntity lookupLibraryMember(IndexedLibrary library, String name,
+  MemberEntity? lookupLibraryMember(IndexedLibrary library, String name,
       {bool setter = false}) {
     assert(checkFamily(library));
     JLibraryEnv libraryEnv = libraries.getEnv(library);
-    ir.Member member = libraryEnv.lookupMember(name, setter: setter);
+    ir.Member? member = libraryEnv.lookupMember(name, setter: setter);
     return member != null ? getMember(member) : null;
   }
 
@@ -590,12 +590,12 @@
     });
   }
 
-  ClassEntity lookupClass(IndexedLibrary library, String name) {
+  ClassEntity? lookupClass(IndexedLibrary library, String name) {
     assert(checkFamily(library));
     JLibraryEnv libraryEnv = libraries.getEnv(library);
-    JClassEnv classEnv = libraryEnv.lookupClass(name);
+    JClassEnv? classEnv = libraryEnv.lookupClass(name);
     if (classEnv != null) {
-      return getClassInternal(classEnv.cls, classEnv);
+      return getClassInternal(classEnv.cls!, classEnv);
     }
     return null;
   }
@@ -605,18 +605,18 @@
     JLibraryEnv libraryEnv = libraries.getEnv(library);
     libraryEnv.forEachClass((JClassEnv classEnv) {
       if (!classEnv.isUnnamedMixinApplication) {
-        f(getClassInternal(classEnv.cls, classEnv));
+        f(getClassInternal(classEnv.cls!, classEnv));
       }
     });
   }
 
-  MemberEntity lookupClassMember(IndexedClass cls, Name name) {
+  MemberEntity? lookupClassMember(IndexedClass cls, Name name) {
     assert(checkFamily(cls));
     JClassEnv classEnv = classes.getEnv(cls);
     return classEnv.lookupMember(this, name);
   }
 
-  ConstructorEntity lookupConstructor(IndexedClass cls, String name) {
+  ConstructorEntity? lookupConstructor(IndexedClass cls, String name) {
     assert(checkFamily(cls));
     JClassEnv classEnv = classes.getEnv(cls);
     return classEnv.lookupConstructor(this, name);
@@ -635,7 +635,7 @@
   ClassEntity getClass(ir.Class node) => getClassInternal(node);
 
   @override
-  InterfaceType getSuperType(IndexedClass cls) {
+  InterfaceType? getSuperType(IndexedClass cls) {
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
@@ -645,7 +645,7 @@
   void _ensureCallType(ClassEntity cls, JClassData data) {
     assert(checkFamily(cls));
     if (data is JClassDataImpl && !data.isCallTypeComputed) {
-      MemberEntity callMember =
+      MemberEntity? callMember =
           _elementEnvironment.lookupClassMember(cls, Names.call);
       if (callMember is FunctionEntity &&
           callMember.isFunction &&
@@ -703,7 +703,7 @@
         data.instantiationToBounds = getInterfaceType(ir.instantiateToBounds(
             coreTypes.legacyRawType(node),
             coreTypes.objectClass,
-            node.enclosingLibrary));
+            node.enclosingLibrary) as ir.InterfaceType);
       }
     }
   }
@@ -720,7 +720,7 @@
       ir.Class node = data.cls;
 
       if (node.supertype == null) {
-        data.orderedTypeSet = OrderedTypeSet.singleton(data.thisType);
+        data.orderedTypeSet = OrderedTypeSet.singleton(data.thisType!);
         data.isMixinApplication = false;
         data.interfaces = const <InterfaceType>[];
       } else {
@@ -733,18 +733,19 @@
 
         InterfaceType processSupertype(ir.Supertype supertypeNode) {
           supertypeNode = classHierarchy.getClassAsInstanceOf(
-              node, supertypeNode.classNode);
+              node, supertypeNode.classNode)!;
           InterfaceType supertype =
               _typeConverter.visitSupertype(supertypeNode);
           canonicalSupertypes.add(supertype);
-          IndexedClass superclass = supertype.element;
+          final superclass = supertype.element as IndexedClass;
           JClassData superdata = classes.getData(superclass);
           _ensureSupertypes(superclass, superdata);
-          for (InterfaceType supertype in superdata.orderedTypeSet.supertypes) {
+          for (InterfaceType supertype
+              in superdata.orderedTypeSet!.supertypes!) {
             ClassDefinition definition = getClassDefinition(supertype.element);
             if (definition.kind == ClassKind.regular) {
-              ir.Supertype canonicalSupertype =
-                  classHierarchy.getClassAsInstanceOf(node, definition.node);
+              ir.Supertype? canonicalSupertype = classHierarchy
+                  .getClassAsInstanceOf(node, definition.node as ir.Class);
               if (canonicalSupertype != null) {
                 supertype = _typeConverter.visitSupertype(canonicalSupertype);
               } else {
@@ -781,21 +782,23 @@
           // Set superclass to `Object`.
           supertype = _commonElements.objectType;
         } else {
-          supertype = processSupertype(node.supertype);
+          supertype = processSupertype(node.supertype!);
         }
         if (supertype == _commonElements.objectType) {
           ClassEntity defaultSuperclass =
               _commonElements.getDefaultSuperclass(cls, nativeData);
-          data.supertype = _elementEnvironment.getRawType(defaultSuperclass);
-          assert(data.supertype.typeArguments.isEmpty,
+          InterfaceType defaultSupertype = data.supertype =
+              _elementEnvironment.getRawType(defaultSuperclass);
+          assert(defaultSupertype.typeArguments.isEmpty,
               "Generic default supertypes are not supported");
-          canonicalSupertypes.add(data.supertype);
+          canonicalSupertypes.add(defaultSupertype);
         } else {
           data.supertype = supertype;
         }
         if (node.mixedInType != null) {
           data.isMixinApplication = true;
-          interfaces.add(data.mixedInType = processSupertype(node.mixedInType));
+          interfaces
+              .add(data.mixedInType = processSupertype(node.mixedInType!));
         } else {
           data.isMixinApplication = false;
         }
@@ -834,19 +837,14 @@
   ConstructorEntity getSuperConstructor(
       ir.Constructor sourceNode, ir.Member targetNode) {
     ConstructorEntity source = getConstructor(sourceNode);
-    ClassEntity sourceClass = source.enclosingClass;
+    final sourceClass = source.enclosingClass as IndexedClass;
     ConstructorEntity target = getConstructor(targetNode);
     ClassEntity targetClass = target.enclosingClass;
-    IndexedClass superClass = getSuperType(sourceClass)?.element;
-    if (superClass == targetClass) {
-      return target;
-    }
+    IndexedClass superClass =
+        getSuperType(sourceClass)!.element as IndexedClass;
+    if (superClass == targetClass) return target;
     JClassEnv env = classes.getEnv(superClass);
-    ConstructorEntity constructor = env.lookupConstructor(this, target.name);
-    if (constructor != null) {
-      return constructor;
-    }
-    throw failedAt(source, "Super constructor for $source not found.");
+    return env.lookupConstructor(this, target.name!)!;
   }
 
   @override
@@ -860,7 +858,7 @@
 
   @override
   TypeVariableType getTypeVariableType(ir.TypeParameterType type) =>
-      getDartType(type).withoutNullability;
+      getDartType(type).withoutNullability as TypeVariableType;
 
   @override
   List<DartType> getDartTypes(List<ir.DartType> types) {
@@ -873,7 +871,7 @@
 
   @override
   InterfaceType getInterfaceType(ir.InterfaceType type) =>
-      _typeConverter.visitType(type).withoutNullability;
+      _typeConverter.visitType(type).withoutNullability as InterfaceType;
 
   @override
   FunctionType getFunctionType(ir.FunctionNode node) {
@@ -908,13 +906,14 @@
     var namedParameters = <String>[];
     var requiredNamedParameters = <String>{};
     List<DartType> namedParameterTypes = [];
-    List<ir.VariableDeclaration> sortedNamedParameters =
-        node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
+    List<ir.VariableDeclaration> sortedNamedParameters = node.namedParameters
+        .toList()
+      ..sort((a, b) => a.name!.compareTo(b.name!));
     for (ir.VariableDeclaration variable in sortedNamedParameters) {
-      namedParameters.add(variable.name);
+      namedParameters.add(variable.name!);
       namedParameterTypes.add(getParameterType(variable));
       if (variable.isRequired) {
-        requiredNamedParameters.add(variable.name);
+        requiredNamedParameters.add(variable.name!);
       }
     }
     List<FunctionTypeVariable> typeVariables;
@@ -957,7 +956,7 @@
   @override
   DartType substByContext(DartType type, InterfaceType context) {
     return types.subst(context.typeArguments,
-        getThisType(context.element).typeArguments, type);
+        getThisType(context.element as IndexedClass).typeArguments, type);
   }
 
   /// Returns the type of the `call` method on 'type'.
@@ -965,13 +964,13 @@
   /// If [type] doesn't have a `call` member or has a non-method `call` member,
   /// `null` is returned.
   @override
-  FunctionType getCallType(InterfaceType type) {
-    IndexedClass cls = type.element;
+  FunctionType? getCallType(InterfaceType type) {
+    final cls = type.element as IndexedClass;
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureCallType(cls, data);
     if (data.callType != null) {
-      return substByContext(data.callType, type);
+      return substByContext(data.callType!, type) as FunctionType;
     }
     return null;
   }
@@ -981,45 +980,45 @@
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureThisAndRawType(cls, data);
-    return data.thisType;
+    return data.thisType!;
   }
 
   InterfaceType _getJsInteropType(IndexedClass cls) {
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureJsInteropType(cls, data);
-    return data.jsInteropType;
+    return data.jsInteropType!;
   }
 
   InterfaceType _getRawType(IndexedClass cls) {
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureThisAndRawType(cls, data);
-    return data.rawType;
+    return data.rawType!;
   }
 
   InterfaceType _getClassInstantiationToBounds(IndexedClass cls) {
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureClassInstantiationToBounds(cls, data);
-    return data.instantiationToBounds;
+    return data.instantiationToBounds!;
   }
 
   FunctionType _getFunctionType(IndexedFunction function) {
     assert(checkFamily(function));
-    FunctionData data = members.getData(function);
+    final data = members.getData(function) as FunctionData;
     return data.getFunctionType(this);
   }
 
   List<TypeVariableType> _getFunctionTypeVariables(IndexedFunction function) {
     assert(checkFamily(function));
-    FunctionData data = members.getData(function);
+    final data = members.getData(function) as FunctionData;
     return data.getFunctionTypeVariables(this);
   }
 
   DartType _getFieldType(IndexedField field) {
     assert(checkFamily(field));
-    JFieldData data = members.getData(field);
+    final data = members.getData(field) as JFieldData;
     return data.getFieldType(this);
   }
 
@@ -1043,7 +1042,7 @@
     return data.getDefaultType(this);
   }
 
-  ClassEntity getAppliedMixin(IndexedClass cls) {
+  ClassEntity? getAppliedMixin(IndexedClass cls) {
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
@@ -1054,7 +1053,7 @@
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
-    return data.isMixinApplication;
+    return data.isMixinApplication!;
   }
 
   bool _isUnnamedMixinApplication(IndexedClass cls) {
@@ -1073,7 +1072,7 @@
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
-    data.orderedTypeSet.supertypes.forEach(f);
+    data.orderedTypeSet!.supertypes!.forEach(f);
   }
 
   void _forEachConstructor(IndexedClass cls, void f(ConstructorEntity member)) {
@@ -1100,18 +1099,19 @@
     JClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     if (data.supertype != null) {
-      _forEachClassMember(data.supertype.element, f);
+      _forEachClassMember(data.supertype!.element as IndexedClass, f);
     }
   }
 
   @override
-  InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls) {
+  InterfaceType? asInstanceOf(InterfaceType type, ClassEntity cls) {
     assert(checkFamily(cls));
-    OrderedTypeSet orderedTypeSet = getOrderedTypeSet(type.element);
-    InterfaceType supertype =
-        orderedTypeSet.asInstanceOf(cls, getHierarchyDepth(cls));
+    OrderedTypeSet orderedTypeSet =
+        getOrderedTypeSet(type.element as IndexedClass);
+    InterfaceType? supertype = orderedTypeSet.asInstanceOf(
+        cls, getHierarchyDepth(cls as IndexedClass));
     if (supertype != null) {
-      supertype = substByContext(supertype, type);
+      supertype = substByContext(supertype, type) as InterfaceType;
     }
     return supertype;
   }
@@ -1121,7 +1121,7 @@
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
-    return data.orderedTypeSet;
+    return data.orderedTypeSet!;
   }
 
   @override
@@ -1129,7 +1129,7 @@
     assert(checkFamily(cls));
     JClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
-    return data.orderedTypeSet.maxDepth;
+    return data.orderedTypeSet!.maxDepth;
   }
 
   @override
@@ -1152,19 +1152,19 @@
 
   @override
   ImportEntity getImport(ir.LibraryDependency node) {
-    ir.Library library = node.parent;
-    JLibraryData data = libraries.getData(getLibraryInternal(library));
-    return data.imports[node];
+    ir.Library library = node.enclosingLibrary;
+    JLibraryData data =
+        libraries.getData(getLibraryInternal(library) as IndexedLibrary);
+    return data.imports[node]!;
   }
 
   @override
-  ir.CoreTypes get coreTypes =>
-      _coreTypes ??= ir.CoreTypes(programEnv.mainComponent);
+  late final ir.CoreTypes coreTypes = ir.CoreTypes(programEnv.mainComponent);
 
-  ir.TypeEnvironment get typeEnvironment =>
-      _typeEnvironment ??= ir.TypeEnvironment(coreTypes, classHierarchy);
+  late final ir.TypeEnvironment typeEnvironment =
+      ir.TypeEnvironment(coreTypes, classHierarchy);
 
-  ir.ClassHierarchy get classHierarchy => _classHierarchy ??=
+  late final ir.ClassHierarchy classHierarchy =
       ir.ClassHierarchy(programEnv.mainComponent, coreTypes);
 
   ir.StaticTypeContext getStaticTypeContext(ir.Member node) {
@@ -1172,38 +1172,38 @@
     return ir.StaticTypeContext(node, typeEnvironment);
   }
 
-  Dart2jsConstantEvaluator get constantEvaluator {
-    return _constantEvaluator ??=
-        Dart2jsConstantEvaluator(programEnv.mainComponent, typeEnvironment,
-            (ir.LocatedMessage message, List<ir.LocatedMessage> context) {
-      reportLocatedMessage(reporter, message, context);
-    },
-            environment: _environment,
-            evaluationMode: options.useLegacySubtyping
-                ? ir.EvaluationMode.weak
-                : ir.EvaluationMode.strong);
-  }
+  late final Dart2jsConstantEvaluator constantEvaluator =
+      Dart2jsConstantEvaluator(programEnv.mainComponent, typeEnvironment,
+          (ir.LocatedMessage message, List<ir.LocatedMessage>? context) {
+    reportLocatedMessage(reporter, message, context);
+  },
+          environment: _environment,
+          evaluationMode: options.useLegacySubtyping
+              ? ir.EvaluationMode.weak
+              : ir.EvaluationMode.strong);
 
   @override
   StaticTypeProvider getStaticTypeProvider(MemberEntity member) {
-    MemberDefinition memberDefinition = members.getData(member).definition;
-    StaticTypeCache cachedStaticTypes;
-    ir.StaticTypeContext staticTypeContext;
+    MemberDefinition memberDefinition =
+        members.getData(member as IndexedMember).definition;
+    late StaticTypeCache cachedStaticTypes;
+    late ir.StaticTypeContext staticTypeContext;
     switch (memberDefinition.kind) {
       case MemberKind.regular:
       case MemberKind.constructor:
       case MemberKind.constructorBody:
-        ir.Member node = memberDefinition.node;
+        final node = memberDefinition.node as ir.Member;
         staticTypeContext = getStaticTypeContext(node);
         cachedStaticTypes = members.getData(member).staticTypes;
         break;
       case MemberKind.closureCall:
-        ir.TreeNode node = memberDefinition.node;
+        var node = memberDefinition.node as ir.TreeNode?;
         while (node != null) {
           if (node is ir.Member) {
             ir.Member member = node;
             staticTypeContext = getStaticTypeContext(member);
-            cachedStaticTypes = members.getData(getMember(member)).staticTypes;
+            cachedStaticTypes =
+                members.getData(getMember(member) as IndexedMember).staticTypes;
             break;
           }
           node = node.parent;
@@ -1213,7 +1213,7 @@
       case MemberKind.signature:
       case MemberKind.generatorBody:
         cachedStaticTypes = const StaticTypeCache();
-        ir.TreeNode node = memberDefinition.node;
+        var node = memberDefinition.node as ir.TreeNode?;
         while (node != null) {
           if (node is ir.Member) {
             ir.Member member = node;
@@ -1229,15 +1229,13 @@
         }
         break;
     }
-    assert(cachedStaticTypes != null, "No static types cached for $member.");
-    assert(staticTypeContext != null, "No static types context for $member.");
     return CachedStaticType(staticTypeContext, cachedStaticTypes,
         ThisInterfaceType.from(staticTypeContext.thisType));
   }
 
   @override
   Name getName(ir.Name name, {bool setter = false}) {
-    return Name(name.text, name.isPrivate ? name.library.importUri : null,
+    return Name(name.text, name.isPrivate ? name.library!.importUri : null,
         isSetter: setter);
   }
 
@@ -1305,13 +1303,13 @@
 
   Selector getGetterSelector(ir.Name irName) {
     Name name =
-        Name(irName.text, irName.isPrivate ? irName.library.importUri : null);
+        Name(irName.text, irName.isPrivate ? irName.library!.importUri : null);
     return Selector.getter(name);
   }
 
   Selector getSetterSelector(ir.Name irName) {
     Name name =
-        Name(irName.text, irName.isPrivate ? irName.library.importUri : null);
+        Name(irName.text, irName.isPrivate ? irName.library!.importUri : null);
     return Selector.setter(name);
   }
 
@@ -1324,16 +1322,16 @@
         : (_cachedTypeLookupFull ??= _typeLookup(resolveAsRaw: false));
   }
 
-  TypeLookup _cachedTypeLookupRaw;
-  TypeLookup _cachedTypeLookupFull;
+  TypeLookup? _cachedTypeLookupRaw;
+  TypeLookup? _cachedTypeLookupFull;
 
-  TypeLookup _typeLookup({bool resolveAsRaw = true}) {
-    bool cachedMayLookupInMain;
+  TypeLookup _typeLookup({required bool resolveAsRaw}) {
+    bool? cachedMayLookupInMain;
 
-    DartType lookup(String typeName, {bool required}) {
-      DartType findInLibrary(LibraryEntity library) {
+    DartType? lookup(String typeName, {bool required = false}) {
+      DartType? findInLibrary(LibraryEntity? library) {
         if (library != null) {
-          ClassEntity cls = elementEnvironment.lookupClass(library, typeName);
+          ClassEntity? cls = elementEnvironment.lookupClass(library, typeName);
           if (cls != null) {
             // TODO(johnniwinther): Align semantics.
             return resolveAsRaw
@@ -1344,7 +1342,7 @@
         return null;
       }
 
-      DartType findIn(Uri uri) {
+      DartType? findIn(Uri uri) {
         return findInLibrary(elementEnvironment.lookupLibrary(uri));
       }
 
@@ -1353,9 +1351,9 @@
       // TODO(johnniwinther): Cache more results to avoid redundant lookups?
       cachedMayLookupInMain ??=
           // Tests permit lookup outside of dart: libraries.
-          allowedNativeTest(elementEnvironment.mainLibrary.canonicalUri);
-      DartType type;
-      if (cachedMayLookupInMain) {
+          allowedNativeTest(elementEnvironment.mainLibrary!.canonicalUri);
+      DartType? type;
+      if (cachedMayLookupInMain!) {
         type ??= findInLibrary(elementEnvironment.mainLibrary);
       }
       type ??= findIn(Uris.dart_core);
@@ -1384,7 +1382,7 @@
     return lookup;
   }
 
-  String _getStringArgument(ir.StaticInvocation node, int index) {
+  String? _getStringArgument(ir.StaticInvocation node, int index) {
     return node.arguments.positional[index].accept(Stringifier());
   }
 
@@ -1397,14 +1395,14 @@
           CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS);
       return NativeBehavior();
     }
-    String specString = _getStringArgument(node, 0);
+    String? specString = _getStringArgument(node, 0);
     if (specString == null) {
       reporter.reportErrorMessage(
           CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_FIRST);
       return NativeBehavior();
     }
 
-    String codeString = _getStringArgument(node, 1);
+    String? codeString = _getStringArgument(node, 1);
     if (codeString == null) {
       reporter.reportErrorMessage(
           CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND);
@@ -1433,7 +1431,7 @@
           CURRENT_ELEMENT_SPANNABLE, "JS builtin is missing name.");
       return NativeBehavior();
     }
-    String specString = _getStringArgument(node, 0);
+    String? specString = _getStringArgument(node, 0);
     if (specString == null) {
       reporter.internalError(
           CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument.");
@@ -1467,7 +1465,7 @@
           "JS embedded global has more than 2 arguments.");
       return NativeBehavior();
     }
-    String specString = _getStringArgument(node, 0);
+    String? specString = _getStringArgument(node, 0);
     if (specString == null) {
       reporter.internalError(
           CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument.");
@@ -1482,7 +1480,7 @@
   }
 
   @override
-  ConstantValue getConstantValue(ir.Member memberContext, ir.Expression node,
+  ConstantValue? getConstantValue(ir.Member memberContext, ir.Expression? node,
       {bool requireConstant = true, bool implicitNull = false}) {
     if (node == null) {
       if (!implicitNull) {
@@ -1498,7 +1496,7 @@
       // computation.
       ir.StaticTypeContext staticTypeContext =
           getStaticTypeContext(memberContext);
-      ir.Constant constant = constantEvaluator.evaluateOrNull(
+      ir.Constant? constant = constantEvaluator.evaluateOrNull(
           staticTypeContext, node,
           requireConstant: requireConstant);
       if (constant == null) {
@@ -1524,13 +1522,14 @@
 
   @override
   FunctionEntity getSuperNoSuchMethod(ClassEntity cls) {
-    while (cls != null) {
-      cls = elementEnvironment.getSuperClass(cls);
-      MemberEntity member =
-          elementEnvironment.lookupLocalClassMember(cls, Names.noSuchMethod_);
+    while (true) {
+      ClassEntity? superclass = elementEnvironment.getSuperClass(cls);
+      if (superclass == null) break;
+      MemberEntity? member = elementEnvironment.lookupLocalClassMember(
+          superclass, Names.noSuchMethod_);
       if (member != null && !member.isAbstract) {
         if (member.isFunction) {
-          FunctionEntity function = member;
+          final function = member as FunctionEntity;
           if (function.parameterStructure.positionalParameters >= 1) {
             return function;
           }
@@ -1539,27 +1538,25 @@
         // `Object.superNoSuchMethod`.
         break;
       }
+      cls = superclass;
     }
-    FunctionEntity function = elementEnvironment.lookupLocalClassMember(
-        commonElements.objectClass, Names.noSuchMethod_);
-    assert(function != null,
-        failedAt(cls, "No super noSuchMethod found for class $cls."));
-    return function;
+    return elementEnvironment.lookupLocalClassMember(
+        commonElements.objectClass, Names.noSuchMethod_)! as FunctionEntity;
   }
 
   TypeVariableEntity createTypeVariable(
-      Entity typeDeclaration, String name, int index) {
+      Entity? typeDeclaration, String name, int index) {
     return JTypeVariable(typeDeclaration, name, index);
   }
 
   JConstructorBody createConstructorBody(
       ConstructorEntity constructor, ParameterStructure parameterStructure) {
-    return JConstructorBody(constructor, parameterStructure);
+    return JConstructorBody(constructor as JConstructor, parameterStructure);
   }
 
   JGeneratorBody createGeneratorBody(
       FunctionEntity function, DartType elementType) {
-    return JGeneratorBody(function, elementType);
+    return JGeneratorBody(function as JFunction, elementType);
   }
 
   void forEachNestedClosure(
@@ -1569,14 +1566,14 @@
   }
 
   @override
-  InterfaceType getMemberThisType(MemberEntity member) {
-    return members.getData(member).getMemberThisType(this);
+  InterfaceType? getMemberThisType(MemberEntity member) {
+    return members.getData(member as IndexedMember).getMemberThisType(this);
   }
 
   @override
   ClassTypeVariableAccess getClassTypeVariableAccessForMember(
       MemberEntity member) {
-    return members.getData(member).classTypeVariableAccess;
+    return members.getData(member as IndexedMember).classTypeVariableAccess;
   }
 
   bool checkFamily(Entity entity) {
@@ -1588,64 +1585,42 @@
   }
 
   @override
-  Spannable getSpannable(MemberEntity member, ir.Node node) {
-    SourceSpan sourceSpan;
-    if (node is ir.TreeNode) {
-      sourceSpan = computeSourceSpanFromTreeNode(node);
-    }
-    sourceSpan ??= getSourceSpan(member, null);
-    return sourceSpan;
-  }
+  Spannable getSpannable(MemberEntity member, ir.Node node) =>
+      node is ir.TreeNode
+          ? computeSourceSpanFromTreeNode(node)
+          : getSourceSpan(member, null);
 
   Iterable<LibraryEntity> get libraryListInternal {
     return libraryMap.values;
   }
 
-  LibraryEntity getLibraryInternal(ir.Library node, [JLibraryEnv env]) {
-    LibraryEntity library = libraryMap[node];
-    assert(library != null, "No library entity for $node");
-    return library;
-  }
+  LibraryEntity getLibraryInternal(ir.Library node, [JLibraryEnv? env]) =>
+      libraryMap[node]!;
 
-  ClassEntity getClassInternal(ir.Class node, [JClassEnv env]) {
-    ClassEntity cls = classMap[node];
-    assert(cls != null, "No class entity for $node");
-    return cls;
-  }
+  ClassEntity getClassInternal(ir.Class node, [JClassEnv? env]) =>
+      classMap[node]!;
 
-  FieldEntity getFieldInternal(ir.Field node) {
-    FieldEntity field = fieldMap[node];
-    assert(field != null, "No field entity for $node");
-    return field;
-  }
+  FieldEntity getFieldInternal(ir.Field node) => fieldMap[node]!;
 
-  FunctionEntity getMethodInternal(ir.Procedure node) {
-    FunctionEntity function = methodMap[node];
-    assert(function != null, "No function entity for $node");
-    return function;
-  }
+  FunctionEntity getMethodInternal(ir.Procedure node) => methodMap[node]!;
 
-  ConstructorEntity getConstructorInternal(ir.Member node) {
-    ConstructorEntity constructor = constructorMap[node];
-    assert(constructor != null, "No constructor entity for $node");
-    return constructor;
-  }
+  ConstructorEntity getConstructorInternal(ir.Member node) =>
+      constructorMap[node]!;
 
   TypeVariableEntity getTypeVariableInternal(ir.TypeParameter node) {
-    TypeVariableEntity typeVariable = typeVariableMap[node];
+    TypeVariableEntity? typeVariable = typeVariableMap[node];
     if (typeVariable == null) {
-      if (node.parent is ir.FunctionNode) {
-        ir.FunctionNode func = node.parent;
-        int index = func.typeParameters.indexOf(node);
-        if (func.parent is ir.Constructor) {
-          ir.Constructor constructor = func.parent;
-          ir.Class cls = constructor.enclosingClass;
+      final parent = node.parent;
+      if (parent is ir.FunctionNode) {
+        final member = parent.parent;
+        int index = parent.typeParameters.indexOf(node);
+        if (member is ir.Constructor) {
+          ir.Class cls = member.enclosingClass;
           typeVariableMap[node] =
               typeVariable = getTypeVariableInternal(cls.typeParameters[index]);
-        } else if (func.parent is ir.Procedure) {
-          ir.Procedure procedure = func.parent;
-          if (procedure.kind == ir.ProcedureKind.Factory) {
-            ir.Class cls = procedure.enclosingClass;
+        } else if (member is ir.Procedure) {
+          if (member.kind == ir.ProcedureKind.Factory) {
+            ir.Class cls = member.enclosingClass!;
             typeVariableMap[node] = typeVariable =
                 getTypeVariableInternal(cls.typeParameters[index]);
           }
@@ -1656,7 +1631,7 @@
       throw failedAt(
           CURRENT_ELEMENT_SPANNABLE,
           "No type variable entity for $node on "
-          "${node.parent is ir.FunctionNode ? node.parent.parent : node.parent}");
+          "${node.parent is ir.FunctionNode ? node.parent!.parent : node.parent}");
     }
     return typeVariable;
   }
@@ -1664,29 +1639,30 @@
   @override
   FunctionEntity getConstructorBody(ir.Constructor node) {
     ConstructorEntity constructor = getConstructor(node);
-    return _getConstructorBody(constructor);
+    return _getConstructorBody(constructor as IndexedConstructor);
   }
 
   JConstructorBody _getConstructorBody(IndexedConstructor constructor) {
-    JConstructorDataImpl data = members.getData(constructor);
-    JConstructorBody /*?*/ constructorBody = data.constructorBody;
+    JConstructorDataImpl data =
+        members.getData(constructor) as JConstructorDataImpl;
+    JConstructorBody? constructorBody = data.constructorBody;
     if (constructorBody == null) {
       /// The constructor calls the constructor body with all parameters.
       // TODO(johnniwinther): Remove parameters that are not used in the
       //  constructor body.
       ParameterStructure parameterStructure =
-          _getParameterStructureFromFunctionNode(data.node.function);
+          _getParameterStructureFromFunctionNode(data.node.function!);
 
       constructorBody = createConstructorBody(constructor, parameterStructure);
       members.register<IndexedFunction, FunctionData>(
           constructorBody,
           ConstructorBodyDataImpl(
               data.node,
-              data.node.function,
+              data.node.function!,
               SpecialMemberDefinition(data.node, MemberKind.constructorBody),
               data.staticTypes));
-      IndexedClass cls = constructor.enclosingClass;
-      JClassEnvImpl classEnv = classes.getEnv(cls);
+      final cls = constructor.enclosingClass as IndexedClass;
+      final classEnv = classes.getEnv(cls) as JClassEnvImpl;
       // TODO(johnniwinther): Avoid this by only including live members in the
       // js-model.
       classEnv.addConstructorBody(constructorBody);
@@ -1699,12 +1675,12 @@
 
   @override
   MemberDefinition getMemberDefinition(MemberEntity member) {
-    return getMemberDefinitionInternal(member);
+    return getMemberDefinitionInternal(member as IndexedMember);
   }
 
   @override
-  ir.Member getMemberContextNode(MemberEntity member) {
-    ir.Member getParentMember(ir.TreeNode node) {
+  ir.Member? getMemberContextNode(MemberEntity member) {
+    ir.Member? getParentMember(ir.TreeNode? node) {
       while (node != null) {
         if (node is ir.Member) {
           return node;
@@ -1719,27 +1695,26 @@
       case MemberKind.regular:
       case MemberKind.constructor:
       case MemberKind.constructorBody:
-        return definition.node;
+        return definition.node as ir.Member;
       case MemberKind.closureCall:
       case MemberKind.closureField:
       case MemberKind.signature:
       case MemberKind.generatorBody:
-        return getParentMember(definition.node);
+        return getParentMember(definition.node as ir.TreeNode?);
     }
-    throw UnsupportedError('Unexpected member kind ${definition}');
   }
 
   @override
   ClassDefinition getClassDefinition(ClassEntity cls) {
-    return getClassDefinitionInternal(cls);
+    return getClassDefinitionInternal(cls as IndexedClass);
   }
 
   /// Calls [f] for each parameter of [function] providing the type and name of
   /// the parameter and the [defaultValue] if the parameter is optional.
   void forEachParameter(covariant IndexedFunction function,
-      void f(DartType type, String name, ConstantValue defaultValue),
+      void f(DartType type, String? name, ConstantValue? defaultValue),
       {bool isNative = false}) {
-    FunctionData data = members.getData(function);
+    final data = members.getData(function) as FunctionData;
     data.forEachParameter(this, function.parameterStructure, f,
         isNative: isNative);
   }
@@ -1756,15 +1731,15 @@
   }
 
   JRecordField _constructRecordFieldEntry(
-      InterfaceType memberThisType,
+      InterfaceType? memberThisType,
       ir.VariableDeclaration variable,
       BoxLocal boxLocal,
       Map<Name, MemberEntity> memberMap) {
     JRecordField boxedField =
-        JRecordField(variable.name, boxLocal, isConst: variable.isConst);
+        JRecordField(variable.name!, boxLocal, isConst: variable.isConst);
     members.register(
         boxedField,
-        ClosureFieldData(
+        closureMigrated.ClosureFieldData(
             ClosureMemberDefinition(computeSourceSpanFromTreeNode(variable),
                 MemberKind.closureField, variable),
             memberThisType));
@@ -1781,7 +1756,7 @@
       KernelScopeInfo info, MemberEntity member) {
     Map<ir.VariableDeclaration, JRecordField> boxedFields = {};
     if (info.boxedVariables.isNotEmpty) {
-      NodeBox box = info.capturedVariablesAccessor;
+      NodeBox box = info.capturedVariablesAccessor!;
 
       Map<Name, IndexedMember> memberMap = {};
       closureMigrated.JRecord container =
@@ -1790,15 +1765,16 @@
       InterfaceType thisType =
           types.interfaceType(container, const <DartType>[]);
       InterfaceType supertype = commonElements.objectType;
-      JClassData containerData = RecordClassData(
+      JClassData containerData = closureMigrated.RecordClassData(
           RecordContainerDefinition(getMemberDefinition(member).location),
           thisType,
           supertype,
-          getOrderedTypeSet(supertype.element).extendClass(types, thisType));
+          getOrderedTypeSet(supertype.element as IndexedClass)
+              .extendClass(types, thisType));
       classes.register(container, containerData, RecordEnv(memberMap));
 
-      InterfaceType memberThisType = member.enclosingClass != null
-          ? elementEnvironment.getThisType(member.enclosingClass)
+      InterfaceType? memberThisType = member.enclosingClass != null
+          ? elementEnvironment.getThisType(member.enclosingClass!)
           : null;
       for (ir.VariableDeclaration variable in info.boxedVariables) {
         boxedFields[variable] = _constructRecordFieldEntry(
@@ -1816,10 +1792,10 @@
     var namedParameters = <String>[];
     var requiredNamedParameters = <String>{};
     for (var p in node.namedParameters.toList()
-      ..sort((a, b) => a.name.compareTo(b.name))) {
-      namedParameters.add(p.name);
+      ..sort((a, b) => a.name!.compareTo(b.name!))) {
+      namedParameters.add(p.name!);
       if (p.isRequired && !options.useLegacySubtyping) {
-        requiredNamedParameters.add(p.name);
+        requiredNamedParameters.add(p.name!);
       }
     }
     return ParameterStructure(
@@ -1837,12 +1813,12 @@
       Map<ir.VariableDeclaration, JRecordField> recordFieldsVisibleInScope,
       KernelScopeInfo info,
       InterfaceType supertype,
-      {bool createSignatureMethod}) {
-    InterfaceType memberThisType = member.enclosingClass != null
-        ? elementEnvironment.getThisType(member.enclosingClass)
+      {required bool createSignatureMethod}) {
+    InterfaceType? memberThisType = member.enclosingClass != null
+        ? elementEnvironment.getThisType(member.enclosingClass!)
         : null;
     ClassTypeVariableAccess typeVariableAccess =
-        members.getData(member).classTypeVariableAccess;
+        members.getData(member as IndexedMember).classTypeVariableAccess;
     if (typeVariableAccess == ClassTypeVariableAccess.instanceField) {
       // A closure in a field initializer will only be executed in the
       // constructor and type variables are therefore accessed through
@@ -1858,20 +1834,23 @@
     // relationships that _ensureSupertypes and _ensureThisAndRawType are doing
     InterfaceType thisType =
         types.interfaceType(classEntity, const <DartType>[]);
-    ClosureClassData closureData = ClosureClassData(
-        ClosureClassDefinition(location),
-        thisType,
-        supertype,
-        getOrderedTypeSet(supertype.element).extendClass(types, thisType));
+    closureMigrated.ClosureClassData closureData =
+        closureMigrated.ClosureClassData(
+            ClosureClassDefinition(location),
+            thisType,
+            supertype,
+            getOrderedTypeSet(supertype.element as IndexedClass)
+                .extendClass(types, thisType));
     classes.register(classEntity, closureData, ClosureClassEnv(memberMap));
 
-    Local closureEntity;
-    ir.VariableDeclaration closureEntityNode;
+    Local? closureEntity;
+    ir.VariableDeclaration? closureEntityNode;
     if (node.parent is ir.FunctionDeclaration) {
-      ir.FunctionDeclaration parent = node.parent;
+      final parent = node.parent as ir.FunctionDeclaration;
       closureEntityNode = parent.variable;
     } else if (node.parent is ir.FunctionExpression) {
-      closureEntity = closureMigrated.AnonymousClosureLocal(classEntity);
+      closureEntity = closureMigrated.AnonymousClosureLocal(
+          classEntity as closureMigrated.JClosureClass);
     }
 
     IndexedFunction callMethod = JClosureCallMethod(classEntity,
@@ -1885,7 +1864,8 @@
     int index = 0;
     for (ir.TypeParameter typeParameter in node.typeParameters) {
       typeVariableMap[typeParameter] = typeVariables.register(
-          createTypeVariable(callMethod, typeParameter.name, index),
+          createTypeVariable(callMethod, typeParameter.name!, index)
+              as IndexedTypeVariable,
           JTypeVariableData(typeParameter));
       index++;
     }
@@ -1898,7 +1878,7 @@
         member.enclosingClass,
         closureEntity,
         closureEntityNode,
-        info.hasThisLocal ? ThisLocal(member.enclosingClass) : null);
+        info.hasThisLocal ? ThisLocal(member.enclosingClass!) : null);
     _buildClosureClassFields(closureClassInfo, member, memberThisType, info,
         recordFieldsVisibleInScope, memberMap);
 
@@ -1911,21 +1891,22 @@
 
     members.register<IndexedFunction, FunctionData>(
         callMethod,
-        ClosureFunctionData(
+        closureMigrated.ClosureFunctionData(
             ClosureMemberDefinition(
-                location, MemberKind.closureCall, node.parent),
+                location, MemberKind.closureCall, node.parent!),
             memberThisType,
-            closureData.callType,
+            closureData.callType!,
             node,
             typeVariableAccess));
-    memberMap[callMethod.memberName] = closureClassInfo.callMethod = callMethod;
+    memberMap[callMethod.memberName] =
+        closureClassInfo.callMethod = callMethod as JFunction;
     return closureClassInfo;
   }
 
   void _buildClosureClassFields(
       JsClosureClassInfo closureClassInfo,
       MemberEntity member,
-      InterfaceType memberThisType,
+      InterfaceType? memberThisType,
       KernelScopeInfo info,
       Map<ir.VariableDeclaration, JRecordField> recordFieldsVisibleInScope,
       Map<Name, MemberEntity> memberMap) {
@@ -1958,13 +1939,13 @@
     // Add a field for the captured 'this'.
     if (info.thisUsedAsFreeVariable) {
       closureClassInfo.registerFieldForLocal(
-          closureClassInfo.thisLocal,
+          closureClassInfo.thisLocal!,
           _constructClosureField(
-              closureClassInfo.thisLocal.name,
+              closureClassInfo.thisLocal!.name!,
               closureClassInfo,
               memberThisType,
               memberMap,
-              getClassDefinition(member.enclosingClass).node,
+              getClassDefinition(member.enclosingClass!).node as ir.TreeNode,
               true,
               false,
               fieldNumber));
@@ -1979,7 +1960,7 @@
           closureClassInfo.registerFieldForVariable(
               variable,
               _constructClosureField(
-                  variable.name,
+                  variable.name!,
                   closureClassInfo,
                   memberThisType,
                   memberMap,
@@ -1995,13 +1976,14 @@
         // We can have distinct TypeVariableTypeWithContexts that have the same
         // local variable but with different nullabilities. We only want to
         // construct a closure field once for each local variable.
-        if (closureClassInfo.hasFieldForTypeVariable(typeVariable)) {
+        if (closureClassInfo
+            .hasFieldForTypeVariable(typeVariable as JTypeVariable)) {
           continue;
         }
         closureClassInfo.registerFieldForTypeVariable(
             typeVariable,
             _constructClosureField(
-                variable.type.parameter.name,
+                variable.type.parameter.name!,
                 closureClassInfo,
                 memberThisType,
                 memberMap,
@@ -2026,12 +2008,12 @@
   bool _constructClosureFieldForRecord(
       ir.VariableDeclaration capturedLocal,
       JsClosureClassInfo closureClassInfo,
-      InterfaceType memberThisType,
+      InterfaceType? memberThisType,
       Map<Name, MemberEntity> memberMap,
       ir.TreeNode sourceNode,
       Map<ir.VariableDeclaration, JRecordField> recordFieldsVisibleInScope,
       int fieldNumber) {
-    JRecordField recordField = recordFieldsVisibleInScope[capturedLocal];
+    JRecordField recordField = recordFieldsVisibleInScope[capturedLocal]!;
 
     // Don't construct a new field if the box that holds this local already has
     // a field in the closure class.
@@ -2041,13 +2023,13 @@
       return false;
     }
 
-    FieldEntity closureField = JClosureField(
+    final closureField = JClosureField(
         '_box_$fieldNumber', closureClassInfo, recordField.box.name,
         isConst: true, isAssignable: false);
 
     members.register<IndexedField, JFieldData>(
         closureField,
-        ClosureFieldData(
+        closureMigrated.ClosureFieldData(
             ClosureMemberDefinition(computeSourceSpanFromTreeNode(sourceNode),
                 MemberKind.closureField, sourceNode),
             memberThisType));
@@ -2061,16 +2043,16 @@
       JsClosureClassInfo closureClassInfo,
       Map<Name, MemberEntity> memberMap,
       ir.FunctionNode closureSourceNode,
-      InterfaceType memberThisType,
+      InterfaceType? memberThisType,
       SourceSpan location,
       ClassTypeVariableAccess typeVariableAccess) {
-    FunctionEntity signatureMethod =
+    final signatureMethod =
         JSignatureMethod(closureClassInfo.closureClassEntity);
     members.register<IndexedFunction, FunctionData>(
         signatureMethod,
         SignatureFunctionData(
             SpecialMemberDefinition(
-                closureSourceNode.parent, MemberKind.signature),
+                closureSourceNode.parent!, MemberKind.signature),
             memberThisType,
             closureSourceNode.typeParameters,
             typeVariableAccess));
@@ -2081,7 +2063,7 @@
   JField _constructClosureField(
       String name,
       JsClosureClassInfo closureClassInfo,
-      InterfaceType memberThisType,
+      InterfaceType? memberThisType,
       Map<Name, MemberEntity> memberMap,
       ir.TreeNode sourceNode,
       bool isConst,
@@ -2093,7 +2075,7 @@
 
     members.register<IndexedField, JFieldData>(
         closureField,
-        ClosureFieldData(
+        closureMigrated.ClosureFieldData(
             ClosureMemberDefinition(computeSourceSpanFromTreeNode(sourceNode),
                 MemberKind.closureField, sourceNode),
             memberThisType));
@@ -2108,7 +2090,7 @@
     // compound name where increasing nesting level corresponds to extra
     // underscores.
     var anonymous = 'closure';
-    ir.TreeNode current = treeNode;
+    ir.TreeNode? current = treeNode;
     // TODO(johnniwinther): Simplify computed names.
     while (current != null) {
       var node = current;
@@ -2116,9 +2098,9 @@
         parts.add(anonymous);
         anonymous = '';
       } else if (node is ir.FunctionDeclaration) {
-        String name = node.variable.name;
+        String? name = node.variable.name;
         if (name != null && name != "") {
-          parts.add(utils.operatorNameToIdentifier(name));
+          parts.add(utils.operatorNameToIdentifier(name)!);
         } else {
           parts.add(anonymous);
           anonymous = '';
@@ -2129,17 +2111,18 @@
         break;
       } else if (node is ir.Procedure) {
         if (node.kind == ir.ProcedureKind.Factory) {
-          parts.add(utils.reconstructConstructorName(getMember(node)));
+          parts.add(utils
+              .reconstructConstructorName(getMember(node) as FunctionEntity));
         } else {
-          parts.add(utils.operatorNameToIdentifier(node.name.text));
+          parts.add(utils.operatorNameToIdentifier(node.name.text)!);
         }
       } else if (node is ir.Constructor) {
-        parts.add(utils.reconstructConstructorName(getMember(node)));
+        parts.add(utils
+            .reconstructConstructorName(getMember(node) as FunctionEntity));
         break;
       } else if (node is ir.Field) {
         // Add the field name for closures in field initializers.
-        String name = node.name?.text;
-        if (name != null) parts.add(name);
+        parts.add(node.name.text);
       }
       current = current.parent;
     }
@@ -2163,9 +2146,9 @@
 
   @override
   JGeneratorBody getGeneratorBody(covariant IndexedFunction function) {
-    JGeneratorBody generatorBody = _generatorBodies[function];
+    JGeneratorBody? generatorBody = _generatorBodies[function];
     if (generatorBody == null) {
-      FunctionData functionData = members.getData(function);
+      final functionData = members.getData(function) as FunctionData;
       DartType elementType =
           elementEnvironment.getFunctionAsyncOrSyncStarElementType(function);
       generatorBody = createGeneratorBody(function, elementType);
@@ -2178,7 +2161,8 @@
 
       if (function.enclosingClass != null) {
         // TODO(sra): Integrate this with ClassEnvImpl.addConstructorBody ?
-        (_injectedClassMembers[function.enclosingClass] ??= <IndexedMember>[])
+        (_injectedClassMembers[function.enclosingClass as IndexedClass] ??=
+                <IndexedMember>[])
             .add(generatorBody);
       }
       lateOutputUnitDataBuilder.registerColocatedMembers(
@@ -2199,37 +2183,37 @@
   DartType get dynamicType => elementMap.types.dynamicType();
 
   @override
-  LibraryEntity get mainLibrary => elementMap._mainLibrary;
+  LibraryEntity? get mainLibrary => elementMap._mainLibrary;
 
   @override
-  FunctionEntity get mainFunction => elementMap._mainFunction;
+  FunctionEntity? get mainFunction => elementMap._mainFunction;
 
   @override
   Iterable<LibraryEntity> get libraries => elementMap.libraryListInternal;
 
   @override
   String getLibraryName(LibraryEntity library) {
-    return elementMap._getLibraryName(library);
+    return elementMap._getLibraryName(library as IndexedLibrary);
   }
 
   @override
   InterfaceType getThisType(ClassEntity cls) {
-    return elementMap.getThisType(cls);
+    return elementMap.getThisType(cls as IndexedClass);
   }
 
   @override
   InterfaceType getJsInteropType(ClassEntity cls) {
-    return elementMap._getJsInteropType(cls);
+    return elementMap._getJsInteropType(cls as IndexedClass);
   }
 
   @override
   InterfaceType getRawType(ClassEntity cls) {
-    return elementMap._getRawType(cls);
+    return elementMap._getRawType(cls as IndexedClass);
   }
 
   @override
   InterfaceType getClassInstantiationToBounds(ClassEntity cls) =>
-      elementMap._getClassInstantiationToBounds(cls);
+      elementMap._getClassInstantiationToBounds(cls as IndexedClass);
 
   @override
   bool isGenericClass(ClassEntity cls) {
@@ -2238,41 +2222,42 @@
 
   @override
   bool isMixinApplication(ClassEntity cls) {
-    return elementMap._isMixinApplication(cls);
+    return elementMap._isMixinApplication(cls as IndexedClass);
   }
 
   @override
   bool isUnnamedMixinApplication(ClassEntity cls) {
-    return elementMap._isUnnamedMixinApplication(cls);
+    return elementMap._isUnnamedMixinApplication(cls as IndexedClass);
   }
 
   @override
   bool isMixinApplicationWithMembers(ClassEntity cls) {
-    return elementMap._isMixinApplicationWithMembers(cls);
+    return elementMap._isMixinApplicationWithMembers(cls as IndexedClass);
   }
 
   @override
-  ClassEntity getEffectiveMixinClass(ClassEntity cls) {
+  ClassEntity? getEffectiveMixinClass(ClassEntity cls) {
     if (!isMixinApplication(cls)) return null;
     do {
-      cls = elementMap.getAppliedMixin(cls);
+      cls = elementMap.getAppliedMixin(cls as IndexedClass)!;
     } while (isMixinApplication(cls));
     return cls;
   }
 
   @override
   DartType getTypeVariableBound(TypeVariableEntity typeVariable) {
-    return elementMap.getTypeVariableBound(typeVariable);
+    return elementMap.getTypeVariableBound(typeVariable as IndexedTypeVariable);
   }
 
   @override
   List<Variance> getTypeVariableVariances(ClassEntity cls) {
-    return elementMap.getTypeVariableVariances(cls);
+    return elementMap.getTypeVariableVariances(cls as IndexedClass);
   }
 
   @override
   DartType getTypeVariableDefaultType(TypeVariableEntity typeVariable) {
-    return elementMap._getTypeVariableDefaultType(typeVariable);
+    return elementMap
+        ._getTypeVariableDefaultType(typeVariable as IndexedTypeVariable);
   }
 
   @override
@@ -2283,12 +2268,12 @@
 
   @override
   FunctionType getFunctionType(FunctionEntity function) {
-    return elementMap._getFunctionType(function);
+    return elementMap._getFunctionType(function as IndexedFunction);
   }
 
   @override
   List<TypeVariableType> getFunctionTypeVariables(FunctionEntity function) {
-    return elementMap._getFunctionTypeVariables(function);
+    return elementMap._getFunctionTypeVariables(function as IndexedFunction);
   }
 
   @override
@@ -2333,13 +2318,13 @@
         }
         return dynamicType;
     }
-    assert(false, 'Unexpected marker ${asyncMarker}');
-    return null;
+    throw failedAt(
+        CURRENT_ELEMENT_SPANNABLE, 'Unexpected marker ${asyncMarker}');
   }
 
   @override
   DartType getFieldType(FieldEntity field) {
-    return elementMap._getFieldType(field);
+    return elementMap._getFieldType(field as IndexedField);
   }
 
   @override
@@ -2348,9 +2333,10 @@
   }
 
   @override
-  ConstructorEntity lookupConstructor(ClassEntity cls, String name,
+  ConstructorEntity? lookupConstructor(ClassEntity cls, String name,
       {bool required = false}) {
-    ConstructorEntity constructor = elementMap.lookupConstructor(cls, name);
+    ConstructorEntity? constructor =
+        elementMap.lookupConstructor(cls as IndexedClass, name);
     if (constructor == null && required) {
       throw failedAt(
           CURRENT_ELEMENT_SPANNABLE,
@@ -2361,9 +2347,10 @@
   }
 
   @override
-  MemberEntity lookupLocalClassMember(ClassEntity cls, Name name,
+  MemberEntity? lookupLocalClassMember(ClassEntity cls, Name name,
       {bool required = false}) {
-    MemberEntity member = elementMap.lookupClassMember(cls, name);
+    MemberEntity? member =
+        elementMap.lookupClassMember(cls as IndexedClass, name);
     if (member == null && required) {
       throw failedAt(CURRENT_ELEMENT_SPANNABLE,
           "The member '$name' was not found in ${cls.name}.");
@@ -2372,14 +2359,16 @@
   }
 
   @override
-  ClassEntity getSuperClass(ClassEntity cls,
+  ClassEntity? getSuperClass(ClassEntity cls,
       {bool skipUnnamedMixinApplications = false}) {
     assert(elementMap.checkFamily(cls));
-    ClassEntity superclass = elementMap.getSuperType(cls)?.element;
+    IndexedClass? superclass =
+        elementMap.getSuperType(cls as IndexedClass)?.element as IndexedClass?;
     if (skipUnnamedMixinApplications) {
       while (superclass != null &&
           elementMap._isUnnamedMixinApplication(superclass)) {
-        superclass = elementMap.getSuperType(superclass)?.element;
+        superclass =
+            elementMap.getSuperType(superclass)?.element as IndexedClass?;
       }
     }
     return superclass;
@@ -2387,36 +2376,36 @@
 
   @override
   void forEachSupertype(ClassEntity cls, void f(InterfaceType supertype)) {
-    elementMap._forEachSupertype(cls, f);
+    elementMap._forEachSupertype(cls as IndexedClass, f);
   }
 
   @override
   void forEachLocalClassMember(ClassEntity cls, void f(MemberEntity member)) {
-    elementMap._forEachLocalClassMember(cls, f);
+    elementMap._forEachLocalClassMember(cls as IndexedClass, f);
   }
 
   @override
   void forEachInjectedClassMember(
       ClassEntity cls, void f(MemberEntity member)) {
-    elementMap.forEachInjectedClassMember(cls, f);
+    elementMap.forEachInjectedClassMember(cls as IndexedClass, f);
   }
 
   @override
   void forEachClassMember(
       ClassEntity cls, void f(ClassEntity declarer, MemberEntity member)) {
-    elementMap._forEachClassMember(cls, f);
+    elementMap._forEachClassMember(cls as IndexedClass, f);
   }
 
   @override
   void forEachConstructor(
       ClassEntity cls, void f(ConstructorEntity constructor)) {
-    elementMap._forEachConstructor(cls, f);
+    elementMap._forEachConstructor(cls as IndexedClass, f);
   }
 
   @override
   void forEachConstructorBody(
       ClassEntity cls, void f(ConstructorBodyEntity constructor)) {
-    elementMap.forEachConstructorBody(cls, f);
+    elementMap.forEachConstructorBody(cls as IndexedClass, f);
   }
 
   @override
@@ -2428,14 +2417,14 @@
   @override
   void forEachLibraryMember(
       LibraryEntity library, void f(MemberEntity member)) {
-    elementMap._forEachLibraryMember(library, f);
+    elementMap._forEachLibraryMember(library as IndexedLibrary, f);
   }
 
   @override
-  MemberEntity lookupLibraryMember(LibraryEntity library, String name,
+  MemberEntity? lookupLibraryMember(LibraryEntity library, String name,
       {bool setter = false, bool required = false}) {
-    MemberEntity member =
-        elementMap.lookupLibraryMember(library, name, setter: setter);
+    MemberEntity? member = elementMap
+        .lookupLibraryMember(library as IndexedLibrary, name, setter: setter);
     if (member == null && required) {
       failedAt(CURRENT_ELEMENT_SPANNABLE,
           "The member '${name}' was not found in library '${library.name}'.");
@@ -2444,9 +2433,9 @@
   }
 
   @override
-  ClassEntity lookupClass(LibraryEntity library, String name,
+  ClassEntity? lookupClass(LibraryEntity library, String name,
       {bool required = false}) {
-    ClassEntity cls = elementMap.lookupClass(library, name);
+    ClassEntity? cls = elementMap.lookupClass(library as IndexedLibrary, name);
     if (cls == null && required) {
       failedAt(CURRENT_ELEMENT_SPANNABLE,
           "The class '$name'  was not found in library '${library.name}'.");
@@ -2456,12 +2445,12 @@
 
   @override
   void forEachClass(LibraryEntity library, void f(ClassEntity cls)) {
-    elementMap._forEachClass(library, f);
+    elementMap._forEachClass(library as IndexedLibrary, f);
   }
 
   @override
-  LibraryEntity lookupLibrary(Uri uri, {bool required = false}) {
-    LibraryEntity library = elementMap.lookupLibrary(uri);
+  LibraryEntity? lookupLibrary(Uri uri, {bool required = false}) {
+    LibraryEntity? library = elementMap.lookupLibrary(uri);
     if (library == null && required) {
       failedAt(CURRENT_ELEMENT_SPANNABLE, "The library '$uri' was not found.");
     }
@@ -2471,14 +2460,14 @@
   @override
   bool isEnumClass(ClassEntity cls) {
     assert(elementMap.checkFamily(cls));
-    JClassData classData = elementMap.classes.getData(cls);
+    JClassData classData = elementMap.classes.getData(cls as IndexedClass);
     return classData.isEnumClass;
   }
 
   @override
   void forEachParameter(FunctionEntity function,
-      void f(DartType type, String name, ConstantValue defaultValue)) {
-    elementMap.forEachParameter(function, f,
+      void f(DartType type, String? name, ConstantValue? defaultValue)) {
+    elementMap.forEachParameter(function as IndexedFunction, f,
         isNative: elementMap.nativeData.isNativeMember(function));
   }
 
@@ -2486,7 +2475,7 @@
   void forEachParameterAsLocal(GlobalLocalsMap globalLocalsMap,
       FunctionEntity function, void f(Local parameter)) {
     forEachOrderedParameterAsLocal(globalLocalsMap, elementMap, function,
-        (Local parameter, {bool isElided}) {
+        (Local parameter, {required bool isElided}) {
       if (!isElided) {
         f(parameter);
       }
@@ -2498,7 +2487,7 @@
       ClassEntity cls, void f(ClassEntity declarer, FieldEntity field)) {
     forEachClassMember(cls, (ClassEntity declarer, MemberEntity member) {
       if (member.isField && member.isInstanceMember) {
-        f(declarer, member);
+        f(declarer, member as FieldEntity);
       }
     });
   }
@@ -2512,7 +2501,7 @@
       if (declarer != cls) return;
       if (!member.isField) return;
       if (!member.isInstanceMember) return;
-      f(member);
+      f(member as FieldEntity);
     });
   }
 }
@@ -2569,32 +2558,17 @@
   }
 
   @override
-  IndexedLibrary getLibraryByIndex(int index) {
-    IndexedLibrary library = _libraries[index];
-    assert(library != null, "No library found for index $index");
-    return library;
-  }
+  IndexedLibrary getLibraryByIndex(int index) => _libraries[index]!;
 
   @override
-  IndexedClass getClassByIndex(int index) {
-    IndexedClass cls = _classes[index];
-    assert(cls != null, "No class found for index $index");
-    return cls;
-  }
+  IndexedClass getClassByIndex(int index) => _classes[index]!;
 
   @override
-  IndexedMember getMemberByIndex(int index) {
-    IndexedMember member = _members[index];
-    assert(member != null, "No member found for index $index");
-    return member;
-  }
+  IndexedMember getMemberByIndex(int index) => _members[index]!;
 
   @override
-  IndexedTypeVariable getTypeVariableByIndex(int index) {
-    IndexedTypeVariable typeVariable = _typeVariables[index];
-    assert(typeVariable != null, "No type variable found for index $index");
-    return typeVariable;
-  }
+  IndexedTypeVariable getTypeVariableByIndex(int index) =>
+      _typeVariables[index]!;
 }
 
 /// [EntityLookup] implementation for an fully built [JsKernelToElementMap].
@@ -2605,22 +2579,22 @@
 
   @override
   IndexedTypeVariable getTypeVariableByIndex(int index) {
-    return _elementMap.typeVariables.getEntity(index);
+    return _elementMap.typeVariables.getEntity(index)!;
   }
 
   @override
   IndexedMember getMemberByIndex(int index) {
-    return _elementMap.members.getEntity(index);
+    return _elementMap.members.getEntity(index)!;
   }
 
   @override
   IndexedClass getClassByIndex(int index) {
-    return _elementMap.classes.getEntity(index);
+    return _elementMap.classes.getEntity(index)!;
   }
 
   @override
   IndexedLibrary getLibraryByIndex(int index) {
-    return _elementMap.libraries.getEntity(index);
+    return _elementMap.libraries.getEntity(index)!;
   }
 }
 
@@ -2657,13 +2631,13 @@
     LateMemberKind kind = source.readEnum(LateMemberKind.values);
     switch (kind) {
       case LateMemberKind.constructorBody:
-        IndexedConstructor constructor = source.readMember();
+        IndexedConstructor constructor =
+            source.readMember() as IndexedConstructor;
         return _elementMap._getConstructorBody(constructor);
       case LateMemberKind.generatorBody:
-        IndexedFunction function = source.readMember();
+        final function = source.readMember() as IndexedFunction;
         return _elementMap.getGeneratorBody(function);
     }
-    throw UnsupportedError("Unexpected late member kind: $kind.");
   }
 }
 
diff --git a/pkg/compiler/lib/src/js_model/element_map_interfaces.dart b/pkg/compiler/lib/src/js_model/element_map_interfaces.dart
index 7b548e09..f7367f9 100644
--- a/pkg/compiler/lib/src/js_model/element_map_interfaces.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_interfaces.dart
@@ -9,20 +9,32 @@
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
+import '../ir/closure.dart';
 import '../ir/element_map.dart';
+import '../native/behavior.dart';
+import '../universe/selector.dart';
+import 'closure_migrated.dart';
 
 // TODO(48820): Remove this interface when nnbd migration is done.
 abstract class JsToElementMap {
+  JCommonElements get commonElements;
   JElementEnvironment get elementEnvironment;
   DartTypes get types;
-  ConstantValue getConstantValue(
-      ir.Member memberContext, ir.Expression expression,
+  ConstantValue? getConstantValue(
+      ir.Member memberContext, ir.Expression? expression,
       {bool requireConstant = true, bool implicitNull = false});
   DartType getDartType(ir.DartType type);
 
+  Selector getSelector(ir.Expression node);
+  ConstructorEntity getConstructor(ir.Member node);
+  FunctionEntity getMethod(ir.Procedure node);
   MemberEntity getMember(ir.Member node);
   MemberDefinition getMemberDefinition(MemberEntity member);
   ConstantValue getRequiredSentinelConstantValue();
+
+  Map<ir.VariableDeclaration, JRecordField> makeRecordContainer(
+      KernelScopeInfo info, MemberEntity member);
+  NativeBehavior getNativeBehaviorForJsCall(ir.StaticInvocation node);
 }
 
 abstract class JsKernelToElementMap implements JsToElementMap, IrToElementMap {}
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index fdb122c..44ec959 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -222,10 +222,9 @@
   @override
   final AsyncMarker asyncMarker;
 
-  JFunction(JLibrary library, JClass? enclosingClass, Name name,
+  JFunction(super.library, super.enclosingClass, super.name,
       this.parameterStructure, this.asyncMarker,
-      {bool isStatic = false, this.isExternal = false})
-      : super(library, enclosingClass, name, isStatic: isStatic);
+      {super.isStatic, this.isExternal = false});
 }
 
 abstract class JConstructor extends JFunction
@@ -267,10 +266,8 @@
   static const String tag = 'generative-constructor';
 
   JGenerativeConstructor(
-      JClass enclosingClass, Name name, ParameterStructure parameterStructure,
-      {required bool isExternal, required bool isConst})
-      : super(enclosingClass, name, parameterStructure,
-            isExternal: isExternal, isConst: isConst);
+      super.enclosingClass, super.name, super.parameterStructure,
+      {required super.isExternal, required super.isConst});
 
   factory JGenerativeConstructor.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
@@ -314,12 +311,10 @@
   final bool isFromEnvironmentConstructor;
 
   JFactoryConstructor(
-      JClass enclosingClass, Name name, ParameterStructure parameterStructure,
-      {required bool isExternal,
-      required bool isConst,
-      required this.isFromEnvironmentConstructor})
-      : super(enclosingClass, name, parameterStructure,
-            isExternal: isExternal, isConst: isConst);
+      super.enclosingClass, super.name, super.parameterStructure,
+      {required super.isExternal,
+      required super.isConst,
+      required this.isFromEnvironmentConstructor});
 
   factory JFactoryConstructor.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
@@ -401,13 +396,11 @@
   @override
   final bool isAbstract;
 
-  JMethod(JLibrary library, JClass? enclosingClass, Name name,
-      ParameterStructure parameterStructure, AsyncMarker asyncMarker,
-      {required bool isStatic,
-      required bool isExternal,
-      required this.isAbstract})
-      : super(library, enclosingClass, name, parameterStructure, asyncMarker,
-            isStatic: isStatic, isExternal: isExternal);
+  JMethod(super.library, super.enclosingClass, super.name,
+      super.parameterStructure, super.asyncMarker,
+      {required super.isStatic,
+      required super.isExternal,
+      required this.isAbstract});
 
   factory JMethod.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
@@ -644,11 +637,10 @@
   @override
   final bool isConst;
 
-  JField(JLibrary library, JClass? enclosingClass, Name name,
-      {required bool isStatic,
+  JField(super.library, super.enclosingClass, super.name,
+      {required super.isStatic,
       required this.isAssignable,
-      required this.isConst})
-      : super(library, enclosingClass, name, isStatic: isStatic);
+      required this.isConst});
 
   factory JField.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
diff --git a/pkg/compiler/lib/src/js_model/env.dart b/pkg/compiler/lib/src/js_model/env.dart
index 065a485..5e712fa 100644
--- a/pkg/compiler/lib/src/js_model/env.dart
+++ b/pkg/compiler/lib/src/js_model/env.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 library dart2js.js_model.env;
 
 import 'package:kernel/ast.dart' as ir;
@@ -20,7 +18,7 @@
 import '../ordered_typeset.dart';
 import '../serialization/deferrable.dart';
 import '../serialization/serialization.dart';
-import 'closure.dart'
+import 'closure_migrated.dart'
     show
         ClosureClassData,
         RecordClassData,
@@ -42,7 +40,7 @@
   JProgramEnv(this._components);
 
   /// TODO(johnniwinther): Handle arbitrary load order if needed.
-  ir.Member get mainMethod => _components.first?.mainMethod;
+  ir.Member? get mainMethod => _components.first.mainMethod;
 
   ir.Component get mainComponent => _components.first;
 
@@ -51,7 +49,7 @@
   }
 
   /// Return the [JLibraryEnv] for the library with the canonical [uri].
-  JLibraryEnv lookupLibrary(Uri uri) {
+  JLibraryEnv? lookupLibrary(Uri uri) {
     return _libraryMap[uri];
   }
 
@@ -84,9 +82,9 @@
     source.begin(tag);
     ir.Library library = source.readLibraryNode();
     Map<String, ir.Member> memberMap =
-        source.readStringMap(source.readMemberNode);
+        source.readStringMap(source.readMemberNode)!;
     Map<String, ir.Member> setterMap =
-        source.readStringMap(source.readMemberNode);
+        source.readStringMap(source.readMemberNode)!;
     source.end(tag);
     return JLibraryEnv(library, memberMap, setterMap);
   }
@@ -105,7 +103,7 @@
   }
 
   /// Return the [JClassEnv] for the class [name] in [library].
-  JClassEnv lookupClass(String name) {
+  JClassEnv? lookupClass(String name) {
     return _classMap[name];
   }
 
@@ -115,7 +113,7 @@
   }
 
   /// Return the [ir.Member] for the member [name] in [library].
-  ir.Member lookupMember(String name, {bool setter = false}) {
+  ir.Member? lookupMember(String name, {bool setter = false}) {
     return setter ? _setterMap[name] : _memberMap[name];
   }
 
@@ -155,6 +153,8 @@
         ImportEntity import = source.readImport();
         imports[library.dependencies[index]] = import;
       }
+    } else {
+      imports = const {};
     }
     source.end(tag);
     return JLibraryData(library, imports);
@@ -163,19 +163,15 @@
   void writeToDataSink(DataSinkWriter sink) {
     sink.begin(tag);
     sink.writeLibraryNode(library);
-    if (imports == null) {
-      sink.writeInt(0);
-    } else {
-      sink.writeInt(imports.length);
-      int index = 0;
-      for (ir.LibraryDependency node in library.dependencies) {
-        ImportEntity import = imports[node];
-        if (import != null) {
-          sink.writeInt(index);
-          sink.writeImport(import);
-        }
-        index++;
+    sink.writeInt(imports.length);
+    int index = 0;
+    for (ir.LibraryDependency node in library.dependencies) {
+      ImportEntity? import = imports[node];
+      if (import != null) {
+        sink.writeInt(index);
+        sink.writeImport(import);
       }
+      index++;
     }
     sink.end(tag);
   }
@@ -197,14 +193,13 @@
       case JClassEnvKind.record:
         return RecordEnv.readFromDataSource(source);
     }
-    throw UnsupportedError("Unsupported JClassEnvKind $kind");
   }
 
   /// Serializes this [JClassEnv] to [sink].
   void writeToDataSink(DataSinkWriter sink);
 
   /// The [ir.Class] that defined the class, if any.
-  ir.Class get cls;
+  ir.Class? get cls;
 
   /// Whether the class is an unnamed mixin application.
   bool get isUnnamedMixinApplication;
@@ -218,13 +213,13 @@
   /// Return the [MemberEntity] for the member [name] in the class. If [setter]
   /// is `true`, the setter or assignable field corresponding to [name] is
   /// returned.
-  MemberEntity lookupMember(IrToElementMap elementMap, Name name);
+  MemberEntity? lookupMember(IrToElementMap elementMap, Name name);
 
   /// Calls [f] for each member of [cls].
   void forEachMember(IrToElementMap elementMap, void f(MemberEntity member));
 
   /// Return the [ConstructorEntity] for the constructor [name] in [cls].
-  ConstructorEntity lookupConstructor(IrToElementMap elementMap, String name);
+  ConstructorEntity? lookupConstructor(IrToElementMap elementMap, String name);
 
   /// Calls [f] for each constructor of [cls].
   void forEachConstructor(
@@ -250,7 +245,7 @@
   final bool isMixinApplicationWithMembers;
 
   /// Constructor bodies created for this class.
-  List<ConstructorBodyEntity> _constructorBodyList;
+  List<ConstructorBodyEntity>? _constructorBodyList;
 
   JClassEnvImpl(this.cls, this._constructorMap, this._memberMap, this._members,
       this.isMixinApplicationWithMembers);
@@ -259,8 +254,8 @@
     source.begin(tag);
     ir.Class cls = source.readClassNode();
     Map<String, ir.Member> constructorMap =
-        source.readStringMap(source.readMemberNode);
-    Map<Name, ir.Member> memberMap = source.readNameMap(source.readMemberNode);
+        source.readStringMap(source.readMemberNode)!;
+    Map<Name, ir.Member> memberMap = source.readNameMap(source.readMemberNode)!;
     List<ir.Member> members = source.readMemberNodes();
     bool isSuperMixinApplication = source.readBool();
     source.end(tag);
@@ -284,8 +279,8 @@
   bool get isUnnamedMixinApplication => cls.isAnonymousMixin;
 
   @override
-  MemberEntity lookupMember(IrToElementMap elementMap, Name name) {
-    ir.Member member = _memberMap[name];
+  MemberEntity? lookupMember(IrToElementMap elementMap, Name name) {
+    ir.Member? member = _memberMap[name];
     return member != null ? elementMap.getMember(member) : null;
   }
 
@@ -297,8 +292,8 @@
   }
 
   @override
-  ConstructorEntity lookupConstructor(IrToElementMap elementMap, String name) {
-    ir.Member constructor = _constructorMap[name];
+  ConstructorEntity? lookupConstructor(IrToElementMap elementMap, String name) {
+    ir.Member? constructor = _constructorMap[name];
     return constructor != null ? elementMap.getConstructor(constructor) : null;
   }
 
@@ -311,8 +306,7 @@
   }
 
   void addConstructorBody(ConstructorBodyEntity constructorBody) {
-    _constructorBodyList ??= <ConstructorBodyEntity>[];
-    _constructorBodyList.add(constructorBody);
+    (_constructorBodyList ??= <ConstructorBodyEntity>[]).add(constructorBody);
   }
 
   @override
@@ -333,7 +327,7 @@
   factory RecordEnv.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
     Map<Name, IndexedMember> _memberMap =
-        source.readNameMap(() => source.readMember());
+        source.readNameMap(() => source.readMember() as IndexedMember)!;
     source.end(tag);
     return RecordEnv(_memberMap);
   }
@@ -359,7 +353,7 @@
   }
 
   @override
-  ConstructorEntity lookupConstructor(IrToElementMap elementMap, String name) {
+  ConstructorEntity? lookupConstructor(IrToElementMap elementMap, String name) {
     // We do not create constructors for containers.
     return null;
   }
@@ -370,7 +364,7 @@
   }
 
   @override
-  MemberEntity lookupMember(IrToElementMap elementMap, Name name) {
+  MemberEntity? lookupMember(IrToElementMap elementMap, Name name) {
     return _memberMap[name];
   }
 
@@ -381,7 +375,7 @@
   bool get isMixinApplicationWithMembers => false;
 
   @override
-  ir.Class get cls => null;
+  ir.Class? get cls => null;
 }
 
 class ClosureClassEnv extends RecordEnv {
@@ -389,12 +383,12 @@
   /// debugging data stream.
   static const String tag = 'closure-class-env';
 
-  ClosureClassEnv(Map<Name, MemberEntity> memberMap) : super(memberMap);
+  ClosureClassEnv(super.memberMap);
 
   factory ClosureClassEnv.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
     Map<Name, IndexedMember> _memberMap =
-        source.readNameMap(() => source.readMember());
+        source.readNameMap(() => source.readMember() as IndexedMember)!;
     source.end(tag);
     return ClosureClassEnv(_memberMap);
   }
@@ -424,7 +418,6 @@
       case JClassDataKind.record:
         return RecordClassData.readFromDataSource(source);
     }
-    throw UnsupportedError("Unexpected JClassDataKind $kind");
   }
 
   /// Serializes this [JClassData] to [sink].
@@ -432,18 +425,18 @@
 
   ClassDefinition get definition;
 
-  InterfaceType get thisType;
-  InterfaceType get jsInteropType;
-  InterfaceType get rawType;
-  InterfaceType get instantiationToBounds;
-  InterfaceType get supertype;
-  InterfaceType get mixedInType;
+  InterfaceType? get thisType;
+  InterfaceType? get jsInteropType;
+  InterfaceType? get rawType;
+  InterfaceType? get instantiationToBounds;
+  InterfaceType? get supertype;
+  InterfaceType? get mixedInType;
   List<InterfaceType> get interfaces;
-  OrderedTypeSet get orderedTypeSet;
-  FunctionType get callType;
+  OrderedTypeSet? get orderedTypeSet;
+  FunctionType? get callType;
 
   bool get isEnumClass;
-  bool get isMixinApplication;
+  bool? get isMixinApplication;
 
   List<Variance> getVariances();
 }
@@ -457,26 +450,26 @@
   @override
   final ClassDefinition definition;
   @override
-  bool isMixinApplication;
+  bool? isMixinApplication;
 
   @override
-  InterfaceType thisType;
+  InterfaceType? thisType;
   @override
-  InterfaceType jsInteropType;
+  InterfaceType? jsInteropType;
   @override
-  InterfaceType rawType;
+  InterfaceType? rawType;
   @override
-  InterfaceType instantiationToBounds;
+  InterfaceType? instantiationToBounds;
   @override
-  InterfaceType supertype;
+  InterfaceType? supertype;
   @override
-  InterfaceType mixedInType;
+  InterfaceType? mixedInType;
   @override
-  List<InterfaceType> interfaces;
+  late List<InterfaceType> interfaces;
   @override
-  OrderedTypeSet orderedTypeSet;
+  OrderedTypeSet? orderedTypeSet;
 
-  List<Variance> _variances;
+  List<Variance>? _variances;
 
   JClassDataImpl(this.cls, this.definition);
 
@@ -498,10 +491,10 @@
   }
 
   @override
-  bool get isEnumClass => cls != null && cls.isEnum;
+  bool get isEnumClass => cls.isEnum;
 
   @override
-  FunctionType callType;
+  FunctionType? callType;
   bool isCallTypeComputed = false;
 
   @override
@@ -524,7 +517,7 @@
 abstract class JMemberData {
   MemberDefinition get definition;
 
-  InterfaceType getMemberThisType(JsToElementMap elementMap);
+  InterfaceType? getMemberThisType(JsToElementMap elementMap);
 
   ClassTypeVariableAccess get classTypeVariableAccess;
 
@@ -553,7 +546,6 @@
       case JMemberDataKind.closureField:
         return ClosureFieldData.readFromDataSource(source);
     }
-    throw UnsupportedError("Unexpected JMemberDataKind $kind");
   }
 
   /// Serializes this [JMemberData] to [sink].
@@ -576,9 +568,9 @@
   JMemberDataImpl._deserialized(this.node, this.definition, this._staticTypes);
 
   @override
-  InterfaceType getMemberThisType(JsToElementMap elementMap) {
+  InterfaceType? getMemberThisType(JsToElementMap elementMap) {
     MemberEntity member = elementMap.getMember(node);
-    ClassEntity cls = member.enclosingClass;
+    ClassEntity? cls = member.enclosingClass;
     if (cls != null) {
       return elementMap.elementEnvironment.getThisType(cls);
     }
@@ -594,13 +586,13 @@
   void forEachParameter(
       JsToElementMap elementMap,
       ParameterStructure parameterStructure,
-      void f(DartType type, String name, ConstantValue defaultValue),
+      void f(DartType type, String? name, ConstantValue? defaultValue),
       {bool isNative = false});
 }
 
 abstract class FunctionDataTypeVariablesMixin implements FunctionData {
   ir.FunctionNode get functionNode;
-  List<TypeVariableType> _typeVariables;
+  List<TypeVariableType>? _typeVariables;
 
   @override
   List<TypeVariableType> getFunctionTypeVariables(
@@ -609,7 +601,7 @@
       if (functionNode.typeParameters.isEmpty) {
         _typeVariables = const <TypeVariableType>[];
       } else {
-        ir.TreeNode parent = functionNode.parent;
+        ir.TreeNode parent = functionNode.parent!;
         if (parent is ir.Constructor ||
             (parent is ir.Procedure &&
                 parent.kind == ir.ProcedureKind.Factory)) {
@@ -620,12 +612,12 @@
             return elementMap
                 .getDartType(ir.TypeParameterType(
                     typeParameter, ir.Nullability.nonNullable))
-                .withoutNullability;
+                .withoutNullability as TypeVariableType;
           }).toList();
         }
       }
     }
-    return _typeVariables;
+    return _typeVariables!;
   }
 }
 
@@ -640,13 +632,13 @@
   void forEachParameter(
       JsToElementMap elementMap,
       ParameterStructure parameterStructure,
-      void f(DartType type, String name, ConstantValue defaultValue),
+      void f(DartType type, String? name, ConstantValue? defaultValue),
       {bool isNative = false}) {
     void handleParameter(ir.VariableDeclaration parameter,
         {bool isOptional = true}) {
       DartType type = elementMap.getDartType(parameter.type);
-      String name = parameter.name;
-      ConstantValue defaultValue;
+      String? name = parameter.name;
+      ConstantValue? defaultValue;
       if (parameter.isRequired) {
         if (elementMap.types.useLegacySubtyping) {
           defaultValue = NullConstantValue();
@@ -655,8 +647,8 @@
         }
       } else if (isOptional) {
         if (parameter.initializer != null) {
-          defaultValue =
-              elementMap.getConstantValue(memberContext, parameter.initializer);
+          defaultValue = elementMap.getConstantValue(
+              memberContext, parameter.initializer!);
         } else {
           defaultValue = NullConstantValue();
         }
@@ -665,7 +657,8 @@
     }
 
     forEachOrderedParameterByFunctionNode(functionNode, parameterStructure,
-        (ir.VariableDeclaration parameter, {bool isOptional, bool isElided}) {
+        (ir.VariableDeclaration parameter,
+            {required bool isOptional, required bool isElided}) {
       if (!isElided) {
         handleParameter(parameter, isOptional: isOptional);
       }
@@ -682,7 +675,7 @@
 
   @override
   final ir.FunctionNode functionNode;
-  FunctionType _type;
+  FunctionType? _type;
 
   FunctionDataImpl(ir.Member node, this.functionNode,
       MemberDefinition definition, StaticTypeCache staticTypes)
@@ -744,7 +737,7 @@
 
   @override
   final MemberDefinition definition;
-  final InterfaceType memberThisType;
+  final InterfaceType? memberThisType;
   @override
   final ClassTypeVariableAccess classTypeVariableAccess;
   List<ir.TypeParameter> get typeParameters => _typeParameters.loaded();
@@ -760,8 +753,8 @@
   factory SignatureFunctionData.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
     MemberDefinition definition = MemberDefinition.readFromDataSource(source);
-    InterfaceType /*?*/ memberThisType =
-        source.readDartTypeOrNull() as InterfaceType /*?*/;
+    InterfaceType? memberThisType =
+        source.readDartTypeOrNull() as InterfaceType?;
     Deferrable<List<ir.TypeParameter>> typeParameters =
         source.readDeferrable(() => source.readTypeParameterNodes());
     ClassTypeVariableAccess classTypeVariableAccess =
@@ -797,7 +790,7 @@
       return elementMap
           .getDartType(
               ir.TypeParameterType(typeParameter, ir.Nullability.nonNullable))
-          .withoutNullability;
+          .withoutNullability as TypeVariableType;
     }).toList();
   }
 
@@ -805,15 +798,13 @@
   void forEachParameter(
       JsToElementMap elementMap,
       ParameterStructure parameterStructure,
-      void f(DartType type, String name, ConstantValue defaultValue),
+      void f(DartType type, String? name, ConstantValue? defaultValue),
       {bool isNative = false}) {
     throw UnimplementedError('SignatureData.forEachParameter');
   }
 
   @override
-  InterfaceType getMemberThisType(JsToElementMap elementMap) {
-    return memberThisType;
-  }
+  InterfaceType? getMemberThisType(JsToElementMap elementMap) => memberThisType;
 }
 
 abstract class DelegatedFunctionData implements FunctionData {
@@ -835,14 +826,14 @@
   void forEachParameter(
       JsToElementMap elementMap,
       ParameterStructure parameterStructure,
-      void f(DartType type, String name, ConstantValue defaultValue),
+      void f(DartType type, String? name, ConstantValue? defaultValue),
       {bool isNative = false}) {
     return baseData.forEachParameter(elementMap, parameterStructure, f,
         isNative: isNative);
   }
 
   @override
-  InterfaceType getMemberThisType(JsToElementMap elementMap) {
+  InterfaceType? getMemberThisType(JsToElementMap elementMap) {
     return baseData.getMemberThisType(elementMap);
   }
 
@@ -859,14 +850,14 @@
   @override
   final MemberDefinition definition;
 
-  GeneratorBodyFunctionData(FunctionData baseData, this.definition)
-      : super(baseData);
+  GeneratorBodyFunctionData(super.baseData, this.definition);
 
   factory GeneratorBodyFunctionData.readFromDataSource(
       DataSourceReader source) {
     source.begin(tag);
     // TODO(johnniwinther): Share the original base data on deserialization.
-    FunctionData baseData = JMemberData.readFromDataSource(source);
+    FunctionData baseData =
+        JMemberData.readFromDataSource(source) as FunctionData;
     MemberDefinition definition = MemberDefinition.readFromDataSource(source);
     source.end(tag);
     return GeneratorBodyFunctionData(baseData, definition);
@@ -893,18 +884,14 @@
   /// debugging data stream.
   static const String tag = 'constructor-data';
 
-  JConstructorBody constructorBody;
+  JConstructorBody? constructorBody;
 
-  JConstructorDataImpl(ir.Member node, ir.FunctionNode functionNode,
-      MemberDefinition definition, StaticTypeCache staticTypes)
-      : super(node, functionNode, definition, staticTypes);
+  JConstructorDataImpl(
+      super.node, super.functionNode, super.definition, super.staticTypes);
 
   JConstructorDataImpl._deserialized(
-      ir.Member node,
-      ir.FunctionNode functionNode,
-      MemberDefinition definition,
-      Deferrable<StaticTypeCache> staticTypes)
-      : super._deserialized(node, functionNode, definition, staticTypes);
+      super.node, super.functionNode, super.definition, super.staticTypes)
+      : super._deserialized();
 
   factory JConstructorDataImpl.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
@@ -947,16 +934,12 @@
   /// a debugging data stream.
   static const String tag = 'constructor-body-data';
 
-  ConstructorBodyDataImpl(ir.Member node, ir.FunctionNode functionNode,
-      MemberDefinition definition, StaticTypeCache staticTypes)
-      : super(node, functionNode, definition, staticTypes);
+  ConstructorBodyDataImpl(
+      super.node, super.functionNode, super.definition, super.staticTypes);
 
   ConstructorBodyDataImpl._deserialized(
-      ir.Member node,
-      ir.FunctionNode functionNode,
-      MemberDefinition definition,
-      Deferrable<StaticTypeCache> staticTypes)
-      : super._deserialized(node, functionNode, definition, staticTypes);
+      super.node, super.functionNode, super.definition, super.staticTypes)
+      : super._deserialized();
 
   factory ConstructorBodyDataImpl.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
@@ -1004,15 +987,12 @@
   /// a debugging data stream.
   static const String tag = 'field-data';
 
-  DartType _type;
+  DartType? _type;
 
-  JFieldDataImpl(
-      ir.Field node, MemberDefinition definition, StaticTypeCache staticTypes)
-      : super(node, definition, staticTypes);
+  JFieldDataImpl(super.node, super.definition, super.staticTypes);
 
-  JFieldDataImpl._deserialized(ir.Field node, MemberDefinition definition,
-      Deferrable<StaticTypeCache> staticTypes)
-      : super._deserialized(node, definition, staticTypes);
+  JFieldDataImpl._deserialized(super.node, super.definition, super.staticTypes)
+      : super._deserialized();
 
   factory JFieldDataImpl.readFromDataSource(DataSourceReader source) {
     source.begin(tag);
@@ -1021,7 +1001,8 @@
     Deferrable<StaticTypeCache> staticTypes = source
         .readDeferrable(() => StaticTypeCache.readFromDataSource(source, node));
     source.end(tag);
-    return JFieldDataImpl._deserialized(node, definition, staticTypes);
+    return JFieldDataImpl._deserialized(
+        node as ir.Field, definition, staticTypes);
   }
 
   @override
@@ -1035,7 +1016,7 @@
   }
 
   @override
-  ir.Field get node => super.node;
+  ir.Field get node => super.node as ir.Field;
 
   @override
   DartType getFieldType(covariant JsKernelToElementMap elementMap) {
@@ -1055,8 +1036,8 @@
   static const String tag = 'type-variable-data';
 
   final ir.TypeParameter node;
-  DartType _bound;
-  DartType _defaultType;
+  DartType? _bound;
+  DartType? _defaultType;
 
   JTypeVariableData(this.node);
 
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index a509e8a..c5965a0 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -25,6 +25,9 @@
 import '../inferrer/abstract_value_domain.dart';
 import '../inferrer/type_graph_inferrer.dart';
 import '../inferrer/types.dart';
+import '../inferrer_experimental/types.dart' as experimentalInferrer;
+import '../inferrer_experimental/type_graph_inferrer.dart'
+    as experimentalInferrer;
 import '../js/js_source_mapping.dart';
 import '../js_backend/backend.dart';
 import '../js_backend/backend_impact.dart';
@@ -404,6 +407,15 @@
         _compiler, closedWorld, globalLocalsMap, inferredDataBuilder);
   }
 
+  /// Creates the [TypesInferrer] used by this strategy.
+  experimentalInferrer.TypesInferrer createExperimentalTypesInferrer(
+      JClosedWorld closedWorld,
+      GlobalLocalsMap globalLocalsMap,
+      InferredDataBuilder inferredDataBuilder) {
+    return experimentalInferrer.TypeGraphInferrer(
+        _compiler, closedWorld, globalLocalsMap, inferredDataBuilder);
+  }
+
   /// Prepare [source] to deserialize modular code generation data.
   void prepareCodegenReader(DataSourceReader source) {
     source.registerEntityReader(ClosedEntityReader(_elementMap));
@@ -625,7 +637,9 @@
 
   @override
   AbstractValue typeFromNativeBehavior(
-      NativeBehavior nativeBehavior, JClosedWorld closedWorld) {
+      // TODO(48820): remove covariant once interface and implementation match.
+      NativeBehavior nativeBehavior,
+      covariant JClosedWorld closedWorld) {
     return AbstractValueFactory.fromNativeBehavior(nativeBehavior, closedWorld);
   }
 }
diff --git a/pkg/compiler/lib/src/js_model/js_to_frontend_map.dart b/pkg/compiler/lib/src/js_model/js_to_frontend_map.dart
index aa5cdac..9c5f6ab 100644
--- a/pkg/compiler/lib/src/js_model/js_to_frontend_map.dart
+++ b/pkg/compiler/lib/src/js_model/js_to_frontend_map.dart
@@ -26,7 +26,7 @@
 
   DartType toBackendType(DartType type, {bool allowFreeVariables = false});
 
-  ConstantValue toBackendConstant(ConstantValue value,
+  ConstantValue? toBackendConstant(ConstantValue? value,
       {bool allowNull = false});
 
   Set<LibraryEntity> toBackendLibrarySet(Iterable<LibraryEntity> set) {
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index 7f0bb7b..6d3a960 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -65,6 +65,7 @@
   // TODO(johnniwinther): Can this be derived from [ClassSet]s?
   final Set<ClassEntity> implementedClasses;
 
+  @override
   final Set<MemberEntity> liveInstanceMembers;
 
   /// Members that are written either directly or through a setter selector.
@@ -82,6 +83,7 @@
   @override
   final ClassHierarchy classHierarchy;
 
+  @override
   final JsKernelToElementMap elementMap;
   @override
   final RuntimeTypesNeed rtiNeed;
@@ -475,6 +477,9 @@
   }
 
   @override
+  Selector getSelector(ir.Expression node) => elementMap.getSelector(node);
+
+  @override
   AbstractValue computeReceiverType(Selector selector, AbstractValue receiver) {
     _ensureFunctionSet();
     if (includesClosureCall(selector, receiver)) {
diff --git a/pkg/compiler/lib/src/js_model/js_world_builder.dart b/pkg/compiler/lib/src/js_model/js_world_builder.dart
index a222f01..aef9963 100644
--- a/pkg/compiler/lib/src/js_model/js_world_builder.dart
+++ b/pkg/compiler/lib/src/js_model/js_world_builder.dart
@@ -37,8 +37,9 @@
 import 'element_map_impl.dart';
 import 'js_to_frontend_map.dart';
 import 'js_world.dart';
+import 'js_world_builder_interfaces.dart' as interfaces;
 
-class JsClosedWorldBuilder {
+class JsClosedWorldBuilder implements interfaces.JsClosedWorldBuilder {
   final JsKernelToElementMap _elementMap;
   final Map<ClassEntity, ClassHierarchyNode> _classHierarchyNodes =
       ClassHierarchyNodesMap();
@@ -315,6 +316,7 @@
 
   /// Construct a closure class and set up the necessary class inference
   /// hierarchy.
+  @override
   JsClosureClassInfo buildClosureClass(
       MemberEntity member,
       ir.FunctionNode originalClosureFunctionNode,
@@ -557,7 +559,7 @@
   }
 
   @override
-  ConstantValue toBackendConstant(ConstantValue constant,
+  ConstantValue /*?*/ toBackendConstant(ConstantValue /*?*/ constant,
       {bool allowNull = false}) {
     if (constant == null) {
       if (!allowNull) {
diff --git a/pkg/compiler/lib/src/js_model/js_world_builder_interfaces.dart b/pkg/compiler/lib/src/js_model/js_world_builder_interfaces.dart
new file mode 100644
index 0000000..52b8965
--- /dev/null
+++ b/pkg/compiler/lib/src/js_model/js_world_builder_interfaces.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2022, 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' as ir;
+
+import '../elements/entities.dart';
+import '../ir/closure.dart';
+import 'closure.dart';
+import 'elements.dart';
+
+abstract class JsClosedWorldBuilder {
+  JsClosureClassInfo buildClosureClass(
+      MemberEntity member,
+      ir.FunctionNode originalClosureFunctionNode,
+      JLibrary enclosingLibrary,
+      Map<ir.VariableDeclaration, JRecordField> boxedVariables,
+      KernelScopeInfo info,
+      {required bool createSignatureMethod});
+}
diff --git a/pkg/compiler/lib/src/js_model/locals.dart b/pkg/compiler/lib/src/js_model/locals.dart
index bfa00b1..2d89963 100644
--- a/pkg/compiler/lib/src/js_model/locals.dart
+++ b/pkg/compiler/lib/src/js_model/locals.dart
@@ -640,7 +640,7 @@
     GlobalLocalsMap globalLocalsMap,
     JsToElementMap elementMap,
     FunctionEntity function,
-    void f(Local parameter, {bool? isElided})) {
+    void f(Local parameter, {required bool isElided})) {
   KernelToLocalsMap localsMap = globalLocalsMap.getLocalsMap(function);
   forEachOrderedParameter(elementMap, function,
       (ir.VariableDeclaration variable, {required bool isElided}) {
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 96a9081..e4bda64 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -13,12 +13,14 @@
 import 'package:_js_interop_checks/js_interop_checks.dart';
 import 'package:_js_interop_checks/src/transformations/js_util_optimizer.dart';
 import 'package:_js_interop_checks/src/transformations/static_interop_class_eraser.dart';
+import 'package:_js_interop_checks/src/transformations/static_interop_mock_creator.dart';
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/reference_from_index.dart';
 import 'package:kernel/target/changed_structure_notifier.dart';
 import 'package:kernel/target/targets.dart';
+import 'package:kernel/type_environment.dart';
 
 import '../options.dart';
 import 'invocation_mirror_constants.dart';
@@ -154,19 +156,28 @@
         coreTypes,
         diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>,
         _nativeClasses!);
+    var staticInteropMockCreator = StaticInteropMockCreator(
+        TypeEnvironment(coreTypes, hierarchy), diagnosticReporter);
     var jsUtilOptimizer = JsUtilOptimizer(coreTypes, hierarchy);
-    var staticInteropClassEraser =
-        StaticInteropClassEraser(coreTypes, referenceFromIndex);
+    // Cache extensions for entire component before creating mock.
+    for (var library in libraries) {
+      staticInteropMockCreator.processExtensions(library);
+    }
     for (var library in libraries) {
       jsInteropChecks.visitLibrary(library);
+      staticInteropMockCreator.visitLibrary(library);
       // TODO (rileyporter): Merge js_util optimizations with other lowerings
       // in the single pass in `transformations/lowering.dart`.
       jsUtilOptimizer.visitLibrary(library);
     }
+    var staticInteropClassEraser =
+        StaticInteropClassEraser(coreTypes, referenceFromIndex);
     lowering.transformLibraries(libraries, coreTypes, hierarchy, options);
     logger?.call("Lowering transformations performed");
     if (canPerformGlobalTransforms) {
       transformMixins.transformLibraries(libraries);
+      // Do the erasure after any possible mock creation to avoid erasing types
+      // that need to be used during mock conformance checking.
       for (var library in libraries) {
         staticInteropClassEraser.visitLibrary(library);
       }
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index eb27551..9cd4295 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -2,10 +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.
 
-// @dart = 2.10
-
 // TODO(joshualitt): Merge the contents of element_map_impl.dart into this file.
 export 'element_map_impl.dart';
+export 'element_map_migrated.dart';
 
 /// Kinds of foreign functions.
 export 'element_map_interfaces.dart' show ForeignKind;
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 907a610..47993ed 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import 'package:front_end/src/api_prototype/constant_evaluator.dart' as ir;
 import 'package:front_end/src/api_unstable/dart2js.dart' as ir;
 import 'package:js_shared/synced/embedded_names.dart' show JsGetName;
@@ -38,7 +36,7 @@
 import '../js_backend/backend_impact.dart';
 import '../js_backend/backend_usage.dart';
 import '../js_backend/custom_elements_analysis.dart';
-import '../js_backend/namer.dart';
+import '../js_backend/namer_interfaces.dart';
 import '../js_backend/native_data.dart';
 import '../js_backend/runtime_types_resolution.dart';
 import '../js_model/locals.dart';
@@ -55,15 +53,18 @@
 import '../universe/selector.dart';
 import '../universe/world_impact.dart';
 
-import 'element_map.dart';
 import 'element_map_interfaces.dart' as interfaces
     show
+        ForeignKind,
         KernelElementEnvironment,
         KernelToElementMapForClassHierarchy,
+        KernelToElementMapForEnv,
         KernelToElementMapForImpactData,
         KernelToElementMapForKernelImpact,
         KernelToElementMapForNativeData,
-        KernelToElementMapForDeferredLoading;
+        KernelToElementMapForDeferredLoading,
+        KernelToElementMapForJsModel;
+import 'element_map_migrated.dart';
 import 'env.dart';
 import 'kelements.dart';
 import 'kernel_impact.dart';
@@ -73,10 +74,12 @@
 class KernelToElementMap
     implements
         interfaces.KernelToElementMapForClassHierarchy,
+        interfaces.KernelToElementMapForEnv,
         interfaces.KernelToElementMapForImpactData,
         interfaces.KernelToElementMapForNativeData,
         interfaces.KernelToElementMapForDeferredLoading,
         interfaces.KernelToElementMapForKernelImpact,
+        interfaces.KernelToElementMapForJsModel,
         IrToElementMap {
   @override
   final CompilerOptions options;
@@ -85,31 +88,37 @@
   final Environment _environment;
   final NativeBasicDataBuilder nativeBasicDataBuilder =
       NativeBasicDataBuilder();
-  NativeBasicData /*?*/ _nativeBasicData;
-  /*late final*/ KCommonElements /*!*/ _commonElements;
-  /*late final*/ KernelElementEnvironment /*!*/ _elementEnvironment;
-  /*late final*/ DartTypeConverter _typeConverter;
-  /*late final*/ KernelDartTypes /*!*/ _types;
-  ir.CoreTypes /*?*/ _coreTypes;
-  ir.TypeEnvironment /*?*/ _typeEnvironment;
-  ir.ClassHierarchy /*?*/ _classHierarchy;
-  Dart2jsConstantEvaluator /*?*/ _constantEvaluator;
-  /*late final*/ ConstantValuefier _constantValuefier;
+  NativeBasicData? _nativeBasicData;
+  late final KCommonElements _commonElements;
+  late final KernelElementEnvironment _elementEnvironment;
+  late final DartTypeConverter _typeConverter;
+  late final KernelDartTypes _types;
+  ir.CoreTypes? _coreTypes;
+  ir.TypeEnvironment? _typeEnvironment;
+  ir.ClassHierarchy? _classHierarchy;
+  Dart2jsConstantEvaluator? _constantEvaluator;
+  late final ConstantValuefier _constantValuefier;
 
   /// Library environment. Used for fast lookup.
+  @override
   KProgramEnv env = KProgramEnv();
 
+  @override
   final EntityDataEnvMap<IndexedLibrary, KLibraryData, KLibraryEnv> libraries =
       EntityDataEnvMap<IndexedLibrary, KLibraryData, KLibraryEnv>();
+  @override
   final EntityDataEnvMap<IndexedClass, KClassData, KClassEnv> classes =
       EntityDataEnvMap<IndexedClass, KClassData, KClassEnv>();
+  @override
   final EntityDataMap<IndexedMember, KMemberData> members =
       EntityDataMap<IndexedMember, KMemberData>();
+  @override
   final EntityDataMap<IndexedTypeVariable, KTypeVariableData> typeVariables =
       EntityDataMap<IndexedTypeVariable, KTypeVariableData>();
 
   /// Set to `true` before creating the J-World from the K-World to assert that
   /// no entities are created late.
+  @override
   bool envIsClosed = false;
 
   final Map<ir.Library, IndexedLibrary> libraryMap = {};
@@ -128,10 +137,10 @@
   final Map<ir.Field, IndexedField> fieldMap = {};
   final Map<ir.TreeNode, Local> localFunctionMap = {};
 
-  BehaviorBuilder _nativeBehaviorBuilder;
+  BehaviorBuilder? _nativeBehaviorBuilder;
 
-  Map<KMember, Map<ir.Expression, TypeMap>> typeMapsForTesting;
-  Map<ir.Member, ImpactData> impactDataForTesting;
+  Map<KMember, Map<ir.Expression, TypeMap>>? typeMapsForTesting;
+  Map<ir.Member, ImpactData>? impactDataForTesting;
 
   KernelToElementMap(this.reporter, this._environment, this.options) {
     _elementEnvironment = KernelElementEnvironment(this);
@@ -152,17 +161,19 @@
   @override
   KCommonElements get commonElements => _commonElements;
 
-  FunctionEntity get _mainFunction {
-    return env.mainMethod != null ? getMethodInternal(env.mainMethod) : null;
-  }
-
-  LibraryEntity get _mainLibrary {
+  FunctionEntity? get _mainFunction {
     return env.mainMethod != null
-        ? getLibraryInternal(env.mainMethod.enclosingLibrary)
+        ? getMethodInternal(env.mainMethod as ir.Procedure)
         : null;
   }
 
-  SourceSpan getSourceSpan(Spannable spannable, Entity currentElement) {
+  LibraryEntity? get _mainLibrary {
+    return env.mainMethod != null
+        ? getLibraryInternal(env.mainMethod!.enclosingLibrary)
+        : null;
+  }
+
+  SourceSpan getSourceSpan(Spannable spannable, Entity? currentElement) {
     SourceSpan fromSpannable(Spannable spannable) {
       if (spannable is IndexedLibrary &&
           spannable.libraryIndex < libraries.length) {
@@ -171,12 +182,10 @@
       } else if (spannable is IndexedClass &&
           spannable.classIndex < classes.length) {
         KClassData data = classes.getData(spannable);
-        assert(data != null, "No data for $spannable in $this");
         return computeSourceSpanFromTreeNode(data.node);
       } else if (spannable is IndexedMember &&
           spannable.memberIndex < members.length) {
         KMemberData data = members.getData(spannable);
-        assert(data != null, "No data for $spannable in $this");
         return computeSourceSpanFromTreeNode(data.node);
       } else if (spannable is KLocalFunction) {
         return getSourceSpan(spannable.memberContext, currentElement);
@@ -188,11 +197,11 @@
 
     SourceSpan sourceSpan = fromSpannable(spannable);
     if (sourceSpan.isKnown) return sourceSpan;
-    return fromSpannable(currentElement);
+    return fromSpannable(currentElement!);
   }
 
-  LibraryEntity lookupLibrary(Uri uri) {
-    KLibraryEnv libraryEnv = env.lookupLibrary(uri);
+  LibraryEntity? lookupLibrary(Uri uri) {
+    KLibraryEnv? libraryEnv = env.lookupLibrary(uri);
     if (libraryEnv == null) return null;
     return getLibraryInternal(libraryEnv.library, libraryEnv);
   }
@@ -203,11 +212,11 @@
     return libraryEnv.library.name ?? '';
   }
 
-  MemberEntity lookupLibraryMember(IndexedLibrary library, String name,
+  MemberEntity? lookupLibraryMember(IndexedLibrary library, String name,
       {bool setter = false}) {
     assert(checkFamily(library));
     KLibraryEnv libraryEnv = libraries.getEnv(library);
-    ir.Member member = libraryEnv.lookupMember(name, setter: setter);
+    ir.Member? member = libraryEnv.lookupMember(name, setter: setter);
     return member != null ? getMember(member) : null;
   }
 
@@ -220,10 +229,10 @@
     });
   }
 
-  ClassEntity lookupClass(IndexedLibrary library, String name) {
+  ClassEntity? lookupClass(IndexedLibrary library, String name) {
     assert(checkFamily(library));
     KLibraryEnv libraryEnv = libraries.getEnv(library);
-    KClassEnv classEnv = libraryEnv.lookupClass(name);
+    KClassEnv? classEnv = libraryEnv.lookupClass(name);
     if (classEnv != null) {
       return getClassInternal(classEnv.cls, classEnv);
     }
@@ -252,20 +261,20 @@
   /// environment, not ensuring the computation of the class members, can result
   /// in a live member being present in the J-model but unavailable when queried
   /// as a member of its enclosing class.
-  ClassEntity getClassForMemberInternal(ir.Class node) {
-    ClassEntity cls = getClassInternal(node);
+  IndexedClass getClassForMemberInternal(ir.Class node) {
+    final cls = getClassInternal(node);
     classes.getEnv(cls).ensureMembers(this);
     return cls;
   }
 
-  MemberEntity lookupClassMember(IndexedClass cls, Name name,
+  MemberEntity? lookupClassMember(IndexedClass cls, Name name,
       {bool setter = false}) {
     assert(checkFamily(cls));
     KClassEnv classEnv = classes.getEnv(cls);
     return classEnv.lookupMember(this, name);
   }
 
-  ConstructorEntity lookupConstructor(IndexedClass cls, String name) {
+  ConstructorEntity? lookupConstructor(IndexedClass cls, String name) {
     assert(checkFamily(cls));
     KClassEnv classEnv = classes.getEnv(cls);
     return classEnv.lookupConstructor(this, name);
@@ -279,6 +288,7 @@
     return types.interfaceType(getClass(cls), getDartTypes(typeArguments));
   }
 
+  @override
   LibraryEntity getLibrary(ir.Library node) => getLibraryInternal(node);
 
   /// Returns the [ClassEntity] corresponding to the class [node].
@@ -286,7 +296,7 @@
   ClassEntity getClass(ir.Class node) => getClassInternal(node);
 
   @override
-  InterfaceType getSuperType(IndexedClass cls) {
+  InterfaceType? getSuperType(IndexedClass cls) {
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
@@ -295,14 +305,14 @@
 
   /// Returns the superclass of [cls] if any.
   @override
-  ClassEntity getSuperClass(ClassEntity cls) {
-    return getSuperType(cls)?.element;
+  ClassEntity? getSuperClass(ClassEntity cls) {
+    return getSuperType(cls as IndexedClass)?.element;
   }
 
   void _ensureCallType(ClassEntity cls, KClassData data) {
     assert(checkFamily(cls));
     if (data is KClassDataImpl && !data.isCallTypeComputed) {
-      MemberEntity callMember =
+      MemberEntity? callMember =
           _elementEnvironment.lookupClassMember(cls, Names.call);
       if (callMember is FunctionEntity &&
           callMember.isFunction &&
@@ -360,7 +370,7 @@
         data.instantiationToBounds = getInterfaceType(ir.instantiateToBounds(
             coreTypes.legacyRawType(node),
             coreTypes.objectClass,
-            node.enclosingLibrary));
+            node.enclosingLibrary) as ir.InterfaceType);
       }
     }
   }
@@ -377,7 +387,7 @@
       ir.Class node = data.node;
 
       if (node.supertype == null) {
-        data.orderedTypeSet = OrderedTypeSet.singleton(data.thisType);
+        data.orderedTypeSet = OrderedTypeSet.singleton(data.thisType!);
         data.isMixinApplication = false;
         data.interfaces = const <InterfaceType>[];
       } else {
@@ -390,16 +400,18 @@
 
         InterfaceType processSupertype(ir.Supertype supertypeNode) {
           supertypeNode = classHierarchy.getClassAsInstanceOf(
-              node, supertypeNode.classNode);
+              node, supertypeNode.classNode)!;
           InterfaceType supertype =
               _typeConverter.visitSupertype(supertypeNode);
           canonicalSupertypes.add(supertype);
-          IndexedClass superclass = supertype.element;
+          IndexedClass superclass = supertype.element as IndexedClass;
           KClassData superdata = classes.getData(superclass);
           _ensureSupertypes(superclass, superdata);
-          for (InterfaceType supertype in superdata.orderedTypeSet.supertypes) {
-            ir.Supertype canonicalSupertype = classHierarchy
-                .getClassAsInstanceOf(node, getClassNode(supertype.element));
+          for (InterfaceType supertype
+              in superdata.orderedTypeSet!.supertypes!) {
+            ir.Supertype? canonicalSupertype =
+                classHierarchy.getClassAsInstanceOf(
+                    node, getClassNode(supertype.element as IndexedClass));
             if (canonicalSupertype != null) {
               supertype = _typeConverter.visitSupertype(canonicalSupertype);
             } else {
@@ -435,21 +447,22 @@
           // Set superclass to `Object`.
           supertype = _commonElements.objectType;
         } else {
-          supertype = processSupertype(node.supertype);
+          supertype = processSupertype(node.supertype!);
         }
         if (supertype == _commonElements.objectType) {
           ClassEntity defaultSuperclass =
               _commonElements.getDefaultSuperclass(cls, nativeBasicData);
           data.supertype = _elementEnvironment.getRawType(defaultSuperclass);
-          assert(data.supertype.typeArguments.isEmpty,
+          assert(data.supertype!.typeArguments.isEmpty,
               "Generic default supertypes are not supported");
-          canonicalSupertypes.add(data.supertype);
+          canonicalSupertypes.add(data.supertype!);
         } else {
           data.supertype = supertype;
         }
         if (node.mixedInType != null) {
           data.isMixinApplication = true;
-          interfaces.add(data.mixedInType = processSupertype(node.mixedInType));
+          interfaces
+              .add(data.mixedInType = processSupertype(node.mixedInType!));
         } else {
           data.isMixinApplication = false;
         }
@@ -511,15 +524,16 @@
     ClassEntity sourceClass = source.enclosingClass;
     ConstructorEntity target = getConstructor(targetNode);
     ClassEntity targetClass = target.enclosingClass;
-    IndexedClass superClass = getSuperType(sourceClass)?.element;
+    IndexedClass? superClass =
+        getSuperType(sourceClass as IndexedClass)?.element as IndexedClass?;
     if (superClass == targetClass) {
       return target;
     }
 
     /// This path is needed for synthetically injected superclasses like
     /// `Interceptor` and `LegacyJavaScriptObject`.
-    KClassEnv env = classes.getEnv(superClass);
-    ConstructorEntity constructor = env.lookupConstructor(this, target.name);
+    KClassEnv env = classes.getEnv(superClass!);
+    ConstructorEntity? constructor = env.lookupConstructor(this, target.name);
     if (constructor != null) {
       return constructor;
     }
@@ -540,7 +554,7 @@
 
   /// Returns the [TypeVariableType] corresponding to [type].
   TypeVariableType getTypeVariableType(ir.TypeParameterType type) =>
-      getDartType(type).withoutNullability;
+      getDartType(type).withoutNullability as TypeVariableType;
 
   List<DartType> getDartTypes(List<ir.DartType> types) {
     List<DartType> list = <DartType>[];
@@ -553,7 +567,7 @@
   /// Returns the [InterfaceType] corresponding to [type].
   @override
   InterfaceType getInterfaceType(ir.InterfaceType type) =>
-      _typeConverter.visitType(type).withoutNullability;
+      _typeConverter.visitType(type).withoutNullability as InterfaceType;
 
   /// Returns the [FunctionType] of the [node].
   @override
@@ -589,13 +603,14 @@
     List<String> namedParameters = <String>[];
     Set<String> requiredNamedParameters = <String>{};
     List<DartType> namedParameterTypes = <DartType>[];
-    List<ir.VariableDeclaration> sortedNamedParameters =
-        node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
+    List<ir.VariableDeclaration> sortedNamedParameters = node.namedParameters
+        .toList()
+      ..sort((a, b) => a.name!.compareTo(b.name!));
     for (ir.VariableDeclaration variable in sortedNamedParameters) {
-      namedParameters.add(variable.name);
+      namedParameters.add(variable.name!);
       namedParameterTypes.add(getParameterType(variable));
       if (variable.isRequired) {
-        requiredNamedParameters.add(variable.name);
+        requiredNamedParameters.add(variable.name!);
       }
     }
     List<FunctionTypeVariable> typeVariables;
@@ -638,7 +653,7 @@
   @override
   DartType substByContext(DartType type, InterfaceType context) {
     return types.subst(context.typeArguments,
-        getThisType(context.element).typeArguments, type);
+        getThisType(context.element as IndexedClass).typeArguments, type);
   }
 
   /// Returns the type of the `call` method on 'type'.
@@ -646,13 +661,13 @@
   /// If [type] doesn't have a `call` member or has a non-method `call` member,
   /// `null` is returned.
   @override
-  FunctionType getCallType(InterfaceType type) {
-    IndexedClass cls = type.element;
+  FunctionType? getCallType(InterfaceType type) {
+    IndexedClass cls = type.element as IndexedClass;
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureCallType(cls, data);
     if (data.callType != null) {
-      return substByContext(data.callType, type);
+      return substByContext(data.callType!, type) as FunctionType?;
     }
     return null;
   }
@@ -662,10 +677,10 @@
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureThisAndRawType(cls, data);
-    return data.thisType;
+    return data.thisType!;
   }
 
-  InterfaceType _getJsInteropType(IndexedClass cls) {
+  InterfaceType? _getJsInteropType(IndexedClass cls) {
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureJsInteropType(cls, data);
@@ -676,32 +691,31 @@
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureThisAndRawType(cls, data);
-    return data.rawType;
+    return data.rawType!;
   }
 
   InterfaceType _getClassInstantiationToBounds(IndexedClass cls) {
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureClassInstantiationToBounds(cls, data);
-    return data.instantiationToBounds;
+    return data.instantiationToBounds!;
   }
 
   DartType _getFieldType(IndexedField field) {
     assert(checkFamily(field));
-    KFieldData data = members.getData(field);
+    KFieldData data = members.getData(field) as KFieldData;
     return data.getFieldType(this);
   }
 
   FunctionType _getFunctionType(IndexedFunction function) {
     assert(checkFamily(function));
-    KFunctionData data = members.getData(function);
+    KFunctionData data = members.getData(function) as KFunctionData;
     return data.getFunctionType(this);
   }
 
-  List<TypeVariableType> /*!*/ _getFunctionTypeVariables(
-      IndexedFunction function) {
+  List<TypeVariableType> _getFunctionTypeVariables(IndexedFunction function) {
     assert(checkFamily(function));
-    KFunctionData data = members.getData(function);
+    KFunctionData data = members.getData(function) as KFunctionData;
     return data.getFunctionTypeVariables(this);
   }
 
@@ -726,7 +740,7 @@
   //     class B = Object with A;
   //     class C = Object with B;
   @override
-  ClassEntity getAppliedMixin(IndexedClass cls) {
+  ClassEntity? getAppliedMixin(IndexedClass cls) {
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
@@ -750,18 +764,18 @@
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
-    data.orderedTypeSet.supertypes.forEach(f);
+    data.orderedTypeSet!.supertypes!.forEach(f);
   }
 
-  void _forEachMixin(IndexedClass cls, void f(ClassEntity mixin)) {
-    assert(checkFamily(cls));
+  void _forEachMixin(IndexedClass? cls, void f(ClassEntity mixin)) {
+    assert(checkFamily(cls!));
     while (cls != null) {
       KClassData data = classes.getData(cls);
       _ensureSupertypes(cls, data);
       if (data.mixedInType != null) {
-        f(data.mixedInType.element);
+        f(data.mixedInType!.element);
       }
-      cls = data.supertype?.element;
+      cls = data.supertype?.element as IndexedClass?;
     }
   }
 
@@ -796,34 +810,35 @@
     KClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     if (data.supertype != null) {
-      _forEachClassMember(data.supertype.element, f);
+      _forEachClassMember(data.supertype!.element as IndexedClass, f);
     }
   }
 
   @override
-  InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls) {
+  InterfaceType? asInstanceOf(InterfaceType type, ClassEntity cls) {
     assert(checkFamily(cls));
-    OrderedTypeSet orderedTypeSet = getOrderedTypeSet(type.element);
-    InterfaceType /*?*/ supertype =
-        orderedTypeSet.asInstanceOf(cls, getHierarchyDepth(cls));
+    OrderedTypeSet orderedTypeSet =
+        getOrderedTypeSet(type.element as IndexedClass);
+    InterfaceType? supertype = orderedTypeSet.asInstanceOf(
+        cls, getHierarchyDepth(cls as IndexedClass));
     if (supertype != null) {
-      supertype = substByContext(supertype, type);
+      supertype = substByContext(supertype, type) as InterfaceType?;
     }
     return supertype;
   }
 
   @override
-  OrderedTypeSet /*!*/ getOrderedTypeSet(IndexedClass cls) {
+  OrderedTypeSet getOrderedTypeSet(IndexedClass cls) {
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
-    return data.orderedTypeSet;
+    return data.orderedTypeSet!;
   }
 
   /// Returns all supertypes of [cls].
   @override
   Iterable<InterfaceType> getSuperTypes(ClassEntity cls) {
-    return getOrderedTypeSet(cls).supertypes;
+    return getOrderedTypeSet(cls as IndexedClass).supertypes!;
   }
 
   /// Returns the hierarchy depth of [cls].
@@ -832,38 +847,38 @@
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
-    return data.orderedTypeSet.maxDepth;
+    return data.orderedTypeSet!.maxDepth;
   }
 
   @override
-  Iterable<InterfaceType> /*!*/ getInterfaces(IndexedClass cls) {
+  Iterable<InterfaceType> getInterfaces(IndexedClass cls) {
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     assert(data.interfaces != null);
-    return data.interfaces;
+    return data.interfaces!;
   }
 
   /// Returns the defining node for [member].
   @override
-  ir.Member getMemberNode(covariant IndexedMember member) {
+  ir.Member getMemberNode(MemberEntity member) {
     assert(checkFamily(member));
-    return members.getData(member).node;
+    return members.getData(member as IndexedMember).node;
   }
 
   /// Returns the defining node for [cls].
-  ir.Class getClassNode(covariant IndexedClass cls) {
+  ir.Class getClassNode(ClassEntity cls) {
     assert(checkFamily(cls));
-    return classes.getData(cls).node;
+    return classes.getData(cls as IndexedClass).node;
   }
 
   /// Return the [ImportEntity] corresponding to [node].
   @override
-  ImportEntity getImport(ir.LibraryDependency node) {
+  ImportEntity? getImport(ir.LibraryDependency? node) {
     if (node == null) return null;
-    ir.Library library = node.parent;
+    ir.Library library = node.enclosingLibrary;
     KLibraryData data = libraries.getData(getLibraryInternal(library));
-    return data.imports[node];
+    return data.imports![node];
   }
 
   /// Returns the core types for the underlying kernel model.
@@ -882,14 +897,15 @@
   @override
   ir.StaticTypeContext getStaticTypeContext(MemberEntity member) {
     // TODO(johnniwinther): Cache the static type context.
-    return ir.StaticTypeContext(getMemberNode(member), typeEnvironment);
+    return ir.StaticTypeContext(
+        getMemberNode(member as IndexedMember), typeEnvironment);
   }
 
   @override
   Dart2jsConstantEvaluator get constantEvaluator {
     return _constantEvaluator ??=
         Dart2jsConstantEvaluator(env.mainComponent, typeEnvironment,
-            (ir.LocatedMessage message, List<ir.LocatedMessage> context) {
+            (ir.LocatedMessage message, List<ir.LocatedMessage>? context) {
       reportLocatedMessage(reporter, message, context);
     },
             environment: _environment,
@@ -900,7 +916,7 @@
 
   @override
   Name getName(ir.Name name, {bool setter = false}) {
-    return Name(name.text, name.isPrivate ? name.library.importUri : null,
+    return Name(name.text, name.isPrivate ? name.library!.importUri : null,
         isSetter: setter);
   }
 
@@ -922,12 +938,13 @@
     int typeParameters = node.typeParameters.length;
     List<String> namedParameters = <String>[];
     Set<String> requiredNamedParameters = <String>{};
-    List<ir.VariableDeclaration> sortedNamedParameters =
-        node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
+    List<ir.VariableDeclaration> sortedNamedParameters = node.namedParameters
+        .toList()
+      ..sort((a, b) => a.name!.compareTo(b.name!));
     for (var variable in sortedNamedParameters) {
-      namedParameters.add(variable.name);
+      namedParameters.add(variable.name!);
       if (variable.isRequired && !options.useLegacySubtyping) {
-        requiredNamedParameters.add(variable.name);
+        requiredNamedParameters.add(variable.name!);
       }
     }
     return ParameterStructure(
@@ -964,35 +981,34 @@
 
   Selector getGetterSelector(ir.Name irName) {
     Name name =
-        Name(irName.text, irName.isPrivate ? irName.library.importUri : null);
+        Name(irName.text, irName.isPrivate ? irName.library!.importUri : null);
     return Selector.getter(name);
   }
 
   Selector getSetterSelector(ir.Name irName) {
     Name name =
-        Name(irName.text, irName.isPrivate ? irName.library.importUri : null);
+        Name(irName.text, irName.isPrivate ? irName.library!.importUri : null);
     return Selector.setter(name);
   }
 
   /// Looks up [typeName] for use in the spec-string of a `JS` call.
   // TODO(johnniwinther): Use this in [NativeBehavior] instead of calling
   // the `ForeignResolver`.
-  TypeLookup typeLookup({bool resolveAsRaw = true}) {
-    return resolveAsRaw
-        ? (_cachedTypeLookupRaw ??= _typeLookup(resolveAsRaw: true))
-        : (_cachedTypeLookupFull ??= _typeLookup(resolveAsRaw: false));
+  TypeLookup typeLookup({required bool resolveAsRaw}) {
+    return resolveAsRaw ? _cachedTypeLookupRaw : _cachedTypeLookupFull;
   }
 
-  TypeLookup _cachedTypeLookupRaw;
-  TypeLookup _cachedTypeLookupFull;
+  late final TypeLookup _cachedTypeLookupRaw = _typeLookup(resolveAsRaw: true);
+  late final TypeLookup _cachedTypeLookupFull =
+      _typeLookup(resolveAsRaw: false);
 
-  TypeLookup _typeLookup({bool resolveAsRaw = true}) {
-    bool cachedMayLookupInMain;
+  TypeLookup _typeLookup({required bool resolveAsRaw}) {
+    bool? cachedMayLookupInMain;
 
-    DartType lookup(String typeName, {bool required}) {
-      DartType findInLibrary(LibraryEntity library) {
+    DartType lookup(String typeName, {bool? required}) {
+      DartType? findInLibrary(LibraryEntity? library) {
         if (library != null) {
-          ClassEntity cls = elementEnvironment.lookupClass(library, typeName);
+          ClassEntity? cls = elementEnvironment.lookupClass(library, typeName);
           if (cls != null) {
             // TODO(johnniwinther): Align semantics.
             return resolveAsRaw
@@ -1003,7 +1019,7 @@
         return null;
       }
 
-      DartType findIn(Uri uri) {
+      DartType? findIn(Uri uri) {
         return findInLibrary(elementEnvironment.lookupLibrary(uri));
       }
 
@@ -1012,9 +1028,9 @@
       // TODO(johnniwinther): Cache more results to avoid redundant lookups?
       cachedMayLookupInMain ??=
           // Tests permit lookup outside of dart: libraries.
-          allowedNativeTest(elementEnvironment.mainLibrary.canonicalUri);
-      DartType type;
-      if (cachedMayLookupInMain) {
+          allowedNativeTest(elementEnvironment.mainLibrary!.canonicalUri);
+      DartType? type;
+      if (cachedMayLookupInMain!) {
         type ??= findInLibrary(elementEnvironment.mainLibrary);
       }
       type ??= findIn(Uris.dart_core);
@@ -1033,17 +1049,17 @@
       type ??= findIn(Uris.dart_typed_data);
       type ??= findIn(Uris.dart__rti);
       type ??= findIn(Uris.dart_mirrors);
-      if (type == null && required) {
+      if (type == null && required!) {
         reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE,
             MessageKind.GENERIC, {'text': "Type '$typeName' not found."});
       }
-      return type;
+      return type!;
     }
 
     return lookup;
   }
 
-  String /*?*/ _getStringArgument(ir.StaticInvocation node, int index) {
+  String? _getStringArgument(ir.StaticInvocation node, int index) {
     return node.arguments.positional[index].accept(Stringifier());
   }
 
@@ -1057,14 +1073,14 @@
           CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS);
       return NativeBehavior();
     }
-    String specString = _getStringArgument(node, 0);
+    String? specString = _getStringArgument(node, 0);
     if (specString == null) {
       reporter.reportErrorMessage(
           CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_FIRST);
       return NativeBehavior();
     }
 
-    String codeString = _getStringArgument(node, 1);
+    String? codeString = _getStringArgument(node, 1);
     if (codeString == null) {
       reporter.reportErrorMessage(
           CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND);
@@ -1095,7 +1111,7 @@
           CURRENT_ELEMENT_SPANNABLE, "JS builtin is missing name.");
       return NativeBehavior();
     }
-    String specString = _getStringArgument(node, 0);
+    String? specString = _getStringArgument(node, 0);
     if (specString == null) {
       reporter.internalError(
           CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument.");
@@ -1131,7 +1147,7 @@
           "JS embedded global has more than 2 arguments.");
       return NativeBehavior();
     }
-    String specString = _getStringArgument(node, 0);
+    String? specString = _getStringArgument(node, 0);
     if (specString == null) {
       reporter.internalError(
           CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument.");
@@ -1146,15 +1162,15 @@
   }
 
   /// Returns the [js.Name] for the `JsGetName` [constant] value.
-  js.Name getNameForJsGetName(ConstantValue constant, Namer namer) {
-    int index = extractEnumIndexFromConstantValue(
+  js.Name? getNameForJsGetName(ConstantValue constant, ModularNamer namer) {
+    int? index = extractEnumIndexFromConstantValue(
         constant, commonElements.jsGetNameEnum);
     if (index == null) return null;
     return namer.getNameForJsGetName(
         CURRENT_ELEMENT_SPANNABLE, JsGetName.values[index]);
   }
 
-  int extractEnumIndexFromConstantValue(
+  int? extractEnumIndexFromConstantValue(
       ConstantValue constant, ClassEntity classElement) {
     if (constant is ConstructedConstantValue) {
       if (constant.type.element == classElement) {
@@ -1170,8 +1186,8 @@
 
   /// Computes the [ConstantValue] for the constant [expression].
   @override
-  ConstantValue getConstantValue(
-      ir.StaticTypeContext staticTypeContext, ir.Expression node,
+  ConstantValue? getConstantValue(
+      ir.StaticTypeContext staticTypeContext, ir.Expression? node,
       {bool requireConstant = true,
       bool implicitNull = false,
       bool checkCasts = true}) {
@@ -1182,7 +1198,7 @@
       }
       return NullConstantValue();
     }
-    ir.Constant constant = constantEvaluator.evaluateOrNull(
+    ir.Constant? constant = constantEvaluator.evaluateOrNull(
         staticTypeContext, node,
         requireConstant: requireConstant);
     if (constant == null) {
@@ -1202,15 +1218,16 @@
   }
 
   /// Converts [annotations] into a list of [ConstantValue]s.
+  @override
   List<ConstantValue> getMetadata(
       ir.StaticTypeContext staticTypeContext, List<ir.Expression> annotations) {
     if (annotations.isEmpty) return const <ConstantValue>[];
-    List<ConstantValue /*!*/ > metadata = <ConstantValue>[];
+    List<ConstantValue> metadata = <ConstantValue>[];
     annotations.forEach((ir.Expression node) {
       // We skip the implicit cast checks for metadata to avoid circular
       // dependencies in the js-interop class registration.
       metadata
-          .add(getConstantValue(staticTypeContext, node, checkCasts: false));
+          .add(getConstantValue(staticTypeContext, node, checkCasts: false)!);
     });
     return metadata;
   }
@@ -1219,27 +1236,25 @@
   /// `super.noSuchMethod` invocation within [cls].
   @override
   FunctionEntity getSuperNoSuchMethod(ClassEntity cls) {
-    while (cls != null) {
-      cls = elementEnvironment.getSuperClass(cls);
-      MemberEntity member =
-          elementEnvironment.lookupLocalClassMember(cls, Names.noSuchMethod_);
+    while (true) {
+      ClassEntity? superclass = elementEnvironment.getSuperClass(cls);
+      if (superclass == null) break;
+      MemberEntity? member = elementEnvironment.lookupLocalClassMember(
+          superclass, Names.noSuchMethod_);
       if (member != null && !member.isAbstract) {
-        if (member.isFunction) {
-          FunctionEntity function = member;
-          if (function.parameterStructure.positionalParameters >= 1) {
-            return function;
+        if (member is KMethod) {
+          if (member.parameterStructure.positionalParameters >= 1) {
+            return member;
           }
         }
         // If [member] is not a valid `noSuchMethod` the target is
         // `Object.superNoSuchMethod`.
         break;
       }
+      cls = superclass;
     }
-    FunctionEntity function = elementEnvironment.lookupLocalClassMember(
-        commonElements.objectClass, Names.noSuchMethod_);
-    assert(function != null,
-        failedAt(cls, "No super noSuchMethod found for class $cls."));
-    return function;
+    return elementEnvironment.lookupLocalClassMember(
+        commonElements.objectClass, Names.noSuchMethod_)! as FunctionEntity;
   }
 
   Iterable<LibraryEntity> get libraryListInternal {
@@ -1252,17 +1267,18 @@
     return libraryMap.values;
   }
 
-  LibraryEntity getLibraryInternal(ir.Library node, [KLibraryEnv libraryEnv]) {
+  IndexedLibrary getLibraryInternal(ir.Library node,
+      [KLibraryEnv? libraryEnv]) {
     return libraryMap[node] ??= _getLibraryCreate(node, libraryEnv);
   }
 
-  LibraryEntity _getLibraryCreate(ir.Library node, KLibraryEnv libraryEnv) {
+  IndexedLibrary _getLibraryCreate(ir.Library node, KLibraryEnv? libraryEnv) {
     assert(
         !envIsClosed,
         "Environment of $this is closed. Trying to create "
         "library for $node.");
     Uri canonicalUri = node.importUri;
-    String name = node.name;
+    String? name = node.name;
     if (name == null) {
       // Use the file name as script name.
       String path = canonicalUri.path;
@@ -1270,22 +1286,24 @@
     }
     IndexedLibrary library =
         createLibrary(name, canonicalUri, node.isNonNullableByDefault);
-    return libraries.register(library, KLibraryData(node),
-        libraryEnv ?? env.lookupLibrary(canonicalUri));
+    return libraries.register<IndexedLibrary, KLibraryData, KLibraryEnv>(
+        library,
+        KLibraryData(node),
+        libraryEnv ?? env.lookupLibrary(canonicalUri)!);
   }
 
-  ClassEntity getClassInternal(ir.Class node, [KClassEnv classEnv]) {
+  IndexedClass getClassInternal(ir.Class node, [KClassEnv? classEnv]) {
     return classMap[node] ??= _getClassCreate(node, classEnv);
   }
 
-  ClassEntity _getClassCreate(ir.Class node, KClassEnv classEnv) {
+  IndexedClass _getClassCreate(ir.Class node, KClassEnv? classEnv) {
     assert(
         !envIsClosed,
         "Environment of $this is closed. Trying to create "
         "class for $node.");
-    KLibrary library = getLibraryInternal(node.enclosingLibrary);
+    KLibrary library = getLibraryInternal(node.enclosingLibrary) as KLibrary;
     if (classEnv == null) {
-      classEnv = libraries.getEnv(library).lookupClass(node.name);
+      classEnv = libraries.getEnv(library).lookupClass(node.name)!;
     }
     IndexedClass cls =
         createClass(library, node.name, isAbstract: node.isAbstract);
@@ -1293,42 +1311,44 @@
   }
 
   TypeVariableEntity getTypeVariableInternal(ir.TypeParameter node) {
-    return typeVariableMap[node] ??= _getTypeVariableCreate(node);
+    return typeVariableMap[node] ??= _getTypeVariableCreate(node)!;
   }
 
-  TypeVariableEntity _getTypeVariableCreate(ir.TypeParameter node) {
+  TypeVariableEntity? _getTypeVariableCreate(ir.TypeParameter node) {
     assert(
         !envIsClosed,
         "Environment of $this is closed. Trying to create "
         "type variable for $node.");
-    if (node.parent is ir.Class) {
-      ir.Class cls = node.parent;
+    final parent = node.parent;
+    if (parent is ir.Class) {
+      ir.Class cls = parent;
       int index = cls.typeParameters.indexOf(node);
       return typeVariables.register(
-          createTypeVariable(getClassInternal(cls), node.name, index),
+          createTypeVariable(getClassInternal(cls), node.name!, index),
           KTypeVariableData(node));
     }
-    if (node.parent is ir.FunctionNode) {
-      ir.FunctionNode func = node.parent;
+    if (parent is ir.FunctionNode) {
+      ir.FunctionNode func = parent;
       int index = func.typeParameters.indexOf(node);
-      if (func.parent is ir.Constructor) {
-        ir.Constructor constructor = func.parent;
+      final funcParent = func.parent;
+      if (funcParent is ir.Constructor) {
+        ir.Constructor constructor = funcParent;
         ir.Class cls = constructor.enclosingClass;
         return getTypeVariableInternal(cls.typeParameters[index]);
-      } else if (func.parent is ir.Procedure) {
-        ir.Procedure procedure = func.parent;
+      } else if (funcParent is ir.Procedure) {
+        ir.Procedure procedure = funcParent;
         if (procedure.kind == ir.ProcedureKind.Factory) {
-          ir.Class cls = procedure.enclosingClass;
+          ir.Class cls = procedure.enclosingClass!;
           return getTypeVariableInternal(cls.typeParameters[index]);
         } else {
           return typeVariables.register(
               createTypeVariable(
-                  getMethodInternal(procedure), node.name, index),
+                  getMethodInternal(procedure), node.name!, index),
               KTypeVariableData(node));
         }
-      } else if (func.parent is ir.LocalFunction) {
+      } else if (funcParent is ir.LocalFunction) {
         // Ensure that local function type variables have been created.
-        getLocalFunction(func.parent);
+        getLocalFunction(funcParent);
         return typeVariableMap[node];
       } else {
         throw UnsupportedError('Unsupported function type parameter parent '
@@ -1338,17 +1358,18 @@
     throw UnsupportedError('Unsupported type parameter type node $node.');
   }
 
-  ConstructorEntity getConstructorInternal(ir.Member node) {
+  IndexedConstructor getConstructorInternal(ir.Member node) {
     return constructorMap[node] ??= _getConstructorCreate(node);
   }
 
-  ConstructorEntity _getConstructorCreate(ir.Member node) {
+  IndexedConstructor _getConstructorCreate(ir.Member node) {
     assert(
         !envIsClosed,
         "Environment of $this is closed. Trying to create "
         "constructor for $node.");
     ir.FunctionNode functionNode;
-    ClassEntity enclosingClass = getClassForMemberInternal(node.enclosingClass);
+    final enclosingClass =
+        getClassForMemberInternal(node.enclosingClass!) as KClass;
     Name name = getName(node.name);
     bool isExternal = node.isExternal;
 
@@ -1380,25 +1401,26 @@
         constructor, KConstructorDataImpl(node, functionNode));
   }
 
-  FunctionEntity getMethodInternal(ir.Procedure /*!*/ node) {
+  IndexedFunction getMethodInternal(ir.Procedure node) {
     // [_getMethodCreate] inserts the created function in [methodMap] so we
     // don't need to use ??= here.
     return methodMap[node] ?? _getMethodCreate(node);
   }
 
-  FunctionEntity /*!*/ _getMethodCreate(ir.Procedure node) {
+  IndexedFunction _getMethodCreate(ir.Procedure node) {
     assert(
         !envIsClosed,
         "Environment of $this is closed. Trying to create "
         "function for $node.");
-    FunctionEntity function;
-    LibraryEntity library;
-    ClassEntity enclosingClass;
+    late IndexedFunction function;
+    KLibrary library;
+    KClass? enclosingClass;
     if (node.enclosingClass != null) {
-      enclosingClass = getClassForMemberInternal(node.enclosingClass);
+      enclosingClass =
+          getClassForMemberInternal(node.enclosingClass!) as KClass;
       library = enclosingClass.library;
     } else {
-      library = getLibraryInternal(node.enclosingLibrary);
+      library = getLibraryInternal(node.enclosingLibrary) as KLibrary;
     }
     Name name = getName(node.name);
     bool isStatic = node.isStatic;
@@ -1435,22 +1457,23 @@
     return function;
   }
 
-  FieldEntity getFieldInternal(ir.Field node) {
+  IndexedField getFieldInternal(ir.Field node) {
     return fieldMap[node] ??= _getFieldCreate(node);
   }
 
-  FieldEntity _getFieldCreate(ir.Field node) {
+  IndexedField _getFieldCreate(ir.Field node) {
     assert(
         !envIsClosed,
         "Environment of $this is closed. Trying to create "
         "field for $node.");
-    LibraryEntity library;
-    ClassEntity enclosingClass;
+    KLibrary library;
+    KClass? enclosingClass;
     if (node.enclosingClass != null) {
-      enclosingClass = getClassForMemberInternal(node.enclosingClass);
+      enclosingClass =
+          getClassForMemberInternal(node.enclosingClass!) as KClass;
       library = enclosingClass.library;
     } else {
-      library = getLibraryInternal(node.enclosingLibrary);
+      library = getLibraryInternal(node.enclosingLibrary) as KLibrary;
     }
     Name name = getName(node.name);
     bool isStatic = node.isStatic;
@@ -1522,13 +1545,13 @@
 
     if (impactBuilderData.typeMapsForTesting != null) {
       typeMapsForTesting ??= {};
-      typeMapsForTesting[member] = impactBuilderData.typeMapsForTesting;
+      typeMapsForTesting![member] = impactBuilderData.typeMapsForTesting!;
     }
     ImpactData impactData = impactBuilderData.impactData;
     memberData.staticTypes = impactBuilderData.cachedStaticTypes;
     if (retainDataForTesting) {
       impactDataForTesting ??= {};
-      impactDataForTesting[node] = impactData;
+      impactDataForTesting![node] = impactData;
     }
     KernelImpactConverter converter = KernelImpactConverter(
         this,
@@ -1549,33 +1572,31 @@
   }
 
   StaticTypeCache getCachedStaticTypes(KMember member) {
-    StaticTypeCache staticTypes = members.getData(member).staticTypes;
-    assert(staticTypes != null, "No static types cached for $member.");
-    return staticTypes;
+    return members.getData(member).staticTypes!;
   }
 
-  Map<ir.Expression, TypeMap> getTypeMapsForTesting(KMember member) {
-    return typeMapsForTesting[member];
+  Map<ir.Expression, TypeMap>? getTypeMapsForTesting(KMember member) {
+    return typeMapsForTesting![member];
   }
 
   /// Returns the kernel [ir.Procedure] node for the [method].
   ir.Procedure lookupProcedure(KFunction method) {
-    return members.getData(method).node;
+    return members.getData(method).node as ir.Procedure;
   }
 
   /// Returns the [ir.Library] corresponding to [library].
   ir.Library getLibraryNode(LibraryEntity library) {
-    return libraries.getData(library).library;
+    return libraries.getData(library as IndexedLibrary).library;
   }
 
   /// Returns the [Local] corresponding to the local function [node].
   @override
-  Local getLocalFunction(ir.LocalFunction node) {
-    KLocalFunction localFunction = localFunctionMap[node];
+  KLocalFunction getLocalFunction(ir.LocalFunction? node) {
+    KLocalFunction? localFunction = localFunctionMap[node!] as KLocalFunction?;
     if (localFunction == null) {
-      MemberEntity memberContext;
-      Entity executableContext;
-      ir.TreeNode parent = node.parent;
+      late MemberEntity memberContext;
+      late Entity executableContext;
+      ir.TreeNode? parent = node.parent;
       while (parent != null) {
         if (parent is ir.Member) {
           executableContext = memberContext = getMember(parent);
@@ -1589,8 +1610,8 @@
         }
         parent = parent.parent;
       }
-      String name;
-      ir.FunctionNode function;
+      String? name;
+      late ir.FunctionNode function;
       if (node is ir.FunctionDeclaration) {
         name = node.variable.name;
         function = node.function;
@@ -1603,7 +1624,7 @@
       List<KLocalTypeVariable> typeVariables = <KLocalTypeVariable>[];
       for (ir.TypeParameter typeParameter in function.typeParameters) {
         typeVariables.add(typeVariableMap[typeParameter] =
-            KLocalTypeVariable(localFunction, typeParameter.name, index));
+            KLocalTypeVariable(localFunction, typeParameter.name!, index));
         index++;
       }
       index = 0;
@@ -1624,10 +1645,10 @@
   bool implementsFunction(IndexedClass cls) {
     assert(checkFamily(cls));
     KClassData data = classes.getData(cls);
-    OrderedTypeSet orderedTypeSet = data.orderedTypeSet;
-    InterfaceType supertype = orderedTypeSet.asInstanceOf(
+    OrderedTypeSet orderedTypeSet = data.orderedTypeSet!;
+    InterfaceType? supertype = orderedTypeSet.asInstanceOf(
         commonElements.functionClass,
-        getHierarchyDepth(commonElements.functionClass));
+        getHierarchyDepth(commonElements.functionClass as IndexedClass));
     if (supertype != null) {
       return true;
     }
@@ -1636,26 +1657,27 @@
 
   /// Compute the kind of foreign helper function called by [node], if any.
   @override
-  ForeignKind getForeignKind(ir.StaticInvocation node) {
+  interfaces.ForeignKind getForeignKind(ir.StaticInvocation node) {
     if (commonElements.isForeignHelper(getMember(node.target))) {
       switch (node.target.name.text) {
         case Identifiers.JS:
-          return ForeignKind.JS;
+          return interfaces.ForeignKind.JS;
         case Identifiers.JS_BUILTIN:
-          return ForeignKind.JS_BUILTIN;
+          return interfaces.ForeignKind.JS_BUILTIN;
         case Identifiers.JS_EMBEDDED_GLOBAL:
-          return ForeignKind.JS_EMBEDDED_GLOBAL;
+          return interfaces.ForeignKind.JS_EMBEDDED_GLOBAL;
         case Identifiers.JS_INTERCEPTOR_CONSTANT:
-          return ForeignKind.JS_INTERCEPTOR_CONSTANT;
+          return interfaces.ForeignKind.JS_INTERCEPTOR_CONSTANT;
       }
     }
-    return ForeignKind.NONE;
+    return interfaces.ForeignKind.NONE;
   }
 
   /// Computes the [InterfaceType] referenced by a call to the
   /// [JS_INTERCEPTOR_CONSTANT] function, if any.
   @override
-  InterfaceType getInterfaceTypeForJsInterceptorCall(ir.StaticInvocation node) {
+  InterfaceType? getInterfaceTypeForJsInterceptorCall(
+      ir.StaticInvocation node) {
     if (node.arguments.positional.length != 1 ||
         node.arguments.named.isNotEmpty) {
       reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE,
@@ -1663,12 +1685,13 @@
     }
     ir.Node argument = node.arguments.positional.first;
     if (argument is ir.TypeLiteral && argument.type is ir.InterfaceType) {
-      return getInterfaceType(argument.type);
+      return getInterfaceType(argument.type as ir.InterfaceType);
     } else if (argument is ir.ConstantExpression &&
         argument.constant is ir.TypeLiteralConstant) {
-      ir.TypeLiteralConstant constant = argument.constant;
+      ir.TypeLiteralConstant constant =
+          argument.constant as ir.TypeLiteralConstant;
       if (constant.type is ir.InterfaceType) {
-        return getInterfaceType(constant.type);
+        return getInterfaceType(constant.type as ir.InterfaceType);
       }
     }
     return null;
@@ -1679,7 +1702,7 @@
   @override
   NativeBehavior getNativeBehaviorForFieldLoad(ir.Field field,
       Iterable<String> createsAnnotations, Iterable<String> returnsAnnotations,
-      {bool isJsInterop}) {
+      {required bool isJsInterop}) {
     DartType type = getDartType(field.type);
     return nativeBehaviorBuilder.buildFieldLoadBehavior(type,
         createsAnnotations, returnsAnnotations, typeLookup(resolveAsRaw: false),
@@ -1700,8 +1723,8 @@
   @override
   NativeBehavior getNativeBehaviorForMethod(ir.Member member,
       Iterable<String> createsAnnotations, Iterable<String> returnsAnnotations,
-      {bool isJsInterop}) {
-    DartType type;
+      {required bool isJsInterop}) {
+    late DartType type;
     if (member is ir.Procedure) {
       type = getFunctionType(member.function);
     } else if (member is ir.Constructor) {
@@ -1709,8 +1732,8 @@
     } else {
       failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected method node $member.");
     }
-    return nativeBehaviorBuilder.buildMethodBehavior(type, createsAnnotations,
-        returnsAnnotations, typeLookup(resolveAsRaw: false),
+    return nativeBehaviorBuilder.buildMethodBehavior(type as FunctionType,
+        createsAnnotations, returnsAnnotations, typeLookup(resolveAsRaw: false),
         isJsInterop: isJsInterop);
   }
 
@@ -1719,73 +1742,68 @@
     return KLibrary(name, canonicalUri, isNonNullableByDefault);
   }
 
-  IndexedClass createClass(LibraryEntity library, String name,
-      {/*required*/ bool isAbstract}) {
+  IndexedClass createClass(KLibrary library, String name,
+      {required bool isAbstract}) {
     return KClass(library, name, isAbstract: isAbstract);
   }
 
-  TypeVariableEntity createTypeVariable(
+  KTypeVariable createTypeVariable(
       Entity typeDeclaration, String name, int index) {
     return KTypeVariable(typeDeclaration, name, index);
   }
 
-  IndexedConstructor createGenerativeConstructor(ClassEntity enclosingClass,
-      Name name, ParameterStructure parameterStructure,
-      {/*required*/ bool isExternal, /*required*/ bool isConst}) {
+  IndexedConstructor createGenerativeConstructor(
+      KClass enclosingClass, Name name, ParameterStructure parameterStructure,
+      {required bool isExternal, required bool isConst}) {
     return KGenerativeConstructor(enclosingClass, name, parameterStructure,
         isExternal: isExternal, isConst: isConst);
   }
 
   // TODO(dart2js-team): Rename isFromEnvironmentConstructor to
   // isEnvironmentConstructor: Here, and everywhere in the compiler.
-  IndexedConstructor createFactoryConstructor(ClassEntity enclosingClass,
-      Name name, ParameterStructure parameterStructure,
-      {/*required*/ bool isExternal,
-      /*required*/ bool isConst,
-      /*required*/ bool isFromEnvironmentConstructor}) {
+  IndexedConstructor createFactoryConstructor(
+      KClass enclosingClass, Name name, ParameterStructure parameterStructure,
+      {required bool isExternal,
+      required bool isConst,
+      required bool isFromEnvironmentConstructor}) {
     return KFactoryConstructor(enclosingClass, name, parameterStructure,
         isExternal: isExternal,
         isConst: isConst,
         isFromEnvironmentConstructor: isFromEnvironmentConstructor);
   }
 
-  IndexedFunction createGetter(LibraryEntity library,
-      ClassEntity enclosingClass, Name name, AsyncMarker asyncMarker,
-      {/*required*/ bool isStatic,
-      /*required*/ bool isExternal,
-      /*required*/ bool isAbstract}) {
+  IndexedFunction createGetter(KLibrary library, KClass? enclosingClass,
+      Name name, AsyncMarker asyncMarker,
+      {required bool isStatic,
+      required bool isExternal,
+      required bool isAbstract}) {
     return KGetter(library, enclosingClass, name, asyncMarker,
         isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
   }
 
-  IndexedFunction createMethod(
-      LibraryEntity library,
-      ClassEntity enclosingClass,
-      Name name,
-      ParameterStructure parameterStructure,
-      AsyncMarker asyncMarker,
-      {/*required*/ bool isStatic,
-      /*required*/ bool isExternal,
-      /*required*/ bool isAbstract}) {
+  IndexedFunction createMethod(KLibrary library, KClass? enclosingClass,
+      Name name, ParameterStructure parameterStructure, AsyncMarker asyncMarker,
+      {required bool isStatic,
+      required bool isExternal,
+      required bool isAbstract}) {
     return KMethod(
         library, enclosingClass, name, parameterStructure, asyncMarker,
         isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
   }
 
   IndexedFunction createSetter(
-      LibraryEntity library, ClassEntity enclosingClass, Name name,
-      {/*required*/ bool isStatic,
-      /*required*/ bool isExternal,
-      /*required*/ bool isAbstract}) {
+      KLibrary library, KClass? enclosingClass, Name name,
+      {required bool isStatic,
+      required bool isExternal,
+      required bool isAbstract}) {
     return KSetter(library, enclosingClass, name,
         isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
   }
 
-  IndexedField createField(
-      LibraryEntity library, ClassEntity enclosingClass, Name name,
-      {/*required*/ bool isStatic,
-      /*required*/ bool isAssignable,
-      /*required*/ bool isConst}) {
+  IndexedField createField(KLibrary library, KClass? enclosingClass, Name name,
+      {required bool isStatic,
+      required bool isAssignable,
+      required bool isConst}) {
     return KField(library, enclosingClass, name,
         isStatic: isStatic, isAssignable: isAssignable, isConst: isConst);
   }
@@ -1801,37 +1819,37 @@
   DartType get dynamicType => elementMap.types.dynamicType();
 
   @override
-  LibraryEntity get mainLibrary => elementMap._mainLibrary;
+  LibraryEntity? get mainLibrary => elementMap._mainLibrary;
 
   @override
-  FunctionEntity get mainFunction => elementMap._mainFunction;
+  FunctionEntity? get mainFunction => elementMap._mainFunction;
 
   @override
   Iterable<LibraryEntity> get libraries => elementMap.libraryListInternal;
 
   @override
   String getLibraryName(LibraryEntity library) {
-    return elementMap._getLibraryName(library);
+    return elementMap._getLibraryName(library as IndexedLibrary);
   }
 
   @override
   InterfaceType getThisType(ClassEntity cls) {
-    return elementMap.getThisType(cls);
+    return elementMap.getThisType(cls as IndexedClass);
   }
 
   @override
   InterfaceType getJsInteropType(ClassEntity cls) {
-    return elementMap._getJsInteropType(cls);
+    return elementMap._getJsInteropType(cls as IndexedClass)!;
   }
 
   @override
   InterfaceType getRawType(ClassEntity cls) {
-    return elementMap._getRawType(cls);
+    return elementMap._getRawType(cls as IndexedClass);
   }
 
   @override
   InterfaceType getClassInstantiationToBounds(ClassEntity cls) =>
-      elementMap._getClassInstantiationToBounds(cls);
+      elementMap._getClassInstantiationToBounds(cls as IndexedClass);
 
   @override
   bool isGenericClass(ClassEntity cls) {
@@ -1840,23 +1858,23 @@
 
   @override
   bool isMixinApplication(ClassEntity cls) {
-    return elementMap._isMixinApplication(cls);
+    return elementMap._isMixinApplication(cls as IndexedClass);
   }
 
   @override
   bool isUnnamedMixinApplication(ClassEntity cls) {
-    return elementMap._isUnnamedMixinApplication(cls);
+    return elementMap._isUnnamedMixinApplication(cls as IndexedClass);
   }
 
   @override
   DartType getTypeVariableBound(TypeVariableEntity typeVariable) {
     if (typeVariable is KLocalTypeVariable) return typeVariable.bound;
-    return elementMap.getTypeVariableBound(typeVariable);
+    return elementMap.getTypeVariableBound(typeVariable as IndexedTypeVariable);
   }
 
   @override
   List<Variance> getTypeVariableVariances(ClassEntity cls) {
-    return elementMap.getTypeVariableVariances(cls);
+    return elementMap.getTypeVariableVariances(cls as IndexedClass);
   }
 
   @override
@@ -1867,17 +1885,17 @@
 
   @override
   FunctionType getFunctionType(FunctionEntity function) {
-    return elementMap._getFunctionType(function);
+    return elementMap._getFunctionType(function as IndexedFunction);
   }
 
   @override
   List<TypeVariableType> getFunctionTypeVariables(FunctionEntity function) {
-    return elementMap._getFunctionTypeVariables(function);
+    return elementMap._getFunctionTypeVariables(function as IndexedFunction);
   }
 
   @override
   DartType getFieldType(FieldEntity field) {
-    return elementMap._getFieldType(field);
+    return elementMap._getFieldType(field as IndexedField);
   }
 
   @override
@@ -1886,9 +1904,10 @@
   }
 
   @override
-  ConstructorEntity lookupConstructor(ClassEntity cls, String name,
+  ConstructorEntity? lookupConstructor(ClassEntity cls, String name,
       {bool required = false}) {
-    ConstructorEntity constructor = elementMap.lookupConstructor(cls, name);
+    ConstructorEntity? constructor =
+        elementMap.lookupConstructor(cls as IndexedClass, name);
     if (constructor == null && required) {
       throw failedAt(
           CURRENT_ELEMENT_SPANNABLE,
@@ -1899,9 +1918,10 @@
   }
 
   @override
-  MemberEntity lookupLocalClassMember(ClassEntity cls, Name name,
+  MemberEntity? lookupLocalClassMember(ClassEntity cls, Name name,
       {bool required = false}) {
-    MemberEntity member = elementMap.lookupClassMember(cls, name);
+    MemberEntity? member =
+        elementMap.lookupClassMember(cls as IndexedClass, name);
     if (member == null && required) {
       throw failedAt(CURRENT_ELEMENT_SPANNABLE,
           "The member '$name' was not found in ${cls.name}.");
@@ -1910,13 +1930,14 @@
   }
 
   @override
-  ClassEntity getSuperClass(ClassEntity cls,
+  ClassEntity? getSuperClass(ClassEntity cls,
       {bool skipUnnamedMixinApplications = false}) {
     assert(elementMap.checkFamily(cls));
-    ClassEntity superclass = elementMap.getSuperType(cls)?.element;
+    ClassEntity? superclass =
+        elementMap.getSuperType(cls as IndexedClass)?.element;
     if (skipUnnamedMixinApplications) {
       while (superclass != null &&
-          elementMap._isUnnamedMixinApplication(superclass)) {
+          elementMap._isUnnamedMixinApplication(superclass as IndexedClass)) {
         superclass = elementMap.getSuperType(superclass)?.element;
       }
     }
@@ -1925,42 +1946,42 @@
 
   @override
   void forEachSupertype(ClassEntity cls, void f(InterfaceType supertype)) {
-    elementMap._forEachSupertype(cls, f);
+    elementMap._forEachSupertype(cls as IndexedClass, f);
   }
 
   @override
   void forEachMixin(ClassEntity cls, void f(ClassEntity mixin)) {
-    elementMap._forEachMixin(cls, f);
+    elementMap._forEachMixin(cls as IndexedClass, f);
   }
 
   @override
   void forEachLocalClassMember(ClassEntity cls, void f(MemberEntity member)) {
-    elementMap._forEachLocalClassMember(cls, f);
+    elementMap._forEachLocalClassMember(cls as IndexedClass, f);
   }
 
   @override
   void forEachClassMember(
       ClassEntity cls, void f(ClassEntity declarer, MemberEntity member)) {
-    elementMap._forEachClassMember(cls, f);
+    elementMap._forEachClassMember(cls as IndexedClass, f);
   }
 
   @override
   void forEachConstructor(
       ClassEntity cls, void f(ConstructorEntity constructor)) {
-    elementMap._forEachConstructor(cls, f);
+    elementMap._forEachConstructor(cls as IndexedClass, f);
   }
 
   @override
   void forEachLibraryMember(
       LibraryEntity library, void f(MemberEntity member)) {
-    elementMap._forEachLibraryMember(library, f);
+    elementMap._forEachLibraryMember(library as IndexedLibrary, f);
   }
 
   @override
-  MemberEntity lookupLibraryMember(LibraryEntity library, String name,
+  MemberEntity? lookupLibraryMember(LibraryEntity library, String name,
       {bool setter = false, bool required = false}) {
-    MemberEntity member =
-        elementMap.lookupLibraryMember(library, name, setter: setter);
+    MemberEntity? member = elementMap
+        .lookupLibraryMember(library as IndexedLibrary, name, setter: setter);
     if (member == null && required) {
       failedAt(CURRENT_ELEMENT_SPANNABLE,
           "The member '${name}' was not found in library '${library.name}'.");
@@ -1969,9 +1990,9 @@
   }
 
   @override
-  ClassEntity lookupClass(LibraryEntity library, String name,
+  ClassEntity? lookupClass(LibraryEntity library, String name,
       {bool required = false}) {
-    ClassEntity cls = elementMap.lookupClass(library, name);
+    ClassEntity? cls = elementMap.lookupClass(library as IndexedLibrary, name);
     if (cls == null && required) {
       failedAt(CURRENT_ELEMENT_SPANNABLE,
           "The class '$name'  was not found in library '${library.name}'.");
@@ -1981,12 +2002,12 @@
 
   @override
   void forEachClass(LibraryEntity library, void f(ClassEntity cls)) {
-    elementMap._forEachClass(library, f);
+    elementMap._forEachClass(library as IndexedLibrary, f);
   }
 
   @override
-  LibraryEntity lookupLibrary(Uri uri, {bool required = false}) {
-    LibraryEntity library = elementMap.lookupLibrary(uri);
+  LibraryEntity? lookupLibrary(Uri uri, {bool required = false}) {
+    LibraryEntity? library = elementMap.lookupLibrary(uri);
     if (library == null && required) {
       failedAt(CURRENT_ELEMENT_SPANNABLE, "The library '$uri' was not found.");
     }
@@ -2012,15 +2033,15 @@
   @override
   bool isEnumClass(ClassEntity cls) {
     assert(elementMap.checkFamily(cls));
-    KClassData classData = elementMap.classes.getData(cls);
+    KClassData classData = elementMap.classes.getData(cls as IndexedClass);
     return classData.isEnumClass;
   }
 
   @override
-  ClassEntity getEffectiveMixinClass(ClassEntity cls) {
+  ClassEntity? getEffectiveMixinClass(ClassEntity cls) {
     if (!isMixinApplication(cls)) return null;
     do {
-      cls = elementMap.getAppliedMixin(cls);
+      cls = elementMap.getAppliedMixin(cls as IndexedClass)!;
     } while (isMixinApplication(cls));
     return cls;
   }
@@ -2028,14 +2049,14 @@
   @override
   bool isLateBackingField(covariant IndexedField field) {
     assert(elementMap.checkFamily(field));
-    KFieldData fieldData = elementMap.members.getData(field);
+    KFieldData fieldData = elementMap.members.getData(field) as KFieldData;
     return fieldData.isLateBackingField;
   }
 
   @override
   bool isLateFinalBackingField(covariant IndexedField field) {
     assert(elementMap.checkFamily(field));
-    KFieldData fieldData = elementMap.members.getData(field);
+    KFieldData fieldData = elementMap.members.getData(field) as KFieldData;
     return fieldData.isLateFinalBackingField;
   }
 }
@@ -2045,36 +2066,36 @@
 
   final KernelToElementMap _elementMap;
   final NativeBasicData _nativeBasicData;
-  final NativeDataBuilder _nativeDataBuilder;
+  final NativeDataBuilder? _nativeDataBuilder;
 
   KernelNativeMemberResolver(
       this._elementMap, this._nativeBasicData, this._nativeDataBuilder);
 
   /// Computes whether [node] is native or JsInterop.
   void resolveNativeMember(ir.Member node, IrAnnotationData annotationData) {
-    assert(annotationData != null);
     bool isJsInterop = _isJsInteropMember(node);
     if (node is ir.Procedure || node is ir.Constructor) {
-      FunctionEntity method = _elementMap.getMember(node);
+      FunctionEntity method = _elementMap.getMember(node) as FunctionEntity;
       bool isNative = _processMethodAnnotations(node, annotationData);
       if (isNative || isJsInterop) {
         NativeBehavior behavior = _computeNativeMethodBehavior(
-            method, annotationData,
+            method as KFunction, annotationData,
             isJsInterop: isJsInterop);
-        _nativeDataBuilder.setNativeMethodBehavior(method, behavior);
+        _nativeDataBuilder!.setNativeMethodBehavior(method, behavior);
       }
     } else if (node is ir.Field) {
-      FieldEntity field = _elementMap.getMember(node);
+      FieldEntity field = _elementMap.getMember(node) as FieldEntity;
       bool isNative = _processFieldAnnotations(node, annotationData);
       if (isNative || isJsInterop) {
         NativeBehavior fieldLoadBehavior = _computeNativeFieldLoadBehavior(
-            field, annotationData,
+            field as KField, annotationData,
             isJsInterop: isJsInterop);
         NativeBehavior fieldStoreBehavior =
             _computeNativeFieldStoreBehavior(field);
-        _nativeDataBuilder.setNativeFieldLoadBehavior(field, fieldLoadBehavior);
-        _nativeDataBuilder.setNativeFieldStoreBehavior(
-            field, fieldStoreBehavior);
+        _nativeDataBuilder!
+            .setNativeFieldLoadBehavior(field, fieldLoadBehavior);
+        _nativeDataBuilder!
+            .setNativeFieldStoreBehavior(field, fieldStoreBehavior);
       }
     }
   }
@@ -2083,10 +2104,9 @@
   /// attributes. Returns `true` of [method] is native.
   bool _processFieldAnnotations(
       ir.Field node, IrAnnotationData annotationData) {
-    assert(annotationData != null);
     if (node.isInstanceMember &&
         _nativeBasicData
-            .isNativeClass(_elementMap.getClass(node.enclosingClass))) {
+            .isNativeClass(_elementMap.getClass(node.enclosingClass!))) {
       // Exclude non-instance (static) fields - they are not really native and
       // are compiled as isolate globals.  Access of a property of a constructor
       // function or a non-method property in the prototype chain, must be coded
@@ -2094,7 +2114,7 @@
       _setNativeName(node, annotationData);
       return true;
     } else {
-      String name = _findJsNameFromAnnotation(node, annotationData);
+      String? name = _findJsNameFromAnnotation(node, annotationData);
       if (name != null) {
         failedAt(
             computeSourceSpanFromTreeNode(node),
@@ -2109,11 +2129,10 @@
   /// attributes. Returns `true` of [method] is native.
   bool _processMethodAnnotations(
       ir.Member node, IrAnnotationData annotationData) {
-    assert(annotationData != null);
     if (_isNativeMethod(node, annotationData)) {
       if (node.enclosingClass != null && !node.isInstanceMember) {
         if (!_nativeBasicData
-            .isNativeClass(_elementMap.getClass(node.enclosingClass))) {
+            .isNativeClass(_elementMap.getClass(node.enclosingClass!))) {
           _elementMap.reporter.reportErrorMessage(
               computeSourceSpanFromTreeNode(node),
               MessageKind.NATIVE_NON_INSTANCE_IN_NON_NATIVE_CLASS);
@@ -2131,9 +2150,9 @@
   /// Sets the native name of [element], either from an annotation, or
   /// defaulting to the Dart name.
   void _setNativeName(ir.Member node, IrAnnotationData annotationData) {
-    String name = _findJsNameFromAnnotation(node, annotationData);
+    String? name = _findJsNameFromAnnotation(node, annotationData);
     name ??= node.name.text;
-    _nativeDataBuilder.setNativeMemberName(_elementMap.getMember(node), name);
+    _nativeDataBuilder!.setNativeMemberName(_elementMap.getMember(node), name);
   }
 
   /// Sets the native name of the static native method [element], using the
@@ -2146,10 +2165,10 @@
   ///    the method with the @Native name of the enclosing class.
   void _setNativeNameForStaticMethod(
       ir.Member node, IrAnnotationData annotationData) {
-    String name = _findJsNameFromAnnotation(node, annotationData);
+    String? name = _findJsNameFromAnnotation(node, annotationData);
     name ??= node.name.text;
     if (_isIdentifier(name)) {
-      ClassEntity cls = _elementMap.getClass(node.enclosingClass);
+      ClassEntity cls = _elementMap.getClass(node.enclosingClass!);
       List<String> nativeNames = _nativeBasicData.getNativeTagsOfClass(cls);
       if (nativeNames.length != 1) {
         failedAt(
@@ -2157,10 +2176,11 @@
             'Unable to determine a native name for the enclosing class, '
             'options: $nativeNames');
       }
-      _nativeDataBuilder.setNativeMemberName(
+      _nativeDataBuilder!.setNativeMemberName(
           _elementMap.getMember(node), '${nativeNames[0]}.$name');
     } else {
-      _nativeDataBuilder.setNativeMemberName(_elementMap.getMember(node), name);
+      _nativeDataBuilder!
+          .setNativeMemberName(_elementMap.getMember(node), name);
     }
   }
 
@@ -2168,22 +2188,20 @@
 
   /// Returns the JSName annotation string or `null` if no JSName annotation is
   /// present.
-  String _findJsNameFromAnnotation(
+  String? _findJsNameFromAnnotation(
       ir.Member node, IrAnnotationData annotationData) {
-    assert(annotationData != null);
     return annotationData.getNativeMemberName(node);
   }
 
   NativeBehavior _computeNativeFieldStoreBehavior(covariant KField field) {
-    ir.Field node = _elementMap.getMemberNode(field);
+    ir.Field node = _elementMap.getMemberNode(field) as ir.Field;
     return _elementMap.getNativeBehaviorForFieldStore(node);
   }
 
   NativeBehavior _computeNativeFieldLoadBehavior(
       KField field, IrAnnotationData annotationData,
-      {bool isJsInterop}) {
-    assert(annotationData != null);
-    ir.Field node = _elementMap.getMemberNode(field);
+      {required bool isJsInterop}) {
+    ir.Field node = _elementMap.getMemberNode(field) as ir.Field;
     Iterable<String> createsAnnotations =
         annotationData.getCreatesAnnotations(node);
     Iterable<String> returnsAnnotations =
@@ -2195,8 +2213,7 @@
 
   NativeBehavior _computeNativeMethodBehavior(
       KFunction function, IrAnnotationData annotationData,
-      {bool isJsInterop}) {
-    assert(annotationData != null);
+      {required bool isJsInterop}) {
     ir.Member node = _elementMap.getMemberNode(function);
     Iterable<String> createsAnnotations =
         annotationData.getCreatesAnnotations(node);
@@ -2208,7 +2225,6 @@
   }
 
   bool _isNativeMethod(ir.Member node, IrAnnotationData annotationData) {
-    assert(annotationData != null);
     if (!maybeEnableNative(node.enclosingLibrary.importUri)) return false;
     bool hasNativeBody = annotationData.hasNativeBody(node);
     // TODO(rileyporter): Move this check on non-native external usage to
@@ -2228,22 +2244,3 @@
     return _nativeBasicData.isJsInteropMember(_elementMap.getMember(node));
   }
 }
-
-DiagnosticMessage _createDiagnosticMessage(
-    DiagnosticReporter reporter, ir.LocatedMessage message) {
-  SourceSpan sourceSpan = SourceSpan(
-      message.uri, message.charOffset, message.charOffset + message.length);
-  return reporter.createMessage(
-      sourceSpan, MessageKind.GENERIC, {'text': message.problemMessage});
-}
-
-void reportLocatedMessage(DiagnosticReporter reporter,
-    ir.LocatedMessage message, List<ir.LocatedMessage> context) {
-  DiagnosticMessage diagnosticMessage =
-      _createDiagnosticMessage(reporter, message);
-  List<DiagnosticMessage> infos = [];
-  for (ir.LocatedMessage message in context) {
-    infos.add(_createDiagnosticMessage(reporter, message));
-  }
-  reporter.reportError(diagnosticMessage, infos);
-}
diff --git a/pkg/compiler/lib/src/kernel/element_map_interfaces.dart b/pkg/compiler/lib/src/kernel/element_map_interfaces.dart
index 12453f5..f393fdd 100644
--- a/pkg/compiler/lib/src/kernel/element_map_interfaces.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_interfaces.dart
@@ -14,6 +14,7 @@
         Expression,
         Field,
         InterfaceType,
+        Library,
         LibraryDependency,
         LocalFunction,
         Member,
@@ -31,18 +32,28 @@
         ConstructorEntity,
         FieldEntity,
         FunctionEntity,
+        LibraryEntity,
         Local,
         MemberEntity,
         ImportEntity;
 import '../constants/values.dart';
-import '../elements/indexed.dart' show IndexedClass;
+import '../elements/indexed.dart'
+    show
+        EntityDataEnvMap,
+        EntityDataMap,
+        IndexedClass,
+        IndexedMember,
+        IndexedLibrary,
+        IndexedTypeVariable;
 import '../elements/names.dart' show Name;
 import '../elements/types.dart' show DartType, DartTypes, InterfaceType;
 import '../ir/constants.dart' show Dart2jsConstantEvaluator;
+import '../ir/element_map.dart' show IrToElementMap;
 import '../native/behavior.dart';
 import '../js_backend/native_data.dart' show NativeBasicData;
 import '../options.dart';
 import '../universe/selector.dart';
+import 'env_interfaces.dart';
 
 enum ForeignKind {
   JS,
@@ -97,7 +108,7 @@
       {bool requireConstant = true,
       bool implicitNull = false,
       bool checkCasts = true});
-  ImportEntity getImport(ir.LibraryDependency? node);
+  ImportEntity? getImport(ir.LibraryDependency? node);
   ir.Member getMemberNode(MemberEntity member);
   ir.StaticTypeContext getStaticTypeContext(MemberEntity member);
 }
@@ -144,6 +155,26 @@
       List<String> namedArguments, int typeArguments);
 }
 
+abstract class KernelToElementMapForJsModel implements IrToElementMap {
+  CompilerOptions get options;
+  EntityDataEnvMap<IndexedLibrary, KLibraryData, KLibraryEnv> get libraries;
+
+  EntityDataEnvMap<IndexedClass, KClassData, KClassEnv> get classes;
+  EntityDataMap<IndexedMember, KMemberData> get members;
+  EntityDataMap<IndexedTypeVariable, KTypeVariableData> get typeVariables;
+
+  KProgramEnv get env;
+  bool get envIsClosed;
+  set envIsClosed(bool v);
+}
+
+abstract class KernelToElementMapForEnv implements IrToElementMap {
+  ir.TypeEnvironment get typeEnvironment;
+  LibraryEntity getLibrary(ir.Library node);
+  List<ConstantValue> getMetadata(
+      ir.StaticTypeContext staticTypeContext, List<ir.Expression> annotations);
+}
+
 // Members which dart2js ignores.
 bool memberIsIgnorable(ir.Member node, {ir.Class? cls}) {
   if (node is! ir.Procedure) return false;
diff --git a/pkg/compiler/lib/src/kernel/element_map_migrated.dart b/pkg/compiler/lib/src/kernel/element_map_migrated.dart
new file mode 100644
index 0000000..d8b1e41
--- /dev/null
+++ b/pkg/compiler/lib/src/kernel/element_map_migrated.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2017, 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:front_end/src/api_unstable/dart2js.dart' as ir;
+import '../common.dart';
+
+DiagnosticMessage _createDiagnosticMessage(
+    DiagnosticReporter reporter, ir.LocatedMessage message) {
+  SourceSpan sourceSpan = SourceSpan(
+      message.uri!, message.charOffset, message.charOffset + message.length);
+  return reporter.createMessage(
+      sourceSpan, MessageKind.GENERIC, {'text': message.problemMessage});
+}
+
+void reportLocatedMessage(DiagnosticReporter reporter,
+    ir.LocatedMessage message, List<ir.LocatedMessage>? context) {
+  DiagnosticMessage diagnosticMessage =
+      _createDiagnosticMessage(reporter, message);
+  List<DiagnosticMessage> infos = [];
+  for (ir.LocatedMessage message in context ?? const []) {
+    infos.add(_createDiagnosticMessage(reporter, message));
+  }
+  reporter.reportError(diagnosticMessage, infos);
+}
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index f4ca087..0e26f39 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 library dart2js.kernel.env;
 
 import 'package:front_end/src/api_unstable/dart2js.dart'
@@ -26,93 +24,69 @@
 import '../js_model/env.dart';
 import '../ordered_typeset.dart';
 import '../universe/member_usage.dart';
-import 'element_map.dart';
-import 'element_map_interfaces.dart' show memberIsIgnorable;
+import 'element_map_interfaces.dart'
+    show memberIsIgnorable, KernelToElementMapForEnv;
+
+import 'env_interfaces.dart' as interfaces;
 
 /// Environment for fast lookup of component libraries.
-class KProgramEnv {
-  final Set<ir.Component> _components = Set<ir.Component>();
+class KProgramEnv implements interfaces.KProgramEnv {
+  final Set<ir.Component> _components = {};
 
-  Map<Uri, KLibraryEnv> _libraryMap;
+  late final Map<Uri, KLibraryEnv> _libraryMap = {
+    for (final component in _components)
+      for (final library in component.libraries)
+        library.importUri: KLibraryEnv(library),
+  };
 
   /// TODO(johnniwinther): Handle arbitrary load order if needed.
-  ir.Member get mainMethod => _components.first?.mainMethod;
+  ir.Member? get mainMethod => mainComponent.mainMethod;
 
   ir.Component get mainComponent => _components.first;
 
   void addComponent(ir.Component component) {
     if (_components.add(component)) {
-      if (_libraryMap != null) {
-        _addLibraries(component);
-      }
-    }
-  }
-
-  void _addLibraries(ir.Component component) {
-    for (ir.Library library in component.libraries) {
-      _libraryMap[library.importUri] = KLibraryEnv(library);
-    }
-  }
-
-  void _ensureLibraryMap() {
-    if (_libraryMap == null) {
-      _libraryMap = <Uri, KLibraryEnv>{};
-      for (ir.Component component in _components) {
-        _addLibraries(component);
+      for (ir.Library library in component.libraries) {
+        _libraryMap[library.importUri] ??= KLibraryEnv(library);
       }
     }
   }
 
   /// Return the [KLibraryEnv] for the library with the canonical [uri].
-  KLibraryEnv lookupLibrary(Uri uri) {
-    _ensureLibraryMap();
-    return _libraryMap[uri];
-  }
+  KLibraryEnv? lookupLibrary(Uri uri) => _libraryMap[uri];
 
   /// Calls [f] for each library in this environment.
   void forEachLibrary(void f(KLibraryEnv library)) {
-    _ensureLibraryMap();
     _libraryMap.values.forEach(f);
   }
 
   /// Returns the number of libraries in this environment.
-  int get length {
-    _ensureLibraryMap();
-    return _libraryMap.length;
-  }
+  int get length => _libraryMap.length;
 
   /// Convert this [KProgramEnv] to the corresponding [JProgramEnv].
+  @override
   JProgramEnv convert() => JProgramEnv(_components);
 }
 
 /// Environment for fast lookup of library classes and members.
-class KLibraryEnv {
+class KLibraryEnv implements interfaces.KLibraryEnv {
+  @override
   final ir.Library library;
 
-  Map<String, KClassEnv> _classMap;
-  Map<String, ir.Member> _memberMap;
-  Map<String, ir.Member> _setterMap;
+  late final Map<String, KClassEnv> _classMap = {
+    for (ir.Class cls in library.classes) cls.name: KClassEnvImpl(cls),
+  };
+
+  Map<String, ir.Member>? _memberMap;
+  Map<String, ir.Member>? _setterMap;
 
   KLibraryEnv(this.library);
 
-  void _ensureClassMap() {
-    if (_classMap == null) {
-      _classMap = <String, KClassEnv>{};
-      for (ir.Class cls in library.classes) {
-        _classMap[cls.name] = KClassEnvImpl(cls);
-      }
-    }
-  }
-
   /// Return the [KClassEnv] for the class [name] in [library].
-  KClassEnv lookupClass(String name) {
-    _ensureClassMap();
-    return _classMap[name];
-  }
+  KClassEnv? lookupClass(String name) => _classMap[name];
 
   /// Calls [f] for each class in this library.
   void forEachClass(void f(KClassEnv cls)) {
-    _ensureClassMap();
     _classMap.values.forEach(f);
   }
 
@@ -126,14 +100,14 @@
         }
         if (member is ir.Procedure) {
           if (member.kind == ir.ProcedureKind.Setter) {
-            _setterMap[member.name.text] = member;
+            _setterMap![member.name.text] = member;
           } else {
-            _memberMap[member.name.text] = member;
+            _memberMap![member.name.text] = member;
           }
         } else if (member is ir.Field) {
-          _memberMap[member.name.text] = member;
+          _memberMap![member.name.text] = member;
           if (member.hasSetter) {
-            _setterMap[member.name.text] = member;
+            _setterMap![member.name.text] = member;
           }
         } else {
           failedAt(
@@ -144,15 +118,15 @@
   }
 
   /// Return the [ir.Member] for the member [name] in [library].
-  ir.Member lookupMember(String name, {bool setter = false}) {
+  ir.Member? lookupMember(String name, {bool setter = false}) {
     _ensureMemberMaps();
-    return setter ? _setterMap[name] : _memberMap[name];
+    return setter ? _setterMap![name] : _memberMap![name];
   }
 
   void forEachMember(void f(ir.Member member)) {
     _ensureMemberMaps();
-    _memberMap.values.forEach(f);
-    for (ir.Member member in _setterMap.values) {
+    _memberMap!.values.forEach(f);
+    for (ir.Member member in _setterMap!.values) {
       if (member is ir.Procedure) {
         f(member);
       } else {
@@ -163,6 +137,7 @@
 
   /// Convert this [KLibraryEnv] to a corresponding [JLibraryEnv] containing
   /// only the members in [liveMembers].
+  @override
   JLibraryEnv convert(IrToElementMap kElementMap,
       Map<MemberEntity, MemberUsage> liveMemberUsage) {
     Map<String, ir.Member> memberMap;
@@ -171,7 +146,7 @@
       memberMap = const <String, ir.Member>{};
     } else {
       memberMap = <String, ir.Member>{};
-      _memberMap.forEach((String name, ir.Member node) {
+      _memberMap!.forEach((String name, ir.Member node) {
         MemberEntity member = kElementMap.getMember(node);
         if (liveMemberUsage.containsKey(member)) {
           memberMap[name] = node;
@@ -182,7 +157,7 @@
       setterMap = const <String, ir.Member>{};
     } else {
       setterMap = <String, ir.Member>{};
-      _setterMap.forEach((String name, ir.Member node) {
+      _setterMap!.forEach((String name, ir.Member node) {
         MemberEntity member = kElementMap.getMember(node);
         if (liveMemberUsage.containsKey(member)) {
           setterMap[name] = node;
@@ -193,22 +168,22 @@
   }
 }
 
-class KLibraryData {
+class KLibraryData implements interfaces.KLibraryData {
   final ir.Library library;
-  Iterable<ConstantValue> _metadata;
+  Iterable<ConstantValue>? _metadata;
   // TODO(johnniwinther): Avoid direct access to [imports].
-  Map<ir.LibraryDependency, ImportEntity> imports;
+  Map<ir.LibraryDependency, ImportEntity>? imports;
 
   KLibraryData(this.library);
 
-  Iterable<ConstantValue> getMetadata(KernelToElementMap elementMap) {
+  Iterable<ConstantValue> getMetadata(KernelToElementMapForEnv elementMap) {
     return _metadata ??= elementMap.getMetadata(
         ir.StaticTypeContext.forAnnotations(
             library, elementMap.typeEnvironment),
         library.annotations);
   }
 
-  Iterable<ImportEntity> getImports(KernelToElementMap elementMap) {
+  Iterable<ImportEntity> getImports(KernelToElementMapForEnv elementMap) {
     if (imports == null) {
       List<ir.LibraryDependency> dependencies = library.dependencies;
       if (dependencies.isEmpty) {
@@ -217,7 +192,7 @@
         imports = <ir.LibraryDependency, ImportEntity>{};
         dependencies.forEach((ir.LibraryDependency node) {
           if (node.isExport) return;
-          imports[node] = ImportEntity(
+          imports![node] = ImportEntity(
               node.isDeferred,
               node.name,
               node.targetLibrary.importUri,
@@ -225,19 +200,21 @@
         });
       }
     }
-    return imports.values;
+    return imports!.values;
   }
 
   /// Convert this [KLibraryData] to the corresponding [JLibraryData].
   // TODO(johnniwinther): Why isn't [imports] ensured to be non-null here?
+  @override
   JLibraryData convert() {
-    return JLibraryData(library, imports);
+    return JLibraryData(library, imports ?? const {});
   }
 }
 
 /// Member data for a class.
-abstract class KClassEnv {
+abstract class KClassEnv implements interfaces.KClassEnv {
   /// The [ir.Class] that defined the class, if any.
+  @override
   ir.Class get cls;
 
   /// Whether the class is an unnamed mixin application.
@@ -250,16 +227,16 @@
   bool get isMixinApplicationWithMembers;
 
   /// Ensures that all members have been computed for [cls].
-  void ensureMembers(KernelToElementMap elementMap);
+  void ensureMembers(KernelToElementMapForEnv elementMap);
 
   /// Return the [MemberEntity] for the member [name] in the class.
-  MemberEntity lookupMember(IrToElementMap elementMap, Name name);
+  MemberEntity? lookupMember(IrToElementMap elementMap, Name name);
 
   /// Calls [f] for each member of [cls].
   void forEachMember(IrToElementMap elementMap, void f(MemberEntity member));
 
   /// Return the [ConstructorEntity] for the constructor [name] in [cls].
-  ConstructorEntity lookupConstructor(IrToElementMap elementMap, String name);
+  ConstructorEntity? lookupConstructor(IrToElementMap elementMap, String? name);
 
   /// Calls [f] for each constructor of [cls].
   void forEachConstructor(
@@ -274,6 +251,7 @@
   ///
   /// [getJLibrary] returns the [LibraryEntity] in the J-model corresponding to
   /// a [ir.Library] node.
+  @override
   JClassEnv convert(
       IrToElementMap kElementMap,
       Map<MemberEntity, MemberUsage> liveMemberUsage,
@@ -287,8 +265,8 @@
 }
 
 int orderByFileOffset(ir.TreeNode a, ir.TreeNode b) {
-  var aLoc = a.location;
-  var bLoc = b.location;
+  var aLoc = a.location!;
+  var bLoc = b.location!;
   var aUri = '${aLoc.file}';
   var bUri = '${bLoc.file}';
   var uriCompare = aUri.compareTo(bUri);
@@ -301,41 +279,35 @@
   @override
   final ir.Class cls;
 
-  Map<String, ir.Member> _constructorMap;
-  Map<Name, ir.Member> _memberMap;
-  List<ir.Member> _members; // in declaration order.
-  bool _isMixinApplicationWithMembers;
+  Map<String, ir.Member>? _constructorMap;
+  Map<Name, ir.Member>? _memberMap;
+  List<ir.Member>? _members; // in declaration order.
+  bool? _isMixinApplicationWithMembers;
 
   /// Constructor bodies created for this class.
-  List<ConstructorBodyEntity> _constructorBodyList;
+  List<ConstructorBodyEntity>? _constructorBodyList;
 
   KClassEnvImpl(this.cls);
 
-  KClassEnvImpl.internal(this.cls, this._constructorMap, this._memberMap,
-      this._members, this._isMixinApplicationWithMembers);
-
   @override
   bool get isUnnamedMixinApplication => cls.isAnonymousMixin;
 
   @override
-  bool get isMixinApplicationWithMembers {
-    assert(_isMixinApplicationWithMembers != null);
-    return _isMixinApplicationWithMembers;
-  }
+  bool get isMixinApplicationWithMembers => _isMixinApplicationWithMembers!;
 
   @override
   bool checkHasMember(ir.Member node) {
     if (_memberMap == null) return false;
-    return _memberMap.values.contains(node) ||
-        _constructorMap.values.contains(node);
+    return _memberMap!.values.contains(node) ||
+        _constructorMap!.values.contains(node);
   }
 
   @override
-  void ensureMembers(KernelToElementMap elementMap) {
+  void ensureMembers(KernelToElementMapForEnv elementMap) {
     _ensureMaps(elementMap);
   }
 
-  void _ensureMaps(KernelToElementMap elementMap) {
+  void _ensureMaps(KernelToElementMapForEnv elementMap) {
     if (_memberMap != null) return;
 
     _memberMap = <Name, ir.Member>{};
@@ -343,20 +315,20 @@
     var members = <ir.Member>[];
     _isMixinApplicationWithMembers = false;
 
-    void addField(ir.Field member, {bool includeStatic}) {
+    void addField(ir.Field member, {required bool includeStatic}) {
       if (!includeStatic && member.isStatic) return;
       if (isRedirectingFactoryField(member)) return;
       var name = elementMap.getName(member.name);
-      _memberMap[name] = member;
+      _memberMap![name] = member;
       if (member.hasSetter) {
-        _memberMap[name.setter] = member;
+        _memberMap![name.setter] = member;
       }
       members.add(member);
     }
 
     void addProcedure(ir.Procedure member,
-        {bool includeStatic,
-        bool includeNoSuchMethodForwarders,
+        {required bool includeStatic,
+        required bool includeNoSuchMethodForwarders,
         bool isFromMixinApplication = false}) {
       if (memberIsIgnorable(member, cls: cls)) return;
       if (!includeStatic && member.isStatic) return;
@@ -370,10 +342,10 @@
           // Don't include redirecting factories.
           return;
         }
-        _constructorMap[member.name.text] = member;
+        _constructorMap![member.name.text] = member;
       } else {
         var name = elementMap.getName(member.name, setter: member.isSetter);
-        _memberMap[name] = member;
+        _memberMap![name] = member;
         members.add(member);
         if (isFromMixinApplication) {
           _isMixinApplicationWithMembers = true;
@@ -384,21 +356,21 @@
     void addConstructors(ir.Class c) {
       for (ir.Constructor member in c.constructors) {
         var name = member.name.text;
-        _constructorMap[name] = member;
+        _constructorMap![name] = member;
       }
     }
 
     int mixinMemberCount = 0;
 
     if (cls.mixedInClass != null) {
-      for (ir.Field field in cls.mixedInClass.mixin.fields) {
+      for (ir.Field field in cls.mixedInClass!.mixin.fields) {
         if (field.containsSuperCalls) {
           _isMixinApplicationWithMembers = true;
           continue;
         }
         addField(field, includeStatic: false);
       }
-      for (ir.Procedure procedure in cls.mixedInClass.mixin.procedures) {
+      for (ir.Procedure procedure in cls.mixedInClass!.mixin.procedures) {
         if (procedure.containsSuperCalls) {
           _isMixinApplicationWithMembers = true;
           continue;
@@ -426,39 +398,41 @@
   }
 
   @override
-  MemberEntity lookupMember(IrToElementMap elementMap, Name name) {
+  MemberEntity? lookupMember(
+      covariant KernelToElementMapForEnv elementMap, Name name) {
     _ensureMaps(elementMap);
-    ir.Member member = _memberMap[name];
+    ir.Member? member = _memberMap![name];
     return member != null ? elementMap.getMember(member) : null;
   }
 
   @override
   void forEachMember(IrToElementMap elementMap, void f(MemberEntity member)) {
-    _ensureMaps(elementMap);
-    _members.forEach((ir.Member member) {
+    _ensureMaps(elementMap as KernelToElementMapForEnv);
+    _members!.forEach((ir.Member member) {
       f(elementMap.getMember(member));
     });
   }
 
   @override
-  ConstructorEntity lookupConstructor(IrToElementMap elementMap, String name) {
-    _ensureMaps(elementMap);
-    ir.Member constructor = _constructorMap[name];
+  ConstructorEntity? lookupConstructor(
+      IrToElementMap elementMap, String? name) {
+    _ensureMaps(elementMap as KernelToElementMapForEnv);
+    ir.Member? constructor = _constructorMap![name!];
     return constructor != null ? elementMap.getConstructor(constructor) : null;
   }
 
   @override
   void forEachConstructor(
       IrToElementMap elementMap, void f(ConstructorEntity constructor)) {
-    _ensureMaps(elementMap);
-    _constructorMap.values.forEach((ir.Member constructor) {
+    _ensureMaps(elementMap as KernelToElementMapForEnv);
+    _constructorMap!.values.forEach((ir.Member constructor) {
       f(elementMap.getConstructor(constructor));
     });
   }
 
   void addConstructorBody(ConstructorBodyEntity constructorBody) {
     _constructorBodyList ??= <ConstructorBodyEntity>[];
-    _constructorBodyList.add(constructorBody);
+    _constructorBodyList!.add(constructorBody);
   }
 
   @override
@@ -478,7 +452,7 @@
       constructorMap = const <String, ir.Member>{};
     } else {
       constructorMap = <String, ir.Member>{};
-      _constructorMap.forEach((String name, ir.Member node) {
+      _constructorMap!.forEach((String name, ir.Member node) {
         MemberEntity member = kElementMap.getMember(node);
         if (liveMemberUsage.containsKey(member)) {
           constructorMap[name] = node;
@@ -489,7 +463,7 @@
       memberMap = const <Name, ir.Member>{};
     } else {
       memberMap = <Name, ir.Member>{};
-      _memberMap.forEach((Name name, ir.Member node) {
+      _memberMap!.forEach((Name name, ir.Member node) {
         MemberEntity member = kElementMap.getMember(node);
         if (liveMemberUsage.containsKey(member)) {
           memberMap[name] = node;
@@ -500,7 +474,7 @@
       members = const <ir.Member>[];
     } else {
       members = <ir.Member>[];
-      _members.forEach((ir.Member node) {
+      _members!.forEach((ir.Member node) {
         MemberEntity member = kElementMap.getMember(node);
         if (liveMemberUsage.containsKey(member)) {
           members.add(node);
@@ -512,18 +486,18 @@
   }
 }
 
-abstract class KClassData {
+abstract class KClassData implements interfaces.KClassData {
   ir.Class get node;
 
-  InterfaceType get thisType;
-  InterfaceType get jsInteropType;
-  InterfaceType /*?*/ get rawType;
-  InterfaceType /*?*/ get instantiationToBounds;
-  InterfaceType get supertype;
-  InterfaceType get mixedInType;
-  List<InterfaceType> get interfaces;
-  OrderedTypeSet get orderedTypeSet;
-  DartType get callType;
+  InterfaceType? get thisType;
+  InterfaceType? get jsInteropType;
+  InterfaceType? get rawType;
+  InterfaceType? get instantiationToBounds;
+  InterfaceType? get supertype;
+  InterfaceType? get mixedInType;
+  List<InterfaceType>? get interfaces;
+  OrderedTypeSet? get orderedTypeSet;
+  DartType? get callType;
 
   bool get isEnumClass;
   bool get isMixinApplication;
@@ -532,6 +506,7 @@
   List<Variance> getVariances();
 
   /// Convert this [KClassData] to the corresponding [JClassData].
+  @override
   JClassData convert();
 }
 
@@ -539,27 +514,27 @@
   @override
   final ir.Class node;
   @override
-  bool isMixinApplication;
+  late bool isMixinApplication;
 
   @override
-  InterfaceType thisType;
+  InterfaceType? thisType;
   @override
-  InterfaceType jsInteropType;
+  InterfaceType? jsInteropType;
   @override
-  InterfaceType rawType;
+  InterfaceType? rawType;
   @override
-  InterfaceType instantiationToBounds;
+  InterfaceType? instantiationToBounds;
   @override
-  InterfaceType supertype;
+  InterfaceType? supertype;
   @override
-  InterfaceType mixedInType;
+  InterfaceType? mixedInType;
   @override
-  List<InterfaceType> interfaces;
+  List<InterfaceType>? interfaces;
   @override
-  OrderedTypeSet orderedTypeSet;
+  OrderedTypeSet? orderedTypeSet;
 
-  Iterable<ConstantValue> _metadata;
-  List<Variance> _variances;
+  Iterable<ConstantValue>? _metadata;
+  List<Variance>? _variances;
 
   KClassDataImpl(this.node);
 
@@ -567,11 +542,12 @@
   bool get isEnumClass => node.isEnum;
 
   @override
-  FunctionType callType;
+  FunctionType? callType;
   bool isCallTypeComputed = false;
 
   @override
-  Iterable<ConstantValue> getMetadata(covariant KernelToElementMap elementMap) {
+  Iterable<ConstantValue> getMetadata(
+      covariant KernelToElementMapForEnv elementMap) {
     return _metadata ??= elementMap.getMetadata(
         ir.StaticTypeContext.forAnnotations(
             node.enclosingLibrary, elementMap.typeEnvironment),
@@ -588,18 +564,20 @@
   }
 }
 
-abstract class KMemberData {
+abstract class KMemberData implements interfaces.KMemberData {
+  @override
   ir.Member get node;
 
-  StaticTypeCache staticTypes;
+  StaticTypeCache? staticTypes;
 
   Iterable<ConstantValue> getMetadata(IrToElementMap elementMap);
 
-  InterfaceType getMemberThisType(JsToElementMap elementMap);
+  InterfaceType? getMemberThisType(JsToElementMap elementMap);
 
   ClassTypeVariableAccess get classTypeVariableAccess;
 
   /// Convert this [KMemberData] to the corresponding [JMemberData].
+  @override
   JMemberData convert();
 }
 
@@ -607,24 +585,25 @@
   @override
   final ir.Member node;
 
-  Iterable<ConstantValue> _metadata;
+  Iterable<ConstantValue>? _metadata;
 
   @override
-  StaticTypeCache staticTypes;
+  StaticTypeCache? staticTypes;
 
   KMemberDataImpl(this.node);
 
   @override
-  Iterable<ConstantValue> getMetadata(covariant KernelToElementMap elementMap) {
+  Iterable<ConstantValue> getMetadata(
+      covariant KernelToElementMapForEnv elementMap) {
     return _metadata ??= elementMap.getMetadata(
         ir.StaticTypeContext(node, elementMap.typeEnvironment),
         node.annotations);
   }
 
   @override
-  InterfaceType getMemberThisType(JsToElementMap elementMap) {
+  InterfaceType? getMemberThisType(JsToElementMap elementMap) {
     MemberEntity member = elementMap.getMember(node);
-    ClassEntity cls = member.enclosingClass;
+    ClassEntity? cls = member.enclosingClass;
     if (cls != null) {
       return elementMap.elementEnvironment.getThisType(cls);
     }
@@ -638,21 +617,21 @@
   List<TypeVariableType> getFunctionTypeVariables(IrToElementMap elementMap);
 
   void forEachParameter(JsToElementMap elementMap,
-      void f(DartType type, String name, ConstantValue defaultValue));
+      void f(DartType type, String? name, ConstantValue? defaultValue));
 }
 
 abstract class KFunctionDataMixin implements KFunctionData {
   ir.FunctionNode get functionNode;
-  List<TypeVariableType> _typeVariables;
+  List<TypeVariableType>? _typeVariables;
 
   @override
-  List<TypeVariableType> /*!*/ getFunctionTypeVariables(
-      covariant KernelToElementMap elementMap) {
+  List<TypeVariableType> getFunctionTypeVariables(
+      covariant KernelToElementMapForEnv elementMap) {
     if (_typeVariables == null) {
       if (functionNode.typeParameters.isEmpty) {
         _typeVariables = const <TypeVariableType>[];
       } else {
-        ir.TreeNode parent = functionNode.parent;
+        ir.TreeNode? parent = functionNode.parent;
         if (parent is ir.Constructor ||
             (parent is ir.Procedure &&
                 parent.kind == ir.ProcedureKind.Factory)) {
@@ -663,12 +642,12 @@
             return elementMap
                 .getDartType(ir.TypeParameterType(
                     typeParameter, ir.Nullability.nonNullable))
-                .withoutNullability;
+                .withoutNullability as TypeVariableType;
           }).toList();
         }
       }
     }
-    return _typeVariables;
+    return _typeVariables!;
   }
 }
 
@@ -677,23 +656,23 @@
     implements KFunctionData {
   @override
   final ir.FunctionNode functionNode;
-  FunctionType _type;
+  FunctionType? _type;
 
-  KFunctionDataImpl(ir.Member node, this.functionNode) : super(node);
+  KFunctionDataImpl(super.node, this.functionNode);
 
   @override
-  FunctionType getFunctionType(covariant KernelToElementMap elementMap) {
+  FunctionType getFunctionType(covariant KernelToElementMapForEnv elementMap) {
     return _type ??= elementMap.getFunctionType(functionNode);
   }
 
   @override
   void forEachParameter(JsToElementMap elementMap,
-      void f(DartType type, String name, ConstantValue defaultValue)) {
+      void f(DartType type, String? name, ConstantValue? defaultValue)) {
     void handleParameter(ir.VariableDeclaration parameter,
         {bool isOptional = true}) {
       DartType type = elementMap.getDartType(parameter.type);
-      String name = parameter.name;
-      ConstantValue defaultValue;
+      String? name = parameter.name;
+      ConstantValue? defaultValue;
       if (isOptional) {
         if (parameter.initializer != null) {
           defaultValue =
@@ -717,7 +696,7 @@
   @override
   FunctionData convert() {
     return FunctionDataImpl(
-        node, functionNode, RegularMemberDefinition(node), staticTypes);
+        node, functionNode, RegularMemberDefinition(node), staticTypes!);
   }
 
   @override
@@ -731,10 +710,9 @@
 
 class KConstructorDataImpl extends KFunctionDataImpl
     implements KConstructorData {
-  ConstructorBodyEntity constructorBody;
+  ConstructorBodyEntity? constructorBody;
 
-  KConstructorDataImpl(ir.Member node, ir.FunctionNode functionNode)
-      : super(node, functionNode);
+  KConstructorDataImpl(super.node, super.functionNode);
 
   @override
   JConstructorData convert() {
@@ -744,7 +722,7 @@
     } else {
       definition = RegularMemberDefinition(node);
     }
-    return JConstructorDataImpl(node, functionNode, definition, staticTypes);
+    return JConstructorDataImpl(node, functionNode, definition, staticTypes!);
   }
 
   @override
@@ -765,7 +743,7 @@
 }
 
 class KFieldDataImpl extends KMemberDataImpl implements KFieldData {
-  DartType _type;
+  DartType? _type;
 
   @override
   final bool isLateBackingField;
@@ -773,16 +751,15 @@
   @override
   final bool isLateFinalBackingField;
 
-  KFieldDataImpl(ir.Field node,
-      {/*required*/ this.isLateBackingField,
-      /*required*/ this.isLateFinalBackingField})
-      : super(node);
+  KFieldDataImpl(super.node,
+      {required this.isLateBackingField,
+      required this.isLateFinalBackingField});
 
   @override
-  ir.Field get node => super.node;
+  ir.Field get node => super.node as ir.Field;
 
   @override
-  DartType getFieldType(covariant KernelToElementMap elementMap) {
+  DartType getFieldType(covariant KernelToElementMapForEnv elementMap) {
     return _type ??= elementMap.getDartType(node.type);
   }
 
@@ -794,14 +771,15 @@
 
   @override
   JFieldData convert() {
-    return JFieldDataImpl(node, RegularMemberDefinition(node), staticTypes);
+    return JFieldDataImpl(node, RegularMemberDefinition(node), staticTypes!);
   }
 }
 
-class KTypeVariableData {
+class KTypeVariableData implements interfaces.KTypeVariableData {
+  @override
   final ir.TypeParameter node;
-  DartType _bound;
-  DartType _defaultType;
+  DartType? _bound;
+  DartType? _defaultType;
 
   KTypeVariableData(this.node);
 
@@ -810,12 +788,10 @@
   }
 
   DartType getDefaultType(IrToElementMap elementMap) {
-    // TODO(34522): Remove `?? const ir.DynamicType()` when issue 34522 is
-    // fixed.
-    return _defaultType ??=
-        elementMap.getDartType(node.defaultType ?? const ir.DynamicType());
+    return _defaultType ??= elementMap.getDartType(node.defaultType);
   }
 
+  @override
   JTypeVariableData copy() {
     return JTypeVariableData(node);
   }
diff --git a/pkg/compiler/lib/src/kernel/env_interfaces.dart b/pkg/compiler/lib/src/kernel/env_interfaces.dart
new file mode 100644
index 0000000..89bc978
--- /dev/null
+++ b/pkg/compiler/lib/src/kernel/env_interfaces.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2022, 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' as ir;
+
+import '../elements/entities.dart';
+import '../ir/element_map.dart';
+import '../js_model/env.dart';
+import '../universe/member_usage.dart';
+
+// TODO(48820): Delete once migration is complete
+abstract class KLibraryData {
+  JLibraryData convert();
+}
+
+abstract class KLibraryEnv {
+  ir.Library get library;
+  JLibraryEnv convert(IrToElementMap kElementMap,
+      Map<MemberEntity, MemberUsage> liveMemberUsage);
+}
+
+abstract class KClassData {
+  JClassData convert();
+}
+
+abstract class KClassEnv {
+  ir.Class get cls;
+
+  JClassEnv convert(
+      IrToElementMap kElementMap,
+      Map<MemberEntity, MemberUsage> liveMemberUsage,
+      LibraryEntity Function(ir.Library library) getJLibrary);
+}
+
+abstract class KMemberData {
+  ir.Member get node;
+  JMemberData convert();
+}
+
+abstract class KTypeVariableData {
+  ir.TypeParameter get node;
+  JTypeVariableData copy();
+}
+
+abstract class KProgramEnv {
+  JProgramEnv convert();
+}
diff --git a/pkg/compiler/lib/src/kernel/kelements.dart b/pkg/compiler/lib/src/kernel/kelements.dart
index b2a7409..7daaa84 100644
--- a/pkg/compiler/lib/src/kernel/kelements.dart
+++ b/pkg/compiler/lib/src/kernel/kelements.dart
@@ -111,10 +111,9 @@
   @override
   final AsyncMarker asyncMarker;
 
-  KFunction(KLibrary library, KClass enclosingClass, Name name,
+  KFunction(super.library, super.enclosingClass, super.name,
       this.parameterStructure, this.asyncMarker,
-      {bool isStatic = false, this.isExternal = false})
-      : super(library, enclosingClass, name, isStatic: isStatic);
+      {super.isStatic, this.isExternal = false});
 }
 
 abstract class KConstructor extends KFunction
@@ -152,10 +151,8 @@
 
 class KGenerativeConstructor extends KConstructor {
   KGenerativeConstructor(
-      KClass enclosingClass, Name name, ParameterStructure parameterStructure,
-      {required bool isExternal, required bool isConst})
-      : super(enclosingClass, name, parameterStructure,
-            isExternal: isExternal, isConst: isConst);
+      super.enclosingClass, super.name, super.parameterStructure,
+      {required super.isExternal, required super.isConst});
 
   @override
   bool get isFactoryConstructor => false;
@@ -169,12 +166,10 @@
   final bool isFromEnvironmentConstructor;
 
   KFactoryConstructor(
-      KClass enclosingClass, Name name, ParameterStructure parameterStructure,
-      {required bool isExternal,
-      required bool isConst,
-      required this.isFromEnvironmentConstructor})
-      : super(enclosingClass, name, parameterStructure,
-            isExternal: isExternal, isConst: isConst);
+      super.enclosingClass, super.name, super.parameterStructure,
+      {required super.isExternal,
+      required super.isConst,
+      required this.isFromEnvironmentConstructor});
 
   @override
   bool get isFactoryConstructor => true;
@@ -187,13 +182,11 @@
   @override
   final bool isAbstract;
 
-  KMethod(KLibrary library, KClass enclosingClass, Name name,
-      ParameterStructure parameterStructure, AsyncMarker asyncMarker,
-      {required bool isStatic,
-      required bool isExternal,
-      required this.isAbstract})
-      : super(library, enclosingClass, name, parameterStructure, asyncMarker,
-            isStatic: isStatic, isExternal: isExternal);
+  KMethod(super.library, super.enclosingClass, super.name,
+      super.parameterStructure, super.asyncMarker,
+      {required super.isStatic,
+      required super.isExternal,
+      required this.isAbstract});
 
   @override
   bool get isFunction => true;
@@ -206,7 +199,7 @@
   @override
   final bool isAbstract;
 
-  KGetter(KLibrary library, KClass enclosingClass, Name name,
+  KGetter(KLibrary library, KClass? enclosingClass, Name name,
       AsyncMarker asyncMarker,
       {required bool isStatic,
       required bool isExternal,
@@ -226,7 +219,7 @@
   @override
   final bool isAbstract;
 
-  KSetter(KLibrary library, KClass enclosingClass, Name name,
+  KSetter(KLibrary library, KClass? enclosingClass, Name name,
       {required bool isStatic,
       required bool isExternal,
       required this.isAbstract})
@@ -250,11 +243,10 @@
   @override
   final bool isConst;
 
-  KField(KLibrary library, KClass enclosingClass, Name name,
-      {required bool isStatic,
+  KField(super.library, super.enclosingClass, super.name,
+      {required super.isStatic,
       required this.isAssignable,
-      required this.isConst})
-      : super(library, enclosingClass, name, isStatic: isStatic);
+      required this.isConst});
 
   @override
   bool get isField => true;
diff --git a/pkg/compiler/lib/src/kernel/kernel_world.dart b/pkg/compiler/lib/src/kernel/kernel_world.dart
index 0f9ae53..554258b 100644
--- a/pkg/compiler/lib/src/kernel/kernel_world.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_world.dart
@@ -27,6 +27,7 @@
 
 /// The immutable result of the [ResolutionWorldBuilder].
 class KClosedWorld implements BuiltWorld, interfaces.KClosedWorld {
+  @override
   final KernelToElementMap elementMap;
   @override
   final KElementEnvironment elementEnvironment;
@@ -34,6 +35,8 @@
   final DartTypes dartTypes;
   @override
   final KCommonElements commonElements;
+
+  @override
   final NativeData nativeData;
   final InterceptorData interceptorData;
   @override
@@ -48,8 +51,11 @@
 
   /// Members that are written either directly or through a setter selector.
   final Iterable<MemberEntity> assignedInstanceMembers;
+
+  @override
   final KFieldAnalysis fieldAnalysis;
   final Iterable<ClassEntity> liveNativeClasses;
+  @override
   final Map<MemberEntity, MemberUsage> liveMemberUsage;
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/kernel_world_interfaces.dart b/pkg/compiler/lib/src/kernel/kernel_world_interfaces.dart
index 6bbd4ad..0447b79 100644
--- a/pkg/compiler/lib/src/kernel/kernel_world_interfaces.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_world_interfaces.dart
@@ -6,13 +6,22 @@
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../js_backend/backend_usage.dart';
+import '../js_backend/native_data.dart';
+import '../js_backend/field_analysis.dart';
 import '../world_interfaces.dart';
+import '../universe/member_usage.dart';
+import 'element_map.dart';
 
 abstract class KClosedWorld implements BuiltWorld {
+  KernelToElementMap get elementMap;
   KElementEnvironment get elementEnvironment;
 
   KCommonElements get commonElements;
 
+  NativeData get nativeData;
+
+  KFieldAnalysis get fieldAnalysis;
+
   Iterable<Local> get localFunctions;
 
   Set<FunctionEntity> get closurizedMembersWithFreeTypeVariables;
@@ -21,5 +30,7 @@
 
   BackendUsage get backendUsage;
 
+  Map<MemberEntity, MemberUsage> get liveMemberUsage;
+
   bool isMemberUsed(MemberEntity member);
 }
diff --git a/pkg/compiler/lib/src/kernel/native_basic_data.dart b/pkg/compiler/lib/src/kernel/native_basic_data.dart
index 2ea23da..85e91e8 100644
--- a/pkg/compiler/lib/src/kernel/native_basic_data.dart
+++ b/pkg/compiler/lib/src/kernel/native_basic_data.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import 'package:kernel/ast.dart' as ir;
 
 import '../common.dart';
@@ -22,30 +20,29 @@
   final IrAnnotationData annotationData;
 
   KernelAnnotationProcessor(
-      this.elementMap, this._nativeBasicDataBuilder, this.annotationData)
-      : assert(annotationData != null);
+      this.elementMap, this._nativeBasicDataBuilder, this.annotationData);
 
   void extractNativeAnnotations(LibraryEntity library) {
     KElementEnvironment elementEnvironment = elementMap.elementEnvironment;
 
     elementEnvironment.forEachClass(library, (ClassEntity cls) {
       ir.Class node = elementMap.getClassNode(cls);
-      String annotationName = annotationData.getNativeClassName(node);
+      String? annotationName = annotationData.getNativeClassName(node);
       if (annotationName != null) {
         _nativeBasicDataBuilder.setNativeClassTagInfo(cls, annotationName);
       }
     });
   }
 
-  String getJsInteropName(
+  String? getJsInteropName(
       Spannable spannable, Iterable<ConstantValue> metadata) {
     KCommonElements commonElements = elementMap.commonElements;
-    String annotationName;
+    String? annotationName;
     for (ConstantValue value in metadata) {
-      String name = readAnnotationName(commonElements.dartTypes, spannable,
-              value, commonElements.jsAnnotationClass1, defaultValue: '') ??
+      String? name = readAnnotationName(commonElements.dartTypes, spannable,
+              value, commonElements.jsAnnotationClass1!, defaultValue: '') ??
           readAnnotationName(commonElements.dartTypes, spannable, value,
-              commonElements.jsAnnotationClass2,
+              commonElements.jsAnnotationClass2!,
               defaultValue: '');
       if (annotationName == null) {
         annotationName = name;
@@ -63,13 +60,13 @@
     KElementEnvironment elementEnvironment = elementMap.elementEnvironment;
 
     ir.Library libraryNode = elementMap.getLibraryNode(library);
-    String libraryName = annotationData.getJsInteropLibraryName(libraryNode);
+    String? libraryName = annotationData.getJsInteropLibraryName(libraryNode);
     final bool isExplicitlylyJsLibrary = libraryName != null;
     bool isJsLibrary = isExplicitlylyJsLibrary;
 
     elementEnvironment.forEachLibraryMember(library, (MemberEntity member) {
       ir.Member memberNode = elementMap.getMemberNode(member);
-      String memberName = annotationData.getJsInteropMemberName(memberNode);
+      String? memberName = annotationData.getJsInteropMemberName(memberNode);
       if (member.isField) {
         if (memberName != null) {
           // TODO(34174): Disallow js-interop fields.
@@ -77,7 +74,7 @@
               member, MessageKind.JS_INTEROP_FIELD_NOT_SUPPORTED);*/
         }
       } else {
-        FunctionEntity function = member;
+        FunctionEntity function = member as FunctionEntity;
         if (function.isExternal && isExplicitlylyJsLibrary) {
           // External members of explicit js-interop library are implicitly
           // js-interop members.
@@ -100,7 +97,7 @@
 
     elementEnvironment.forEachClass(library, (ClassEntity cls) {
       ir.Class classNode = elementMap.getClassNode(cls);
-      String className = annotationData.getJsInteropClassName(classNode);
+      String? className = annotationData.getJsInteropClassName(classNode);
       if (className != null) {
         bool isAnonymous = annotationData.isAnonymousJsInteropClass(classNode);
         // TODO(johnniwinther): Report an error if the class is anonymous but
@@ -117,12 +114,12 @@
             /*reporter.reportErrorMessage(
                 member, MessageKind.IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED);*/
           } else {
-            FunctionEntity function = member;
+            FunctionEntity function = member as FunctionEntity;
             ir.Member memberNode = elementMap.getMemberNode(member);
             // Members that are not annotated and not external will result in
             // null here. For example, the default constructor which is not
             // user-specified.
-            String /*?*/ memberName =
+            String? memberName =
                 annotationData.getJsInteropMemberName(memberNode);
             if (function.isExternal) {
               memberName ??= function.name;
@@ -137,7 +134,7 @@
         });
         elementEnvironment.forEachConstructor(cls,
             (ConstructorEntity constructor) {
-          String memberName = getJsInteropName(
+          String? memberName = getJsInteropName(
               library, elementEnvironment.getMemberMetadata(constructor));
           if (constructor.isExternal) {
             // TODO(johnniwinther): It should probably be an error to have a
diff --git a/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart b/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart
index 165a67a..442d358d 100644
--- a/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart
+++ b/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import 'package:kernel/ast.dart' as ir;
 
 import '../common/elements.dart';
@@ -30,8 +28,8 @@
     if (node.function.positionalParameters.isEmpty) return false;
     ir.VariableDeclaration firstParameter =
         node.function.positionalParameters.first;
-    ir.Statement body = node.function.body;
-    ir.Expression expr;
+    ir.Statement? body = node.function.body;
+    ir.Expression? expr;
     if (body is ir.Block && body.statements.isNotEmpty) {
       ir.Block block = body;
       body = block.statements.first;
@@ -50,7 +48,7 @@
       if (arguments.positional.length == 1 &&
           arguments.named.isEmpty &&
           arguments.positional.first is ir.VariableGet) {
-        ir.VariableGet get = arguments.positional.first;
+        ir.VariableGet get = arguments.positional.first as ir.VariableGet;
         return get.variable == firstParameter;
       }
     }
@@ -63,12 +61,12 @@
   ///
   bool hasThrowingSyntax(KFunction method) {
     ir.Procedure node = elementMap.lookupProcedure(method);
-    ir.Statement body = node.function.body;
+    ir.Statement? body = node.function.body;
     if (body is ir.Block && body.statements.isNotEmpty) {
       ir.Block block = body;
       body = block.statements.first;
     }
-    ir.Expression expr;
+    ir.Expression? expr;
     if (body is ir.ReturnStatement) {
       expr = body.expression;
     } else if (body is ir.ExpressionStatement) {
@@ -79,6 +77,6 @@
 
   /// Returns the `noSuchMethod` that [method] overrides.
   FunctionEntity getSuperNoSuchMethod(FunctionEntity method) {
-    return elementMap.getSuperNoSuchMethod(method.enclosingClass);
+    return elementMap.getSuperNoSuchMethod(method.enclosingClass!);
   }
 }
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index 7b6f737..0f3f138 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -166,13 +166,8 @@
   /// and exactly one of [unusedClasses] and [registeredClasses].
   final Set<ClassEntity> _nativeClasses = {};
 
-  NativeResolutionEnqueuer(
-      CompilerOptions options,
-      ElementEnvironment elementEnvironment,
-      CommonElements commonElements,
-      DartTypes dartTypes,
-      this._nativeClassFinder)
-      : super(options, elementEnvironment, commonElements, dartTypes);
+  NativeResolutionEnqueuer(super.options, super.elementEnvironment,
+      super.commonElements, super.dartTypes, this._nativeClassFinder);
 
   Iterable<ClassEntity> get nativeClassesForTesting => _nativeClasses;
 
@@ -209,14 +204,13 @@
   final Set<ClassEntity> _doneAddSubtypes = {};
 
   NativeCodegenEnqueuer(
-      CompilerOptions options,
-      ElementEnvironment elementEnvironment,
-      CommonElements commonElements,
-      DartTypes dartTypes,
+      super.options,
+      super.elementEnvironment,
+      super.commonElements,
+      super.dartTypes,
       this._emitter,
       this._nativeClasses,
-      this._nativeData)
-      : super(options, elementEnvironment, commonElements, dartTypes);
+      this._nativeData);
 
   @override
   WorldImpact processNativeClasses(Iterable<Uri> libraries) {
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 6c8d90d..b973ebc 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -454,6 +454,9 @@
   /// The compiler is run from the build bot.
   bool testMode = false;
 
+  /// Whether to use the development type inferrer.
+  bool experimentalInferrer = false;
+
   /// Whether to trust primitive types during inference and optimizations.
   bool trustPrimitives = false;
 
@@ -685,6 +688,7 @@
       ..laxRuntimeTypeToString =
           _hasOption(options, Flags.laxRuntimeTypeToString)
       ..testMode = _hasOption(options, Flags.testMode)
+      ..experimentalInferrer = _hasOption(options, Flags.experimentalInferrer)
       ..trustPrimitives = _hasOption(options, Flags.trustPrimitives)
       ..useFrequencyNamer =
           !_hasOption(options, Flags.noFrequencyBasedMinification)
diff --git a/pkg/compiler/lib/src/phase/modular_analysis.dart b/pkg/compiler/lib/src/phase/modular_analysis.dart
index a1cf19a..4866ed9 100644
--- a/pkg/compiler/lib/src/phase/modular_analysis.dart
+++ b/pkg/compiler/lib/src/phase/modular_analysis.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 import 'package:kernel/ast.dart' as ir;
 
 import '../common.dart';
@@ -44,7 +42,7 @@
   final annotationProcessor = KernelAnnotationProcessor(
       elementMap, elementMap.nativeBasicDataBuilder, irAnnotationData);
   for (final uri in libraries) {
-    LibraryEntity library = elementMap.elementEnvironment.lookupLibrary(uri);
+    LibraryEntity library = elementMap.elementEnvironment.lookupLibrary(uri)!;
     if (maybeEnableNative(library.canonicalUri)) {
       annotationProcessor.extractNativeAnnotations(library);
     }
diff --git a/pkg/compiler/lib/src/serialization/node_indexer.dart b/pkg/compiler/lib/src/serialization/node_indexer.dart
index c01a54c..5d73404 100644
--- a/pkg/compiler/lib/src/serialization/node_indexer.dart
+++ b/pkg/compiler/lib/src/serialization/node_indexer.dart
@@ -360,8 +360,8 @@
       for (ir.Constant field in node.positional) {
         field.accept(this);
       }
-      for (ir.ConstantRecordNamedField namedField in node.named) {
-        namedField.value.accept(this);
+      for (ir.Constant field in node.named.values) {
+        field.accept(this);
       }
     }
   }
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index 667f25f..8218c11 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -2,8 +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.
 
-// @dart = 2.10
-
 library source_file_provider;
 
 import 'dart:async';
@@ -14,14 +12,13 @@
 
 import '../compiler_api.dart' as api;
 import 'colors.dart' as colors;
-import 'dart2js.dart' show AbortLeg;
 import 'io/source_file.dart';
 
 abstract class SourceFileProvider implements api.CompilerInput {
   bool isWindows = (Platform.operatingSystem == 'windows');
   Uri cwd = Uri.base;
-  Map<Uri, api.Input> utf8SourceFiles = <Uri, api.Input>{};
-  Map<Uri, api.Input> binarySourceFiles = <Uri, api.Input>{};
+  Map<Uri, SourceFile<List<int>>> utf8SourceFiles = {};
+  Map<Uri, api.Input<List<int>>> binarySourceFiles = {};
   int dartCharactersRead = 0;
 
   Future<api.Input<List<int>>> readBytesFromUri(
@@ -29,7 +26,7 @@
     if (!resourceUri.isAbsolute) {
       resourceUri = cwd.resolveUri(resourceUri);
     }
-    api.Input<List<int>> input = _loadInputFromCache(resourceUri, inputKind);
+    api.Input<List<int>>? input = _loadInputFromCache(resourceUri, inputKind);
     if (input != null) return Future.value(input);
 
     if (resourceUri.isScheme('file')) {
@@ -47,11 +44,11 @@
   /// utf8, the CFE file system may read them as binary inputs. In case the CFE
   /// needs to report errors, dart2js will only find the location data if it
   /// checks both caches.
-  api.Input<List<int>> _loadInputFromCache(
+  api.Input<List<int>>? _loadInputFromCache(
       Uri resourceUri, api.InputKind inputKind) {
     switch (inputKind) {
       case api.InputKind.UTF8:
-        var input = utf8SourceFiles[resourceUri];
+        api.Input<List<int>>? input = utf8SourceFiles[resourceUri];
         if (input != null) return input;
         input = binarySourceFiles[resourceUri];
         if (input == null) return null;
@@ -59,11 +56,10 @@
       case api.InputKind.binary:
         return binarySourceFiles[resourceUri];
     }
-    return null;
   }
 
   /// Adds [source] to the cache under the [resourceUri] key.
-  api.Input _storeSourceInCache(
+  api.Input<List<int>> _storeSourceInCache(
       Uri resourceUri, List<int> source, api.InputKind inputKind) {
     switch (inputKind) {
       case api.InputKind.UTF8:
@@ -72,7 +68,6 @@
       case api.InputKind.binary:
         return binarySourceFiles[resourceUri] = Binary(resourceUri, source);
     }
-    return null;
   }
 
   @override
@@ -85,14 +80,15 @@
     }
   }
 
-  api.Input _readFromFileSync(Uri resourceUri, api.InputKind inputKind) {
+  api.Input<List<int>> _readFromFileSync(
+      Uri resourceUri, api.InputKind inputKind) {
     assert(resourceUri.isScheme('file'));
     List<int> source;
     try {
       source = readAll(resourceUri.toFilePath(),
           zeroTerminated: inputKind == api.InputKind.UTF8);
     } on FileSystemException catch (ex) {
-      String message = ex.osError?.message;
+      String? message = ex.osError?.message;
       String detail = message != null ? ' ($message)' : '';
       throw "Error reading '${relativizeUri(resourceUri)}' $detail";
     }
@@ -102,7 +98,7 @@
 
   /// Read [resourceUri] directly as a UTF-8 file. If reading fails, `null` is
   /// returned.
-  api.Input readUtf8FromFileSyncForTesting(Uri resourceUri) {
+  api.Input<List<int>>? readUtf8FromFileSyncForTesting(Uri resourceUri) {
     try {
       return _readFromFileSync(resourceUri, api.InputKind.UTF8);
     } catch (e) {
@@ -125,18 +121,15 @@
 
   relativizeUri(Uri uri) => fe.relativizeUri(cwd, uri, isWindows);
 
-  SourceFile<List<int>> getUtf8SourceFile(Uri resourceUri) {
+  api.Input<List<int>>? getUtf8SourceFile(Uri resourceUri) {
     return _loadInputFromCache(resourceUri, api.InputKind.UTF8);
   }
 
   Iterable<Uri> getSourceUris() {
-    Set<Uri> uris = Set<Uri>();
     // Note: this includes also indirect sources that were used to create
     // `.dill` inputs to the compiler. This is OK, since this API is only
     // used to calculate DEPS for gn build systems.
-    uris.addAll(utf8SourceFiles.keys);
-    uris.addAll(binarySourceFiles.keys);
-    return uris;
+    return <Uri>{...utf8SourceFiles.keys, ...binarySourceFiles.keys};
   }
 }
 
@@ -170,16 +163,15 @@
   bool enableColors = false;
   bool throwOnError = false;
   int throwOnErrorCount = 0;
-  api.Diagnostic lastKind = null;
+  api.Diagnostic? lastKind = null;
   int fatalCount = 0;
 
   final int FATAL = api.Diagnostic.CRASH.ordinal | api.Diagnostic.ERROR.ordinal;
   final int INFO =
       api.Diagnostic.INFO.ordinal | api.Diagnostic.VERBOSE_INFO.ordinal;
 
-  FormattingDiagnosticHandler([SourceFileProvider provider])
-      : this.provider =
-            (provider == null) ? CompilerSourceFileProvider() : provider;
+  FormattingDiagnosticHandler([SourceFileProvider? provider])
+      : this.provider = provider ?? CompilerSourceFileProvider();
 
   void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) {
     if (!verbose && kind == api.Diagnostic.VERBOSE_INFO) return;
@@ -209,7 +201,7 @@
   }
 
   @override
-  void report(var code, Uri uri, int begin, int end, String message,
+  void report(var code, Uri? uri, int? begin, int? end, String message,
       api.Diagnostic kind) {
     if (isAborting) return;
     isAborting = (kind == api.Diagnostic.CRASH);
@@ -253,29 +245,41 @@
     if (uri == null) {
       print('${color(message)}');
     } else {
-      api.Input file = provider.getUtf8SourceFile(uri);
-      if (file is SourceFile) {
-        print(file.getLocationMessage(color(message), begin, end,
-            colorize: color));
+      api.Input<List<int>>? file = provider.getUtf8SourceFile(uri);
+      if (file is SourceFile && begin != null && end != null) {
+        print((file as SourceFile)
+            .getLocationMessage(color(message), begin, end, colorize: color));
       } else {
-        String position = end - begin > 0 ? '@$begin+${end - begin}' : '';
+        String position = begin != null && end != null && end - begin > 0
+            ? '@$begin+${end - begin}'
+            : '';
         print('${provider.relativizeUri(uri)}$position:\n'
             '${color(message)}');
       }
     }
     if (fatal && ++fatalCount >= throwOnErrorCount && throwOnError) {
       isAborting = true;
-      throw AbortLeg(message);
+      throw _CompilationErrorError(message);
     }
   }
 }
 
+class _CompilationErrorError {
+  final message;
+  _CompilationErrorError(this.message);
+  @override
+  toString() => 'Aborted due to --throw-on-error: $message';
+}
+
 typedef MessageCallback = void Function(String message);
 
 class RandomAccessFileOutputProvider implements api.CompilerOutput {
   final Uri out;
   final Uri sourceMapOut;
   final MessageCallback onInfo;
+
+  // TODO(48820): Make [onFailure] return `Never`. The value passed in for the
+  // real compiler exits. [onFailure] is not specified or faked in some tests.
   final MessageCallback onFailure;
 
   int totalCharactersWritten = 0;
@@ -286,7 +290,9 @@
   List<String> allOutputFiles = <String>[];
 
   RandomAccessFileOutputProvider(this.out, this.sourceMapOut,
-      {this.onInfo, this.onFailure});
+      {this.onInfo = _ignore, this.onFailure = _ignore});
+
+  static void _ignore(String message) {}
 
   Uri createUri(String name, String extension, api.OutputType type) {
     Uri uri;
@@ -330,6 +336,7 @@
         break;
       default:
         onFailure('Unknown output type: $type');
+        throw StateError('unreachable');
     }
     return uri;
   }
@@ -350,6 +357,8 @@
           .openSync(mode: FileMode.write);
     } on FileSystemException catch (e) {
       onFailure('$e');
+      // TODO(48820): Make onFailure return `Never`
+      throw StateError('unreachable');
     }
 
     allOutputFiles.add(fe.relativizeUri(Uri.base, uri, Platform.isWindows));
@@ -414,11 +423,13 @@
           .openSync(mode: FileMode.write);
     } on FileSystemException catch (e) {
       onFailure('$e');
+      // TODO(48820): Make `onFailure` return `Never`.
+      throw StateError('unreachable');
     }
 
     int bytesWritten = 0;
 
-    void writeBytesSync(List<int> data, [int start = 0, int end]) {
+    void writeBytesSync(List<int> data, [int start = 0, int? end]) {
       output.writeFromSync(data, start, end);
       bytesWritten += (end ?? data.length) - start;
     }
@@ -439,7 +450,7 @@
       : output = File.fromUri(uri).openSync(mode: FileMode.write);
 
   @override
-  void write(List<int> buffer, [int start = 0, int end]) {
+  void write(List<int> buffer, [int start = 0, int? end]) {
     output.writeFromSync(buffer, start, end);
   }
 
@@ -463,13 +474,13 @@
 }
 
 class _BinaryOutputSinkWrapper extends api.BinaryOutputSink {
-  void Function(List<int>, [int, int]) onWrite;
+  void Function(List<int>, [int, int?]) onWrite;
   void Function() onClose;
 
   _BinaryOutputSinkWrapper(this.onWrite, this.onClose);
 
   @override
-  void write(List<int> data, [int start = 0, int end]) =>
+  void write(List<int> data, [int start = 0, int? end]) =>
       onWrite(data, start, end);
 
   @override
@@ -543,10 +554,10 @@
       }
       switch (inputKind) {
         case api.InputKind.UTF8:
-          utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri];
+          utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri]!;
           break;
         case api.InputKind.binary:
-          binarySourceFiles[uri] = binarySourceFiles[resolvedUri];
+          binarySourceFiles[uri] = binarySourceFiles[resolvedUri]!;
           break;
       }
     }
@@ -590,10 +601,10 @@
         await readBytesFromUri(resolvedUri, inputKind);
     switch (inputKind) {
       case api.InputKind.UTF8:
-        utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri];
+        utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri]!;
         break;
       case api.InputKind.binary:
-        binarySourceFiles[uri] = binarySourceFiles[resolvedUri];
+        binarySourceFiles[uri] = binarySourceFiles[resolvedUri]!;
         break;
     }
     return result;
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index 7adc686..b44a53f 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -9,7 +9,7 @@
 import '../inferrer/abstract_value_domain.dart';
 import '../options.dart';
 import '../universe/selector.dart' show Selector;
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 import 'codegen.dart' show CodegenPhase;
 import 'nodes.dart';
 
diff --git a/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart b/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart
index 45e2c3b..5135652 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart
@@ -9,7 +9,7 @@
 import '../inferrer/abstract_value_domain.dart';
 import '../js_backend/interceptor_data.dart';
 import '../universe/selector.dart' show Selector;
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 import 'nodes.dart';
 import 'optimize.dart';
 
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index 030d794..e8817f5 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -10,7 +10,7 @@
 import '../inferrer/abstract_value_domain.dart';
 import '../js_backend/interceptor_data.dart';
 import '../universe/selector.dart' show Selector;
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 import 'nodes.dart';
 import 'optimize.dart';
 
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index 3e1c039..217ca44 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -12,7 +12,7 @@
 import '../inferrer/abstract_value_domain.dart';
 import '../inferrer/types.dart';
 import '../universe/selector.dart';
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 import 'logging.dart';
 import 'nodes.dart';
 import 'types.dart';
diff --git a/pkg/compiler/lib/src/ssa/locals_handler.dart b/pkg/compiler/lib/src/ssa/locals_handler.dart
index 295aaac..ca2fe43 100644
--- a/pkg/compiler/lib/src/ssa/locals_handler.dart
+++ b/pkg/compiler/lib/src/ssa/locals_handler.dart
@@ -17,7 +17,7 @@
 import '../js_backend/interceptor_data.dart';
 import '../js_model/closure.dart' show JRecordField, JClosureField;
 import '../js_model/locals.dart' show GlobalLocalsMap, JLocal;
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 
 import 'builder.dart';
 import 'nodes.dart';
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 50b2f2e..5b63bf1 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -26,7 +26,7 @@
 import '../universe/selector.dart' show Selector;
 import '../universe/side_effects.dart' show SideEffects;
 import '../util/util.dart';
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 import 'invoke_dynamic_specializers.dart';
 import 'validate.dart';
 
diff --git a/pkg/compiler/lib/src/ssa/tracer.dart b/pkg/compiler/lib/src/ssa/tracer.dart
index 5f7a465..397eab6 100644
--- a/pkg/compiler/lib/src/ssa/tracer.dart
+++ b/pkg/compiler/lib/src/ssa/tracer.dart
@@ -11,7 +11,7 @@
 import '../inferrer/abstract_value_domain.dart';
 import '../js_backend/namer.dart' show suffixForGetInterceptor;
 import '../tracer.dart';
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 import 'nodes.dart';
 
 /// Outputs SSA code in a format readable by Hydra IR.
diff --git a/pkg/compiler/lib/src/ssa/types.dart b/pkg/compiler/lib/src/ssa/types.dart
index afcca37..b060791 100644
--- a/pkg/compiler/lib/src/ssa/types.dart
+++ b/pkg/compiler/lib/src/ssa/types.dart
@@ -11,7 +11,7 @@
 import '../inferrer/types.dart';
 import '../native/behavior.dart';
 import '../universe/selector.dart' show Selector;
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 
 class AbstractValueFactory {
   static AbstractValue inferredReturnTypeForElement(
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 1ddc6f2..9874e20 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -10,7 +10,7 @@
 import '../inferrer/abstract_value_domain.dart';
 import '../inferrer/types.dart';
 import '../universe/selector.dart' show Selector;
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 import 'logging.dart';
 import 'nodes.dart';
 import 'optimize.dart';
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index d947b06..709df80 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -6,7 +6,7 @@
 
 import '../constants/constant_system.dart' as constant_system;
 import '../constants/values.dart';
-import '../world.dart' show JClosedWorld;
+import '../world_interfaces.dart' show JClosedWorld;
 import 'nodes.dart';
 import 'optimize.dart';
 
diff --git a/pkg/compiler/lib/src/universe/member_usage.dart b/pkg/compiler/lib/src/universe/member_usage.dart
index 558f8ac..d9321e7 100644
--- a/pkg/compiler/lib/src/universe/member_usage.dart
+++ b/pkg/compiler/lib/src/universe/member_usage.dart
@@ -278,7 +278,7 @@
   @override
   final EnumSet<Access> invokes;
 
-  PropertyUsage.cloned(MemberEntity member, EnumSet<MemberUse> pendingUse,
+  PropertyUsage.cloned(super.member, super.pendingUse,
       {required this.potentialReads,
       required this.potentialWrites,
       required this.potentialInvokes,
@@ -292,9 +292,9 @@
         assert((reads as dynamic) != null),
         assert((writes as dynamic) != null),
         assert((invokes as dynamic) != null),
-        super.cloned(member, pendingUse);
+        super.cloned();
 
-  PropertyUsage(MemberEntity member,
+  PropertyUsage(super.member,
       {required this.potentialReads,
       required this.potentialWrites,
       required this.potentialInvokes})
@@ -305,7 +305,7 @@
         assert((potentialReads as dynamic) != null),
         assert((potentialWrites as dynamic) != null),
         assert((potentialInvokes as dynamic) != null),
-        super.internal(member);
+        super.internal();
 
   @override
   EnumSet<MemberUse> read(EnumSet<Access> accesses) {
@@ -390,7 +390,7 @@
 
   List<ConstantValue>? _initialConstants;
 
-  FieldUsage.cloned(FieldEntity field, EnumSet<MemberUse> pendingUse,
+  FieldUsage.cloned(FieldEntity super.field, super.pendingUse,
       {required this.potentialReads,
       required this.potentialWrites,
       required this.potentialInvokes,
@@ -405,9 +405,9 @@
         assert((reads as dynamic) != null),
         assert((writes as dynamic) != null),
         assert((invokes as dynamic) != null),
-        super.cloned(field, pendingUse);
+        super.cloned();
 
-  FieldUsage(FieldEntity field,
+  FieldUsage(FieldEntity super.field,
       {required this.potentialReads,
       required this.potentialWrites,
       required this.potentialInvokes})
@@ -419,7 +419,7 @@
         assert((potentialReads as dynamic) != null),
         assert((potentialWrites as dynamic) != null),
         assert((potentialInvokes as dynamic) != null),
-        super.internal(field);
+        super.internal();
 
   @override
   Iterable<ConstantValue> get initialConstants => _initialConstants ?? const [];
@@ -532,14 +532,14 @@
         assert((invokes as dynamic) != null),
         super.cloned(function, pendingUse);
 
-  MethodUsage(FunctionEntity function,
+  MethodUsage(FunctionEntity super.function,
       {required this.potentialReads, required this.potentialInvokes})
       : reads = EnumSet(),
         invokes = EnumSet(),
         parameterUsage = ParameterUsage(function.parameterStructure),
         assert((potentialReads as dynamic) != null),
         assert((potentialInvokes as dynamic) != null),
-        super.internal(function);
+        super.internal();
 
   @override
   bool get hasInvoke => invokes.isNotEmpty && parameterUsage.hasInvoke;
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index a7aa234..e75bed4 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -25,7 +25,7 @@
 import '../options.dart';
 import '../util/enumset.dart';
 import '../util/util.dart';
-import '../world.dart' show World;
+import '../world_interfaces.dart' show World;
 import 'call_structure.dart';
 import 'class_hierarchy.dart' show ClassHierarchyBuilder;
 import 'class_set.dart';
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index fb60943..0bda473 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -52,7 +52,7 @@
             "${selector.callStructure.typeArgumentCount} but "
             "${_typeArguments?.length ?? 0} were passed.");
 
-  DynamicUse withReceiverConstraint(Object otherReceiverConstraint) {
+  DynamicUse withReceiverConstraint(Object? otherReceiverConstraint) {
     if (otherReceiverConstraint == receiverConstraint) {
       return this;
     }
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 9c400e0..b7b9e0b 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -46,6 +46,7 @@
   @override
   NativeData get nativeData;
 
+  @override
   InterceptorData get interceptorData;
 
   @override
@@ -69,6 +70,9 @@
 
   Iterable<MemberEntity> get processedMembers;
 
+  @override
+  Iterable<MemberEntity> get liveInstanceMembers;
+
   /// Returns the set of interfaces passed as type arguments to the internal
   /// `extractTypeArguments` function.
   Set<ClassEntity> get extractTypeArgumentsInterfacesNewRti;
@@ -79,30 +83,37 @@
   @override
   AnnotationsData get annotationsData;
 
+  @override
   ClosureData get closureDataLookup;
 
+  @override
   OutputUnitData get outputUnitData;
 
   /// The [Sorter] used for sorting elements in the generated code.
   Sorter get sorter;
 
   /// Returns `true` if [cls] is implemented by an instantiated class.
+  @override
   bool isImplemented(ClassEntity cls);
 
   /// Returns the most specific subclass of [cls] (including [cls]) that is
   /// directly instantiated or a superclass of all directly instantiated
   /// subclasses. If [cls] is not instantiated, `null` is returned.
+  @override
   ClassEntity getLubOfInstantiatedSubclasses(ClassEntity cls);
 
   /// Returns the most specific subtype of [cls] (including [cls]) that is
   /// directly instantiated or a superclass of all directly instantiated
   /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned.
+  @override
   ClassEntity getLubOfInstantiatedSubtypes(ClassEntity cls);
 
   /// Returns an iterable over the common supertypes of the [classes].
+  @override
   Iterable<ClassEntity> commonSupertypesOf(Iterable<ClassEntity> classes);
 
   /// Returns an iterable over the live mixin applications that mixin [cls].
+  @override
   Iterable<ClassEntity> mixinUsesOf(ClassEntity cls);
 
   /// Returns `true` if [cls] is mixed into a live class.
@@ -110,21 +121,26 @@
   bool isUsedAsMixin(ClassEntity cls);
 
   /// Returns `true` if any live class that mixes in [cls] implements [type].
+  @override
   bool hasAnySubclassOfMixinUseThatImplements(
       ClassEntity cls, ClassEntity type);
 
   /// Returns `true` if any live class that mixes in [mixin] is also a subclass
   /// of [superclass].
+  @override
   bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin);
 
   /// Returns `true` if [cls] or any superclass mixes in [mixin].
+  @override
   bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin);
 
   /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass
   /// of a mixin application of [y].
+  @override
   bool everySubtypeIsSubclassOfOrMixinUseOf(ClassEntity x, ClassEntity y);
 
   /// Returns `true` if any subclass of [superclass] implements [type].
+  @override
   bool hasAnySubclassThatImplements(ClassEntity superclass, ClassEntity type);
 
   /// Returns `true` if a call of [selector] on [cls] and/or subclasses/subtypes
@@ -166,11 +182,13 @@
   ///
   /// If we're calling bar on an object of type A we do need the handler because
   /// we may have to call B.noSuchMethod since B does not implement bar.
+  @override
   bool needsNoSuchMethod(ClassEntity cls, Selector selector, ClassQuery query);
 
   /// Returns whether [element] will be the one used at runtime when being
   /// invoked on an instance of [cls]. [name] is used to ensure library
   /// privacy is taken into account.
+  @override
   bool hasElementIn(ClassEntity cls, Name name, MemberEntity element);
 
   /// Returns `true` if the field [element] is known to be effectively final.
@@ -183,6 +201,7 @@
   /// Every implementation of `Closure` has a 'call' method with its own
   /// signature so it cannot be modelled by a [FunctionEntity]. Also,
   /// call-methods for tear-off are not part of the element model.
+  @override
   bool includesClosureCallInDomain(Selector selector, AbstractValue receiver,
       AbstractValueDomain abstractValueDomain);
 
@@ -208,6 +227,7 @@
   /// on the given [receiver] using the [abstractValueDomain]. The returned elements may include noSuchMethod
   /// handlers that are potential targets indirectly through the noSuchMethod
   /// mechanism.
+  @override
   Iterable<MemberEntity> locateMembersInDomain(Selector selector,
       AbstractValue receiver, AbstractValueDomain abstractValueDomain);
 
diff --git a/pkg/compiler/lib/src/world_interfaces.dart b/pkg/compiler/lib/src/world_interfaces.dart
index fadcbce..eae1660 100644
--- a/pkg/compiler/lib/src/world_interfaces.dart
+++ b/pkg/compiler/lib/src/world_interfaces.dart
@@ -2,12 +2,19 @@
 // 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:compiler/src/js_model/element_map_interfaces.dart';
+
+import 'closure.dart';
+import 'package:kernel/ast.dart' as ir;
 import 'common/elements.dart';
+import 'deferred_load/output_unit.dart' show OutputUnitData;
 import 'elements/entities.dart';
+import 'elements/names.dart';
 import 'elements/types.dart';
 import 'inferrer/abstract_value_domain.dart';
 import 'js_backend/annotations.dart';
 import 'js_backend/native_data.dart';
+import 'js_backend/interceptor_data.dart';
 import 'universe/class_hierarchy.dart';
 import 'universe/selector.dart';
 
@@ -29,6 +36,16 @@
 
   AnnotationsData get annotationsData;
 
+  ClosureData get closureDataLookup;
+
+  OutputUnitData get outputUnitData;
+
+  InterceptorData get interceptorData;
+
+  Iterable<MemberEntity> get liveInstanceMembers;
+
+  JsToElementMap get elementMap;
+
   bool isUsedAsMixin(ClassEntity cls);
 
   bool includesClosureCall(Selector selector, AbstractValue? receiver);
@@ -37,6 +54,39 @@
       Selector selector, AbstractValue? receiver);
 
   bool fieldNeverChanges(MemberEntity element);
+
+  Selector getSelector(ir.Expression node);
+
+  Iterable<ClassEntity> mixinUsesOf(ClassEntity cls);
+
+  bool isImplemented(ClassEntity cls);
+
+  Iterable<ClassEntity> commonSupertypesOf(Iterable<ClassEntity> classes);
+
+  bool hasElementIn(ClassEntity cls, Name name, MemberEntity element);
+
+  bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin);
+
+  bool hasAnySubclassThatImplements(ClassEntity superclass, ClassEntity type);
+
+  bool hasAnySubclassOfMixinUseThatImplements(
+      ClassEntity cls, ClassEntity type);
+
+  bool needsNoSuchMethod(ClassEntity cls, Selector selector, ClassQuery query);
+
+  bool includesClosureCallInDomain(Selector selector, AbstractValue receiver,
+      AbstractValueDomain abstractValueDomain);
+
+  Iterable<MemberEntity> locateMembersInDomain(Selector selector,
+      AbstractValue receiver, AbstractValueDomain abstractValueDomain);
+
+  bool everySubtypeIsSubclassOfOrMixinUseOf(ClassEntity x, ClassEntity y);
+
+  bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin);
+
+  ClassEntity? getLubOfInstantiatedSubtypes(ClassEntity cls);
+
+  ClassEntity? getLubOfInstantiatedSubclasses(ClassEntity cls);
 }
 
 // TODO(48820): Move back to `world.dart` when migrated.
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index d25829f..c4e9fa3 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -4,7 +4,7 @@
 # This package is not intended for consumption on pub.dev. DO NOT publish.
 publish_to: none
 environment:
-  sdk: '>=2.16.0 <3.0.0'
+  sdk: '>=2.17.0 <3.0.0'
 
 # Use 'any' constraints here; we get our versions from the DEPS file.
 dependencies:
diff --git a/pkg/compiler/test/analyses/api_allowed.json b/pkg/compiler/test/analyses/api_allowed.json
index 34db685..55e3010 100644
--- a/pkg/compiler/test/analyses/api_allowed.json
+++ b/pkg/compiler/test/analyses/api_allowed.json
@@ -27,53 +27,19 @@
     "Dynamic invocation of 'toJson'.": 1
   },
   "org-dartlang-sdk:///lib/html/dart2js/html_dart2js.dart": {
-    "Dynamic access of 'style'.": 1,
     "Dynamic invocation of 'call'.": 2,
-    "Dynamic invocation of 'dart.dom.html::_initKeyboardEvent'.": 1,
     "Dynamic access of 'attributes'.": 1,
     "Dynamic invocation of '[]'.": 1,
-    "Dynamic invocation of 'toLowerCase'.": 1,
-    "Dynamic invocation of 'attached'.": 1,
-    "Dynamic invocation of 'detached'.": 1,
-    "Dynamic invocation of 'attributeChanged'.": 1,
-    "Dynamic invocation of 'createElement'.": 1
-  },
-  "org-dartlang-sdk:///lib/html/html_common/conversions.dart": {
-    "Dynamic invocation of '[]='.": 1
-  },
-  "org-dartlang-sdk:///lib/io/directory_impl.dart": {
-    "Dynamic invocation of '[]'.": 10
-  },
-  "org-dartlang-sdk:///lib/io/file_impl.dart": {
-    "Dynamic invocation of '[]'.": 4,
-    "Dynamic access of 'length'.": 2
-  },
-  "org-dartlang-sdk:///lib/io/file_system_entity.dart": {
-    "Dynamic invocation of '[]'.": 7
-  },
-  "org-dartlang-sdk:///lib/io/io_resource_info.dart": {
-    "Dynamic invocation of '[]'.": 1,
-    "Dynamic access of 'path'.": 1,
-    "Dynamic access of 'dart.io::_path'.": 1,
-    "Dynamic access of 'pid'.": 1,
-    "Dynamic access of 'dart.io::_arguments'.": 1,
-    "Dynamic access of 'dart.io::_workingDirectory'.": 2
-  },
-  "org-dartlang-sdk:///lib/io/link.dart": {
-    "Dynamic invocation of '[]'.": 3
+    "Dynamic invocation of 'toLowerCase'.": 1
   },
   "org-dartlang-sdk:///lib/io/secure_server_socket.dart": {
     "Dynamic update to 'dart.io::_owner'.": 1
   },
   "org-dartlang-sdk:///lib/io/secure_socket.dart": {
-    "Dynamic invocation of '[]'.": 10,
+    "Dynamic invocation of '[]'.": 4,
     "Dynamic invocation of 'dart.io::_detachRaw'.": 2,
     "Dynamic access of 'closedReadEventSent'.": 1,
-    "Dynamic update to 'dart.io::_owner'.": 1,
-    "Dynamic access of 'length'.": 1
-  },
-  "org-dartlang-sdk:///lib/io/common.dart": {
-    "Dynamic invocation of '[]'.": 3
+    "Dynamic update to 'dart.io::_owner'.": 1
   },
   "org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_patch.dart": {
     "Dynamic invocation of '[]'.": 1
diff --git a/pkg/compiler/test/analyses/dart2js_allowed.json b/pkg/compiler/test/analyses/dart2js_allowed.json
index ad4ddfd..4cb5076 100644
--- a/pkg/compiler/test/analyses/dart2js_allowed.json
+++ b/pkg/compiler/test/analyses/dart2js_allowed.json
@@ -19,29 +19,16 @@
     "Dynamic invocation of '~/'.": 1
   },
   "pkg/compiler/lib/src/dart2js.dart": {
-    "Dynamic invocation of 'call'.": 1,
-    "Dynamic invocation of 'pause'.": 1,
-    "Dynamic invocation of 'resume'.": 1
+    "Dynamic invocation of 'call'.": 1
   },
   "pkg/compiler/lib/src/deferred_load/deferred_load.dart": {
     "Dynamic access of 'memberContext'.": 1,
     "Dynamic access of 'name'.": 1
   },
-  "pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart": {
-    "Dynamic access of 'forwardTo'.": 1,
-    "Dynamic access of 'isForwarding'.": 1
-  },
   "pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart": {
     "Dynamic invocation of '[]='.": 1,
     "Dynamic invocation of 'add'.": 1
   },
-  "pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart": {
-    "Dynamic access of 'needsTearOff'.": 1,
-    "Dynamic access of 'superclass'.": 1
-  },
-  "pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart": {
-    "Dynamic invocation of '[]='.": 1
-  },
   "pkg/compiler/lib/src/serialization/binary_sink.dart": {
     "Dynamic access of 'index'.": 1
   },
diff --git a/samples-dev/OWNERS b/pkg/compiler/test/codesize/OWNERS
similarity index 100%
rename from samples-dev/OWNERS
rename to pkg/compiler/test/codesize/OWNERS
diff --git a/samples-dev/swarm/App.dart b/pkg/compiler/test/codesize/swarm/App.dart
similarity index 100%
rename from samples-dev/swarm/App.dart
rename to pkg/compiler/test/codesize/swarm/App.dart
diff --git a/samples-dev/swarm/BiIterator.dart b/pkg/compiler/test/codesize/swarm/BiIterator.dart
similarity index 100%
rename from samples-dev/swarm/BiIterator.dart
rename to pkg/compiler/test/codesize/swarm/BiIterator.dart
diff --git a/samples-dev/swarm/CSS.dart b/pkg/compiler/test/codesize/swarm/CSS.dart
similarity index 100%
rename from samples-dev/swarm/CSS.dart
rename to pkg/compiler/test/codesize/swarm/CSS.dart
diff --git a/samples-dev/swarm/CannedData.dart b/pkg/compiler/test/codesize/swarm/CannedData.dart
similarity index 100%
rename from samples-dev/swarm/CannedData.dart
rename to pkg/compiler/test/codesize/swarm/CannedData.dart
diff --git a/samples-dev/swarm/ConfigHintDialog.dart b/pkg/compiler/test/codesize/swarm/ConfigHintDialog.dart
similarity index 100%
rename from samples-dev/swarm/ConfigHintDialog.dart
rename to pkg/compiler/test/codesize/swarm/ConfigHintDialog.dart
diff --git a/samples-dev/swarm/Dart_Logo_21.png b/pkg/compiler/test/codesize/swarm/Dart_Logo_21.png
similarity index 100%
rename from samples-dev/swarm/Dart_Logo_21.png
rename to pkg/compiler/test/codesize/swarm/Dart_Logo_21.png
Binary files differ
diff --git a/samples-dev/swarm/DataSource.dart b/pkg/compiler/test/codesize/swarm/DataSource.dart
similarity index 95%
rename from samples-dev/swarm/DataSource.dart
rename to pkg/compiler/test/codesize/swarm/DataSource.dart
index a181de3..3a1118d 100644
--- a/samples-dev/swarm/DataSource.dart
+++ b/pkg/compiler/test/codesize/swarm/DataSource.dart
@@ -4,7 +4,6 @@
 
 // @dart = 2.9
 
-
 part of swarmlib;
 
 /// The top-level collection of all sections for a user. */
@@ -47,7 +46,8 @@
   }
 
   // This method is exposed for tests.
-  static void initializeFromData(String data, void Function(Sections sects) callback) {
+  static void initializeFromData(
+      String data, void Function(Sections sects) callback) {
     final decoder = Decoder(data);
     int nSections = decoder.readInt();
     final sections = <Section>[];
@@ -64,8 +64,7 @@
       initializeFromData(CannedData.data['user.data'], callback);
     } else {
       // TODO(jmesserly): display an error if we fail here! Silent failure bad.
-      HttpRequest
-          .getString('data/user.data')
+      HttpRequest.getString('data/user.data')
           .then(EventBatch.wrap((responseText) {
         // TODO(jimhug): Nice response if get error back from server.
         // TODO(jimhug): Might be more efficient to parse request
@@ -188,8 +187,7 @@
   }
 
   String get dataUri {
-    return SwarmUri
-        .encodeComponent(id)
+    return SwarmUri.encodeComponent(id)
         .replaceAll('%2F', '/')
         .replaceAll('%253A', '%3A');
   }
@@ -235,8 +233,8 @@
     final author = decoder.readString();
     final dateInSeconds = decoder.readInt();
     final snippet = decoder.readString();
-    final date = DateTime.fromMillisecondsSinceEpoch(dateInSeconds * 1000,
-        isUtc: true);
+    final date =
+        DateTime.fromMillisecondsSinceEpoch(dateInSeconds * 1000, isUtc: true);
     return Article(
         source, id, date, title, author, srcUrl, hasThumbnail, snippet);
   }
diff --git a/samples-dev/swarm/Decoder.dart b/pkg/compiler/test/codesize/swarm/Decoder.dart
similarity index 100%
rename from samples-dev/swarm/Decoder.dart
rename to pkg/compiler/test/codesize/swarm/Decoder.dart
diff --git a/samples-dev/swarm/HelpDialog.dart b/pkg/compiler/test/codesize/swarm/HelpDialog.dart
similarity index 100%
rename from samples-dev/swarm/HelpDialog.dart
rename to pkg/compiler/test/codesize/swarm/HelpDialog.dart
diff --git a/pkg/compiler/test/codesize/swarm/README b/pkg/compiler/test/codesize/swarm/README
index 9574d64..785e629 100644
--- a/pkg/compiler/test/codesize/swarm/README
+++ b/pkg/compiler/test/codesize/swarm/README
@@ -4,6 +4,31 @@
 
 A sample news reader application.
 
-This is not a customer facing sample app, and is only being retained
+**NOTE**: This is not a customer facing sample app, and is only being retained
 to continue testing JS code size.
 
+Running in the Editor with demo data (demo only, no feeds):
+
+1. open the Dart Editor
+
+2. from the menu, click File / Open Folder and load this directory
+
+3. click the green run button
+
+4. alternatively, to run as javascript:
+  - compile (under the Tools / Generate JavaScript menu option)
+  - load the same url shown in Dartium in step 3 in any other browser
+
+Running in Dartium from the file system (demo only, no feeds):
+
+1. run the Dartium Chrome binary from the command line with the following flag: --allow-file-access-from-files
+
+2. navigate to the swarm.html file in this directory
+
+Running from App Engine (TODO: these are stale instructions):
+
+1. To run on App Engine, install the App Engine SDK for your platform, then
+  $ easy_install --upgrade google-api-python-client per http://code.google.com/p/google-api-python-client/wiki/Installation
+  $ cd samples/swarm/appengine
+  $ enable-app-engine-project . per http://code.google.com/p/google-api-python-client/wiki/GoogleAppEngine
+  Start the App Engine dev server and browse to /swarm-js.html
diff --git a/samples-dev/swarm/SwarmApp.dart b/pkg/compiler/test/codesize/swarm/SwarmApp.dart
similarity index 100%
rename from samples-dev/swarm/SwarmApp.dart
rename to pkg/compiler/test/codesize/swarm/SwarmApp.dart
diff --git a/samples-dev/swarm/SwarmState.dart b/pkg/compiler/test/codesize/swarm/SwarmState.dart
similarity index 100%
rename from samples-dev/swarm/SwarmState.dart
rename to pkg/compiler/test/codesize/swarm/SwarmState.dart
diff --git a/samples-dev/swarm/SwarmViews.dart b/pkg/compiler/test/codesize/swarm/SwarmViews.dart
similarity index 100%
rename from samples-dev/swarm/SwarmViews.dart
rename to pkg/compiler/test/codesize/swarm/SwarmViews.dart
diff --git a/samples-dev/swarm/UIState.dart b/pkg/compiler/test/codesize/swarm/UIState.dart
similarity index 100%
rename from samples-dev/swarm/UIState.dart
rename to pkg/compiler/test/codesize/swarm/UIState.dart
diff --git a/samples-dev/swarm/Views.dart b/pkg/compiler/test/codesize/swarm/Views.dart
similarity index 100%
rename from samples-dev/swarm/Views.dart
rename to pkg/compiler/test/codesize/swarm/Views.dart
diff --git a/pkg/compiler/test/codesize/swarm/analysis_options.yaml b/pkg/compiler/test/codesize/swarm/analysis_options.yaml
new file mode 100644
index 0000000..08f0661
--- /dev/null
+++ b/pkg/compiler/test/codesize/swarm/analysis_options.yaml
@@ -0,0 +1,14 @@
+# Copyright (c) 2017, 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.
+
+analyzer:
+  errors:
+    todo: ignore
+    deprecated_member_use: ignore
+    unused_local_variable: ignore
+    unused_field: ignore
+    unused_element: ignore
+    missing_return: ignore
+    unnecessary_null_comparison: ignore
+    undefined_shown_name: ignore
diff --git a/samples-dev/swarm/appengine/app.yaml b/pkg/compiler/test/codesize/swarm/appengine/app.yaml
similarity index 100%
rename from samples-dev/swarm/appengine/app.yaml
rename to pkg/compiler/test/codesize/swarm/appengine/app.yaml
diff --git a/samples-dev/swarm/appengine/cron.yaml b/pkg/compiler/test/codesize/swarm/appengine/cron.yaml
similarity index 100%
rename from samples-dev/swarm/appengine/cron.yaml
rename to pkg/compiler/test/codesize/swarm/appengine/cron.yaml
diff --git a/samples-dev/swarm/appengine/dev.html b/pkg/compiler/test/codesize/swarm/appengine/dev.html
similarity index 100%
rename from samples-dev/swarm/appengine/dev.html
rename to pkg/compiler/test/codesize/swarm/appengine/dev.html
diff --git a/samples-dev/swarm/appengine/encoder.py b/pkg/compiler/test/codesize/swarm/appengine/encoder.py
similarity index 100%
rename from samples-dev/swarm/appengine/encoder.py
rename to pkg/compiler/test/codesize/swarm/appengine/encoder.py
diff --git a/samples-dev/swarm/appengine/index.yaml b/pkg/compiler/test/codesize/swarm/appengine/index.yaml
similarity index 100%
rename from samples-dev/swarm/appengine/index.yaml
rename to pkg/compiler/test/codesize/swarm/appengine/index.yaml
diff --git a/samples-dev/swarm/appengine/login.html b/pkg/compiler/test/codesize/swarm/appengine/login.html
similarity index 100%
rename from samples-dev/swarm/appengine/login.html
rename to pkg/compiler/test/codesize/swarm/appengine/login.html
diff --git a/samples-dev/swarm/appengine/main.py b/pkg/compiler/test/codesize/swarm/appengine/main.py
similarity index 96%
rename from samples-dev/swarm/appengine/main.py
rename to pkg/compiler/test/codesize/swarm/appengine/main.py
index 4216fe8..28f4a9d 100644
--- a/samples-dev/swarm/appengine/main.py
+++ b/pkg/compiler/test/codesize/swarm/appengine/main.py
@@ -212,8 +212,9 @@
         if html.compressed:
             # TODO(jimhug): This slightly sucks ;-)
             # Can we write directly to the response.out?
-            gz = gzip.GzipFile(
-                name, 'rb', fileobj=StringIO.StringIO(html.content))
+            gz = gzip.GzipFile(name,
+                               'rb',
+                               fileobj=StringIO.StringIO(html.content))
             self.response.out.write(gz.read())
             gz.close()
         else:
@@ -381,8 +382,8 @@
         for article in db.get(articleKeys):
             article.ensureThumbnail()
             path = 'data/' + article.key().name() + '.html'
-            result.writestr(
-                path.encode('utf-8'), article.content.encode('utf-8'))
+            result.writestr(path.encode('utf-8'),
+                            article.content.encode('utf-8'))
             if article.thumbnail:
                 path = 'data/' + article.key().name() + '.jpg'
                 result.writestr(path.encode('utf-8'), article.thumbnail)
@@ -500,10 +501,9 @@
             sections[categoryId][1].append(feed.key())
 
             # Kick off a high priority feed update
-            taskqueue.add(
-                url='/update/feed',
-                queue_name=queue_name,
-                params={'id': feed.key().name()})
+            taskqueue.add(url='/update/feed',
+                          queue_name=queue_name,
+                          params={'id': feed.key().name()})
 
         sectionKeys = []
         for name, (title, feeds) in sections.items():
@@ -529,10 +529,9 @@
     def get(self):
         queue_name = self.request.get('queue_name', 'background')
         for feed in Feed.all():
-            taskqueue.add(
-                url='/update/feed',
-                queue_name=queue_name,
-                params={'id': feed.key().name()})
+            taskqueue.add(url='/update/feed',
+                          queue_name=queue_name,
+                          params={'id': feed.key().name()})
 
 
 UPDATE_COUNT = 4  # The number of articles to request on periodic updates.
@@ -625,8 +624,8 @@
     article = Article.get_or_insert(articleId)
     # TODO(jimhug): This aborts too early - at lease for one adafruit case.
     if article.date == data['published']:
-        logging.info(
-            'found existing, aborting: %r, %r' % (articleId, article.date))
+        logging.info('found existing, aborting: %r, %r' %
+                     (articleId, article.date))
         return False
 
     if data.has_key('content'):
diff --git a/samples-dev/swarm/appengine/queue.yaml b/pkg/compiler/test/codesize/swarm/appengine/queue.yaml
similarity index 100%
rename from samples-dev/swarm/appengine/queue.yaml
rename to pkg/compiler/test/codesize/swarm/appengine/queue.yaml
diff --git a/samples-dev/swarm/appengine/top.html b/pkg/compiler/test/codesize/swarm/appengine/top.html
similarity index 100%
rename from samples-dev/swarm/appengine/top.html
rename to pkg/compiler/test/codesize/swarm/appengine/top.html
diff --git a/samples-dev/swarm/appengine/upload.html b/pkg/compiler/test/codesize/swarm/appengine/upload.html
similarity index 100%
rename from samples-dev/swarm/appengine/upload.html
rename to pkg/compiler/test/codesize/swarm/appengine/upload.html
diff --git a/samples-dev/swarm/back-21.png b/pkg/compiler/test/codesize/swarm/back-21.png
similarity index 100%
rename from samples-dev/swarm/back-21.png
rename to pkg/compiler/test/codesize/swarm/back-21.png
Binary files differ
diff --git a/samples-dev/swarm/buildapp.py b/pkg/compiler/test/codesize/swarm/buildapp.py
similarity index 100%
rename from samples-dev/swarm/buildapp.py
rename to pkg/compiler/test/codesize/swarm/buildapp.py
diff --git a/samples-dev/swarm/cacheimages.py b/pkg/compiler/test/codesize/swarm/cacheimages.py
similarity index 83%
rename from samples-dev/swarm/cacheimages.py
rename to pkg/compiler/test/codesize/swarm/cacheimages.py
index 2324125..9d0f256 100755
--- a/samples-dev/swarm/cacheimages.py
+++ b/pkg/compiler/test/codesize/swarm/cacheimages.py
@@ -23,11 +23,10 @@
 def convertImgs(infile):
     global options
     try:
-        htmlconverter.convertForOffline(
-            infile,
-            infile,
-            verbose=options.verbose,
-            encode_images=options.inline_images)
+        htmlconverter.convertForOffline(infile,
+                                        infile,
+                                        verbose=options.verbose,
+                                        encode_images=options.inline_images)
         print('Converted ' + infile)
     except BaseException as e:
         print('Caught error: %s' % e)
@@ -41,11 +40,10 @@
         help=("Encode img payloads as data:// URLs rather than local files."),
         default=False,
         action='store_true')
-    parser.add_option(
-        "--verbose",
-        help="Print verbose output",
-        default=False,
-        action="store_true")
+    parser.add_option("--verbose",
+                      help="Print verbose output",
+                      default=False,
+                      action="store_true")
     return parser
 
 
diff --git a/samples-dev/swarm/data/Test0_0_0.html b/pkg/compiler/test/codesize/swarm/data/Test0_0_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_0_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_0_0.html
diff --git a/samples-dev/swarm/data/Test0_0_1.html b/pkg/compiler/test/codesize/swarm/data/Test0_0_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_0_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_0_1.html
diff --git a/samples-dev/swarm/data/Test0_0_2.html b/pkg/compiler/test/codesize/swarm/data/Test0_0_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_0_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_0_2.html
diff --git a/samples-dev/swarm/data/Test0_0_3.html b/pkg/compiler/test/codesize/swarm/data/Test0_0_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_0_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_0_3.html
diff --git a/samples-dev/swarm/data/Test0_0_4.html b/pkg/compiler/test/codesize/swarm/data/Test0_0_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_0_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_0_4.html
diff --git a/samples-dev/swarm/data/Test0_0_5.html b/pkg/compiler/test/codesize/swarm/data/Test0_0_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_0_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_0_5.html
diff --git a/samples-dev/swarm/data/Test0_0_6.html b/pkg/compiler/test/codesize/swarm/data/Test0_0_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_0_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_0_6.html
diff --git a/samples-dev/swarm/data/Test0_0_7.html b/pkg/compiler/test/codesize/swarm/data/Test0_0_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_0_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_0_7.html
diff --git a/samples-dev/swarm/data/Test0_1_0.html b/pkg/compiler/test/codesize/swarm/data/Test0_1_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_1_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_1_0.html
diff --git a/samples-dev/swarm/data/Test0_1_1.html b/pkg/compiler/test/codesize/swarm/data/Test0_1_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_1_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_1_1.html
diff --git a/samples-dev/swarm/data/Test0_1_2.html b/pkg/compiler/test/codesize/swarm/data/Test0_1_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_1_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_1_2.html
diff --git a/samples-dev/swarm/data/Test0_1_3.html b/pkg/compiler/test/codesize/swarm/data/Test0_1_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_1_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_1_3.html
diff --git a/samples-dev/swarm/data/Test0_1_4.html b/pkg/compiler/test/codesize/swarm/data/Test0_1_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_1_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_1_4.html
diff --git a/samples-dev/swarm/data/Test0_1_5.html b/pkg/compiler/test/codesize/swarm/data/Test0_1_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_1_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_1_5.html
diff --git a/samples-dev/swarm/data/Test0_1_6.html b/pkg/compiler/test/codesize/swarm/data/Test0_1_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_1_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_1_6.html
diff --git a/samples-dev/swarm/data/Test0_1_7.html b/pkg/compiler/test/codesize/swarm/data/Test0_1_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_1_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_1_7.html
diff --git a/samples-dev/swarm/data/Test0_2_0.html b/pkg/compiler/test/codesize/swarm/data/Test0_2_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_2_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_2_0.html
diff --git a/samples-dev/swarm/data/Test0_2_1.html b/pkg/compiler/test/codesize/swarm/data/Test0_2_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_2_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_2_1.html
diff --git a/samples-dev/swarm/data/Test0_2_2.html b/pkg/compiler/test/codesize/swarm/data/Test0_2_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_2_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_2_2.html
diff --git a/samples-dev/swarm/data/Test0_2_3.html b/pkg/compiler/test/codesize/swarm/data/Test0_2_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_2_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_2_3.html
diff --git a/samples-dev/swarm/data/Test0_2_4.html b/pkg/compiler/test/codesize/swarm/data/Test0_2_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_2_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_2_4.html
diff --git a/samples-dev/swarm/data/Test0_2_5.html b/pkg/compiler/test/codesize/swarm/data/Test0_2_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_2_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_2_5.html
diff --git a/samples-dev/swarm/data/Test0_2_6.html b/pkg/compiler/test/codesize/swarm/data/Test0_2_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_2_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_2_6.html
diff --git a/samples-dev/swarm/data/Test0_2_7.html b/pkg/compiler/test/codesize/swarm/data/Test0_2_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_2_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_2_7.html
diff --git a/samples-dev/swarm/data/Test0_3_0.html b/pkg/compiler/test/codesize/swarm/data/Test0_3_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_3_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_3_0.html
diff --git a/samples-dev/swarm/data/Test0_3_1.html b/pkg/compiler/test/codesize/swarm/data/Test0_3_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_3_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_3_1.html
diff --git a/samples-dev/swarm/data/Test0_3_2.html b/pkg/compiler/test/codesize/swarm/data/Test0_3_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_3_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_3_2.html
diff --git a/samples-dev/swarm/data/Test0_3_3.html b/pkg/compiler/test/codesize/swarm/data/Test0_3_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_3_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_3_3.html
diff --git a/samples-dev/swarm/data/Test0_3_4.html b/pkg/compiler/test/codesize/swarm/data/Test0_3_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_3_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_3_4.html
diff --git a/samples-dev/swarm/data/Test0_3_5.html b/pkg/compiler/test/codesize/swarm/data/Test0_3_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_3_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_3_5.html
diff --git a/samples-dev/swarm/data/Test0_3_6.html b/pkg/compiler/test/codesize/swarm/data/Test0_3_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_3_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_3_6.html
diff --git a/samples-dev/swarm/data/Test0_3_7.html b/pkg/compiler/test/codesize/swarm/data/Test0_3_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test0_3_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test0_3_7.html
diff --git a/samples-dev/swarm/data/Test1_0_0.html b/pkg/compiler/test/codesize/swarm/data/Test1_0_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_0_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_0_0.html
diff --git a/samples-dev/swarm/data/Test1_0_1.html b/pkg/compiler/test/codesize/swarm/data/Test1_0_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_0_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_0_1.html
diff --git a/samples-dev/swarm/data/Test1_0_2.html b/pkg/compiler/test/codesize/swarm/data/Test1_0_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_0_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_0_2.html
diff --git a/samples-dev/swarm/data/Test1_0_3.html b/pkg/compiler/test/codesize/swarm/data/Test1_0_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_0_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_0_3.html
diff --git a/samples-dev/swarm/data/Test1_0_4.html b/pkg/compiler/test/codesize/swarm/data/Test1_0_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_0_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_0_4.html
diff --git a/samples-dev/swarm/data/Test1_0_5.html b/pkg/compiler/test/codesize/swarm/data/Test1_0_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_0_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_0_5.html
diff --git a/samples-dev/swarm/data/Test1_0_6.html b/pkg/compiler/test/codesize/swarm/data/Test1_0_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_0_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_0_6.html
diff --git a/samples-dev/swarm/data/Test1_0_7.html b/pkg/compiler/test/codesize/swarm/data/Test1_0_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_0_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_0_7.html
diff --git a/samples-dev/swarm/data/Test1_1_0.html b/pkg/compiler/test/codesize/swarm/data/Test1_1_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_1_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_1_0.html
diff --git a/samples-dev/swarm/data/Test1_1_1.html b/pkg/compiler/test/codesize/swarm/data/Test1_1_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_1_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_1_1.html
diff --git a/samples-dev/swarm/data/Test1_1_2.html b/pkg/compiler/test/codesize/swarm/data/Test1_1_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_1_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_1_2.html
diff --git a/samples-dev/swarm/data/Test1_1_3.html b/pkg/compiler/test/codesize/swarm/data/Test1_1_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_1_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_1_3.html
diff --git a/samples-dev/swarm/data/Test1_1_4.html b/pkg/compiler/test/codesize/swarm/data/Test1_1_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_1_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_1_4.html
diff --git a/samples-dev/swarm/data/Test1_1_5.html b/pkg/compiler/test/codesize/swarm/data/Test1_1_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_1_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_1_5.html
diff --git a/samples-dev/swarm/data/Test1_1_6.html b/pkg/compiler/test/codesize/swarm/data/Test1_1_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_1_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_1_6.html
diff --git a/samples-dev/swarm/data/Test1_1_7.html b/pkg/compiler/test/codesize/swarm/data/Test1_1_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_1_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_1_7.html
diff --git a/samples-dev/swarm/data/Test1_2_0.html b/pkg/compiler/test/codesize/swarm/data/Test1_2_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_2_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_2_0.html
diff --git a/samples-dev/swarm/data/Test1_2_1.html b/pkg/compiler/test/codesize/swarm/data/Test1_2_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_2_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_2_1.html
diff --git a/samples-dev/swarm/data/Test1_2_2.html b/pkg/compiler/test/codesize/swarm/data/Test1_2_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_2_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_2_2.html
diff --git a/samples-dev/swarm/data/Test1_2_3.html b/pkg/compiler/test/codesize/swarm/data/Test1_2_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_2_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_2_3.html
diff --git a/samples-dev/swarm/data/Test1_2_4.html b/pkg/compiler/test/codesize/swarm/data/Test1_2_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_2_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_2_4.html
diff --git a/samples-dev/swarm/data/Test1_2_5.html b/pkg/compiler/test/codesize/swarm/data/Test1_2_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_2_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_2_5.html
diff --git a/samples-dev/swarm/data/Test1_2_6.html b/pkg/compiler/test/codesize/swarm/data/Test1_2_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_2_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_2_6.html
diff --git a/samples-dev/swarm/data/Test1_2_7.html b/pkg/compiler/test/codesize/swarm/data/Test1_2_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_2_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_2_7.html
diff --git a/samples-dev/swarm/data/Test1_3_0.html b/pkg/compiler/test/codesize/swarm/data/Test1_3_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_3_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_3_0.html
diff --git a/samples-dev/swarm/data/Test1_3_1.html b/pkg/compiler/test/codesize/swarm/data/Test1_3_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_3_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_3_1.html
diff --git a/samples-dev/swarm/data/Test1_3_2.html b/pkg/compiler/test/codesize/swarm/data/Test1_3_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_3_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_3_2.html
diff --git a/samples-dev/swarm/data/Test1_3_3.html b/pkg/compiler/test/codesize/swarm/data/Test1_3_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_3_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_3_3.html
diff --git a/samples-dev/swarm/data/Test1_3_4.html b/pkg/compiler/test/codesize/swarm/data/Test1_3_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_3_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_3_4.html
diff --git a/samples-dev/swarm/data/Test1_3_5.html b/pkg/compiler/test/codesize/swarm/data/Test1_3_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_3_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_3_5.html
diff --git a/samples-dev/swarm/data/Test1_3_6.html b/pkg/compiler/test/codesize/swarm/data/Test1_3_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_3_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_3_6.html
diff --git a/samples-dev/swarm/data/Test1_3_7.html b/pkg/compiler/test/codesize/swarm/data/Test1_3_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test1_3_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test1_3_7.html
diff --git a/samples-dev/swarm/data/Test2_0_0.html b/pkg/compiler/test/codesize/swarm/data/Test2_0_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_0_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_0_0.html
diff --git a/samples-dev/swarm/data/Test2_0_1.html b/pkg/compiler/test/codesize/swarm/data/Test2_0_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_0_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_0_1.html
diff --git a/samples-dev/swarm/data/Test2_0_2.html b/pkg/compiler/test/codesize/swarm/data/Test2_0_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_0_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_0_2.html
diff --git a/samples-dev/swarm/data/Test2_0_3.html b/pkg/compiler/test/codesize/swarm/data/Test2_0_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_0_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_0_3.html
diff --git a/samples-dev/swarm/data/Test2_0_4.html b/pkg/compiler/test/codesize/swarm/data/Test2_0_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_0_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_0_4.html
diff --git a/samples-dev/swarm/data/Test2_0_5.html b/pkg/compiler/test/codesize/swarm/data/Test2_0_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_0_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_0_5.html
diff --git a/samples-dev/swarm/data/Test2_0_6.html b/pkg/compiler/test/codesize/swarm/data/Test2_0_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_0_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_0_6.html
diff --git a/samples-dev/swarm/data/Test2_0_7.html b/pkg/compiler/test/codesize/swarm/data/Test2_0_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_0_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_0_7.html
diff --git a/samples-dev/swarm/data/Test2_1_0.html b/pkg/compiler/test/codesize/swarm/data/Test2_1_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_1_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_1_0.html
diff --git a/samples-dev/swarm/data/Test2_1_1.html b/pkg/compiler/test/codesize/swarm/data/Test2_1_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_1_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_1_1.html
diff --git a/samples-dev/swarm/data/Test2_1_2.html b/pkg/compiler/test/codesize/swarm/data/Test2_1_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_1_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_1_2.html
diff --git a/samples-dev/swarm/data/Test2_1_3.html b/pkg/compiler/test/codesize/swarm/data/Test2_1_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_1_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_1_3.html
diff --git a/samples-dev/swarm/data/Test2_1_4.html b/pkg/compiler/test/codesize/swarm/data/Test2_1_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_1_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_1_4.html
diff --git a/samples-dev/swarm/data/Test2_1_5.html b/pkg/compiler/test/codesize/swarm/data/Test2_1_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_1_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_1_5.html
diff --git a/samples-dev/swarm/data/Test2_1_6.html b/pkg/compiler/test/codesize/swarm/data/Test2_1_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_1_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_1_6.html
diff --git a/samples-dev/swarm/data/Test2_1_7.html b/pkg/compiler/test/codesize/swarm/data/Test2_1_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_1_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_1_7.html
diff --git a/samples-dev/swarm/data/Test2_2_0.html b/pkg/compiler/test/codesize/swarm/data/Test2_2_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_2_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_2_0.html
diff --git a/samples-dev/swarm/data/Test2_2_1.html b/pkg/compiler/test/codesize/swarm/data/Test2_2_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_2_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_2_1.html
diff --git a/samples-dev/swarm/data/Test2_2_2.html b/pkg/compiler/test/codesize/swarm/data/Test2_2_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_2_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_2_2.html
diff --git a/samples-dev/swarm/data/Test2_2_3.html b/pkg/compiler/test/codesize/swarm/data/Test2_2_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_2_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_2_3.html
diff --git a/samples-dev/swarm/data/Test2_2_4.html b/pkg/compiler/test/codesize/swarm/data/Test2_2_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_2_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_2_4.html
diff --git a/samples-dev/swarm/data/Test2_2_5.html b/pkg/compiler/test/codesize/swarm/data/Test2_2_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_2_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_2_5.html
diff --git a/samples-dev/swarm/data/Test2_2_6.html b/pkg/compiler/test/codesize/swarm/data/Test2_2_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_2_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_2_6.html
diff --git a/samples-dev/swarm/data/Test2_2_7.html b/pkg/compiler/test/codesize/swarm/data/Test2_2_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_2_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_2_7.html
diff --git a/samples-dev/swarm/data/Test2_3_0.html b/pkg/compiler/test/codesize/swarm/data/Test2_3_0.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_3_0.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_3_0.html
diff --git a/samples-dev/swarm/data/Test2_3_1.html b/pkg/compiler/test/codesize/swarm/data/Test2_3_1.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_3_1.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_3_1.html
diff --git a/samples-dev/swarm/data/Test2_3_2.html b/pkg/compiler/test/codesize/swarm/data/Test2_3_2.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_3_2.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_3_2.html
diff --git a/samples-dev/swarm/data/Test2_3_3.html b/pkg/compiler/test/codesize/swarm/data/Test2_3_3.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_3_3.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_3_3.html
diff --git a/samples-dev/swarm/data/Test2_3_4.html b/pkg/compiler/test/codesize/swarm/data/Test2_3_4.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_3_4.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_3_4.html
diff --git a/samples-dev/swarm/data/Test2_3_5.html b/pkg/compiler/test/codesize/swarm/data/Test2_3_5.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_3_5.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_3_5.html
diff --git a/samples-dev/swarm/data/Test2_3_6.html b/pkg/compiler/test/codesize/swarm/data/Test2_3_6.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_3_6.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_3_6.html
diff --git a/samples-dev/swarm/data/Test2_3_7.html b/pkg/compiler/test/codesize/swarm/data/Test2_3_7.html
similarity index 100%
rename from samples-dev/swarm/data/Test2_3_7.html
rename to pkg/compiler/test/codesize/swarm/data/Test2_3_7.html
diff --git a/samples-dev/swarm/data/user.data b/pkg/compiler/test/codesize/swarm/data/user.data
similarity index 100%
rename from samples-dev/swarm/data/user.data
rename to pkg/compiler/test/codesize/swarm/data/user.data
Binary files differ
diff --git a/samples-dev/swarm/externallink.svg b/pkg/compiler/test/codesize/swarm/externallink.svg
similarity index 100%
rename from samples-dev/swarm/externallink.svg
rename to pkg/compiler/test/codesize/swarm/externallink.svg
diff --git a/samples-dev/swarm/favicon.png b/pkg/compiler/test/codesize/swarm/favicon.png
similarity index 100%
rename from samples-dev/swarm/favicon.png
rename to pkg/compiler/test/codesize/swarm/favicon.png
Binary files differ
diff --git a/samples-dev/swarm/favicon128.png b/pkg/compiler/test/codesize/swarm/favicon128.png
similarity index 100%
rename from samples-dev/swarm/favicon128.png
rename to pkg/compiler/test/codesize/swarm/favicon128.png
Binary files differ
diff --git a/samples-dev/swarm/gen_manifest.py b/pkg/compiler/test/codesize/swarm/gen_manifest.py
similarity index 100%
rename from samples-dev/swarm/gen_manifest.py
rename to pkg/compiler/test/codesize/swarm/gen_manifest.py
diff --git a/samples-dev/swarm/info.svg b/pkg/compiler/test/codesize/swarm/info.svg
similarity index 100%
rename from samples-dev/swarm/info.svg
rename to pkg/compiler/test/codesize/swarm/info.svg
diff --git a/samples-dev/swarm/lefttriangle.svg b/pkg/compiler/test/codesize/swarm/lefttriangle.svg
similarity index 100%
rename from samples-dev/swarm/lefttriangle.svg
rename to pkg/compiler/test/codesize/swarm/lefttriangle.svg
diff --git a/samples-dev/swarm/manifest.json b/pkg/compiler/test/codesize/swarm/manifest.json
similarity index 100%
rename from samples-dev/swarm/manifest.json
rename to pkg/compiler/test/codesize/swarm/manifest.json
diff --git a/samples-dev/swarm/pigeons-jumpinjimmyjava-white90pct-q70.jpg b/pkg/compiler/test/codesize/swarm/pigeons-jumpinjimmyjava-white90pct-q70.jpg
similarity index 100%
rename from samples-dev/swarm/pigeons-jumpinjimmyjava-white90pct-q70.jpg
rename to pkg/compiler/test/codesize/swarm/pigeons-jumpinjimmyjava-white90pct-q70.jpg
Binary files differ
diff --git a/samples-dev/swarm/pubspec.yaml b/pkg/compiler/test/codesize/swarm/pubspec.yaml
similarity index 100%
rename from samples-dev/swarm/pubspec.yaml
rename to pkg/compiler/test/codesize/swarm/pubspec.yaml
diff --git a/samples-dev/swarm/refresh-21.png b/pkg/compiler/test/codesize/swarm/refresh-21.png
similarity index 100%
rename from samples-dev/swarm/refresh-21.png
rename to pkg/compiler/test/codesize/swarm/refresh-21.png
Binary files differ
diff --git a/samples-dev/swarm/righttriangle.svg b/pkg/compiler/test/codesize/swarm/righttriangle.svg
similarity index 100%
rename from samples-dev/swarm/righttriangle.svg
rename to pkg/compiler/test/codesize/swarm/righttriangle.svg
diff --git a/samples-dev/swarm/settings-21.png b/pkg/compiler/test/codesize/swarm/settings-21.png
similarity index 100%
rename from samples-dev/swarm/settings-21.png
rename to pkg/compiler/test/codesize/swarm/settings-21.png
Binary files differ
diff --git a/samples-dev/swarm/sliderarrow.svg b/pkg/compiler/test/codesize/swarm/sliderarrow.svg
similarity index 100%
rename from samples-dev/swarm/sliderarrow.svg
rename to pkg/compiler/test/codesize/swarm/sliderarrow.svg
diff --git a/samples-dev/swarm/swarm-dev.pem b/pkg/compiler/test/codesize/swarm/swarm-dev.pem
similarity index 100%
rename from samples-dev/swarm/swarm-dev.pem
rename to pkg/compiler/test/codesize/swarm/swarm-dev.pem
diff --git a/samples-dev/swarm/swarm.css b/pkg/compiler/test/codesize/swarm/swarm.css
similarity index 100%
rename from samples-dev/swarm/swarm.css
rename to pkg/compiler/test/codesize/swarm/swarm.css
diff --git a/samples-dev/swarm/swarm.dart b/pkg/compiler/test/codesize/swarm/swarm.dart
similarity index 100%
rename from samples-dev/swarm/swarm.dart
rename to pkg/compiler/test/codesize/swarm/swarm.dart
diff --git a/samples-dev/swarm/swarm.html b/pkg/compiler/test/codesize/swarm/swarm.html
similarity index 100%
rename from samples-dev/swarm/swarm.html
rename to pkg/compiler/test/codesize/swarm/swarm.html
diff --git a/samples-dev/swarm/swarm.scss b/pkg/compiler/test/codesize/swarm/swarm.scss
similarity index 100%
rename from samples-dev/swarm/swarm.scss
rename to pkg/compiler/test/codesize/swarm/swarm.scss
diff --git a/samples-dev/swarm/swarm_ui_lib/base/AnimationScheduler.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/AnimationScheduler.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/base/AnimationScheduler.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/AnimationScheduler.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/base/Device.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/Device.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/base/Device.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/Device.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/base/DomWrapper.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/DomWrapper.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/base/DomWrapper.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/DomWrapper.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/base/Env.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/Env.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/base/Env.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/Env.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/base/Size.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/Size.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/base/Size.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/Size.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/base/base.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/base.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/base/base.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/base/base.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/GridLayout.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/GridLayout.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/layout/GridLayout.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/GridLayout.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParams.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/GridLayoutParams.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParams.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/GridLayoutParams.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParser.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/GridLayoutParser.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParser.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/GridLayoutParser.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/GridTracks.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/GridTracks.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/layout/GridTracks.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/GridTracks.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/SizingFunctions.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/SizingFunctions.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/layout/SizingFunctions.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/SizingFunctions.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/ViewLayout.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/ViewLayout.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/layout/ViewLayout.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/ViewLayout.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/layout.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/layout.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/layout/layout.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/layout/layout.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/observable/ChangeEvent.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/observable/ChangeEvent.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/observable/ChangeEvent.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/observable/ChangeEvent.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/observable/EventBatch.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/observable/EventBatch.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/observable/EventBatch.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/observable/EventBatch.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/observable/observable.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/observable/observable.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/observable/observable.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/observable/observable.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/BezierPhysics.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/BezierPhysics.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/BezierPhysics.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/BezierPhysics.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/ClickBuster.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/ClickBuster.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/ClickBuster.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/ClickBuster.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/EventUtil.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/EventUtil.dart
similarity index 99%
rename from samples-dev/swarm/swarm_ui_lib/touch/EventUtil.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/EventUtil.dart
index 543df42..3a35527 100644
--- a/samples-dev/swarm/swarm_ui_lib/touch/EventUtil.dart
+++ b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/EventUtil.dart
@@ -4,7 +4,6 @@
 
 // @dart = 2.9
 
-
 part of touch;
 
 /// Common events related helpers.
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/FxUtil.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/FxUtil.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/FxUtil.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/FxUtil.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/Geometry.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/Geometry.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/Geometry.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/Geometry.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/InfiniteScroller.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/InfiniteScroller.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/InfiniteScroller.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/InfiniteScroller.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/Math.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/Math.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/Math.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/Math.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/Momentum.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/Momentum.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/Momentum.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/Momentum.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/ScrollWatcher.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/ScrollWatcher.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/ScrollWatcher.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/ScrollWatcher.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/Scrollbar.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/Scrollbar.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/Scrollbar.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/Scrollbar.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/Scroller.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/Scroller.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/Scroller.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/Scroller.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/TimeUtil.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/TimeUtil.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/TimeUtil.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/TimeUtil.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/TouchHandler.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/TouchHandler.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/TouchHandler.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/TouchHandler.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/TouchUtil.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/TouchUtil.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/TouchUtil.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/TouchUtil.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/resources/touch.css b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/resources/touch.css
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/resources/touch.css
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/resources/touch.css
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/touch.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/touch.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/touch/touch.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/touch/touch.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/util/CollectionUtils.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/util/CollectionUtils.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/util/CollectionUtils.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/util/CollectionUtils.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/util/DateUtils.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/util/DateUtils.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/util/StringUtils.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/util/StringUtils.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/util/StringUtils.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/util/StringUtils.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/util/Uri.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/util/Uri.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/util/Uri.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/util/Uri.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/util/utilslib.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/util/utilslib.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/util/utilslib.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/util/utilslib.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/view/CompositeView.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/CompositeView.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/view/CompositeView.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/CompositeView.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/view/ConveyorView.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/ConveyorView.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/view/ConveyorView.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/ConveyorView.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/view/MeasureText.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/MeasureText.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/view/MeasureText.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/MeasureText.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/view/PagedViews.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/PagedViews.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/view/PagedViews.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/PagedViews.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/view/SliderMenu.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/SliderMenu.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/view/SliderMenu.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/SliderMenu.dart
diff --git a/samples-dev/swarm/swarm_ui_lib/view/resources/view.css b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/resources/view.css
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/view/resources/view.css
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/resources/view.css
diff --git a/samples-dev/swarm/swarm_ui_lib/view/view.dart b/pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/view.dart
similarity index 100%
rename from samples-dev/swarm/swarm_ui_lib/view/view.dart
rename to pkg/compiler/test/codesize/swarm/swarm_ui_lib/view/view.dart
diff --git a/samples-dev/swarm/swarmlib.dart b/pkg/compiler/test/codesize/swarm/swarmlib.dart
similarity index 100%
rename from samples-dev/swarm/swarmlib.dart
rename to pkg/compiler/test/codesize/swarm/swarmlib.dart
diff --git a/samples-dev/swarm/update.py b/pkg/compiler/test/codesize/swarm/update.py
similarity index 80%
rename from samples-dev/swarm/update.py
rename to pkg/compiler/test/codesize/swarm/update.py
index 5ff7000..fca04ea 100755
--- a/samples-dev/swarm/update.py
+++ b/pkg/compiler/test/codesize/swarm/update.py
@@ -39,22 +39,19 @@
 def Flags():
     """ Consturcts a parser for extracting flags from the command line. """
     result = optparse.OptionParser()
-    result.add_option(
-        "-t",
-        "--target",
-        help="The target html to generate",
-        metavar="[js,dart]",
-        default='js,dart')
-    result.add_option(
-        "--verbose",
-        help="Print verbose output",
-        default=False,
-        action="store_true")
-    result.add_option(
-        "--dartc_extra_flags",
-        help="Additional flag text to pass to dartc",
-        default="",
-        action="store")
+    result.add_option("-t",
+                      "--target",
+                      help="The target html to generate",
+                      metavar="[js,dart]",
+                      default='js,dart')
+    result.add_option("--verbose",
+                      help="Print verbose output",
+                      default=False,
+                      action="store_true")
+    result.add_option("--dartc_extra_flags",
+                      help="Additional flag text to pass to dartc",
+                      default="",
+                      action="store")
     #result.set_usage("update.py input.html -o OUTDIR -t chromium,dartium")
     return result
 
diff --git a/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart b/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart
index 8ed7162..d3c4e14 100644
--- a/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart
@@ -23,9 +23,9 @@
 
 /*two-frag.library: 
  a_pre_fragments=[
-  p1: {units: [4{libB}, 1{libA}], usedBy: [p2, p3], needs: []},
-  p2: {units: [3{libA, libC}, 6{libC}], usedBy: [p3], needs: [p1]},
-  p3: {units: [2{libA, libB, libC}, 5{libB, libC}], usedBy: [], needs: [p2, p1]}],
+  p1: {units: [4{libB}, 1{libA}], usedBy: [p3], needs: []},
+  p2: {units: [6{libC}], usedBy: [p3], needs: []},
+  p3: {units: [2{libA, libB, libC}, 5{libB, libC}, 3{libA, libC}], usedBy: [], needs: [p2, p1]}],
  b_finalized_fragments=[
   f1: [4{libB}, 1{libA}],
   f2: [6{libC}],
diff --git a/pkg/compiler/test/deferred_loading/data/many_parts/main.dart b/pkg/compiler/test/deferred_loading/data/many_parts/main.dart
index aa07a8a..3a0e4c1 100644
--- a/pkg/compiler/test/deferred_loading/data/many_parts/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/many_parts/main.dart
@@ -80,30 +80,28 @@
 /*three-frag.library: 
  a_pre_fragments=[
   p1: {units: [26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}], usedBy: [p2], needs: []},
-  p2: {units: [9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}], usedBy: [p4, p3], needs: [p1]},
-  p3: {units: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}], usedBy: [p4], needs: [p2]},
-  p4: {units: [2{b1, b2, b3, b4, b5}], usedBy: [], needs: [p2, p3]}],
+  p2: {units: [9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}], usedBy: [p3], needs: [p1]},
+  p3: {units: [2{b1, b2, b3, b4, b5}, 24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}], usedBy: [], needs: [p2]}],
  b_finalized_fragments=[
   f1: [26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}],
   f2: [9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}],
-  f3: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}],
-  f4: [2{b1, b2, b3, b4, b5}]],
+  f3: [2{b1, b2, b3, b4, b5}, 24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}]],
  c_steps=[
-  b1=(f4, f3, f2, f1),
-  b2=(f4, f3, f2, f1),
-  b3=(f4, f3, f2, f1),
-  b4=(f4, f3, f2, f1),
-  b5=(f4, f3, f2, f1)]
+  b1=(f3, f2, f1),
+  b2=(f3, f2, f1),
+  b3=(f3, f2, f1),
+  b4=(f3, f2, f1),
+  b5=(f3, f2, f1)]
 */
 
 /*two-frag.library: 
  a_pre_fragments=[
-  p1: {units: [12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}], usedBy: [p2], needs: []},
-  p2: {units: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}], usedBy: [p3], needs: [p1]},
+  p1: {units: [8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}], usedBy: [p2], needs: []},
+  p2: {units: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}], usedBy: [p3], needs: [p1]},
   p3: {units: [2{b1, b2, b3, b4, b5}], usedBy: [], needs: [p2]}],
  b_finalized_fragments=[
-  f1: [12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}],
-  f2: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}],
+  f1: [8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}],
+  f2: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}],
   f3: [2{b1, b2, b3, b4, b5}]],
  c_steps=[
   b1=(f3, f2, f1),
diff --git a/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart b/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart
index 86f5ed6..0a5f87d 100644
--- a/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart
@@ -15,7 +15,19 @@
   lib3=(f2)]
 */
 
-/*two-frag|three-frag.library: 
+/*two-frag.library: 
+ a_pre_fragments=[
+  p1: {units: [1{lib1}], usedBy: [p2], needs: []},
+  p2: {units: [2{lib1, lib3}, 3{lib3}], usedBy: [], needs: [p1]}],
+ b_finalized_fragments=[
+  f1: [1{lib1}],
+  f2: [3{lib3}]],
+ c_steps=[
+  lib1=(f1),
+  lib3=(f2)]
+*/
+
+/*three-frag.library: 
  a_pre_fragments=[
   p1: {units: [1{lib1}], usedBy: [p3], needs: []},
   p2: {units: [3{lib3}], usedBy: [p3], needs: []},
diff --git a/pkg/compiler/test/dump_info/data/deferred_future/main.dart b/pkg/compiler/test/dump_info/data/deferred_future/main.dart
index 5cfb182..955c4ea 100644
--- a/pkg/compiler/test/dump_info/data/deferred_future/main.dart
+++ b/pkg/compiler/test/dump_info/data/deferred_future/main.dart
@@ -110,7 +110,7 @@
   "id": "outputUnit/1",
   "kind": "outputUnit",
   "name": "1",
-  "size": 895,
+  "size": 834,
   "filename": "out_1.part.js",
   "imports": [
     "lib1"
diff --git a/pkg/compiler/test/end_to_end/dart2js_batch_test.dart b/pkg/compiler/test/end_to_end/dart2js_batch_test.dart
index ade191a..5d32912 100644
--- a/pkg/compiler/test/end_to_end/dart2js_batch_test.dart
+++ b/pkg/compiler/test/end_to_end/dart2js_batch_test.dart
@@ -42,7 +42,7 @@
   return createTempDir().then((Directory directory) {
     tmpDir = directory;
     Directory appDir =
-        new Directory.fromUri(Uri.base.resolve('samples-dev/swarm'));
+        Directory.fromUri(Uri.base.resolve('pkg/compiler/test/codesize/swarm'));
 
     print("Copying '${appDir.path}' to '${tmpDir.path}'.");
     copyDirectory(appDir, tmpDir);
diff --git a/pkg/compiler/test/end_to_end/dump_info_test.dart b/pkg/compiler/test/end_to_end/dump_info_test.dart
index 642bb2d..74ff99d 100644
--- a/pkg/compiler/test/end_to_end/dump_info_test.dart
+++ b/pkg/compiler/test/end_to_end/dump_info_test.dart
@@ -36,8 +36,8 @@
   out2.createSync();
   Directory out3 = new Directory.fromUri(tmpDir.uri.resolve('binary'));
   out3.createSync();
-  Directory appDir =
-      new Directory.fromUri(Uri.base.resolve('samples-dev/swarm'));
+  Directory appDir = new Directory.fromUri(
+      Uri.base.resolve('pkg/compiler/test/codesize/swarm'));
 
   print("Copying '${appDir.path}' to '${tmpDir.path}'.");
   copyDirectory(appDir, tmpDir);
diff --git a/pkg/compiler/test/equivalence/show_helper.dart b/pkg/compiler/test/equivalence/show_helper.dart
index d8b955b..6f27a86 100644
--- a/pkg/compiler/test/equivalence/show_helper.dart
+++ b/pkg/compiler/test/equivalence/show_helper.dart
@@ -71,7 +71,8 @@
       if (show != null && !show.any((f) => '$fileUri'.endsWith(f))) {
         continue;
       }
-      SourceFile sourceFile = provider.readUtf8FromFileSyncForTesting(fileUri);
+      SourceFile<List<int>> sourceFile =
+          provider.readUtf8FromFileSyncForTesting(fileUri);
       String sourceCode = sourceFile?.slowText();
       if (sourceCode == null) {
         sourceCode = new File.fromUri(fileUri).readAsStringSync();
diff --git a/pkg/compiler/test/impact/data/jsinterop.dart b/pkg/compiler/test/impact/data/jsinterop.dart
index 0451381..65598fd 100644
--- a/pkg/compiler/test/impact/data/jsinterop.dart
+++ b/pkg/compiler/test/impact/data/jsinterop.dart
@@ -27,7 +27,7 @@
 
 @JS()
 class JsInteropClass {
-  /*member: JsInteropClass.:static=[LegacyJavaScriptObject.(0)]*/
+  /*member: JsInteropClass.:*/
   external JsInteropClass();
 
   /*member: JsInteropClass.method:
diff --git a/pkg/compiler/test/inference/trivial_abstract_value_domain_test.dart b/pkg/compiler/test/inference/trivial_abstract_value_domain_test.dart
index 6929dfd..8587a46 100644
--- a/pkg/compiler/test/inference/trivial_abstract_value_domain_test.dart
+++ b/pkg/compiler/test/inference/trivial_abstract_value_domain_test.dart
@@ -17,7 +17,7 @@
   asyncTest(() async {
     ArgResults argResults = argParser.parse(args);
     Uri entryPoint = getEntryPoint(argResults) ??
-        Uri.base.resolve('samples-dev/swarm/swarm.dart');
+        Uri.base.resolve('pkg/compiler/test/codesize/swarm/swarm.dart');
     Uri librariesSpecificationUri = getLibrariesSpec(argResults);
     Uri packageConfig = getPackages(argResults);
     List<String> options = getOptions(argResults);
diff --git a/pkg/compiler/test/model/cfe_annotations_test.dart b/pkg/compiler/test/model/cfe_annotations_test.dart
index 7d1fd81..e909acc 100644
--- a/pkg/compiler/test/model/cfe_annotations_test.dart
+++ b/pkg/compiler/test/model/cfe_annotations_test.dart
@@ -428,7 +428,7 @@
               Expect.equals(
                   expectedAnonymousJsInteropClass,
                   nativeData.isAnonymousJsInteropClass(classEntity),
-                  "Unexpected js anonymousclass result from native data for "
+                  "Unexpected js anonymous class result from native data for "
                   "$cls");
 
               for (ir.Member member in cls.members) {
diff --git a/pkg/compiler/test/model/cfe_constant_swarm_test.dart b/pkg/compiler/test/model/cfe_constant_swarm_test.dart
index 474766e..88fdd28 100644
--- a/pkg/compiler/test/model/cfe_constant_swarm_test.dart
+++ b/pkg/compiler/test/model/cfe_constant_swarm_test.dart
@@ -16,7 +16,7 @@
   asyncTest(() async {
     ArgResults argResults = argParser.parse(args);
     Uri entryPoint = getEntryPoint(argResults) ??
-        Uri.base.resolve('samples-dev/swarm/swarm.dart');
+        Uri.base.resolve('pkg/compiler/test/codesize/swarm/swarm.dart');
     Uri librariesSpecificationUri = getLibrariesSpec(argResults);
     Uri packageConfig = getPackages(argResults);
     List<String> options = getOptions(argResults);
diff --git a/pkg/compiler/test/optimization/data/condition_value.dart b/pkg/compiler/test/optimization/data/condition_value.dart
index e7d1904..b8a9991 100644
--- a/pkg/compiler/test/optimization/data/condition_value.dart
+++ b/pkg/compiler/test/optimization/data/condition_value.dart
@@ -162,7 +162,7 @@
 }
 
 // Unlike loop5, this is not 'hoisted'. GVN is not required to match the
-// condition with its use, so the subsitution happens in a simplify pass before
+// condition with its use, so the substitution happens in a simplify pass before
 // GVN/LICM can hoist the negation.
 /*member: loop6ElseJoin:ConditionValue=[count=1&value=false&where=else-join]*/
 loop6ElseJoin(bool x) {
diff --git a/pkg/compiler/test/serialization/in_memory_split_test.dart b/pkg/compiler/test/serialization/in_memory_split_test.dart
index 7f4be63..fbea3d6 100644
--- a/pkg/compiler/test/serialization/in_memory_split_test.dart
+++ b/pkg/compiler/test/serialization/in_memory_split_test.dart
@@ -27,7 +27,7 @@
     }
 
     Uri entryPoint = getEntryPoint(argResults) ??
-        Uri.base.resolve('samples-dev/swarm/swarm.dart');
+        Uri.base.resolve('pkg/compiler/test/codesize/swarm/swarm.dart');
     Uri librariesSpecificationUri = getLibrariesSpec(argResults);
     Uri packageConfig = getPackages(argResults);
     List<String> options = getOptions(argResults);
diff --git a/pkg/compiler/test/serialization/on_disk_split_test.dart b/pkg/compiler/test/serialization/on_disk_split_test.dart
index 22cedb1..72dbf0a 100644
--- a/pkg/compiler/test/serialization/on_disk_split_test.dart
+++ b/pkg/compiler/test/serialization/on_disk_split_test.dart
@@ -21,7 +21,7 @@
       '--libraries-spec=$sdkLibrariesSpecificationUri',
     ];
     await internalMain([
-          'samples-dev/swarm/swarm.dart',
+          'pkg/compiler/test/codesize/swarm/swarm.dart',
           Flags.writeClosedWorld,
           '--out=${dillUri}',
         ] +
diff --git a/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart b/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart
index ba0851d..d13cd71 100644
--- a/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart
+++ b/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart
@@ -104,7 +104,8 @@
 
   @override
   SourceFile getSourceFile(uri) {
-    SourceFile sourceFile = sourceFileProvider.getUtf8SourceFile(uri);
+    SourceFile<List<int>> sourceFile =
+        sourceFileProvider.getUtf8SourceFile(uri);
     sourceFile ??= sourceFileProvider.readUtf8FromFileSyncForTesting(uri);
     if (sourceFile == null) {
       sourceFile = outputProvider.getSourceFile(uri);
diff --git a/pkg/compiler/test/sourcemaps/minified/is_not_a_function.dart b/pkg/compiler/test/sourcemaps/minified/is_not_a_function.dart
index 01a3a36..a725a33 100644
--- a/pkg/compiler/test/sourcemaps/minified/is_not_a_function.dart
+++ b/pkg/compiler/test/sourcemaps/minified/is_not_a_function.dart
@@ -5,7 +5,7 @@
 // @dart = 2.7
 
 // TODO(sigmund): should this be handled as "other"? (the identifier appears
-// direclty in the line producing the error).
+// directly in the line producing the error).
 //
 // Error pattern: \.([^\.]*) is not a function
 // Kind of minified name: instance
diff --git a/pkg/compiler/testing.json b/pkg/compiler/testing.json
index 923911a..7273827 100644
--- a/pkg/compiler/testing.json
+++ b/pkg/compiler/testing.json
@@ -17,6 +17,7 @@
       "^pkg/compiler/test/.*/data_2/.*",
       "^pkg/compiler/test/.*/emission/.*",
       "^pkg/compiler/test/.*/model_data/.*",
+      "^pkg/compiler/test/codesize/swarm/.*",
       "^pkg/compiler/test/deferred_loading/libs/.*",
       "^pkg/compiler/test/sourcemaps/stacktrace/extension_method.dart"
     ]
diff --git a/pkg/dart2js_info/bin/src/runtime_coverage_analysis.dart b/pkg/dart2js_info/bin/src/runtime_coverage_analysis.dart
index 9d4bcbe..6323909 100644
--- a/pkg/dart2js_info/bin/src/runtime_coverage_analysis.dart
+++ b/pkg/dart2js_info/bin/src/runtime_coverage_analysis.dart
@@ -35,6 +35,7 @@
 import 'package:dart2js_info/info.dart';
 import 'package:dart2js_info/src/io.dart';
 import 'package:dart2js_info/src/util.dart';
+import 'package:dart2js_info/src/runtime_coverage_utils.dart';
 
 import 'usage_exception.dart';
 
@@ -274,12 +275,9 @@
   // The value associated with each coverage item isn't used for now.
   Set<String> coverage = coverageRaw.keys.toSet();
 
-  final classFilterData = <String, RuntimeClassInfo>{};
-  for (final runtimeClassInfo in File(filterFile)
-      .readAsLinesSync()
-      .map((l) => RuntimeClassInfo.fromAngularInfo(l))) {
-    classFilterData[runtimeClassInfo.key] = runtimeClassInfo;
-  }
+  final classFilterData = {
+    for (final info in runtimeInfoFromAngularInfo(filterFile)) info.key: info
+  };
 
   // Ensure that a used class's super, mixed in, and implemented classes are
   // correctly marked as used.
@@ -313,9 +311,6 @@
     final used = coverage.contains(name);
     final nameWithoutPrefix =
         name.substring(name.indexOf(':') + 1, name.length);
-    if (used) {
-      usedCode += info.size;
-    }
 
     final runtimeClassInfo = classFilterData[nameWithoutPrefix];
     if (runtimeClassInfo == null) {
@@ -445,88 +440,3 @@
 void _leftPadded(String msg1, String msg2) {
   print(' ${pad(msg1, 50, right: true)} $msg2');
 }
-
-class RuntimePackageInfo {
-  final elements = PriorityQueue<BasicInfo>((a, b) => b.size.compareTo(a.size));
-
-  num mainUnitSize = 0;
-  num totalSize = 0;
-  num unusedMainUnitSize = 0;
-  num unusedSize = 0;
-  num usedRatio = 0;
-  num usedSize = 0;
-
-  RuntimePackageInfo();
-
-  void add(BasicInfo i, {bool used = true}) {
-    totalSize += i.size;
-    if (used) {
-      usedSize += i.size;
-    } else {
-      unusedSize += i.size;
-    }
-    if (i.outputUnit!.name == 'main') {
-      mainUnitSize += i.size;
-      if (!used) {
-        unusedMainUnitSize += i.size;
-      }
-    }
-    elements.add(i);
-    usedRatio = usedSize / totalSize;
-  }
-}
-
-class RuntimeClassInfo {
-  late String scheme;
-  late String package;
-  late String? path;
-  late String name;
-
-  late num size;
-  late bool used;
-  late bool inMainUnit;
-  late ClassInfo info;
-
-  bool annotated = false;
-
-  RuntimeClassInfo();
-
-  /// Ingests the output from Angular's info generator.
-  ///
-  /// Example: 'fully:qualified/path/to/file.dart - ClassName'
-  RuntimeClassInfo.fromAngularInfo(String input) {
-    final colonIndex = input.indexOf(':');
-    if (colonIndex < 0) {
-      throw ArgumentError('AngularInfo format cannot accept undefined schemes.'
-          ' No scheme found for: $input');
-    }
-    final slashIndex = input.indexOf('/');
-    final spaceIndex = input.indexOf(' ');
-    final separatorSize = ' - '.length;
-    scheme = input.substring(0, colonIndex);
-    if (slashIndex < 0) {
-      path = null;
-      package = input.substring(colonIndex + 1, spaceIndex);
-    } else {
-      package = input.substring(colonIndex + 1, slashIndex);
-      path = input.substring(slashIndex + 1, spaceIndex);
-    }
-    name = input.substring(spaceIndex + separatorSize, input.length);
-  }
-
-  String get key =>
-      '$package${path == null ? '' : '/$path'}:$name'.replaceAll('/lib/', '/');
-
-  void annotateWithClassInfo(ClassInfo i, {bool used = true}) {
-    size = i.size;
-    this.used = used;
-    inMainUnit = i.outputUnit!.name == 'main';
-    info = i;
-    annotated = true;
-  }
-
-  @override
-  String toString() {
-    return '$package/$path - $name';
-  }
-}
diff --git a/pkg/dart2js_info/lib/src/runtime_coverage_utils.dart b/pkg/dart2js_info/lib/src/runtime_coverage_utils.dart
new file mode 100644
index 0000000..04a1356
--- /dev/null
+++ b/pkg/dart2js_info/lib/src/runtime_coverage_utils.dart
@@ -0,0 +1,117 @@
+import 'dart:io';
+
+import 'package:collection/collection.dart';
+import 'package:dart2js_info/info.dart';
+
+List<RuntimeClassInfo> runtimeInfoFromAngularInfo(String angularInfoFilePath) {
+  final angularInfoFile = File(angularInfoFilePath);
+  final runtimeInfo = <RuntimeClassInfo>[];
+  final separator = ' - ';
+  for (final line in angularInfoFile.readAsLinesSync()) {
+    // Ignore lines without two ' - ' separators.
+    if (separator.allMatches(line).length != 2) continue;
+    runtimeInfo.add(RuntimeClassInfo.fromAngularInfo(line));
+  }
+  return runtimeInfo;
+}
+
+class RuntimePackageInfo {
+  final elements = PriorityQueue<BasicInfo>((a, b) => b.size.compareTo(a.size));
+
+  num mainUnitSize = 0;
+  num totalSize = 0;
+  num unusedMainUnitSize = 0;
+  num unusedSize = 0;
+  num usedRatio = 0;
+  num usedSize = 0;
+
+  RuntimePackageInfo();
+
+  void add(BasicInfo i, {bool used = true}) {
+    totalSize += i.size;
+    if (used) {
+      usedSize += i.size;
+    } else {
+      unusedSize += i.size;
+    }
+    if (i.outputUnit!.name == 'main') {
+      mainUnitSize += i.size;
+      if (!used) {
+        unusedMainUnitSize += i.size;
+      }
+    }
+    elements.add(i);
+    usedRatio = usedSize / totalSize;
+  }
+}
+
+class RuntimeClassInfo {
+  late String scheme;
+  late String package;
+  late String? path;
+  late String name;
+
+  late num size;
+  late bool used;
+  late bool inMainUnit;
+  late ClassInfo info;
+
+  bool annotated = false;
+
+  RuntimeClassInfo();
+
+  RuntimeClassInfo.fromQualifiedName(String qualifiedName) {
+    final colonIndex = qualifiedName.indexOf(':');
+    final slashIndex = qualifiedName.indexOf('/');
+    final colonIndex2 = qualifiedName.lastIndexOf(':');
+    scheme = qualifiedName.substring(0, colonIndex);
+    package = qualifiedName.substring(colonIndex + 1, slashIndex);
+    path = qualifiedName.substring(slashIndex + 1, colonIndex2);
+    name = qualifiedName.substring(colonIndex2 + 1, qualifiedName.length);
+  }
+
+  /// Ingests the output from Angular's info generator.
+  ///
+  /// Example: 'fully:qualified/path/to/file.dart - ClassName - 123 (bytes)'
+  RuntimeClassInfo.fromAngularInfo(String rawInput) {
+    final separator = ' - ';
+    final separatorSize = separator.length;
+    // Remove the size specification.
+    var input = rawInput;
+    if (separator.allMatches(rawInput).length > 1) {
+      input = rawInput.substring(0, rawInput.lastIndexOf(separator));
+    }
+    final colonIndex = input.indexOf(':');
+    if (colonIndex < 0) {
+      throw ArgumentError('AngularInfo format cannot accept undefined schemes.'
+          ' No scheme found for: $input');
+    }
+    final slashIndex = input.indexOf('/');
+    final spaceIndex = input.indexOf(' ');
+    scheme = input.substring(0, colonIndex);
+    if (slashIndex < 0) {
+      path = null;
+      package = input.substring(colonIndex + 1, spaceIndex);
+    } else {
+      package = input.substring(colonIndex + 1, slashIndex);
+      path = input.substring(slashIndex + 1, spaceIndex);
+    }
+    name = input.substring(spaceIndex + separatorSize, input.length);
+  }
+
+  String get key =>
+      '$package${path == null ? '' : '/$path'}:$name'.replaceAll('/lib/', '/');
+
+  void annotateWithClassInfo(ClassInfo i, {bool used = true}) {
+    size = i.size;
+    this.used = used;
+    inMainUnit = i.outputUnit!.name == 'main';
+    info = i;
+    annotated = true;
+  }
+
+  @override
+  String toString() {
+    return '$package/$path - $name';
+  }
+}
diff --git a/pkg/dart2js_info/test/classes/class_filter.txt b/pkg/dart2js_info/test/classes/class_filter.txt
index aa011aa..e1aec5b 100644
--- a/pkg/dart2js_info/test/classes/class_filter.txt
+++ b/pkg/dart2js_info/test/classes/class_filter.txt
@@ -1,5 +1,5 @@
-dart:_rti - _Universe
-dart:core - Error
-testroot:classes.dart - Subsub1
-testroot:classes.dart - Super
-package:expect/expect.dart - Expect
+dart:_rti - _Universe - 300 (bytes)
+dart:core - Error - 300 (bytes)
+testroot:classes.dart - Subsub1 - 300 (bytes)
+testroot:classes.dart - Super - 300 (bytes)
+package:expect/expect.dart - Expect - 300 (bytes)
diff --git a/pkg/dart2js_info/test/runtime_coverage_test.dart b/pkg/dart2js_info/test/runtime_coverage_test.dart
index 9d5d048..d73b836 100644
--- a/pkg/dart2js_info/test/runtime_coverage_test.dart
+++ b/pkg/dart2js_info/test/runtime_coverage_test.dart
@@ -14,10 +14,10 @@
 import 'dart:io';
 
 import 'package:dart2js_info/binary_serialization.dart';
+import 'package:dart2js_info/src/runtime_coverage_utils.dart';
 import 'package:dart2js_info/src/util.dart';
-import 'package:test/test.dart';
 
-import '../bin/src/runtime_coverage_analysis.dart';
+import 'package:test/test.dart';
 
 void main() {
   group('runtime coverage', () {
diff --git a/pkg/dart2native/lib/dart2native_macho.dart b/pkg/dart2native/lib/dart2native_macho.dart
index b10133e..701e3c3 100644
--- a/pkg/dart2native/lib/dart2native_macho.dart
+++ b/pkg/dart2native/lib/dart2native_macho.dart
@@ -2,244 +2,15 @@
 // 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 'dart:io';
 import 'dart:math';
-import 'dart:typed_data';
 
-import 'package:dart2native/macho.dart';
-import 'package:dart2native/macho_parser.dart';
-
-const String kSnapshotSegmentName = "__CUSTOM";
-const String kSnapshotSectionName = "__dart_app_snap";
-const int kMinimumSegmentSize = 0x4000;
-// Since arm64 macOS has 16K pages, which is larger than the 4K pages on x64
-// macOS, we use this larger page size to ensure the MachO file is aligned
-// properly on all architectures.
-const int kSegmentAlignment = 0x4000;
-
-int align(int size, int base) {
-  final int over = size % base;
-  if (over != 0) {
-    return size + (base - over);
-  }
-  return size;
-}
-
-// Utility for aligning parts of MachO headers to the defined sizes.
-int vmSizeAlign(int size) {
-  return align(max(size, kMinimumSegmentSize), kSegmentAlignment);
-}
-
-// Returns value + amount only if the original value is within the bounds
-// defined by [withinStart, withinStart + withinSize).
-Uint32 addIfWithin(
-    Uint32 value, Uint64 amount, Uint64 withinStart, Uint64 withinSize) {
-  final intWithinStart = withinStart.asInt();
-  final intWithinSize = withinSize.asInt();
-
-  if (value >= intWithinStart && value < (intWithinStart + intWithinSize)) {
-    return (value.asUint64() + amount).asUint32();
-  } else {
-    return value;
-  }
-}
-
-// Trims a bytestring that an arbitrary number of null characters on the end of
-// it.
-String trimmedBytestring(Uint8List bytestring) {
-  return String.fromCharCodes(bytestring.takeWhile((value) => value != 0));
-}
+import './macho.dart';
+import './macho_utils.dart';
 
 // Simplifies casting so we get null values back instead of exceptions.
 T? cast<T>(x) => x is T ? x : null;
 
-// Inserts a segment definition into a MachOFile. This does NOT insert the
-// actual segment into the file. It only inserts the definition of that segment
-// into the MachO header.
-//
-// In addition to simply specifying the definition for the segment, this
-// function also moves the existing __LINKEDIT segment to the end of the header
-// definition as is required by the MachO specification (or at least MacOS's
-// implementation of it). In doing so there are several offsets in the original
-// __LINKEDIT segment that must be updated to point to their new location
-// because the __LINKEDIT segment and sections are now in a different
-// place. This function takes care of those shifts as well.
-//
-// Returns the original, unmodified, __LINKEDIT segment.
-Future<MachOSegmentCommand64> insertSegmentDefinition(MachOFile file,
-    File segment, String segmentName, String sectionName) async {
-  // Load in the data to be inserted.
-  final segmentData = await segment.readAsBytes();
-
-  // Find the existing __LINKEDIT segment
-  final linkedit = cast<MachOSegmentCommand64>(file.commands
-      .where((segment) =>
-          segment.asType() is MachOSegmentCommand64 &&
-          MachOConstants.SEG_LINKEDIT ==
-              trimmedBytestring((segment as MachOSegmentCommand64).segname))
-      .first);
-
-  final linkeditIndex = file.commands.indexWhere((segment) =>
-      segment.asType() is MachOSegmentCommand64 &&
-      MachOConstants.SEG_LINKEDIT ==
-          trimmedBytestring((segment as MachOSegmentCommand64).segname));
-
-  if (linkedit == null) {
-    throw FormatException(
-        "Could not find a __LINKEDIT section in the specified binary.");
-  } else {
-    // Create the new segment.
-    final Uint8List segname = Uint8List(16);
-    segname.setRange(0, segmentName.length, ascii.encode(segmentName));
-    segname.fillRange(segmentName.length, 16, 0);
-
-    final Uint64 vmaddr = linkedit.vmaddr;
-    final Uint64 vmsize = Uint64(vmSizeAlign(segmentData.length));
-    final Uint64 fileoff = linkedit.fileoff;
-    final Uint64 filesize = vmsize;
-    final Int32 maxprot = MachOConstants.VM_PROT_READ;
-    final Int32 initprot = maxprot;
-    final Uint32 nsects = Uint32(1);
-
-    final Uint8List sectname = Uint8List(16);
-    sectname.setRange(0, sectionName.length, ascii.encode(sectionName));
-    sectname.fillRange(sectionName.length, 16, 0);
-
-    final Uint64 addr = vmaddr;
-    final Uint64 size = Uint64(segmentData.length);
-    final Uint32 offset = fileoff.asUint32();
-    final Uint32 flags = MachOConstants.S_REGULAR;
-
-    final Uint32 zero = Uint32(0);
-
-    final loadCommandDefinitionSize = 4 * 2;
-    final sectionDefinitionSize = 16 * 2 + 8 * 2 + 4 * 8;
-    final segmentDefinitionSize = 16 + 8 * 4 + 4 * 4;
-    final commandSize = loadCommandDefinitionSize +
-        segmentDefinitionSize +
-        sectionDefinitionSize;
-
-    final loadCommand =
-        MachOLoadCommand(MachOConstants.LC_SEGMENT_64, Uint32(commandSize));
-
-    final section = MachOSection64(sectname, segname, addr, size, offset, zero,
-        zero, zero, flags, zero, zero, zero);
-
-    final segment = MachOSegmentCommand64(Uint32(commandSize), segname, vmaddr,
-        vmsize, fileoff, filesize, maxprot, initprot, nsects, zero, [section]);
-
-    // Setup the new linkedit command.
-    final shiftedLinkeditVmaddr = linkedit.vmaddr + segment.vmsize;
-    final shiftedLinkeditFileoff = linkedit.fileoff + segment.filesize;
-    final shiftedLinkedit = MachOSegmentCommand64(
-        linkedit.cmdsize,
-        linkedit.segname,
-        shiftedLinkeditVmaddr,
-        linkedit.vmsize,
-        shiftedLinkeditFileoff,
-        linkedit.filesize,
-        linkedit.maxprot,
-        linkedit.initprot,
-        linkedit.nsects,
-        linkedit.flags,
-        linkedit.sections);
-
-    // Shift all of the related commands that need to reference the new file
-    // position of the linkedit segment.
-    for (var i = 0; i < file.commands.length; i++) {
-      final command = file.commands[i];
-
-      final offsetAmount = segment.filesize;
-      final withinStart = linkedit.fileoff;
-      final withinSize = linkedit.filesize;
-
-      // For the specific command that we need to adjust, we need to move the
-      // commands' various offsets forward by the new segment's size in the file
-      // (segment.filesize). However, we need to ensure that when we move the
-      // offset forward, we exclude cases where the offset was originally
-      // outside of the linkedit segment (i.e. offset < linkedit.fileoff or
-      // offset >= linkedit.fileoff + linkedit.filesize). The DRY-ing function
-      // addIfWithin takes care of that repeated logic.
-      if (command is MachODyldInfoCommand) {
-        file.commands[i] = MachODyldInfoCommand(
-            command.cmd,
-            command.cmdsize,
-            addIfWithin(
-                command.rebase_off, offsetAmount, withinStart, withinSize),
-            command.rebase_size,
-            addIfWithin(
-                command.bind_off, offsetAmount, withinStart, withinSize),
-            command.bind_size,
-            addIfWithin(
-                command.weak_bind_off, offsetAmount, withinStart, withinSize),
-            command.weak_bind_size,
-            addIfWithin(
-                command.lazy_bind_off, offsetAmount, withinStart, withinSize),
-            command.lazy_bind_size,
-            addIfWithin(
-                command.export_off, offsetAmount, withinStart, withinSize),
-            command.export_size);
-      } else if (command is MachOSymtabCommand) {
-        file.commands[i] = MachOSymtabCommand(
-            command.cmdsize,
-            addIfWithin(command.symoff, offsetAmount, withinStart, withinSize),
-            command.nsyms,
-            addIfWithin(command.stroff, offsetAmount, withinStart, withinSize),
-            command.strsize);
-      } else if (command is MachODysymtabCommand) {
-        file.commands[i] = MachODysymtabCommand(
-            command.cmdsize,
-            command.ilocalsym,
-            command.nlocalsym,
-            command.iextdefsym,
-            command.nextdefsym,
-            command.iundefsym,
-            command.nundefsym,
-            addIfWithin(command.tocoff, offsetAmount, withinStart, withinSize),
-            command.ntoc,
-            addIfWithin(
-                command.modtaboff, offsetAmount, withinStart, withinSize),
-            command.nmodtab,
-            addIfWithin(
-                command.extrefsymoff, offsetAmount, withinStart, withinSize),
-            command.nextrefsyms,
-            addIfWithin(
-                command.indirectsymoff, offsetAmount, withinStart, withinSize),
-            command.nindirectsyms,
-            addIfWithin(
-                command.extreloff, offsetAmount, withinStart, withinSize),
-            command.nextrel,
-            addIfWithin(
-                command.locreloff, offsetAmount, withinStart, withinSize),
-            command.nlocrel);
-      } else if (command is MachOLinkeditDataCommand) {
-        file.commands[i] = MachOLinkeditDataCommand(
-            command.cmd,
-            command.cmdsize,
-            addIfWithin(command.dataoff, offsetAmount, withinStart, withinSize),
-            command.datasize);
-      }
-    }
-
-    // Now we need to build the new header from these modified pieces.
-    file.header = MachOHeader(
-        file.header!.magic,
-        file.header!.cputype,
-        file.header!.cpusubtype,
-        file.header!.filetype,
-        file.header!.ncmds + Uint32(1),
-        file.header!.sizeofcmds + loadCommand.cmdsize,
-        file.header!.flags,
-        file.header!.reserved);
-
-    file.commands[linkeditIndex] = shiftedLinkedit;
-    file.commands.insert(linkeditIndex, segment);
-  }
-
-  return linkedit;
-}
-
 // Pipe from one file stream into another. We do this in chunks to avoid
 // excessive memory load.
 Future<int> pipeStream(RandomAccessFile from, RandomAccessFile to,
@@ -297,17 +68,22 @@
     String dartaotruntimePath, String payloadPath, String outputPath) async {
   File originalExecutableFile = File(dartaotruntimePath);
 
-  MachOFile machOFile = MachOFile();
-  await machOFile.loadFromFile(originalExecutableFile);
+  MachOFile machOFile = MachOFile.fromFile(originalExecutableFile);
+  final oldLinkEditSegmentFileOffset = machOFile.linkEditSegment?.fileOffset;
+  if (oldLinkEditSegmentFileOffset == null) {
+    throw FormatException("__LINKEDIT segment not found");
+  }
 
   // Insert the new segment that contains our snapshot data.
   File newSegmentFile = File(payloadPath);
 
-  // Note that these two values MUST match the ones in
-  // runtime/bin/snapshot_utils.cc, which looks specifically for the snapshot in
-  // this segment/section.
-  final linkeditCommand = await insertSegmentDefinition(
-      machOFile, newSegmentFile, kSnapshotSegmentName, kSnapshotSectionName);
+  // Get the length of the contents of the section to be added.
+  final payloadLength = newSegmentFile.lengthSync();
+  // We only need the original offset of the __LINKEDIT segment from the
+  // original headers, which we've already retrieved. Thus, use the new
+  // MachOFile from inserting the snapshot segment from here on.
+  machOFile = machOFile.insertSegmentLoadCommand(
+      payloadLength, snapshotSegmentName, snapshotSectionName);
 
   // Write out the new executable, with the same contents except the new header.
   File outputFile = File(outputPath);
@@ -321,16 +97,22 @@
   RandomAccessFile originalFileStream = await originalExecutableFile.open();
   await originalFileStream.setPosition(headerBytesWritten);
 
-  // Write the unchanged data from the original file.
+  // Write the unchanged data from the original file up to the __LINKEDIT
+  // segment contents, so we can insert the snapshot there.
   await pipeStream(originalFileStream, stream,
-      numToWrite: linkeditCommand.fileoff.asInt() - headerBytesWritten);
+      numToWrite: oldLinkEditSegmentFileOffset - headerBytesWritten);
+
+  void addPadding(int size) => stream.writeFromSync(List.filled(size, 0));
+
+  final snapshotSegment = machOFile.snapshotSegment!;
+  // There may be additional padding needed between the old __LINKEDIT file
+  // offset and the start of the new snapshot.
+  addPadding(snapshotSegment.fileOffset - oldLinkEditSegmentFileOffset);
 
   // Write the inserted section data, ensuring that the data is padded to the
   // segment size.
   await pipeStream(newSegmentFileStream, stream);
-  final int newSegmentLength = newSegmentFileStream.lengthSync();
-  final int alignedSegmentSize = vmSizeAlign(newSegmentLength);
-  await stream.writeFrom(List.filled(alignedSegmentSize - newSegmentLength, 0));
+  addPadding(align(payloadLength, segmentAlignment) - payloadLength);
 
   // Copy the rest of the file from the original to the new one.
   await pipeStream(originalFileStream, stream);
diff --git a/pkg/dart2native/lib/generate.dart b/pkg/dart2native/lib/generate.dart
index 23797c9..9ddb38f 100644
--- a/pkg/dart2native/lib/generate.dart
+++ b/pkg/dart2native/lib/generate.dart
@@ -67,22 +67,10 @@
           if (soundNullSafety != null)
             '--${soundNullSafety ? '' : 'no-'}sound-null-safety',
         ]);
+    await _forwardOutput(kernelResult);
     if (kernelResult.exitCode != 0) {
-      // We pipe both stdout and stderr to stderr because the CFE doesn't print
-      // errors to stderr. This unfortunately does emit info-only output in
-      // stderr, though.
-      stderr.write(kernelResult.stdout);
-      stderr.write(kernelResult.stderr);
-      await stderr.flush();
       throw 'Generating AOT kernel dill failed!';
     }
-    // Pipe info and warnings from the CFE to stdout since the compilation
-    // succeeded. Stderr should be empty but we pipe it to stderr for
-    // completeness.
-    stdout.write(kernelResult.stdout);
-    await stdout.flush();
-    stderr.write(kernelResult.stderr);
-    await stderr.flush();
 
     if (verbose) {
       print('Generating AOT snapshot.');
@@ -93,10 +81,11 @@
         : path.join(tempDir.path, 'snapshot.aot'));
     final snapshotResult = await generateAotSnapshot(genSnapshot, kernelFile,
         snapshotFile, debugPath, enableAsserts, extraOptions);
+
+    if (verbose || snapshotResult.exitCode != 0) {
+      await _forwardOutput(snapshotResult);
+    }
     if (snapshotResult.exitCode != 0) {
-      stderr.writeln(snapshotResult.stdout);
-      stderr.writeln(snapshotResult.stderr);
-      await stderr.flush();
       throw 'Generating AOT snapshot failed!';
     }
 
@@ -119,3 +108,22 @@
     tempDir.deleteSync(recursive: true);
   }
 }
+
+Future<void> _forwardOutput(ProcessResult result) async {
+  if (result.stdout.isNotEmpty) {
+    final bool needsNewLine = !result.stdout.endsWith('\n');
+    if (result.exitCode == 0) {
+      stdout.write(result.stdout);
+      if (needsNewLine) stdout.writeln();
+      await stdout.flush();
+    } else {
+      stderr.write(result.stdout);
+      if (needsNewLine) stderr.writeln();
+    }
+  }
+  if (result.stderr.isNotEmpty) {
+    stderr.write(result.stderr);
+    if (!result.stderr.endsWith('\n')) stderr.writeln();
+    await stderr.flush();
+  }
+}
diff --git a/pkg/dart2native/lib/macho.dart b/pkg/dart2native/lib/macho.dart
index 9294483..3919d92 100644
--- a/pkg/dart2native/lib/macho.dart
+++ b/pkg/dart2native/lib/macho.dart
@@ -9,429 +9,585 @@
 // ignore_for_file: non_constant_identifier_names, constant_identifier_names
 
 import 'dart:io';
+import 'dart:math';
 import 'dart:typed_data';
 
-// Extensions for writing the custom byte types (defined below) to streams
-// (RandomAccessFile).
-extension ByteWriter on RandomAccessFile {
-  void writeUint32(Uint32 value) {
-    final intValue = value.asInt();
-    for (int i = 0; i < 4; i++) {
-      writeByteSync((intValue >> (8 * i)) & 0xff);
+import './macho_utils.dart';
+
+class OffsetsAdjuster {
+  /// A sorted list of non-negative offsets signifying the start of
+  /// non-overlapping adjustment ranges, so either up to (but not including) the
+  /// next listed offset or the end of the file.
+  final offsets = <int>[0];
+
+  /// The map of offsets to the adjustment needed for their adjustment range.
+  final adjustments = <int, int>{0: 0};
+
+  /// Adds a new adjustment at the given offset. If there is not an existing
+  /// adjustment range starting at that offset, the adjustment range containing
+  /// that offset is split, and all adjustment ranges that start at that offset
+  /// or at later offsets have their adjustment increased accordingly.
+  void add(int offset, int adjustment) {
+    assert(offset >= 0);
+    assert(adjustment >= 0);
+    var startingIndex = offsets.lastIndexWhere((o) => o <= offset);
+    // If the offset didn't already have an adjustment range, split the previous
+    // range
+    if (offsets[startingIndex] != offset) {
+      final newIndex = startingIndex + 1;
+      // Add a new adjustment range that starts at the offset and has an
+      // initial adjustment value that's the same as the previous range the
+      // offset was in.
+      offsets.insert(newIndex, offset);
+      adjustments[offset] = adjustments[offsets[startingIndex]]!;
+      // Start making adjustments at the new range.
+      startingIndex = newIndex;
+    }
+    // Adjust the adjustments for all ranges that start at the given offset
+    // or later.
+    for (int i = startingIndex; i < offsets.length; i++) {
+      final off = offsets[i];
+      adjustments[off] = adjustments[offset]! + adjustment;
     }
   }
 
-  void writeUint64(Uint64 value) {
-    final intValue = value.asInt();
-    for (int i = 0; i < 8; i++) {
-      writeByteSync((intValue >> (8 * i)) & 0xff);
-    }
-  }
-
-  void writeInt32(Int32 value) {
-    final intValue = value.asInt();
-    for (int i = 0; i < 4; i++) {
-      writeByteSync((intValue >> (8 * i)) & 0xff);
-    }
+  /// Adjusts the given offset according to the adjustment ranges collected.
+  int adjust(int offset) {
+    assert(offset >= 0);
+    // We should always get a valid index since we add an entry for the start
+    // of the file.
+    final rangeStart = offsets.lastWhere((o) => o <= offset);
+    return offset + adjustments[rangeStart]!;
   }
 }
 
-// The dart ffi library doesn't have definitions for integer operations (among
-// others) on ffi types. Since we use those operations prolifically in handling
-// MachO files, these are here as a convenience to avoid polluting the code with
-// casts and operations.
-abstract class IntLike {
-  final int _data;
-  const IntLike(this._data);
+enum CpuType {
+  i386(_typeX86, 'I386'),
+  x64(_typeX86 | _architectureABI64, 'X64'),
+  arm(_typeArm, 'ARM'),
+  arm64(_typeArm | _architectureABI64, 'ARM64');
 
-  int asInt() => _data;
+  final int _code;
+  final String _headerName;
+
+  const CpuType(this._code, this._headerName);
+
+  /// Marks an architecture as using a 64-bit ABI.
+  static const _architectureABI64 = 0x0100000;
+
+  /// The base type of all X86 architecture variants.
+  static const _typeX86 = 0x7;
+
+  /// The base type of all ARM architecture variants.
+  static const _typeArm = 0x12;
+
+  static const _prefix = 'CPU_TYPE';
+
+  static CpuType? fromCode(int code) {
+    for (final value in values) {
+      if (value._code == code) {
+        return value;
+      }
+    }
+    return null;
+  }
+
+  /// Returns whether the architecture represented by a given `cputype` value
+  /// from the MachO header uses 64-bit pointers.
+  static bool cpuTypeUses64BitPointers(int code) =>
+      code & _architectureABI64 == _architectureABI64;
+
+  /// Returns whether the architecture represented by this uses 64-bit pointers.
+  bool get uses64BitPointers => cpuTypeUses64BitPointers(_code);
 
   @override
-  String toString() => asInt().toString();
+  String toString() => '${_prefix}_$_headerName';
 }
 
-class Uint64 extends IntLike {
-  const Uint64(int data) : super(data);
+enum VirtualMemoryProtection {
+  none(0x00, 'NONE'),
+  read(0x01, 'READ'),
+  write(0x02, 'WRITE'),
+  execute(0x04, 'EXECUTE');
 
-  Uint64 operator +(Uint64 other) {
-    return Uint64(_data + other._data);
-  }
+  final int code;
+  final String _headerName;
 
-  Uint32 asUint32() {
-    if (_data < 0 || _data >= (1 << 32)) {
-      throw FormatException(
-          "Attempted to cast a Uint64 to a Uint32, but the value will not fit in "
-          "32bits: $_data");
-    }
+  const VirtualMemoryProtection(this.code, this._headerName);
 
-    return Uint32(_data);
-  }
-
-  bool operator <(int other) {
-    // All positively encoded integers are less than negatively encoded ones.
-    if (_data < 0 && other > 0) {
-      return false;
-    }
-    if (other < 0) {
-      return true;
-    }
-    return _data < other;
-  }
-
-  bool operator >(int other) {
-    // All negatively encoded integers are greater than positively encoded ones.
-    if (_data < 0 && other > 0) {
-      return true;
-    }
-    if (other < 0) {
-      return false;
-    }
-    return _data > other;
-  }
+  static const _prefix = 'VM_PROT';
 
   @override
-  bool operator ==(other) {
-    if (other is Uint64) {
-      return _data == other._data;
-    } else {
-      return false;
-    }
-  }
-
-  @override
-  int get hashCode => _data.hashCode;
+  String toString() => '${_prefix}_$_headerName';
 }
 
-class Int32 extends IntLike {
-  const Int32(int data) : super(data);
+enum LoadCommandType {
+  // Note that entries marked 'obsolete' in the C headers have not been
+  // translated into enum values below.
+  //
+  // We also do not translate entries that we need not understand (even
+  // if LC_REQ_DYLD is set).
 
-  Int32 operator |(Int32 other) {
-    return Int32(_data | other._data);
+  /// A 32-bit segment of the file that is mapped into memory at runtime.
+  segment(0x1, 'SEGMENT'),
+
+  /// The static symbol table.
+  symbolTable(0x2, 'SYMTAB'),
+
+  /// The dynamic symbol table.
+  dynamicSymbolTable(0xb, 'DYSYMTAB'),
+
+  /// A 64-bit segment of the file that is mapped into memory at runtime.
+  segment64(0x19, 'SEGMENT_64'),
+
+  /// A code signature.
+  codeSignature(0x1d, 'CODE_SIGNATURE'),
+
+  /// Information to split segments.
+  segmentSplitInfo(0x1e, 'SEGMENT_SPLIT_INFO'),
+
+  /// 32-bit encrypted segment information.
+  encryptionInfo(0x21, 'ENCRYPTION_INFO'),
+
+  /// Compressed dynamically linked shared library information.
+  ///
+  /// Note that the C headers include a separate name for the version that has
+  /// LD_REQ_DYLD set: LC_DYLD_INFO_ONLY. We do not include this name.
+  dynamicLibraryInfo(0x22, 'DYLD_INFO'),
+
+  /// Compressed table of function start addresses.
+  functionStarts(0x26, 'FUNCTION_STARTS'),
+
+  /// Main entry point (replacement for LC_UNIXTHREAD).
+  main(0x28 | _reqDyld, 'MAIN'),
+
+  /// Table of non-instructions in the text segment.
+  dataInCode(0x29, 'DATA_IN_CODE'),
+
+  /// Code signing DRs copied from dynamically linked shared libraries.
+  dynamicLibraryCodeSigningDRs(0x2b, 'DYLIB_CODE_SIGN_DRS'),
+
+  /// 64-bit encrypted segment information.
+  encryptionInfo64(0x2c, 'ENCRYPTION_INFO_64'),
+
+  /// Optimization hints in object files.
+  linkerOptimizationHint(0x2e, 'LINKER_OPTIMIZATION_HINT'),
+
+  /// Arbitrary data included within a MachO file.
+  note(0x31, 'NOTE'),
+
+  /// A trie of dynamically linked shared library exports.
+  dynamicLibraryExportsTrie(0x33 | _reqDyld, 'DYLD_EXPORTS_TRIE'),
+
+  /// Chained fixups for dynamically linked shared libraries.
+  dynamicLibraryChainedFixups(0x34 | _reqDyld, 'DYLD_CHAINED_FIXUPS'),
+
+  /// A fileset entry.
+  fileSetEntry(0x35 | _reqDyld, 'FILESET_ENTRY');
+
+  /// After MacOS X 10.1 when a new load command is added that is required to be
+  /// understood by the dynamic linker for the image to execute properly, this
+  /// bit will be or'ed into the load command constant. If the dynamic
+  /// linker sees such a load command it it does not understand will issue a
+  /// "unknown load command required for execution" error and refuse to use the
+  /// image.  Other load commands without this bit that are not understood will
+  /// simply be ignored.
+  ///
+  /// `LC_REQ_DYLD` in the C headers.
+  static const _reqDyld = 0x80000000;
+
+  final int code;
+  final String _headerName;
+
+  const LoadCommandType(this.code, this._headerName);
+
+  static const _prefix = "LC";
+
+  static LoadCommandType? fromCode(int code) {
+    for (final value in values) {
+      if ((value.code & _reqDyld != 0)) {
+        /// LC_REQ_DYLD is set on the enum value, so it can only match exactly.
+        if (value.code == code) {
+          return value;
+        }
+      } else {
+        /// The LC_REQ_DYLD bit should be ignored for matching purposes.
+        final stripped = code & ~_reqDyld;
+        if (value.code == stripped) {
+          return value;
+        }
+      }
+    }
+    return null;
   }
 
   @override
-  bool operator ==(other) {
-    if (other is Int32) {
-      return _data == other._data;
-    } else {
-      return false;
+  String toString() => '${_prefix}_$_headerName';
+}
+
+/// A load command describes how to load and use various parts of the file
+/// contents (e.g., where to find the TEXT and DATA sections).
+abstract class MachOLoadCommand {
+  /// The encoding of this load command's type as a 32-bit value.
+  ///
+  /// `uint32_t cmd` in the C headers.
+  final int code;
+
+  /// The total size of the load command in bytes, including the type and size
+  /// fields.
+  ///
+  /// `uint32_t cmdsize` in the C headers.
+  final int size;
+
+  MachOLoadCommand(this.code, this.size);
+
+  static MachOLoadCommand fromStream(MachOReader stream) {
+    final code = stream.readUint32();
+    final size = stream.readUint32();
+
+    final type = LoadCommandType.fromCode(code);
+    if (type == null) {
+      // Not a MachO section that needs to be adjusted for offset changes, so
+      // just read the bytes without interpretation.
+      final contents = stream.readBytes(size - 2 * 4);
+      return MachOGenericLoadCommand(code, size, contents);
+    }
+
+    switch (type) {
+      case LoadCommandType.segment:
+      case LoadCommandType.segment64:
+        return MachOSegmentCommand.fromStream(code, size, stream);
+      case LoadCommandType.dynamicLibraryInfo:
+        return MachODyldInfoCommand.fromStream(code, size, stream);
+      case LoadCommandType.symbolTable:
+        return MachOSymtabCommand.fromStream(code, size, stream);
+      case LoadCommandType.dynamicSymbolTable:
+        return MachODysymtabCommand.fromStream(code, size, stream);
+      case LoadCommandType.codeSignature:
+      case LoadCommandType.segmentSplitInfo:
+      case LoadCommandType.functionStarts:
+      case LoadCommandType.dataInCode:
+      case LoadCommandType.dynamicLibraryCodeSigningDRs:
+      case LoadCommandType.linkerOptimizationHint:
+      case LoadCommandType.dynamicLibraryExportsTrie:
+      case LoadCommandType.dynamicLibraryChainedFixups:
+        return MachOLinkeditDataCommand.fromStream(code, size, stream);
+      case LoadCommandType.encryptionInfo:
+      case LoadCommandType.encryptionInfo64:
+        return MachOEncryptionInfoCommand.fromStream(code, size, stream);
+      case LoadCommandType.main:
+        return MachOEntryPointCommand.fromStream(code, size, stream);
+      case LoadCommandType.note:
+        return MachONoteCommand.fromStream(code, size, stream);
+      case LoadCommandType.fileSetEntry:
+        return MachOFileSetEntryCommand.fromStream(code, size, stream);
     }
   }
 
-  @override
-  int get hashCode => _data.hashCode;
-}
+  /// The type for this load command. Returns null for MachOGenericLoadCommand.
+  LoadCommandType? get type => LoadCommandType.fromCode(code);
 
-class Uint16 extends IntLike {
-  const Uint16(int data) : super(data);
-}
+  /// Whether or not the dynamic linker is required to understand this load
+  /// command.
+  bool get mustBeUnderstood => (code & LoadCommandType._reqDyld) != 0;
 
-class Uint32 extends IntLike {
-  const Uint32(int data) : super(data);
+  // Overwrite in subclasses that are used in the minimumFileOffset calculation.
+  int? get minimumFileOffset => null;
 
-  Uint32 operator |(Uint32 other) {
-    return Uint32(_data | other._data);
-  }
+  // Returns a version of the load command with any file offsets appropriately
+  // adjusted as needed. Should be overloaded by any load commands that contain
+  // file offsets.
+  MachOLoadCommand adjust(OffsetsAdjuster adjuster) => this;
 
-  Uint32 operator +(Uint32 other) {
-    return Uint32(_data + other._data);
-  }
-
-  Uint32 operator &(Uint32 other) {
-    return Uint32(_data & other._data);
-  }
-
-  Uint32 operator >>(Uint32 other) {
-    return Uint32(_data >> other._data);
-  }
-
-  bool operator <(int other) {
-    return _data < other;
-  }
-
-  bool operator >(int other) {
-    return _data > other;
-  }
-
-  bool operator >=(int other) {
-    return _data >= other;
-  }
-
-  @override
-  bool operator ==(other) {
-    if (other is Uint32) {
-      return _data == other._data;
-    } else {
-      return false;
-    }
-  }
-
-  @override
-  int get hashCode => _data.hashCode;
-
-  Uint64 asUint64() {
-    return Uint64(_data);
-  }
-}
-
-// A load command is simply a part of the MachO header that indicates there is
-// typed schema that a consumer of the headers can use to understand how to load
-// and run various parts of the file (e.g. where to find the TEXT and DATA
-// sections). Every load command with a known schema in a MachO header should
-// extend this abstract class. This class does not appear in the original MachO
-// definitions, but is useful for the object-oriented nature of this
-// implementation.
-abstract class IMachOLoadCommand<T> {
-  /* type of load command (uint32_t) */
-  final Uint32 cmd;
-  /* total size of command in bytes (uint32_t) */
-  final Uint32 cmdsize;
-
-  IMachOLoadCommand(this.cmd, this.cmdsize);
-  T asType();
-
-  void writeSync(RandomAccessFile stream) {
-    stream.writeUint32(cmd);
-    stream.writeUint32(cmdsize);
+  void writeSync(MachOWriter stream) {
+    stream
+      ..writeUint32(code)
+      ..writeUint32(size);
     writeContentsSync(stream);
   }
 
   // Subclasses need to implement this serializer, which should NOT
   // attempt to serialize the cmd and the cmdsize to the stream. That
   // logic is handled by the parent class automatically.
-  void writeContentsSync(RandomAccessFile stream);
+  void writeContentsSync(MachOWriter stream);
 }
 
-// In cases where it's not necessary to actually deserialize a load command into
-// its schema, we use this catch-all class.
-class MachOGenericLoadCommand
-    extends IMachOLoadCommand<MachOGenericLoadCommand> {
+/// A MachO load command that can be copied wholesale without any adjustments.
+class MachOGenericLoadCommand extends MachOLoadCommand {
   final Uint8List contents;
 
   MachOGenericLoadCommand(cmd, cmdsize, this.contents) : super(cmd, cmdsize);
 
   @override
-  MachOGenericLoadCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeFromSync(contents);
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeBytes(contents);
   }
 }
 
-// There are two types of headers: 32bit and 64bit. The only difference is that
-// 64bit headers have a reserved field. This class does not appear in the
-// original header definitions, but is useful for the object-oriented nature of
-// this implementation.
-abstract class IMachOHeader {
-  /* mach magic number identifier (uint32_t) */
-  final Uint32 magic;
-  /* cpu specifier (uint32_t) */
-  final Uint32 cputype;
-  /* machine specifier (uint32_t) */
-  final Uint32 cpusubtype;
-  /* type of file (uint32_t) */
-  final Uint32 filetype;
-  /* number of load commands (uint32_t) */
-  final Uint32 ncmds;
-  /* the size of all the load commands (uint32_t) */
-  final Uint32 sizeofcmds;
-  /* flags (uint32_t) */
-  final Uint32 flags;
+/// The header of a MachO file. There are 32-bit and 64-bit variations, but
+/// the only difference is that 64-bit headers have a reserved field for
+/// padding. Thus, we merge the two into a single class.
+class MachOHeader {
+  /// The magic number identifier for the MachO file. Denotes whether the file
+  /// is 32-bit or 64-bit, and whether its endianness matches the host.
+  ///
+  /// `uint32_t magic` in the C headers.
+  final int magic;
 
-  /* reserved (uint32_t) */
-  final Uint32 reserved; // Only used in 64bit MachO files
+  /// The CPU type assumed by this MachO file.
+  ///
+  /// `cpu_type_t cputype` in the C headers, where `cpu_type_t` is
+  /// `integer_t` which is `int`.
+  final int cpu;
 
-  IMachOHeader(
-    this.magic,
-    this.cputype,
-    this.cpusubtype,
-    this.filetype,
-    this.ncmds,
-    this.sizeofcmds,
-    this.flags,
-    this.reserved,
-  );
+  /// The machine type assumed by this MachO file.
+  ///
+  /// `cpu_subtype_t cpusubtype` in the C headers, where `cpu_subtype_t` is
+  /// `integer_t` which is `int`.
+  final int machine;
+
+  /// The type of the MachO file.
+  ///
+  /// `uint32_t filetype` in the C headers.
+  final int type;
+
+  /// The number of load commands in this MachO file.
+  ///
+  /// `uint32_t ncmds` in the C headers.
+  final int loadCommandsCount;
+
+  /// The total size of the load commands.
+  ///
+  /// `uint32_t sizeofcmds` in the C headers.
+  final int loadCommandsSize;
+
+  /// A bit array of flags in the MachO file.
+  ///
+  /// `uint32_t flags` in the C headers.
+  final int flags;
+
+  /// Reserved space in 64-bit headers, null in 32-bit headers.
+  ///
+  /// `uint32_t reserved` in the C headers.
+  final int? reserved;
+
+  MachOHeader(this.magic, this.cpu, this.machine, this.type,
+      this.loadCommandsCount, this.loadCommandsSize, this.flags, this.reserved);
+
+  /// Constant for the magic field of a 32-bit mach_header with host endianness.
+  static const int _magic32 = 0xfeedface;
+
+  /// Constant for the magic field of a 32-bit mach_header with swapped
+  /// endianness.
+  static const int _cigam32 = 0xcefaedfe;
+
+  /// Constant for the magic field of a 64-bit mach_header with host endianness.
+  static const int _magic64 = 0xfeedfacf;
+
+  /// Constant for the magic field of a 64-bit mach_header with swapped
+  /// endianness.
+  static const int _cigam64 = 0xcffaedfe;
+
+  static MachOHeader? fromStream(RandomAccessFile original) {
+    // First, read the magic value using host endianness, so we can determine
+    // whether the file uses host endianness or swapped endianness.
+    final magic = MachOReader(original, Endian.host).readUint32();
+
+    if (!validMagic(magic)) return null;
+
+    final is64Bit = magic == _magic64 || magic == _cigam64;
+    final endian = magicEndian(magic);
+
+    // Now recreate the MachOReader with the right endianness.
+    final stream = MachOReader(original, endian);
+    final cpu = stream.readInt32();
+    final machine = stream.readInt32();
+    final type = stream.readUint32();
+    final loadCommandsCount = stream.readUint32();
+    final loadCommandsSize = stream.readUint32();
+    final flags = stream.readUint32();
+    final reserved = is64Bit ? stream.readUint32() : null;
+
+    return MachOHeader(magic, cpu, machine, type, loadCommandsCount,
+        loadCommandsSize, flags, reserved);
+  }
+
+  static bool validMagic(int magic) =>
+      magic == _magic32 ||
+      magic == _magic64 ||
+      magic == _cigam32 ||
+      magic == _cigam64;
+
+  static Endian magicEndian(int magic) =>
+      (magic == _magic64 || magic == _magic32)
+          ? Endian.host
+          : Endian.host == Endian.big
+              ? Endian.little
+              : Endian.big;
+
+  // A faster check than rechecking the magic number.
+  bool get is64Bit => reserved != null;
+  Endian get endian => magicEndian(magic);
+
+  void writeSync(RandomAccessFile original) {
+    // Like reading, first we write the magic value using host endianness,
+    // and then write the rest of the value using the detected endianness.
+    MachOWriter(original, Endian.host).writeUint32(magic);
+    final stream = MachOWriter(original, endian);
+    stream
+      ..writeInt32(cpu)
+      ..writeInt32(machine)
+      ..writeUint32(type)
+      ..writeUint32(loadCommandsCount)
+      ..writeUint32(loadCommandsSize)
+      ..writeUint32(flags);
+    if (is64Bit) {
+      stream.writeUint32(reserved!);
+    }
+  }
 }
 
-/*
-* The 32-bit mach header appears at the very beginning of the object file for
-* 32-bit architectures.
-*/
-class MachOHeader32 extends IMachOHeader {
-  MachOHeader32(
-    Uint32 magic,
-    Uint32 cputype,
-    Uint32 cpusubtype,
-    Uint32 filetype,
-    Uint32 ncmds,
-    Uint32 sizeofcmds,
-    Uint32 flags,
-  ) : super(
-          magic,
-          cputype,
-          cpusubtype,
-          filetype,
-          ncmds,
-          sizeofcmds,
-          flags,
-          Uint32(0),
-        );
-}
+/// A segment load command indicates that a part of this file is to be mapped
+/// into a task's address space.  If the segment has sections, the section
+/// structures follow directly after the segment load command and their size
+/// is reflected in the [size] of the load command.
+///
+/// In the C headers, there are two different structs for 32-bit and 64-bit
+/// segments. Here, we combine them into one, with the [type] of the load
+/// command determining whether we read and write 32-bit or 64-bit values for
+/// particular fields.
+class MachOSegmentCommand extends MachOLoadCommand {
+  /// The name of the segment.
+  ///
+  /// `char segname[16]` in the C headers.
+  final String name;
 
-/*
-* The 64-bit mach header appears at the very beginning of object files for
-* 64-bit architectures.
-*/
-class MachOHeader extends IMachOHeader {
-  MachOHeader(
-    Uint32 magic,
-    Uint32 cputype,
-    Uint32 cpusubtype,
-    Uint32 filetype,
-    Uint32 ncmds,
-    Uint32 sizeofcmds,
-    Uint32 flags,
-    Uint32 reserved,
-  ) : super(
-          magic,
-          cputype,
-          cpusubtype,
-          filetype,
-          ncmds,
-          sizeofcmds,
-          flags,
-          reserved,
-        );
-}
+  /// The memory address at which this segment should be placed.
+  ///
+  /// `uint64_t vmaddr` for 64-bit segment commands and `uint32_t vmaddr`
+  /// for 32-bit segment commands in the C headers.
+  final int memoryAddress;
 
-/*
-* The load commands directly follow the mach_header.  The total size of all
-* of the commands is given by the sizeofcmds field in the mach_header.  All
-* load commands must have as their first two fields cmd and cmdsize.  The cmd
-* field is filled in with a constant for that command type.  Each command type
-* has a structure specifically for it.  The cmdsize field is the size in bytes
-* of the particular load command structure plus anything that follows it that
-* is a part of the load command (i.e. section structures, strings, etc.).  To
-* advance to the next load command the cmdsize can be added to the offset or
-* pointer of the current load command.  The cmdsize for 32-bit architectures
-* MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple
-* of 8 bytes (these are forever the maximum alignment of any load commands).
-* The padded bytes must be zero.  All tables in the object file must also
-* follow these rules so the file can be memory mapped.  Otherwise the pointers
-* to these tables will not work well or at all on some machines.  With all
-* padding zeroed like objects will compare byte for byte.
-*/
-class MachOLoadCommand {
-  /* type of load command (uint32_t) */
-  final Uint32 cmd;
-  /* total size of command in bytes (uint32_t) */
-  final Uint32 cmdsize;
+  /// The memory size for this segment.
+  ///
+  /// `uint64_t vmsize` for 64-bit segment commands and `uint32_t vmsize`
+  /// for 32-bit segment commands in the C headers.
+  final int memorySize;
 
-  MachOLoadCommand(this.cmd, this.cmdsize);
-}
+  /// The file offset for this segment.
+  ///
+  /// `uint64_t fileoff` for 64-bit segment commands and `uint32_t fileoff`
+  /// for 32-bit segment commands in the C headers.
+  final int fileOffset;
 
-/*
-* The segment load command indicates that a part of this file is to be
-* mapped into the task's address space.  The size of this segment in memory,
-* vmsize, maybe equal to or larger than the amount to map from this file,
-* filesize.  The file is mapped starting at fileoff to the beginning of
-* the segment in memory, vmaddr.  The rest of the memory of the segment,
-* if any, is allocated zero fill on demand.  The segment's maximum virtual
-* memory protection and initial virtual memory protection are specified
-* by the maxprot and initprot fields.  If the segment has sections then the
-* section structures directly follow the segment command and their size is
-* reflected in cmdsize.
-*/
-class MachOSegmentCommand extends IMachOLoadCommand<MachOSegmentCommand> {
-  /* For 32Bit Architectures */
-  final Uint8List segname; /* segment name */
-  final Uint32 vmaddr; /* memory address of this segment (uint32_t) */
-  final Uint32 vmsize; /* memory size of this segment (uint32_t) */
-  final Uint32 fileoff; /* file offset of this segment (uint32_t) */
-  final Uint32 filesize; /* amount to map from the file (uint32_t) */
-  final Int32 maxprot; /* maximum VM protection (int32) */
-  final Int32 initprot; /* initial VM protection (int32) */
-  final Uint32 nsects; /* number of sections in segment (uint32_t) */
-  final Uint32 flags; /* flags (uint32_t) */
+  /// The file size of this segment.
+  ///
+  /// `uint64_t filesize` for 64-bit segment commands and `uint32_t filesize`
+  /// for 32-bit segment commands in the C headers.
+  final int fileSize;
+
+  /// The maximum VM protection allowed for this segment.
+  ///
+  /// `vm_prot_t maxprot` in the C headers, where `vm_prot_t` is `int`.
+  final int maxProtection;
+
+  /// The initial VM protection used for this segment.
+  ///
+  /// `vm_prot_t initprot` in the C headers, where `vm_prot_t` is `int`.
+  final int initialProtection;
+
+  /// The flags set for this segment.
+  ///
+  /// `uint32_t flags` in the C headers.
+  final int flags;
+
+  /// The list of sections structures in the segment.
+  ///
+  /// Note that we do not keep a separate field for the number of sections
+  /// (`uint32_t nsects` in the C headers), but instead just use the length
+  /// of this list.
+  final List<MachOSection> sections;
 
   MachOSegmentCommand(
-    Uint32 cmdsize,
-    this.segname,
-    this.vmaddr,
-    this.vmsize,
-    this.fileoff,
-    this.filesize,
-    this.maxprot,
-    this.initprot,
-    this.nsects,
-    this.flags,
-  ) : super(MachOConstants.LC_SEGMENT, cmdsize);
-
-  @override
-  MachOSegmentCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeFromSync(segname);
-    stream.writeUint32(vmaddr);
-    stream.writeUint32(vmsize);
-    stream.writeUint32(fileoff);
-    stream.writeUint32(filesize);
-    stream.writeInt32(maxprot);
-    stream.writeInt32(initprot);
-    stream.writeUint32(nsects);
-    stream.writeUint32(flags);
-  }
-}
-
-/*
-* The 64-bit segment load command indicates that a part of this file is to be
-* mapped into a 64-bit task's address space.  If the 64-bit segment has
-* sections then section_64 structures directly follow the 64-bit segment
-* command and their size is reflected in cmdsize.
-*/
-class MachOSegmentCommand64 extends IMachOLoadCommand<MachOSegmentCommand64> {
-  /* For 64Bit Architectures */
-  final Uint8List segname; //[16] /* segment name */
-  final Uint64 vmaddr; /* memory address of this segment (uint64_t) */
-  final Uint64 vmsize; /* memory size of this segment (uint64_t) */
-  final Uint64 fileoff; /* file offset of this segment (uint64_t) */
-  final Uint64 filesize; /* amount to map from the file (uint64_t) */
-  final Int32 maxprot; /* maximum VM protection (int32) */
-  final Int32 initprot; /* initial VM protection (int32) */
-  final Uint32 nsects; /* number of sections in segment (uint32_t) */
-  final Uint32 flags; /* flags (uint32_t) */
-
-  final List<MachOSection64> sections;
-
-  MachOSegmentCommand64(
-    Uint32 cmdsize,
-    this.segname,
-    this.vmaddr,
-    this.vmsize,
-    this.fileoff,
-    this.filesize,
-    this.maxprot,
-    this.initprot,
-    this.nsects,
+    int code,
+    int size,
+    this.name,
+    this.memoryAddress,
+    this.memorySize,
+    this.fileOffset,
+    this.fileSize,
+    this.maxProtection,
+    this.initialProtection,
     this.flags,
     this.sections,
-  ) : super(MachOConstants.LC_SEGMENT_64, cmdsize);
+  ) : super(code, size);
+
+  static const _nameLength = 16;
+
+  static MachOSegmentCommand fromStream(
+      int code, int size, MachOReader stream) {
+    bool is64Bit = LoadCommandType.fromCode(code) == LoadCommandType.segment64;
+    final wordSize = is64Bit ? 8 : 4;
+
+    final String name = stream.readFixedLengthNullTerminatedString(_nameLength);
+    final memoryAddress = stream.readUword(wordSize);
+    final memorySize = stream.readUword(wordSize);
+    final fileOffset = stream.readUword(wordSize);
+    final fileSize = stream.readUword(wordSize);
+    final maxProtection = stream.readInt32();
+    final initialProtection = stream.readInt32();
+    final sectionCount = stream.readUint32();
+    final flags = stream.readUint32();
+
+    final sections = List<MachOSection>.generate(
+        sectionCount, (_) => MachOSection.fromStream(stream, is64Bit),
+        growable: false);
+
+    return MachOSegmentCommand(
+        code,
+        size,
+        name,
+        memoryAddress,
+        memorySize,
+        fileOffset,
+        fileSize,
+        maxProtection,
+        initialProtection,
+        flags,
+        sections);
+  }
+
+  int get _wordSize =>
+      LoadCommandType.fromCode(code) == LoadCommandType.segment64 ? 8 : 4;
 
   @override
-  MachOSegmentCommand64 asType() => this;
+  int? get minimumFileOffset {
+    if (sections.isEmpty) {
+      // Don't use the file offset of this segment if the segment is empty.
+      return fileSize != 0 ? fileOffset : null;
+    }
+    int? minOffset;
+    for (final section in sections) {
+      // Skip zero fill sections.
+      if (section.isZeroFill) continue;
+      assert(section.fileOffset != 0 && section.size != 0);
+      minOffset = minOffset == null
+          ? section.fileOffset
+          : min(minOffset, section.fileOffset);
+    }
+    return minOffset;
+  }
 
   @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeFromSync(segname);
-    stream.writeUint64(vmaddr);
-    stream.writeUint64(vmsize);
-    stream.writeUint64(fileoff);
-    stream.writeUint64(filesize);
-    stream.writeInt32(maxprot);
-    stream.writeInt32(initprot);
-    stream.writeUint32(nsects);
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeFixedLengthNullTerminatedString(name, _nameLength);
+    stream.writeUword(memoryAddress, _wordSize);
+    stream.writeUword(memorySize, _wordSize);
+    stream.writeUword(fileOffset, _wordSize);
+    stream.writeUword(fileSize, _wordSize);
+    stream.writeInt32(maxProtection);
+    stream.writeInt32(initialProtection);
+    stream.writeUint32(sections.length);
     stream.writeUint32(flags);
 
     for (final section in sections) {
@@ -440,1991 +596,1056 @@
   }
 }
 
-/*
-* A segment is made up of zero or more sections.  Non-MH_OBJECT files have
-* all of their segments with the proper sections in each, and padded to the
-* specified segment alignment when produced by the link editor.  The first
-* segment of a MH_EXECUTE and MH_FVMLIB format file contains the mach_header
-* and load commands of the object file before its first section.  The zero
-* fill sections are always last in their segment (in all formats).  This
-* allows the zeroed segment padding to be mapped into memory where zero fill
-* sections might be. The gigabyte zero fill sections, those with the section
-* type S_GB_ZEROFILL, can only be in a segment with sections of this type.
-* These segments are then placed after all other segments.
-*
-* The MH_OBJECT format has all of its sections in one segment for
-* compactness.  There is no padding to a specified segment boundary and the
-* mach_header and load commands are not part of the segment.
-*
-* Sections with the same section name, sectname, going into the same segment,
-* segname, are combined by the link editor.  The resulting section is aligned
-* to the maximum alignment of the combined sections and is the new section's
-* alignment.  The combined sections are aligned to their original alignment in
-* the combined section.  Any padded bytes to get the specified alignment are
-* zeroed.
-*
-* The format of the relocation entries referenced by the reloff and nreloc
-* fields of the section structure for mach object files is described in the
-* header file <reloc.h>.
-*/
-class MachOSection {
-  /* for 32-bit architectures */
-  final Uint8List sectname; /* name of this section */
-  final Uint8List segname; /* segment this section goes in */
-  final Uint32 addr; /* memory address of this section (uint32_t) */
-  final Uint32 size; /* size in bytes of this section (uint32_t) */
-  final Uint32 offset; /* file offset of this section (uint32_t) */
-  final Uint32 align; /* section alignment (power of 2) (uint32_t) */
-  final Uint32 reloff; /* file offset of relocation entries (uint32_t) */
-  final Uint32 nreloc; /* number of relocation entries (uint32_t) */
-  final Uint32 flags; /* flags (section type and attributes)(uint32_t) */
-  final Uint32 reserved1; /* reserved (for offset or index) (uint32_t) */
-  final Uint32 reserved2; /* reserved (for count or sizeof) (uint32_t) */
+enum SectionType {
+  /// A standard section that has no special meaning.
+  regular(0x0, 'REGULAR'),
 
-  MachOSection(
-    this.sectname,
-    this.segname,
-    this.addr,
-    this.size,
-    this.offset,
-    this.align,
-    this.reloff,
-    this.nreloc,
-    this.flags,
-    this.reserved1,
-    this.reserved2,
-  ) {
-    if (segname.length != 16) {
-      throw ArgumentError("segname must be 16 bytes exactly");
+  /// This section has no file contents, but instead any virtual memory for
+  /// this section is zero-filled at startup. Must be smaller than 4 gigabytes,
+  /// but can be mixed with other types of sections in a given segment.
+  zeroFill(0x1, 'ZEROFILL'),
+
+  /// This section has no file contents, but instead any virtual memory for
+  /// this section is zero-filled at startup. Can be larger than 4 gigabytes,
+  /// but can only be in a segment with the same kind of section.
+  gigabyteZeroFill(0xc, 'GB_ZEROFILL'),
+
+  /// This section has no file contents, but instead any virtual memory for
+  /// this section is zero-filled at startup. Used for BSS sections.
+  threadLocalZeroFill(0x12, 'THREAD_LOCAL_ZEROFILL');
+
+  final int _code;
+  final String _headerName;
+
+  const SectionType(this._code, this._headerName);
+
+  static SectionType? fromFlags(int flags) {
+    final code = flags & _typeMask;
+    for (final value in values) {
+      if (value._code == code) {
+        return value;
+      }
     }
+    return null;
   }
+
+  static const _prefix = 'S';
+  static const _typeSize = 8;
+  static const _typeMask = (1 << _typeSize) - 1;
+
+  @override
+  String toString() => '${_prefix}_$_headerName';
 }
 
-class MachOSection64 {
-  /* for 64-bit architectures */
-  final Uint8List sectname; //[16] /* name of this section */
-  final Uint8List segname; //[16] /* segment this section goes in */
-  final Uint64 addr; /* memory address of this section (uint64_t) */
-  final Uint64 size; /* size in bytes of this section (uint64_t) */
-  final Uint32 offset; /* file offset of this section (uint32_t) */
-  final Uint32 align; /* section alignment (power of 2) (uint32_t) */
-  final Uint32 reloff; /* file offset of relocation entries (uint32_t) */
-  final Uint32 nreloc; /* number of relocation entries (uint32_t) */
-  final Uint32 flags; /* flags (section type and attributes)(uint32_t) */
-  final Uint32 reserved1; /* reserved (for offset or index) (uint32_t) */
-  final Uint32 reserved2; /* reserved (for count or sizeof) (uint32_t) */
-  final Uint32 reserved3; /* reserved (uint32_t) */
+/// A section describes a specific portion of a segment. The specifics of
+/// sections are mostly unimportant for our work here, except that we need
+/// to recognize S_ZEROFILL/S_GB_ZEROFILL sections so they can be ignored for
+/// file offset purposes.
+///
+/// In the C headers, sections are represented by two structs, one for 32-bit
+/// headers and one for 64-bit headers. Other than whether specific fields
+/// are 32-bit or 64-bit, the only other difference is that the 64-bit header
+/// contains one more 32-bit reserved field.
+class MachOSection {
+  /// Name of this section.
+  final String name;
 
-  MachOSection64(
-    this.sectname,
-    this.segname,
-    this.addr,
+  /// Name of the containing segment.
+  final String segmentName;
+
+  /// Memory address of this section.
+  final int memoryAddress;
+
+  /// The size of this section in memory (and in the file contents if not
+  /// a zero fill section).
+  final int size;
+
+  /// File offset of the contents of this section.
+  final int fileOffset;
+  final int alignment;
+
+  /// File offset of the relocation entries.
+  final int relocationsFileOffset;
+
+  /// Nuber of relocation entries.
+  final int relocationsCount;
+
+  /// Flags, which encode both the section type and any section attributes.
+  final int flags;
+
+  /// Reserved (for offset or index).
+  ///
+  /// `uint32_t reserved1` in the C headers.
+  final int reserved1;
+  // Reserved (for count or sizeof).
+  ///
+  /// `uint32_t reserved2` in the C headers.
+  final int reserved2;
+
+  /// Reserved in 64-bit sections for padding purposes. Null in 32-bit sections.
+  ///
+  /// `uint32_t reserved3` in the C headers.
+  final int? reserved3;
+
+  MachOSection(
+    this.name,
+    this.segmentName,
+    this.memoryAddress,
     this.size,
-    this.offset,
-    this.align,
-    this.reloff,
-    this.nreloc,
+    this.fileOffset,
+    this.alignment,
+    this.relocationsFileOffset,
+    this.relocationsCount,
     this.flags,
     this.reserved1,
     this.reserved2,
     this.reserved3,
-  ) {
-    if (segname.length != 16) {
-      throw ArgumentError("segname must be 16 bytes exactly");
+  );
+
+  static MachOSection fromStream(MachOReader stream, bool is64Bit) {
+    final wordSize = is64Bit ? 8 : 4;
+
+    final String name = stream.readFixedLengthNullTerminatedString(_nameLength);
+    final String segmentName = stream
+        .readFixedLengthNullTerminatedString(MachOSegmentCommand._nameLength);
+    final memoryAddress = stream.readUword(wordSize);
+    final size = stream.readUword(wordSize);
+    final fileOffset = stream.readUint32();
+    final alignment = stream.readUint32();
+    final relocationsFileOffset = stream.readUint32();
+    final relocationsCount = stream.readUint32();
+    final flags = stream.readUint32();
+    final reserved1 = stream.readUint32();
+    final reserved2 = stream.readUint32();
+    int? reserved3;
+    if (is64Bit) {
+      reserved3 = stream.readUint32();
     }
+
+    return MachOSection(
+        name,
+        segmentName,
+        memoryAddress,
+        size,
+        fileOffset,
+        alignment,
+        relocationsFileOffset,
+        relocationsCount,
+        flags,
+        reserved1,
+        reserved2,
+        reserved3);
   }
 
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeFromSync(sectname);
-    stream.writeFromSync(segname);
-    stream.writeUint64(addr);
-    stream.writeUint64(size);
-    stream.writeUint32(offset);
-    stream.writeUint32(align);
-    stream.writeUint32(reloff);
-    stream.writeUint32(nreloc);
+  static const _nameLength = 16;
+  static const _attributesMask = 0xffffffff & ~SectionType._typeMask;
+
+  static int combineIntoFlags(SectionType type, int attributes) {
+    assert((attributes & ~_attributesMask) == 0);
+    return attributes & type._code;
+  }
+
+  bool get is64Bit => reserved3 != null;
+
+  SectionType? get type => SectionType.fromFlags(flags);
+  int get attributes => flags & _attributesMask;
+
+  bool get isZeroFill {
+    final cachedType = type; // Don't recalculate for each comparison.
+    return cachedType == SectionType.zeroFill ||
+        cachedType == SectionType.gigabyteZeroFill ||
+        cachedType == SectionType.threadLocalZeroFill;
+  }
+
+  void writeContentsSync(MachOWriter stream) {
+    final int wordSize = is64Bit ? 8 : 4;
+    stream.writeFixedLengthNullTerminatedString(name, _nameLength);
+    stream.writeFixedLengthNullTerminatedString(
+        segmentName, MachOSegmentCommand._nameLength);
+    stream.writeUword(memoryAddress, wordSize);
+    stream.writeUword(size, wordSize);
+    stream.writeUint32(fileOffset);
+    stream.writeUint32(alignment);
+    stream.writeUint32(relocationsFileOffset);
+    stream.writeUint32(relocationsCount);
     stream.writeUint32(flags);
     stream.writeUint32(reserved1);
     stream.writeUint32(reserved2);
-    stream.writeUint32(reserved3);
-  }
-}
-
-// This is a stand-in for the lc_str union in the MachO header.
-class MachOStr {
-  final int offset;
-  final Uint8List ptr;
-
-  MachOStr(this.offset, this.ptr);
-  // part of the schema so it doesn't contribute to
-  // the size of this schema.
-
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeInt32(Int32(offset));
-    stream.writeFromSync(ptr);
-  }
-}
-
-/*
- * Fixed virtual memory shared libraries are identified by two things.  The
- * target pathname (the name of the library as found for execution), and the
- * minor version number.  The address of where the headers are loaded is in
- * header_addr. (THIS IS OBSOLETE and no longer supported).
- */
-class MachOFvmlib {
-  final MachOStr name; /* library's target pathname */
-  final Uint32 minor_version; /* library's minor version number (uint32_t) */
-  final Uint32 header_addr; /* library's header address (uint32_t) */
-
-  MachOFvmlib(
-    this.name,
-    this.minor_version,
-    this.header_addr,
-  );
-
-  void writeContentsSync(RandomAccessFile stream) {
-    name.writeContentsSync(stream);
-    stream.writeUint32(minor_version);
-    stream.writeUint32(header_addr);
-  }
-}
-
-/*
- * A fixed virtual shared library (filetype == MH_FVMLIB in the mach header)
- * contains a fvmlib_command (cmd == LC_IDFVMLIB) to identify the library.
- * An object that uses a fixed virtual shared library also contains a
- * fvmlib_command (cmd == LC_LOADFVMLIB) for each library it uses.
- * (THIS IS OBSOLETE and no longer supported).
- */
-class MachOFvmlibCommand extends IMachOLoadCommand<MachOFvmlibCommand> {
-  final MachOFvmlib fvmlib; /* the library identification */
-
-  MachOFvmlibCommand(
-    Uint32 cmdsize,
-    this.fvmlib,
-  ) : super(MachOConstants.LC_IDFVMLIB, cmdsize);
-
-  @override
-  MachOFvmlibCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    fvmlib.writeContentsSync(stream);
-  }
-}
-
-/*
- * Dynamicly linked shared libraries are identified by two things.  The
- * pathname (the name of the library as found for execution), and the
- * compatibility version number.  The pathname must match and the compatibility
- * number in the user of the library must be greater than or equal to the
- * library being used.  The time stamp is used to record the time a library was
- * built and copied into user so it can be use to determined if the library used
- * at runtime is exactly the same as used to built the program.
- */
-class MachODylib {
-  final MachOStr name; /* library's path name */
-  final Uint32 timestamp; /* library's build time stamp (uint32_t) */
-  final Uint32
-      current_version; /* library's current version number (uint32_t) */
-  final Uint32
-      compatibility_version; /* library's compatibility vers number(uint32_t) */
-
-  MachODylib(
-    this.name,
-    this.timestamp,
-    this.current_version,
-    this.compatibility_version,
-  );
-
-  void writeContentsSync(RandomAccessFile stream) {
-    name.writeContentsSync(stream);
-    stream.writeUint32(timestamp);
-    stream.writeUint32(current_version);
-    stream.writeUint32(compatibility_version);
-  }
-}
-
-/*
- * A dynamically linked shared library (filetype == MH_DYLIB in the mach header)
- * contains a dylib_command (cmd == LC_ID_DYLIB) to identify the library.
- * An object that uses a dynamically linked shared library also contains a
- * dylib_command (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or
- * LC_REEXPORT_DYLIB) for each library it uses.
- */
-class MachODylibCommand extends IMachOLoadCommand<MachODylibCommand> {
-  final MachODylib dylib; /* the library identification */
-
-  MachODylibCommand(
-    Uint32 cmd,
-    Uint32 cmdsize,
-    this.dylib,
-  ) : super(cmd, cmdsize) {
-    if (this.cmd != MachOConstants.LC_ID_DYLIB &&
-        this.cmd != MachOConstants.LC_LOAD_WEAK_DYLIB &&
-        this.cmd != MachOConstants.LC_REEXPORT_DYLIB) {
-      throw ArgumentError(
-          "cmd was not one of LC_ID_DYLIB (${MachOConstants.LC_ID_DYLIB}), "
-          "LC_LOAD_WEAK_DYLIB (${MachOConstants.LC_LOAD_WEAK_DYLIB}), "
-          "LC_REEXPORT_DYLIB (${MachOConstants.LC_REEXPORT_DYLIB}): $cmd");
+    if (is64Bit) {
+      stream.writeUint32(reserved3!);
     }
   }
-
-  @override
-  MachODylibCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    dylib.writeContentsSync(stream);
-  }
 }
 
-/*
- * A dynamically linked shared library may be a subframework of an umbrella
- * framework.  If so it will be linked with "-umbrella umbrella_name" where
- * Where "umbrella_name" is the name of the umbrella framework. A subframework
- * can only be linked against by its umbrella framework or other subframeworks
- * that are part of the same umbrella framework.  Otherwise the static link
- * editor produces an error and states to link against the umbrella framework.
- * The name of the umbrella framework for subframeworks is recorded in the
- * following structure.
- */
-class MachOSubFrameworkCommand
-    extends IMachOLoadCommand<MachOSubFrameworkCommand> {
-  final MachOStr umbrella; /* the umbrella framework name */
+/// A load command that describes a static symbol table.
+class MachOSymtabCommand extends MachOLoadCommand {
+  /// The file offset of the symbol table.
+  ///
+  /// `uint32_t symoff` in the C headers.
+  final int fileOffset;
 
-  MachOSubFrameworkCommand(
-    Uint32 cmdsize,
-    this.umbrella,
-  ) : super(MachOConstants.LC_SUB_FRAMEWORK, cmdsize);
+  /// The number of symbol table entries.
+  ///
+  /// `uint32_t symoff` in the C headers.
+  final int symbolsCount;
 
-  @override
-  MachOSubFrameworkCommand asType() => this;
+  /// The file offset of the string table.
+  ///
+  /// `uint32_t stroff` in the C headers.
+  final int stringTableFileOffset;
 
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    umbrella.writeContentsSync(stream);
-  }
-}
-
-/*
- * For dynamically linked shared libraries that are subframework of an umbrella
- * framework they can allow clients other than the umbrella framework or other
- * subframeworks in the same umbrella framework.  To do this the subframework
- * is built with "-allowable_client client_name" and an LC_SUB_CLIENT load
- * command is created for each -allowable_client flag.  The client_name is
- * usually a framework name.  It can also be a name used for bundles clients
- * where the bundle is built with "-client_name client_name".
- */
-class MachOSubClientCommand extends IMachOLoadCommand<MachOSubClientCommand> {
-  final MachOStr client; /* the client name */
-
-  MachOSubClientCommand(
-    Uint32 cmdsize,
-    this.client,
-  ) : super(MachOConstants.LC_SUB_CLIENT, cmdsize);
-
-  @override
-  MachOSubClientCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    client.writeContentsSync(stream);
-  }
-}
-
-/*
- * A dynamically linked shared library may be a sub_umbrella of an umbrella
- * framework.  If so it will be linked with "-sub_umbrella umbrella_name" where
- * Where "umbrella_name" is the name of the sub_umbrella framework.  When
- * staticly linking when -twolevel_namespace is in effect a twolevel namespace
- * umbrella framework will only cause its subframeworks and those frameworks
- * listed as sub_umbrella frameworks to be implicited linked in.  Any other
- * dependent dynamic libraries will not be linked it when -twolevel_namespace
- * is in effect.  The primary library recorded by the static linker when
- * resolving a symbol in these libraries will be the umbrella framework.
- * Zero or more sub_umbrella frameworks may be use by an umbrella framework.
- * The name of a sub_umbrella framework is recorded in the following structure.
- */
-class MachOSubUmbrellaCommand
-    extends IMachOLoadCommand<MachOSubUmbrellaCommand> {
-  final MachOStr sub_umbrella; /* the sub_umbrella framework name */
-
-  MachOSubUmbrellaCommand(
-    Uint32 cmdsize,
-    this.sub_umbrella,
-  ) : super(
-          MachOConstants.LC_SUB_UMBRELLA,
-          cmdsize,
-        );
-
-  @override
-  MachOSubUmbrellaCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    sub_umbrella.writeContentsSync(stream);
-  }
-}
-
-/*
- * A dynamically linked shared library may be a sub_library of another shared
- * library.  If so it will be linked with "-sub_library library_name" where
- * Where "library_name" is the name of the sub_library shared library.  When
- * staticly linking when -twolevel_namespace is in effect a twolevel namespace
- * shared library will only cause its subframeworks and those frameworks
- * listed as sub_umbrella frameworks and libraries listed as sub_libraries to
- * be implicited linked in.  Any other dependent dynamic libraries will not be
- * linked it when -twolevel_namespace is in effect.  The primary library
- * recorded by the static linker when resolving a symbol in these libraries
- * will be the umbrella framework (or dynamic library). Zero or more sub_library
- * shared libraries may be use by an umbrella framework or (or dynamic library).
- * The name of a sub_library framework is recorded in the following structure.
- * For example /usr/lib/libobjc_profile.A.dylib would be recorded as "libobjc".
- */
-class MachOSubLibraryCommand extends IMachOLoadCommand<MachOSubLibraryCommand> {
-  final MachOStr sub_library; /* the sub_library name */
-
-  MachOSubLibraryCommand(
-    Uint32 cmdsize,
-    this.sub_library,
-  ) : super(
-          MachOConstants.LC_SUB_LIBRARY,
-          cmdsize,
-        );
-
-  @override
-  MachOSubLibraryCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    sub_library.writeContentsSync(stream);
-  }
-}
-
-/*
- * A program (filetype == MH_EXECUTE) that is
- * prebound to its dynamic libraries has one of these for each library that
- * the static linker used in prebinding.  It contains a bit vector for the
- * modules in the library.  The bits indicate which modules are bound (1) and
- * which are not (0) from the library.  The bit for module 0 is the low bit
- * of the first byte.  So the bit for the Nth module is:
- * (linked_modules[N/8] >> N%8) & 1
- */
-class MachOPreboundDylibCommand
-    extends IMachOLoadCommand<MachOPreboundDylibCommand> {
-  final MachOStr name; /* library's path name */
-  final Uint32 nmodules; /* number of modules in library (uint32_t) */
-  final MachOStr linked_modules; /* bit vector of linked modules */
-
-  MachOPreboundDylibCommand(
-    Uint32 cmdsize,
-    this.name,
-    this.nmodules,
-    this.linked_modules,
-  ) : super(
-          MachOConstants.LC_PREBOUND_DYLIB,
-          cmdsize,
-        );
-
-  @override
-  MachOPreboundDylibCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    name.writeContentsSync(stream);
-    stream.writeUint32(nmodules);
-    linked_modules.writeContentsSync(stream);
-  }
-}
-
-/*
- * A program that uses a dynamic linker contains a dylinker_command to identify
- * the name of the dynamic linker (LC_LOAD_DYLINKER).  And a dynamic linker
- * contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER).
- * A file can have at most one of these.
- * This struct is also used for the LC_DYLD_ENVIRONMENT load command and
- * contains string for dyld to treat like environment variable.
- */
-class MachODylinkerCommand extends IMachOLoadCommand<MachODylinkerCommand> {
-  final MachOStr name; /* dynamic linker's path name */
-
-  MachODylinkerCommand(
-    Uint32 cmd,
-    Uint32 cmdsize,
-    this.name,
-  ) : super(
-          cmd,
-          cmdsize,
-        ) {
-    if (this.cmd != MachOConstants.LC_ID_DYLINKER &&
-        this.cmd != MachOConstants.LC_LOAD_DYLINKER &&
-        this.cmd != MachOConstants.LC_DYLD_ENVIRONMENT) {
-      throw ArgumentError(
-          "cmd was not one of LC_ID_DYLINKER (${MachOConstants.LC_ID_DYLINKER}), "
-          "LC_LOAD_DYLINKER (${MachOConstants.LC_LOAD_DYLINKER}), "
-          "LC_DYLD_ENVIRONMENT (${MachOConstants.LC_DYLD_ENVIRONMENT}): $cmd");
-    }
-  }
-
-  @override
-  MachODylinkerCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    name.writeContentsSync(stream);
-  }
-}
-
-/*
- * Thread commands contain machine-specific data structures suitable for
- * use in the thread state primitives.  The machine specific data structures
- * follow the struct thread_command as follows.
- * Each flavor of machine specific data structure is preceded by an uint32_t
- * constant for the flavor of that data structure, an uint32_t that is the
- * count of uint32_t's of the size of the state data structure and then
- * the state data structure follows.  This triple may be repeated for many
- * flavors.  The constants for the flavors, counts and state data structure
- * definitions are expected to be in the header file <machine/thread_status.h>.
- * These machine specific data structures sizes must be multiples of
- * 4 bytes.  The cmdsize reflects the total size of the thread_command
- * and all of the sizes of the constants for the flavors, counts and state
- * data structures.
- *
- * For executable objects that are unix processes there will be one
- * thread_command (cmd == LC_UNIXTHREAD) created for it by the link-editor.
- * This is the same as a LC_THREAD, except that a stack is automatically
- * created (based on the shell's limit for the stack size).  Command arguments
- * and environment variables are copied onto that stack.
- */
-class MachOThreadCommand extends IMachOLoadCommand<MachOThreadCommand> {
-  /* final int flavor		   flavor of thread state (uint32_t) */
-  /* final int count		   count of longs in thread state (uint32_t) */
-  /* struct XXX_thread_state state   thread state for this flavor */
-  /* ... */
-
-  MachOThreadCommand(
-    Uint32 cmd,
-    Uint32 cmdsize,
-    /* final int flavor		   flavor of thread state (uint32_t) */
-    /* final int count		   count of longs in thread state (uint32_t) */
-    /* struct XXX_thread_state state   thread state for this flavor */
-    /* ... */
-  ) : super(
-          cmd,
-          cmdsize,
-        ) {
-    if (this.cmd != MachOConstants.LC_THREAD &&
-        this.cmd != MachOConstants.LC_UNIXTHREAD) {
-      throw ArgumentError(
-          "cmd was not one of LC_THREAD (${MachOConstants.LC_THREAD}), "
-          "LC_UNIXTHREAD (${MachOConstants.LC_UNIXTHREAD}): $cmd");
-    }
-  }
-
-  @override
-  MachOThreadCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {}
-}
-
-/*
- * The routines command contains the address of the dynamic shared library
- * initialization routine and an index into the module table for the module
- * that defines the routine.  Before any modules are used from the library the
- * dynamic linker fully binds the module that defines the initialization routine
- * and then calls it.  This gets called before any module initialization
- * routines (used for C++ static constructors) in the library.
- */
-class MachORoutinesCommand extends IMachOLoadCommand<MachORoutinesCommand> {
-  final Uint32 init_address; /* address of initialization routine (uint32_t) */
-  final Uint32 init_module; /* index into the module table that (uint32_t) */
-  /*  the init routine is defined in */
-  final Uint32 reserved1; /* (uint32_t) */
-  final Uint32 reserved2; /* (uint32_t) */
-  final Uint32 reserved3; /* (uint32_t) */
-  final Uint32 reserved4; /* (uint32_t) */
-  final Uint32 reserved5; /* (uint32_t) */
-  final Uint32 reserved6; /* (uint32_t) */
-
-  MachORoutinesCommand(
-    Uint32 cmdsize,
-    this.init_address,
-    this.init_module,
-    this.reserved1,
-    this.reserved2,
-    this.reserved3,
-    this.reserved4,
-    this.reserved5,
-    this.reserved6,
-  ) : super(
-          MachOConstants.LC_ROUTINES,
-          cmdsize,
-        );
-
-  @override
-  MachORoutinesCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint32(init_address);
-    stream.writeUint32(init_module);
-    stream.writeUint32(reserved1);
-    stream.writeUint32(reserved2);
-    stream.writeUint32(reserved3);
-    stream.writeUint32(reserved4);
-    stream.writeUint32(reserved5);
-    stream.writeUint32(reserved6);
-  }
-}
-
-/*
- * The 64-bit routines command.  Same use as above.
- */
-class MachORoutinesCommand64 extends IMachOLoadCommand<MachORoutinesCommand64> {
-  final Uint64 init_address; /* address of initialization routine (uint64_t) */
-  final Uint64 init_module; /* index into the module table that (uint64_t) */
-  /*  the init routine is defined in */
-  final Uint64 reserved1; /* (uint64_t) */
-  final Uint64 reserved2; /* (uint64_t) */
-  final Uint64 reserved3; /* (uint64_t) */
-  final Uint64 reserved4; /* (uint64_t) */
-  final Uint64 reserved5; /* (uint64_t) */
-  final Uint64 reserved6; /* (uint64_t) */
-
-  MachORoutinesCommand64(
-    Uint32 cmdsize,
-    this.init_address,
-    this.init_module,
-    this.reserved1,
-    this.reserved2,
-    this.reserved3,
-    this.reserved4,
-    this.reserved5,
-    this.reserved6,
-  ) : super(
-          MachOConstants.LC_ROUTINES_64,
-          cmdsize,
-        );
-
-  @override
-  MachORoutinesCommand64 asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint64(init_address);
-    stream.writeUint64(init_module);
-    stream.writeUint64(reserved1);
-    stream.writeUint64(reserved2);
-    stream.writeUint64(reserved3);
-    stream.writeUint64(reserved4);
-    stream.writeUint64(reserved5);
-    stream.writeUint64(reserved6);
-  }
-}
-
-/*
- * The symtab_command contains the offsets and sizes of the link-edit 4.3BSD
- * "stab" style symbol table information as described in the header files
- * <nlist.h> and <stab.h>.
- */
-class MachOSymtabCommand extends IMachOLoadCommand<MachOSymtabCommand> {
-  final Uint32 symoff; /* symbol table offset (uint32_t) */
-  final Uint32 nsyms; /* number of symbol table entries (uint32_t) */
-  final Uint32 stroff; /* string table offset (uint32_t) */
-  final Uint32 strsize; /* string table size in bytes (uint32_t) */
+  /// The file size of the string table.
+  ///
+  /// `uint32_t strsize` in the C headers.
+  final int stringTableSize;
 
   MachOSymtabCommand(
-    Uint32 cmdsize,
-    this.symoff,
-    this.nsyms,
-    this.stroff,
-    this.strsize,
-  ) : super(
-          MachOConstants.LC_SYMTAB,
-          cmdsize,
-        );
+    int code,
+    int size,
+    this.fileOffset,
+    this.symbolsCount,
+    this.stringTableFileOffset,
+    this.stringTableSize,
+  ) : super(code, size);
+
+  static MachOSymtabCommand fromStream(int code, int size, MachOReader stream) {
+    final fileOffset = stream.readUint32();
+    final symbolsCount = stream.readUint32();
+    final stringTableFileOffset = stream.readUint32();
+    final stringTableSize = stream.readUint32();
+
+    return MachOSymtabCommand(code, size, fileOffset, symbolsCount,
+        stringTableFileOffset, stringTableSize);
+  }
 
   @override
-  MachOSymtabCommand asType() => this;
+  MachOSymtabCommand adjust(OffsetsAdjuster adjuster) => MachOSymtabCommand(
+      code,
+      size,
+      adjuster.adjust(fileOffset),
+      symbolsCount,
+      adjuster.adjust(stringTableFileOffset),
+      stringTableSize);
 
   @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint32(symoff);
-    stream.writeUint32(nsyms);
-    stream.writeUint32(stroff);
-    stream.writeUint32(strsize);
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeUint32(fileOffset);
+    stream.writeUint32(symbolsCount);
+    stream.writeUint32(stringTableFileOffset);
+    stream.writeUint32(stringTableSize);
   }
 }
 
-/*
- * This is the second set of the symbolic information which is used to support
- * the data structures for the dynamically link editor.
- *
- * The original set of symbolic information in the symtab_command which contains
- * the symbol and string tables must also be present when this load command is
- * present.  When this load command is present the symbol table is organized
- * into three groups of symbols:
- *	local symbols (static and debugging symbols) - grouped by module
- *	defined external symbols - grouped by module (sorted by name if not lib)
- *	undefined external symbols (sorted by name if MH_BINDATLOAD is not set,
- *	     			    and in order the were seen by the static
- *				    linker if MH_BINDATLOAD is set)
- * In this load command there are offsets and counts to each of the three groups
- * of symbols.
- *
- * This load command contains a the offsets and sizes of the following new
- * symbolic information tables:
- *	table of contents
- *	module table
- *	reference symbol table
- *	indirect symbol table
- * The first three tables above (the table of contents, module table and
- * reference symbol table) are only present if the file is a dynamically linked
- * shared library.  For executable and object modules, which are files
- * containing only one module, the information that would be in these three
- * tables is determined as follows:
- * 	table of contents - the defined external symbols are sorted by name
- *	module table - the file contains only one module so everything in the
- *		       file is part of the module.
- *	reference symbol table - is the defined and undefined external symbols
- *
- * For dynamically linked shared library files this load command also contains
- * offsets and sizes to the pool of relocation entries for all sections
- * separated into two groups:
- *	external relocation entries
- *	local relocation entries
- * For executable and object modules the relocation entries continue to hang
- * off the section structures.
- */
-class MachODysymtabCommand extends IMachOLoadCommand<MachODysymtabCommand> {
-  /*
-     * The symbols indicated by symoff and nsyms of the LC_SYMTAB load command
-     * are grouped into the following three groups:
-     *    local symbols (further grouped by the module they are from)
-     *    defined external symbols (further grouped by the module they are from)
-     *    undefined symbols
-     *
-     * The local symbols are used only for debugging.  The dynamic binding
-     * process may have to use them to indicate to the debugger the local
-     * symbols for a module that is being bound.
-     *
-     * The last two groups are used by the dynamic binding process to do the
-     * binding (indirectly through the module table and the reference symbol
-     * table when this is a dynamically linked shared library file).
-     */
-  final Uint32 ilocalsym; /* index to local symbols (uint32_t) */
-  final Uint32 nlocalsym; /* number of local symbols (uint32_t) */
+/// A load command representing the dynamic symbol table.
+class MachODysymtabCommand extends MachOLoadCommand {
+  /// The index of the local symbols.
+  ///
+  /// `uint32_t ilocalsym` in the C headers.
+  final int localSymbolsIndex;
 
-  final Uint32 iextdefsym; /* index to externally defined symbols (uint32_t) */
-  final Uint32 nextdefsym; /* number of externally defined symbols (uint32_t) */
+  /// The number of local symbols.
+  ///
+  /// `uint32_t nlocalsym` in the C headers.
+  final int localSymbolsCount;
 
-  final Uint32 iundefsym; /* index to undefined symbols (uint32_t) */
-  final Uint32 nundefsym; /* number of undefined symbols (uint32_t) */
+  /// The index of the externally defined symbols.
+  ///
+  /// `uint32_t iextdefsym` in the C headers.
+  final int externalSymbolsIndex;
 
-  /*
-     * For the for the dynamic binding process to find which module a symbol
-     * is defined in the table of contents is used (analogous to the ranlib
-     * structure in an archive) which maps defined external symbols to modules
-     * they are defined in.  This exists only in a dynamically linked shared
-     * library file.  For executable and object modules the defined external
-     * symbols are sorted by name and is use as the table of contents.
-     */
-  final Uint32 tocoff; /* file offset to table of contents (uint32_t) */
-  final Uint32 ntoc; /* number of entries in table of contents (uint32_t) */
+  /// The number of externally defined symbols.
+  ///
+  /// `uint32_t nextdefsym` in the C headers.
+  final int externalSymbolsCount;
 
-  /*
-     * To support dynamic binding of "modules" (whole object files) the symbol
-     * table must reflect the modules that the file was created from.  This is
-     * done by having a module table that has indexes and counts into the merged
-     * tables for each module.  The module structure that these two entries
-     * refer to is described below.  This exists only in a dynamically linked
-     * shared library file.  For executable and object modules the file only
-     * contains one module so everything in the file belongs to the module.
-     */
-  final Uint32 modtaboff; /* file offset to module table (uint32_t) */
-  final Uint32 nmodtab; /* number of module table entries (uint32_t) */
+  /// The index of the undefined symbols.
+  ///
+  /// `uint32_t iundefsym` in the C headers.
+  final int undefinedSymbolsIndex;
 
-  /*
-     * To support dynamic module binding the module structure for each module
-     * indicates the external references (defined and undefined) each module
-     * makes.  For each module there is an offset and a count into the
-     * reference symbol table for the symbols that the module references.
-     * This exists only in a dynamically linked shared library file.  For
-     * executable and object modules the defined external symbols and the
-     * undefined external symbols indicates the external references.
-     */
-  final Uint32 extrefsymoff; /* offset to referenced symbol table (uint32_t) */
-  final Uint32
-      nextrefsyms; /* number of referenced symbol table entries (uint32_t) */
+  /// The number of undefined symbols.
+  ///
+  /// `uint32_t nundefsym` in the C headers.
+  final int undefinedSymbolsCount;
 
-  /*
-     * The sections that contain "symbol pointers" and "routine stubs" have
-     * indexes and (implied counts based on the size of the section and fixed
-     * size of the entry) into the "indirect symbol" table for each pointer
-     * and stub.  For every section of these two types the index into the
-     * indirect symbol table is stored in the section header in the field
-     * reserved1.  An indirect symbol table entry is simply a 32bit index into
-     * the symbol table to the symbol that the pointer or stub is referring to.
-     * The indirect symbol table is ordered to match the entries in the section.
-     */
-  final Uint32
-      indirectsymoff; /* file offset to the indirect symbol table (uint32_t) */
-  final Uint32
-      nindirectsyms; /* number of indirect symbol table entries (uint32_t) */
+  /// The file offset of the table of contents.
+  ///
+  /// `uint32_t tocoff` in the C headers.
+  final int tableOfContentsFileOffset;
 
-  /*
-     * To support relocating an individual module in a library file quickly the
-     * external relocation entries for each module in the library need to be
-     * accessed efficiently.  Since the relocation entries can't be accessed
-     * through the section headers for a library file they are separated into
-     * groups of local and external entries further grouped by module.  In this
-     * case the presents of this load command who's extreloff, nextrel,
-     * locreloff and nlocrel fields are non-zero indicates that the relocation
-     * entries of non-merged sections are not referenced through the section
-     * structures (and the reloff and nreloc fields in the section headers are
-     * set to zero).
-     *
-     * Since the relocation entries are not accessed through the section headers
-     * this requires the r_address field to be something other than a section
-     * offset to identify the item to be relocated.  In this case r_address is
-     * set to the offset from the vmaddr of the first LC_SEGMENT command.
-     * For MH_SPLIT_SEGS images r_address is set to the offset from the
-     * vmaddr of the first read-write LC_SEGMENT command.
-     *
-     * The relocation entries are grouped by module and the module table
-     * entries have indexes and counts into them for the group of external
-     * relocation entries for that the module.
-     *
-     * For sections that are merged across modules there must not be any
-     * remaining external relocation entries for them (for merged sections
-     * remaining relocation entries must be local).
-     */
-  final Uint32 extreloff; /* offset to external relocation entries (uint32_t) */
-  final Uint32 nextrel; /* number of external relocation entries (uint32_t) */
+  /// The number of entries in the table of contents.
+  ///
+  /// `uint32_t ntoc` in the C headers.
+  final int tableOfContentsEntryCount;
 
-  /*
-     * All the local relocation entries are grouped together (they are not
-     * grouped by their module since they are only used if the object is moved
-     * from it staticly link edited address).
-     */
-  final Uint32 locreloff; /* offset to local relocation entries (uint32_t) */
-  final Uint32 nlocrel; /* number of local relocation entries (uint32_t) */
+  /// The file offset of the module table.
+  ///
+  /// `uint32_t modtaboff` in the C headers.
+  final int moduleTableFileOffset;
+
+  /// The number of entries in the module table.
+  ///
+  /// `uint32_t nmodtab` in the C headers.
+  final int moduleTableEntryCount;
+
+  /// The file offset of the referenced symbol table.
+  ///
+  /// `uint32_t extrefsymoff` in the C headers.
+  final int referencedSymbolTableFileOffset;
+
+  /// The number of entries in the referenced symbol table.
+  ///
+  /// `uint32_t nextrefsyms` in the C headers.
+  final int referencedSymbolTableEntryCount;
+
+  /// The file offset of the indirect symbol table.
+  ///
+  /// `uint32_t indirectsymoff` in the C headers.
+  final int indirectSymbolTableFileOffset;
+
+  /// The number of entries in the indirect symbol table.
+  ///
+  /// `uint32_t nindirectsyms` in the C headers.
+  final int indirectSymbolTableEntryCount;
+
+  /// The file offset of external relocation entries.
+  ///
+  /// `uint32_t extreloff` in the C headers.
+  final int externalRelocationsFileOffset;
+
+  /// The number of external relocation entries.
+  ///
+  /// `uint32_t nextrel` in the C headers.
+  final int externalRelocationsCount;
+
+  /// The file offset of local relocation entries.
+  ///
+  /// `uint32_t locreloff` in the C headers.
+  final int localRelocationsFileOffset;
+
+  /// The number of local relocation entries.
+  ///
+  /// `uint32_t nlocrel` in the C headers.
+  final int localRelocationsCount;
 
   MachODysymtabCommand(
-    Uint32 cmdsize,
-    this.ilocalsym,
-    this.nlocalsym,
-    this.iextdefsym,
-    this.nextdefsym,
-    this.iundefsym,
-    this.nundefsym,
-    this.tocoff,
-    this.ntoc,
-    this.modtaboff,
-    this.nmodtab,
-    this.extrefsymoff,
-    this.nextrefsyms,
-    this.indirectsymoff,
-    this.nindirectsyms,
-    this.extreloff,
-    this.nextrel,
-    this.locreloff,
-    this.nlocrel,
-  ) : super(
-          MachOConstants.LC_DYSYMTAB,
-          cmdsize,
-        );
+      int code,
+      int size,
+      this.localSymbolsIndex,
+      this.localSymbolsCount,
+      this.externalSymbolsIndex,
+      this.externalSymbolsCount,
+      this.undefinedSymbolsIndex,
+      this.undefinedSymbolsCount,
+      this.tableOfContentsFileOffset,
+      this.tableOfContentsEntryCount,
+      this.moduleTableFileOffset,
+      this.moduleTableEntryCount,
+      this.referencedSymbolTableFileOffset,
+      this.referencedSymbolTableEntryCount,
+      this.indirectSymbolTableFileOffset,
+      this.indirectSymbolTableEntryCount,
+      this.externalRelocationsFileOffset,
+      this.externalRelocationsCount,
+      this.localRelocationsFileOffset,
+      this.localRelocationsCount)
+      : super(code, size);
+
+  static MachODysymtabCommand fromStream(
+      int code, int size, MachOReader stream) {
+    final localSymbolsIndex = stream.readUint32();
+    final localSymbolsCount = stream.readUint32();
+    final externalSymbolsIndex = stream.readUint32();
+    final externalSymbolsCount = stream.readUint32();
+    final undefinedSymbolsIndex = stream.readUint32();
+    final undefinedSymbolsCount = stream.readUint32();
+    final tableOfContentsFileOffset = stream.readUint32();
+    final tableOfContentsEntryCount = stream.readUint32();
+    final moduleTableFileOffset = stream.readUint32();
+    final moduleTableEntryCount = stream.readUint32();
+    final referencedSymbolTableFileOffset = stream.readUint32();
+    final referencedSymbolTableEntryCount = stream.readUint32();
+    final indirectSymbolTableFileOffset = stream.readUint32();
+    final indirectSymbolTableEntryCount = stream.readUint32();
+    final externalRelocationsFileOffset = stream.readUint32();
+    final externalRelocationsCount = stream.readUint32();
+    final localRelocationsFileOffset = stream.readUint32();
+    final localRelocationsCount = stream.readUint32();
+
+    return MachODysymtabCommand(
+        code,
+        size,
+        localSymbolsIndex,
+        localSymbolsCount,
+        externalSymbolsIndex,
+        externalSymbolsCount,
+        undefinedSymbolsIndex,
+        undefinedSymbolsCount,
+        tableOfContentsFileOffset,
+        tableOfContentsEntryCount,
+        moduleTableFileOffset,
+        moduleTableEntryCount,
+        referencedSymbolTableFileOffset,
+        referencedSymbolTableEntryCount,
+        indirectSymbolTableFileOffset,
+        indirectSymbolTableEntryCount,
+        externalRelocationsFileOffset,
+        externalRelocationsCount,
+        localRelocationsFileOffset,
+        localRelocationsCount);
+  }
 
   @override
-  MachODysymtabCommand asType() => this;
+  MachODysymtabCommand adjust(OffsetsAdjuster adjuster) => MachODysymtabCommand(
+      code,
+      size,
+      localSymbolsIndex,
+      localSymbolsCount,
+      externalSymbolsIndex,
+      externalSymbolsCount,
+      undefinedSymbolsIndex,
+      undefinedSymbolsCount,
+      adjuster.adjust(tableOfContentsFileOffset),
+      tableOfContentsEntryCount,
+      adjuster.adjust(moduleTableFileOffset),
+      moduleTableEntryCount,
+      adjuster.adjust(referencedSymbolTableFileOffset),
+      referencedSymbolTableEntryCount,
+      adjuster.adjust(indirectSymbolTableFileOffset),
+      indirectSymbolTableEntryCount,
+      adjuster.adjust(externalRelocationsFileOffset),
+      externalRelocationsCount,
+      adjuster.adjust(localRelocationsFileOffset),
+      localRelocationsCount);
 
   @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint32(ilocalsym);
-    stream.writeUint32(nlocalsym);
-    stream.writeUint32(iextdefsym);
-    stream.writeUint32(nextdefsym);
-    stream.writeUint32(iundefsym);
-    stream.writeUint32(nundefsym);
-    stream.writeUint32(tocoff);
-    stream.writeUint32(ntoc);
-    stream.writeUint32(modtaboff);
-    stream.writeUint32(nmodtab);
-    stream.writeUint32(extrefsymoff);
-    stream.writeUint32(nextrefsyms);
-    stream.writeUint32(indirectsymoff);
-    stream.writeUint32(nindirectsyms);
-    stream.writeUint32(extreloff);
-    stream.writeUint32(nextrel);
-    stream.writeUint32(locreloff);
-    stream.writeUint32(nlocrel);
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeUint32(localSymbolsIndex);
+    stream.writeUint32(localSymbolsCount);
+    stream.writeUint32(externalSymbolsIndex);
+    stream.writeUint32(externalSymbolsCount);
+    stream.writeUint32(undefinedSymbolsIndex);
+    stream.writeUint32(undefinedSymbolsCount);
+    stream.writeUint32(tableOfContentsFileOffset);
+    stream.writeUint32(tableOfContentsEntryCount);
+    stream.writeUint32(moduleTableFileOffset);
+    stream.writeUint32(moduleTableEntryCount);
+    stream.writeUint32(referencedSymbolTableFileOffset);
+    stream.writeUint32(referencedSymbolTableEntryCount);
+    stream.writeUint32(indirectSymbolTableFileOffset);
+    stream.writeUint32(indirectSymbolTableEntryCount);
+    stream.writeUint32(externalRelocationsFileOffset);
+    stream.writeUint32(externalRelocationsCount);
+    stream.writeUint32(localRelocationsFileOffset);
+    stream.writeUint32(localRelocationsCount);
   }
 }
 
-/* a table of contents entry */
-class MachODylibTableOfContents {
-  final Uint32
-      symbol_index; /* the defined external symb(uint32_t) ol
-				   (index into the symbol table) */
-  final Uint32
-      module_index; /* index into the module table this symb(uint32_t) ol
-				   is defined in */
+/// A load command that contains the offsets and sizes of a blob of data in
+/// the __LINKEDIT segment. The contents of the blob is determined by the
+/// specific `code` value used for the load command.
+class MachOLinkeditDataCommand extends MachOLoadCommand {
+  /// The file offset for the segment data.
+  ///
+  /// `uint32_t dataoff` in the C headers.
+  final int dataFileOffset;
 
-  MachODylibTableOfContents(
-    this.symbol_index,
-    this.module_index,
-  );
-}
-
-/* a module table entry */
-class MachODylibModule {
-  final Uint32
-      module_name; /* the module name (index into string table) (uint32_t) */
-
-  final Uint32
-      iextdefsym; /* index into externally defined symbols (uint32_t) */
-  final Uint32 nextdefsym; /* number of externally defined symbols (uint32_t) */
-  final Uint32 irefsym; /* index into reference symbol table (uint32_t) */
-  final Uint32
-      nrefsym; /* number of reference symbol table entries (uint32_t) */
-  final Uint32 ilocalsym; /* index into symbols for local symbols (uint32_t) */
-  final Uint32 nlocalsym; /* number of local symbols (uint32_t) */
-
-  final Uint32 iextrel; /* index into external relocation entries (uint32_t) */
-  final Uint32 nextrel; /* number of external relocation entries (uint32_t) */
-
-  final Uint32
-      iinit_iterm; /* low 16 bits are the index into the in(uint32_t) it
-				   section, high 16 bits are the index into
-			           the term section */
-  final Uint32
-      ninit_nterm; /* low 16 bits are the number of init secti(uint32_t) on
-				   entries, high 16 bits are the number of
-				   term section entries */
-
-  final Uint32 /* for this module address of the start of (uint32_t) */
-      objc_module_info_addr; /*  the (__OBJC,__module_info) section */
-  final Uint32 /* for this module size of (uint32_t) */
-      objc_module_info_size; /*  the (__OBJC,__module_info) section */
-
-  MachODylibModule(
-    this.module_name,
-    this.iextdefsym,
-    this.nextdefsym,
-    this.irefsym,
-    this.nrefsym,
-    this.ilocalsym,
-    this.nlocalsym,
-    this.iextrel,
-    this.nextrel,
-    this.iinit_iterm,
-    this.ninit_nterm,
-    this.objc_module_info_addr,
-    this.objc_module_info_size,
-  );
-}
-
-/* a 64-bit module table entry */
-class MachODylibModule64 {
-  final Uint32
-      module_name; /* the module name (index into string table) (uint32_t) */
-
-  final Uint32
-      iextdefsym; /* index into externally defined symbols (uint32_t) */
-  final Uint32 nextdefsym; /* number of externally defined symbols (uint32_t) */
-  final Uint32 irefsym; /* index into reference symbol table (uint32_t) */
-  final Uint32
-      nrefsym; /* number of reference symbol table entries (uint32_t) */
-  final Uint32 ilocalsym; /* index into symbols for local symbols (uint32_t) */
-  final Uint32 nlocalsym; /* number of local symbols (uint32_t) */
-
-  final Uint32 iextrel; /* index into external relocation entries (uint32_t) */
-  final Uint32 nextrel; /* number of external relocation entries (uint32_t) */
-
-  final Uint32
-      iinit_iterm; /* low 16 bits are the index into the in(uint32_t) it
-				   section, high 16 bits are the index into
-				   the term section */
-  final Uint32
-      ninit_nterm; /* low 16 bits are the number of init secti(uint32_t) on
-				  entries, high 16 bits are the number of
-				  term section entries */
-
-  final Uint32 /* for this module size of (uint32_t) */
-      objc_module_info_size; /*  the (__OBJC,__module_info) section */
-  final Uint64 /* for this module address of the start of (uint64_t) */
-      objc_module_info_addr; /*  the (__OBJC,__module_info) section */
-
-  MachODylibModule64(
-    this.module_name,
-    this.iextdefsym,
-    this.nextdefsym,
-    this.irefsym,
-    this.nrefsym,
-    this.ilocalsym,
-    this.nlocalsym,
-    this.iextrel,
-    this.nextrel,
-    this.iinit_iterm,
-    this.ninit_nterm,
-    this.objc_module_info_size,
-    this.objc_module_info_addr,
-  );
-}
-
-/*
- * The entries in the reference symbol table are used when loading the module
- * (both by the static and dynamic link editors) and if the module is unloaded
- * or replaced.  Therefore all external symbols (defined and undefined) are
- * listed in the module's reference table.  The flags describe the type of
- * reference that is being made.  The constants for the flags are defined in
- * <mach-o/nlist.h> as they are also used for symbol table entries.
- */
-class MachODylibReference {
-  final Uint32 isym; //:24,		/* index into the symbol table (uint32_t) */
-  final Uint32 flags; //:8;	/* flags to indicate the type of reference */
-
-  MachODylibReference(Uint32 value)
-      : isym = value & Uint32(0xffffff),
-        flags = value >> Uint32(24);
-}
-
-/*
- * The twolevel_hints_command contains the offset and number of hints in the
- * two-level namespace lookup hints table.
- */
-class MachOTwolevelHintsCommand
-    extends IMachOLoadCommand<MachOTwolevelHintsCommand> {
-  final Uint32 offset; /* offset to the hint table (uint32_t) */
-  final Uint32 nhints; /* number of hints in the hint table (uint32_t) */
-
-  MachOTwolevelHintsCommand(
-    Uint32 cmdsize,
-    this.offset,
-    this.nhints,
-  ) : super(
-          MachOConstants.LC_TWOLEVEL_HINTS,
-          cmdsize,
-        );
-
-  @override
-  MachOTwolevelHintsCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint32(offset);
-    stream.writeUint32(nhints);
-  }
-}
-
-/*
- * The entries in the two-level namespace lookup hints table are twolevel_hint
- * structs.  These provide hints to the dynamic link editor where to start
- * looking for an undefined symbol in a two-level namespace image.  The
- * isub_image field is an index into the sub-images (sub-frameworks and
- * sub-umbrellas list) that made up the two-level image that the undefined
- * symbol was found in when it was built by the static link editor.  If
- * isub-image is 0 the symbol is expected to be defined in library and not
- * in the sub-images.  If isub-image is non-zero it is an index into the array
- * of sub-images for the umbrella with the first index in the sub-images being
- * 1. The array of sub-images is the ordered list of sub-images of the umbrella
- * that would be searched for a symbol that has the umbrella recorded as its
- * primary library.  The table of contents index is an index into the
- * library's table of contents.  This is used as the starting point of the
- * binary search or a directed linear search.
- */
-class MachOTwolevelHint {
-  final int isub_image; //:8,	/* index into the sub images */
-  final int itoc; //:24;	/* index into the table of contents */
-
-  MachOTwolevelHint(int value)
-      : isub_image = value & 0xff,
-        itoc = value >> 8;
-}
-
-/*
- * The prebind_cksum_command contains the value of the original check sum for
- * prebound files or zero.  When a prebound file is first created or modified
- * for other than updating its prebinding information the value of the check sum
- * is set to zero.  When the file has it prebinding re-done and if the value of
- * the check sum is zero the original check sum is calculated and stored in
- * cksum field of this load command in the output file.  If when the prebinding
- * is re-done and the cksum field is non-zero it is left unchanged from the
- * input file.
- */
-class MachOPrebindCksumCommand
-    extends IMachOLoadCommand<MachOPrebindCksumCommand> {
-  final Uint32 cksum; /* the check sum or zero (uint32_t) */
-
-  MachOPrebindCksumCommand(
-    Uint32 cmdsize,
-    this.cksum,
-  ) : super(
-          MachOConstants.LC_PREBIND_CKSUM,
-          cmdsize,
-        );
-
-  @override
-  MachOPrebindCksumCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint32(cksum);
-  }
-}
-
-/*
- * The uuid load command contains a single 128-bit unique random number that
- * identifies an object produced by the static link editor.
- */
-class MachOUuidCommand extends IMachOLoadCommand<MachOUuidCommand> {
-  final Uint8List uuid; //[16];	/* the 128-bit uuid */
-
-  MachOUuidCommand(
-    Uint32 cmdsize,
-    this.uuid,
-  ) : super(
-          MachOConstants.LC_UUID,
-          cmdsize,
-        );
-
-  @override
-  MachOUuidCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeFromSync(uuid);
-  }
-}
-
-/*
- * The rpath_command contains a path which at runtime should be added to
- * the current run path used to find @rpath prefixed dylibs.
- */
-class MachORpathCommand extends IMachOLoadCommand<MachORpathCommand> {
-  final MachOStr path; /* path to add to run path */
-
-  MachORpathCommand(
-    Uint32 cmdsize,
-    this.path,
-  ) : super(
-          MachOConstants.LC_RPATH,
-          cmdsize,
-        );
-
-  @override
-  MachORpathCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    path.writeContentsSync(stream);
-  }
-}
-
-/*
- * The linkedit_data_command contains the offsets and sizes of a blob
- * of data in the __LINKEDIT segment.
- */
-class MachOLinkeditDataCommand
-    extends IMachOLoadCommand<MachOLinkeditDataCommand> {
-  final Uint32
-      dataoff; /* file offset of data in __LINKEDIT segment (uint32_t) */
-  final Uint32
-      datasize; /* file size of data in __LINKEDIT segment  (uint32_t) */
+  /// The file size of the segment data.
+  ///
+  /// `uint32_t datasize` in the C headers.
+  final int dataSize;
 
   MachOLinkeditDataCommand(
-    Uint32 cmd,
-    Uint32 cmdsize,
-    this.dataoff,
-    this.datasize,
-  ) : super(cmd, cmdsize) {
-    if (this.cmd != MachOConstants.LC_CODE_SIGNATURE &&
-        this.cmd != MachOConstants.LC_SEGMENT_SPLIT_INFO &&
-        this.cmd != MachOConstants.LC_FUNCTION_STARTS &&
-        this.cmd != MachOConstants.LC_DATA_IN_CODE &&
-        this.cmd != MachOConstants.LC_DYLIB_CODE_SIGN_DRS) {
-      throw ArgumentError("cmd was not one of LC_CODE_SIGNATURE "
-          "(${MachOConstants.LC_CODE_SIGNATURE}), LC_SEGMENT_SPLIT_INFO "
-          "(${MachOConstants.LC_SEGMENT_SPLIT_INFO}), LC_FUNCTION_STARTS "
-          "(${MachOConstants.LC_FUNCTION_STARTS}), LC_DATA_IN_CODE "
-          "(${MachOConstants.LC_DATA_IN_CODE}), LC_DYLIB_CODE_SIGN_DRS "
-          "(${MachOConstants.LC_DYLIB_CODE_SIGN_DRS}): $cmd");
+    int code,
+    int size,
+    this.dataFileOffset,
+    this.dataSize,
+  ) : super(code, size);
+
+  static MachOLinkeditDataCommand fromStream(
+      int code, final int size, MachOReader stream) {
+    final dataFileOffset = stream.readUint32();
+    final dataSize = stream.readUint32();
+
+    return MachOLinkeditDataCommand(code, size, dataFileOffset, dataSize);
+  }
+
+  @override
+  MachOLinkeditDataCommand adjust(OffsetsAdjuster adjuster) =>
+      MachOLinkeditDataCommand(
+          code, size, adjuster.adjust(dataFileOffset), dataSize);
+
+  @override
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeUint32(dataFileOffset);
+    stream.writeUint32(dataSize);
+  }
+}
+
+/// A load command that contains the offset and size of an encrypted segment.
+class MachOEncryptionInfoCommand extends MachOLoadCommand {
+  /// The file offset for the encrypted segment.
+  ///
+  /// `uint32_t cryptoff` in the C headers.
+  final int fileOffset;
+
+  /// The file size of the encrypted segment.
+  ///
+  /// `uint32_t cryptsize` in the C headers.
+  final int fileSize;
+
+  /// The id of the encryption system used for the encrypted segment.
+  /// A value of 0 means that the segment is not yet encrypted.
+  ///
+  /// `uint32_t cryptid` in the C headers.
+  final int encryptionSystem;
+
+  /// Padding for 64-bit encryption info load commands. Null for 32-bit
+  /// encryption info load commands.
+  ///
+  /// `uint32_t pad` for `encryption_info_command_64` in the C headers.
+  final int? padding;
+
+  MachOEncryptionInfoCommand(int code, int size, this.fileOffset, this.fileSize,
+      this.encryptionSystem, this.padding)
+      : super(code, size);
+
+  static MachOEncryptionInfoCommand fromStream(
+      int code, final int size, MachOReader stream) {
+    final is64Bit =
+        LoadCommandType.fromCode(code) == LoadCommandType.encryptionInfo64;
+
+    final fileOffset = stream.readUint32();
+    final fileSize = stream.readUint32();
+    final encryptionSystem = stream.readUint32();
+    int? padding;
+    if (is64Bit) {
+      padding = stream.readUint32();
+    }
+
+    return MachOEncryptionInfoCommand(
+        code, size, fileOffset, fileSize, encryptionSystem, padding);
+  }
+
+  @override
+  MachOEncryptionInfoCommand adjust(OffsetsAdjuster adjuster) =>
+      MachOEncryptionInfoCommand(code, size, adjuster.adjust(fileOffset),
+          fileSize, encryptionSystem, padding);
+
+  @override
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeUint32(fileOffset);
+    stream.writeUint32(fileSize);
+    stream.writeUint32(encryptionSystem);
+    if (padding != null) {
+      stream.writeUint32(padding!);
     }
   }
-
-  @override
-  MachOLinkeditDataCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint32(dataoff);
-    stream.writeUint32(datasize);
-  }
 }
 
-/*
- * The encryption_info_command contains the file offset and size of an
- * of an encrypted segment.
- */
-class MachOEncryptionInfoCommand
-    extends IMachOLoadCommand<MachOEncryptionInfoCommand> {
-  final Uint32 cryptoff; /* file offset of encrypted range (uint32_t) */
-  final Uint32 cryptsize; /* file size of encrypted range (uint32_t) */
-  final Uint32
-      cryptid; /* which enryption syste(uint32_t) m,
-				   0 means not-encrypted yet */
+/// A load command that contains the file offsets and sizes of  the new
+/// compressed form of the information dyld needs to load the image on
+/// MacOS 10.6 and later.
+class MachODyldInfoCommand extends MachOLoadCommand {
+  /// File offset for rebase information.
+  ///
+  /// `uint32_t rebase_off` in the C headers.
+  final int rebaseOffset;
 
-  MachOEncryptionInfoCommand(
-    Uint32 cmdsize,
-    this.cryptoff,
-    this.cryptsize,
-    this.cryptid,
-  ) : super(
-          MachOConstants.LC_ENCRYPTION_INFO,
-          cmdsize,
-        );
+  /// File size of rebase information.
+  ///
+  /// `uint32_t rebase_size` in the C headers.
+  final int rebaseSize;
 
-  @override
-  MachOEncryptionInfoCommand asType() => this;
+  /// File offset for binding information.
+  ///
+  /// `uint32_t bind_off` in the C headers.
+  final int bindingOffset;
 
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint32(cryptoff);
-    stream.writeUint32(cryptsize);
-    stream.writeUint32(cryptid);
-  }
-}
+  /// File size of binding information.
+  ///
+  /// `uint32_t bind_size` in the C headers.
+  final int bindingSize;
 
-/*
- * The version_min_command contains the min OS version on which this
- * binary was built to run.
- */
-class MachOVersionMinCommand extends IMachOLoadCommand<MachOVersionMinCommand> {
-  final Uint32 version; /* X.Y.Z is encoded in nibbles xxxx.yy.zz (uint32_t) */
-  final Uint32 sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz (uint32_t) */
+  /// File offset for weak binding information.
+  ///
+  /// `uint32_t weak_bind_off` in the C headers.
+  final int weakBindingOffset;
 
-  MachOVersionMinCommand(
-    Uint32 cmd,
-    Uint32 cmdsize,
-    this.version,
-    this.sdk,
-  ) : super(cmd, cmdsize) {
-    if (this.cmd != MachOConstants.LC_VERSION_MIN_MACOSX &&
-        this.cmd != MachOConstants.LC_VERSION_MIN_IPHONEOS) {
-      throw ArgumentError("cmd was not one of: LC_VERSION_MIN_MACOSX "
-          "(${MachOConstants.LC_VERSION_MIN_MACOSX}), LC_VERSION_MIN_IPHONEOS "
-          "(${MachOConstants.LC_VERSION_MIN_IPHONEOS}): $cmd");
-    }
-  }
+  /// File size of weak binding information.
+  ///
+  /// `uint32_t weak_bind_size` in the C headers.
+  final int weakBindingSize;
 
-  @override
-  MachOVersionMinCommand asType() => this;
+  /// File offset for lazy binding information.
+  ///
+  /// `uint32_t lazy_bind_off` in the C headers.
+  final int lazyBindingOffset;
 
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint32(version);
-    stream.writeUint32(sdk);
-  }
-}
+  /// File size of lazy binding information.
+  ///
+  /// `uint32_t lazy_bind_size` in the C headers.
+  final int lazyBindingSize;
 
-/*
- * The dyld_info_command contains the file offsets and sizes of
- * the new compressed form of the information dyld needs to
- * load the image.  This information is used by dyld on Mac OS X
- * 10.6 and later.  All information pointed to by this command
- * is encoded using byte streams, so no endian swapping is needed
- * to interpret it.
- */
-class MachODyldInfoCommand extends IMachOLoadCommand<MachODyldInfoCommand> {
-  /*
-     * Dyld rebases an image whenever dyld loads it at an address different
-     * from its preferred address.  The rebase information is a stream
-     * of byte sized opcodes whose symbolic names start with REBASE_OPCODE_.
-     * Conceptually the rebase information is a table of tuples:
-     *    <seg-index, seg-offset, type>
-     * The opcodes are a compressed way to encode the table by only
-     * encoding when a column changes.  In addition simple patterns
-     * like "every n'th offset for m times" can be encoded in a few
-     * bytes.
-     */
-  final Uint32 rebase_off; /* file offset to rebase info  (uint32_t) */
-  final Uint32 rebase_size; /* size of rebase info   (uint32_t) */
+  /// File offset for export information.
+  ///
+  /// `uint32_t export_off` in the C headers.
+  final int exportOffset;
 
-  /*
-  * Dyld binds an image during the loading process, if the image
-  * requires any pointers to be initialized to symbols in other images.
-  * The bind information is a stream of byte sized
-  * opcodes whose symbolic names start with BIND_OPCODE_.
-  * Conceptually the bind information is a table of tuples:
-  *   <seg-index, seg-offset, type, symbol-library-ordinal, symbol-name, addend>
-  * The opcodes are a compressed way to encode the table by only
-  * encoding when a column changes.  In addition simple patterns
-  * like for runs of pointers initialzed to the same value can be
-  * encoded in a few bytes.
-  */
-  final Uint32 bind_off; /* file offset to binding info   (uint32_t) */
-  final Uint32 bind_size; /* size of binding info  (uint32_t) */
-
-  /*
-     * Some C++ programs require dyld to unique symbols so that all
-     * images in the process use the same copy of some code/data.
-     * This step is done after binding. The content of the weak_bind
-     * info is an opcode stream like the bind_info.  But it is sorted
-     * alphabetically by symbol name.  This enable dyld to walk
-     * all images with weak binding information in order and look
-     * for collisions.  If there are no collisions, dyld does
-     * no updating.  That means that some fixups are also encoded
-     * in the bind_info.  For instance, all calls to "operator new"
-     * are first bound to libstdc++.dylib using the information
-     * in bind_info.  Then if some image overrides operator new
-     * that is detected when the weak_bind information is processed
-     * and the call to operator new is then rebound.
-     */
-  final Uint32
-      weak_bind_off; /* file offset to weak binding info   (uint32_t) */
-  final Uint32 weak_bind_size; /* size of weak binding info  (uint32_t) */
-
-  /*
-     * Some uses of external symbols do not need to be bound immediately.
-     * Instead they can be lazily bound on first use.  The lazy_bind
-     * are contains a stream of BIND opcodes to bind all lazy symbols.
-     * Normal use is that dyld ignores the lazy_bind section when
-     * loading an image.  Instead the static linker arranged for the
-     * lazy pointer to initially point to a helper function which
-     * pushes the offset into the lazy_bind area for the symbol
-     * needing to be bound, then jumps to dyld which simply adds
-     * the offset to lazy_bind_off to get the information on what
-     * to bind.
-     */
-  final Uint32 lazy_bind_off; /* file offset to lazy binding info (uint32_t) */
-  final Uint32 lazy_bind_size; /* size of lazy binding infs (uint32_t) */
-
-  /*
-     * The symbols exported by a dylib are encoded in a trie.  This
-     * is a compact representation that factors out common prefixes.
-     * It also reduces LINKEDIT pages in RAM because it encodes all
-     * information (name, address, flags) in one small, contiguous range.
-     * The export area is a stream of nodes.  The first node sequentially
-     * is the start node for the trie.
-     *
-     * Nodes for a symbol start with a uleb128 that is the length of
-     * the exported symbol information for the string so far.
-     * If there is no exported symbol, the node starts with a zero byte.
-     * If there is exported info, it follows the length.
-	 *
-	 * First is a uleb128 containing flags. Normally, it is followed by
-     * a uleb128 encoded offset which is location of the content named
-     * by the symbol from the mach_header for the image.  If the flags
-     * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is
-     * a uleb128 encoded library ordinal, then a zero terminated
-     * UTF8 string.  If the string is zero length, then the symbol
-     * is re-export from the specified dylib with the same name.
-	 * If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following
-	 * the flags is two uleb128s: the stub offset and the resolver offset.
-	 * The stub is used by non-lazy pointers.  The resolver is used
-	 * by lazy pointers and must be called to get the actual address to use.
-     *
-     * After the optional exported symbol information is a byte of
-     * how many edges (0-255) that this node has leaving it,
-     * followed by each edge.
-     * Each edge is a zero terminated UTF8 of the addition chars
-     * in the symbol, followed by a uleb128 offset for the node that
-     * edge points to.
-     *
-     */
-  final Uint32 export_off; /* file offset to lazy binding info (uint32_t) */
-  final Uint32 export_size; /* size of lazy binding infs (uint32_t) */
+  /// File size of export information.
+  ///
+  /// `uint32_t export_size` in the C headers.
+  final int exportSize;
 
   MachODyldInfoCommand(
-    Uint32 cmd,
-    Uint32 cmdsize,
-    this.rebase_off,
-    this.rebase_size,
-    this.bind_off,
-    this.bind_size,
-    this.weak_bind_off,
-    this.weak_bind_size,
-    this.lazy_bind_off,
-    this.lazy_bind_size,
-    this.export_off,
-    this.export_size,
-  ) : super(
-          cmd,
-          cmdsize,
-        ) {
-    if (this.cmd != MachOConstants.LC_DYLD_INFO &&
-        this.cmd != MachOConstants.LC_DYLD_INFO_ONLY) {
-      throw ArgumentError(
-          "cmd was not one of LC_DYLD_INFO (${MachOConstants.LC_DYLD_INFO}), "
-          "LC_DYLD_INFO_ONLY (${MachOConstants.LC_DYLD_INFO_ONLY}): $cmd");
-    }
+      int code,
+      int size,
+      this.rebaseOffset,
+      this.rebaseSize,
+      this.bindingOffset,
+      this.bindingSize,
+      this.weakBindingOffset,
+      this.weakBindingSize,
+      this.lazyBindingOffset,
+      this.lazyBindingSize,
+      this.exportOffset,
+      this.exportSize)
+      : super(code, size);
+
+  static MachODyldInfoCommand fromStream(
+      int code, int size, MachOReader stream) {
+    final rebaseOffset = stream.readUint32();
+    final rebaseSize = stream.readUint32();
+    final bindingOffset = stream.readUint32();
+    final bindingSize = stream.readUint32();
+    final weakBindingOffset = stream.readUint32();
+    final weakBindingSize = stream.readUint32();
+    final lazyBindingOffset = stream.readUint32();
+    final lazyBindingSize = stream.readUint32();
+    final exportOffset = stream.readUint32();
+    final exportSize = stream.readUint32();
+
+    return MachODyldInfoCommand(
+        code,
+        size,
+        rebaseOffset,
+        rebaseSize,
+        bindingOffset,
+        bindingSize,
+        weakBindingOffset,
+        weakBindingSize,
+        lazyBindingOffset,
+        lazyBindingSize,
+        exportOffset,
+        exportSize);
   }
 
   @override
-  MachODyldInfoCommand asType() => this;
+  MachODyldInfoCommand adjust(OffsetsAdjuster adjuster) => MachODyldInfoCommand(
+      code,
+      size,
+      adjuster.adjust(rebaseOffset),
+      rebaseSize,
+      adjuster.adjust(bindingOffset),
+      bindingSize,
+      adjuster.adjust(weakBindingOffset),
+      weakBindingSize,
+      adjuster.adjust(lazyBindingOffset),
+      lazyBindingSize,
+      adjuster.adjust(exportOffset),
+      exportSize);
 
   @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint32(rebase_off);
-    stream.writeUint32(rebase_size);
-    stream.writeUint32(bind_off);
-    stream.writeUint32(bind_size);
-    stream.writeUint32(weak_bind_off);
-    stream.writeUint32(weak_bind_size);
-    stream.writeUint32(lazy_bind_off);
-    stream.writeUint32(lazy_bind_size);
-    stream.writeUint32(export_off);
-    stream.writeUint32(export_size);
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeUint32(rebaseOffset);
+    stream.writeUint32(rebaseSize);
+    stream.writeUint32(bindingOffset);
+    stream.writeUint32(bindingSize);
+    stream.writeUint32(weakBindingOffset);
+    stream.writeUint32(weakBindingSize);
+    stream.writeUint32(lazyBindingOffset);
+    stream.writeUint32(lazyBindingSize);
+    stream.writeUint32(exportOffset);
+    stream.writeUint32(exportSize);
   }
 }
 
-/*
- * The symseg_command contains the offset and size of the GNU style
- * symbol table information as described in the header file <symseg.h>.
- * The symbol roots of the symbol segments must also be aligned properly
- * in the file.  So the requirement of keeping the offsets aligned to a
- * multiple of a 4 bytes translates to the length field of the symbol
- * roots also being a multiple of a long.  Also the padding must again be
- * zeroed. (THIS IS OBSOLETE and no longer supported).
- */
-class MachOSymsegCommand extends IMachOLoadCommand<MachOSymsegCommand> {
-  final Uint32 offset; /* symbol segment offset (uint32_t) */
-  final Uint32 size; /* symbol segment size in bytes (uint32_t) */
+/// A load command used for executables to specify the file offset of the entry
+/// point of the program.
+class MachOEntryPointCommand extends MachOLoadCommand {
+  /// The file offset of the entry point to the program (e.g., main()).
+  ///
+  /// `uint64_t entryoff` in the C headers.
+  final int entryOffset;
 
-  MachOSymsegCommand(
-    Uint32 cmdsize,
-    this.offset,
-    this.size,
-  ) : super(
-          MachOConstants.LC_SYMSEG,
-          cmdsize,
-        );
+  /// When non-zero, specifies the initial stack size.
+  ///
+  /// `uint64_t stacksize` in the C headers.
+  final int stackSize;
+
+  MachOEntryPointCommand(int code, int size, this.entryOffset, this.stackSize)
+      : super(code, size);
+
+  static MachOEntryPointCommand fromStream(
+      int code, int size, MachOReader stream) {
+    final entryOffset = stream.readUint64();
+    final stackSize = stream.readUint64();
+    return MachOEntryPointCommand(code, size, entryOffset, stackSize);
+  }
 
   @override
-  MachOSymsegCommand asType() => this;
+  MachOEntryPointCommand adjust(OffsetsAdjuster adjuster) =>
+      MachOEntryPointCommand(
+          code, size, adjuster.adjust(entryOffset), stackSize);
 
   @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint32(offset);
-    stream.writeUint32(size);
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeUint64(entryOffset);
+    stream.writeUint64(stackSize);
   }
 }
 
-/*
- * The ident_command contains a free format string table following the
- * ident_command structure.  The strings are null terminated and the size of
- * the command is padded out with zero bytes to a multiple of 4 bytes/
- * (THIS IS OBSOLETE and no longer supported).
- */
-class MachOIdentCommand extends IMachOLoadCommand<MachOIdentCommand> {
-  MachOIdentCommand(
-    Uint32 cmdsize,
-  ) : super(
-          MachOConstants.LC_IDENT,
-          cmdsize,
-        );
+/// A load command that references an array of entries in the __LINKEDIT
+/// segment, each of which describes a range of data located in the __TEXT
+/// segment.
+class MachODataInCodeEntry extends MachOLoadCommand {
+  /// The file offset of the array of data in code entries.
+  ///
+  /// `uint32_t offset` in the C headers.
+  final int offset;
 
-  @override
-  MachOIdentCommand asType() => this;
+  /// The length of the array of data in bytes.
+  ///
+  /// `uint16_t length` in the C headers.
+  final int length;
 
-  @override
-  void writeContentsSync(RandomAccessFile stream) {}
-}
-
-/*
- * The fvmfile_command contains a reference to a file to be loaded at the
- * specified virtual address.  (Presently, this command is reserved for
- * internal use.  The kernel ignores this command when loading a program into
- * memory).
- */
-class MachOFvmfileCommand extends IMachOLoadCommand<MachOFvmfileCommand> {
-  final MachOStr name; /* files pathname */
-  final Uint32 header_addr; /* files virtual address (uint32_t) */
-
-  MachOFvmfileCommand(
-    Uint32 cmdsize,
-    this.name,
-    this.header_addr,
-  ) : super(
-          MachOConstants.LC_FVMFILE,
-          cmdsize,
-        );
-
-  @override
-  MachOFvmfileCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    name.writeContentsSync(stream);
-    stream.writeUint32(header_addr);
-  }
-}
-
-/*
- * The entry_point_command is a replacement for thread_command.
- * It is used for main executables to specify the location (file offset)
- * of main().  If -stack_size was used at link time, the stacksize
- * field will contain the stack size need for the main thread.
- */
-class MachOEntryPointCommand extends IMachOLoadCommand<MachOEntryPointCommand> {
-  final Uint64 entryoff; /* file (__TEXT) offset of main (uint64_t)() */
-  final Uint64 stacksize; /* if not zero, initial stack size (uint64_t) */
-
-  MachOEntryPointCommand(
-    Uint32 cmdsize,
-    this.entryoff,
-    this.stacksize,
-  ) : super(
-          MachOConstants.LC_MAIN,
-          cmdsize,
-        );
-
-  @override
-  MachOEntryPointCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint64(entryoff);
-    stream.writeUint64(stacksize);
-  }
-}
-
-/*
- * The source_version_command is an optional load command containing
- * the version of the sources used to build the binary.
- */
-class MachOSourceVersionCommand
-    extends IMachOLoadCommand<MachOSourceVersionCommand> {
-  final Uint64 version; /* A.B.C.D.E packed as a24.b10.c10.d10.e10 (uint64_t) */
-
-  MachOSourceVersionCommand(
-    Uint32 cmdsize,
-    this.version,
-  ) : super(
-          MachOConstants.LC_SOURCE_VERSION,
-          cmdsize,
-        );
-
-  @override
-  MachOSourceVersionCommand asType() => this;
-
-  @override
-  void writeContentsSync(RandomAccessFile stream) {
-    stream.writeUint64(version);
-  }
-}
-
-/*
- * The LC_DATA_IN_CODE load commands uses a linkedit_data_command
- * to point to an array of data_in_code_entry entries. Each entry
- * describes a range of data in a code section.  This load command
- * is only used in final linked images.
- */
-class MachODataInCodeEntry {
-  final Uint32 offset; /* from mach_header to start of data range(uint32_t) */
-  final Uint16 length; /* number of bytes in data range (uint16_t) */
-  final Uint16 kind; /* a DICE_KIND_* value  (uint16_t) */
+  /// The kind of entries contained in the array as a `DICE_KIND_` value.
+  ///
+  /// `uint16_t kind` in the C headers.
+  final int kind;
 
   MachODataInCodeEntry(
+    int code,
+    int size,
     this.offset,
     this.length,
     this.kind,
-  );
+  ) : super(code, size);
+
+  static MachODataInCodeEntry fromStream(
+      int code, int size, MachOReader stream) {
+    final offset = stream.readUint32();
+    final length = stream.readUint16();
+    final kind = stream.readUint16();
+    return MachODataInCodeEntry(code, size, offset, length, kind);
+  }
+
+  @override
+  MachODataInCodeEntry adjust(OffsetsAdjuster adjuster) =>
+      MachODataInCodeEntry(code, size, adjuster.adjust(offset), length, kind);
+
+  @override
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeUint32(offset);
+    stream.writeUint16(length);
+    stream.writeUint16(kind);
+  }
 }
 
-/*
- * Sections of type S_THREAD_LOCAL_VARIABLES contain an array
- * of tlv_descriptor structures.
- */
-// class MachOTlvDescriptor {
-// 	void*		(*thunk)(struct tlv_descriptor*);
-// 	unsigned long	key;
-// 	unsigned long	offset;
+/// A load command that points to an arbitrary block of data in the file.
+class MachONoteCommand extends MachOLoadCommand {
+  /// The owner name for this note.
+  ///
+  /// `char data_owner[16]` in the C headers.
+  final String dataOwner;
 
-// 	MachOTlvDescriptor(
-//     void*		(*thunk)(struct tlv_descriptor*);
-// 	unsigned long	key;
-// 	unsigned long	offset;
-// );
+  /// The file offset for the data.
+  ///
+  /// `uint64_t offset` in the C headers.
+  final int fileOffset;
 
-// }
+  /// The file size of the data.
+  ///
+  /// `uint64_t size` in the C headers.
+  final int fileSize;
 
-class MachOConstants {
-  /* Constant for the magic field of the mach_header (32-bit architectures) */
-  static const Uint32 MH_MAGIC = Uint32(0xfeedface); /* the mach magic number */
-  static const Uint32 MH_CIGAM = Uint32(0xcefaedfe); /* NXSwapInt(MH_MAGIC) */
+  MachONoteCommand(
+      int code, int size, this.dataOwner, this.fileOffset, this.fileSize)
+      : super(code, size);
 
-  /* Constant for the magic field of the mach_header_64 (64-bit architectures) */
-  static const Uint32 MH_MAGIC_64 =
-      Uint32(0xfeedfacf); /* the 64-bit mach magic number */
-  static const Uint32 MH_CIGAM_64 =
-      Uint32(0xcffaedfe); /* NXSwapInt(MH_MAGIC_64) */
+  static const _dataOwnerLength = 16;
 
-  /*
-  * After MacOS X 10.1 when a new load command is added that is required to be
-  * understood by the dynamic linker for the image to execute properly the
-  * LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic
-  * linker sees such a load command it it does not understand will issue a
-  * "unknown load command required for execution" error and refuse to use the
-  * image.  Other load commands without this bit that are not understood will
-  * simply be ignored.
-  */
-  static const Uint32 LC_REQ_DYLD = Uint32(0x80000000);
-  // This one is a convenience so we can define other constants in this class as
-  // actual const.
-  static const int _LC_REQ_DYLD = 0x80000000;
+  static MachONoteCommand fromStream(int code, int size, MachOReader stream) {
+    final dataOwner =
+        stream.readFixedLengthNullTerminatedString(_dataOwnerLength);
+    final fileOffset = stream.readUint64();
+    final fileSize = stream.readUint64();
+    return MachONoteCommand(code, size, dataOwner, fileOffset, fileSize);
+  }
 
-  /*; Constants for the cmd field of all load commands, the type */
-  static const Uint32 LC_SEGMENT =
-      Uint32(0x1); /* segment of this file to be mapped */
-  static const Uint32 LC_SYMTAB =
-      Uint32(0x2); /* link-edit stab symbol table info */
-  static const Uint32 LC_SYMSEG =
-      Uint32(0x3); /* link-edit gdb symbol table info (obsolete) */
-  static const Uint32 LC_THREAD = Uint32(0x4); /* thread */
-  static const Uint32 LC_UNIXTHREAD =
-      Uint32(0x5); /* unix thread (includes a stack) */
-  static const Uint32 LC_LOADFVMLIB =
-      Uint32(0x6); /* load a specified fixed VM shared library */
-  static const Uint32 LC_IDFVMLIB =
-      Uint32(0x7); /* fixed VM shared library identification */
-  static const Uint32 LC_IDENT =
-      Uint32(0x8); /* object identification info (obsolete) */
-  static const Uint32 LC_FVMFILE =
-      Uint32(0x9); /* fixed VM file inclusion (internal use) */
-  static const Uint32 LC_PREPAGE =
-      Uint32(0xa); /* prepage command (internal use) */
-  static const Uint32 LC_DYSYMTAB =
-      Uint32(0xb); /* dynamic link-edit symbol table info */
-  static const Uint32 LC_LOAD_DYLIB =
-      Uint32(0xc); /* load a dynamically linked shared library */
-  static const Uint32 LC_ID_DYLIB =
-      Uint32(0xd); /* dynamically linked shared lib ident */
-  static const Uint32 LC_LOAD_DYLINKER =
-      Uint32(0xe); /* load a dynamic linker */
-  static const Uint32 LC_ID_DYLINKER =
-      Uint32(0xf); /* dynamic linker identification */
-  static const Uint32 LC_PREBOUND_DYLIB =
-      Uint32(0x10); /* modules prebound for a dynamically */
-  /*  linked shared library */
-  static const Uint32 LC_ROUTINES = Uint32(0x11); /* image routines */
-  static const Uint32 LC_SUB_FRAMEWORK = Uint32(0x12); /* sub framework */
-  static const Uint32 LC_SUB_UMBRELLA = Uint32(0x13); /* sub umbrella */
-  static const Uint32 LC_SUB_CLIENT = Uint32(0x14); /* sub client */
-  static const Uint32 LC_SUB_LIBRARY = Uint32(0x15); /* sub library */
-  static const Uint32 LC_TWOLEVEL_HINTS =
-      Uint32(0x16); /* two-level namespace lookup hints */
-  static const Uint32 LC_PREBIND_CKSUM = Uint32(0x17); /* prebind checksum */
+  @override
+  MachONoteCommand adjust(OffsetsAdjuster adjuster) => MachONoteCommand(
+      code, size, dataOwner, adjuster.adjust(fileOffset), fileSize);
 
-  /*
-  * load a dynamically linked shared library that is allowed to be missing
-  * (all symbols are weak imported).
-  */
-  static const Uint32 LC_LOAD_WEAK_DYLIB = Uint32(0x18 | _LC_REQ_DYLD);
+  @override
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeFixedLengthNullTerminatedString(dataOwner, _dataOwnerLength);
+    stream.writeUint64(fileOffset);
+    stream.writeUint64(fileSize);
+  }
+}
 
-  static const Uint32 LC_SEGMENT_64 = Uint32(0x19);
-  /* 64-bit segment of this file to be
-	mapped */
-  static const Uint32 LC_ROUTINES_64 = Uint32(0x1a); /* 64-bit image routines */
-  static const Uint32 LC_UUID = Uint32(0x1b); /* the uuid */
-  static const Uint32 LC_RPATH =
-      Uint32(0x1c | _LC_REQ_DYLD); /* runpath additions */
-  static const Uint32 LC_CODE_SIGNATURE =
-      Uint32(0x1d); /* local of code signature */
-  static const Uint32 LC_SEGMENT_SPLIT_INFO =
-      Uint32(0x1e); /* local of info to split segments */
-  static const Uint32 LC_REEXPORT_DYLIB =
-      Uint32(0x1f | _LC_REQ_DYLD); /* load and re-export dylib */
-  static const Uint32 LC_LAZY_LOAD_DYLIB =
-      Uint32(0x20); /* delay load of dylib until first use */
-  static const Uint32 LC_ENCRYPTION_INFO =
-      Uint32(0x21); /* encrypted segment information */
-  static const Uint32 LC_DYLD_INFO =
-      Uint32(0x22); /* compressed dyld information */
-  static const Uint32 LC_DYLD_INFO_ONLY =
-      Uint32(0x22 | _LC_REQ_DYLD); /* compressed dyld information only */
-  static const Uint32 LC_LOAD_UPWARD_DYLIB =
-      Uint32(0x23 | _LC_REQ_DYLD); /* load upward dylib */
-  static const Uint32 LC_VERSION_MIN_MACOSX =
-      Uint32(0x24); /* build for MacOSX min OS version */
-  static const Uint32 LC_VERSION_MIN_IPHONEOS =
-      Uint32(0x25); /* build for iPhoneOS min OS version */
-  static const Uint32 LC_FUNCTION_STARTS =
-      Uint32(0x26); /* compressed table of function start addresses */
-  static const Uint32 LC_DYLD_ENVIRONMENT = Uint32(0x27);
-  /* string for dyld to treat
-	like environment variable */
-  static const Uint32 LC_MAIN =
-      Uint32(0x28 | _LC_REQ_DYLD); /* replacement for LC_UNIXTHREAD */
-  static const Uint32 LC_DATA_IN_CODE =
-      Uint32(0x29); /* table of non-instructions in __text */
-  static const Uint32 LC_SOURCE_VERSION =
-      Uint32(0x2A); /* source version used to build binary */
-  static const Uint32 LC_DYLIB_CODE_SIGN_DRS =
-      Uint32(0x2B); /* Code signing DRs copied from linked dylibs */
-  static const Uint32 LC_BUILD_VERSION =
-      Uint32(0x32); /* Platform min OS version */
+/// A load command that specifies a fileset entry.
+class MachOFileSetEntryCommand extends MachOLoadCommand {
+  /// The memory address of the dynamically linked shared library.
+  ///
+  /// `uint64_t vmaddr` in the C headers.
+  final int memoryAddress;
 
-  /* Constants for the flags field of the segment_command */
+  /// The file offset of the dynamically linked shared library.
+  ///
+  /// `uint64_t fileoff` in the C headers.
+  final int fileOffset;
 
-  /* the file contents for this segment is for the high part of the VM space,
-	the low part is zero filled (for stacks in core files) */
-  static const Uint32 SG_HIGHVM = Uint32(0x1);
-  /* this segment is the VM that is allocated by a fixed VM library, for overlap
-	checking in the link editor */
-  static const Uint32 SG_FVMLIB = Uint32(0x2);
-  /* this segment has nothing that was relocated in it and nothing relocated to
-	it, that is it maybe safely replaced without relocation */
-  static const Uint32 SG_NORELOC = Uint32(0x4);
-  /* This segment is protected.  If the segment starts at file offset 0, the
-	first page of the segment is not protected.  All other pages of the segment
-	are protected. */
-  static const Uint32 SG_PROTECTED_VERSION_1 = Uint32(0x8);
+  /// The contained entry id.
+  ///
+  /// `lc_str entry_id` in the C headers.
+  final int entryId;
 
-/*
- * The flags field of a section structure is separated into two parts a section
- * type and section attributes.  The section types are mutually exclusive (it
- * can only have one type) but the section attributes are not (it may have more
- * than one attribute).
- */
-  static const Uint32 SECTION_TYPE = Uint32(0x000000ff); /* 256 section types */
-  static const Uint32 SECTION_ATTRIBUTES =
-      Uint32(0xffffff00); /*  24 section attributes */
+  /// Reserved padding.
+  ///
+  /// `uint32_t reserved` in the C headers.
+  final int reserved;
 
-/* Constants for the type of a section */
-  static const Uint32 S_REGULAR = Uint32(0x0); /* regular section */
-  static const Uint32 S_ZEROFILL =
-      Uint32(0x1); /* zero fill on demand section */
-  static const Uint32 S_CSTRING_LITERALS =
-      Uint32(0x2); /* section with only literal C strings*/
-  static const Uint32 S_4BYTE_LITERALS =
-      Uint32(0x3); /* section with only 4 byte literals */
-  static const Uint32 S_8BYTE_LITERALS =
-      Uint32(0x4); /* section with only 8 byte literals */
-  static const Uint32 S_LITERAL_POINTERS =
-      Uint32(0x5); /* section with only pointers to */
-  /*  literals */
-/*
- * For the two types of symbol pointers sections and the symbol stubs section
- * they have indirect symbol table entries.  For each of the entries in the
- * section the indirect symbol table entries, in corresponding order in the
- * indirect symbol table, start at the index stored in the reserved1 field
- * of the section structure.  Since the indirect symbol table entries
- * correspond to the entries in the section the number of indirect symbol table
- * entries is inferred from the size of the section divided by the size of the
- * entries in the section.  For symbol pointers sections the size of the entries
- * in the section is 4 bytes and for symbol stubs sections the byte size of the
- * stubs is stored in the reserved2 field of the section structure.
- */
-  static const Uint32 S_NON_LAZY_SYMBOL_POINTERS =
-      Uint32(0x6); /* section with only non-lazy
-						   symbol pointers */
-  static const Uint32 S_LAZY_SYMBOL_POINTERS =
-      Uint32(0x7); /* section with only lazy symbol
- pointers */
-  static const Uint32 S_SYMBOL_STUBS = Uint32(
-      0x8); /* section with only symbol
- stubs, byte size of stub in
- the reserved2 field */
-  static const Uint32 S_MOD_INIT_FUNC_POINTERS =
-      Uint32(0x9); /* section with only function
- pointers for initialization*/
-  static const Uint32 S_MOD_TERM_FUNC_POINTERS =
-      Uint32(0xa); /* section with only function
- pointers for termination */
-  static const Uint32 S_COALESCED =
-      Uint32(0xb); /* section contains symbols that
- are to be coalesced */
-  static const Uint32 S_GB_ZEROFILL = Uint32(
-      0xc); /* zero fill on demand section
- (that can be larger than 4
- gigabytes) */
-  static const Uint32 S_INTERPOSING = Uint32(
-      0xd); /* section with only pairs of
- function pointers for
- interposing */
-  static const Uint32 S_16BYTE_LITERALS =
-      Uint32(0xe); /* section with only 16 byte
- literals */
-  static const Uint32 S_DTRACE_DOF =
-      Uint32(0xf); /* section contains
- DTrace Object Format */
-  static const Uint32 S_LAZY_DYLIB_SYMBOL_POINTERS = Uint32(
-      0x10); /* section with only lazy
- symbol pointers to lazy
- loaded dylibs */
-  /*
- * Section types to support thread local variables
- */
-  static const Uint32 S_THREAD_LOCAL_REGULAR =
-      Uint32(0x11); /* template of initial
- values for TLVs */
-  static const Uint32 S_THREAD_LOCAL_ZEROFILL =
-      Uint32(0x12); /* template of initial
- values for TLVs */
-  static const Uint32 S_THREAD_LOCAL_VARIABLES =
-      Uint32(0x13); /* TLV descriptors */
-  static const Uint32 S_THREAD_LOCAL_VARIABLE_POINTERS =
-      Uint32(0x14); /* pointers to TLV
- descriptors */
-  static const Uint32 S_THREAD_LOCAL_INIT_FUNCTION_POINTERS =
-      Uint32(0x15); /* functions to call
- to initialize TLV
- values */
+  MachOFileSetEntryCommand(int code, int size, this.memoryAddress,
+      this.fileOffset, this.entryId, this.reserved)
+      : super(code, size);
 
-  /*
- * Constants for the section attributes part of the flags field of a section
- * structure.
- */
-  static const Uint32 SECTION_ATTRIBUTES_USR =
-      Uint32(0xff000000); /* User setable attributes */
-  static const Uint32 S_ATTR_PURE_INSTRUCTIONS =
-      Uint32(0x80000000); /* section contains only true
- machine instructions */
-  static const Uint32 S_ATTR_NO_TOC = Uint32(
-      0x40000000); /* section contains coalesced
- symbols that are not to be
- in a ranlib table of
- contents */
-  static const Uint32 S_ATTR_STRIP_STATIC_SYMS = Uint32(
-      0x20000000); /* ok to strip static symbols
- in this section in files
- with the MH_DYLDLINK flag */
-  static const Uint32 S_ATTR_NO_DEAD_STRIP =
-      Uint32(0x10000000); /* no dead stripping */
-  static const Uint32 S_ATTR_LIVE_SUPPORT =
-      Uint32(0x08000000); /* blocks are live if they
- reference live blocks */
-  static const Uint32 S_ATTR_SELF_MODIFYING_CODE =
-      Uint32(0x04000000); /* Used with i386 code stubs
- written on by dyld */
-  /*
- * If a segment contains any sections marked with S_ATTR_DEBUG then all
- * sections in that segment must have this attribute.  No section other than
- * a section marked with this attribute may reference the contents of this
- * section.  A section with this attribute may contain no symbols and must have
- * a section type S_REGULAR.  The static linker will not copy section contents
- * from sections with this attribute into its output file.  These sections
- * generally contain DWARF debugging info.
- */
-  static const Uint32 S_ATTR_DEBUG = Uint32(0x02000000); /* a debug section */
-  static const Uint32 SECTION_ATTRIBUTES_SYS =
-      Uint32(0x00ffff00); /* system setable attributes */
-  static const Uint32 S_ATTR_SOME_INSTRUCTIONS =
-      Uint32(0x00000400); /* section contains some
- machine instructions */
-  static const Uint32 S_ATTR_EXT_RELOC =
-      Uint32(0x00000200); /* section has external
- relocation entries */
-  static const Uint32 S_ATTR_LOC_RELOC =
-      Uint32(0x00000100); /* section has local
- relocation entries */
+  static MachOFileSetEntryCommand fromStream(
+      int code, int size, MachOReader stream) {
+    final memoryAddress = stream.readUint64();
+    final fileOffset = stream.readUint64();
+    final entryId = stream.readLCString();
+    final reserved = stream.readUint32();
+    return MachOFileSetEntryCommand(
+        code, size, memoryAddress, fileOffset, entryId, reserved);
+  }
 
-  /*
- * The names of segments and sections in them are mostly meaningless to the
- * link-editor.  But there are few things to support traditional UNIX
- * executables that require the link-editor and assembler to use some names
- * agreed upon by convention.
- *
- * The initial protection of the "__TEXT" segment has write protection turned
- * off (not writeable).
- *
- * The link-editor will allocate common symbols at the end of the "__common"
- * section in the "__DATA" segment.  It will create the section and segment
- * if needed.
- */
+  @override
+  MachOFileSetEntryCommand adjust(OffsetsAdjuster adjuster) =>
+      MachOFileSetEntryCommand(code, size, memoryAddress,
+          adjuster.adjust(fileOffset), entryId, reserved);
 
-/* The currently known segment names and the section names in those segments */
+  @override
+  void writeContentsSync(MachOWriter stream) {
+    stream.writeUint64(memoryAddress);
+    stream.writeUint64(fileOffset);
+    stream.writeLCString(entryId);
+    stream.writeUint32(reserved);
+  }
+}
 
-  static final String SEG_PAGEZERO =
-      "__PAGEZERO"; /* the pagezero segment which has no */
-  /* protections and catches NULL */
-  /* references for MH_EXECUTE files */
+/// The headers and load commands of a MachO file. Note that this class does
+/// not contain the contents of the load commands. Instead, those are expected
+/// to be copied over from the original file appropriately.
+class MachOFile {
+  /// The header of the MachO file.
+  final MachOHeader header;
 
-  static final String SEG_TEXT = "__TEXT"; /* the tradition UNIX text segment */
-  static final String SECT_TEXT = "__text"; /* the real text part of the text */
-  /* section no headers, and no padding */
-  static final String SECT_FVMLIB_INIT0 =
-      "__fvmlib_init0"; /* the fvmlib initialization */
-  /*  section */
-  static final String SECT_FVMLIB_INIT1 =
-      "__fvmlib_init1"; /* the section following the */
-  /*  fvmlib initialization */
-  /*  section */
+  /// The load commands of the MachO file, which represent how to read the
+  /// non-header contents of the MachO file.
+  final List<MachOLoadCommand> commands;
 
-  static final String SEG_DATA = "__DATA"; /* the tradition UNIX data segment */
-  static final String SECT_DATA =
-      "__data"; /* the real initialized data section */
-  /* no padding, no bss overlap */
-  static final String SECT_BSS =
-      "__bss"; /* the real uninitialized data section*/
-  /* no padding */
-  static final String SECT_COMMON =
-      "__common"; /* the section common symbols are */
-  /* allocated in by the link editor */
+  /// A cached version of the minimum file offset of any segments or sections,
+  /// which we use to determine post-header padding.
+  final int minimumFileOffset;
 
-  static final String SEG_OBJC = "__OBJC"; /* objective-C runtime segment */
-  static final String SECT_OBJC_SYMBOLS = "__symbol_table"; /* symbol table */
-  static final String SECT_OBJC_MODULES =
-      "__module_info"; /* module information */
-  static final String SECT_OBJC_STRINGS = "__selector_strs"; /* string table */
-  static final String SECT_OBJC_REFS = "__selector_refs"; /* string table */
+  /// Whether or not the parsed MachO file has a code signature.
+  final bool hasCodeSignature;
 
-  static final String SEG_ICON = "__ICON"; /* the icon segment */
-  static final String SECT_ICON_HEADER = "__header"; /* the icon headers */
-  static final String SECT_ICON_TIFF = "__tiff"; /* the icons in tiff format */
+  MachOFile._(this.header, this.commands, this.minimumFileOffset,
+      this.hasCodeSignature);
 
-  static final String SEG_LINKEDIT =
-      "__LINKEDIT"; /* the segment containing all structs */
-  /* created and maintained by the link */
-  /* editor.  Created with -seglinkedit */
-  /* option to ld(1) for MH_EXECUTE and */
-  /* FVMLIB file types only */
+  static MachOFile fromFile(File file) {
+    // Ensure the file is long enough to contain the magic bytes.
+    final int fileLength = file.lengthSync();
+    if (fileLength < 4) {
+      throw FormatException(
+          "File was not formatted properly. Length was too short: $fileLength");
+    }
 
-  static final String SEG_UNIXSTACK =
-      "__UNIXSTACK"; /* the unix stack segment */
+    final stream = file.openSync();
+    final header = MachOHeader.fromStream(stream);
+    if (header == null) {
+      throw FormatException(
+          "Could not parse a MachO header from the file: ${file.path}");
+    }
 
-  static final String SEG_IMPORT =
-      "__IMPORT"; /* the segment for the self (dyld) */
-  /* modifing code stubs that has read, */
-  /* write and execute permissions */
+    final uses64BitPointers = CpuType.cpuTypeUses64BitPointers(header.cpu);
+    final reader = MachOReader(stream, header.endian, uses64BitPointers);
 
-  /*
- * An indirect symbol table entry is simply a 32bit index into the symbol table
- * to the symbol that the pointer or stub is refering to.  Unless it is for a
- * non-lazy symbol pointer section for a defined symbol which strip(1) as
- * removed.  In which case it has the value INDIRECT_SYMBOL_LOCAL.  If the
- * symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that.
- */
-  static const Uint32 INDIRECT_SYMBOL_LOCAL = Uint32(0x80000000);
-  static const Uint32 INDIRECT_SYMBOL_ABS = Uint32(0x40000000);
+    final commands = List<MachOLoadCommand>.generate(
+        header.loadCommandsCount, (_) => MachOLoadCommand.fromStream(reader));
 
-  /*
- * The following are used to encode rebasing information
- */
-  static const Uint32 REBASE_TYPE_POINTER = Uint32(1);
-  static const Uint32 REBASE_TYPE_TEXT_ABSOLUTE32 = Uint32(2);
-  static const Uint32 REBASE_TYPE_TEXT_PCREL32 = Uint32(3);
+    // Set the max header offset to the maximum file size so that when we read
+    // in the header we can correctly set the total header size.
+    final minimumFileOffset = commands.fold<int>((1 << 63) - 1, (i, c) {
+      final minFileOffset = c.minimumFileOffset;
+      return minFileOffset != null ? min(i, minFileOffset) : i;
+    });
+    final hasCodeSignature =
+        commands.any((c) => c.type == LoadCommandType.codeSignature);
 
-  static const Uint32 REBASE_OPCODE_MASK = Uint32(0xF0);
-  static const Uint32 REBASE_IMMEDIATE_MASK = Uint32(0x0F);
-  static const Uint32 REBASE_OPCODE_DONE = Uint32(0x00);
-  static const Uint32 REBASE_OPCODE_SET_TYPE_IMM = Uint32(0x10);
-  static const Uint32 REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = Uint32(0x20);
-  static const Uint32 REBASE_OPCODE_ADD_ADDR_ULEB = Uint32(0x30);
-  static const Uint32 REBASE_OPCODE_ADD_ADDR_IMM_SCALED = Uint32(0x40);
-  static const Uint32 REBASE_OPCODE_DO_REBASE_IMM_TIMES = Uint32(0x50);
-  static const Uint32 REBASE_OPCODE_DO_REBASE_ULEB_TIMES = Uint32(0x60);
-  static const Uint32 REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB = Uint32(0x70);
-  static const Uint32 REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB =
-      Uint32(0x80);
+    return MachOFile._(header, commands, minimumFileOffset, hasCodeSignature);
+  }
 
-/*
- * The following are used to encode binding information
- */
-  static const Uint32 BIND_TYPE_POINTER = Uint32(1);
-  static const Uint32 BIND_TYPE_TEXT_ABSOLUTE32 = Uint32(2);
-  static const Uint32 BIND_TYPE_TEXT_PCREL32 = Uint32(3);
+  /// Returns a new MachOFile that is like the input, but with a new
+  /// segment load command with a single section inserted prior to the
+  /// __LINKEDIT segment load command. Any file offsets in other load commands
+  /// that reference the __LINKEDIT segment are adjusted appropriately.
+  MachOFile insertSegmentLoadCommand(
+      int segmentLength, String segmentName, String sectionName) {
+    final linkedit = linkEditSegment;
+    if (linkedit == null) {
+      throw FormatException("__LINKEDIT segment not found");
+    }
 
-  static const Uint32 BIND_SPECIAL_DYLIB_SELF = Uint32(0);
-  static const Uint32 BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = Uint32(-1);
-  static const Uint32 BIND_SPECIAL_DYLIB_FLAT_LOOKUP = Uint32(-2);
+    // Create the new segment.
+    final int fileOffset = align(linkedit.fileOffset, segmentAlignment);
+    final int fileSize = align(segmentLength, segmentAlignment);
+    final int memoryAddress = linkedit.memoryAddress;
+    final int memorySize = fileSize;
+    final int maxProtection = VirtualMemoryProtection.read.code;
+    final int initialProtection = maxProtection;
 
-  static const Uint32 BIND_SYMBOL_FLAGS_WEAK_IMPORT = Uint32(0x1);
-  static const Uint32 BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION = Uint32(0x8);
+    final int sectionFlags =
+        MachOSection.combineIntoFlags(SectionType.regular, 0);
 
-  static const Uint32 BIND_OPCODE_MASK = Uint32(0xF0);
-  static const Uint32 BIND_IMMEDIATE_MASK = Uint32(0x0F);
-  static const Uint32 BIND_OPCODE_DONE = Uint32(0x00);
-  static const Uint32 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM = Uint32(0x10);
-  static const Uint32 BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB = Uint32(0x20);
-  static const Uint32 BIND_OPCODE_SET_DYLIB_SPECIAL_IMM = Uint32(0x30);
-  static const Uint32 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM = Uint32(0x40);
-  static const Uint32 BIND_OPCODE_SET_TYPE_IMM = Uint32(0x50);
-  static const Uint32 BIND_OPCODE_SET_ADDEND_SLEB = Uint32(0x60);
-  static const Uint32 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = Uint32(0x70);
-  static const Uint32 BIND_OPCODE_ADD_ADDR_ULEB = Uint32(0x80);
-  static const Uint32 BIND_OPCODE_DO_BIND = Uint32(0x90);
-  static const Uint32 BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB = Uint32(0xA0);
-  static const Uint32 BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED = Uint32(0xB0);
-  static const Uint32 BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB =
-      Uint32(0xC0);
+    final loadCommandDefinitionSize = 4 * 2;
+    final sectionDefinitionSize = 16 * 2 + 8 * 2 + 4 * 8;
+    final segmentDefinitionSize = 16 + 8 * 4 + 4 * 4;
+    final commandSize = loadCommandDefinitionSize +
+        segmentDefinitionSize +
+        sectionDefinitionSize;
 
-/*
- * The following are used on the flags byte of a terminal node
- * in the export information.
- */
-  static const Uint32 EXPORT_SYMBOL_FLAGS_KIND_MASK = Uint32(0x03);
-  static const Uint32 EXPORT_SYMBOL_FLAGS_KIND_REGULAR = Uint32(0x00);
-  static const Uint32 EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL = Uint32(0x01);
-  static const Uint32 EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION = Uint32(0x04);
-  static const Uint32 EXPORT_SYMBOL_FLAGS_REEXPORT = Uint32(0x08);
-  static const Uint32 EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER = Uint32(0x10);
+    final section = MachOSection(
+        sectionName,
+        segmentName,
+        memoryAddress,
+        fileSize,
+        fileOffset,
+        segmentAlignmentLog2,
+        0,
+        0,
+        sectionFlags,
+        0,
+        0,
+        0);
 
-  static const Uint32 DICE_KIND_DATA =
-      Uint32(0x0001); /* L$start$data$...  label */
-  static const Uint32 DICE_KIND_JUMP_TABLE8 =
-      Uint32(0x0002); /* L$start$jt8$...   label */
-  static const Uint32 DICE_KIND_JUMP_TABLE16 =
-      Uint32(0x0003); /* L$start$jt16$...  label */
-  static const Uint32 DICE_KIND_JUMP_TABLE32 =
-      Uint32(0x0004); /* L$start$jt32$...  label */
-  static const Uint32 DICE_KIND_ABS_JUMP_TABLE32 =
-      Uint32(0x0005); /* L$start$jta32$... label */
+    final segment = MachOSegmentCommand(
+        LoadCommandType.segment64.code,
+        commandSize,
+        segmentName,
+        memoryAddress,
+        memorySize,
+        fileOffset,
+        fileSize,
+        maxProtection,
+        initialProtection,
+        0,
+        [section]);
 
-/*
- *	Protection values, defined as bits within the vm_prot_t type
- */
+    // Setup the new linkedit command.
+    final shiftedLinkeditMemoryAddress = memoryAddress + segment.memorySize;
+    final shiftedLinkeditFileOffset = fileOffset + segment.fileSize;
+    final shiftedLinkedit = MachOSegmentCommand(
+        linkedit.code,
+        linkedit.size,
+        linkedit.name,
+        shiftedLinkeditMemoryAddress,
+        linkedit.memorySize,
+        shiftedLinkeditFileOffset,
+        linkedit.fileSize,
+        linkedit.maxProtection,
+        linkedit.initialProtection,
+        linkedit.flags,
+        linkedit.sections);
 
-  static const Int32 VM_PROT_NONE = Int32(0x00);
-  static const Int32 VM_PROT_READ = Int32(0x01); /* read permission */
-  static const Int32 VM_PROT_WRITE = Int32(0x02); /* write permission */
-  static const Int32 VM_PROT_EXECUTE = Int32(0x04); /* execute permission */
+    // Now we need to build the new header from these modified pieces.
+    final newHeader = MachOHeader(
+        header.magic,
+        header.cpu,
+        header.machine,
+        header.type,
+        header.loadCommandsCount + 1,
+        header.loadCommandsSize + segment.size,
+        header.flags,
+        header.reserved);
 
-/*
- *	The default protection for newly-created virtual memory
- */
+    final adjuster = OffsetsAdjuster();
+    adjuster.add(
+        linkedit.fileOffset, shiftedLinkeditFileOffset - linkedit.fileOffset);
+    final newCommands = <MachOLoadCommand>[];
+    for (final command in commands) {
+      if (command == linkedit) {
+        // Insert the new segment prior to the __LINKEDIT segment.
+        newCommands.add(segment);
+        // Replace the old __LINKEDIT segment with the new one.
+        newCommands.add(shiftedLinkedit);
+      } else {
+        // Shift the offsets of any other load command that fall within the
+        // __LINKEDIT segment appropriately.
+        newCommands.add(command.adjust(adjuster));
+      }
+    }
 
-  static final Int32 VM_PROT_DEFAULT = VM_PROT_READ | VM_PROT_WRITE;
+    return MachOFile._(
+        newHeader, newCommands, minimumFileOffset, hasCodeSignature);
+  }
 
-/*
- *	The maximum privileges possible, for parameter checking.
- */
+  /// The name of the segment containing all the structs created and maintained
+  /// by the link editor.
+  static const _linkEditSegmentName = "__LINKEDIT";
 
-  static final Int32 VM_PROT_ALL =
-      VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
+  MachOSegmentCommand? get linkEditSegment {
+    final linkEditIndex = commands.indexWhere(
+        (c) => c is MachOSegmentCommand && c.name == _linkEditSegmentName);
+    if (linkEditIndex < 0) {
+      return null;
+    }
 
-/*
- *	An invalid protection value.
- *	Used only by memory_object_lock_request to indicate no change
- *	to page locks.  Using -1 here is a bad idea because it
- *	looks like VM_PROT_ALL and then some.
- */
+    // __LINKEDIT  should be the last segment load command.
+    assert(
+        !commands.skip(linkEditIndex + 1).any((c) => c is MachOSegmentCommand));
 
-  static const Int32 VM_PROT_NO_CHANGE = Int32(0x08);
+    return commands[linkEditIndex] as MachOSegmentCommand;
+  }
 
-/*
- *      When a caller finds that he cannot obtain write permission on a
- *      mapped entry, the following flag can be used.  The entry will
- *      be made "needs copy" effectively copying the object (using COW),
- *      and write permission will be added to the maximum protections
- *      for the associated entry.
- */
+  MachOSegmentCommand? get snapshotSegment {
+    final snapshotIndex = commands.indexWhere(
+        (c) => c is MachOSegmentCommand && c.name == snapshotSegmentName);
+    if (snapshotIndex < 0) {
+      return null;
+    }
 
-  static const Int32 VM_PROT_COPY = Int32(0x10);
+    return commands[snapshotIndex] as MachOSegmentCommand;
+  }
 
-/*
- *	Another invalid protection value.
- *	Used only by memory_object_data_request upon an object
- *	which has specified a copy_call copy strategy. It is used
- *	when the kernel wants a page belonging to a copy of the
- *	object, and is only asking the object as a result of
- *	following a shadow chain. This solves the race between pages
- *	being pushed up by the memory manager and the kernel
- *	walking down the shadow chain.
- */
+  /// Writes the MachO file to the given [RandomAccessFile] stream.
+  void writeSync(RandomAccessFile stream) {
+    header.writeSync(stream);
 
-  static const Int32 VM_PROT_WANTS_COPY = Int32(0x10);
+    final uses64BitPointers = CpuType.cpuTypeUses64BitPointers(header.cpu);
+    final writer = MachOWriter(stream, header.endian, uses64BitPointers);
+    // Write all of the commands.
+    for (var command in commands) {
+      command.writeSync(writer);
+    }
+
+    // Pad the header according to the offset.
+    final int paddingAmount = minimumFileOffset - stream.positionSync();
+    if (paddingAmount > 0) {
+      stream.writeFromSync(List.filled(paddingAmount, 0));
+    }
+  }
 }
diff --git a/pkg/dart2native/lib/macho_parser.dart b/pkg/dart2native/lib/macho_parser.dart
deleted file mode 100644
index 99dce1a..0000000
--- a/pkg/dart2native/lib/macho_parser.dart
+++ /dev/null
@@ -1,376 +0,0 @@
-// Copyright (c) 2022, 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:io';
-import 'dart:math';
-import 'dart:typed_data';
-
-import './macho.dart';
-
-extension ByteReader on RandomAccessFile {
-  Uint32 readUint32() {
-    Uint8List rawBytes = readSync(4);
-    var byteView = ByteData.view(rawBytes.buffer);
-    return Uint32(byteView.getUint32(0, Endian.little));
-  }
-
-  Uint64 readUint64() {
-    Uint8List rawBytes = readSync(8);
-    var byteView = ByteData.view(rawBytes.buffer);
-    return Uint64(byteView.getUint64(0, Endian.little));
-  }
-
-  Int32 readInt32() {
-    Uint8List rawBytes = readSync(4);
-    var byteView = ByteData.view(rawBytes.buffer);
-    return Int32(byteView.getInt32(0, Endian.little));
-  }
-}
-
-class MachOFile {
-  IMachOHeader? header;
-  // The headerMaxOffset is set during parsing based on the maximum offset for
-  // segment offsets. Assuming the header start at byte 0 (that seems to always
-  // be the case), this number represents the total size of the header, which
-  // often includes a significant amount of zero-padding.
-  int headerMaxOffset = 0;
-  // We keep track on whether a code signature was seen so we can recreate it
-  // in the case that the binary has a CD hash that nededs updating.
-  bool hasCodeSignature = false;
-
-  // This wil contain all of the "load commands" in this MachO file. A load
-  // command is really a typed schema that indicates various parts of the MachO
-  // file (e.g. where to find the TEXT and DATA sections).
-  List<IMachOLoadCommand> commands =
-      List<IMachOLoadCommand>.empty(growable: true);
-
-  MachOFile();
-
-  // Returns the number of bytes read from the file.
-  Future<int> loadFromFile(File file) async {
-    // Ensure the file is long enough to contain the magic bytes.
-    final int fileLength = await file.length();
-    if (fileLength < 4) {
-      throw FormatException(
-          "File was not formatted properly. Length was too short: $fileLength");
-    }
-
-    // Read the first 4 bytes to see what type of MachO file this is.
-    var stream = await file.open();
-    var magic = stream.readUint32();
-
-    bool is64Bit = magic == MachOConstants.MH_MAGIC_64 ||
-        magic == MachOConstants.MH_CIGAM_64;
-
-    await stream.setPosition(0);
-
-    // Set the max header offset to the maximum file size so that when we read
-    // in the header we can correctly set the total header size.
-    headerMaxOffset = (1 << 63) - 1;
-
-    header = await _headerFromStream(stream, is64Bit);
-    if (header == null) {
-      throw FormatException(
-          "Could not parse a MachO header from the file: ${file.path}");
-    } else {
-      commands = await _commandsFromStream(stream, header!);
-    }
-
-    return stream.positionSync();
-  }
-
-  Future<MachOSymtabCommand> parseSymtabFromStream(
-      final Uint32 cmdsize, RandomAccessFile stream) async {
-    final symoff = stream.readUint32();
-    final nsyms = stream.readUint32();
-    final stroff = stream.readUint32();
-    final strsize = stream.readUint32();
-
-    return MachOSymtabCommand(cmdsize, symoff, nsyms, stroff, strsize);
-  }
-
-  Future<MachODysymtabCommand> parseDysymtabFromStream(
-      final Uint32 cmdsize, RandomAccessFile stream) async {
-    final ilocalsym = stream.readUint32();
-    final nlocalsym = stream.readUint32();
-    final iextdefsym = stream.readUint32();
-    final nextdefsym = stream.readUint32();
-    final iundefsym = stream.readUint32();
-    final nundefsym = stream.readUint32();
-    final tocoff = stream.readUint32();
-    final ntoc = stream.readUint32();
-    final modtaboff = stream.readUint32();
-    final nmodtab = stream.readUint32();
-    final extrefsymoff = stream.readUint32();
-    final nextrefsyms = stream.readUint32();
-    final indirectsymoff = stream.readUint32();
-    final nindirectsyms = stream.readUint32();
-    final extreloff = stream.readUint32();
-    final nextrel = stream.readUint32();
-    final locreloff = stream.readUint32();
-    final nlocrel = stream.readUint32();
-
-    return MachODysymtabCommand(
-        cmdsize,
-        ilocalsym,
-        nlocalsym,
-        iextdefsym,
-        nextdefsym,
-        iundefsym,
-        nundefsym,
-        tocoff,
-        ntoc,
-        modtaboff,
-        nmodtab,
-        extrefsymoff,
-        nextrefsyms,
-        indirectsymoff,
-        nindirectsyms,
-        extreloff,
-        nextrel,
-        locreloff,
-        nlocrel);
-  }
-
-  Future<MachOLinkeditDataCommand> parseLinkeditDataCommand(
-      final Uint32 cmd, final Uint32 cmdsize, RandomAccessFile stream) async {
-    final dataoff = stream.readUint32();
-    final datasize = stream.readUint32();
-
-    return MachOLinkeditDataCommand(
-      cmd,
-      cmdsize,
-      dataoff,
-      datasize,
-    );
-  }
-
-  Future<MachODyldInfoCommand> parseDyldInfoFromStream(
-      final Uint32 cmd, final Uint32 cmdsize, RandomAccessFile stream) async {
-    // Note that we're relying on the fact that the mirror returns the list of
-    // fields in the same order they're defined ni the class definition.
-
-    final rebaseOff = stream.readUint32();
-    final rebaseSize = stream.readUint32();
-    final bindOff = stream.readUint32();
-    final bindSize = stream.readUint32();
-    final weakBindOff = stream.readUint32();
-    final weakBindSize = stream.readUint32();
-    final lazyBindOff = stream.readUint32();
-    final lazyBindSize = stream.readUint32();
-    final exportOff = stream.readUint32();
-    final exportSize = stream.readUint32();
-
-    return MachODyldInfoCommand(
-        cmd,
-        cmdsize,
-        rebaseOff,
-        rebaseSize,
-        bindOff,
-        bindSize,
-        weakBindOff,
-        weakBindSize,
-        lazyBindOff,
-        lazyBindSize,
-        exportOff,
-        exportSize);
-  }
-
-  Future<MachOSegmentCommand64> parseSegmentCommand64FromStream(
-      final Uint32 cmdsize, RandomAccessFile stream) async {
-    final Uint8List segname = await stream.read(16);
-    final vmaddr = stream.readUint64();
-    final vmsize = stream.readUint64();
-    final fileoff = stream.readUint64();
-    final filesize = stream.readUint64();
-    final maxprot = stream.readInt32();
-    final initprot = stream.readInt32();
-    final nsects = stream.readUint32();
-    final flags = stream.readUint32();
-
-    if (nsects.asInt() == 0 && filesize.asInt() != 0) {
-      headerMaxOffset = min(headerMaxOffset, fileoff.asInt());
-    }
-
-    final sections = List.filled(nsects.asInt(), 0).map((_) {
-      final Uint8List sectname = stream.readSync(16);
-      final Uint8List segname = stream.readSync(16);
-      final addr = stream.readUint64();
-      final size = stream.readUint64();
-      final offset = stream.readUint32();
-      final align = stream.readUint32();
-      final reloff = stream.readUint32();
-      final nreloc = stream.readUint32();
-      final flags = stream.readUint32();
-      final reserved1 = stream.readUint32();
-      final reserved2 = stream.readUint32();
-      final reserved3 = stream.readUint32();
-
-      final notZerofill =
-          (flags & MachOConstants.S_ZEROFILL) != MachOConstants.S_ZEROFILL;
-      if (offset > 0 && size > 0 && notZerofill) {
-        headerMaxOffset = min(headerMaxOffset, offset.asInt());
-      }
-
-      return MachOSection64(sectname, segname, addr, size, offset, align,
-          reloff, nreloc, flags, reserved1, reserved2, reserved3);
-    }).toList();
-
-    return MachOSegmentCommand64(cmdsize, segname, vmaddr, vmsize, fileoff,
-        filesize, maxprot, initprot, nsects, flags, sections);
-  }
-
-  Future<IMachOHeader> _headerFromStream(
-      RandomAccessFile stream, bool is64Bit) async {
-    final magic = stream.readUint32();
-    final cputype = stream.readUint32();
-    final cpusubtype = stream.readUint32();
-    final filetype = stream.readUint32();
-    final ncmds = stream.readUint32();
-    final sizeofcmds = stream.readUint32();
-    final flags = stream.readUint32();
-
-    if (is64Bit) {
-      final reserved = stream.readUint32();
-      return MachOHeader(magic, cputype, cpusubtype, filetype, ncmds,
-          sizeofcmds, flags, reserved);
-    } else {
-      return MachOHeader32(
-          magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags);
-    }
-  }
-
-  void writeLoadCommandToStream(
-      IMachOLoadCommand command, RandomAccessFile stream) {
-    command.writeSync(stream);
-  }
-
-  void writeSync(RandomAccessFile stream) {
-    // Write the header.
-    stream.writeUint32(header!.magic);
-    stream.writeUint32(header!.cputype);
-    stream.writeUint32(header!.cpusubtype);
-    stream.writeUint32(header!.filetype);
-    stream.writeUint32(header!.ncmds);
-    stream.writeUint32(header!.sizeofcmds);
-    stream.writeUint32(header!.flags);
-
-    if (header is MachOHeader) {
-      stream.writeUint32(header!.reserved);
-    }
-
-    // Write all of the commands.
-    for (var command in commands) {
-      writeLoadCommandToStream(command, stream);
-    }
-
-    // Pad the header according to the offset.
-    final int paddingAmount = headerMaxOffset - stream.positionSync();
-    if (paddingAmount > 0) {
-      stream.writeFromSync(List.filled(paddingAmount, 0));
-    }
-  }
-
-  Future<List<IMachOLoadCommand>> _commandsFromStream(
-      RandomAccessFile stream, IMachOHeader header) async {
-    final loadCommands = List<MachOLoadCommand>.empty(growable: true);
-    for (int i = 0; i < header.ncmds.asInt(); i++) {
-      final cmd = stream.readUint32();
-      final cmdsize = stream.readUint32();
-
-      // We need to read cmdsize bytes to get to the next command definition,
-      // but the cmdsize does includes the 2 bytes we just read (cmd +
-      // cmdsize) so we need to subtract those.
-      await stream
-          .setPosition((await stream.position()) + cmdsize.asInt() - 2 * 4);
-
-      loadCommands.add(MachOLoadCommand(cmd, cmdsize));
-    }
-
-    // Un-read all the bytes we just read.
-    var loadCommandsOffset = loadCommands
-        .map((command) => command.cmdsize)
-        .reduce((value, element) => value + element);
-    await stream
-        .setPosition((await stream.position()) - loadCommandsOffset.asInt());
-
-    final commands = List<IMachOLoadCommand>.empty(growable: true);
-    for (int i = 0; i < header.ncmds.asInt(); i++) {
-      final cmd = stream.readUint32();
-      final cmdsize = stream.readUint32();
-
-      // TODO(sarietta): Handle all MachO load command types. For now, since
-      // this implementation is exclusively being used to handle generating
-      // MacOS-compatible MachO executables for compiled dart scripts, only the
-      // load commands that are currently implemented are strictly necessary. It
-      // may be useful to handle all cases and pull this functionality out to a
-      // separate MachO library.
-      if (cmd == MachOConstants.LC_SEGMENT_64) {
-        commands.add(await parseSegmentCommand64FromStream(cmdsize, stream));
-      } else if (cmd == MachOConstants.LC_DYLD_INFO_ONLY ||
-          cmd == MachOConstants.LC_DYLD_INFO) {
-        commands.add(await parseDyldInfoFromStream(cmd, cmdsize, stream));
-      } else if (cmd == MachOConstants.LC_SYMTAB) {
-        commands.add(await parseSymtabFromStream(cmdsize, stream));
-      } else if (cmd == MachOConstants.LC_DYSYMTAB) {
-        commands.add(await parseDysymtabFromStream(cmdsize, stream));
-      } else if (cmd == MachOConstants.LC_CODE_SIGNATURE ||
-          cmd == MachOConstants.LC_SEGMENT_SPLIT_INFO ||
-          cmd == MachOConstants.LC_FUNCTION_STARTS ||
-          cmd == MachOConstants.LC_DATA_IN_CODE ||
-          cmd == MachOConstants.LC_DYLIB_CODE_SIGN_DRS) {
-        if (cmd == MachOConstants.LC_CODE_SIGNATURE) {
-          hasCodeSignature = true;
-        }
-        commands.add(await parseLinkeditDataCommand(cmd, cmdsize, stream));
-      } else if (cmd == MachOConstants.LC_SEGMENT ||
-          cmd == MachOConstants.LC_SYMSEG ||
-          cmd == MachOConstants.LC_THREAD ||
-          cmd == MachOConstants.LC_UNIXTHREAD ||
-          cmd == MachOConstants.LC_LOADFVMLIB ||
-          cmd == MachOConstants.LC_IDFVMLIB ||
-          cmd == MachOConstants.LC_IDENT ||
-          cmd == MachOConstants.LC_FVMFILE ||
-          cmd == MachOConstants.LC_PREPAGE ||
-          cmd == MachOConstants.LC_LOAD_DYLIB ||
-          cmd == MachOConstants.LC_ID_DYLIB ||
-          cmd == MachOConstants.LC_LOAD_DYLINKER ||
-          cmd == MachOConstants.LC_ID_DYLINKER ||
-          cmd == MachOConstants.LC_PREBOUND_DYLIB ||
-          cmd == MachOConstants.LC_ROUTINES ||
-          cmd == MachOConstants.LC_SUB_FRAMEWORK ||
-          cmd == MachOConstants.LC_SUB_UMBRELLA ||
-          cmd == MachOConstants.LC_SUB_CLIENT ||
-          cmd == MachOConstants.LC_SUB_LIBRARY ||
-          cmd == MachOConstants.LC_TWOLEVEL_HINTS ||
-          cmd == MachOConstants.LC_PREBIND_CKSUM ||
-          cmd == MachOConstants.LC_LOAD_WEAK_DYLIB ||
-          cmd == MachOConstants.LC_ROUTINES_64 ||
-          cmd == MachOConstants.LC_UUID ||
-          cmd == MachOConstants.LC_RPATH ||
-          cmd == MachOConstants.LC_REEXPORT_DYLIB ||
-          cmd == MachOConstants.LC_LAZY_LOAD_DYLIB ||
-          cmd == MachOConstants.LC_ENCRYPTION_INFO ||
-          cmd == MachOConstants.LC_LOAD_UPWARD_DYLIB ||
-          cmd == MachOConstants.LC_VERSION_MIN_MACOSX ||
-          cmd == MachOConstants.LC_VERSION_MIN_IPHONEOS ||
-          cmd == MachOConstants.LC_DYLD_ENVIRONMENT ||
-          cmd == MachOConstants.LC_MAIN ||
-          cmd == MachOConstants.LC_SOURCE_VERSION ||
-          cmd == MachOConstants.LC_BUILD_VERSION) {
-        // cmdsize includes the size of the contents + cmd + cmdsize
-        final contents = await stream.read(cmdsize.asInt() - 2 * 4);
-        commands.add(MachOGenericLoadCommand(cmd, cmdsize, contents));
-      } else {
-        // cmdsize includes the size of the contents + cmd + cmdsize
-        final contents = await stream.read(cmdsize.asInt() - 2 * 4);
-        commands.add(MachOGenericLoadCommand(cmd, cmdsize, contents));
-        final cmdString = "0x${cmd.asInt().toRadixString(16)}";
-        print("Found unknown MachO load command: $cmdString");
-      }
-    }
-
-    return commands;
-  }
-}
diff --git a/pkg/dart2native/lib/macho_utils.dart b/pkg/dart2native/lib/macho_utils.dart
new file mode 100644
index 0000000..b9ff8360
--- /dev/null
+++ b/pkg/dart2native/lib/macho_utils.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2022, 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 'dart:io';
+import 'dart:typed_data';
+
+// Note that these two values MUST match the ones in
+// runtime/bin/snapshot_utils.cc, which looks specifically for the snapshot in
+// this segment and section.
+const String snapshotSegmentName = "__CUSTOM";
+const String snapshotSectionName = "__dart_app_snap";
+
+/// The page size for aligning segments in MachO files. X64 MacOS uses 4k pages,
+/// and ARM64 MacOS uses 16k pages, so we use 16k here.
+const int segmentAlignmentLog2 = 14;
+const int segmentAlignment = 1 << segmentAlignmentLog2;
+
+/// Pads the given size so that it is a multiple of the given alignment.
+int align(int size, int alignment) {
+  final int unpadded = size % alignment;
+  return size + (unpadded != 0 ? alignment - unpadded : 0);
+}
+
+/// A reader utility class that wraps a stream to include endian information
+/// and whether or not the architecture for the MachO file uses 64-bit pointers.
+class MachOReader {
+  final RandomAccessFile _stream;
+  final Endian _endian;
+
+  /// Used to determine whether to read 4 or 8 bytes for the `lc_str` union
+  /// type, which depends on the `__LP64__` define (e.g., is the target
+  /// architecture using 64-bit pointers). May be null if no `lc_str` values
+  /// will be read by this reader.
+  final bool? _arch64BitPointers;
+
+  MachOReader(this._stream, this._endian, [this._arch64BitPointers]);
+
+  /// Reads a 16-bit unsigned integer from the contained stream.
+  int readUint16() =>
+      ByteData.sublistView(_stream.readSync(2)).getUint16(0, _endian);
+
+  /// Reads a 32-bit unsigned integer from the contained stream.
+  int readUint32() =>
+      ByteData.sublistView(_stream.readSync(4)).getUint32(0, _endian);
+
+  /// Reads a 64-bit unsigned integer from the contained stream.
+  int readUint64() =>
+      ByteData.sublistView(_stream.readSync(8)).getUint64(0, _endian);
+
+  /// Reads a 32-bit signed integer from the contained stream.
+  int readInt32() =>
+      ByteData.sublistView(_stream.readSync(4)).getInt32(0, _endian);
+
+  /// Reads an unsigned integer of the given word size from the contained
+  /// stream. Throws an [ArgumentError] for if [wordSize] is not 4 or 8.
+  int readUword(int wordSize) {
+    switch (wordSize) {
+      case 4:
+        return readUint32();
+      case 8:
+        return readUint64();
+      default:
+        throw ArgumentError('Unexpected word size: $wordSize', 'wordSize');
+    }
+  }
+
+  /// Reads a fixed length string from the contained stream. The string may be
+  /// null terminated, in which case the returned string may contain less
+  /// code points than the provided size.
+  String readFixedLengthNullTerminatedString(int size) {
+    final buffer = _stream.readSync(size);
+    return String.fromCharCodes(buffer.takeWhile((value) => value != 0));
+  }
+
+  /// Reads an `lc_str` value from the contained stream. For 32-bit
+  /// architectures, or 64-bit architectures using 32-bit pointers, this is
+  /// 32 bits. On 64-bit architectures using 64-bit pointers, this is 64 bits.
+  int readLCString() => _arch64BitPointers! ? readUint64() : readUint32();
+
+  /// Reads [size] bytes from the contained stream.
+  Uint8List readBytes(int size) => _stream.readSync(size);
+}
+
+/// A writer utility class that wraps a stream to include endian information
+/// and whether or not the architecture for the MachO file uses 64-bit pointers.
+class MachOWriter {
+  final RandomAccessFile _stream;
+  final Endian _endian;
+
+  /// Used to determine whether to write 4 or 8 bytes for the `lc_str` union
+  /// type, which depends on the `__LP64__` define (e.g., is the target
+  /// architecture using 64-bit pointers). May be null if no `lc_str` values
+  /// will be written by this reader.
+  final bool? _arch64BitPointers;
+
+  MachOWriter(this._stream, this._endian, [this._arch64BitPointers]);
+
+  /// Writes a 16-bit unsigned integer to the contained stream. Throws
+  /// a [FormatException] if the value is negative or does not fit in 16 bits.
+  void writeUint16(int value) {
+    if (value < 0) {
+      throw FormatException("Attempted to write a negative value $value");
+    }
+    if ((value >> 16) != 0) {
+      throw FormatException("Attempted to write an unsigned value that doesn't "
+          "fit in 16 bits: $value");
+    }
+    final buffer = ByteData(2)..setUint16(0, value, _endian);
+    _stream.writeFromSync(Uint8List.sublistView(buffer));
+  }
+
+  /// Writes a 32-bit unsigned integer to the contained stream. Throws
+  /// a [FormatException] if the value is negative or does not fit in 32 bits.
+  void writeUint32(int value) {
+    if (value < 0) {
+      throw FormatException("Attempted to write a negative value $value");
+    }
+    if ((value >> 32) != 0) {
+      throw FormatException("Attempted to write an unsigned value that doesn't "
+          "fit in 32 bits: $value");
+    }
+    final buffer = ByteData(4)..setUint32(0, value, _endian);
+    _stream.writeFromSync(Uint8List.sublistView(buffer));
+  }
+
+  /// Writes a 64-bit unsigned integer to the contained stream.
+  void writeUint64(int value) {
+    final buffer = ByteData(8)..setUint64(0, value, _endian);
+    _stream.writeFromSync(Uint8List.sublistView(buffer));
+  }
+
+  /// Writes a 32-bit unsigned integer to the contained stream. Throws
+  /// a [FormatException] if the signed value does not fit in 32 bits.
+  void writeInt32(int value) {
+    if (((value < 0 ? ~value : value) >> 31) != 0) {
+      throw FormatException("Attempted to write a signed value that doesn't "
+          "fit in 32 bits: $value");
+    }
+    final buffer = ByteData(4)..setInt32(0, value, _endian);
+    _stream.writeFromSync(Uint8List.sublistView(buffer));
+  }
+
+  /// Writes an unsigned integer with a given word size to the contained
+  /// stream. Throws an [ArgumentError] for if [wordSize] is not 4 or 8.
+  void writeUword(int value, int wordSize) {
+    switch (wordSize) {
+      case 4:
+        return writeUint32(value);
+      case 8:
+        return writeUint64(value);
+      default:
+        throw ArgumentError('Unexpected word size: $wordSize', 'wordSize');
+    }
+  }
+
+  /// Writes the given string as an ASCII-encoded null terminated string
+  /// with a given fixed length. Throws a format exception if the ASCII
+  /// character length of the string is longer than the given length.
+  /// If the ASCII character length of the string is the same as the given
+  /// length, there will be no null terminator in the written data.
+  void writeFixedLengthNullTerminatedString(String s, int length) {
+    final Uint8List buffer = Uint8List(length);
+    final encoded = ascii.encode(s);
+    if (encoded.length > length) {
+      throw FormatException('Attempted to write a string longer than $length '
+          'characters: "$s"');
+    }
+    buffer.setRange(0, encoded.length, encoded);
+    _stream.writeFromSync(buffer);
+  }
+
+  /// Writes an `lc_str` value to the contained stream. For 32-bit
+  /// architectures, or 64-bit architectures using 32-bit pointers, this is
+  /// 32 bits. On 64-bit architectures using 64-bit pointers, this is 64 bits.
+  void writeLCString(int value) =>
+      _arch64BitPointers! ? writeUint64(value) : writeUint32(value);
+
+  /// Writes the given bytes to the contained stream.
+  void writeBytes(Uint8List bytes) => _stream.writeFromSync(bytes);
+}
diff --git a/pkg/dart2native/pubspec.yaml b/pkg/dart2native/pubspec.yaml
index 80bf3ee..309ca5a 100644
--- a/pkg/dart2native/pubspec.yaml
+++ b/pkg/dart2native/pubspec.yaml
@@ -3,7 +3,7 @@
 publish_to: none
 
 environment:
-  sdk: '>=2.12.0 <3.0.0'
+  sdk: '>=2.17.0 <3.0.0'
 
 # Add the bin/dart2native.dart script to the scripts pub installs.
 executables:
diff --git a/pkg/dart2wasm/bin/dart2wasm.dart b/pkg/dart2wasm/bin/dart2wasm.dart
index ce2dcc9..13b87cc 100644
--- a/pkg/dart2wasm/bin/dart2wasm.dart
+++ b/pkg/dart2wasm/bin/dart2wasm.dart
@@ -25,9 +25,6 @@
       defaultsTo: _d.translatorOptions.importSharedMemory),
   Flag("inlining", (o, value) => o.translatorOptions.inlining = value,
       defaultsTo: _d.translatorOptions.inlining),
-  Flag(
-      "lazy-constants", (o, value) => o.translatorOptions.lazyConstants = value,
-      defaultsTo: _d.translatorOptions.lazyConstants),
   Flag("name-section", (o, value) => o.translatorOptions.nameSection = value,
       defaultsTo: _d.translatorOptions.nameSection),
   Flag("polymorphic-specialization",
diff --git a/pkg/dart2wasm/bin/run_wasm.js b/pkg/dart2wasm/bin/run_wasm.js
index 6592a43..9edf69f 100644
--- a/pkg/dart2wasm/bin/run_wasm.js
+++ b/pkg/dart2wasm/bin/run_wasm.js
@@ -150,8 +150,13 @@
     },
     stringFromDartString: stringFromDartString,
     stringToDartString: stringToDartString,
-    wrapDartFunction: function(dartFunction, exportFunctionName) {
+    wrapDartFunction: function(dartFunction, exportFunctionName, argCount) {
         var wrapped = function (...args) {
+            // Pad `undefined` for optional arguments that aren't passed so that
+            // the trampoline can replace these values with defaults.
+            while (args.length < argCount) {
+                args.push(undefined);
+            }
             return dartInstance.exports[`${exportFunctionName}`](
                 dartFunction, ...args.map(dartInstance.exports.$dartifyRaw));
         }
@@ -354,6 +359,18 @@
         }
         return stringToDartString(jsString);
     },
+    areEqualInJS: function(l, r) {
+        return l === r;
+    },
+    promiseThen: function(promise, successFunc, failureFunc) {
+        promise.then(successFunc, failureFunc);
+    },
+    performanceNow: function() {
+        return performance.now();
+    },
+    instanceofTrampoline: function(object, type) {
+        return object instanceof type;
+    },
 };
 
 function instantiate(filename, imports) {
diff --git a/pkg/dart2wasm/dart2wasm.md b/pkg/dart2wasm/dart2wasm.md
index 0f9d65f..54e0a18 100644
--- a/pkg/dart2wasm/dart2wasm.md
+++ b/pkg/dart2wasm/dart2wasm.md
@@ -15,7 +15,6 @@
 | `--`[`no-`]`export-all`                 | no      | Export all functions; otherwise, just export `main`.
 | `--`[`no-`]`import-shared-memory`       | no      | Import a shared memory buffer. If this is on, `--shared-memory-max-pages` must also be specified.
 | `--`[`no-`]`inlining`                   | no      | Inline small functions.
-| `--`[`no-`]`lazy-constants`             | no      | Instantiate constants lazily.
 | `--`[`no-`]`name-section`               | yes     | Emit Name Section with function names.
 | `--`[`no-`]`polymorphic-specialization` | no      | Do virtual calls by switching on the class ID instead of using `call_indirect`.
 | `--`[`no-`]`print-kernel`               | no      | Print IR for each function before compiling it.
@@ -60,5 +59,5 @@
 In the signatures of imported and exported functions, use the following types:
 
 - For numbers, use `double`.
-- For Dart objects, use the corresponding Dart type. The fields of the underlying representation can be accessed on the JS side as `.$field0`, `.$field1` etc., but there is currently no defined way of finding the field index of a particular Dart field, so this mechanism is mainly useful for special objects with known layout.
-- For JS objects, use the `WasmAnyRef` type (or `WasmAnyRef?` as applicable) from the `dart:wasm` package. These can be passed around and stored as opaque values on the Dart side.
+- For JS objects, use the `WasmExternRef?` type from the `dart:wasm` package, which translates to the Wasm `externref` type. These can be passed around and stored as opaque values on the Dart side.
+- For Dart objects, use the corresponding Dart type. This will be emitted as `externref` and automatically converted to and from the Dart type at the boundary.
diff --git a/pkg/dart2wasm/lib/class_info.dart b/pkg/dart2wasm/lib/class_info.dart
index 204ab35..7cf72dd 100644
--- a/pkg/dart2wasm/lib/class_info.dart
+++ b/pkg/dart2wasm/lib/class_info.dart
@@ -24,7 +24,8 @@
   static const hashBaseIndex = 2;
   static const hashBaseData = 4;
   static const closureContext = 2;
-  static const closureFunction = 3;
+  static const closureVtable = 3;
+  static const closureRuntimeType = 4;
   static const typeIsNullable = 2;
   static const interfaceTypeTypeArguments = 4;
   static const functionTypeNamedParameters = 6;
diff --git a/pkg/dart2wasm/lib/closures.dart b/pkg/dart2wasm/lib/closures.dart
index 882182e..30868e0 100644
--- a/pkg/dart2wasm/lib/closures.dart
+++ b/pkg/dart2wasm/lib/closures.dart
@@ -2,13 +2,396 @@
 // 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 'dart:math' show min;
+
 import 'package:dart2wasm/code_generator.dart';
 import 'package:dart2wasm/translator.dart';
 
 import 'package:kernel/ast.dart';
 
+import 'package:vm/metadata/procedure_attributes.dart';
+import 'package:vm/transformations/type_flow/utils.dart' show UnionFind;
+
 import 'package:wasm_builder/wasm_builder.dart' as w;
 
+/// Describes the implementation of a concrete closure, including its vtable
+/// contents.
+class ClosureImplementation {
+  /// The representation of the closure.
+  final ClosureRepresentation representation;
+
+  /// The functions pointed to by the function entries in the vtable.
+  final List<w.DefinedFunction> functions;
+
+  /// The constant global variable pointing to the vtable.
+  final w.Global vtable;
+
+  ClosureImplementation(this.representation, this.functions, this.vtable);
+}
+
+/// Describes the representation of closures for a particular function
+/// signature, including the layout of their vtable.
+///
+/// Each vtable layout will have an entry for each number of positional
+/// arguments from 0 up to the maximum number for the signature, followed by
+/// an entry for each (non-empty) combination of argument names that closures
+/// with this layout can be called with.
+class ClosureRepresentation {
+  /// The struct field index in the vtable struct at which the function
+  /// entries start.
+  final int vtableBaseIndex;
+
+  /// The Wasm struct type for the vtable.
+  final w.StructType vtableStruct;
+
+  /// The Wasm struct type for the closure object.
+  final w.StructType closureStruct;
+
+  final Map<NameCombination, int>? _indexOfCombination;
+
+  ClosureRepresentation(this.vtableBaseIndex, this.vtableStruct,
+      this.closureStruct, this._indexOfCombination);
+
+  /// The field index in the vtable struct for the function entry to use when
+  /// calling the closure with the given number of positional arguments and the
+  /// given set of named arguments.
+  int fieldIndexForSignature(int posArgCount, List<String> argNames) {
+    if (argNames.isEmpty) {
+      return vtableBaseIndex + posArgCount;
+    } else {
+      return vtableBaseIndex +
+          (posArgCount + 1) +
+          _indexOfCombination![NameCombination(argNames)]!;
+    }
+  }
+
+  /// The combinations of parameter names for which there are entries in the
+  /// vtable of this closure, not including the empty combination, if
+  /// applicable.
+  Iterable<NameCombination> get nameCombinations =>
+      _indexOfCombination?.keys ?? const [];
+}
+
+/// A combination of argument names for a call of a closure. The names within a
+/// name combination are sorted alphabetically. Name combinations can be sorted
+/// lexicographically according to their lists of names, corresponding to the
+/// order in which entry points taking named arguments will appear in vtables.
+class NameCombination implements Comparable<NameCombination> {
+  List<String> names;
+
+  NameCombination(this.names);
+
+  @override
+  int compareTo(NameCombination other) {
+    int common = min(names.length, other.names.length);
+    for (int i = 0; i < common; i++) {
+      int comp = names[i].compareTo(other.names[i]);
+      if (comp != 0) return comp;
+    }
+    return names.length - other.names.length;
+  }
+
+  @override
+  String toString() => names.toString();
+}
+
+/// Visitor to collect all closures and closure calls in the program to
+/// compute the vtable layouts necessary to cover all signatures that occur.
+///
+/// For each combination of type parameter count and positional parameter count,
+/// the names of named parameters occurring together with that combination are
+/// partitioned into clusters such that any combination of names that occurs
+/// together is contained within a single cluster.
+///
+/// Each cluster gets a corresponding vtable layout with en extry point for each
+/// combination of names from the cluster that occurs in a call in the program.
+class ClosureLayouter extends RecursiveVisitor {
+  final Translator translator;
+  final Map<TreeNode, ProcedureAttributesMetadata> procedureAttributeMetadata;
+
+  List<List<ClosureRepresentationsForParameterCount>> representations = [];
+
+  Set<Constant> visitedConstants = Set.identity();
+
+  // Base struct for vtables.
+  late final w.StructType vtableBaseStruct = m.addStructType("#VtableBase");
+
+  // Base struct for closures.
+  late final w.StructType closureBaseStruct = _makeClosureStruct("#ClosureBase",
+      vtableBaseStruct, translator.classInfo[translator.functionClass]!.struct);
+
+  w.StructType _makeClosureStruct(
+      String name, w.StructType vtableStruct, w.StructType superType) {
+    // A closure contains:
+    //  - A class ID (always the `_Function` class ID)
+    //  - An identity hash
+    //  - A context reference (used for `this` in tear-offs)
+    //  - A vtable reference
+    //  - A type
+    return m.addStructType("#ClosureBase",
+        fields: [
+          w.FieldType(w.NumType.i32),
+          w.FieldType(w.NumType.i32),
+          w.FieldType(w.RefType.data(nullable: false)),
+          w.FieldType(w.RefType.def(vtableStruct, nullable: false),
+              mutable: false),
+          w.FieldType(typeType, mutable: false)
+        ],
+        superType: superType);
+  }
+
+  w.Module get m => translator.m;
+  w.ValueType get topType => translator.topInfo.nullableType;
+  w.ValueType get typeType =>
+      translator.classInfo[translator.typeClass]!.nonNullableType;
+
+  ClosureLayouter(this.translator)
+      : procedureAttributeMetadata =
+            (translator.component.metadata["vm.procedure-attributes.metadata"]
+                    as ProcedureAttributesMetadataRepository)
+                .mapping;
+
+  void collect() {
+    translator.component.accept(this);
+    computeClusters();
+  }
+
+  void computeClusters() {
+    for (int typeCount = 0; typeCount < representations.length; typeCount++) {
+      final representationsForTypeCount = representations[typeCount];
+      for (int positionalCount = 0;
+          positionalCount < representationsForTypeCount.length;
+          positionalCount++) {
+        final representationsForCounts =
+            representationsForTypeCount[positionalCount];
+        if (typeCount > 0) {
+          // Due to generic function instantiations, any name combination that
+          // occurs in a call of a non-generic function also counts as occurring
+          // in a call of all corresponding generic functions.
+          // Thus, the generic closure inherits the combinations for the
+          // corresponding closure with zero type parameters.
+          final instantiatedRepresentations =
+              representations[0][positionalCount];
+          representationsForCounts
+              .inheritCombinationsFrom(instantiatedRepresentations);
+        }
+        representationsForCounts.computeClusters();
+      }
+    }
+  }
+
+  /// Get the representation for closures with a specific signature, described
+  /// by the number of type parameters, the maximum number of positional
+  /// parameters and the names of named parameters.
+  ClosureRepresentation? getClosureRepresentation(
+      int typeCount, int positionalCount, List<String> names) {
+    final representations =
+        _representationsForCounts(typeCount, positionalCount);
+    if (representations.withoutNamed == null) {
+      ClosureRepresentation parent = positionalCount == 0
+          ? ClosureRepresentation(vtableBaseStruct.fields.length,
+              vtableBaseStruct, closureBaseStruct, null)
+          : getClosureRepresentation(typeCount, positionalCount - 1, const [])!;
+      representations.withoutNamed = _createRepresentation(typeCount,
+          positionalCount, const [], parent, null, [positionalCount]);
+    }
+
+    if (names.isEmpty) return representations.withoutNamed!;
+
+    ClosureRepresentationCluster? cluster =
+        representations.clusterForNames(names);
+    if (cluster == null) return null;
+    return cluster.representation ??= _createRepresentation(
+        typeCount,
+        positionalCount,
+        names,
+        representations.withoutNamed!,
+        cluster.indexOfCombination,
+        cluster.indexOfCombination.keys
+            .map((c) => positionalCount + c.names.length));
+  }
+
+  ClosureRepresentation _createRepresentation(
+      int typeCount,
+      int positionalCount,
+      List<String> names,
+      ClosureRepresentation parent,
+      Map<NameCombination, int>? indexOfCombination,
+      Iterable<int> paramCounts) {
+    List<String> nameTags = ["$typeCount", "$positionalCount", ...names];
+    String vtableName = ["#Vtable", ...nameTags].join("-");
+    String closureName = ["#Closure", ...nameTags].join("-");
+    w.StructType vtableStruct = m.addStructType(vtableName,
+        fields: parent.vtableStruct.fields, superType: parent.vtableStruct);
+    for (int paramCount in paramCounts) {
+      w.FunctionType entry = m.addFunctionType([
+        w.RefType.data(nullable: false),
+        ...List.filled(typeCount, typeType),
+        ...List.filled(paramCount, topType)
+      ], [
+        topType
+      ]);
+      vtableStruct.fields.add(
+          w.FieldType(w.RefType.def(entry, nullable: false), mutable: false));
+    }
+    w.StructType closureStruct =
+        _makeClosureStruct(closureName, vtableStruct, parent.closureStruct);
+    return ClosureRepresentation(vtableBaseStruct.fields.length, vtableStruct,
+        closureStruct, indexOfCombination);
+  }
+
+  ClosureRepresentationsForParameterCount _representationsForCounts(
+      int typeCount, int positionalCount) {
+    while (representations.length <= typeCount) {
+      representations.add([]);
+    }
+    List<ClosureRepresentationsForParameterCount> positionals =
+        representations[typeCount];
+    while (positionals.length <= positionalCount) {
+      positionals.add(ClosureRepresentationsForParameterCount());
+    }
+    return positionals[positionalCount];
+  }
+
+  void _visitFunctionNode(FunctionNode functionNode) {
+    final representations = _representationsForCounts(
+        functionNode.typeParameters.length,
+        functionNode.positionalParameters.length);
+    representations.registerFunction(functionNode);
+    if (functionNode.typeParameters.isNotEmpty) {
+      // Due to generic function instantiations, any generic function present
+      // in the program also counts as a presence of the corresponding
+      // non-generic function.
+      final instantiatedRepresentations = _representationsForCounts(
+          0, functionNode.positionalParameters.length);
+      instantiatedRepresentations.registerFunction(functionNode);
+    }
+  }
+
+  void _visitFunctionInvocation(Arguments arguments) {
+    final representations = _representationsForCounts(
+        arguments.types.length, arguments.positional.length);
+    representations.registerCall(arguments);
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    _visitFunctionNode(node.function);
+    super.visitFunctionExpression(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    _visitFunctionNode(node.function);
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitProcedure(Procedure node) {
+    if (node.isInstanceMember) {
+      ProcedureAttributesMetadata metadata = procedureAttributeMetadata[node]!;
+      if (metadata.hasTearOffUses) {
+        _visitFunctionNode(node.function);
+      }
+    }
+    super.visitProcedure(node);
+  }
+
+  @override
+  void visitStaticTearOffConstantReference(StaticTearOffConstant constant) {
+    _visitFunctionNode(constant.function);
+  }
+
+  @override
+  void defaultConstantReference(Constant constant) {
+    if (visitedConstants.add(constant)) {
+      constant.visitChildren(this);
+    }
+  }
+
+  @override
+  void visitFunctionInvocation(FunctionInvocation node) {
+    _visitFunctionInvocation(node.arguments);
+    super.visitFunctionInvocation(node);
+  }
+
+  @override
+  void visitDynamicInvocation(DynamicInvocation node) {
+    if (node.name.text == "call") {
+      _visitFunctionInvocation(node.arguments);
+    }
+    super.visitDynamicInvocation(node);
+  }
+}
+
+class ClosureRepresentationsForParameterCount {
+  ClosureRepresentation? withoutNamed;
+  final Set<NameCombination> callCombinations = SplayTreeSet();
+  final Map<String, int> nameIds = SplayTreeMap();
+  final UnionFind nameUnions = UnionFind();
+  final Map<String, ClosureRepresentationCluster> clusterForName = {};
+
+  void registerFunction(FunctionNode functionNode) {
+    int? prevIndex = null;
+    for (VariableDeclaration named in functionNode.namedParameters) {
+      String name = named.name!;
+      int nameIndex = nameIds.putIfAbsent(name, () => nameUnions.add());
+      if (prevIndex != null) {
+        nameUnions.union(prevIndex, nameIndex);
+      }
+      prevIndex = nameIndex;
+    }
+  }
+
+  void registerCall(Arguments arguments) {
+    if (arguments.named.isNotEmpty) {
+      NameCombination combination =
+          NameCombination(arguments.named.map((a) => a.name).toList()..sort());
+      callCombinations.add(combination);
+    }
+  }
+
+  void inheritCombinationsFrom(ClosureRepresentationsForParameterCount other) {
+    callCombinations.addAll(other.callCombinations);
+  }
+
+  ClosureRepresentationCluster? clusterForNames(List<String> names) {
+    final cluster = clusterForName[names[0]];
+    for (int i = 1; i < names.length; i++) {
+      if (clusterForName[names[i]] != cluster) {
+        return null;
+      }
+    }
+    return cluster;
+  }
+
+  void computeClusters() {
+    Map<int, ClosureRepresentationCluster> clusterForId = {};
+    nameIds.forEach((name, id) {
+      int canonicalId = nameUnions.find(id);
+      final cluster = clusterForId.putIfAbsent(canonicalId, () {
+        return ClosureRepresentationCluster();
+      });
+      cluster.names.add(name);
+      clusterForName[name] = cluster;
+    });
+    for (NameCombination combination in callCombinations) {
+      final cluster = clusterForNames(combination.names);
+      if (cluster != null) {
+        cluster.indexOfCombination[combination] =
+            cluster.indexOfCombination.length;
+      }
+    }
+  }
+}
+
+class ClosureRepresentationCluster {
+  final List<String> names = [];
+  final Map<NameCombination, int> indexOfCombination = SplayTreeMap();
+  ClosureRepresentation? representation;
+}
+
 /// A local function or function expression.
 class Lambda {
   final FunctionNode functionNode;
@@ -105,7 +488,7 @@
   w.Module get m => translator.m;
 
   late final w.ValueType typeType =
-      translator.classInfo[translator.typeClass]!.nullableType;
+      translator.classInfo[translator.typeClass]!.nonNullableType;
 
   void findCaptures(Member member) {
     var find = CaptureFinder(this, member);
@@ -155,7 +538,7 @@
         }
         for (TypeParameter parameter in context.typeParameters) {
           int index = struct.fields.length;
-          struct.fields.add(w.FieldType(typeType));
+          struct.fields.add(w.FieldType(typeType.withNullability(true)));
           captures[parameter]!.fieldIndex = index;
         }
       }
@@ -260,18 +643,21 @@
   }
 
   void _visitLambda(FunctionNode node) {
-    if (node.positionalParameters.length != node.requiredParameterCount ||
-        node.namedParameters.isNotEmpty) {
-      throw "Not supported: Optional parameters for "
-          "function expression or local function at ${node.location}";
-    }
-    if (node.typeParameters.isNotEmpty) {
-      throw "Not supported: Type parameters for "
-          "function expression or local function at ${node.location}";
-    }
-    int parameterCount = node.requiredParameterCount;
-    w.FunctionType type = translator.closureFunctionType(parameterCount);
-    w.DefinedFunction function = m.addFunction(type, "$member (closure)");
+    List<w.ValueType> inputs = [
+      w.RefType.data(nullable: false),
+      ...List.filled(node.typeParameters.length, closures.typeType),
+      for (VariableDeclaration param in node.positionalParameters)
+        translator.translateType(param.type),
+      for (VariableDeclaration param in node.namedParameters)
+        translator.translateType(param.type)
+    ];
+    List<w.ValueType> outputs = [
+      if (node.returnType != const VoidType())
+        translator.translateType(node.returnType)
+    ];
+    w.FunctionType type = m.addFunctionType(inputs, outputs);
+    w.DefinedFunction function =
+        m.addFunction(type, "$member closure at ${node.location}");
     closures.lambdas[node] = Lambda(node, function);
 
     depth++;
diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart
index 8177ada..f369957 100644
--- a/pkg/dart2wasm/lib/code_generator.dart
+++ b/pkg/dart2wasm/lib/code_generator.dart
@@ -4,6 +4,7 @@
 
 import 'package:dart2wasm/class_info.dart';
 import 'package:dart2wasm/closures.dart';
+import 'package:dart2wasm/constants.dart';
 import 'package:dart2wasm/dispatch_table.dart';
 import 'package:dart2wasm/intrinsics.dart';
 import 'package:dart2wasm/param_info.dart';
@@ -45,6 +46,8 @@
 
   late final Closures closures;
 
+  bool exceptionLocationPrinted = false;
+
   final Map<VariableDeclaration, w.Local> locals = {};
   w.Local? thisLocal;
   w.Local? preciseThisLocal;
@@ -125,6 +128,7 @@
 
   /// Generate code for the member.
   void generate() {
+    // Build closure information.
     closures = Closures(this);
 
     Member member = this.member;
@@ -166,18 +170,19 @@
       Procedure procedure = member as Procedure;
       w.BaseFunction inner =
           translator.functions.getFunction(procedure.asyncInnerReference);
-      return generateAsyncWrapper(procedure.function, inner);
+      int parameterOffset = _initializeThis(member);
+      return generateAsyncWrapper(procedure.function, inner, parameterOffset);
     }
 
     return generateBody(member);
   }
 
   void generateTearOffGetter(Procedure procedure) {
-    w.DefinedFunction closureFunction =
-        translator.getTearOffFunction(procedure);
-
-    int parameterCount = procedure.function.requiredParameterCount;
-    w.DefinedGlobal global = translator.makeFunctionRef(closureFunction);
+    _initializeThis(member);
+    DartType functionType =
+        procedure.function.computeThisFunctionType(Nullability.nonNullable);
+    ClosureImplementation closure = translator.getTearOffClosure(procedure);
+    w.StructType struct = closure.representation.closureStruct;
 
     ClassInfo info = translator.classInfo[translator.functionClass]!;
     translator.functions.allocateClass(info.classId);
@@ -185,8 +190,9 @@
     b.i32_const(info.classId);
     b.i32_const(initialIdentityHash);
     b.local_get(paramLocals[0]);
-    b.global_get(global);
-    b.struct_new(translator.closureStructType(parameterCount));
+    b.global_get(closure.vtable);
+    types.makeType(this, functionType);
+    b.struct_new(struct);
     b.end();
   }
 
@@ -252,7 +258,8 @@
   ///
   /// The stub function unwraps the arguments from the struct and calls the
   /// inner function, containing the implementation of the async function.
-  void generateAsyncWrapper(FunctionNode functionNode, w.BaseFunction inner) {
+  void generateAsyncWrapper(
+      FunctionNode functionNode, w.BaseFunction inner, int parameterOffset) {
     w.DefinedFunction stub =
         m.addFunction(translator.functions.asyncStubFunctionType);
     w.BaseFunction asyncHelper =
@@ -262,6 +269,13 @@
     w.Local stubArguments = stub.locals[0];
     w.Local stubStack = stub.locals[1];
 
+    // Set up the type parameter to local mapping, in case a type parameter is
+    // used in the return type.
+    int paramIndex = parameterOffset;
+    for (TypeParameter typeParam in functionNode.typeParameters) {
+      typeLocals[typeParam] = paramLocals[paramIndex++];
+    }
+
     // Push the type argument to the async helper, specifying the type argument
     // of the returned `Future`.
     DartType returnType = functionNode.returnType;
@@ -313,48 +327,64 @@
 
   void generateBody(Member member) {
     ParameterInfo paramInfo = translator.paramInfoFor(reference);
-    bool hasThis = member.isInstanceMember || member is Constructor;
-    int typeParameterOffset = hasThis ? 1 : 0;
-    int implicitParams = typeParameterOffset + paramInfo.typeParamCount;
+    int parameterOffset = _initializeThis(member);
+    int implicitParams = parameterOffset + paramInfo.typeParamCount;
+
+    void setupParamLocal(
+        VariableDeclaration variable, int index, Constant? defaultValue) {
+      w.Local local = paramLocals[implicitParams + index];
+      locals[variable] = local;
+      if (defaultValue == ParameterInfo.defaultValueSentinel) {
+        // The default value for this parameter differs between implementations
+        // within the same selector. This means that callers will pass the
+        // default value sentinel to indicate that the parameter is not given.
+        // The callee must check for the sentinel value and substitute the
+        // actual default value.
+        b.local_get(local);
+        translator.constants.instantiateConstant(
+            function, b, ParameterInfo.defaultValueSentinel, local.type);
+        b.ref_eq();
+        b.if_();
+        wrap(variable.initializer!, local.type);
+        b.local_set(local);
+        b.end();
+      }
+    }
+
     List<VariableDeclaration> positional =
         member.function!.positionalParameters;
     for (int i = 0; i < positional.length; i++) {
-      locals[positional[i]] = paramLocals[implicitParams + i];
+      setupParamLocal(positional[i], i, paramInfo.positional[i]);
     }
     List<VariableDeclaration> named = member.function!.namedParameters;
     for (var param in named) {
-      locals[param] =
-          paramLocals[implicitParams + paramInfo.nameIndex[param.name]!];
+      setupParamLocal(
+          param, paramInfo.nameIndex[param.name]!, paramInfo.named[param.name]);
     }
     List<TypeParameter> typeParameters = member is Constructor
         ? member.enclosingClass.typeParameters
         : member.function!.typeParameters;
     for (int i = 0; i < typeParameters.length; i++) {
-      typeLocals[typeParameters[i]] = paramLocals[typeParameterOffset + i];
+      typeLocals[typeParameters[i]] = paramLocals[parameterOffset + i];
     }
 
+    // For all parameters whose Wasm type has been forced to `externref` due to
+    // this function being an export, internalize and cast the parameter to the
+    // canonical representation type for its Dart type.
+    locals.forEach((parameter, local) {
+      DartType parameterType = parameter.type;
+      if (local.type == w.RefType.extern(nullable: true) &&
+          !(parameterType is InterfaceType &&
+              parameterType.classNode == translator.wasmExternRefClass)) {
+        w.Local newLocal = addLocal(translateType(parameterType));
+        b.local_get(local);
+        translator.convertType(function, local.type, newLocal.type);
+        b.local_set(newLocal);
+        locals[parameter] = newLocal;
+      }
+    });
+
     closures.findCaptures(member);
-
-    if (hasThis) {
-      Class cls = member.enclosingClass!;
-      ClassInfo info = translator.classInfo[cls]!;
-      thisLocal = paramLocals[0];
-      assert(!thisLocal!.type.nullable);
-      w.RefType thisType = info.nonNullableType;
-      if (translator.needsConversion(paramLocals[0].type, thisType) &&
-          !(cls == translator.objectInfo.cls ||
-              cls == translator.ffiPointerClass ||
-              translator.isFfiCompound(cls) ||
-              translator.isWasmType(cls))) {
-        preciseThisLocal = addLocal(thisType);
-        b.local_get(paramLocals[0]);
-        b.ref_cast(info.struct);
-        b.local_set(preciseThisLocal!);
-      } else {
-        preciseThisLocal = paramLocals[0];
-      }
-    }
-
     closures.collectContexts(member);
     if (member is Constructor) {
       for (Field field in member.enclosingClass.fields) {
@@ -389,36 +419,90 @@
         }
       }
       for (Initializer initializer in member.initializers) {
-        initializer.accept(this);
+        visitInitializer(initializer);
       }
     }
 
-    member.function!.body?.accept(this);
+    Statement? body = member.function!.body;
+    if (body != null) {
+      visitStatement(body);
+    }
     _implicitReturn();
     b.end();
   }
 
   /// Generate code for the body of a lambda.
   w.DefinedFunction generateLambda(Lambda lambda, Closures closures) {
-    if (lambda.functionNode.asyncMarker == AsyncMarker.Async &&
+    // Initialize closure information from enclosing member.
+    this.closures = closures;
+
+    FunctionNode functionNode = lambda.functionNode;
+    _initializeContextLocals(functionNode);
+
+    if (functionNode.asyncMarker == AsyncMarker.Async &&
         lambda.function == function) {
       w.DefinedFunction inner =
           translator.functions.addAsyncInnerFunctionFor(function);
-      generateAsyncWrapper(lambda.functionNode, inner);
+      generateAsyncWrapper(functionNode, inner, 1);
       return CodeGenerator(translator, inner, reference)
           .generateLambda(lambda, closures);
     }
 
-    this.closures = closures;
-
-    final int implicitParams = 1;
-    List<VariableDeclaration> positional =
-        lambda.functionNode.positionalParameters;
-    for (int i = 0; i < positional.length; i++) {
-      locals[positional[i]] = paramLocals[implicitParams + i];
+    int paramIndex = 1;
+    for (TypeParameter typeParam in functionNode.typeParameters) {
+      typeLocals[typeParam] = paramLocals[paramIndex++];
+    }
+    for (VariableDeclaration param in functionNode.positionalParameters) {
+      locals[param] = paramLocals[paramIndex++];
+    }
+    for (VariableDeclaration param in functionNode.namedParameters) {
+      locals[param] = paramLocals[paramIndex++];
     }
 
-    Context? context = closures.contexts[lambda.functionNode]?.parent;
+    allocateContext(functionNode);
+    captureParameters();
+
+    visitStatement(functionNode.body!);
+    _implicitReturn();
+    b.end();
+
+    return function;
+  }
+
+  /// Initialize locals containing `this` in constructors and instance members.
+  /// Returns the number of parameter locals taken up by the receiver parameter,
+  /// i.e. the parameter offset for the first type parameter (or the first
+  /// parameter if there are no type parameters).
+  int _initializeThis(Member member) {
+    bool hasThis = member.isInstanceMember || member is Constructor;
+    if (hasThis) {
+      Class cls = member.enclosingClass!;
+      ClassInfo info = translator.classInfo[cls]!;
+      thisLocal = paramLocals[0];
+      assert(!thisLocal!.type.nullable);
+      w.RefType thisType = info.nonNullableType;
+      if (translator.needsConversion(paramLocals[0].type, thisType) &&
+          !(cls == translator.objectInfo.cls ||
+              cls == translator.ffiPointerClass ||
+              translator.isFfiCompound(cls) ||
+              translator.isWasmType(cls))) {
+        preciseThisLocal = addLocal(thisType);
+        b.local_get(paramLocals[0]);
+        b.ref_cast(info.struct);
+        b.local_set(preciseThisLocal!);
+      } else {
+        preciseThisLocal = paramLocals[0];
+      }
+      return 1;
+    }
+    return 0;
+  }
+
+  /// Initialize locals pointing to every context in the context chain of a
+  /// closure, plus the locals containing `this` if `this` is captured by the
+  /// closure.
+  void _initializeContextLocals(FunctionNode functionNode) {
+    Context? context = closures.contexts[functionNode]?.parent;
     if (context != null) {
       b.local_get(paramLocals[0]);
       b.ref_cast(context.struct);
@@ -447,14 +531,6 @@
         b.local_set(thisLocal!);
       }
     }
-    allocateContext(lambda.functionNode);
-    captureParameters();
-
-    lambda.functionNode.body!.accept(this);
-    _implicitReturn();
-    b.end();
-
-    return function;
   }
 
   void _implicitReturn() {
@@ -532,9 +608,39 @@
   /// result to the expected type if needed. All expression code generation goes
   /// through this method.
   w.ValueType wrap(Expression node, w.ValueType expectedType) {
-    w.ValueType resultType = node.accept1(this, expectedType);
-    translator.convertType(function, resultType, expectedType);
-    return expectedType;
+    try {
+      w.ValueType resultType = node.accept1(this, expectedType);
+      translator.convertType(function, resultType, expectedType);
+      return expectedType;
+    } catch (_) {
+      _printLocation(node);
+      rethrow;
+    }
+  }
+
+  void visitStatement(Statement node) {
+    try {
+      node.accept(this);
+    } catch (_) {
+      _printLocation(node);
+      rethrow;
+    }
+  }
+
+  void visitInitializer(Initializer node) {
+    try {
+      node.accept(this);
+    } catch (_) {
+      _printLocation(node);
+      rethrow;
+    }
+  }
+
+  void _printLocation(TreeNode node) {
+    if (!exceptionLocationPrinted) {
+      print("Exception in ${node.runtimeType} at ${node.location}");
+      exceptionLocationPrinted = true;
+    }
   }
 
   w.ValueType call(Reference target) {
@@ -567,7 +673,7 @@
 
   @override
   void visitLocalInitializer(LocalInitializer node) {
-    node.variable.accept(this);
+    visitStatement(node.variable);
   }
 
   @override
@@ -613,7 +719,7 @@
   @override
   void visitBlock(Block node) {
     for (Statement statement in node.statements) {
-      statement.accept(this);
+      visitStatement(statement);
     }
   }
 
@@ -621,7 +727,7 @@
   void visitLabeledStatement(LabeledStatement node) {
     w.Label label = b.block();
     labels[node] = label;
-    node.body.accept(this);
+    visitStatement(node.body);
     labels.remove(node);
     b.end();
   }
@@ -684,7 +790,7 @@
     // nodes, we generate a single wasm catch instruction, and dispatch at
     // runtime based on the type of the caught exception.
     w.Label try_ = b.try_();
-    node.body.accept(this);
+    visitStatement(node.body);
     b.br(try_);
 
     // Insert a catch instruction which will catch any thrown Dart
@@ -744,7 +850,7 @@
         b.local_get(thrownStackTrace);
         b.local_set(guardedStackTrace);
       }
-      catch_.body.accept(this);
+      visitStatement(catch_.body);
 
       // Jump out of the try entirely if we enter any catch block.
       b.br(try_);
@@ -771,18 +877,18 @@
     w.Label finalizerBlock = b.block();
     finalizers.add(TryBlockFinalizer(finalizerBlock));
     w.Label tryBlock = b.try_();
-    node.body.accept(this);
+    visitStatement(node.body);
     bool mustHandleReturn = finalizers.removeLast().mustHandleReturn;
     b.br(tryBlock);
     b.catch_(translator.exceptionTag);
-    node.finalizer.accept(this);
+    visitStatement(node.finalizer);
     b.rethrow_(tryBlock);
     b.end(); // end tryBlock.
-    node.finalizer.accept(this);
+    visitStatement(node.finalizer);
     b.br(tryFinallyBlock);
     b.end(); // end finalizerBlock.
     if (mustHandleReturn) {
-      node.finalizer.accept(this);
+      visitStatement(node.finalizer);
       if (finalizers.isNotEmpty) {
         b.br(finalizers.last.label);
       } else {
@@ -873,8 +979,8 @@
   void visitIfStatement(IfStatement node) {
     _conditional(
         node.condition,
-        () => node.then.accept(this),
-        node.otherwise != null ? () => node.otherwise!.accept(this) : null,
+        () => visitStatement(node.then),
+        node.otherwise != null ? () => visitStatement(node.otherwise!) : null,
         const []);
   }
 
@@ -882,7 +988,7 @@
   void visitDoStatement(DoStatement node) {
     w.Label loop = b.loop();
     allocateContext(node);
-    node.body.accept(this);
+    visitStatement(node.body);
     _branchIf(node.condition, loop, negated: false);
     b.end();
   }
@@ -893,7 +999,7 @@
     w.Label loop = b.loop();
     _branchIf(node.condition, block, negated: true);
     allocateContext(node);
-    node.body.accept(this);
+    visitStatement(node.body);
     b.br(loop);
     b.end();
     b.end();
@@ -904,34 +1010,36 @@
     Context? context = closures.contexts[node];
     allocateContext(node);
     for (VariableDeclaration variable in node.variables) {
-      variable.accept(this);
+      visitStatement(variable);
     }
     w.Label block = b.block();
     w.Label loop = b.loop();
     _branchIf(node.condition, block, negated: true);
-    node.body.accept(this);
+    visitStatement(node.body);
 
-    // If the loop variable is captured then we have to create a new context for
-    // each iteration of the loop. We must also ensure the local pointing to the
-    // [oldContext] now points to [newContext].
-    if (node.variables.any((v) => closures.captures.containsKey(v))) {
-      w.Local oldContext = context!.currentLocal;
+    if (context != null && !context.isEmpty) {
+      // Create a new context for each iteration of the loop.
+      w.Local oldContext = context.currentLocal;
       allocateContext(node);
       w.Local newContext = context.currentLocal;
+
+      // Copy the values of captured loop variables to the new context.
       for (VariableDeclaration variable in node.variables) {
         Capture? capture = closures.captures[variable];
         if (capture != null) {
+          assert(capture.context == context);
           b.local_get(newContext);
           b.local_get(oldContext);
           b.struct_get(context.struct, capture.fieldIndex);
           b.struct_set(context.struct, capture.fieldIndex);
         }
       }
+
+      // Update the context local to point to the new context.
       b.local_get(newContext);
       b.local_set(oldContext);
-    } else {
-      allocateContext(node);
     }
+
     for (Expression update in node.updates) {
       wrap(update, voidMarker);
     }
@@ -1122,7 +1230,7 @@
         switchBackwardJumpInfos[node]!.defaultLoopLabel = b.loop();
       }
 
-      c.body.accept(this);
+      visitStatement(c.body);
 
       if (c.isDefault) {
         b.end(); // defaultLoopLabel
@@ -1188,13 +1296,13 @@
   @override
   w.ValueType visitBlockExpression(
       BlockExpression node, w.ValueType expectedType) {
-    node.body.accept(this);
+    visitStatement(node.body);
     return wrap(node.value, expectedType);
   }
 
   @override
   w.ValueType visitLet(Let node, w.ValueType expectedType) {
-    node.variable.accept(this);
+    visitStatement(node.variable);
     return wrap(node.body, expectedType);
   }
 
@@ -1321,8 +1429,7 @@
       DynamicInvocation node, w.ValueType expectedType) {
     // Handle dynamic 'call' seperately.
     if (node.name.text == "call") {
-      return _functionCall(
-          node.arguments.positional.length, node.receiver, node.arguments);
+      return _functionCall(node.receiver, node.arguments);
     }
     return translator.dynamics.emitDynamicCall(this, node);
   }
@@ -1647,7 +1754,12 @@
       SuperPropertyGet node, w.ValueType expectedType) {
     Member target = _lookupSuperTarget(node.interfaceTarget, setter: false);
     if (target is Procedure && !target.isGetter) {
-      throw "Not supported: Super tear-off at ${node.location}";
+      // Super tear-off
+      w.StructType closureStruct = _pushClosure(
+          translator.getTearOffClosure(target),
+          target.function.computeThisFunctionType(Nullability.nonNullable),
+          () => visitThis(w.RefType.data(nullable: false)));
+      return w.RefType.def(closureStruct, nullable: false);
     }
     return _directGet(target, ThisExpression(), () => null);
   }
@@ -1836,19 +1948,31 @@
   }
 
   w.StructType _instantiateClosure(FunctionNode functionNode) {
-    int parameterCount = functionNode.requiredParameterCount;
     Lambda lambda = closures.lambdas[functionNode]!;
-    w.DefinedGlobal global = translator.makeFunctionRef(lambda.function);
+    ClosureImplementation closure = translator.getClosure(
+        functionNode,
+        lambda.function,
+        ParameterInfo.fromLocalFunction(functionNode),
+        "closure wrapper at ${functionNode.location}");
+    return _pushClosure(
+        closure,
+        functionNode.computeThisFunctionType(Nullability.nonNullable),
+        () => _pushContext(functionNode));
+  }
+
+  w.StructType _pushClosure(ClosureImplementation closure,
+      DartType functionType, void pushContext()) {
+    w.StructType struct = closure.representation.closureStruct;
 
     ClassInfo info = translator.classInfo[translator.functionClass]!;
     translator.functions.allocateClass(info.classId);
-    w.StructType struct = translator.closureStructType(parameterCount);
 
     b.i32_const(info.classId);
     b.i32_const(initialIdentityHash);
-    _pushContext(functionNode);
-    b.global_get(global);
-    b.struct_new(translator.closureStructType(parameterCount));
+    pushContext();
+    b.global_get(closure.vtable);
+    types.makeType(this, functionType);
+    b.struct_new(struct);
 
     return struct;
   }
@@ -1870,23 +1994,57 @@
         intrinsifier.generateFunctionCallIntrinsic(node);
     if (intrinsicResult != null) return intrinsicResult;
 
-    int parameterCount = node.functionType?.requiredParameterCount ??
-        node.arguments.positional.length;
-    return _functionCall(parameterCount, node.receiver, node.arguments);
+    return _functionCall(node.receiver, node.arguments);
   }
 
-  w.ValueType _functionCall(
-      int parameterCount, Expression receiver, Arguments arguments) {
-    w.StructType struct = translator.closureStructType(parameterCount);
+  w.ValueType _functionCall(Expression receiver, Arguments arguments) {
+    int typeCount = arguments.types.length;
+    int posArgCount = arguments.positional.length;
+    List<String> argNames = arguments.named.map((a) => a.name).toList()..sort();
+    ClosureRepresentation? representation = translator.closureLayouter
+        .getClosureRepresentation(typeCount, posArgCount, argNames);
+    if (representation == null) {
+      // This is a dynamic function call with a signature that matches no
+      // functions in the program.
+      b.unreachable();
+      return translator.topInfo.nullableType;
+    }
+
+    // Evaluate receiver
+    w.StructType struct = representation.closureStruct;
     w.Local temp = addLocal(w.RefType.def(struct, nullable: false));
     wrap(receiver, temp.type);
     b.local_tee(temp);
     b.struct_get(struct, FieldIndex.closureContext);
+
+    // Type arguments
+    for (DartType typeArg in arguments.types) {
+      types.makeType(this, typeArg);
+    }
+
+    // Positional arguments
     for (Expression arg in arguments.positional) {
       wrap(arg, translator.topInfo.nullableType);
     }
+
+    // Named arguments
+    final Map<String, w.Local> namedLocals = {};
+    for (final namedArg in arguments.named) {
+      final w.Local namedLocal = addLocal(translator.topInfo.nullableType);
+      namedLocals[namedArg.name] = namedLocal;
+      wrap(namedArg.value, namedLocal.type);
+      b.local_set(namedLocal);
+    }
+    for (String name in argNames) {
+      b.local_get(namedLocals[name]!);
+    }
+
+    // Call entry point in vtable
+    int vtableIndex =
+        representation.fieldIndexForSignature(posArgCount, argNames);
     b.local_get(temp);
-    b.struct_get(struct, FieldIndex.closureFunction);
+    b.struct_get(struct, FieldIndex.closureVtable);
+    b.struct_get(representation.vtableStruct, vtableIndex);
     b.call_ref();
     return translator.topInfo.nullableType;
   }
@@ -1895,14 +2053,15 @@
   w.ValueType visitLocalFunctionInvocation(
       LocalFunctionInvocation node, w.ValueType expectedType) {
     var decl = node.variable.parent as FunctionDeclaration;
-    _pushContext(decl.function);
-    for (Expression arg in node.arguments.positional) {
-      wrap(arg, translator.topInfo.nullableType);
-    }
     Lambda lambda = closures.lambdas[decl.function]!;
+    _pushContext(decl.function);
+    Arguments arguments = node.arguments;
+    visitArgumentsLists(arguments.positional, lambda.function.type,
+        ParameterInfo.fromLocalFunction(decl.function), 1,
+        typeArguments: arguments.types, named: arguments.named);
     b.comment("Local call of ${decl.variable.name}");
     b.call(lambda.function);
-    return translator.topInfo.nullableType;
+    return translator.outputOrVoid(lambda.function.type.outputs);
   }
 
   @override
@@ -2099,8 +2258,8 @@
     b.i32_const(initialIdentityHash);
     types.makeType(this, typeArg);
     b.i64_const(length);
-    if (options.lazyConstants) {
-      // Avoid array.init instruction in lazy constants mode
+    if (length > maxArrayNewFixedLength) {
+      // Too long for `array.new_fixed`. Set elements individually.
       b.i32_const(length);
       b.array_new_default(arrayType);
       if (length > 0) {
diff --git a/pkg/dart2wasm/lib/constants.dart b/pkg/dart2wasm/lib/constants.dart
index a29932e..a2f327e 100644
--- a/pkg/dart2wasm/lib/constants.dart
+++ b/pkg/dart2wasm/lib/constants.dart
@@ -6,45 +6,49 @@
 import 'dart:typed_data';
 
 import 'package:dart2wasm/class_info.dart';
+import 'package:dart2wasm/closures.dart';
+import 'package:dart2wasm/param_info.dart';
 import 'package:dart2wasm/translator.dart';
 import 'package:dart2wasm/types.dart';
 
 import 'package:kernel/ast.dart';
-import 'package:kernel/type_algebra.dart' show substitute;
+import 'package:kernel/type_algebra.dart' show substitute, Substitution;
 
 import 'package:wasm_builder/wasm_builder.dart' as w;
 
+const int maxArrayNewFixedLength = 10000;
+
 class ConstantInfo {
   final Constant constant;
   final w.DefinedGlobal global;
   final w.DefinedFunction? function;
 
   ConstantInfo(this.constant, this.global, this.function);
+
+  bool get isLazy => function != null;
 }
 
 typedef ConstantCodeGenerator = void Function(
     w.DefinedFunction?, w.Instructions);
 
-/// Handles the creation of Dart constants. Can operate in two modes - eager and
-/// lazy - controlled by [TranslatorOptions.lazyConstants].
+/// Handles the creation of Dart constants.
 ///
 /// Each (non-trivial) constant is assigned to a Wasm global. Multiple
 /// occurrences of the same constant use the same global.
 ///
-/// In eager mode, the constant is contained within the global initializer,
-/// meaning all constants are initialized eagerly during module initialization.
-/// In lazy mode, the global starts out uninitialized, and every use of the
-/// constant checks the global to see if it has been initialized and calls an
-/// initialization function otherwise.
+/// When possible, the constant is contained within the global initializer,
+/// meaning the constant is initialized eagerly during module initialization.
+/// If this would exceed built-in Wasm limits (in particular the maximum length
+/// for `array.new_fixed`), the constant is lazy, meaning that the global starts
+/// out uninitialized, and every use of the constant checks the global to see if
+/// it has been initialized and calls an initialization function otherwise.
+/// A constant is also forced to be lazy if any sub-constants (e.g. elements of
+/// a constant list) are lazy.
 class Constants {
   final Translator translator;
   final Map<Constant, ConstantInfo> constantInfo = {};
-  final StringBuffer oneByteStrings = StringBuffer();
-  final StringBuffer twoByteStrings = StringBuffer();
-  late final w.DefinedFunction oneByteStringFunction;
-  late final w.DefinedFunction twoByteStringFunction;
-  late final w.DataSegment oneByteStringSegment;
-  late final w.DataSegment twoByteStringSegment;
+  w.DataSegment? oneByteStringSegment;
+  w.DataSegment? twoByteStringSegment;
   late final w.DefinedGlobal emptyString;
   late final w.DefinedGlobal emptyTypeList;
   late final ClassInfo typeInfo = translator.classInfo[translator.typeClass]!;
@@ -52,19 +56,11 @@
   bool currentlyCreating = false;
 
   Constants(this.translator) {
-    if (lazyConstants) {
-      oneByteStringFunction = makeStringFunction(translator.oneByteStringClass);
-      twoByteStringFunction = makeStringFunction(translator.twoByteStringClass);
-    } else if (stringDataSegments) {
-      oneByteStringSegment = m.addDataSegment();
-      twoByteStringSegment = m.addDataSegment();
-    }
     initEmptyString();
     initEmptyTypeList();
   }
 
   w.Module get m => translator.m;
-  bool get lazyConstants => translator.options.lazyConstants;
   bool get stringDataSegments => translator.options.stringDataSegments;
 
   void initEmptyString() {
@@ -73,29 +69,14 @@
     w.ArrayType arrayType =
         (info.struct.fields.last.type as w.RefType).heapType as w.ArrayType;
 
-    if (lazyConstants) {
-      w.RefType emptyStringType = info.nullableType;
-      emptyString = m.addGlobal(w.GlobalType(emptyStringType));
-      emptyString.initializer.ref_null(emptyStringType.heapType);
-      emptyString.initializer.end();
-
-      w.Instructions b = translator.initFunction.body;
-      b.i32_const(info.classId);
-      b.i32_const(initialIdentityHash);
-      b.i32_const(0);
-      b.array_new_default(arrayType);
-      b.struct_new(info.struct);
-      b.global_set(emptyString);
-    } else {
-      w.RefType emptyStringType = info.nonNullableType;
-      emptyString = m.addGlobal(w.GlobalType(emptyStringType, mutable: false));
-      w.Instructions ib = emptyString.initializer;
-      ib.i32_const(info.classId);
-      ib.i32_const(initialIdentityHash);
-      ib.array_new_fixed(arrayType, 0);
-      ib.struct_new(info.struct);
-      ib.end();
-    }
+    w.RefType emptyStringType = info.nonNullableType;
+    emptyString = m.addGlobal(w.GlobalType(emptyStringType, mutable: false));
+    w.Instructions ib = emptyString.initializer;
+    ib.i32_const(info.classId);
+    ib.i32_const(initialIdentityHash);
+    ib.array_new_fixed(arrayType, 0);
+    ib.struct_new(info.struct);
+    ib.end();
 
     Constant emptyStringConstant = StringConstant("");
     constantInfo[emptyStringConstant] =
@@ -109,33 +90,16 @@
     w.ArrayType arrayType = refType.heapType as w.ArrayType;
 
     // Create the empty type list with its type parameter uninitialized for now.
-    if (lazyConstants) {
-      w.RefType emptyListType = info.nullableType;
-      emptyTypeList = m.addGlobal(w.GlobalType(emptyListType));
-      emptyTypeList.initializer.ref_null(emptyListType.heapType);
-      emptyTypeList.initializer.end();
-
-      w.Instructions b = translator.initFunction.body;
-      b.i32_const(info.classId);
-      b.i32_const(initialIdentityHash);
-      b.ref_null(typeInfo.struct); // Initialized later
-      b.i64_const(0);
-      b.i32_const(0);
-      b.array_new_default(arrayType);
-      b.struct_new(info.struct);
-      b.global_set(emptyTypeList);
-    } else {
-      w.RefType emptyListType = info.nonNullableType;
-      emptyTypeList = m.addGlobal(w.GlobalType(emptyListType, mutable: false));
-      w.Instructions ib = emptyTypeList.initializer;
-      ib.i32_const(info.classId);
-      ib.i32_const(initialIdentityHash);
-      ib.ref_null(typeInfo.struct); // Initialized later
-      ib.i64_const(0);
-      ib.array_new_fixed(arrayType, 0);
-      ib.struct_new(info.struct);
-      ib.end();
-    }
+    w.RefType emptyListType = info.nonNullableType;
+    emptyTypeList = m.addGlobal(w.GlobalType(emptyListType, mutable: false));
+    w.Instructions ib = emptyTypeList.initializer;
+    ib.i32_const(info.classId);
+    ib.i32_const(initialIdentityHash);
+    ib.ref_null(typeInfo.struct); // Initialized later
+    ib.i64_const(0);
+    ib.array_new_fixed(arrayType, 0);
+    ib.struct_new(info.struct);
+    ib.end();
 
     Constant emptyTypeListConstant = ListConstant(
         InterfaceType(translator.typeClass, Nullability.nonNullable), const []);
@@ -156,40 +120,6 @@
         translator.typeParameterIndex[info.cls!.typeParameters.single]!);
   }
 
-  void finalize() {
-    if (lazyConstants) {
-      finalizeStrings();
-    }
-  }
-
-  void finalizeStrings() {
-    Uint8List oneByteStringsAsBytes =
-        Uint8List.fromList(oneByteStrings.toString().codeUnits);
-    assert(Endian.host == Endian.little);
-    Uint8List twoByteStringsAsBytes =
-        Uint16List.fromList(twoByteStrings.toString().codeUnits)
-            .buffer
-            .asUint8List();
-    Uint8List stringsAsBytes = (BytesBuilder()
-          ..add(twoByteStringsAsBytes)
-          ..add(oneByteStringsAsBytes))
-        .toBytes();
-
-    w.Memory stringMemory =
-        m.addMemory(false, stringsAsBytes.length, stringsAsBytes.length);
-    m.addDataSegment(stringsAsBytes, stringMemory, 0);
-    makeStringFunctionBody(translator.oneByteStringClass, oneByteStringFunction,
-        (b) {
-      b.i32_load8_u(stringMemory, twoByteStringsAsBytes.length);
-    });
-    makeStringFunctionBody(translator.twoByteStringClass, twoByteStringFunction,
-        (b) {
-      b.i32_const(1);
-      b.i32_shl();
-      b.i32_load16_u(stringMemory, 0);
-    });
-  }
-
   /// Create one of the two Wasm functions (one for each string type) called
   /// from every lazily initialized string constant (of that type) to create and
   /// initialize the string.
@@ -201,7 +131,7 @@
     ClassInfo info = translator.classInfo[cls]!;
     w.FunctionType ftype = m.addFunctionType(
         const [w.NumType.i32, w.NumType.i32], [info.nonNullableType]);
-    return m.addFunction(ftype, "makeString (${cls.name})");
+    return m.addFunction(ftype, "makeString ${cls.name}");
   }
 
   void makeStringFunctionBody(Class cls, w.DefinedFunction function,
@@ -276,11 +206,11 @@
 
   /// Ensure that the constant has a Wasm global assigned.
   ///
-  /// In eager mode, sub-constants must have Wasm globals assigned before the
-  /// global for the composite constant is assigned, since global initializers
-  /// can only refer to earlier globals.
-  void ensureConstant(Constant constant) {
-    ConstantCreator(this).ensureConstant(constant);
+  /// Sub-constants must have Wasm globals assigned before the global for the
+  /// composite constant is assigned, since global initializers can only refer
+  /// to earlier globals.
+  ConstantInfo? ensureConstant(Constant constant) {
+    return ConstantCreator(this).ensureConstant(constant);
   }
 
   /// Emit code to push a constant onto the stack.
@@ -312,29 +242,36 @@
   @override
   w.ValueType defaultConstant(Constant constant) {
     ConstantInfo info = ConstantCreator(constants).ensureConstant(constant)!;
-    w.ValueType globalType = info.global.type.type;
-    if (globalType.nullable) {
-      if (info.function != null) {
-        // Lazily initialized constant.
-        w.Label done = b.block(const [], [globalType.withNullability(false)]);
-        b.global_get(info.global);
-        b.br_on_non_null(done);
-        b.call(info.function!);
-        b.end();
-      } else {
-        // Constant initialized in the module init function.
-        b.global_get(info.global);
-        b.ref_as_non_null();
-      }
-      return globalType.withNullability(false);
+    if (info.isLazy) {
+      // Lazily initialized constant.
+      w.ValueType type = info.global.type.type.withNullability(false);
+      w.Label done = b.block(const [], [type]);
+      b.global_get(info.global);
+      b.br_on_non_null(done);
+      b.call(info.function!);
+      b.end();
+      return type;
     } else {
       // Constant initialized eagerly in a global initializer.
       b.global_get(info.global);
-      return globalType;
+      return info.global.type.type;
     }
   }
 
   @override
+  w.ValueType visitUnevaluatedConstant(UnevaluatedConstant constant) {
+    if (constant == ParameterInfo.defaultValueSentinel) {
+      // Instantiate a sentinel value specific to the parameter type.
+      w.ValueType sentinelType = expectedType.withNullability(false);
+      assert(sentinelType is w.RefType,
+          "Default value sentinel for unboxed parameter");
+      translator.globals.instantiateDummyValue(b, sentinelType);
+      return sentinelType;
+    }
+    return super.visitUnevaluatedConstant(constant);
+  }
+
+  @override
   w.ValueType visitNullConstant(NullConstant node) {
     w.ValueType? expectedType = this.expectedType;
     if (expectedType != translator.voidMarker) {
@@ -397,7 +334,6 @@
   Translator get translator => constants.translator;
   Types get types => translator.types;
   w.Module get m => constants.m;
-  bool get lazyConstants => constants.lazyConstants;
 
   ConstantInfo? ensureConstant(Constant constant) {
     ConstantInfo? info = constants.constantInfo[constant];
@@ -411,9 +347,10 @@
   }
 
   ConstantInfo createConstant(
-      Constant constant, w.RefType type, ConstantCodeGenerator generator) {
+      Constant constant, w.RefType type, ConstantCodeGenerator generator,
+      {bool lazy = false}) {
     assert(!type.nullable);
-    if (lazyConstants) {
+    if (lazy) {
       // Create uninitialized global and function to initialize it.
       w.DefinedGlobal global =
           m.addGlobal(w.GlobalType(type.withNullability(true)));
@@ -454,55 +391,40 @@
         : translator.twoByteStringClass]!;
     translator.functions.allocateClass(info.classId);
     w.RefType type = info.nonNullableType;
-    return createConstant(constant, type, (function, b) {
-      if (lazyConstants) {
-        // Copy string contents from linear memory on initialization. The memory
-        // is initialized by an active data segment for each string type.
-        StringBuffer buffer =
-            isOneByte ? constants.oneByteStrings : constants.twoByteStrings;
-        int offset = buffer.length;
-        int length = constant.value.length;
-        buffer.write(constant.value);
+    bool lazy = constant.value.length > maxArrayNewFixedLength;
+    return createConstant(constant, type, lazy: lazy, (function, b) {
+      w.ArrayType arrayType =
+          (info.struct.fields.last.type as w.RefType).heapType as w.ArrayType;
 
-        b.i32_const(offset);
-        b.i32_const(length);
-        b.call(isOneByte
-            ? constants.oneByteStringFunction
-            : constants.twoByteStringFunction);
-      } else {
-        w.ArrayType arrayType =
-            (info.struct.fields.last.type as w.RefType).heapType as w.ArrayType;
-
-        b.i32_const(info.classId);
-        b.i32_const(initialIdentityHash);
-        if (constants.stringDataSegments) {
-          // Initialize string contents from passive data segment.
-          w.DataSegment segment;
-          Uint8List bytes;
-          if (isOneByte) {
-            segment = constants.oneByteStringSegment;
-            bytes = Uint8List.fromList(constant.value.codeUnits);
-          } else {
-            assert(Endian.host == Endian.little);
-            segment = constants.twoByteStringSegment;
-            bytes = Uint16List.fromList(constant.value.codeUnits)
-                .buffer
-                .asUint8List();
-          }
-          int offset = segment.length;
-          segment.append(bytes);
-          b.i32_const(offset);
-          b.i32_const(constant.value.length);
-          b.array_new_data(arrayType, segment);
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      if (lazy || constants.stringDataSegments) {
+        // Initialize string contents from passive data segment.
+        w.DataSegment segment;
+        Uint8List bytes;
+        if (isOneByte) {
+          segment = constants.oneByteStringSegment ??= m.addDataSegment();
+          bytes = Uint8List.fromList(constant.value.codeUnits);
         } else {
-          // Initialize string contents from i32 constants on the stack.
-          for (int charCode in constant.value.codeUnits) {
-            b.i32_const(charCode);
-          }
-          b.array_new_fixed(arrayType, constant.value.length);
+          assert(Endian.host == Endian.little);
+          segment = constants.twoByteStringSegment ??= m.addDataSegment();
+          bytes = Uint16List.fromList(constant.value.codeUnits)
+              .buffer
+              .asUint8List();
         }
-        b.struct_new(info.struct);
+        int offset = segment.length;
+        segment.append(bytes);
+        b.i32_const(offset);
+        b.i32_const(constant.value.length);
+        b.array_new_data(arrayType, segment);
+      } else {
+        // Initialize string contents from i32 constants on the stack.
+        for (int charCode in constant.value.codeUnits) {
+          b.i32_const(charCode);
+        }
+        b.array_new_fixed(arrayType, constant.value.length);
       }
+      b.struct_new(info.struct);
     });
   }
 
@@ -517,11 +439,12 @@
     const int baseFieldCount = 2;
     int fieldCount = info.struct.fields.length;
     List<Constant?> subConstants = List.filled(fieldCount, null);
+    bool lazy = false;
     constant.fieldValues.forEach((reference, subConstant) {
       int index = translator.fieldIndex[reference.asField]!;
       assert(subConstants[index] == null);
       subConstants[index] = subConstant;
-      ensureConstant(subConstant);
+      lazy |= ensureConstant(subConstant)?.isLazy ?? false;
     });
 
     // Collect sub-constants for type arguments.
@@ -543,7 +466,7 @@
       args = supertype.typeArguments;
     }
 
-    return createConstant(constant, type, (function, b) {
+    return createConstant(constant, type, lazy: lazy, (function, b) {
       b.i32_const(info.classId);
       b.i32_const(initialIdentityHash);
       for (int i = baseFieldCount; i < fieldCount; i++) {
@@ -559,14 +482,15 @@
   ConstantInfo? visitListConstant(ListConstant constant) {
     Constant typeArgConstant = TypeLiteralConstant(constant.typeArgument);
     ensureConstant(typeArgConstant);
+    bool lazy = constant.entries.length > maxArrayNewFixedLength;
     for (Constant subConstant in constant.entries) {
-      ensureConstant(subConstant);
+      lazy |= ensureConstant(subConstant)?.isLazy ?? false;
     }
 
     ClassInfo info = translator.classInfo[translator.immutableListClass]!;
     translator.functions.allocateClass(info.classId);
     w.RefType type = info.nonNullableType;
-    return createConstant(constant, type, (function, b) {
+    return createConstant(constant, type, lazy: lazy, (function, b) {
       w.RefType refType = info.struct.fields.last.type.unpacked as w.RefType;
       w.ArrayType arrayType = refType.heapType as w.ArrayType;
       w.ValueType elementType = arrayType.elementType.type.unpacked;
@@ -576,7 +500,7 @@
       constants.instantiateConstant(
           function, b, typeArgConstant, constants.typeInfo.nullableType);
       b.i64_const(length);
-      if (lazyConstants) {
+      if (lazy) {
         // Allocate array and set each entry to the corresponding sub-constant.
         w.Local arrayLocal = function!.addLocal(refType.withNullability(false));
         b.i32_const(length);
@@ -614,12 +538,12 @@
       return i.isEven ? entry.key : entry.value;
     });
     ListConstant dataList = ListConstant(const DynamicType(), dataElements);
-    ensureConstant(dataList);
+    bool lazy = ensureConstant(dataList)?.isLazy ?? false;
 
     ClassInfo info = translator.classInfo[translator.immutableMapClass]!;
     translator.functions.allocateClass(info.classId);
     w.RefType type = info.nonNullableType;
-    return createConstant(constant, type, (function, b) {
+    return createConstant(constant, type, lazy: lazy, (function, b) {
       w.RefType indexType =
           info.struct.fields[FieldIndex.hashBaseIndex].type as w.RefType;
       w.RefType dataType =
@@ -645,12 +569,12 @@
     Constant elementTypeConstant = TypeLiteralConstant(constant.typeArgument);
     ensureConstant(elementTypeConstant);
     ListConstant dataList = ListConstant(const DynamicType(), constant.entries);
-    ensureConstant(dataList);
+    bool lazy = ensureConstant(dataList)?.isLazy ?? false;
 
     ClassInfo info = translator.classInfo[translator.immutableSetClass]!;
     translator.functions.allocateClass(info.classId);
     w.RefType type = info.nonNullableType;
-    return createConstant(constant, type, (function, b) {
+    return createConstant(constant, type, lazy: lazy, (function, b) {
       w.RefType indexType =
           info.struct.fields[FieldIndex.hashBaseIndex].type as w.RefType;
       w.RefType dataType =
@@ -682,10 +606,12 @@
 
   @override
   ConstantInfo? visitStaticTearOffConstant(StaticTearOffConstant constant) {
-    w.DefinedFunction closureFunction =
-        translator.getTearOffFunction(constant.targetReference.asProcedure);
-    int parameterCount = closureFunction.type.inputs.length - 1;
-    w.StructType struct = translator.closureStructType(parameterCount);
+    Procedure member = constant.targetReference.asProcedure;
+    Constant functionTypeConstant = TypeLiteralConstant(
+        member.function.computeThisFunctionType(Nullability.nonNullable));
+    ensureConstant(functionTypeConstant);
+    ClosureImplementation closure = translator.getTearOffClosure(member);
+    w.StructType struct = closure.representation.closureStruct;
     w.RefType type = w.RefType.def(struct, nullable: false);
     return createConstant(constant, type, (function, b) {
       ClassInfo info = translator.classInfo[translator.functionClass]!;
@@ -694,13 +620,98 @@
       b.i32_const(info.classId);
       b.i32_const(initialIdentityHash);
       b.global_get(translator.globals.dummyGlobal); // Dummy context
-      if (lazyConstants) {
-        w.DefinedGlobal global = translator.makeFunctionRef(closureFunction);
-        b.global_get(global);
-      } else {
-        b.ref_func(closureFunction);
+      b.global_get(closure.vtable);
+      constants.instantiateConstant(
+          function, b, functionTypeConstant, this.types.nonNullableTypeType);
+      b.struct_new(struct);
+    });
+  }
+
+  @override
+  ConstantInfo? visitInstantiationConstant(InstantiationConstant constant) {
+    TearOffConstant tearOffConstant =
+        constant.tearOffConstant as TearOffConstant;
+    List<ConstantInfo> types = constant.types
+        .map((c) => ensureConstant(TypeLiteralConstant(c))!)
+        .toList();
+    Procedure tearOffProcedure = tearOffConstant.targetReference.asProcedure;
+    FunctionType tearOffFunctionType = tearOffProcedure.function
+        .computeThisFunctionType(Nullability.nonNullable);
+    FunctionType instantiatedFunctionType = Substitution.fromPairs(
+            tearOffFunctionType.typeParameters, constant.types)
+        .substituteType(tearOffFunctionType) as FunctionType;
+    Constant functionTypeConstant =
+        TypeLiteralConstant(instantiatedFunctionType);
+    ensureConstant(functionTypeConstant);
+    ClosureImplementation tearOffClosure =
+        translator.getTearOffClosure(tearOffProcedure);
+    int positionalCount = tearOffConstant.function.positionalParameters.length;
+    List<String> names =
+        tearOffConstant.function.namedParameters.map((p) => p.name!).toList();
+    ClosureRepresentation representation = translator.closureLayouter
+        .getClosureRepresentation(0, positionalCount, names)!;
+    w.StructType struct = representation.closureStruct;
+    w.RefType type = w.RefType.def(struct, nullable: false);
+    return createConstant(constant, type, (function, b) {
+      ClassInfo info = translator.classInfo[translator.functionClass]!;
+      translator.functions.allocateClass(info.classId);
+
+      w.DefinedFunction makeTrampoline(
+          w.FunctionType signature, w.DefinedFunction tearOffFunction) {
+        assert(tearOffFunction.type.inputs.length ==
+            signature.inputs.length + types.length);
+        w.DefinedFunction function =
+            m.addFunction(signature, "instantiation constant trampoline");
+        w.Instructions b = function.body;
+        b.local_get(function.locals[0]);
+        for (ConstantInfo typeInfo in types) {
+          b.global_get(typeInfo.global);
+        }
+        for (int i = 1; i < signature.inputs.length; i++) {
+          b.local_get(function.locals[i]);
+        }
+        b.call(tearOffFunction);
+        b.end();
+        return function;
       }
-      b.struct_new(translator.closureStructType(parameterCount));
+
+      void fillVtableEntry(int posArgCount, List<String> argNames) {
+        int fieldIndex =
+            representation.fieldIndexForSignature(posArgCount, argNames);
+        int tearOffFieldIndex = tearOffClosure.representation
+            .fieldIndexForSignature(posArgCount, argNames);
+
+        w.FunctionType signature =
+            (representation.vtableStruct.fields[fieldIndex].type as w.RefType)
+                .heapType as w.FunctionType;
+        w.DefinedFunction tearOffFunction = tearOffClosure.functions[
+            tearOffFieldIndex - tearOffClosure.representation.vtableBaseIndex];
+        w.DefinedFunction function =
+            translator.globals.isDummyFunction(tearOffFunction)
+                ? translator.globals.getDummyFunction(signature)
+                : makeTrampoline(signature, tearOffFunction);
+        b.ref_func(function);
+      }
+
+      void makeVtable() {
+        for (int posArgCount = 0;
+            posArgCount <= positionalCount;
+            posArgCount++) {
+          fillVtableEntry(posArgCount, const []);
+        }
+        for (NameCombination combination in representation.nameCombinations) {
+          fillVtableEntry(positionalCount, combination.names);
+        }
+        b.struct_new(representation.vtableStruct);
+      }
+
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      b.global_get(translator.globals.dummyGlobal); // Dummy context
+      makeVtable();
+      constants.instantiateConstant(
+          function, b, functionTypeConstant, this.types.nonNullableTypeType);
+      b.struct_new(struct);
     });
   }
 
@@ -829,8 +840,9 @@
     w.RefType stringType =
         translator.classInfo[translator.coreTypes.stringClass]!.nonNullableType;
     StringConstant nameConstant = StringConstant(constant.name);
-    ensureConstant(nameConstant);
-    return createConstant(constant, info.nonNullableType, (function, b) {
+    bool lazy = ensureConstant(nameConstant)?.isLazy ?? false;
+    return createConstant(constant, info.nonNullableType, lazy: lazy,
+        (function, b) {
       b.i32_const(info.classId);
       b.i32_const(initialIdentityHash);
       constants.instantiateConstant(function, b, nameConstant, stringType);
diff --git a/pkg/dart2wasm/lib/dispatch_table.dart b/pkg/dart2wasm/lib/dispatch_table.dart
index 68bf8ad..2087d81 100644
--- a/pkg/dart2wasm/lib/dispatch_table.dart
+++ b/pkg/dart2wasm/lib/dispatch_table.dart
@@ -38,9 +38,10 @@
 
   w.Module get m => translator.m;
 
-  String get name => paramInfo.member.name.text;
+  String get name => paramInfo.member!.name.text;
 
-  bool get alive => callCount > 0 && targetCount > 1 || calledDynamically;
+  bool get alive =>
+      calledDynamically ? targetCount > 0 : callCount > 0 && targetCount > 1;
 
   int get sortWeight => classIds.length * 10 + callCount;
 
@@ -60,6 +61,7 @@
         List.generate(1 + paramInfo.paramCount, (_) => {});
     List<Set<ClassInfo>> outputSets = List.generate(returnCount, (_) => {});
     List<bool> inputNullable = List.filled(1 + paramInfo.paramCount, false);
+    List<bool> ensureBoxed = List.filled(1 + paramInfo.paramCount, false);
     List<bool> outputNullable = List.filled(returnCount, false);
     targets.forEach((id, target) {
       ClassInfo receiver = translator.classes[id];
@@ -99,11 +101,14 @@
       }
       assert(returns.length <= outputSets.length);
       inputSets[0].add(receiver);
+      ensureBoxed[0] = true;
       for (int i = 0; i < positional.length; i++) {
         DartType type = positional[i];
         inputSets[1 + i]
             .add(translator.classInfo[translator.classForType(type)]!);
         inputNullable[1 + i] |= type.isPotentiallyNullable;
+        ensureBoxed[1 + i] |=
+            paramInfo.positional[i] == ParameterInfo.defaultValueSentinel;
       }
       for (String name in named.keys) {
         int i = nameIndex[name]!;
@@ -111,6 +116,8 @@
         inputSets[1 + i]
             .add(translator.classInfo[translator.classForType(type)]!);
         inputNullable[1 + i] |= type.isPotentiallyNullable;
+        ensureBoxed[1 + i] |=
+            paramInfo.named[name] == ParameterInfo.defaultValueSentinel;
       }
       for (int i = 0; i < returnCount; i++) {
         if (i < returns.length) {
@@ -128,8 +135,8 @@
     List<w.ValueType> inputs = List.generate(
         inputSets.length,
         (i) => translator.typeForInfo(
-                upperBound(inputSets[i]), inputNullable[i], ensureBoxed: i == 0)
-            as w.ValueType);
+            upperBound(inputSets[i]), inputNullable[i],
+            ensureBoxed: ensureBoxed[i]) as w.ValueType);
     if (name == '==') {
       // == can't be called with null
       inputs[1] = inputs[1].withNullability(false);
diff --git a/pkg/dart2wasm/lib/ffi_native_transformer.dart b/pkg/dart2wasm/lib/ffi_native_transformer.dart
new file mode 100644
index 0000000..b2e02f4
--- /dev/null
+++ b/pkg/dart2wasm/lib/ffi_native_transformer.dart
@@ -0,0 +1,395 @@
+// Copyright (c) 2022, 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';
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/core_types.dart';
+import 'package:kernel/library_index.dart' show LibraryIndex;
+import 'package:kernel/reference_from_index.dart' show ReferenceFromIndex;
+import 'package:kernel/target/targets.dart' show DiagnosticReporter;
+import 'package:vm/transformations/ffi/common.dart' show NativeType;
+import 'package:vm/transformations/ffi/native.dart' show FfiNativeTransformer;
+
+/// Transform `@FfiNative`-annotated functions to convert Dart arguments to
+/// Wasm arguments expected by the FFI functions, and convert the Wasm function
+/// return value to the Dart value.
+///
+/// Add a new `external` procedure for the Wasm import.
+///
+/// Example:
+///
+///   @FfiNative<Int8 Function(Int8, Int8)>("ffi.addInt8")
+///   external int addInt8(int a, int b);
+///
+/// Converted to:
+///
+///   external static wasm::WasmI32 addInt8_$import(wasm::WasmI32 a, wasm::WasmI32 b);
+///
+///   static int addInt8(int a, int b) =>
+///     addInt8_$import(WasmI32::int8FromInt(a), WasmI32::int8FromInt(b)).toIntSigned();
+///
+void transformLibraries(
+    Component component,
+    CoreTypes coreTypes,
+    ClassHierarchy hierarchy,
+    List<Library> libraries,
+    DiagnosticReporter diagnosticReporter,
+    ReferenceFromIndex? referenceFromIndex) {
+  final index = LibraryIndex(component, [
+    'dart:core',
+    'dart:ffi',
+    'dart:_internal',
+    'dart:typed_data',
+    'dart:nativewrappers',
+    'dart:wasm'
+  ]);
+  final transformer = WasmFfiNativeTransformer(
+      index, coreTypes, hierarchy, diagnosticReporter, referenceFromIndex);
+  libraries.forEach(transformer.visitLibrary);
+}
+
+class WasmFfiNativeTransformer extends FfiNativeTransformer {
+  final Class ffiNativeClass;
+  final Class nativeFunctionClass;
+  final Class wasmI32Class;
+  final Class wasmI64Class;
+  final Class wasmF32Class;
+  final Class wasmF64Class;
+  final Class wasmEqRefClass;
+  final Field ffiNativeNameField;
+  final Field ffiNativeIsLeafField;
+  final Procedure wasmI32FromInt;
+  final Procedure wasmI32Int8FromInt;
+  final Procedure wasmI32Uint8FromInt;
+  final Procedure wasmI32Int16FromInt;
+  final Procedure wasmI32Uint16FromInt;
+  final Procedure wasmI32FromBool;
+  final Procedure wasmI32ToIntSigned;
+  final Procedure wasmI32ToIntUnsigned;
+  final Procedure wasmI32ToBool;
+  final Procedure wasmI64FromInt;
+  final Procedure wasmI64ToInt;
+  final Procedure wasmF32FromDouble;
+  final Procedure wasmF32ToDouble;
+  final Procedure wasmF64FromDouble;
+  final Procedure wasmF64ToDouble;
+
+  WasmFfiNativeTransformer(
+      LibraryIndex index,
+      CoreTypes coreTypes,
+      ClassHierarchy hierarchy,
+      DiagnosticReporter diagnosticReporter,
+      ReferenceFromIndex? referenceFromIndex)
+      : ffiNativeClass = index.getClass('dart:ffi', 'FfiNative'),
+        nativeFunctionClass = index.getClass('dart:ffi', 'NativeFunction'),
+        wasmI32Class = index.getClass('dart:wasm', 'WasmI32'),
+        wasmI64Class = index.getClass('dart:wasm', 'WasmI64'),
+        wasmF32Class = index.getClass('dart:wasm', 'WasmF32'),
+        wasmF64Class = index.getClass('dart:wasm', 'WasmF64'),
+        wasmEqRefClass = index.getClass('dart:wasm', 'WasmEqRef'),
+        ffiNativeNameField =
+            index.getField('dart:ffi', 'FfiNative', 'nativeName'),
+        ffiNativeIsLeafField =
+            index.getField('dart:ffi', 'FfiNative', 'isLeaf'),
+        wasmI32FromInt = index.getProcedure('dart:wasm', 'WasmI32', 'fromInt'),
+        wasmI32Int8FromInt =
+            index.getProcedure('dart:wasm', 'WasmI32', 'int8FromInt'),
+        wasmI32Uint8FromInt =
+            index.getProcedure('dart:wasm', 'WasmI32', 'uint8FromInt'),
+        wasmI32Int16FromInt =
+            index.getProcedure('dart:wasm', 'WasmI32', 'int16FromInt'),
+        wasmI32Uint16FromInt =
+            index.getProcedure('dart:wasm', 'WasmI32', 'uint16FromInt'),
+        wasmI32FromBool =
+            index.getProcedure('dart:wasm', 'WasmI32', 'fromBool'),
+        wasmI32ToIntSigned =
+            index.getProcedure('dart:wasm', 'WasmI32', 'toIntSigned'),
+        wasmI32ToIntUnsigned =
+            index.getProcedure('dart:wasm', 'WasmI32', 'toIntUnsigned'),
+        wasmI32ToBool = index.getProcedure('dart:wasm', 'WasmI32', 'toBool'),
+        wasmI64ToInt = index.getProcedure('dart:wasm', 'WasmI64', 'toInt'),
+        wasmI64FromInt = index.getProcedure('dart:wasm', 'WasmI64', 'fromInt'),
+        wasmF32FromDouble =
+            index.getProcedure('dart:wasm', 'WasmF32', 'fromDouble'),
+        wasmF32ToDouble =
+            index.getProcedure('dart:wasm', 'WasmF32', 'toDouble'),
+        wasmF64FromDouble =
+            index.getProcedure('dart:wasm', 'WasmF64', 'fromDouble'),
+        wasmF64ToDouble =
+            index.getProcedure('dart:wasm', 'WasmF64', 'toDouble'),
+        super(index, coreTypes, hierarchy, diagnosticReporter,
+            referenceFromIndex);
+
+  @override
+  visitProcedure(Procedure node) {
+    // Only transform functions that are external and have FfiNative annotation:
+    //   @FfiNative<Double Function(Double)>('Math_sqrt')
+    //   external double _square_root(double x);
+    final ffiNativeAnnotation = tryGetFfiNativeAnnotation(node);
+    if (ffiNativeAnnotation == null) {
+      return node;
+    }
+
+    // Original function should be external and without body
+    assert(node.isExternal == true);
+    assert(node.function.body == null);
+
+    final ffiConstant = ffiNativeAnnotation.constant as InstanceConstant;
+    final ffiFunctionType = ffiConstant.typeArguments[0] as FunctionType;
+    final nativeFunctionName = ffiConstant
+        .fieldValues[ffiNativeNameField.fieldReference] as StringConstant;
+    final isLeaf = (ffiConstant.fieldValues[ffiNativeIsLeafField.fieldReference]
+            as BoolConstant)
+        .value;
+
+    final dartFunctionType =
+        node.function.computeThisFunctionType(Nullability.nonNullable);
+
+    final wrappedDartFunctionType = checkFfiType(node, dartFunctionType,
+        ffiFunctionType, isLeaf, ffiNativeAnnotation.fileOffset);
+
+    if (wrappedDartFunctionType == null) {
+      // It's OK to continue because the diagnostics issued will cause
+      // compilation to fail. By continuing, we can report more diagnostics
+      // before compilation ends.
+      return node;
+    }
+
+    // Create a new extern static procedure for the import. The original
+    // function will be calling this one with arguments converted to right Wasm
+    // types, and it will convert the return value to the right Dart type.
+    final wasmImportName = Name('${node.name.text}_\$import', currentLibrary);
+    final wasmImportPragma =
+        ConstantExpression(InstanceConstant(pragmaClass.reference, [], {
+      pragmaName.fieldReference: StringConstant("wasm:import"),
+      pragmaOptions.fieldReference: nativeFunctionName,
+    }));
+
+    // For the imported function arguments, use names in the Dart function but
+    // types in the FFI declaration
+    final List<VariableDeclaration> wasmImportProcedureArgs = [];
+    for (int i = 0; i < ffiFunctionType.positionalParameters.length; i += 1) {
+      final argWasmType =
+          _convertFfiTypeToWasmType(ffiFunctionType.positionalParameters[i]);
+      if (argWasmType != null) {
+        wasmImportProcedureArgs.add(VariableDeclaration(
+          node.function.positionalParameters[i].name!,
+          type: argWasmType,
+        ));
+      }
+    }
+
+    final retWasmType = _convertFfiTypeToWasmType(ffiFunctionType.returnType);
+    final retWasmType_ = retWasmType ?? VoidType();
+
+    final wasmImportProcedure = Procedure(
+        wasmImportName,
+        ProcedureKind.Method,
+        FunctionNode(null,
+            positionalParameters: wasmImportProcedureArgs,
+            returnType: retWasmType_),
+        fileUri: currentLibrary.fileUri,
+        isExternal: true,
+        isStatic: true,
+        isSynthetic: true)
+      ..fileOffset = node.fileOffset
+      ..isNonNullableByDefault = true;
+    wasmImportProcedure.addAnnotation(wasmImportPragma);
+    currentLibrary.addProcedure(wasmImportProcedure);
+
+    // Update the original procedure to call the Wasm import, converting
+    // arguments and return value
+    node.isExternal = false;
+    node.annotations.remove(ffiNativeAnnotation);
+
+    // Convert arguments
+    assert(ffiFunctionType.positionalParameters.length ==
+        node.function.positionalParameters.length);
+
+    final ffiCallArgs = <Expression>[];
+
+    for (int i = 0; i < node.function.positionalParameters.length; i += 1) {
+      final ffiArgumentType = ffiFunctionType.positionalParameters[i];
+
+      final ffiValue = _dartValueToFfiValue(
+          ffiArgumentType, VariableGet(node.function.positionalParameters[i]));
+
+      if (ffiValue != null) {
+        ffiCallArgs.add(ffiValue);
+      }
+    }
+
+    // Convert return value
+    node.function.body = ReturnStatement(_ffiValueToDartValue(
+        ffiFunctionType.returnType,
+        StaticInvocation(wasmImportProcedure, Arguments(ffiCallArgs))));
+
+    return node;
+  }
+
+  /// Converts a Dart value to the corresponding Wasm FFI value according to
+  /// emscripten ABI.
+  ///
+  /// For example, converts a Dart `int` for an `Uint8` native type to Wasm I32
+  /// and masks high bits.
+  ///
+  /// Returns `null` for [Void] values.
+  Expression? _dartValueToFfiValue(DartType ffiType, Expression expr) {
+    final InterfaceType abiType_ = ffiType as InterfaceType;
+    final NativeType abiTypeNativeType = getType(abiType_.classNode)!;
+
+    switch (abiTypeNativeType) {
+      case NativeType.kInt8:
+        return StaticInvocation(wasmI32Int8FromInt, Arguments([expr]));
+
+      case NativeType.kUint8:
+        return StaticInvocation(wasmI32Uint8FromInt, Arguments([expr]));
+
+      case NativeType.kInt16:
+        return StaticInvocation(wasmI32Int16FromInt, Arguments([expr]));
+
+      case NativeType.kUint16:
+        return StaticInvocation(wasmI32Uint16FromInt, Arguments([expr]));
+
+      case NativeType.kInt32:
+      case NativeType.kUint32:
+        return StaticInvocation(wasmI32FromInt, Arguments([expr]));
+
+      case NativeType.kInt64:
+      case NativeType.kUint64:
+        return StaticInvocation(wasmI64FromInt, Arguments([expr]));
+
+      case NativeType.kFloat:
+        return StaticInvocation(wasmF32FromDouble, Arguments([expr]));
+
+      case NativeType.kDouble:
+        return StaticInvocation(wasmF64FromDouble, Arguments([expr]));
+
+      case NativeType.kPointer:
+      case NativeType.kStruct:
+        return expr;
+
+      case NativeType.kBool:
+        return StaticInvocation(wasmI32FromBool, Arguments([expr]));
+
+      case NativeType.kVoid:
+        return null;
+
+      case NativeType.kHandle:
+      case NativeType.kNativeDouble:
+      case NativeType.kNativeFunction:
+      case NativeType.kNativeInteger:
+      case NativeType.kNativeType:
+      case NativeType.kOpaque:
+        throw '_dartValueToFfiValue: $abiTypeNativeType cannot be converted';
+    }
+  }
+
+  /// Converts a Wasm FFI value to the corresponding Dart value according to
+  /// emscripten ABI.
+  ///
+  /// For example, converts an `Bool` native type to Dart bool by checking the
+  /// Wasm I32 value for the bool: 0 means `false`, non-0 means `true`.
+  Expression _ffiValueToDartValue(DartType ffiType, Expression expr) {
+    final InterfaceType ffiType_ = ffiType as InterfaceType;
+    final NativeType nativeType = getType(ffiType_.classNode)!;
+
+    Expression instanceInvocation(Procedure converter, Expression receiver) =>
+        InstanceInvocation(
+          InstanceAccessKind.Instance,
+          receiver,
+          converter.name,
+          Arguments([]),
+          interfaceTarget: converter,
+          functionType: converter.getterType as FunctionType,
+        );
+
+    switch (nativeType) {
+      case NativeType.kInt8:
+      case NativeType.kInt16:
+      case NativeType.kInt32:
+        return instanceInvocation(wasmI32ToIntSigned, expr);
+
+      case NativeType.kUint8:
+      case NativeType.kUint16:
+      case NativeType.kUint32:
+        return instanceInvocation(wasmI32ToIntUnsigned, expr);
+
+      case NativeType.kPointer:
+      case NativeType.kVoid:
+      case NativeType.kStruct:
+        return expr;
+
+      case NativeType.kUint64:
+      case NativeType.kInt64:
+        return instanceInvocation(wasmI64ToInt, expr);
+
+      case NativeType.kFloat:
+        return instanceInvocation(wasmF32ToDouble, expr);
+
+      case NativeType.kDouble:
+        return instanceInvocation(wasmF64ToDouble, expr);
+
+      case NativeType.kBool:
+        return instanceInvocation(wasmI32ToBool, expr);
+
+      case NativeType.kHandle:
+      case NativeType.kNativeDouble:
+      case NativeType.kNativeFunction:
+      case NativeType.kNativeInteger:
+      case NativeType.kNativeType:
+      case NativeType.kOpaque:
+        throw '_ffiValueToDartValue: $nativeType cannot be converted';
+    }
+  }
+
+  /// Converts an FFI type like `InterfaceType(Int8)` to the corresponding Wasm
+  /// type (`InterfaceType(WasmI32)`) according to emscripten Wasm ABI.
+  ///
+  /// Returns `null` for [Void]. Other types are converted to their
+  /// [InterfaceType]s.
+  DartType? _convertFfiTypeToWasmType(DartType ffiType) {
+    if (ffiType is! InterfaceType) {
+      throw 'Native type is not an interface type: $ffiType';
+    }
+    final Class nativeClass = ffiType.classNode;
+    final NativeType nativeType_ = getType(nativeClass)!;
+
+    switch (nativeType_) {
+      case NativeType.kInt8:
+      case NativeType.kUint8:
+      case NativeType.kInt16:
+      case NativeType.kUint16:
+      case NativeType.kInt32:
+      case NativeType.kUint32:
+      case NativeType.kBool:
+        return InterfaceType(wasmI32Class, Nullability.nonNullable);
+
+      case NativeType.kInt64:
+      case NativeType.kUint64:
+        return InterfaceType(wasmI64Class, Nullability.nonNullable);
+
+      case NativeType.kFloat:
+        return InterfaceType(wasmF32Class, Nullability.nonNullable);
+
+      case NativeType.kDouble:
+        return InterfaceType(wasmF64Class, Nullability.nonNullable);
+
+      case NativeType.kPointer:
+      case NativeType.kStruct:
+        return ffiType;
+
+      case NativeType.kVoid:
+        return null;
+
+      case NativeType.kHandle:
+      case NativeType.kNativeDouble:
+      case NativeType.kNativeFunction:
+      case NativeType.kNativeInteger:
+      case NativeType.kNativeType:
+      case NativeType.kOpaque:
+        throw '_convertFfiTypeToWasmType: $nativeType_ cannot be converted';
+    }
+  }
+}
diff --git a/pkg/dart2wasm/lib/functions.dart b/pkg/dart2wasm/lib/functions.dart
index 10bdcd5..7e73b87 100644
--- a/pkg/dart2wasm/lib/functions.dart
+++ b/pkg/dart2wasm/lib/functions.dart
@@ -132,7 +132,7 @@
     w.FunctionType ftype = m.addFunctionType(
         [...outer.type.inputs, asyncStackType],
         [translator.topInfo.nullableType]);
-    return m.addFunction(ftype, "${outer.functionName} (inner)");
+    return m.addFunction(ftype, "${outer.functionName} inner");
   }
 
   void activateSelector(SelectorInfo selector) {
@@ -219,12 +219,14 @@
     List<w.ValueType> typeParameters = List.filled(typeParamCount,
         translator.classInfo[translator.typeClass]!.nonNullableType);
 
-    // The JS embedder will not accept Wasm struct types as parameter or return
-    // types for functions called from JS. We need to use eqref instead.
+    // The only reference types allowed as parameters and returns on imported
+    // or exported functions for JS interop are `externref` and `funcref`.
     w.ValueType adjustExternalType(w.ValueType type) {
-      if (isImportOrExport &&
-          type.isSubtypeOf(translator.topInfo.nullableType)) {
-        return w.RefType.eq(nullable: type.nullable);
+      if (isImportOrExport && type is w.RefType) {
+        if (type.heapType.isSubtypeOf(w.HeapType.func)) {
+          return w.RefType.func(nullable: true);
+        }
+        return w.RefType.extern(nullable: true);
       }
       return type;
     }
diff --git a/pkg/dart2wasm/lib/globals.dart b/pkg/dart2wasm/lib/globals.dart
index dd0bc36..24146ea 100644
--- a/pkg/dart2wasm/lib/globals.dart
+++ b/pkg/dart2wasm/lib/globals.dart
@@ -15,6 +15,7 @@
   final Map<Field, w.Global> globals = {};
   final Map<Field, w.BaseFunction> globalInitializers = {};
   final Map<Field, w.Global> globalInitializedFlag = {};
+  final Map<w.FunctionType, w.DefinedFunction> dummyFunctions = {};
   final Map<w.HeapType, w.DefinedGlobal> dummyValues = {};
   late final w.DefinedGlobal dummyGlobal;
 
@@ -37,6 +38,23 @@
     dummyValues[w.HeapType.data] = dummyGlobal;
   }
 
+  /// Provide a dummy function with the given signature. Used for empty entries
+  /// in vtables and for dummy values of function reference type.
+  w.DefinedFunction getDummyFunction(w.FunctionType type) {
+    return dummyFunctions.putIfAbsent(type, () {
+      w.DefinedFunction function = m.addFunction(type, "#dummy function $type");
+      w.Instructions b = function.body;
+      b.unreachable();
+      b.end();
+      return function;
+    });
+  }
+
+  /// Returns whether the given function was provided by [getDummyFunction].
+  bool isDummyFunction(w.BaseFunction function) {
+    return dummyFunctions[function.type] == function;
+  }
+
   w.Global? prepareDummyValue(w.ValueType type) {
     if (type is w.RefType && !type.nullable) {
       w.HeapType heapType = type.heapType;
@@ -60,14 +78,9 @@
           ib.array_new_fixed(heapType, 0);
           ib.end();
         } else if (heapType is w.FunctionType) {
-          w.DefinedFunction function =
-              m.addFunction(heapType, "#dummy function $heapType");
-          w.Instructions b = function.body;
-          b.unreachable();
-          b.end();
           global = m.addGlobal(w.GlobalType(type, mutable: false));
           w.Instructions ib = global.initializer;
-          ib.ref_func(function);
+          ib.ref_func(getDummyFunction(heapType));
           ib.end();
         }
         dummyValues[heapType] = global!;
@@ -78,8 +91,10 @@
     return null;
   }
 
+  /// Produce a dummy value of any Wasm type. For non-nullable reference types,
+  /// the value is constructed in a global initializer, and the instantiation
+  /// of the value merely reads the global.
   void instantiateDummyValue(w.Instructions b, w.ValueType type) {
-    w.Global? global = prepareDummyValue(type);
     switch (type) {
       case w.NumType.i32:
         b.i32_const(0);
@@ -99,7 +114,7 @@
           if (type.nullable) {
             b.ref_null(heapType);
           } else {
-            b.global_get(global!);
+            b.global_get(prepareDummyValue(type)!);
           }
         } else {
           throw "Unsupported global type ${type} ($type)";
@@ -114,7 +129,6 @@
     if (init is IntLiteral) return IntConstant(init.value);
     if (init is DoubleLiteral) return DoubleConstant(init.value);
     if (init is BoolLiteral) return BoolConstant(init.value);
-    if (translator.options.lazyConstants) return null;
     if (init is StringLiteral) return StringConstant(init.value);
     if (init is ConstantExpression) return init.constant;
     return null;
@@ -127,9 +141,9 @@
     return globals.putIfAbsent(variable, () {
       w.ValueType type = translator.translateType(variable.type);
       Constant? init = _getConstantInitializer(variable);
-      if (init != null) {
+      if (init != null &&
+          !(translator.constants.ensureConstant(init)?.isLazy ?? false)) {
         // Initialized to a constant
-        translator.constants.ensureConstant(init);
         w.DefinedGlobal global =
             m.addGlobal(w.GlobalType(type, mutable: !variable.isFinal));
         translator.constants
diff --git a/pkg/dart2wasm/lib/intrinsics.dart b/pkg/dart2wasm/lib/intrinsics.dart
index bffa742..97efd6b 100644
--- a/pkg/dart2wasm/lib/intrinsics.dart
+++ b/pkg/dart2wasm/lib/intrinsics.dart
@@ -431,17 +431,21 @@
       w.StorageType receiverType = translator.builtinTypes[cls]!;
       switch (receiverType) {
         case w.NumType.i32:
-          assert(name == "toIntSigned" || name == "toIntUnsigned");
           codeGen.wrap(receiver, w.NumType.i32);
           switch (name) {
             case "toIntSigned":
               b.i64_extend_i32_s();
-              break;
+              return w.NumType.i64;
             case "toIntUnsigned":
               b.i64_extend_i32_u();
-              break;
+              return w.NumType.i64;
+            case "toBool":
+              b.i32_const(0);
+              b.i32_ne();
+              return w.NumType.i32;
+            default:
+              throw 'Unknown i32 conversion to $receiverType';
           }
-          return w.NumType.i64;
         case w.NumType.i64:
           assert(name == "toInt");
           codeGen.wrap(receiver, w.NumType.i64);
@@ -712,6 +716,13 @@
           return translator.types.makeTypeRulesSubstitutions(b);
         case "_getTypeNames":
           return translator.types.makeTypeNames(b);
+        case "_getFunctionTypeRuntimeType":
+          Expression object = node.arguments.positional[0];
+          w.StructType closureBase =
+              translator.closureLayouter.closureBaseStruct;
+          codeGen.wrap(object, w.RefType.def(closureBase, nullable: true));
+          b.struct_get(closureBase, FieldIndex.closureRuntimeType);
+          return translator.types.typeClassInfo.nonNullableType;
         case "_getInterfaceTypeRuntimeType":
           Expression object = node.arguments.positional[0];
           Expression typeArguments = node.arguments.positional[1];
@@ -991,9 +1002,40 @@
       w.StorageType targetType = translator.builtinTypes[cls]!;
       switch (targetType) {
         case w.NumType.i32:
-          codeGen.wrap(value, w.NumType.i64);
-          b.i32_wrap_i64();
-          return w.NumType.i32;
+          switch (name) {
+            case "fromInt":
+              codeGen.wrap(value, w.NumType.i64);
+              b.i32_wrap_i64();
+              return w.NumType.i32;
+            case "int8FromInt":
+              codeGen.wrap(value, w.NumType.i64);
+              b.i32_wrap_i64();
+              b.i32_extend8_s();
+              return w.NumType.i32;
+            case "uint8FromInt":
+              codeGen.wrap(value, w.NumType.i64);
+              b.i32_wrap_i64();
+              b.i32_const(0xFF);
+              b.i32_and();
+              return w.NumType.i32;
+            case "int16FromInt":
+              codeGen.wrap(value, w.NumType.i64);
+              b.i32_wrap_i64();
+              b.i32_extend16_s();
+              return w.NumType.i32;
+            case "uint16FromInt":
+              codeGen.wrap(value, w.NumType.i64);
+              b.i32_wrap_i64();
+              b.i32_const(0xFFFF);
+              b.i32_and();
+              return w.NumType.i32;
+            case "fromBool":
+              codeGen.wrap(value, w.NumType.i32);
+              return w.NumType.i32;
+            default:
+              throw 'Unhandled WasmI32 factory: $name';
+          }
+
         case w.NumType.i64:
           codeGen.wrap(value, w.NumType.i64);
           return w.NumType.i64;
diff --git a/pkg/dart2wasm/lib/param_info.dart b/pkg/dart2wasm/lib/param_info.dart
index 182af47..2d2ad28 100644
--- a/pkg/dart2wasm/lib/param_info.dart
+++ b/pkg/dart2wasm/lib/param_info.dart
@@ -9,7 +9,7 @@
 /// Information about optional parameters and their default values for a
 /// member or a set of members belonging to the same override group.
 class ParameterInfo {
-  final Member member;
+  final Member? member;
   int typeParamCount = 0;
   late final List<Constant?> positional;
   late final Map<String, Constant?> named;
@@ -20,6 +20,12 @@
     for (int i = 0; i < names.length; i++) names[i]: positional.length + i
   };
 
+  /// A special marker value to use for default parameter values to indicate
+  /// that different implementations within the same selector have different
+  /// default values.
+  static final Constant defaultValueSentinel =
+      UnevaluatedConstant(InvalidExpression("Default value sentinel"));
+
   int get paramCount => positional.length + named.length;
 
   static Constant? defaultValue(VariableDeclaration param) {
@@ -34,13 +40,13 @@
   }
 
   ParameterInfo.fromMember(Reference target) : member = target.asMember {
-    FunctionNode? function = member.function;
+    FunctionNode? function = member!.function;
     if (target.isTearOffReference) {
       positional = [];
       named = {};
     } else if (function != null) {
       typeParamCount = (member is Constructor
-              ? member.enclosingClass!.typeParameters
+              ? member!.enclosingClass!.typeParameters
               : function.typeParameters)
           .length;
       positional = List.generate(function.positionalParameters.length, (i) {
@@ -59,6 +65,19 @@
     }
   }
 
+  ParameterInfo.fromLocalFunction(FunctionNode function) : member = null {
+    typeParamCount = function.typeParameters.length;
+    positional = List.generate(function.positionalParameters.length, (i) {
+      // A required parameter has no default value.
+      if (i < function.requiredParameterCount) return null;
+      return defaultValue(function.positionalParameters[i]);
+    });
+    named = {
+      for (VariableDeclaration param in function.namedParameters)
+        param.name!: defaultValue(param)
+    };
+  }
+
   void merge(ParameterInfo other) {
     assert(typeParamCount == other.typeParamCount);
     for (int i = 0; i < other.positional.length; i++) {
@@ -69,9 +88,8 @@
           positional[i] = other.positional[i];
         } else if (other.positional[i] != null) {
           if (positional[i] != other.positional[i]) {
-            print("Mismatching default value for parameter $i: "
-                "${member}: ${positional[i]} vs "
-                "${other.member}: ${other.positional[i]}");
+            // Default value differs between implementations.
+            positional[i] = defaultValueSentinel;
           }
         }
       }
@@ -83,9 +101,8 @@
         named[name] = otherValue;
       } else if (otherValue != null) {
         if (value != otherValue) {
-          print("Mismatching default value for parameter '$name': "
-              "${member}: ${value} vs "
-              "${other.member}: ${otherValue}");
+          // Default value differs between implementations.
+          named[name] = defaultValueSentinel;
         }
       }
     }
diff --git a/pkg/dart2wasm/lib/target.dart b/pkg/dart2wasm/lib/target.dart
index 6b1657a..43c3cc1 100644
--- a/pkg/dart2wasm/lib/target.dart
+++ b/pkg/dart2wasm/lib/target.dart
@@ -8,6 +8,7 @@
 import 'package:_js_interop_checks/src/js_interop.dart' as jsInteropHelper;
 import 'package:_js_interop_checks/src/transformations/js_util_wasm_optimizer.dart';
 import 'package:_js_interop_checks/src/transformations/static_interop_class_eraser.dart';
+import 'package:_js_interop_checks/src/transformations/static_interop_mock_creator.dart';
 import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/clone.dart';
@@ -15,6 +16,7 @@
 import 'package:kernel/reference_from_index.dart';
 import 'package:kernel/target/changed_structure_notifier.dart';
 import 'package:kernel/target/targets.dart';
+import 'package:kernel/type_environment.dart';
 import 'package:vm/transformations/mixin_full_resolution.dart'
     as transformMixins show transformLibraries;
 import 'package:vm/transformations/ffi/common.dart' as ffiHelper
@@ -24,6 +26,7 @@
 import 'package:vm/transformations/ffi/use_sites.dart' as transformFfiUseSites
     show transformLibraries;
 
+import 'package:dart2wasm/ffi_native_transformer.dart' as wasmFfiNativeTrans;
 import 'package:dart2wasm/transformers.dart' as wasmTrans;
 
 class WasmTarget extends Target {
@@ -94,7 +97,7 @@
       Component component,
       CoreTypes coreTypes,
       ClassHierarchy hierarchy,
-      List<Library> interopDependentLibraries,
+      Set<Library> interopDependentLibraries,
       DiagnosticReporter diagnosticReporter,
       ReferenceFromIndex? referenceFromIndex) {
     _nativeClasses ??= JsInteropChecks.getNativeClasses(component);
@@ -102,14 +105,25 @@
         coreTypes,
         diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>,
         _nativeClasses!);
+    final staticInteropMockCreator = StaticInteropMockCreator(
+        TypeEnvironment(coreTypes, hierarchy), diagnosticReporter);
     final jsUtilOptimizer = JsUtilWasmOptimizer(coreTypes, hierarchy);
+    // Cache extensions for entire component before creating mock.
+    for (Library library in interopDependentLibraries) {
+      staticInteropMockCreator.processExtensions(library);
+    }
+    for (Library library in interopDependentLibraries) {
+      jsInteropChecks.visitLibrary(library);
+      staticInteropMockCreator.visitLibrary(library);
+      jsUtilOptimizer.visitLibrary(library);
+    }
+    // Do the erasure after any possible mock creation to avoid erasing types
+    // that need to be used during mock conformance checking.
     final staticInteropClassEraser = StaticInteropClassEraser(
         coreTypes, referenceFromIndex,
         libraryForJavaScriptObject: 'dart:_js_helper',
         classNameOfJavaScriptObject: 'JSValue');
     for (Library library in interopDependentLibraries) {
-      jsInteropChecks.visitLibrary(library);
-      jsUtilOptimizer.visitLibrary(library);
       staticInteropClassEraser.visitLibrary(library);
     }
   }
@@ -136,12 +150,12 @@
       ReferenceFromIndex? referenceFromIndex,
       {void logger(String msg)?,
       ChangedStructureNotifier? changedStructureNotifier}) {
-    List<Library> transitiveImportingJSInterop = [
+    Set<Library> transitiveImportingJSInterop = {
       ...?jsInteropHelper.calculateTransitiveImportsOfJsInteropIfUsed(
           component, Uri.parse("package:js/js.dart")),
       ...?jsInteropHelper.calculateTransitiveImportsOfJsInteropIfUsed(
           component, Uri.parse("dart:_js_annotations"))
-    ];
+    };
     if (transitiveImportingJSInterop.isEmpty) {
       logger?.call("Skipped JS interop transformations");
     } else {
@@ -158,6 +172,8 @@
     if (transitiveImportingDartFfi == null) {
       logger?.call("Skipped ffi transformation");
     } else {
+      wasmFfiNativeTrans.transformLibraries(component, coreTypes, hierarchy,
+          transitiveImportingDartFfi, diagnosticReporter, referenceFromIndex);
       transformFfiDefinitions.transformLibraries(
           component,
           coreTypes,
@@ -247,7 +263,7 @@
       bool isStatic = false,
       bool isConstructor = false,
       bool isTopLevel = false}) {
-    return ConstructorInvocation(
+    return StaticInvocation(
         coreTypes.noSuchMethodErrorDefaultConstructor,
         Arguments(
             [receiver, _instantiateInvocation(coreTypes, name, arguments)]));
diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart
index b832d9c..91bb4a8 100644
--- a/pkg/dart2wasm/lib/translator.dart
+++ b/pkg/dart2wasm/lib/translator.dart
@@ -34,7 +34,6 @@
   bool importSharedMemory = false;
   bool inlining = false;
   int inliningLimit = 3;
-  bool lazyConstants = false;
   bool nameSection = true;
   bool polymorphicSpecialization = false;
   bool printKernel = false;
@@ -138,6 +137,7 @@
   late final Map<w.ValueType, Class> boxedClasses;
 
   // Other parts of the global compiler state.
+  late final ClosureLayouter closureLayouter;
   late final ClassInfoCollector classInfoCollector;
   late final DispatchTable dispatchTable;
   late final Globals globals;
@@ -166,9 +166,8 @@
 
   // Caches for when identical source constructs need a common representation.
   final Map<w.StorageType, w.ArrayType> arrayTypeCache = {};
-  final Map<int, w.StructType> functionTypeCache = {};
   final Map<w.BaseFunction, w.DefinedGlobal> functionRefCache = {};
-  final Map<Procedure, w.DefinedFunction> tearOffFunctionCache = {};
+  final Map<Procedure, ClosureImplementation> tearOffFunctionCache = {};
 
   ClassInfo get topInfo => classes[0];
   ClassInfo get objectInfo => classInfo[coreTypes.objectClass]!;
@@ -179,24 +178,28 @@
         hierarchy =
             ClassHierarchy(component, coreTypes) as ClosedWorldClassHierarchy {
     subtypes = hierarchy.computeSubtypesInformation();
+    closureLayouter = ClosureLayouter(this);
     classInfoCollector = ClassInfoCollector(this);
     dispatchTable = DispatchTable(this);
     functions = FunctionCollector(this);
     types = Types(this);
     dynamics = DynamicDispatcher(this);
 
-    Class Function(String) makeLookup(String libraryName) {
-      Library library =
-          component.libraries.firstWhere((l) => l.name == libraryName);
-      return (name) => library.classes.firstWhere((c) => c.name == name);
+    Library lookupLibrary(String importUriString) => component.libraries
+        .firstWhere((l) => l.importUri == Uri.parse(importUriString));
+
+    Class Function(String) makeLookup(String importUriString) {
+      return (name) => lookupLibrary(importUriString)
+          .classes
+          .firstWhere((c) => c.name == name);
     }
 
-    Class Function(String) lookupCore = makeLookup("dart.core");
-    Class Function(String) lookupCollection = makeLookup("dart.collection");
-    Class Function(String) lookupFfi = makeLookup("dart.ffi");
-    Class Function(String) lookupInternal = makeLookup("dart._internal");
-    Class Function(String) lookupTypedData = makeLookup("dart.typed_data");
-    Class Function(String) lookupWasm = makeLookup("dart.wasm");
+    Class Function(String) lookupCore = makeLookup("dart:core");
+    Class Function(String) lookupCollection = makeLookup("dart:collection");
+    Class Function(String) lookupFfi = makeLookup("dart:ffi");
+    Class Function(String) lookupInternal = makeLookup("dart:_internal");
+    Class Function(String) lookupTypedData = makeLookup("dart:typed_data");
+    Class Function(String) lookupWasm = makeLookup("dart:wasm");
 
     wasmTypesBaseClass = lookupWasm("_WasmBase");
     wasmArrayBaseClass = lookupWasm("_WasmArray");
@@ -250,12 +253,10 @@
         .firstWhere((p) => p.name.text == "callIndirect");
     stackTraceCurrent =
         stackTraceClass.procedures.firstWhere((p) => p.name.text == "current");
-    asyncHelper = component.libraries
-        .firstWhere((l) => l.name == "dart.async")
+    asyncHelper = lookupLibrary("dart:async")
         .procedures
         .firstWhere((p) => p.name.text == "_asyncHelper");
-    awaitHelper = component.libraries
-        .firstWhere((l) => l.name == "dart.async")
+    awaitHelper = lookupLibrary("dart:async")
         .procedures
         .firstWhere((p) => p.name.text == "_awaitHelper");
     stringEquals =
@@ -285,8 +286,7 @@
     hashImmutableIndexNullable = lookupCollection("_HashAbstractImmutableBase")
         .procedures
         .firstWhere((p) => p.name.text == "_indexNullable");
-    isSubtype = component.libraries
-        .firstWhere((l) => l.name == "dart.core")
+    isSubtype = lookupLibrary("dart:core")
         .procedures
         .firstWhere((p) => p.name.text == "_isSubtype");
     objectRuntimeType = lookupCore("Object")
@@ -361,6 +361,7 @@
     voidMarker = w.RefType.def(w.StructType("void"), nullable: true);
 
     dynamics.collect();
+    closureLayouter.collect();
     classInfoCollector.collect();
 
     functions.collectImportsAndExports();
@@ -447,7 +448,6 @@
     }
 
     dispatchTable.output();
-    constants.finalize();
     initFunction.body.end();
 
     for (ConstantInfo info in constants.constantInfo.values) {
@@ -461,10 +461,6 @@
         }
       }
     }
-    if (options.lazyConstants) {
-      _printFunction(constants.oneByteStringFunction, "makeOneByteString");
-      _printFunction(constants.twoByteStringFunction, "makeTwoByteString");
-    }
     _printFunction(initFunction, "init");
 
     return m.encode(emitNameSection: options.nameSection);
@@ -630,11 +626,15 @@
       return topInfo.typeWithNullability(type.isPotentiallyNullable);
     }
     if (type is FunctionType) {
-      if (type.requiredParameterCount != type.positionalParameters.length ||
-          type.namedParameters.isNotEmpty) {
-        throw "Function types with optional parameters not supported: $type";
-      }
-      return w.RefType.def(closureStructType(type.requiredParameterCount),
+      ClosureRepresentation? representation =
+          closureLayouter.getClosureRepresentation(
+              type.typeParameters.length,
+              type.positionalParameters.length,
+              type.namedParameters.map((p) => p.name).toList());
+      return w.RefType.def(
+          representation != null
+              ? representation.closureStruct
+              : classInfo[typeClass]!.struct,
           nullable: type.isPotentiallyNullable);
     }
     throw "Unsupported type ${type.runtimeType}";
@@ -653,28 +653,6 @@
         () => m.addArrayType("Array<$name>", elementType: w.FieldType(type)));
   }
 
-  w.StructType closureStructType(int parameterCount) {
-    return functionTypeCache.putIfAbsent(parameterCount, () {
-      ClassInfo info = classInfo[functionClass]!;
-      w.StructType struct = m.addStructType("Function$parameterCount",
-          fields: info.struct.fields, superType: info.struct);
-      assert(struct.fields.length == FieldIndex.closureFunction);
-      struct.fields.add(w.FieldType(
-          w.RefType.def(closureFunctionType(parameterCount), nullable: false),
-          mutable: false));
-      return struct;
-    });
-  }
-
-  w.FunctionType closureFunctionType(int parameterCount) {
-    return m.addFunctionType([
-      w.RefType.data(nullable: false),
-      ...List<w.ValueType>.filled(parameterCount, topInfo.nullableType)
-    ], [
-      topInfo.nullableType
-    ]);
-  }
-
   w.DefinedGlobal makeFunctionRef(w.BaseFunction f) {
     return functionRefCache.putIfAbsent(f, () {
       w.DefinedGlobal global = m.addGlobal(
@@ -685,42 +663,150 @@
     });
   }
 
-  w.DefinedFunction getTearOffFunction(Procedure member) {
+  ClosureImplementation getTearOffClosure(Procedure member) {
     return tearOffFunctionCache.putIfAbsent(member, () {
       assert(member.kind == ProcedureKind.Method);
-      FunctionNode functionNode = member.function;
-      int parameterCount = functionNode.requiredParameterCount;
-      if (functionNode.positionalParameters.length != parameterCount ||
-          functionNode.namedParameters.isNotEmpty) {
-        throw "Not supported: Tear-off with optional parameters"
-            " at ${member.location}";
-      }
-      if (functionNode.typeParameters.isNotEmpty) {
-        throw "Not supported: Tear-off with type parameters"
-            " at ${member.location}";
-      }
-      w.FunctionType memberSignature = signatureFor(member.reference);
-      w.FunctionType closureSignature = closureFunctionType(parameterCount);
-      int signatureOffset = member.isInstanceMember ? 1 : 0;
-      assert(memberSignature.inputs.length == signatureOffset + parameterCount);
-      assert(closureSignature.inputs.length == 1 + parameterCount);
-      w.DefinedFunction function =
-          m.addFunction(closureSignature, "$member (tear-off)");
       w.BaseFunction target = functions.getFunction(member.reference);
-      w.Instructions b = function.body;
-      for (int i = 0; i < memberSignature.inputs.length; i++) {
-        w.Local paramLocal = function.locals[(1 - signatureOffset) + i];
-        b.local_get(paramLocal);
-        convertType(function, paramLocal.type, memberSignature.inputs[i]);
-      }
-      b.call(target);
-      convertType(function, outputOrVoid(target.type.outputs),
-          outputOrVoid(closureSignature.outputs));
-      b.end();
-      return function;
+      return getClosure(member.function, target, paramInfoFor(member.reference),
+          "$member tear-off");
     });
   }
 
+  ClosureImplementation getClosure(FunctionNode functionNode,
+      w.BaseFunction target, ParameterInfo paramInfo, String name) {
+    // The target function takes an extra initial parameter if it's a function
+    // expression / local function (which takes a context) or a tear-off of an
+    // instance method (which takes a receiver).
+    bool takesContextOrReceiver =
+        paramInfo.member == null || paramInfo.member!.isInstanceMember;
+
+    // Look up the closure representation for the signature.
+    int typeCount = functionNode.typeParameters.length;
+    int positionalCount = functionNode.positionalParameters.length;
+    List<String> names =
+        functionNode.namedParameters.map((p) => p.name!).toList();
+    assert(typeCount == paramInfo.typeParamCount);
+    assert(positionalCount <= paramInfo.positional.length);
+    assert(names.length <= paramInfo.named.length);
+    assert(target.type.inputs.length ==
+        (takesContextOrReceiver ? 1 : 0) +
+            paramInfo.typeParamCount +
+            paramInfo.positional.length +
+            paramInfo.named.length);
+    ClosureRepresentation representation = closureLayouter
+        .getClosureRepresentation(typeCount, positionalCount, names)!;
+    assert(representation.vtableStruct.fields.length ==
+        representation.vtableBaseIndex +
+            (1 + positionalCount) +
+            representation.nameCombinations.length);
+
+    List<w.DefinedFunction> functions = [];
+
+    bool canBeCalledWith(int posArgCount, List<String> argNames) {
+      if (posArgCount < functionNode.requiredParameterCount) {
+        return false;
+      }
+      int i = 0, j = 0;
+      while (i < argNames.length && j < functionNode.namedParameters.length) {
+        int comp = argNames[i].compareTo(functionNode.namedParameters[j].name!);
+        if (comp < 0) return false;
+        if (comp > 0) {
+          if (functionNode.namedParameters[j++].isRequired) return false;
+          continue;
+        }
+        i++;
+        j++;
+      }
+      if (i < argNames.length) return false;
+      while (j < functionNode.namedParameters.length) {
+        if (functionNode.namedParameters[j++].isRequired) return false;
+      }
+      return true;
+    }
+
+    w.DefinedFunction makeTrampoline(
+        w.FunctionType signature, int posArgCount, List<String> argNames) {
+      w.DefinedFunction function = m.addFunction(signature, name);
+      w.Instructions b = function.body;
+      int targetIndex = 0;
+      if (takesContextOrReceiver) {
+        w.Local receiver = function.locals[0];
+        b.local_get(receiver);
+        convertType(function, receiver.type, target.type.inputs[targetIndex++]);
+      }
+      int argIndex = 1;
+      for (int i = 0; i < typeCount; i++) {
+        b.local_get(function.locals[argIndex++]);
+        targetIndex++;
+      }
+      for (int i = 0; i < paramInfo.positional.length; i++) {
+        if (i < posArgCount) {
+          w.Local arg = function.locals[argIndex++];
+          b.local_get(arg);
+          convertType(function, arg.type, target.type.inputs[targetIndex++]);
+        } else {
+          constants.instantiateConstant(function, b, paramInfo.positional[i]!,
+              target.type.inputs[targetIndex++]);
+        }
+      }
+      int argNameIndex = 0;
+      for (int i = 0; i < paramInfo.names.length; i++) {
+        String argName = paramInfo.names[i];
+        if (argNameIndex < argNames.length &&
+            argNames[argNameIndex] == argName) {
+          w.Local arg = function.locals[argIndex++];
+          b.local_get(arg);
+          convertType(function, arg.type, target.type.inputs[targetIndex++]);
+          argNameIndex++;
+        } else {
+          constants.instantiateConstant(function, b, paramInfo.named[argName]!,
+              target.type.inputs[targetIndex++]);
+        }
+      }
+      assert(argIndex == signature.inputs.length);
+      assert(targetIndex == target.type.inputs.length);
+      assert(argNameIndex == argNames.length);
+
+      b.call(target);
+
+      convertType(function, outputOrVoid(target.type.outputs),
+          outputOrVoid(signature.outputs));
+      b.end();
+
+      return function;
+    }
+
+    void fillVtableEntry(
+        w.Instructions ib, int posArgCount, List<String> argNames) {
+      int fieldIndex = representation.vtableBaseIndex + functions.length;
+      assert(fieldIndex ==
+          representation.fieldIndexForSignature(posArgCount, argNames));
+      w.FunctionType signature =
+          (representation.vtableStruct.fields[fieldIndex].type as w.RefType)
+              .heapType as w.FunctionType;
+      w.DefinedFunction function = canBeCalledWith(posArgCount, argNames)
+          ? makeTrampoline(signature, posArgCount, argNames)
+          : globals.getDummyFunction(signature);
+      functions.add(function);
+      ib.ref_func(function);
+    }
+
+    w.DefinedGlobal vtable = m.addGlobal(w.GlobalType(
+        w.RefType.def(representation.vtableStruct, nullable: false),
+        mutable: false));
+    w.Instructions ib = vtable.initializer;
+    for (int posArgCount = 0; posArgCount <= positionalCount; posArgCount++) {
+      fillVtableEntry(ib, posArgCount, const []);
+    }
+    for (NameCombination nameCombination in representation.nameCombinations) {
+      fillVtableEntry(ib, positionalCount, nameCombination.names);
+    }
+    ib.struct_new(representation.vtableStruct);
+    ib.end();
+
+    return ClosureImplementation(representation, functions, vtable);
+  }
+
   w.ValueType outputOrVoid(List<w.ValueType> outputs) {
     return outputs.isEmpty ? voidMarker : outputs.single;
   }
@@ -739,8 +825,8 @@
       }
       if (to != voidMarker) {
         if (to is w.RefType && to.nullable) {
-          // This can happen when a void method has its return type overridden to
-          // return a value, in which case the selector signature will have a
+          // This can happen when a void method has its return type overridden
+          // to return a value, in which case the selector signature will have a
           // non-void return type to encompass all possible return values.
           b.ref_null(to.heapType);
         } else {
@@ -752,6 +838,17 @@
         return;
       }
     }
+
+    bool fromIsExtern = from.isSubtypeOf(w.RefType.extern(nullable: true));
+    bool toIsExtern = to.isSubtypeOf(w.RefType.extern(nullable: true));
+    if (fromIsExtern && !toIsExtern) {
+      b.extern_internalize();
+      from = w.RefType.any(nullable: from.nullable);
+    }
+    if (!fromIsExtern && toIsExtern) {
+      to = w.RefType.any(nullable: to.nullable);
+    }
+
     if (!from.isSubtypeOf(to)) {
       if (from is! w.RefType && to is w.RefType) {
         // Boxing
@@ -812,6 +909,10 @@
         }
       }
     }
+
+    if (!fromIsExtern && toIsExtern) {
+      b.extern_externalize();
+    }
   }
 
   w.FunctionType signatureFor(Reference target) {
diff --git a/pkg/dart2wasm/lib/types.dart b/pkg/dart2wasm/lib/types.dart
index ab61a93..20da36b 100644
--- a/pkg/dart2wasm/lib/types.dart
+++ b/pkg/dart2wasm/lib/types.dart
@@ -431,10 +431,9 @@
   void emitTypeTest(CodeGenerator codeGen, DartType type, DartType operandType,
       TreeNode node) {
     w.Instructions b = codeGen.b;
-    if (type is FunctionType) {
-      // TODO(joshualitt): We can enable type tests for [FunctionType] after
-      // enabling `.runtimeType` for [FunctionType].
-      print("Not implemented: Type test with function type $type"
+    if (type is FunctionType && isGenericFunction(type)) {
+      // TODO(joshualitt): Finish generic function types.
+      print("Not implemented: Type test with generic function type $type"
           " at ${node.location}");
       b.drop();
       b.i32_const(1);
@@ -482,7 +481,10 @@
       }
     }
     List<Class> concrete = _getConcreteSubtypes(type.classNode).toList();
-    if (type.classNode == coreTypes.functionClass) {
+    if (type.classNode == coreTypes.objectClass) {
+      b.drop();
+      b.i32_const(1);
+    } else if (type.classNode == coreTypes.functionClass) {
       ClassInfo functionInfo = translator.classInfo[translator.functionClass]!;
       b.ref_test(functionInfo.struct);
     } else if (concrete.isEmpty) {
diff --git a/pkg/dart2wasm/pubspec.yaml b/pkg/dart2wasm/pubspec.yaml
index 2aec845..6162b48 100644
--- a/pkg/dart2wasm/pubspec.yaml
+++ b/pkg/dart2wasm/pubspec.yaml
@@ -2,7 +2,7 @@
 # This package is not intended for consumption on pub.dev. DO NOT publish.
 publish_to: none
 environment:
-  sdk: '>=2.12.0'
+  sdk: '>=2.17.0'
 
 # Use 'any' constraints here; we get our versions from the DEPS file.
 dependencies:
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 288c8d0..d27a4ad 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -314,9 +314,12 @@
         extraOptions: args['extra-gen-snapshot-options'],
       );
       return 0;
-    } catch (e) {
+    } catch (e, st) {
       log.stderr('Error: AOT compilation failed');
       log.stderr(e.toString());
+      if (verbose) {
+        log.stderr(st.toString());
+      }
       return compileErrorExitCode;
     }
   }
diff --git a/pkg/dartdev/test/commands/compile_test.dart b/pkg/dartdev/test/commands/compile_test.dart
index a4e5741..e42927a 100644
--- a/pkg/dartdev/test/commands/compile_test.dart
+++ b/pkg/dartdev/test/commands/compile_test.dart
@@ -5,7 +5,6 @@
 import 'dart:io';
 
 import 'package:dart2native/macho.dart';
-import 'package:dart2native/macho_parser.dart';
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
@@ -48,21 +47,14 @@
           reason: 'File not found: $outFile');
 
       // Ensure the file contains the __CUSTOM segment.
-      final machOFile = MachOFile();
-      await machOFile.loadFromFile(File(outFile));
+      final machOFile = MachOFile.fromFile(File(outFile));
 
       // Throws an exception (and thus the test fails) if the segment doesn't
       // exist.
-      machOFile.commands.where((segment) {
-        if (segment.asType() is MachOSegmentCommand64) {
-          final segmentName = (segment as MachOSegmentCommand64).segname;
-          final segmentNameTrimmed = String.fromCharCodes(
-              segmentName.takeWhile((value) => value != 0));
-          return segmentNameTrimmed == '__CUSTOM';
-        } else {
-          return false;
-        }
-      }).first;
+      machOFile.commands
+          .where((segment) =>
+              segment is MachOSegmentCommand && segment.name == '__CUSTOM')
+          .first;
 
       // Ensure that the exe can be signed.
       final codeSigningProcess = await Process.start('codesign', [
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index 778e28e..bf932f1 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -13,7 +13,7 @@
 
 import '../utils.dart';
 
-const String soundNullSafetyMessage = 'Info: Compiling with sound null safety';
+const String soundNullSafetyMessage = 'Info: Compiling with sound null safety.';
 const devToolsMessagePrefix =
     'The Dart DevTools debugger and profiler is available at: http://127.0.0.1:';
 const dartVMServiceMessagePrefix =
diff --git a/pkg/dartdev/test/no_such_file_test.dart b/pkg/dartdev/test/no_such_file_test.dart
index 4d8032d..49a0d61 100644
--- a/pkg/dartdev/test/no_such_file_test.dart
+++ b/pkg/dartdev/test/no_such_file_test.dart
@@ -33,7 +33,8 @@
     expect(result.stderr, isNotEmpty);
     expect(result.stderr, contains("Error when reading 'foo.dart':"));
     expect(result.stdout, isNotEmpty);
-    expect(result.stdout, contains('Info: Compiling with sound null safety\n'));
+    expect(
+        result.stdout, contains('Info: Compiling with sound null safety.\n'));
     expect(result.exitCode, 254);
   });
 }
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index 5fffdf9..600af14 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,3 +1,17 @@
+# 2.4.0
+- [DAP] Added support for sending progress notifications via `DartDebugAdapter.startProgressNotification`.
+  Standard progress events are sent when a clients sets `supportsProgressReporting: true` in its capabilities,
+  unless `sendCustomProgressEvents: true` is included in launch configuration, in which case prefixed (`dart.`) custom notifications will be sent instead.
+
+# 2.3.1
+- Fixed issue where DDS wasn't correctly handling `Sentinel` responses in `IsolateManager.initialize()`.
+
+# 2.3.0
+- [DAP] Removed an unused parameter `resumeIfStarting` from `DartDebugAdapter.connectDebugger`.
+- [DAP] Fixed some issues where removing breakpoints could fail if an isolate exited during an update or multiple client breakpoints mapped to the same VM breakpoint.
+- [DAP] Paths provided to DAP now always have Windows drive letters normalized to uppercase to avoid some issues where paths may be treated case sensitively.
+- Fixed issue where DDS wasn't correctly handling `Sentinel` responses in `IsolateManager.initialize()`.
+
 # 2.2.6
 - Fixed an issue where debug adapters would not automatically close after terminating/disconnecting from the debugee.
 
diff --git a/pkg/dds/analysis_options.yaml b/pkg/dds/analysis_options.yaml
index 8f7435b..59a93d3 100644
--- a/pkg/dds/analysis_options.yaml
+++ b/pkg/dds/analysis_options.yaml
@@ -6,3 +6,5 @@
     - directives_ordering
     - prefer_generic_function_type_aliases
     - prefer_relative_imports
+    - unnecessary_new
+    - unnecessary_const
diff --git a/pkg/dds/lib/dap.dart b/pkg/dds/lib/dap.dart
index 792e9dd..2f80c23 100644
--- a/pkg/dds/lib/dap.dart
+++ b/pkg/dds/lib/dap.dart
@@ -6,6 +6,7 @@
 export 'src/dap/adapters/mixins.dart';
 export 'src/dap/exceptions.dart';
 export 'src/dap/logging.dart';
+export 'src/dap/progress_reporter.dart';
 export 'src/dap/protocol_common.dart';
 export 'src/dap/protocol_generated.dart';
 export 'src/dap/protocol_stream.dart';
diff --git a/pkg/dds/lib/devtools_server.dart b/pkg/dds/lib/devtools_server.dart
index 8949604..9d30263 100644
--- a/pkg/dds/lib/devtools_server.dart
+++ b/pkg/dds/lib/devtools_server.dart
@@ -507,7 +507,7 @@
         params.containsKey('notify') && params['notify'] == true;
     final page = params['page'];
     if (canReuse &&
-        _tryReuseExistingDevToolsInstance(
+        await _tryReuseExistingDevToolsInstance(
           vmServiceUri,
           page,
           shouldNotify,
@@ -586,15 +586,20 @@
     print('Writing memory profile samples to $profileFile...');
   }
 
-  bool _tryReuseExistingDevToolsInstance(
+  /// Tries to reuse an existing DevTools instance.
+  ///
+  /// Because SSE connections have timeouts that prevent us knowing if a client
+  /// has really gone away for up to 30s, this method will attempt to ping
+  /// candidate first to see if it is still responsive.
+  Future<bool> _tryReuseExistingDevToolsInstance(
     Uri vmServiceUri,
     String? page,
     bool notifyUser,
-  ) {
+  ) async {
     // First try to find a client that's already connected to this VM service,
     // and just send the user a notification for that one.
     final existingClient =
-        clientManager.findExistingConnectedReusableClient(vmServiceUri);
+        await clientManager.findExistingConnectedReusableClient(vmServiceUri);
     if (existingClient != null) {
       try {
         if (page != null) {
@@ -610,7 +615,7 @@
       }
     }
 
-    final reusableClient = clientManager.findReusableClient();
+    final reusableClient = await clientManager.findReusableClient();
     if (reusableClient != null) {
       try {
         reusableClient.connectToVmService(vmServiceUri, notifyUser);
diff --git a/pkg/dds/lib/src/dap/adapters/dart.dart b/pkg/dds/lib/src/dap/adapters/dart.dart
index 3e2fac4..537b556 100644
--- a/pkg/dds/lib/src/dap/adapters/dart.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart.dart
@@ -7,6 +7,7 @@
 import 'dart:io';
 
 import 'package:collection/collection.dart';
+import 'package:json_rpc_2/error_code.dart' as jsonRpcErrors;
 import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
 import 'package:vm_service/vm_service.dart' as vm;
@@ -17,11 +18,13 @@
 import '../exceptions.dart';
 import '../isolate_manager.dart';
 import '../logging.dart';
+import '../progress_reporter.dart';
 import '../protocol_common.dart';
 import '../protocol_converter.dart';
 import '../protocol_generated.dart';
 import '../protocol_stream.dart';
 import '../utils.dart';
+import 'mixins.dart';
 
 /// The mime type to send with source responses to the client.
 ///
@@ -111,6 +114,7 @@
     bool? evaluateGettersInDebugViews,
     bool? evaluateToStringInDebugViews,
     bool? sendLogsToClient,
+    bool? sendCustomProgressEvents,
   }) : super(
           name: name,
           cwd: cwd,
@@ -123,6 +127,7 @@
           evaluateGettersInDebugViews: evaluateGettersInDebugViews,
           evaluateToStringInDebugViews: evaluateToStringInDebugViews,
           sendLogsToClient: sendLogsToClient,
+          sendCustomProgressEvents: sendCustomProgressEvents,
         );
 
   DartAttachRequestArguments.fromMap(Map<String, Object?> obj)
@@ -169,6 +174,11 @@
   /// libraries.
   final bool? debugSdkLibraries;
 
+  /// Whether to send custom progress events for long-running operations.
+  ///
+  /// If `false` or `null`, will send standard DAP progress notifications.
+  final bool? sendCustomProgressEvents;
+
   /// Whether external package libraries should be marked as debuggable.
   ///
   /// Treated as `false` if null, which means "step in" will not step into
@@ -212,6 +222,7 @@
     required this.evaluateGettersInDebugViews,
     required this.evaluateToStringInDebugViews,
     required this.sendLogsToClient,
+    this.sendCustomProgressEvents = false,
   });
 
   DartCommonLaunchAttachRequestArguments.fromMap(Map<String, Object?> obj)
@@ -228,7 +239,8 @@
             obj['evaluateGettersInDebugViews'] as bool?,
         evaluateToStringInDebugViews =
             obj['evaluateToStringInDebugViews'] as bool?,
-        sendLogsToClient = obj['sendLogsToClient'] as bool?;
+        sendLogsToClient = obj['sendLogsToClient'] as bool?,
+        sendCustomProgressEvents = obj['sendCustomProgressEvents'] as bool?;
 
   Map<String, Object?> toJson() => {
         if (restart != null) 'restart': restart,
@@ -245,6 +257,8 @@
         if (evaluateToStringInDebugViews != null)
           'evaluateToStringInDebugViews': evaluateToStringInDebugViews,
         if (sendLogsToClient != null) 'sendLogsToClient': sendLogsToClient,
+        if (sendCustomProgressEvents != null)
+          'sendCustomProgressEvents': sendCustomProgressEvents,
       };
 }
 
@@ -285,7 +299,8 @@
 /// (for example when the server sends a `StoppedEvent` it may cause the client
 /// to then send a `stackTraceRequest` or `scopesRequest` to get variables).
 abstract class DartDebugAdapter<TL extends LaunchRequestArguments,
-    TA extends AttachRequestArguments> extends BaseDebugAdapter<TL, TA> {
+        TA extends AttachRequestArguments> extends BaseDebugAdapter<TL, TA>
+    with FileUtils {
   late final DartCommonLaunchAttachRequestArguments args;
   final _debuggerInitializedCompleter = Completer<void>();
   final _configurationDoneCompleter = Completer<void>();
@@ -544,12 +559,7 @@
   /// The URI protocol will be changed to ws/wss but otherwise not normalised.
   /// The caller should handle any other normalisation (such as adding /ws to
   /// the end if required).
-  Future<void> connectDebugger(
-    Uri uri, {
-    // TODO(dantup): Remove this after parameter after updating the Flutter
-    //   DAP to not pass it.
-    bool? resumeIfStarting,
-  }) async {
+  Future<void> connectDebugger(Uri uri) async {
     // Start up a DDS instance for this VM.
     if (enableDds) {
       logger?.call('Starting a DDS instance for $uri');
@@ -637,6 +647,26 @@
     );
   }
 
+  /// Starts reporting progress to the client for a single operation.
+  ///
+  /// The returned [DapProgressReporter] can be used to send updated messages
+  /// and to complete progress (hiding the progress notification).
+  ///
+  /// Clients will use [title] as a prefix for all updates, appending [message]
+  /// in the form:
+  ///
+  /// title: message
+  ///
+  /// When `update` is called, the new message will replace the previous
+  /// message but the title prefix will remain.
+  DapProgressReporter startProgressNotification(
+    String id,
+    String title, {
+    String? message,
+  }) {
+    return DapProgressReporter.start(this, id, title, message: message);
+  }
+
   /// Process any existing isolates that may have been created before the
   /// streams above were set up.
   Future<void> _configureExistingIsolates(
@@ -711,7 +741,6 @@
     void Function(Object?) sendResponse,
   ) 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.
@@ -1191,7 +1220,7 @@
 
     final path = args.source.path;
     final name = args.source.name;
-    final uri = path != null ? Uri.file(path).toString() : name!;
+    final uri = path != null ? Uri.file(normalizePath(path)).toString() : name!;
 
     await _isolateManager.setBreakpoints(uri, breakpoints);
 
@@ -2071,13 +2100,22 @@
     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;
+      // If we've been asked to shut down while this request was occurring,
+      // it's normal to get some types of errors from in-flight VM Service
+      // requests and we should handle them silently.
+      if (isTerminating) {
+        // kServiceDisappeared is thrown sometimes when services disappear.
+        if (e.code == RpcErrorCodes.kServiceDisappeared) {
+          return null;
+        }
+        // SERVER_ERROR can occur when DDS completes any outstanding requests
+        // with "The client closed with pending request".
+        if (e.code == jsonRpcErrors.SERVER_ERROR) {
+          return null;
+        }
       }
 
+      // Otherwise, it's an unexpected/unknown failure and should be rethrown.
       rethrow;
     }
   }
@@ -2169,6 +2207,7 @@
     bool? evaluateGettersInDebugViews,
     bool? evaluateToStringInDebugViews,
     bool? sendLogsToClient,
+    bool? sendCustomProgressEvents,
   }) : super(
           restart: restart,
           name: name,
@@ -2180,6 +2219,7 @@
           evaluateGettersInDebugViews: evaluateGettersInDebugViews,
           evaluateToStringInDebugViews: evaluateToStringInDebugViews,
           sendLogsToClient: sendLogsToClient,
+          sendCustomProgressEvents: sendCustomProgressEvents,
         );
 
   DartLaunchRequestArguments.fromMap(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 b10813e..6b24ef2 100644
--- a/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
@@ -93,9 +93,19 @@
 
     final debug = !(args.noDebug ?? false);
     if (debug) {
+      final progress = startProgressNotification(
+        "launch",
+        "Debugger",
+        message: "Starting…",
+      );
       vmServiceInfoFile = generateVmServiceInfoFile();
-      unawaited(waitForVmServiceInfoFile(logger, vmServiceInfoFile)
-          .then((uri) => connectDebugger(uri)));
+      unawaited(
+        waitForVmServiceInfoFile(logger, vmServiceInfoFile).then((uri) async {
+          progress.update(message: "Connecting…");
+          await connectDebugger(uri);
+          progress.end();
+        }),
+      );
     }
 
     final vmArgs = <String>[
@@ -124,7 +134,9 @@
     }
 
     // Handle customTool and deletion of any arguments for it.
-    final executable = args.customTool ?? Platform.resolvedExecutable;
+    final executable = normalizePath(
+      args.customTool ?? Platform.resolvedExecutable,
+    );
     final removeArgs = args.customToolReplacesArgs;
     if (args.customTool != null && removeArgs != null) {
       vmArgs.removeRange(0, math.min(removeArgs, vmArgs.length));
@@ -133,7 +145,7 @@
     final processArgs = [
       ...vmArgs,
       ...toolArgs,
-      args.program,
+      normalizePath(args.program),
       ...?args.args,
     ];
 
@@ -153,20 +165,25 @@
                 : null
         : null;
 
+    var cwd = args.cwd;
+    if (cwd != null) {
+      cwd = normalizePath(cwd);
+    }
+
     if (terminalKind != null) {
       await launchInEditorTerminal(
         debug,
         terminalKind,
         executable,
         processArgs,
-        workingDirectory: args.cwd,
+        workingDirectory: cwd,
         env: args.env,
       );
     } else {
       await launchAsProcess(
         executable,
         processArgs,
-        workingDirectory: args.cwd,
+        workingDirectory: cwd,
         env: args.env,
       );
     }
@@ -216,7 +233,7 @@
     // we can detect with the normal watching code.
     final requestArgs = RunInTerminalRequestArguments(
       args: [executable, ...processArgs],
-      cwd: workingDirectory ?? path.dirname(args.program),
+      cwd: workingDirectory ?? normalizePath(path.dirname(args.program)),
       env: env,
       kind: terminalKind,
       title: args.name ?? 'Dart',
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 e80f061..efa4e79 100644
--- a/pkg/dds/lib/src/dap/adapters/dart_test_adapter.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart_test_adapter.dart
@@ -111,7 +111,9 @@
     ];
 
     // Handle customTool and deletion of any arguments for it.
-    final executable = args.customTool ?? Platform.resolvedExecutable;
+    final executable = normalizePath(
+      args.customTool ?? Platform.resolvedExecutable,
+    );
     final removeArgs = args.customToolReplacesArgs;
     if (args.customTool != null && removeArgs != null) {
       vmArgs.removeRange(0, math.min(removeArgs, vmArgs.length));
@@ -120,14 +122,19 @@
     final processArgs = [
       ...vmArgs,
       ...?args.toolArgs,
-      args.program,
+      normalizePath(args.program),
       ...?args.args,
     ];
 
+    var cwd = args.cwd;
+    if (cwd != null) {
+      cwd = normalizePath(cwd);
+    }
+
     await launchAsProcess(
       executable,
       processArgs,
-      workingDirectory: args.cwd,
+      workingDirectory: cwd,
       env: args.env,
     );
   }
diff --git a/pkg/dds/lib/src/dap/adapters/mixins.dart b/pkg/dds/lib/src/dap/adapters/mixins.dart
index 8ecf1eb..420c61e 100644
--- a/pkg/dds/lib/src/dap/adapters/mixins.dart
+++ b/pkg/dds/lib/src/dap/adapters/mixins.dart
@@ -134,7 +134,7 @@
 /// A mixin providing some utility functions for working with vm-service-info
 /// files such as ensuring a temp folder exists to create them in, and waiting
 /// for the file to become valid parsable JSON.
-mixin VmServiceInfoFileUtils {
+mixin VmServiceInfoFileUtils on FileUtils {
   /// Creates a temp folder for the VM to write the service-info-file into and
   /// returns the [File] to use.
   File generateVmServiceInfoFile() {
@@ -143,7 +143,8 @@
     // watcher. Creating/watching a folder and writing the file into it seems
     // to be reliable.
     final serviceInfoFilePath = path.join(
-      Directory.systemTemp.createTempSync('dart-vm-service').path,
+      normalizePath(
+          Directory.systemTemp.createTempSync('dart-vm-service').path),
       'vm.json',
     );
 
@@ -203,3 +204,24 @@
     }
   }
 }
+
+mixin FileUtils {
+  /// Normalizes [filePath] to avoid issues with different casing of drive
+  /// letters on Windows.
+  ///
+  /// Some clients like VS Code do their own normalization and may provide drive
+  /// letters case different in some requests (such as breakpoints) to drive
+  /// letters computed elsewhere (such in `Platform.resolvedExecutable`). When
+  /// these do not match, breakpoints may not be hit.
+  ///
+  /// This is the case for the whole path, but drive letters are most commonly
+  /// mismatched due to VS Code's explicit normalization.
+  ///
+  /// https://github.com/dart-lang/sdk/issues/32222
+  String normalizePath(String filePath) {
+    if (!Platform.isWindows || filePath.isEmpty || path.isRelative(filePath)) {
+      return filePath;
+    }
+    return filePath.substring(0, 1).toUpperCase() + filePath.substring(1);
+  }
+}
diff --git a/pkg/dds/lib/src/dap/isolate_manager.dart b/pkg/dds/lib/src/dap/isolate_manager.dart
index eca3678..32502f9 100644
--- a/pkg/dds/lib/src/dap/isolate_manager.dart
+++ b/pkg/dds/lib/src/dap/isolate_manager.dart
@@ -81,7 +81,12 @@
   /// Tracks breakpoints created in the VM so they can be removed when the
   /// editor sends new breakpoints (currently the editor just sends a new list
   /// and not requests to add/remove).
-  final Map<String, Map<String, List<vm.Breakpoint>>>
+  ///
+  /// Breakpoints are indexed by their ID so that duplicates are not stored even
+  /// if multiple client breakpoints resolve to a single VM breakpoint.
+  ///
+  /// IsolateId -> Uri -> breakpointId -> VM Breakpoint.
+  final Map<String, Map<String, Map<String, vm.Breakpoint>>>
       _vmBreakpointsByIsolateIdAndUri = {};
 
   /// The exception pause mode last provided by the client.
@@ -629,14 +634,23 @@
       final existingBreakpointsForIsolate =
           _vmBreakpointsByIsolateIdAndUri.putIfAbsent(isolateId, () => {});
       final existingBreakpointsForIsolateAndUri =
-          existingBreakpointsForIsolate.putIfAbsent(uri, () => []);
+          existingBreakpointsForIsolate.putIfAbsent(uri, () => {});
       // Before doing async work, take a copy of the breakpoints to remove
       // and remove them from the list, so any subsequent calls here don't
-      // try to remove the same ones.
-      final breakpointsToRemove = existingBreakpointsForIsolateAndUri.toList();
+      // try to remove the same ones multiple times.
+      final breakpointsToRemove =
+          existingBreakpointsForIsolateAndUri.values.toList();
       existingBreakpointsForIsolateAndUri.clear();
-      await Future.forEach<vm.Breakpoint>(breakpointsToRemove,
-          (bp) => service.removeBreakpoint(isolateId, bp.id!));
+      await Future.forEach<vm.Breakpoint>(breakpointsToRemove, (bp) async {
+        try {
+          await service.removeBreakpoint(isolateId, bp.id!);
+        } catch (e) {
+          // Swallow errors removing breakpoints rather than failing the whole
+          // request as it's very possible that an isolate exited while we were
+          // sending this and the request will fail.
+          _adapter.logger?.call('Failed to remove old breakpoint $e');
+        }
+      });
 
       // Set new breakpoints.
       final newBreakpoints = _clientBreakpointsByUri[uri] ?? const [];
@@ -655,7 +669,7 @@
           final vmBp = await service.addBreakpointWithScriptUri(
               isolateId, vmUri.toString(), bp.line,
               column: bp.column);
-          existingBreakpointsForIsolateAndUri.add(vmBp);
+          existingBreakpointsForIsolateAndUri[vmBp.id!] = vmBp;
           _clientBreakpointsByVmId[vmBp.id!] = bp;
         } catch (e) {
           // Swallow errors setting breakpoints rather than failing the whole
@@ -908,7 +922,11 @@
         // We can't leave dangling completers here because others may already
         // be waiting on them, so propagate the error to them.
         completers.forEach((uri, completer) => completer.completeError(e));
-        rethrow;
+
+        // Don't rethrow here, because it will cause these completers futures
+        // to not have error handlers attached which can cause their errors to
+        // go unhandled. Instead, these completers futures will be returned
+        // below and awaited by the caller (which will propogate the errors).
       }
     }
 
diff --git a/pkg/dds/lib/src/dap/progress_reporter.dart b/pkg/dds/lib/src/dap/progress_reporter.dart
new file mode 100644
index 0000000..3b76b84
--- /dev/null
+++ b/pkg/dds/lib/src/dap/progress_reporter.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2022, 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 'adapters/dart.dart';
+import 'protocol_generated.dart';
+
+/// A reporter that can send progress notifications to the client.
+abstract class DapProgressReporter {
+  final DartDebugAdapter adapter;
+
+  /// The ID for the this progress, used by the client to distinguish between
+  /// any overlapping progress.
+  final String id;
+
+  /// A suffix to use for the next token to ensure all IDs are unique.
+  static int nextIdSuffix = 1;
+
+  DapProgressReporter(this.adapter, String idPrefix)
+      : id = '${idPrefix}_${nextIdSuffix++}';
+
+  void _start(String title, String? message) {
+    sendStart(ProgressStartEventBody(
+      progressId: id,
+      title: title,
+      message: message,
+    ));
+  }
+
+  void update({required String message}) {
+    sendUpdate(ProgressUpdateEventBody(progressId: id, message: message));
+  }
+
+  void end([String? message]) {
+    sendEnd(ProgressEndEventBody(progressId: id, message: message));
+  }
+
+  /// Creates a progress reporter and sends the start event.
+  factory DapProgressReporter.start(
+    DartDebugAdapter adapter,
+    String idPrefix,
+    String title, {
+    String? message,
+  }) {
+    final supportsStandardProgress =
+        adapter.initializeArgs?.supportsProgressReporting ?? false;
+    final useCustomProgress = adapter.args.sendCustomProgressEvents ?? false;
+
+    final reporter = useCustomProgress
+        ? _CustomDapProgressReporter(adapter, idPrefix)
+        : supportsStandardProgress
+            ? _StandardDapProgressReporter(adapter, idPrefix)
+            : _NoopDapProgressReporter(adapter, idPrefix);
+
+    return reporter.._start(title, message);
+  }
+
+  void sendStart(ProgressStartEventBody body);
+  void sendUpdate(ProgressUpdateEventBody body);
+  void sendEnd(ProgressEndEventBody body);
+}
+
+/// Sends progress notifications using custom events.
+///
+/// Custom events are used by VS Code to allow the Dart extension to control the
+/// notifications instead of VS Code, which allows them to be shown immediately
+/// instead of after a 500ms debounce which can cause fast Hot Reload
+/// notifications to never be shown and provide no user feedback.
+///
+/// https://github.com/microsoft/vscode/issues/101405
+class _CustomDapProgressReporter extends DapProgressReporter {
+  _CustomDapProgressReporter(DartDebugAdapter adapter, String idPrefix)
+      : super(adapter, idPrefix);
+
+  @override
+  void sendStart(ProgressStartEventBody body) {
+    adapter.sendEvent(body, eventType: 'dart.progressStart');
+  }
+
+  @override
+  void sendUpdate(ProgressUpdateEventBody body) {
+    adapter.sendEvent(body, eventType: 'dart.progressUpdate');
+  }
+
+  @override
+  void sendEnd(ProgressEndEventBody body) {
+    adapter.sendEvent(body, eventType: 'dart.progressEnd');
+  }
+}
+
+/// Sends progress notifications using standard events.
+class _StandardDapProgressReporter extends DapProgressReporter {
+  _StandardDapProgressReporter(DartDebugAdapter adapter, String idPrefix)
+      : super(adapter, idPrefix);
+
+  @override
+  void sendStart(ProgressStartEventBody body) {
+    adapter.sendEvent(body);
+  }
+
+  @override
+  void sendUpdate(ProgressUpdateEventBody body) {
+    adapter.sendEvent(body);
+  }
+
+  @override
+  void sendEnd(ProgressEndEventBody body) {
+    adapter.sendEvent(body);
+  }
+}
+
+/// A [DapProgressReporter] that does not send any events.
+class _NoopDapProgressReporter extends DapProgressReporter {
+  _NoopDapProgressReporter(DartDebugAdapter adapter, String idPrefix)
+      : super(adapter, idPrefix);
+
+  @override
+  void sendStart(ProgressStartEventBody body) {}
+
+  @override
+  void sendUpdate(ProgressUpdateEventBody body) {}
+
+  @override
+  void sendEnd(ProgressEndEventBody body) {}
+}
diff --git a/pkg/dds/lib/src/devtools/client.dart b/pkg/dds/lib/src/devtools/client.dart
index af82b55..629b920 100644
--- a/pkg/dds/lib/src/devtools/client.dart
+++ b/pkg/dds/lib/src/devtools/client.dart
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 
-import 'package:collection/collection.dart';
 import 'package:devtools_shared/devtools_server.dart';
 import 'package:json_rpc_2/src/peer.dart' as json_rpc;
 import 'package:meta/meta.dart';
@@ -46,6 +45,18 @@
 class ClientManager {
   ClientManager({required this.requestNotificationPermissions});
 
+  /// The timeout to wait for a ping when verifying a client is still
+  /// responsive.
+  ///
+  /// Usually clients are removed from the set once they disconnect, but due
+  /// to SSE timeouts (to handle proxies dropping connections) a client may
+  /// appear connected for up to 30s after they disconnected.
+  ///
+  /// In cases where we need to know quickly if a client is active (for example
+  /// when trying to reuse it), we will ping it and wait only this period to see
+  /// if it responds before assuming it is not available.
+  static const _clientResponsivenessTimeout = Duration(milliseconds: 500);
+
   /// Whether to immediately request notification permissions when a client connects.
   /// Otherwise permission will be requested only with the first notification.
   final bool requestNotificationPermissions;
@@ -67,22 +78,58 @@
   /// a VM service that we can reuse (for example if a user stopped debugging
   /// and it disconnected, then started debugging again, we want to reuse
   /// the open DevTools window).
-  DevToolsClient? findReusableClient() {
-    return _clients.firstWhereOrNull(
-      (c) => !c.hasConnection && !c.embedded,
-    );
+  ///
+  /// Candidate clients will be pinged first to ensure they are responsive, to
+  /// avoid trying to reuse a client that is in an SSE timeout where we don't
+  /// know if it is refreshing or gone.
+  Future<DevToolsClient?> findReusableClient() {
+    final candidates =
+        _clients.where((c) => !c.hasConnection && !c.embedded).toList();
+
+    return _firstResponsiveClient(candidates);
   }
 
   /// Finds a client that may already be connected to this VM Service.
-  DevToolsClient? findExistingConnectedReusableClient(Uri vmServiceUri) {
-    // Checking the whole URI will fail if DevTools converted it from HTTP to
-    // WS, so just check the host, port and first segment of path (token).
-    return _clients.firstWhereOrNull(
-      (c) =>
-          c.hasConnection &&
-          !c.embedded &&
-          _areSameVmServices(c.vmServiceUri!, vmServiceUri),
+  ///
+  /// Candidate clients will be pinged first to ensure they are responsive, to
+  /// avoid trying to reuse a client that is in an SSE timeout where we don't
+  /// know if it is refreshing or gone.
+  Future<DevToolsClient?> findExistingConnectedReusableClient(
+      Uri vmServiceUri) {
+    final candidates = _clients
+        .where((c) =>
+            c.hasConnection &&
+            !c.embedded &&
+            _areSameVmServices(c.vmServiceUri!, vmServiceUri))
+        .toList();
+
+    return _firstResponsiveClient(candidates);
+  }
+
+  /// Pings [candidates] and returns the first one that responds.
+  ///
+  /// If no clients respond within a short period, returns `null` because all
+  /// clients have likely been closed (but are in an SSE timeout period).
+  Future<DevToolsClient?> _firstResponsiveClient(
+      List<DevToolsClient> candidates) async {
+    if (candidates.isEmpty) {
+      return null;
+    }
+    // Use `Future.any` to get the first client that responds to its
+    // ping.
+    final firstRespondingClient = Future.any(
+      candidates.cast<DevToolsClient?>().map((client) async {
+        await client?.ping();
+        return client;
+      }),
     );
+
+    final client = await firstRespondingClient.timeout(
+      _clientResponsivenessTimeout,
+      onTimeout: () => null,
+    );
+
+    return client;
   }
 
   @override
@@ -100,6 +147,10 @@
         }
       };
 
+  /// Checks whether two VM Services are equiavlent.
+  ///
+  /// Checking the whole URI will fail if DevTools converted it from HTTP to
+  /// WS, so just checks the host, port and first segment of path (token).
   bool _areSameVmServices(Uri uri1, Uri uri2) {
     return uri1.host == uri2.host &&
         uri1.port == uri2.port &&
@@ -171,8 +222,18 @@
       final value = parameters['value'].value;
       ServerApi.devToolsPreferences.properties[key] = value;
     });
+
+    _devToolsPeer.registerMethod('pingResponse', (parameters) {
+      _nextPingResponse.complete();
+      _nextPingResponse = Completer();
+    });
   }
 
+  /// A completer that completes when the client next responds to a ping.
+  ///
+  /// See [ping].
+  Completer<void> _nextPingResponse = Completer();
+
   /// Notify the DevTools client to connect to a specific VM service instance.
   void connectToVmService(Uri uri, bool notifyUser) {
     _devToolsPeer.sendNotification('connectToVm', {
@@ -183,6 +244,12 @@
 
   void notify() => _devToolsPeer.sendNotification('notify');
 
+  /// Pings the client and waits for it to respond.
+  Future<void> ping() {
+    _devToolsPeer.sendNotification('ping');
+    return _nextPingResponse.future;
+  }
+
   /// Enable notifications to the user from this DevTools client.
   void enableNotifications() =>
       _devToolsPeer.sendNotification('enableNotifications');
diff --git a/pkg/dds/lib/src/isolate_manager.dart b/pkg/dds/lib/src/isolate_manager.dart
index 93c2af4..ba725ce 100644
--- a/pkg/dds/lib/src/isolate_manager.dart
+++ b/pkg/dds/lib/src/isolate_manager.dart
@@ -226,6 +226,11 @@
           final isolate = await dds.vmServiceClient.sendRequest('getIsolate', {
             'isolateId': id,
           });
+          // If the isolate has shutdown after the getVM request, ignore it and
+          // continue to the next isolate.
+          if (isolate['type'] == 'Sentinel') {
+            continue;
+          }
           final name = isolate['name'];
           if (isolate.containsKey('pauseEvent')) {
             isolates[id] = _RunningIsolate(this, id, name);
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index 0d8ae8b..bf399ee 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dds
-version: 2.2.6
+version: 2.4.0
 description: >-
   A library used to spawn the Dart Developer Service, used to communicate with
   a Dart VM Service instance.
diff --git a/pkg/dds/test/dap/integration/debug_breakpoints_test.dart b/pkg/dds/test/dap/integration/debug_breakpoints_test.dart
index f067468..9e403ce 100644
--- a/pkg/dds/test/dap/integration/debug_breakpoints_test.dart
+++ b/pkg/dds/test/dap/integration/debug_breakpoints_test.dart
@@ -71,6 +71,30 @@
       await client.setBreakpoints(testFile, []);
     });
 
+    test(
+        'does not fail updating breakpoints after a removal '
+        'if two breakpoints resolved to the same location', () async {
+      final client = dap.client;
+      final testFile =
+          dap.createTestFile(simpleBreakpointWithLeadingBlankLineProgram);
+      final breakpointLine = lineWith(testFile, breakpointMarker);
+      final beforeBreakpointLine = breakpointLine - 1;
+
+      // Hit the breakpoint line first to ensure the function is compiled. This
+      // is required to ensure the VM gives us back the same breakpoint ID for
+      // the two locations.
+      await client.hitBreakpoint(testFile, breakpointLine);
+
+      // Add breakpoints to both lines.
+      await client.setBreakpoints(
+        testFile,
+        [breakpointLine, beforeBreakpointLine],
+      );
+
+      // Remove all breakpoints (which in reality, is just one).
+      await client.setBreakpoints(testFile, []);
+    });
+
     test('stops at a line breakpoint in the SDK set via local sources',
         () async {
       final client = dap.client;
@@ -83,7 +107,8 @@
       await client.hitBreakpoint(sdkFile, breakpointLine, entryFile: testFile);
     });
 
-    test('stops at a line breakpoint and can be resumed', () async {
+    /// Tests hitting a simple breakpoint and resuming.
+    Future<void> _testHitBreakpointAndResume() async {
       final client = dap.client;
       final testFile = dap.createTestFile(simpleBreakpointProgram);
       final breakpointLine = lineWith(testFile, breakpointMarker);
@@ -96,8 +121,32 @@
         client.event('terminated'),
         client.continue_(stop.threadId!),
       ], eagerError: true);
+    }
+
+    test('stops at a line breakpoint and can be resumed', () async {
+      await _testHitBreakpointAndResume();
     });
 
+    test(
+        'stops at a line breakpoint and can be resumed '
+        'when breakpoint requests have lowercase drive letters '
+        'and program/VM have uppercase drive letters', () async {
+      final client = dap.client;
+      client.forceDriveLetterCasingUpper = true;
+      client.forceBreakpointDriveLetterCasingLower = true;
+      await _testHitBreakpointAndResume();
+    }, skip: !Platform.isWindows);
+
+    test(
+        'stops at a line breakpoint and can be resumed '
+        'when breakpoint requests have uppercase drive letters '
+        'and program/VM have lowercase drive letters', () async {
+      final client = dap.client;
+      client.forceDriveLetterCasingLower = true;
+      client.forceBreakpointDriveLetterCasingUpper = true;
+      await _testHitBreakpointAndResume();
+    }, skip: !Platform.isWindows);
+
     test('stops at a line breakpoint and can step over (next)', () async {
       final testFile = dap.createTestFile('''
 void main(List<String> args) async {
diff --git a/pkg/dds/test/dap/integration/debug_test.dart b/pkg/dds/test/dap/integration/debug_test.dart
index 057ad74..9d36c45 100644
--- a/pkg/dds/test/dap/integration/debug_test.dart
+++ b/pkg/dds/test/dap/integration/debug_test.dart
@@ -165,6 +165,102 @@
       );
     });
 
+    group('progress notifications', () {
+      /// Helper to verify [events] are the expected start/update/end events
+      /// in-order for a debug session starting.
+      void verifyLaunchProgressEvents(List<Event> events) {
+        final bodies =
+            events.map((e) => e.body as Map<String, Object?>).toList();
+        final start = ProgressStartEventBody.fromMap(bodies[0]);
+        final update = ProgressUpdateEventBody.fromMap(bodies[1]);
+        final end = ProgressEndEventBody.fromMap(bodies[2]);
+
+        expect(start.progressId, isNotNull);
+        expect(start.title, 'Debugger');
+        expect(start.message, 'Starting…');
+        expect(update.progressId, start.progressId);
+        expect(update.message, 'Connecting…');
+        expect(end.progressId, start.progressId);
+        expect(end.message, isNull);
+      }
+
+      test('sends no events by default', () async {
+        final testFile = dap.createTestFile(simpleArgPrintingProgram);
+
+        final standardEvents = dap.client.standardProgressEvents().toList();
+        final customEvents = dap.client.customProgressEvents().toList();
+
+        // Run the script to completion.
+        await Future.wait([
+          dap.client.event('terminated'),
+          dap.client.initialize(),
+          dap.client.launch(testFile.path),
+        ], eagerError: true);
+
+        expect(await standardEvents, isEmpty);
+        expect(await customEvents, isEmpty);
+      });
+
+      test('sends standard events when supported', () async {
+        final testFile = dap.createTestFile(simpleArgPrintingProgram);
+
+        final standardEventsFuture =
+            dap.client.standardProgressEvents().toList();
+        final customEventsFuture = dap.client.customProgressEvents().toList();
+
+        // Run the script to completion.
+        await Future.wait([
+          dap.client.event('terminated'),
+          dap.client.initialize(
+            supportsProgressReporting: true,
+          ),
+          dap.client.launch(testFile.path),
+        ], eagerError: true);
+
+        final standardEvents = await standardEventsFuture;
+        final customEvents = await customEventsFuture;
+
+        // Verify the standard launch events.
+        expect(
+          standardEvents.map((e) => e.event),
+          ['progressStart', 'progressUpdate', 'progressEnd'],
+        );
+        verifyLaunchProgressEvents(standardEvents);
+        // And no custom events.
+        expect(customEvents, isEmpty);
+      });
+
+      test('sends custom events when requested', () async {
+        final testFile = dap.createTestFile(simpleArgPrintingProgram);
+
+        final standardEventsFuture =
+            dap.client.standardProgressEvents().toList();
+        final customEventsFuture = dap.client.customProgressEvents().toList();
+
+        // Run the script to completion.
+        await Future.wait([
+          dap.client.event('terminated'),
+          dap.client.initialize(),
+          dap.client.launch(
+            testFile.path,
+            sendCustomProgressEvents: true,
+          ),
+        ], eagerError: true);
+
+        final standardEvents = await standardEventsFuture;
+        final customEvents = await customEventsFuture;
+
+        // Verify no standard events.
+        expect(standardEvents, isEmpty);
+        // But custom events are sent.
+        expect(
+          customEvents.map((e) => e.event),
+          ['dart.progressStart', 'dart.progressUpdate', 'dart.progressEnd'],
+        );
+        verifyLaunchProgressEvents(customEvents);
+      });
+    });
+
     test('provides a list of threads', () async {
       final client = dap.client;
       final testFile = dap.createTestFile(simpleBreakpointProgram);
@@ -283,7 +379,12 @@
       // 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);
+
+      // Start the program and expect termination.
+      await Future.wait([
+        dap.client.event('terminated'),
+        dap.client.start(file: testFile),
+      ], eagerError: true);
     });
 
     test('can hot reload', () async {
diff --git a/pkg/dds/test/dap/integration/protocol_test.dart b/pkg/dds/test/dap/integration/protocol_test.dart
index 06f5fd9..081e790 100644
--- a/pkg/dds/test/dap/integration/protocol_test.dart
+++ b/pkg/dds/test/dap/integration/protocol_test.dart
@@ -15,7 +15,11 @@
         () async {
       final errorOutput = Completer<String>();
       final server = await DapTestSession.startServer(
-        onError: (e) => errorOutput.complete('$e'),
+        onError: (e) {
+          if (!errorOutput.isCompleted) {
+            errorOutput.complete('$e');
+          }
+        },
       );
       addTearDown(() => server.stop());
       server.sink.add(utf8.encode('not\r\n\r\nvalid'));
diff --git a/pkg/dds/test/dap/integration/test_client.dart b/pkg/dds/test/dap/integration/test_client.dart
index 2de616d..c90e982 100644
--- a/pkg/dds/test/dap/integration/test_client.dart
+++ b/pkg/dds/test/dap/integration/test_client.dart
@@ -38,6 +38,20 @@
 
   late final Future<Uri?> vmServiceUri;
 
+  /// Used to control drive letter casing on Windows for testing.
+  bool? forceDriveLetterCasingUpper;
+
+  /// Used to control drive letter casing on Windows for testing.
+  bool? forceDriveLetterCasingLower;
+
+  /// Used to control drive letter casing for breakpoint requests on Windows for
+  /// testing.
+  bool? forceBreakpointDriveLetterCasingUpper;
+
+  /// Used to control drive letter casing for breakpoint requests on Windows for
+  /// testing.
+  bool? forceBreakpointDriveLetterCasingLower;
+
   DapTestClient._(
     this._channel,
     this._logger, {
@@ -183,6 +197,28 @@
     return _eventController.stream.where((e) => e.event == event);
   }
 
+  /// Returns a stream for standard progress events.
+  Stream<Event> standardProgressEvents() {
+    const standardProgressEvents = {
+      'progressStart',
+      'progressUpdate',
+      'progressEnd'
+    };
+    return _eventController.stream
+        .where((e) => standardProgressEvents.contains(e.event));
+  }
+
+  /// Returns a stream for custom Dart progress events.
+  Stream<Event> customProgressEvents() {
+    const customProgressEvents = {
+      'dart.progressStart',
+      'dart.progressUpdate',
+      'dart.progressEnd'
+    };
+    return _eventController.stream
+        .where((e) => customProgressEvents.contains(e.event));
+  }
+
   /// Records a handler for when the server sends a [request] request.
   void handleRequest(
     String request,
@@ -203,12 +239,14 @@
   Future<Response> initialize({
     String exceptionPauseMode = 'None',
     bool? supportsRunInTerminalRequest,
+    bool? supportsProgressReporting,
   }) async {
     final responses = await Future.wait([
       event('initialized'),
       sendRequest(InitializeRequestArguments(
         adapterID: 'test',
         supportsRunInTerminalRequest: supportsRunInTerminalRequest,
+        supportsProgressReporting: supportsProgressReporting,
       )),
       sendRequest(
         SetExceptionBreakpointsArguments(
@@ -234,15 +272,17 @@
     bool? evaluateGettersInDebugViews,
     bool? evaluateToStringInDebugViews,
     bool? sendLogsToClient,
+    bool? sendCustomProgressEvents,
   }) {
     return sendRequest(
       DartLaunchRequestArguments(
         noDebug: noDebug,
-        program: program,
-        cwd: cwd,
+        program: _normalizePath(program),
+        cwd: cwd != null ? _normalizePath(cwd) : null,
         args: args,
         toolArgs: toolArgs,
-        additionalProjectPaths: additionalProjectPaths,
+        additionalProjectPaths:
+            additionalProjectPaths?.map(_normalizePath).toList(),
         console: console,
         debugSdkLibraries: debugSdkLibraries,
         debugExternalPackageLibraries: debugExternalPackageLibraries,
@@ -252,6 +292,7 @@
         // to the client-side logger, so force logging on which sends VM Service
         // traffic in a custom event.
         sendLogsToClient: sendLogsToClient ?? captureVmServiceTraffic,
+        sendCustomProgressEvents: sendCustomProgressEvents,
       ),
       // We can't automatically pick the command when using a custom type
       // (DartLaunchRequestArguments).
@@ -522,7 +563,7 @@
   Future<void> setBreakpoint(File file, int line, {String? condition}) async {
     await sendRequest(
       SetBreakpointsArguments(
-        source: Source(path: file.path),
+        source: Source(path: _normalizeBreakpointPath(file.path)),
         breakpoints: [SourceBreakpoint(line: line, condition: condition)],
       ),
     );
@@ -532,12 +573,48 @@
   Future<void> setBreakpoints(File file, List<int> lines) async {
     await sendRequest(
       SetBreakpointsArguments(
-        source: Source(path: file.path),
+        source: Source(path: _normalizeBreakpointPath(file.path)),
         breakpoints: lines.map((line) => SourceBreakpoint(line: line)).toList(),
       ),
     );
   }
 
+  /// Normalizes a non-breakpoint path being sent to the debug adapter based on
+  /// the values of [forceDriveLetterCasingUpper] and
+  /// [forceDriveLetterCasingLower].
+  String _normalizePath(String path) {
+    return _forceDriveLetterCasing(
+      path,
+      upper: forceDriveLetterCasingUpper,
+      lower: forceDriveLetterCasingLower,
+    );
+  }
+
+  /// Normalizes a non-breakpoint path being sent to the debug adapter based on
+  /// the values of [forceBreakpointDriveLetterCasingUpper] and
+  /// [forceBreakpointDriveLetterCasingLower].
+  String _normalizeBreakpointPath(String path) {
+    return _forceDriveLetterCasing(
+      path,
+      upper: forceBreakpointDriveLetterCasingUpper,
+      lower: forceBreakpointDriveLetterCasingLower,
+    );
+  }
+
+  String _forceDriveLetterCasing(String path, {bool? upper, bool? lower}) {
+    assert(upper != true || lower != true);
+    if (!Platform.isWindows || path.isEmpty) {
+      return path;
+    }
+    if (upper ?? false) {
+      return path.substring(0, 1).toUpperCase() + path.substring(1);
+    } else if (lower ?? false) {
+      return path.substring(0, 1).toLowerCase() + path.substring(1);
+    } else {
+      return path;
+    }
+  }
+
   /// Sets the exception pause mode to [pauseMode] and expects to pause after
   /// running the script.
   ///
@@ -585,7 +662,7 @@
       initialize(),
       sendRequest(
         SetBreakpointsArguments(
-          source: Source(path: file.path),
+          source: Source(path: _normalizeBreakpointPath(file.path)),
           breakpoints: [
             SourceBreakpoint(
               line: line,
diff --git a/pkg/dds/test/dap/integration/test_scripts.dart b/pkg/dds/test/dap/integration/test_scripts.dart
index 7abf38f..036180f 100644
--- a/pkg/dds/test/dap/integration/test_scripts.dart
+++ b/pkg/dds/test/dap/integration/test_scripts.dart
@@ -127,6 +127,15 @@
   }
 ''';
 
+/// A simple Dart script that has a blank line before its breakpoint, used to
+/// ensure breakpoints that resolve to the same place are handled correctly.
+const simpleBreakpointWithLeadingBlankLineProgram = '''
+  void main(List<String> args) async {
+
+    print('Hello!'); $breakpointMarker
+  }
+''';
+
 /// A simple Dart script that has a breakpoint and an exception used for
 /// testing whether breakpoints and exceptions are being paused on (for example
 /// during detach where they should not).
diff --git a/pkg/dds/test/devtools_server/instance_reuse_test.dart b/pkg/dds/test/devtools_server/instance_reuse_test.dart
index 71d7428..84955eb 100644
--- a/pkg/dds/test/devtools_server/instance_reuse_test.dart
+++ b/pkg/dds/test/devtools_server/instance_reuse_test.dart
@@ -100,6 +100,53 @@
         }
       }, timeout: const Timeout.factor(20));
 
+      test('does not reuse if browser was terminated (unresponsive ping)',
+          () async {
+        // Register the VM.
+        await testController.send(
+          'vm.register',
+          {'uri': testController.appFixture.serviceUri.toString()},
+        );
+
+        // Spawn a DevTools in a browser.
+        final event = await testController.serverStartedEvent.future;
+        final devToolsUri =
+            'http://${event['params']['host']}:${event['params']['port']}';
+        final launchUrl = '$devToolsUri/?page=logging'
+            '&uri=${Uri.encodeQueryComponent(testController.appFixture.serviceUri.toString())}';
+        final chrome = await Chrome.locate()!.start(url: launchUrl);
+        try {
+          {
+            final serverResponse = await testController.waitForClients(
+              requiredConnectionState: true,
+            );
+            expect(serverResponse['clients'], hasLength(1));
+          }
+
+          // Terminate the browser to prevent it responding to future pings.
+          chrome.kill();
+
+          // Send a request to the server to launch and ensure it did
+          // not reuse the existing connection. Launch it on a different page
+          // so we can easily tell once this one has connected.
+          final launchResponse = await testController.sendLaunchDevToolsRequest(
+            useVmService: useVmService,
+            reuseWindows: true,
+            page: 'memory',
+          );
+          expect(launchResponse['reused'], isFalse);
+
+          // Ensure there's now two connections.
+          final serverResponse = await testController.waitForClients(
+            requiredConnectionState: true,
+            requiredPage: 'memory',
+          );
+          expect(serverResponse['clients'], hasLength(2));
+        } finally {
+          chrome.kill();
+        }
+      }, timeout: const Timeout.factor(20));
+
       test('reuses DevTools instance if not connected to a VM', () async {
         // Register the VM.
         await testController.send(
diff --git a/pkg/dds/tool/dap/README.md b/pkg/dds/tool/dap/README.md
index 5275609..06f677d 100644
--- a/pkg/dds/tool/dap/README.md
+++ b/pkg/dds/tool/dap/README.md
@@ -30,6 +30,7 @@
 - `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
+- `bool? sendCustomProgressEvents` - whether to send custom `dart.progressStart`, `dart.progressUpdate`, `dart.progressEnd` progress events in place of standard DAP `progressStart`, `progressUpdate`, `progressEnd` events. When this is set, only standard events will not be sent regardless of the `supportsProgressReporting` capability.
 
 Arguments specific to `launchRequest` are:
 
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 4962bdc..4ca915c 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -2170,18 +2170,21 @@
     var jsGetter = js_ast.Method(name, getter, isGetter: true)
       ..sourceInformation = _nodeStart(field);
 
-    var args = field.isFinal
-        ? [js_ast.Super(), name]
-        : [js_ast.This(), virtualFieldSymbol];
-
-    js_ast.Expression value = _emitIdentifier('value');
-    if (!field.isFinal && isCovariantField(field)) {
-      value = _emitCast(value, field.type);
+    var body = <js_ast.Statement>[];
+    var value = _emitIdentifier('value');
+    if (_requiresExtraNullCheck(field.setterType, field.annotations)) {
+      body.add(
+          _nullSafetyParameterCheck(value, field.location, field.name.text));
     }
-    args.add(value);
-
-    var jsSetter = js_ast.Method(
-        name, js.fun('function(value) { #[#] = #; }', args),
+    var args = field.isFinal
+        ? [js_ast.Super(), name, value]
+        : [
+            js_ast.This(),
+            virtualFieldSymbol,
+            if (isCovariantField(field)) _emitCast(value, field.type) else value
+          ];
+    body.add(js.call('#[#] = #', args).toStatement());
+    var jsSetter = js_ast.Method(name, js_ast.Fun([value], js_ast.Block(body)),
         isSetter: true)
       ..sourceInformation = _nodeStart(field);
 
@@ -2368,10 +2371,16 @@
               member.fileOffset,
               member.name.text.length));
         if (!member.isFinal && !member.isConst) {
-          // TODO(jmesserly): currently uses a dummy setter to indicate
-          // writable.
+          var body = <js_ast.Statement>[];
+          var value = _emitIdentifier('value');
+          if (_requiresExtraNullCheck(member.setterType, member.annotations)) {
+            body.add(_nullSafetyParameterCheck(
+                value, member.location, member.name.text));
+          }
+          // Even when no null check is present a dummy setter is still required
+          // to indicate writeable.
           accessors.add(js_ast.Method(
-              access, js.call('function(_) {}') as js_ast.Fun,
+              access, js_ast.Fun([value], js_ast.Block(body)),
               isSetter: true));
         }
       } else if (member is Procedure) {
@@ -3608,6 +3617,46 @@
   bool _mustBeNonNullable(DartType type) =>
       type.nullability == Nullability.nonNullable;
 
+  /// Returns `true` when an additional null check is needed because of the
+  /// null safety compile mode, the null safety migration status of the current
+  /// library and the provided [type] with its [annotations].
+  bool _requiresExtraNullCheck(DartType type, List<Expression> annotations) =>
+      !_options.soundNullSafety &&
+      // Libraries that haven't been migrated to null safety represent
+      // non-nullable as legacy.
+      _currentLibrary!.nonNullable == Nullability.nonNullable &&
+      _mustBeNonNullable(type) &&
+      !_annotatedNotNull(annotations);
+
+  /// Returns a null check for [value] that if fails produces an error message
+  /// containing the [location] and [name] of the original value being checked.
+  ///
+  /// This is used to generate checks for non-nullable parameters when running
+  /// with weak null safety. The checks can be silent, warn, or throw, depending
+  /// on the flags set in the SDK at runtime.
+  js_ast.Statement _nullSafetyParameterCheck(
+      js_ast.Identifier value, Location? location, String? name) {
+    // TODO(nshahan): Remove when weak mode null safety assertions are no longer
+    // supported.
+    // The check on `field.setterType` is per:
+    // https://github.com/dart-lang/language/blob/master/accepted/2.12/nnbd/feature-specification.md#automatic-debug-assertion-insertion
+    var condition = js.call('# == null', [value]);
+    // Offsets are not available for compiler-generated variables
+    // Get the best available location even if the offset is missing.
+    // https://github.com/dart-lang/sdk/issues/34942
+    return js.statement(' if (#) #;', [
+      condition,
+      runtimeCall('nullFailed(#, #, #, #)', [
+        location != null
+            ? _cacheUri(location.file.toString())
+            : js_ast.LiteralNull(),
+        js.number(location?.line ?? -1),
+        js.number(location?.column ?? -1),
+        js.escapedString('$name')
+      ])
+    ]);
+  }
+
   /// Emits argument initializers, which handles optional/named args, as well
   /// as generic type checks needed due to our covariance.
   List<js_ast.Statement> _emitArgumentInitializers(
@@ -3638,30 +3687,8 @@
 
       if (_annotatedNullCheck(p.annotations)) {
         body.add(_nullParameterCheck(jsParam));
-      } else if (!_options.soundNullSafety &&
-          _mustBeNonNullable(p.type) &&
-          !_annotatedNotNull(p.annotations)) {
-        // TODO(vsm): Remove if / when CFE does this:
-        // https://github.com/dart-lang/sdk/issues/40597
-        // The check on `p.type` is per:
-        // https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion
-        var condition = js.call('# == null', [jsParam]);
-        // Offsets are not available for compiler-generated variables
-        // Get the best available location even if the offset is missing.
-        // https://github.com/dart-lang/sdk/issues/34942
-        var location = p.location;
-        var check = js.statement(' if (#) #;', [
-          condition,
-          runtimeCall('nullFailed(#, #, #, #)', [
-            location != null
-                ? _cacheUri(location.file.toString())
-                : js_ast.LiteralNull(),
-            js.number(location?.line ?? -1),
-            js.number(location?.column ?? -1),
-            js.escapedString('${p.name}')
-          ])
-        ]);
-        body.add(check);
+      } else if (_requiresExtraNullCheck(p.type, p.annotations)) {
+        body.add(_nullSafetyParameterCheck(jsParam, p.location, p.name));
       }
     }
 
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 3b2416f..70b8712 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -9,6 +9,7 @@
 import 'package:_js_interop_checks/js_interop_checks.dart';
 import 'package:_js_interop_checks/src/transformations/js_util_optimizer.dart';
 import 'package:_js_interop_checks/src/transformations/static_interop_class_eraser.dart';
+import 'package:_js_interop_checks/src/transformations/static_interop_mock_creator.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart';
@@ -16,6 +17,7 @@
 import 'package:kernel/target/changed_structure_notifier.dart';
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/transformations/track_widget_constructor_locations.dart';
+import 'package:kernel/type_environment.dart';
 
 import 'constants.dart' show DevCompilerConstantsBackend;
 import 'kernel_helpers.dart';
@@ -168,13 +170,24 @@
         coreTypes,
         diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>,
         _nativeClasses!);
+    var staticInteropMockCreator = StaticInteropMockCreator(
+        TypeEnvironment(coreTypes, hierarchy), diagnosticReporter);
     var jsUtilOptimizer = JsUtilOptimizer(coreTypes, hierarchy);
-    var staticInteropClassEraser =
-        StaticInteropClassEraser(coreTypes, referenceFromIndex);
+    // Cache extensions for entire component before creating mock.
+    for (var library in libraries) {
+      staticInteropMockCreator.processExtensions(library);
+    }
     for (var library in libraries) {
       _CovarianceTransformer(library).transform();
       jsInteropChecks.visitLibrary(library);
+      staticInteropMockCreator.visitLibrary(library);
       jsUtilOptimizer.visitLibrary(library);
+    }
+    // Do the erasure after any possible mock creation to avoid erasing types
+    // that need to be used during mock conformance checking.
+    var staticInteropClassEraser =
+        StaticInteropClassEraser(coreTypes, referenceFromIndex);
+    for (var library in libraries) {
       staticInteropClassEraser.visitLibrary(library);
     }
   }
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 bac8946..7d6aea0 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
@@ -171,6 +171,14 @@
       experimentEnabledVersion: const Version(2, 13),
       experimentReleasedVersion: const Version(2, 13));
 
+  static const ExperimentalFlag patterns = const ExperimentalFlag(
+      name: 'patterns',
+      isEnabledByDefault: false,
+      isExpired: false,
+      enabledVersion: const Version(2, 19),
+      experimentEnabledVersion: const Version(2, 19),
+      experimentReleasedVersion: const Version(2, 19));
+
   static const ExperimentalFlag records = const ExperimentalFlag(
       name: 'records',
       isEnabledByDefault: false,
@@ -219,6 +227,14 @@
       experimentEnabledVersion: const Version(2, 14),
       experimentReleasedVersion: const Version(2, 14));
 
+  static const ExperimentalFlag unnamedLibraries = const ExperimentalFlag(
+      name: 'unnamed-libraries',
+      isEnabledByDefault: false,
+      isExpired: false,
+      enabledVersion: const Version(2, 19),
+      experimentEnabledVersion: const Version(2, 19),
+      experimentReleasedVersion: const Version(2, 19));
+
   static const ExperimentalFlag valueClass = const ExperimentalFlag(
       name: 'value-class',
       isEnabledByDefault: false,
@@ -342,6 +358,10 @@
   GlobalFeature get nonfunctionTypeAliases => _nonfunctionTypeAliases ??=
       _computeGlobalFeature(ExperimentalFlag.nonfunctionTypeAliases);
 
+  GlobalFeature? _patterns;
+  GlobalFeature get patterns =>
+      _patterns ??= _computeGlobalFeature(ExperimentalFlag.patterns);
+
   GlobalFeature? _records;
   GlobalFeature get records =>
       _records ??= _computeGlobalFeature(ExperimentalFlag.records);
@@ -366,6 +386,10 @@
   GlobalFeature get tripleShift =>
       _tripleShift ??= _computeGlobalFeature(ExperimentalFlag.tripleShift);
 
+  GlobalFeature? _unnamedLibraries;
+  GlobalFeature get unnamedLibraries => _unnamedLibraries ??=
+      _computeGlobalFeature(ExperimentalFlag.unnamedLibraries);
+
   GlobalFeature? _valueClass;
   GlobalFeature get valueClass =>
       _valueClass ??= _computeGlobalFeature(ExperimentalFlag.valueClass);
@@ -468,6 +492,11 @@
           canonicalUri,
           libraryVersion);
 
+  LibraryFeature? _patterns;
+  LibraryFeature get patterns =>
+      _patterns ??= globalFeatures._computeLibraryFeature(
+          ExperimentalFlag.patterns, canonicalUri, libraryVersion);
+
   LibraryFeature? _records;
   LibraryFeature get records =>
       _records ??= globalFeatures._computeLibraryFeature(
@@ -498,6 +527,11 @@
       _tripleShift ??= globalFeatures._computeLibraryFeature(
           ExperimentalFlag.tripleShift, canonicalUri, libraryVersion);
 
+  LibraryFeature? _unnamedLibraries;
+  LibraryFeature get unnamedLibraries =>
+      _unnamedLibraries ??= globalFeatures._computeLibraryFeature(
+          ExperimentalFlag.unnamedLibraries, canonicalUri, libraryVersion);
+
   LibraryFeature? _valueClass;
   LibraryFeature get valueClass =>
       _valueClass ??= globalFeatures._computeLibraryFeature(
@@ -541,6 +575,8 @@
       return ExperimentalFlag.nonNullable;
     case "nonfunction-type-aliases":
       return ExperimentalFlag.nonfunctionTypeAliases;
+    case "patterns":
+      return ExperimentalFlag.patterns;
     case "records":
       return ExperimentalFlag.records;
     case "set-literals":
@@ -553,6 +589,8 @@
       return ExperimentalFlag.testExperiment;
     case "triple-shift":
       return ExperimentalFlag.tripleShift;
+    case "unnamed-libraries":
+      return ExperimentalFlag.unnamedLibraries;
     case "value-class":
       return ExperimentalFlag.valueClass;
     case "variance":
@@ -590,6 +628,7 @@
   ExperimentalFlag.nonNullable: ExperimentalFlag.nonNullable.isEnabledByDefault,
   ExperimentalFlag.nonfunctionTypeAliases:
       ExperimentalFlag.nonfunctionTypeAliases.isEnabledByDefault,
+  ExperimentalFlag.patterns: ExperimentalFlag.patterns.isEnabledByDefault,
   ExperimentalFlag.records: ExperimentalFlag.records.isEnabledByDefault,
   ExperimentalFlag.setLiterals: ExperimentalFlag.setLiterals.isEnabledByDefault,
   ExperimentalFlag.spreadCollections:
@@ -599,6 +638,8 @@
   ExperimentalFlag.testExperiment:
       ExperimentalFlag.testExperiment.isEnabledByDefault,
   ExperimentalFlag.tripleShift: ExperimentalFlag.tripleShift.isEnabledByDefault,
+  ExperimentalFlag.unnamedLibraries:
+      ExperimentalFlag.unnamedLibraries.isEnabledByDefault,
   ExperimentalFlag.valueClass: ExperimentalFlag.valueClass.isEnabledByDefault,
   ExperimentalFlag.variance: ExperimentalFlag.variance.isEnabledByDefault,
 };
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 fe0a730..b4c7847 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -77,6 +77,11 @@
   // TODO(johnniwinther): Should the only exist on [SourceLibraryBuilder]?
   Iterator<Builder> get localMembersIterator;
 
+  /// Returns an iterator of all members of specified type
+  /// declared in this library, including duplicate declarations.
+  // TODO(johnniwinther): Should the only exist on [SourceLibraryBuilder]?
+  Iterator<T> localMembersIteratorOfType<T extends Builder>();
+
   /// Returns an iterator of all members (typedefs, classes and members)
   /// declared in this library, including duplicate declarations.
   ///
@@ -208,6 +213,12 @@
   }
 
   @override
+  Iterator<T> localMembersIteratorOfType<T extends Builder>() {
+    return scope.filteredIterator<T>(
+        parent: this, includeDuplicates: true, includeAugmentations: true);
+  }
+
+  @override
   NameIterator<Builder> get localMembersNameIterator {
     return scope.filteredNameIterator(
         parent: this, includeDuplicates: true, includeAugmentations: true);
diff --git a/pkg/front_end/lib/src/fasta/builder/omitted_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/omitted_type_builder.dart
index 78e06d8..bb0ea74 100644
--- a/pkg/front_end/lib/src/fasta/builder/omitted_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/omitted_type_builder.dart
@@ -150,7 +150,7 @@
       } else {
         registerInferredType(const DynamicType());
       }
-      assert(hasType);
+      assert(hasType, "No type computed for $this");
     }
     return type;
   }
diff --git a/pkg/front_end/lib/src/fasta/crash.dart b/pkg/front_end/lib/src/fasta/crash.dart
index c9a8700..11f22c8 100644
--- a/pkg/front_end/lib/src/fasta/crash.dart
+++ b/pkg/front_end/lib/src/fasta/crash.dart
@@ -10,6 +10,7 @@
     show ContentType, HttpClient, HttpClientRequest, SocketException, stderr;
 
 import 'problems.dart' show DebugAbort;
+import 'uri_offset.dart';
 
 const String defaultServerAddress = "http://127.0.0.1:59410/";
 
@@ -35,11 +36,20 @@
 
   @override
   String toString() {
-    return """
-Crash when compiling $uri,
-at character offset $charOffset:
-$error${trace == null ? '' : '\n$trace'}
-""";
+    StringBuffer sb = new StringBuffer();
+    if (uri != null) {
+      sb.write("Crash when compiling $uri");
+      if (charOffset != null && charOffset != -1) {
+        sb.write(" at character offset $charOffset:\n");
+      } else {
+        sb.write(":\n");
+      }
+    } else {
+      sb.write("Crash when compiling:\n");
+    }
+    sb.write(error);
+    sb.write("\n");
+    return sb.toString();
   }
 }
 
@@ -116,7 +126,7 @@
 }
 
 Future<T> withCrashReporting<T>(
-    Future<T> Function() action, Uri? Function() currentUri) async {
+    Future<T> Function() action, UriOffset? Function() currentUriOffset) async {
   resetCrashReporting();
   try {
     return await action();
@@ -125,6 +135,7 @@
   } on DebugAbort {
     rethrow;
   } catch (e, s) {
-    return reportCrash(e, s, currentUri());
+    UriOffset? uriOffset = currentUriOffset();
+    return reportCrash(e, s, uriOffset?.uri, uriOffset?.fileOffset);
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index 331b622..5e8c32e 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -191,7 +191,7 @@
   @override
   void forEachConstructor(void Function(String, MemberBuilder) f,
       {bool includeInjectedConstructors = false}) {
-    constructorScope.forEach(f);
+    constructorScope.unfilteredNameIterator.forEach(f);
   }
 
   void clearCachedValues() {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
index 15788e8..b55c117 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
@@ -3661,6 +3661,154 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
         Message Function(
+            String name,
+            String name2,
+            DartType _type,
+            String name3,
+            String name4,
+            DartType _type2,
+            bool isNonNullableByDefault)>
+    templateJsInteropStaticInteropMockMemberNotSubtype = const Template<
+            Message Function(
+                String name,
+                String name2,
+                DartType _type,
+                String name3,
+                String name4,
+                DartType _type2,
+                bool isNonNullableByDefault)>(
+        problemMessageTemplate:
+            r"""Dart class member '#name.#name2' with type '#type' is not a subtype of `@staticInterop` external extension member '#name3.#name4' with type '#type2'.""",
+        correctionMessageTemplate:
+            r"""Change '#name.#name2' to be a subtype of '#name3.#name4'.""",
+        withArguments:
+            _withArgumentsJsInteropStaticInteropMockMemberNotSubtype);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+        Message Function(
+            String name,
+            String name2,
+            DartType _type,
+            String name3,
+            String name4,
+            DartType _type2,
+            bool isNonNullableByDefault)>
+    codeJsInteropStaticInteropMockMemberNotSubtype = const Code<
+        Message Function(
+            String name,
+            String name2,
+            DartType _type,
+            String name3,
+            String name4,
+            DartType _type2,
+            bool isNonNullableByDefault)>(
+  "JsInteropStaticInteropMockMemberNotSubtype",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsJsInteropStaticInteropMockMemberNotSubtype(
+    String name,
+    String name2,
+    DartType _type,
+    String name3,
+    String name4,
+    DartType _type2,
+    bool isNonNullableByDefault) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (name2.isEmpty) throw 'No name provided';
+  name2 = demangleMixinApplicationName(name2);
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  if (name3.isEmpty) throw 'No name provided';
+  name3 = demangleMixinApplicationName(name3);
+  if (name4.isEmpty) throw 'No name provided';
+  name4 = demangleMixinApplicationName(name4);
+  List<Object> type2Parts = labeler.labelType(_type2);
+  String type = typeParts.join();
+  String type2 = type2Parts.join();
+  return new Message(codeJsInteropStaticInteropMockMemberNotSubtype,
+      problemMessage:
+          """Dart class member '${name}.${name2}' with type '${type}' is not a subtype of `@staticInterop` external extension member '${name3}.${name4}' with type '${type2}'.""" +
+              labeler.originMessages,
+      correctionMessage:
+          """Change '${name}.${name2}' to be a subtype of '${name3}.${name4}'.""",
+      arguments: {
+        'name': name,
+        'name2': name2,
+        'type': _type,
+        'name3': name3,
+        'name4': name4,
+        'type2': _type2
+      });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(DartType _type, bool isNonNullableByDefault)>
+    templateJsInteropStaticInteropMockNotDartInterfaceType = const Template<
+            Message Function(DartType _type, bool isNonNullableByDefault)>(
+        problemMessageTemplate:
+            r"""Second type argument '#type' is not a Dart interface type.""",
+        correctionMessageTemplate: r"""Use a Dart class instead.""",
+        withArguments:
+            _withArgumentsJsInteropStaticInteropMockNotDartInterfaceType);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(DartType _type, bool isNonNullableByDefault)>
+    codeJsInteropStaticInteropMockNotDartInterfaceType =
+    const Code<Message Function(DartType _type, bool isNonNullableByDefault)>(
+  "JsInteropStaticInteropMockNotDartInterfaceType",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsJsInteropStaticInteropMockNotDartInterfaceType(
+    DartType _type, bool isNonNullableByDefault) {
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeJsInteropStaticInteropMockNotDartInterfaceType,
+      problemMessage:
+          """Second type argument '${type}' is not a Dart interface type.""" +
+              labeler.originMessages,
+      correctionMessage: """Use a Dart class instead.""",
+      arguments: {'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(DartType _type, bool isNonNullableByDefault)>
+    templateJsInteropStaticInteropMockNotStaticInteropType = const Template<
+            Message Function(DartType _type, bool isNonNullableByDefault)>(
+        problemMessageTemplate:
+            r"""First type argument '#type' is not a `@staticInterop` type.""",
+        correctionMessageTemplate: r"""Use a `@staticInterop` class instead.""",
+        withArguments:
+            _withArgumentsJsInteropStaticInteropMockNotStaticInteropType);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(DartType _type, bool isNonNullableByDefault)>
+    codeJsInteropStaticInteropMockNotStaticInteropType =
+    const Code<Message Function(DartType _type, bool isNonNullableByDefault)>(
+  "JsInteropStaticInteropMockNotStaticInteropType",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsJsInteropStaticInteropMockNotStaticInteropType(
+    DartType _type, bool isNonNullableByDefault) {
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeJsInteropStaticInteropMockNotStaticInteropType,
+      problemMessage:
+          """First type argument '${type}' is not a `@staticInterop` type.""" +
+              labeler.originMessages,
+      correctionMessage: """Use a `@staticInterop` class instead.""",
+      arguments: {'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+        Message Function(
             DartType _type, DartType _type2, bool isNonNullableByDefault)>
     templateMainWrongParameterType = const Template<
             Message Function(
diff --git a/pkg/front_end/lib/src/fasta/import.dart b/pkg/front_end/lib/src/fasta/import.dart
index b34f25b..38072ec 100644
--- a/pkg/front_end/lib/src/fasta/import.dart
+++ b/pkg/front_end/lib/src/fasta/import.dart
@@ -8,6 +8,7 @@
 
 import 'builder/builder.dart';
 import 'builder/library_builder.dart';
+import 'builder/name_iterator.dart';
 import 'builder/prefix_builder.dart';
 
 import 'kernel/utils.dart' show toKernelCombinators;
@@ -18,8 +19,6 @@
 
 import 'source/source_library_builder.dart';
 
-import 'scope.dart' show NameIteratorExtension;
-
 class Import {
   /// The library that is importing [imported];
   final SourceLibraryBuilder importer;
@@ -76,21 +75,31 @@
         prefixBuilder!.addToExportScope(name, member, charOffset);
       };
     }
-    imported!.exportScope
-        .filteredNameIterator(
-            includeDuplicates: false, includeAugmentations: false)
-        .forEach((String name, Builder member) {
+    NameIterator<Builder> iterator = imported!.exportScope.filteredNameIterator(
+        includeDuplicates: false, includeAugmentations: false);
+    while (iterator.moveNext()) {
+      String name = iterator.name;
+      Builder member = iterator.current;
+      bool include = true;
       if (combinators != null) {
         for (CombinatorBuilder combinator in combinators!) {
-          if (combinator.isShow && !combinator.names.contains(name)) return;
-          if (combinator.isHide && combinator.names.contains(name)) return;
+          if (combinator.isShow && !combinator.names.contains(name)) {
+            include = false;
+            break;
+          }
+          if (combinator.isHide && combinator.names.contains(name)) {
+            include = false;
+            break;
+          }
         }
       }
-      add(name, member);
-    });
+      if (include) {
+        add(name, member);
+      }
+    }
     if (prefixBuilder != null) {
-      Builder? existing =
-          importer.addBuilder(prefix, prefixBuilder!, prefixCharOffset);
+      Builder? existing = importer.addBuilder(
+          prefixBuilder!.name, prefixBuilder!, prefixCharOffset);
       if (existing == prefixBuilder) {
         importer.addToScope(prefix!, prefixBuilder!, prefixCharOffset, true);
       }
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index e8d1667..78ab0dc 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -128,6 +128,7 @@
 
 import 'source/source_class_builder.dart' show SourceClassBuilder;
 
+import 'source/source_extension_builder.dart';
 import 'util/error_reporter_file_copier.dart' show saveAsGzip;
 
 import 'util/experiment_environment_getter.dart'
@@ -820,6 +821,10 @@
         NameIterator iterator = builder.localMembersNameIterator;
         while (iterator.moveNext()) {
           Builder childBuilder = iterator.current;
+          if (childBuilder is SourceExtensionBuilder &&
+              childBuilder.isUnnamedExtension) {
+            continue;
+          }
           String name = iterator.name;
           Map<String, Builder> map;
           if (childBuilder.isSetter) {
@@ -929,27 +934,26 @@
 
           // TODO(johnniwinther): Should this include non-local (i.e. injected)
           // members?
-          Iterator<Builder> iterator = builder.localMembersIterator;
+          Iterator<SourceClassBuilder> iterator =
+              builder.localMembersIteratorOfType();
           while (iterator.moveNext()) {
-            Builder childBuilder = iterator.current;
-            if (childBuilder is SourceClassBuilder) {
-              TypeBuilder? typeBuilder = childBuilder.supertypeBuilder;
-              _replaceTypeBuilder(
-                  replacementMap, replacementSettersMap, typeBuilder);
-              typeBuilder = childBuilder.mixedInTypeBuilder;
-              _replaceTypeBuilder(
-                  replacementMap, replacementSettersMap, typeBuilder);
-              if (childBuilder.onTypes != null) {
-                for (typeBuilder in childBuilder.onTypes!) {
-                  _replaceTypeBuilder(
-                      replacementMap, replacementSettersMap, typeBuilder);
-                }
+            SourceClassBuilder childBuilder = iterator.current;
+            TypeBuilder? typeBuilder = childBuilder.supertypeBuilder;
+            _replaceTypeBuilder(
+                replacementMap, replacementSettersMap, typeBuilder);
+            typeBuilder = childBuilder.mixedInTypeBuilder;
+            _replaceTypeBuilder(
+                replacementMap, replacementSettersMap, typeBuilder);
+            if (childBuilder.onTypes != null) {
+              for (typeBuilder in childBuilder.onTypes!) {
+                _replaceTypeBuilder(
+                    replacementMap, replacementSettersMap, typeBuilder);
               }
-              if (childBuilder.interfaceBuilders != null) {
-                for (typeBuilder in childBuilder.interfaceBuilders!) {
-                  _replaceTypeBuilder(
-                      replacementMap, replacementSettersMap, typeBuilder);
-                }
+            }
+            if (childBuilder.interfaceBuilders != null) {
+              for (typeBuilder in childBuilder.interfaceBuilders!) {
+                _replaceTypeBuilder(
+                    replacementMap, replacementSettersMap, typeBuilder);
               }
             }
           }
@@ -1204,10 +1208,10 @@
       for (LibraryBuilder builder in reusedResult.notReusedLibraries) {
         // TODO(johnniwinther): Should this include non-local (i.e. injected)
         // members?
-        Iterator<Builder> iterator = builder.localMembersIterator;
+        Iterator<ClassBuilder> iterator = builder.localMembersIteratorOfType();
         while (iterator.moveNext()) {
-          Builder childBuilder = iterator.current;
-          if (childBuilder is ClassBuilder && childBuilder.isMacro) {
+          ClassBuilder childBuilder = iterator.current;
+          if (childBuilder.isMacro) {
             // Changes to a library with macro classes can affect any class that
             // depends on it.
             recorderForTesting?.recordAdvancedInvalidationResult(
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 b3077f0..28504c9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -382,15 +382,18 @@
                     libraryBuilder.importUri.path == "ui"),
         needsImplicitSuperInitializer =
             declarationBuilder is SourceClassBuilder &&
-                coreTypes.objectClass != declarationBuilder.cls,
+                coreTypes.objectClass != declarationBuilder.cls &&
+                !member.isExternal,
         benchmarker = libraryBuilder.loader.target.benchmarker,
         this.scope = enclosingScope {
-    formalParameterScope
-        ?.filteredIterator<VariableBuilder>(
-            includeDuplicates: false, includeAugmentations: false)
-        .forEach((VariableBuilder builder) {
-      typeInferrer.assignedVariables.declare(builder.variable!);
-    });
+    Iterator<VariableBuilder>? iterator =
+        formalParameterScope?.filteredIterator<VariableBuilder>(
+            includeDuplicates: false, includeAugmentations: false);
+    if (iterator != null) {
+      while (iterator.moveNext()) {
+        typeInferrer.assignedVariables.declare(iterator.current.variable!);
+      }
+    }
   }
 
   BodyBuilder.withParents(FieldBuilder field, SourceLibraryBuilder part,
@@ -2255,7 +2258,10 @@
   }
 
   @override
-  void handleParenthesizedCondition(Token token) {
+  void handleParenthesizedCondition(Token token, Token? case_) {
+    if (case_ != null) {
+      throw new UnimplementedError('TODO(paulberry)');
+    }
     assert(checkState(token, [
       unionOfKinds([
         ValueKinds.Expression,
@@ -3963,7 +3969,7 @@
   }
 
   @override
-  void endRecordLiteral(Token token, int count) {
+  void endRecordLiteral(Token token, int count, Token? constKeyword) {
     debugEvent("RecordLiteral");
     assert(checkState(
         token,
@@ -4023,7 +4029,10 @@
       }
     }
     push(new InternalRecordLiteral(
-        positional, named, namedElements, originalElementOrder));
+        positional, named, namedElements, originalElementOrder,
+        isConst:
+            constKeyword != null || constantContext == ConstantContext.inferred)
+      ..fileOffset = token.offset);
   }
 
   void buildLiteralSet(List<TypeBuilder>? typeArguments, Token? constKeyword,
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index d2b8ab7..1c32822 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -283,13 +283,12 @@
         positional[index] = field;
       }
     }
-    List<ConstantRecordNamedField>? named;
-    for (int index = 0; index < node.named.length; index++) {
-      ConstantRecordNamedField namedField = node.named[index];
-      Constant? value = visitConstant(namedField.value);
+    Map<String, Constant>? named;
+    for (MapEntry<String, Constant> entry in node.named.entries) {
+      Constant? value = visitConstant(entry.value);
       if (value != null) {
-        named ??= node.named.toList(growable: false);
-        named[index] = new ConstantRecordNamedField(namedField.name, value);
+        named ??= new Map<String, Constant>.of(node.named);
+        named[entry.key] = value;
       }
     }
     if (recordType != null || positional != null || named != null) {
@@ -804,8 +803,42 @@
   TreeNode visitRecordLiteral(RecordLiteral node, TreeNode? removalSentinel) {
     if (node.isConst) {
       return evaluateAndTransformWithContext(node, node);
+    } else {
+      // A record literal is a compile-time constant expression if and only
+      // if all its field expressions are compile-time constant expressions.
+
+      bool allConstant = true;
+
+      List<Constant> positional = [];
+
+      for (int i = 0; i < node.positional.length; i++) {
+        Expression result = transform(node.positional[i]);
+        node.positional[i] = result..parent = node;
+        if (allConstant && result is ConstantExpression) {
+          positional.add(result.constant);
+        } else {
+          allConstant = false;
+        }
+      }
+
+      Map<String, Constant> named = {};
+      for (NamedExpression expression in node.named) {
+        Expression result = transform(expression.value);
+        expression.value = result..parent = expression;
+        if (allConstant && result is ConstantExpression) {
+          named[expression.name] = result.constant;
+        } else {
+          allConstant = false;
+        }
+      }
+
+      if (allConstant) {
+        Constant constant = constantEvaluator.canonicalize(
+            new RecordConstant(positional, named, node.recordType));
+        return makeConstantExpression(constant, node);
+      }
+      return node;
     }
-    return super.visitRecordLiteral(node, removalSentinel);
   }
 
   @override
@@ -1506,11 +1539,34 @@
 
   @override
   Constant visitRecordLiteral(RecordLiteral node) {
-    // TODO(cstefantsova): Implement RecordConstantBuilder and this method.
-    return createExpressionErrorConstant(
-        node,
-        templateNotConstantExpression
-            .withArguments('Record literal constants not supported.'));
+    // A record literal is a compile-time constant expression if and only
+    // if all its field expressions are compile-time constant expressions.
+    //
+    // This visitor is called when the context requires the literal to be
+    // constant, so we report an error on the expressions when these are not
+    // constants.
+
+    List<Constant>? positional = _evaluatePositionalArguments(node.positional);
+    if (positional == null) {
+      AbortConstant error = _gotError!;
+      _gotError = null;
+      return error;
+    }
+    assert(_gotError == null);
+    // ignore: unnecessary_null_comparison
+    assert(positional != null);
+
+    Map<String, Constant>? named = _evaluateNamedArguments(node.named);
+    if (named == null) {
+      AbortConstant error = _gotError!;
+      _gotError = null;
+      return error;
+    }
+    assert(_gotError == null);
+    // ignore: unnecessary_null_comparison
+    assert(named != null);
+
+    return new RecordConstant(positional, named, node.recordType);
   }
 
   @override
@@ -1656,19 +1712,19 @@
           node, templateAbstractClassInstantiation.withArguments(klass.name));
     }
 
-    final List<Constant>? positionals =
-        _evaluatePositionalArguments(node.arguments);
-    if (positionals == null) {
+    final List<Constant>? positional =
+        _evaluatePositionalArguments(node.arguments.positional);
+    if (positional == null) {
       AbortConstant error = _gotError!;
       _gotError = null;
       return error;
     }
     assert(_gotError == null);
     // ignore: unnecessary_null_comparison
-    assert(positionals != null);
+    assert(positional != null);
 
     final Map<String, Constant>? named =
-        _evaluateNamedArguments(node.arguments);
+        _evaluateNamedArguments(node.arguments.named);
     if (named == null) {
       AbortConstant error = _gotError!;
       _gotError = null;
@@ -1683,14 +1739,14 @@
       return unevaluated(
           node,
           new ConstructorInvocation(constructor,
-              unevaluatedArguments(positionals, named, node.arguments.types),
+              unevaluatedArguments(positional, named, node.arguments.types),
               isConst: true));
     }
 
     // Special case the dart:core's Symbol class here and convert it to a
     // [SymbolConstant].  For invalid values we report a compile-time error.
     if (isSymbol) {
-      final Constant nameValue = positionals.single;
+      final Constant nameValue = positional.single;
 
       // For libraries with null safety Symbol constructor accepts arbitrary
       // string as argument.
@@ -1729,13 +1785,13 @@
       if (shouldBeUnevaluated) {
         enterLazy();
         AbortConstant? error = handleConstructorInvocation(
-            constructor, typeArguments, positionals, named, node);
+            constructor, typeArguments, positional, named, node);
         if (error != null) return error;
         leaveLazy();
         return unevaluated(node, instanceBuilder!.buildUnevaluatedInstance());
       }
       AbortConstant? error = handleConstructorInvocation(
-          constructor, typeArguments, positionals, named, node);
+          constructor, typeArguments, positional, named, node);
       if (error != null) return error;
       if (shouldBeUnevaluated) {
         return unevaluated(node, instanceBuilder!.buildUnevaluatedInstance());
@@ -2004,7 +2060,7 @@
           assert(types != null);
 
           List<Constant>? positionalArguments =
-              _evaluatePositionalArguments(init.arguments);
+              _evaluatePositionalArguments(init.arguments.positional);
           if (positionalArguments == null) {
             AbortConstant error = _gotError!;
             _gotError = null;
@@ -2014,7 +2070,7 @@
           // ignore: unnecessary_null_comparison
           assert(positionalArguments != null);
           Map<String, Constant>? namedArguments =
-              _evaluateNamedArguments(init.arguments);
+              _evaluateNamedArguments(init.arguments.named);
           if (namedArguments == null) {
             AbortConstant error = _gotError!;
             _gotError = null;
@@ -2034,7 +2090,7 @@
               init, init.target, messageConstConstructorRedirectionToNonConst);
           if (error != null) return error;
           List<Constant>? positionalArguments =
-              _evaluatePositionalArguments(init.arguments);
+              _evaluatePositionalArguments(init.arguments.positional);
           if (positionalArguments == null) {
             AbortConstant error = _gotError!;
             _gotError = null;
@@ -2045,7 +2101,7 @@
           assert(positionalArguments != null);
 
           Map<String, Constant>? namedArguments =
-              _evaluateNamedArguments(init.arguments);
+              _evaluateNamedArguments(init.arguments.named);
           if (namedArguments == null) {
             AbortConstant error = _gotError!;
             _gotError = null;
@@ -2172,7 +2228,7 @@
     final Constant receiver = _evaluateSubexpression(node.receiver);
     if (receiver is AbortConstant) return receiver;
     final List<Constant>? positionalArguments =
-        _evaluatePositionalArguments(node.arguments);
+        _evaluatePositionalArguments(node.arguments.positional);
 
     if (positionalArguments == null) {
       AbortConstant error = _gotError!;
@@ -2217,7 +2273,7 @@
     final Constant receiver = _evaluateSubexpression(node.receiver);
     if (receiver is AbortConstant) return receiver;
     final List<Constant>? positionalArguments =
-        _evaluatePositionalArguments(node.arguments);
+        _evaluatePositionalArguments(node.arguments.positional);
 
     if (positionalArguments == null) {
       AbortConstant error = _gotError!;
@@ -2278,21 +2334,21 @@
   }
 
   Constant _evaluateFunctionInvocation(
-      TreeNode node, Constant receiver, Arguments argumentsNode) {
-    final List<Constant>? arguments =
-        _evaluatePositionalArguments(argumentsNode);
+      TreeNode node, Constant receiver, Arguments arguments) {
+    final List<Constant>? positional =
+        _evaluatePositionalArguments(arguments.positional);
 
-    if (arguments == null) {
+    if (positional == null) {
       AbortConstant error = _gotError!;
       _gotError = null;
       return error;
     }
     assert(_gotError == null);
     // ignore: unnecessary_null_comparison
-    assert(arguments != null);
+    assert(positional != null);
 
     // Evaluate type arguments of the function invoked.
-    List<DartType>? types = _evaluateTypeArguments(node, argumentsNode);
+    List<DartType>? types = _evaluateTypeArguments(node, arguments);
     if (types == null) {
       AbortConstant error = _gotError!;
       _gotError = null;
@@ -2303,7 +2359,8 @@
     assert(types != null);
 
     // Evaluate named arguments of the function invoked.
-    final Map<String, Constant>? named = _evaluateNamedArguments(argumentsNode);
+    final Map<String, Constant>? named =
+        _evaluateNamedArguments(arguments.named);
     if (named == null) {
       AbortConstant error = _gotError!;
       _gotError = null;
@@ -2315,7 +2372,7 @@
 
     if (receiver is FunctionValue) {
       return _handleFunctionInvocation(
-          receiver.function, types, arguments, named,
+          receiver.function, types, positional, named,
           functionEnvironment: receiver.environment);
     } else {
       return createEvaluationErrorConstant(
@@ -2574,7 +2631,7 @@
 
       // Evaluate named arguments of the method invoked.
       final Map<String, Constant>? namedArguments =
-          _evaluateNamedArguments(arguments);
+          _evaluateNamedArguments(arguments.named);
       if (namedArguments == null) {
         AbortConstant error = _gotError!;
         _gotError = null;
@@ -2845,12 +2902,7 @@
     final Constant receiver = _evaluateSubexpression(node.receiver);
     if (receiver is AbortConstant) return receiver;
     if (receiver is RecordConstant && enableConstFunctions) {
-      Constant? result;
-      for (ConstantRecordNamedField field in receiver.named) {
-        if (field.name == node.name) {
-          result = field.value;
-        }
-      }
+      Constant? result = receiver.named[node.name];
       if (result == null) {
         return new _AbortDueToThrowConstant(node, new StateError('No element'));
       } else {
@@ -3147,17 +3199,19 @@
 
     final List<DartType> typeArguments = convertTypes(types);
 
-    final List<Constant>? positionals = _evaluatePositionalArguments(arguments);
-    if (positionals == null) {
+    final List<Constant>? positional =
+        _evaluatePositionalArguments(arguments.positional);
+    if (positional == null) {
       AbortConstant error = _gotError!;
       _gotError = null;
       return error;
     }
     assert(_gotError == null);
     // ignore: unnecessary_null_comparison
-    assert(positionals != null);
+    assert(positional != null);
 
-    final Map<String, Constant>? named = _evaluateNamedArguments(arguments);
+    final Map<String, Constant>? named =
+        _evaluateNamedArguments(arguments.named);
     if (named == null) {
       AbortConstant error = _gotError!;
       _gotError = null;
@@ -3171,18 +3225,18 @@
       return unevaluated(
           node,
           new StaticInvocation(
-              target, unevaluatedArguments(positionals, named, arguments.types),
+              target, unevaluatedArguments(positional, named, arguments.types),
               isConst: true));
     }
     if (target.kind == ProcedureKind.Factory) {
       if (target.isConst) {
         if (target.enclosingLibrary == coreTypes.coreLibrary &&
-            positionals.length == 1 &&
+            positional.length == 1 &&
             (target.name.text == "fromEnvironment" ||
                 target.name.text == "hasEnvironment")) {
           if (hasEnvironment) {
             // Evaluate environment constant.
-            Constant name = positionals.single;
+            Constant name = positional.single;
             if (name is StringConstant) {
               if (target.name.text == "fromEnvironment") {
                 return _handleFromEnvironment(target, name, named);
@@ -3198,7 +3252,7 @@
             return unevaluated(
                 node,
                 new StaticInvocation(target,
-                    unevaluatedArguments(positionals, named, arguments.types),
+                    unevaluatedArguments(positional, named, arguments.types),
                     isConst: true));
           }
         } else if (target.isExternal) {
@@ -3206,7 +3260,7 @@
               node, messageConstEvalExternalFactory);
         } else if (enableConstFunctions) {
           return _handleFunctionInvocation(
-              node.target.function, typeArguments, positionals, named);
+              node.target.function, typeArguments, positional, named);
         } else {
           return createExpressionErrorConstant(
               node,
@@ -3216,7 +3270,7 @@
       } else {
         if (enableConstFunctions) {
           return _handleFunctionInvocation(
-              node.target.function, typeArguments, positionals, named);
+              node.target.function, typeArguments, positional, named);
         } else if (!node.isConst) {
           return createExpressionErrorConstant(node,
               templateNotConstantExpression.withArguments('New expression'));
@@ -3231,8 +3285,8 @@
       // Ensure the "identical()" function comes from dart:core.
       final TreeNode? parent = target.parent;
       if (parent is Library && parent == coreTypes.coreLibrary) {
-        final Constant left = positionals[0];
-        final Constant right = positionals[1];
+        final Constant left = positional[0];
+        final Constant right = positional[1];
 
         Constant evaluateIdentical() {
           // Since we canonicalize constants during the evaluation, we can use
@@ -3264,7 +3318,7 @@
       return createEvaluationErrorConstant(node, messageConstEvalExtension);
     } else if (enableConstFunctions && target.kind == ProcedureKind.Method) {
       return _handleFunctionInvocation(
-          node.target.function, typeArguments, positionals, named);
+          node.target.function, typeArguments, positional, named);
     }
 
     return createExpressionErrorConstant(
@@ -3722,14 +3776,14 @@
     return result;
   }
 
-  /// Returns the types on success and null on failure.
+  /// Returns the [positional] arguments on success and null on failure.
   /// Note that on failure an errorConstant is saved in [_gotError].
-  List<Constant>? _evaluatePositionalArguments(Arguments arguments) {
+  List<Constant>? _evaluatePositionalArguments(List<Expression> positional) {
     List<Constant> result = new List<Constant>.filled(
-        arguments.positional.length, dummyConstant,
+        positional.length, dummyConstant,
         growable: true);
-    for (int i = 0; i < arguments.positional.length; i++) {
-      Constant constant = _evaluateSubexpression(arguments.positional[i]);
+    for (int i = 0; i < positional.length; i++) {
+      Constant constant = _evaluateSubexpression(positional[i]);
       if (constant is AbortConstant) {
         _gotError = constant;
         return null;
@@ -3739,23 +3793,23 @@
     return result;
   }
 
-  /// Returns the arguments on success and null on failure.
+  /// Returns the [named] arguments on success and null on failure.
   /// Note that on failure an errorConstant is saved in [_gotError].
-  Map<String, Constant>? _evaluateNamedArguments(Arguments arguments) {
-    if (arguments.named.isEmpty) return const <String, Constant>{};
+  Map<String, Constant>? _evaluateNamedArguments(List<NamedExpression> named) {
+    if (named.isEmpty) return const <String, Constant>{};
 
-    final Map<String, Constant> named = {};
-    for (NamedExpression pair in arguments.named) {
+    final Map<String, Constant> result = {};
+    for (NamedExpression pair in named) {
       if (_gotError != null) return null;
       Constant constant = _evaluateSubexpression(pair.value);
       if (constant is AbortConstant) {
         _gotError = constant;
         return null;
       }
-      named[pair.name] = constant;
+      result[pair.name] = constant;
     }
     if (_gotError != null) return null;
-    return named;
+    return result;
   }
 
   Arguments unevaluatedArguments(List<Constant> positionalArgs,
@@ -4659,7 +4713,7 @@
   return type.accept(new IsInstantiatedVisitor());
 }
 
-class IsInstantiatedVisitor extends DartTypeVisitor<bool> {
+class IsInstantiatedVisitor implements DartTypeVisitor<bool> {
   final _availableVariables = new Set<TypeParameter>();
 
   bool isInstantiated(DartType type) {
@@ -4719,6 +4773,23 @@
 
   @override
   bool visitNeverType(NeverType node) => true;
+
+  @override
+  bool visitRecordType(RecordType node) {
+    return node.positional.every((p) => p.accept(this)) &&
+        node.named.every((p) => p.type.accept(this));
+  }
+
+  @override
+  bool visitExtensionType(ExtensionType node) {
+    return node.typeArguments
+        .every((DartType typeArgument) => typeArgument.accept(this));
+  }
+
+  @override
+  bool visitIntersectionType(IntersectionType node) {
+    return node.left.accept(this) && node.right.accept(this);
+  }
 }
 
 bool _isFormalParameter(VariableDeclaration variable) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
index 1e6ea3e..7bcff0f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
@@ -6,33 +6,29 @@
 import 'package:kernel/type_algebra.dart';
 
 import '../builder/library_builder.dart';
+import '../source/name_scheme.dart';
 import '../source/source_library_builder.dart';
-import '../source/source_member_builder.dart';
 import 'kernel_helper.dart';
 
 const String _tearOffNamePrefix = '_#';
 const String _tearOffNameSuffix = '#tearOff';
 
 /// Creates the synthesized name to use for the lowering of the tear off of a
-/// constructor or factory by the given [name] in [library].
-Name constructorTearOffName(String name, Library library) {
-  return new Name(
-      '$_tearOffNamePrefix'
+/// constructor or factory by the given [name].
+String constructorTearOffName(String name) {
+  return '$_tearOffNamePrefix'
       '${name.isEmpty ? 'new' : name}'
-      '$_tearOffNameSuffix',
-      library);
+      '$_tearOffNameSuffix';
 }
 
 /// Creates the synthesized name to use for the lowering of the tear off of a
-/// constructor or factory by the given [constructorName] in [library].
-Name typedefTearOffName(
-    String typedefName, String constructorName, Library library) {
-  return new Name(
-      '$_tearOffNamePrefix'
+/// constructor or factory by the given [constructorName] through a typedef by
+/// the given [typedefName].
+String typedefTearOffName(String typedefName, String constructorName) {
+  return '$_tearOffNamePrefix'
       '$typedefName#'
       '${constructorName.isEmpty ? 'new' : constructorName}'
-      '$_tearOffNameSuffix',
-      library);
+      '$_tearOffNameSuffix';
 }
 
 /// Returns the name of the corresponding constructor or factory if [name] is
@@ -109,12 +105,8 @@
   if (!forAbstractClassOrEnum &&
       compilationUnit
           .loader.target.backendTarget.isConstructorTearOffLoweringEnabled) {
-    return _createTearOffProcedure(
-        compilationUnit,
-        constructorTearOffName(name, compilationUnit.library),
-        fileUri,
-        fileOffset,
-        reference);
+    return _createTearOffProcedure(compilationUnit,
+        constructorTearOffName(name), fileUri, fileOffset, reference);
   }
   return null;
 }
@@ -131,12 +123,8 @@
     Reference? reference) {
   if (compilationUnit
       .loader.target.backendTarget.isFactoryTearOffLoweringEnabled) {
-    return _createTearOffProcedure(
-        compilationUnit,
-        constructorTearOffName(name, compilationUnit.library),
-        fileUri,
-        fileOffset,
-        reference);
+    return _createTearOffProcedure(compilationUnit,
+        constructorTearOffName(name), fileUri, fileOffset, reference);
   }
   return null;
 }
@@ -151,12 +139,8 @@
     Uri fileUri,
     int fileOffset,
     Reference? reference) {
-  return _createTearOffProcedure(
-      libraryBuilder,
-      typedefTearOffName(typedefName, name, libraryBuilder.library),
-      fileUri,
-      fileOffset,
-      reference);
+  return _createTearOffProcedure(libraryBuilder,
+      typedefTearOffName(typedefName, name), fileUri, fileOffset, reference);
 }
 
 /// Creates the parameters and body for [tearOff] based on
@@ -214,7 +198,6 @@
   _createTearOffBody(tearOff, declarationConstructor, arguments);
   tearOff.function.fileOffset = tearOff.fileOffset;
   tearOff.function.fileEndOffset = tearOff.fileOffset;
-  updatePrivateMemberName(tearOff, libraryBuilder);
 }
 
 /// Creates the parameters and body for [tearOff] for a typedef tearoff of
@@ -286,7 +269,6 @@
   _createTearOffBody(tearOff, declarationConstructor, arguments);
   tearOff.function.fileOffset = tearOff.fileOffset;
   tearOff.function.fileEndOffset = tearOff.fileOffset;
-  updatePrivateMemberName(tearOff, libraryBuilder);
 }
 
 /// Creates the parameters for the redirecting factory [tearOff] based on the
@@ -309,7 +291,6 @@
       libraryBuilder);
   tearOff.function.fileOffset = tearOff.fileOffset;
   tearOff.function.fileEndOffset = tearOff.fileOffset;
-  updatePrivateMemberName(tearOff, libraryBuilder);
   return freshTypeParameters;
 }
 
@@ -367,13 +348,17 @@
 /// Creates the synthesized [Procedure] node for a tear off lowering by the
 /// given [name].
 Procedure _createTearOffProcedure(SourceLibraryBuilder libraryBuilder,
-    Name name, Uri fileUri, int fileOffset, Reference? reference) {
-  return new Procedure(name, ProcedureKind.Method, new FunctionNode(null),
+    String name, Uri fileUri, int fileOffset, Reference? reference) {
+  Procedure tearOff = new Procedure(
+      dummyName, ProcedureKind.Method, new FunctionNode(null),
       fileUri: fileUri, isStatic: true, isSynthetic: true, reference: reference)
     ..fileStartOffset = fileOffset
     ..fileOffset = fileOffset
     ..fileEndOffset = fileOffset
     ..isNonNullableByDefault = libraryBuilder.isNonNullableByDefault;
+  MemberName tearOffName = new MemberName(libraryBuilder.libraryName, name);
+  tearOffName.attachMember(tearOff);
+  return tearOff;
 }
 
 /// Creates the synthesized type parameters for a tear off lowering. The type
@@ -501,8 +486,8 @@
         }
         if (target != null) {
           Class cls = target.enclosingClass!;
-          Name tearOffName =
-              constructorTearOffName(target.name.text, cls.enclosingLibrary);
+          Name tearOffName = new Name(
+              constructorTearOffName(target.name.text), cls.enclosingLibrary);
           for (Procedure procedure in cls.procedures) {
             if (procedure.name == tearOffName) {
               target = procedure;
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index 0babbef..f466806 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -4948,9 +4948,11 @@
   final List<NamedExpression> named;
   final Map<String, NamedExpression>? namedElements;
   final List<Object /*Expression|NamedExpression*/ > originalElementOrder;
+  final bool isConst;
 
   InternalRecordLiteral(this.positional, this.named, this.namedElements,
-      this.originalElementOrder);
+      this.originalElementOrder,
+      {required this.isConst});
 
   @override
   ExpressionInferenceResult acceptInference(
@@ -4964,7 +4966,8 @@
 
   @override
   void transformChildren(Transformer v) {
-    unsupported("${transformChildren}.accept on ${v.runtimeType}", -1, null);
+    unsupported(
+        "${runtimeType}.transformChildren on ${v.runtimeType}", -1, null);
   }
 
   @override
@@ -4985,6 +4988,9 @@
 
   @override
   void toTextInternal(AstPrinter printer) {
+    if (isConst) {
+      printer.write('const ');
+    }
     printer.write('(');
     String comma = '';
     for (Object element in originalElementOrder) {
@@ -5001,3 +5007,167 @@
     printer.write(')');
   }
 }
+
+abstract class Binder extends TreeNode {}
+
+class ListBinder extends Binder {
+  final DartType typeBinderArgument;
+  final List<Binder> binders;
+
+  ListBinder(this.typeBinderArgument, this.binders);
+
+  @override
+  R accept<R>(TreeVisitor<R> visitor) {
+    if (visitor is Printer || visitor is Precedence || visitor is Transformer) {
+      // Allow visitors needed for toString and replaceWith.
+      return visitor.defaultTreeNode(this);
+    }
+    return unsupported(
+        "${runtimeType}.accept on ${visitor.runtimeType}", -1, null);
+  }
+
+  @override
+  R accept1<R, A>(TreeVisitor1<R, A> visitor, A arg) {
+    return unsupported(
+        "${runtimeType}.accept1 on ${visitor.runtimeType}", -1, null);
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.write('[');
+    String comma = '';
+    for (Binder binder in binders) {
+      printer.write(comma);
+      binder.toTextInternal(printer);
+      comma = ', ';
+    }
+    printer.write(']');
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    unsupported(
+        "${runtimeType}.transformChildren on ${v.runtimeType}", -1, null);
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    unsupported("${runtimeType}.transformOrRemoveChildren on ${v.runtimeType}",
+        -1, null);
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    unsupported("${runtimeType}.visitChildren on ${v.runtimeType}", -1, null);
+  }
+
+  @override
+  String toString() {
+    return "ListBinder(${toStringInternal()})";
+  }
+}
+
+class WildcardBinder extends Binder {
+  final DartType? type;
+
+  WildcardBinder(this.type);
+
+  @override
+  R accept<R>(TreeVisitor<R> visitor) {
+    if (visitor is Printer || visitor is Precedence || visitor is Transformer) {
+      // Allow visitors needed for toString and replaceWith.
+      return visitor.defaultTreeNode(this);
+    }
+    return unsupported(
+        "${runtimeType}.accept on ${visitor.runtimeType}", -1, null);
+  }
+
+  @override
+  R accept1<R, A>(TreeVisitor1<R, A> visitor, A arg) {
+    return unsupported(
+        "${runtimeType}.accept1 on ${visitor.runtimeType}", -1, null);
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    if (type != null) {
+      type!.toTextInternal(printer);
+      printer.write(" ");
+    }
+    printer.write("_");
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    unsupported(
+        "${runtimeType}.transformChildren on ${v.runtimeType}", -1, null);
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    unsupported("${runtimeType}.transformOrRemoveChildren on ${v.runtimeType}",
+        -1, null);
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    unsupported("${runtimeType}.visitChildren on ${v.runtimeType}", -1, null);
+  }
+
+  @override
+  String toString() {
+    return "WildcardBinder(${toStringInternal()})";
+  }
+}
+
+class PatternVariableDeclaration extends Statement {
+  final Binder binder;
+  final Expression initializer;
+
+  PatternVariableDeclaration(this.binder, this.initializer);
+
+  @override
+  R accept<R>(StatementVisitor<R> visitor) {
+    if (visitor is Printer || visitor is Precedence || visitor is Transformer) {
+      // Allow visitors needed for toString and replaceWith.
+      return visitor.defaultStatement(this);
+    }
+    return unsupported(
+        "${runtimeType}.accept on ${visitor.runtimeType}", -1, null);
+  }
+
+  @override
+  R accept1<R, A>(StatementVisitor1<R, A> visitor, A arg) {
+    return unsupported(
+        "${runtimeType}.accept1 on ${visitor.runtimeType}", -1, null);
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    binder.toTextInternal(printer);
+    printer.write(" = ");
+    printer.writeExpression(initializer);
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    unsupported(
+        "${runtimeType}.transformChildren on ${v.runtimeType}", -1, null);
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    unsupported("${runtimeType}.transformOrRemoveChildren on ${v.runtimeType}",
+        -1, null);
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    unsupported("${runtimeType}.visitChildren on ${v.runtimeType}", -1, null);
+  }
+
+  @override
+  String toString() {
+    return "PatternVariableDeclaration(${toStringInternal()})";
+  }
+}
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 fbc8923..e1f3c6d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -30,6 +30,7 @@
 import '../builder/invalid_type_declaration_builder.dart';
 import '../builder/library_builder.dart';
 import '../builder/member_builder.dart';
+import '../builder/name_iterator.dart';
 import '../builder/named_type_builder.dart';
 import '../builder/never_type_declaration_builder.dart';
 import '../builder/nullability_builder.dart';
@@ -871,7 +872,7 @@
       constructorReference =
           indexedClass.lookupConstructorReference(new Name(""));
       tearOffReference = indexedClass.lookupGetterReference(
-          constructorTearOffName("", indexedClass.library));
+          new Name(constructorTearOffName(""), indexedClass.library));
     }
 
     /// From [Dart Programming Language Specification, 4th Edition](
@@ -929,7 +930,7 @@
       constructorReference =
           indexedClass.lookupConstructorReference(new Name(""));
       tearOffReference = indexedClass.lookupGetterReference(
-          constructorTearOffName("", indexedClass.library));
+          new Name(constructorTearOffName(""), indexedClass.library));
     }
 
     if (supertype is ClassBuilder) {
@@ -961,7 +962,7 @@
                 // added to `Class` whose name is `_` private to `lib1`.
                 .lookupConstructorReference(memberBuilder.member.name);
             tearOffReference = indexedClass.lookupGetterReference(
-                constructorTearOffName(name, indexedClass.library));
+                new Name(constructorTearOffName(name), indexedClass.library));
           }
           builder.addSyntheticConstructor(_makeMixinApplicationConstructor(
               builder,
@@ -1322,11 +1323,12 @@
           patchConstructorNames.add(name);
         }
       });
-      builder.constructorScope.forEach((String name, Builder builder) {
-        if (builder is ConstructorBuilder) {
-          patchConstructorNames.remove(name);
-        }
-      });
+      NameIterator<ConstructorBuilder> iterator = builder.constructorScope
+          .filteredNameIterator<ConstructorBuilder>(
+              includeDuplicates: false, includeAugmentations: true);
+      while (iterator.moveNext()) {
+        patchConstructorNames.remove(iterator.name);
+      }
       Set<String> kernelConstructorNames =
           cls.constructors.map((c) => c.name.text).toSet().difference({""});
       return kernelConstructorNames.containsAll(patchConstructorNames);
@@ -1334,6 +1336,9 @@
         "Constructors of class '${builder.fullNameForErrors}' "
         "aren't fully patched.");
     for (Constructor constructor in cls.constructors) {
+      if (constructor.isExternal) {
+        continue;
+      }
       bool isRedirecting = false;
       for (Initializer initializer in constructor.initializers) {
         if (initializer is RedirectingInitializer) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro/annotation_parser.dart b/pkg/front_end/lib/src/fasta/kernel/macro/annotation_parser.dart
index 98d9545..b79bf3d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro/annotation_parser.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro/annotation_parser.dart
@@ -287,6 +287,12 @@
   }
 
   @override
+  void handleExtractorPatternFields(
+      int count, Token beginToken, Token endToken) {
+    _unsupported();
+  }
+
+  @override
   void handleNoArguments(Token token) {
     push(const _NoArgumentsNode());
   }
@@ -319,6 +325,11 @@
   }
 
   @override
+  void handlePatternField(Token? colon) {
+    _unsupported();
+  }
+
+  @override
   // TODO: Handle directly.
   void handleNamedRecordField(Token colon) => handleNamedArgument(colon);
 
@@ -447,6 +458,11 @@
   }
 
   @override
+  void beginBinaryPattern(Token token) {
+    _unsupported();
+  }
+
+  @override
   void beginBlock(Token token, BlockKind blockKind) {
     _unsupported();
   }
@@ -949,6 +965,11 @@
   }
 
   @override
+  void endBinaryPattern(Token token) {
+    _unsupported();
+  }
+
+  @override
   void endBlock(
       int count, Token beginToken, Token endToken, BlockKind blockKind) {
     _unsupported();
@@ -1309,7 +1330,7 @@
   }
 
   @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
     _unexpected();
   }
 
@@ -1538,6 +1559,11 @@
   }
 
   @override
+  void handleCastPattern(Token operator) {
+    _unsupported();
+  }
+
+  @override
   void handleAssignmentExpression(Token token) {
     _unsupported();
   }
@@ -1826,11 +1852,26 @@
   }
 
   @override
+  void handleListPattern(int count, Token leftBracket, Token rightBracket) {
+    _unsupported();
+  }
+
+  @override
   void handleLiteralMapEntry(Token colon, Token endToken) {
     _unhandled();
   }
 
   @override
+  void handleMapPattern(int count, Token leftBrace, Token rightBrace) {
+    _unsupported();
+  }
+
+  @override
+  void handleMapPatternEntry(Token colon, Token endToken) {
+    _unsupported();
+  }
+
+  @override
   void handleLiteralSetOrMap(int count, Token leftBrace, Token? constKeyword,
       Token rightBrace, bool hasSetEntry) {
     _unhandled();
@@ -1937,6 +1978,21 @@
   }
 
   @override
+  void handleNullAssertPattern(Token bang) {
+    _unsupported();
+  }
+
+  @override
+  void handleNullCheckPattern(Token question) {
+    _unsupported();
+  }
+
+  @override
+  void handleVariablePattern(Token? keyword, Token variable) {
+    _unsupported();
+  }
+
+  @override
   void handleOperator(Token token) {
     _unknown();
   }
@@ -1947,7 +2003,7 @@
   }
 
   @override
-  void handleParenthesizedCondition(Token token) {
+  void handleParenthesizedCondition(Token token, Token? case_) {
     _unknown();
   }
 
@@ -1957,16 +2013,37 @@
   }
 
   @override
-  void endRecordLiteral(Token token, int count) {
+  void endRecordLiteral(Token token, int count, Token? constKeyword) {
     _unhandled();
   }
 
   @override
+  void handleRecordPattern(Token token, int count) {
+    _unsupported();
+  }
+
+  @override
   void endParenthesizedExpression(Token token) {
     _unhandled();
   }
 
   @override
+  void handleParenthesizedPattern(Token token) {
+    _unsupported();
+  }
+
+  @override
+  void handleConstantPattern(Token? constKeyword) {
+    _unsupported();
+  }
+
+  @override
+  void handleExtractorPattern(
+      Token firstIdentifier, Token? dot, Token? secondIdentifier) {
+    _unsupported();
+  }
+
+  @override
   void handleRecoverClassHeader() {
     _unexpected();
   }
@@ -2069,6 +2146,11 @@
   }
 
   @override
+  void handleRelationalPattern(Token token) {
+    _unsupported();
+  }
+
+  @override
   void handleUnescapeError(
       Message message, covariant Token location, int stringOffset, int length) {
     _unsupported();
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index 172515a..c164062 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -16,6 +16,7 @@
 import '../builder/named_type_builder.dart';
 import '../builder/nullability_builder.dart';
 import '../builder/omitted_type_builder.dart';
+import '../builder/record_type_builder.dart';
 import '../builder/type_alias_builder.dart';
 import '../builder/type_builder.dart';
 import '../builder/type_declaration_builder.dart';
@@ -357,6 +358,61 @@
           type.nullabilityBuilder, type.fileUri, type.charOffset);
     }
     return type;
+  } else if (type is RecordTypeBuilder) {
+    bool changed = false;
+
+    List<RecordTypeFieldBuilder>? positional = type.positionalFields != null
+        ? new List<RecordTypeFieldBuilder>.of(type.positionalFields!)
+        : null;
+    List<RecordTypeFieldBuilder>? named = type.namedFields != null
+        ? new List<RecordTypeFieldBuilder>.of(type.namedFields!)
+        : null;
+    if (positional != null) {
+      for (int i = 0; i < positional.length; i++) {
+        RecordTypeFieldBuilder positionalFieldBuilder = positional[i];
+        TypeBuilder positionalFieldType = substituteRange(
+            positionalFieldBuilder.type,
+            upperSubstitution,
+            lowerSubstitution,
+            unboundTypes,
+            unboundTypeVariables,
+            variance: variance);
+        if (positionalFieldType != positionalFieldBuilder.type) {
+          positional[i] = new RecordTypeFieldBuilder(
+              positionalFieldBuilder.metadata,
+              positionalFieldType,
+              positionalFieldBuilder.name,
+              positionalFieldBuilder.charOffset);
+          changed = true;
+        }
+      }
+    }
+    if (named != null) {
+      for (int i = 0; i < named.length; i++) {
+        RecordTypeFieldBuilder namedFieldBuilder = named[i];
+        TypeBuilder namedFieldType = substituteRange(
+            namedFieldBuilder.type,
+            upperSubstitution,
+            lowerSubstitution,
+            unboundTypes,
+            unboundTypeVariables,
+            variance: variance);
+        if (namedFieldType != namedFieldBuilder.type) {
+          named[i] = new RecordTypeFieldBuilder(
+              namedFieldBuilder.metadata,
+              namedFieldType,
+              namedFieldBuilder.name,
+              namedFieldBuilder.charOffset);
+          changed = true;
+        }
+      }
+    }
+
+    if (changed) {
+      return new RecordTypeBuilder(positional, named, type.nullabilityBuilder,
+          type.fileUri, type.charOffset);
+    }
+    return type;
   }
   return type;
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
index 29184f1..4fe8b55 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -426,10 +426,10 @@
       if (node.positional.isNotEmpty) result.add(", ");
       result.add("{");
       first = true;
-      for (ConstantRecordNamedField namedField in node.named) {
+      for (MapEntry<String, Constant> entry in node.named.entries) {
         if (!first) result.add(", ");
-        result.add("${namedField.name}: ");
-        namedField.value.accept(this);
+        result.add("${entry.key}: ");
+        entry.value.accept(this);
         first = false;
       }
       result.add("}");
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index 8f6be1e..3c0292e 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -21,6 +21,7 @@
 import 'kernel/kernel_helper.dart';
 import 'problems.dart' show internalProblem, unsupported;
 import 'source/source_class_builder.dart';
+import 'source/source_extension_builder.dart';
 import 'source/source_library_builder.dart';
 import 'source/source_member_builder.dart';
 import 'util/helpers.dart' show DelayedActionPerformer;
@@ -472,6 +473,17 @@
     _setters.forEach(f);
   }
 
+  ExtensionBuilder? lookupLocalUnnamedExtension(Uri fileUri, int offset) {
+    if (_extensions != null) {
+      for (ExtensionBuilder extension in _extensions!) {
+        if (extension.fileUri == fileUri && extension.charOffset == offset) {
+          return extension;
+        }
+      }
+    }
+    return null;
+  }
+
   void forEachLocalExtension(void Function(ExtensionBuilder member) f) {
     _extensions?.forEach(f);
   }
@@ -639,18 +651,14 @@
 
 class ConstructorScope {
   /// Constructors declared in this scope.
-  final Map<String, MemberBuilder> local;
+  final Map<String, MemberBuilder> _local;
 
   final String className;
 
-  ConstructorScope(this.className, this.local);
-
-  void forEach(f(String name, MemberBuilder member)) {
-    local.forEach(f);
-  }
+  ConstructorScope(this.className, this._local);
 
   MemberBuilder? lookup(String name, int charOffset, Uri fileUri) {
-    MemberBuilder? builder = local[name];
+    MemberBuilder? builder = _local[name];
     if (builder == null) return null;
     if (builder.next != null) {
       return new AmbiguousMemberBuilder(
@@ -661,11 +669,15 @@
   }
 
   MemberBuilder? lookupLocalMember(String name) {
-    return local[name];
+    return _local[name];
   }
 
   void addLocalMember(String name, MemberBuilder builder) {
-    local[name] = builder;
+    _local[name] = builder;
+  }
+
+  void addLocalMembers(Map<String, MemberBuilder> map) {
+    _local.addAll(map);
   }
 
   /// Returns an iterator of all constructors mapped in this scope,
@@ -721,7 +733,7 @@
   }
 
   @override
-  String toString() => "ConstructorScope($className, ${local.keys})";
+  String toString() => "ConstructorScope($className, ${_local.keys})";
 }
 
 abstract class LazyScope extends Scope {
@@ -968,13 +980,15 @@
 /// directly mapped builder.
 class ScopeIterator implements Iterator<Builder> {
   Iterator<Builder>? local;
-  final Iterator<Builder> setters;
+  Iterator<Builder>? setters;
+  Iterator<Builder>? extensions;
 
   Builder? _current;
 
   ScopeIterator(Scope scope)
       : local = scope._local.values.iterator,
-        setters = scope._setters.values.iterator;
+        setters = scope._setters.values.iterator,
+        extensions = scope._extensions?.iterator;
 
   @override
   bool moveNext() {
@@ -990,13 +1004,28 @@
       }
       local = null;
     }
-    if (setters.moveNext()) {
-      _current = setters.current;
-      return true;
-    } else {
-      _current = null;
-      return false;
+    if (setters != null) {
+      if (setters!.moveNext()) {
+        _current = setters!.current;
+        return true;
+      }
+      setters = null;
     }
+    if (extensions != null) {
+      while (extensions!.moveNext()) {
+        Builder extension = extensions!.current;
+        // Named extensions have already been included throw [local] so we skip
+        // them here.
+        if (extension is SourceExtensionBuilder &&
+            extension.isUnnamedExtension) {
+          _current = extension;
+          return true;
+        }
+      }
+      extensions = null;
+    }
+    _current = null;
+    return false;
   }
 
   @override
@@ -1012,7 +1041,7 @@
 /// access to the name that the builders are mapped to.
 class ScopeNameIterator extends ScopeIterator implements NameIterator<Builder> {
   Iterator<String>? localNames;
-  final Iterator<String> setterNames;
+  Iterator<String>? setterNames;
 
   String? _name;
 
@@ -1035,18 +1064,36 @@
         _name = localNames!.current;
         return true;
       }
+      local = null;
       localNames = null;
     }
-    if (setters.moveNext()) {
-      setterNames.moveNext();
-      _current = setters.current;
-      _name = setterNames.current;
-      return true;
-    } else {
-      _current = null;
-      _name = null;
-      return false;
+    if (setters != null) {
+      if (setters!.moveNext()) {
+        setterNames!.moveNext();
+        _current = setters!.current;
+        _name = setterNames!.current;
+        return true;
+      }
+      setters = null;
+      setterNames = null;
     }
+    if (extensions != null) {
+      while (extensions!.moveNext()) {
+        Builder extension = extensions!.current;
+        // Named extensions have already been included throw [local] so we skip
+        // them here.
+        if (extension is SourceExtensionBuilder &&
+            extension.isUnnamedExtension) {
+          _current = extension;
+          _name = extension.name;
+          return true;
+        }
+      }
+      extensions = null;
+    }
+    _current = null;
+    _name = null;
+    return false;
   }
 
   @override
@@ -1063,7 +1110,7 @@
   MemberBuilder? _current;
 
   ConstructorScopeIterator(ConstructorScope scope)
-      : local = scope.local.values.iterator;
+      : local = scope._local.values.iterator;
 
   @override
   bool moveNext() {
@@ -1097,7 +1144,7 @@
   String? _name;
 
   ConstructorScopeNameIterator(ConstructorScope scope)
-      : localNames = scope.local.keys.iterator,
+      : localNames = scope._local.keys.iterator,
         super(scope);
 
   @override
@@ -1322,13 +1369,24 @@
   }
 
   void _addAugmentationScope(T parentBuilder, Scope scope) {
+    // TODO(johnniwinther): Use `scope.filteredNameIterator` instead of
+    // `scope.forEachLocalMember`/`scope.forEachLocalSetter`.
+
     // Include all augmentation scope members to the origin scope.
     scope.forEachLocalMember((String name, Builder member) {
+      // In case of duplicates we use the first declaration.
+      while (member.isDuplicate) {
+        member = member.next!;
+      }
       _addBuilderToMergedScope(parentBuilder, name, member,
           _originScope.lookupLocalMember(name, setter: false),
           setter: false);
     });
     scope.forEachLocalSetter((String name, Builder member) {
+      // In case of duplicates we use the first declaration.
+      while (member.isDuplicate) {
+        member = member.next!;
+      }
       _addBuilderToMergedScope(parentBuilder, name, member,
           _originScope.lookupLocalMember(name, setter: true),
           setter: true);
@@ -1422,7 +1480,8 @@
 
   void _addAugmentationConstructorScope(
       SourceClassBuilder classBuilder, ConstructorScope constructorScope) {
-    constructorScope.forEach((String name, MemberBuilder newConstructor) {
+    constructorScope._local
+        .forEach((String name, MemberBuilder newConstructor) {
       MemberBuilder? existingConstructor =
           _originConstructorScope.lookupLocalMember(name);
       if (classBuilder.isAugmentation) {
@@ -1471,7 +1530,7 @@
         }
       }
     });
-    _originConstructorScope
+    _originConstructorScope._local
         .forEach((String name, MemberBuilder originConstructor) {
       _addConstructorToAugmentationScope(
           constructorScope, name, originConstructor);
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 b186ca4..38813c1 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -24,6 +24,7 @@
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
 import '../builder/declaration_builder.dart';
+import '../builder/extension_builder.dart';
 import '../builder/formal_parameter_builder.dart';
 import '../builder/function_type_builder.dart';
 import '../builder/metadata_builder.dart';
@@ -80,9 +81,6 @@
 
   bool currentClassIsParserRecovery = false;
 
-  /// Counter used for naming unnamed extension declarations.
-  int unnamedExtensionCounter = 0;
-
   /// For top-level declarations, this is the library scope. For class members,
   /// this is the instance scope of [currentDeclaration].
   Scope memberScope;
@@ -440,9 +438,11 @@
   }
 
   @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
     debugEvent("endLibraryName");
-    pop(); // Name.
+    if (hasName) {
+      pop(); // Name.
+    }
     pop(); // Annotations.
   }
 
@@ -900,7 +900,7 @@
   void beginClassOrMixinOrExtensionBody(DeclarationKind kind, Token token) {
     assert(checkState(token, [
       ValueKinds.Token,
-      ValueKinds.NameOrParserRecovery,
+      ValueKinds.NameOrParserRecoveryOrNull,
       ValueKinds.TokenOrNull
     ]));
     debugEvent("beginClassOrMixinBody");
@@ -913,8 +913,12 @@
       currentClassIsParserRecovery = true;
       return;
     }
-    currentDeclaration =
-        lookupBuilder(beginToken, null, name as String) as DeclarationBuilder;
+    if (name is String) {
+      currentDeclaration =
+          lookupBuilder(beginToken, null, name) as DeclarationBuilder;
+    } else {
+      currentDeclaration = lookupUnnamedExtensionBuilder(beginToken);
+    }
     memberScope = currentDeclaration!.scope;
   }
 
@@ -956,10 +960,7 @@
   @override
   void beginExtensionDeclaration(Token extensionKeyword, Token? nameToken) {
     debugEvent("beginExtensionDeclaration");
-    String name = nameToken?.lexeme ??
-        // Synthesized name used internally.
-        '_extension#${unnamedExtensionCounter++}';
-    push(name);
+    push(nameToken?.lexeme ?? NullValue.Name);
     push(extensionKeyword);
   }
 
@@ -1150,6 +1151,11 @@
     return declaration;
   }
 
+  ExtensionBuilder? lookupUnnamedExtensionBuilder(Token extensionToken) {
+    return libraryBuilder.scope
+        .lookupLocalUnnamedExtension(uri, extensionToken.charOffset);
+  }
+
   Builder? lookupConstructor(Token token, Object nameOrQualified) {
     assert(currentClass != null);
     Builder? declaration;
@@ -1164,7 +1170,7 @@
     if (libraryFeatures.constructorTearoffs.isEnabled) {
       suffix = suffix == "new" ? "" : suffix;
     }
-    declaration = currentClass!.constructorScope.local[suffix];
+    declaration = currentClass!.constructorScope.lookupLocalMember(suffix);
     declaration = handleDuplicatedName(declaration, token);
     checkBuilder(token, declaration, nameOrQualified);
     return declaration;
diff --git a/pkg/front_end/lib/src/fasta/source/name_scheme.dart b/pkg/front_end/lib/src/fasta/source/name_scheme.dart
index 1e7033f..86eab1d 100644
--- a/pkg/front_end/lib/src/fasta/source/name_scheme.dart
+++ b/pkg/front_end/lib/src/fasta/source/name_scheme.dart
@@ -12,15 +12,15 @@
   final bool isInstanceMember;
   final String? className;
   final bool isExtensionMember;
-  final String? extensionName;
-  final Reference? libraryReference;
+  ExtensionName? extensionName;
+  final LibraryName libraryName;
 
   NameScheme(
       {required this.isInstanceMember,
       required this.className,
       required this.isExtensionMember,
       required this.extensionName,
-      required this.libraryReference})
+      required this.libraryName})
       // ignore: unnecessary_null_comparison
       : assert(isInstanceMember != null),
         // ignore: unnecessary_null_comparison
@@ -28,21 +28,23 @@
         // ignore: unnecessary_null_comparison
         assert(!isExtensionMember || extensionName != null),
         // ignore: unnecessary_null_comparison
-        assert(libraryReference != null);
+        assert(libraryName != null);
 
   bool get isStatic => !isInstanceMember;
 
-  Name getFieldName(FieldNameType type, String name,
+  MemberName getFieldMemberName(FieldNameType type, String name,
       {required bool isSynthesized}) {
-    // ignore: unnecessary_null_comparison
-    assert(isSynthesized != null);
-    String text = createFieldName(type, name,
-        isInstanceMember: isInstanceMember,
-        className: className,
-        isExtensionMethod: isExtensionMember,
-        extensionName: extensionName,
-        isSynthesized: isSynthesized);
-    return new Name.byReference(text, libraryReference);
+    if (isSynthesized || isExtensionMember) {
+      return new SynthesizedFieldName(
+          libraryName, className, extensionName, type, name,
+          isInstanceMember: isInstanceMember,
+          isExtensionMember: isExtensionMember,
+          isSynthesized: isSynthesized);
+    } else {
+      return name.startsWith('_')
+          ? new PrivateMemberName(libraryName, name)
+          : new PublicMemberName(name);
+    }
   }
 
   static String createFieldName(FieldNameType type, String name,
@@ -88,20 +90,18 @@
     }
   }
 
-  Name getProcedureName(ProcedureKind kind, String name) {
-    // ignore: unnecessary_null_comparison
-    assert(kind != null);
-    return new Name.byReference(
-        createProcedureName(
-            isExtensionMethod: isExtensionMember,
-            isStatic: isStatic,
-            kind: kind,
-            extensionName: extensionName,
-            name: name),
-        libraryReference);
+  MemberName getProcedureMemberName(ProcedureKind kind, String name) {
+    if (extensionName != null) {
+      return new ExtensionProcedureName(libraryName, extensionName!, kind, name,
+          isStatic: isStatic);
+    } else {
+      return name.startsWith('_')
+          ? new PrivateMemberName(libraryName, name)
+          : new PublicMemberName(name);
+    }
   }
 
-  static String createProcedureName(
+  static String _createProcedureName(
       {required bool isExtensionMethod,
       required bool isStatic,
       required ProcedureKind kind,
@@ -134,4 +134,298 @@
       return name;
     }
   }
+
+  // TODO(johnniwinther): Use [NameScheme] for constructor and constructor
+  // tear-off names.
+}
+
+/// The part of a member name defined by a library.
+///
+/// This is used for creating member names together with the member builders
+/// while still supporting that the resulting library is computed late.
+class LibraryName {
+  /// The reference to the [Library] that defines the library name scope.
+  Reference _reference;
+
+  /// [MemberName]s dependent on this library name.
+  List<MemberName> _memberNames = [];
+
+  LibraryName(this._reference);
+
+  /// Registers [name] as dependent on this library name.
+  void attachMemberName(MemberName name) {
+    _memberNames.add(name);
+  }
+
+  /// Returns the current [Reference] used for creating [Name]s in this library
+  /// name scope.
+  Reference get reference => _reference;
+
+  /// Updates the [Reference] that defines the library name scope.
+  ///
+  /// If changed, the dependent [_memberNames] are updated accordingly.
+  void set reference(Reference value) {
+    if (_reference != value) {
+      _reference = value;
+      for (MemberName name in _memberNames) {
+        name.updateMemberName();
+      }
+    }
+  }
+}
+
+/// The name of an extension, either named or unnamed.
+///
+/// This is used for creating extension member names together with the member
+/// builders while still supporting that the synthesized extension names for
+/// unnamed extensions are computed late.
+abstract class ExtensionName {
+  /// The current name of the extension.
+  ///
+  /// For an unnamed extension, this is initially a sentinel value, which is
+  /// updated within the containing [Library] is composed.
+  String get name;
+
+  /// Updates the name for this extension.
+  ///
+  /// If changed, the dependent [Extension] names and [MemberName]s will be
+  /// updated accordingly.
+  void set name(String value);
+
+  /// Returns `true` if this is the name of an unnamed extension.
+  bool get isUnnamedExtension;
+
+  /// Associates the [extension] with this extension name.
+  ///
+  /// When the [name] is updated, the name of the [extension] will be updated
+  /// accordingly.
+  void attachExtension(Extension extension);
+
+  /// Registers [name] as dependent on this extension name.
+  void attachMemberName(MemberName name);
+}
+
+/// The name of a named extension.
+class FixedExtensionName implements ExtensionName {
+  @override
+  final String name;
+
+  FixedExtensionName(this.name);
+
+  @override
+  bool get isUnnamedExtension => false;
+
+  @override
+  void set name(String value) {
+    throw new UnsupportedError("Cannot change name of a fixed extension name.");
+  }
+
+  @override
+  void attachExtension(Extension extension) {
+    extension.name = name;
+  }
+
+  @override
+  void attachMemberName(MemberName name) {}
+}
+
+/// The name of an unnamed extension.
+class UnnamedExtensionName implements ExtensionName {
+  static const String unnamedExtensionSentinel = '_unnamed-extension_';
+
+  String? _name;
+  Extension? _extension;
+
+  List<MemberName> _memberNames = [];
+
+  @override
+  bool get isUnnamedExtension => true;
+
+  @override
+  String get name => _name ?? unnamedExtensionSentinel;
+
+  @override
+  void attachExtension(Extension extension) {
+    _extension = extension;
+    extension.name = name;
+  }
+
+  @override
+  void set name(String name) {
+    if (_name != name) {
+      _name = name;
+      _extension?.name = name;
+      for (MemberName memberName in _memberNames) {
+        memberName.updateMemberName();
+      }
+    }
+  }
+
+  @override
+  void attachMemberName(MemberName name) {
+    _memberNames.add(name);
+  }
+}
+
+/// The name of a [Member] which support late computation of member names needed
+/// for private names and names of members of unnamed extensions.
+///
+/// Since members are built early when library vs parts haven't been resolved
+/// the private names of parts needed to be updated once the resulting [Library]
+/// node has been determined, and for members of unnamed extensions, when the
+/// synthesized name of the unnamed extension has been determined.
+abstract class MemberName {
+  factory MemberName(LibraryName libraryName, String text) =>
+      text.startsWith('_')
+          ? new PrivateMemberName(libraryName, text)
+          : new PublicMemberName(text);
+
+  /// Returns the current [Name] for this member name.
+  Name get name;
+
+  /// Recomputes the [name] property and, if changed, updates dependent members
+  /// accordingly.
+  ///
+  /// This is called by [LibraryName] and [UnnamedExtensionName] when these
+  /// are updated.
+  void updateMemberName();
+
+  /// Registers [member] has dependent of this member name and set the name
+  /// of [member] to the current [name].
+  void attachMember(Member member);
+}
+
+/// A public member name.
+///
+/// This never changes once created.
+class PublicMemberName implements MemberName {
+  @override
+  final Name name;
+
+  PublicMemberName(String text)
+      : assert(!text.startsWith('_')),
+        name = new Name(text);
+
+  @override
+  void updateMemberName() {}
+
+  @override
+  void attachMember(Member member) {
+    member.name = name;
+  }
+}
+
+/// A member name that can be updated.
+abstract class UpdatableMemberName implements MemberName {
+  Name? _name;
+  List<Member> _members = [];
+
+  Name _createName();
+
+  @override
+  Name get name => _name ??= _createName();
+
+  @override
+  void attachMember(Member member) {
+    member.name = name;
+    _members.add(member);
+  }
+
+  @override
+  void updateMemberName() {
+    Name name = _createName();
+    if (_name != name) {
+      for (Member member in _members) {
+        member.name = name;
+      }
+    }
+  }
+}
+
+/// A private member name.
+///
+/// This depends on a [LibraryName] and is updated when the reference of the
+/// [LibraryName] is changed.
+class PrivateMemberName extends UpdatableMemberName {
+  final LibraryName _libraryName;
+  final String _text;
+
+  PrivateMemberName(this._libraryName, this._text)
+      : assert(_text.startsWith('_')) {
+    _libraryName.attachMemberName(this);
+  }
+
+  @override
+  Name _createName() {
+    return new Name.byReference(_text, _libraryName.reference);
+  }
+}
+
+/// A name for an extension procedure.
+///
+/// This depends on a [LibraryName] and an [ExtensionName] and is updated the
+/// reference of the [LibraryName] or the name of the [ExtensionName] is
+/// changed.
+class ExtensionProcedureName extends UpdatableMemberName {
+  final LibraryName _libraryName;
+  final ExtensionName _extensionName;
+  final ProcedureKind _kind;
+  final bool isStatic;
+  final String _text;
+
+  ExtensionProcedureName(
+      this._libraryName, this._extensionName, this._kind, this._text,
+      {required this.isStatic}) {
+    _libraryName.attachMemberName(this);
+    _extensionName.attachMemberName(this);
+  }
+
+  @override
+  Name _createName() {
+    return new Name.byReference(
+        NameScheme._createProcedureName(
+            isExtensionMethod: true,
+            isStatic: isStatic,
+            kind: _kind,
+            name: _text,
+            extensionName: _extensionName.name),
+        _libraryName.reference);
+  }
+}
+
+/// A name of a synthesized field.
+///
+/// This depends on a [LibraryName] and an [ExtensionName] and is updated the
+/// reference of the [LibraryName] or the name of the [ExtensionName] is
+/// changed.
+class SynthesizedFieldName extends UpdatableMemberName {
+  final LibraryName _libraryName;
+  final String? className;
+  final ExtensionName? _extensionName;
+  final FieldNameType _type;
+  final bool isInstanceMember;
+  final bool isExtensionMember;
+  final bool isSynthesized;
+  final String _text;
+
+  SynthesizedFieldName(this._libraryName, this.className, this._extensionName,
+      this._type, this._text,
+      {required this.isInstanceMember,
+      required this.isExtensionMember,
+      required this.isSynthesized}) {
+    _libraryName.attachMemberName(this);
+    _extensionName?.attachMemberName(this);
+  }
+
+  @override
+  Name _createName() {
+    return new Name.byReference(
+        NameScheme.createFieldName(_type, _text,
+            isInstanceMember: isInstanceMember,
+            className: className,
+            isExtensionMethod: isExtensionMember,
+            extensionName: _extensionName?.name,
+            isSynthesized: isSynthesized),
+        _libraryName.reference);
+  }
 }
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 0d80330..97ef60c 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -436,9 +436,6 @@
 
   String? nativeMethodName;
 
-  /// Counter used for naming unnamed extension declarations.
-  int unnamedExtensionCounter = 0;
-
   Link<DeclarationContext> _declarationContext = const Link();
 
   OutlineBuilder(SourceLibraryBuilder library)
@@ -835,14 +832,20 @@
   }
 
   @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
     debugEvent("endLibraryName");
-    popCharOffset();
-    Object? name = pop();
+    Object? name = null;
+    if (hasName) {
+      popCharOffset();
+      name = pop();
+    }
     List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
-    if (name is! ParserRecovery) {
+    if (name != null && name is! ParserRecovery) {
       libraryBuilder.name =
-          flattenName(name!, offsetForToken(libraryKeyword), uri);
+          flattenName(name, offsetForToken(libraryKeyword), uri);
+    } else {
+      reportIfNotEnabled(
+          libraryFeatures.unnamedLibraries, semicolon.charOffset, noLength);
     }
     libraryBuilder.metadata = metadata;
   }
@@ -1328,14 +1331,11 @@
     List<TypeVariableBuilder>? typeVariables =
         pop() as List<TypeVariableBuilder>?;
     int offset = nameToken?.charOffset ?? extensionKeyword.charOffset;
-    String name = nameToken?.lexeme ??
-        // Synthesized name used internally.
-        '_extension#${unnamedExtensionCounter++}';
-    push(name);
+    push(nameToken?.lexeme ?? NullValue.Name);
     push(offset);
     push(typeVariables ?? NullValue.TypeVariables);
     libraryBuilder.currentTypeParameterScopeBuilder
-        .markAsExtensionDeclaration(name, offset, typeVariables);
+        .markAsExtensionDeclaration(nameToken?.lexeme, offset, typeVariables);
   }
 
   @override
@@ -1401,7 +1401,6 @@
     String? name = pop(NullValue.Name) as String?;
     if (name == null) {
       nameOffset = extensionKeyword.charOffset;
-      name = '$nameOffset';
     }
     List<MetadataBuilder>? metadata =
         pop(NullValue.Metadata) as List<MetadataBuilder>?;
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index c3f7b04..456207e 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -285,10 +285,15 @@
       }
     }
 
-    constructorScope.forEach((String name, Builder constructor) {
+    NameIterator<MemberBuilder> iterator =
+        constructorScope.filteredNameIterator(
+            includeDuplicates: false, includeAugmentations: true);
+    while (iterator.moveNext()) {
+      String name = iterator.name;
+      MemberBuilder constructor = iterator.current;
       Builder? member = scope.lookupLocalMember(name, setter: false);
-      if (member == null) return;
-      if (!member.isStatic) return;
+      if (member == null) continue;
+      if (!member.isStatic) continue;
       // TODO(ahe): Revisit these messages. It seems like the last two should
       // be `context` parameter to this message.
       addProblem(templateConflictsWithMember.withArguments(name),
@@ -305,7 +310,7 @@
             member.charOffset,
             noLength);
       }
-    });
+    }
 
     scope.forEachLocalSetter((String name, Builder setter) {
       Builder? constructor = constructorScope.lookupLocalMember(name);
@@ -1478,8 +1483,12 @@
             _transformProcedureToNoSuchMethodForwarder(
                 noSuchMethod, target, member as Procedure);
           } else {
-            Procedure memberSignature =
-                combinedMemberSignature.createMemberFromSignature()!;
+            // The reason we don't copy the location is to ensure that the stack
+            // trace for throwing no-such-method forwarders point to the class
+            // in which they are inserted and not to the declaration of the
+            // missing member.
+            Procedure memberSignature = combinedMemberSignature
+                .createMemberFromSignature(copyLocation: false)!;
             _transformProcedureToNoSuchMethodForwarder(
                 noSuchMethod, target, memberSignature);
             cls.procedures.add(memberSignature);
@@ -1588,31 +1597,56 @@
       Procedure noSuchMethodInterface,
       KernelTarget target,
       Procedure procedure) {
+    bool shouldThrow = false;
+    Name procedureName = procedure.name;
+    if (procedureName.isPrivate) {
+      Library procedureNameLibrary = procedureName.library!;
+      // If the name is defined in a different library than the library we're
+      // synthesizing a forwarder for, then the forwarder must throw.  This
+      // avoids surprising users by ensuring that all non-throwing
+      // implementations of a private name can be found solely by looking at the
+      // library in which the name is defined; it also avoids soundness holes in
+      // field promotion.
+      if (procedureNameLibrary.compareTo(procedure.enclosingLibrary) != 0) {
+        shouldThrow = true;
+      }
+    }
+    Expression result;
     String prefix = procedure.isGetter
         ? 'get:'
         : procedure.isSetter
             ? 'set:'
             : '';
-    String invocationName = prefix + procedure.name.text;
+    String invocationName = prefix + procedureName.text;
     if (procedure.isSetter) invocationName += '=';
+    CoreTypes coreTypes = target.loader.coreTypes;
     Expression invocation = target.backendTarget.instantiateInvocation(
-        target.loader.coreTypes,
+        coreTypes,
         new ThisExpression(),
         invocationName,
         new Arguments.forwarded(procedure.function, libraryBuilder.library),
         procedure.fileOffset,
         /*isSuper=*/ false);
-    Expression result = new InstanceInvocation(InstanceAccessKind.Instance,
-        new ThisExpression(), noSuchMethodName, new Arguments([invocation]),
-        functionType: noSuchMethodInterface.getterType as FunctionType,
-        interfaceTarget: noSuchMethodInterface)
-      ..fileOffset = procedure.fileOffset;
-    if (procedure.function.returnType is! VoidType) {
-      result = new AsExpression(result, procedure.function.returnType)
-        ..isTypeError = true
-        ..isForDynamic = true
-        ..isForNonNullableByDefault = libraryBuilder.isNonNullableByDefault
+    if (shouldThrow) {
+      // Build `throw new NoSuchMethodError(this, invocation)`.
+      result = new Throw(new StaticInvocation(
+          coreTypes.noSuchMethodErrorDefaultConstructor,
+          new Arguments([new ThisExpression(), invocation])))
         ..fileOffset = procedure.fileOffset;
+    } else {
+      // Build `this.noSuchMethod(invocation)`.
+      result = new InstanceInvocation(InstanceAccessKind.Instance,
+          new ThisExpression(), noSuchMethodName, new Arguments([invocation]),
+          functionType: noSuchMethodInterface.getterType as FunctionType,
+          interfaceTarget: noSuchMethodInterface)
+        ..fileOffset = procedure.fileOffset;
+      if (procedure.function.returnType is! VoidType) {
+        result = new AsExpression(result, procedure.function.returnType)
+          ..isTypeError = true
+          ..isForDynamic = true
+          ..isForNonNullableByDefault = libraryBuilder.isNonNullableByDefault
+          ..fileOffset = procedure.fileOffset;
+      }
     }
     procedure.function.body = new ReturnStatement(result)
       ..fileOffset = procedure.fileOffset
@@ -1674,10 +1708,10 @@
     }
     int count = constructorReferences!.length;
     if (count != 0) {
-      constructorScope
-          .filteredIterator(
-              parent: this, includeDuplicates: true, includeAugmentations: true)
-          .forEach((MemberBuilder declaration) {
+      Iterator<MemberBuilder> iterator = constructorScope.filteredIterator(
+          parent: this, includeDuplicates: true, includeAugmentations: true);
+      while (iterator.moveNext()) {
+        MemberBuilder declaration = iterator.current;
         if (declaration.parent?.origin != origin) {
           unexpected("$fileUri", "${declaration.parent!.fileUri}", charOffset,
               fileUri);
@@ -1792,7 +1826,7 @@
             }
           }
         }
-      });
+      }
     }
     return count;
   }
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
index bec8ff9..2231fc8 100644
--- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -52,6 +52,7 @@
 import '../type_inference/inference_results.dart';
 import '../type_inference/type_schema.dart';
 import '../util/helpers.dart' show DelayedActionPerformer;
+import 'name_scheme.dart';
 import 'source_field_builder.dart';
 import 'source_function_builder.dart';
 
@@ -76,8 +77,8 @@
   @override
   final OmittedTypeBuilder returnType;
 
-  final Constructor _constructor;
-  final Procedure? _constructorTearOff;
+  late final Constructor _constructor;
+  late final Procedure? _constructorTearOff;
 
   Set<SourceFieldBuilder>? _initializedFields;
 
@@ -131,25 +132,25 @@
       Reference? tearOffReference,
       {String? nativeMethodName,
       required bool forAbstractClassOrEnum})
-      : _constructor = new Constructor(new FunctionNode(null),
-            name: new Name(name, compilationUnit.library),
-            fileUri: compilationUnit.fileUri,
-            reference: constructorReference)
-          ..startFileOffset = startCharOffset
-          ..fileOffset = charOffset
-          ..fileEndOffset = charEndOffset
-          ..isNonNullableByDefault = compilationUnit.isNonNullableByDefault,
-        _constructorTearOff = createConstructorTearOffProcedure(
-            name,
-            compilationUnit,
-            compilationUnit.fileUri,
-            charOffset,
-            tearOffReference,
-            forAbstractClassOrEnum: forAbstractClassOrEnum),
-        _hasSuperInitializingFormals =
+      : _hasSuperInitializingFormals =
             formals?.any((formal) => formal.isSuperInitializingFormal) ?? false,
         super(metadata, modifiers, name, typeVariables, formals,
             compilationUnit, charOffset, nativeMethodName) {
+    _constructor = new Constructor(new FunctionNode(null),
+        name: dummyName,
+        fileUri: compilationUnit.fileUri,
+        reference: constructorReference)
+      ..startFileOffset = startCharOffset
+      ..fileOffset = charOffset
+      ..fileEndOffset = charEndOffset
+      ..isNonNullableByDefault = compilationUnit.isNonNullableByDefault;
+    MemberName constructorName =
+        new MemberName(compilationUnit.libraryName, name);
+    constructorName.attachMember(_constructor);
+    _constructorTearOff = createConstructorTearOffProcedure(name,
+        compilationUnit, compilationUnit.fileUri, charOffset, tearOffReference,
+        forAbstractClassOrEnum: forAbstractClassOrEnum);
+
     if (formals != null) {
       for (FormalParameterBuilder formal in formals!) {
         if (formal.isInitializingFormal || formal.isSuperInitializingFormal) {
@@ -265,7 +266,6 @@
       _constructor.function.typeParameters = const <TypeParameter>[];
       _constructor.isConst = isConst;
       _constructor.isExternal = isExternal;
-      updatePrivateMemberName(_constructor, libraryBuilder);
 
       if (_constructorTearOff != null) {
         buildConstructorTearOffProcedure(
@@ -315,29 +315,31 @@
   void inferFormalTypes(ClassHierarchyBase hierarchy) {
     if (_hasFormalsInferred) return;
     if (formals != null) {
-      for (FormalParameterBuilder formal in formals!) {
-        if (formal.type is InferableTypeBuilder) {
-          if (formal.isInitializingFormal) {
-            formal.finalizeInitializingFormal(classBuilder, hierarchy);
+      libraryBuilder.loader.withUriForCrashReporting(fileUri, charOffset, () {
+        for (FormalParameterBuilder formal in formals!) {
+          if (formal.type is InferableTypeBuilder) {
+            if (formal.isInitializingFormal) {
+              formal.finalizeInitializingFormal(classBuilder, hierarchy);
+            }
           }
         }
-      }
 
-      if (_hasSuperInitializingFormals) {
-        List<Initializer>? initializers;
-        if (beginInitializers != null) {
-          BodyBuilder bodyBuilder = libraryBuilder.loader
-              .createBodyBuilderForOutlineExpression(libraryBuilder,
-                  classBuilder, this, classBuilder.scope, fileUri);
-          if (isConst) {
-            bodyBuilder.constantContext = ConstantContext.required;
+        if (_hasSuperInitializingFormals) {
+          List<Initializer>? initializers;
+          if (beginInitializers != null) {
+            BodyBuilder bodyBuilder = libraryBuilder.loader
+                .createBodyBuilderForOutlineExpression(libraryBuilder,
+                    classBuilder, this, classBuilder.scope, fileUri);
+            if (isConst) {
+              bodyBuilder.constantContext = ConstantContext.required;
+            }
+            initializers = bodyBuilder.parseInitializers(beginInitializers!,
+                doFinishConstructor: false);
           }
-          initializers = bodyBuilder.parseInitializers(beginInitializers!,
-              doFinishConstructor: false);
+          finalizeSuperInitializingFormals(
+              hierarchy, _superParameterDefaultValueCloners, initializers);
         }
-        finalizeSuperInitializingFormals(
-            hierarchy, _superParameterDefaultValueCloners, initializers);
-      }
+      });
     }
     _hasFormalsInferred = true;
   }
@@ -400,7 +402,7 @@
     void performRecoveryForErroneousCase() {
       for (FormalParameterBuilder formal in formals!) {
         if (formal.isSuperInitializingFormal) {
-          formal.variable!.type = const DynamicType();
+          formal.type.registerInferredType(const InvalidType());
         }
       }
     }
diff --git a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
index f1f8204..a00333c 100644
--- a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
@@ -198,23 +198,23 @@
     //   }
     // }
 
+    LibraryName libraryName = referencesFromIndexed != null
+        ? new LibraryName(referencesFromIndexed.library.reference)
+        : libraryBuilder.libraryName;
+
     NameScheme staticFieldNameScheme = new NameScheme(
         isInstanceMember: false,
         className: name,
         isExtensionMember: false,
         extensionName: null,
-        libraryReference: referencesFromIndexed != null
-            ? referencesFromIndexed.library.reference
-            : libraryBuilder.library.reference);
+        libraryName: libraryName);
 
     NameScheme procedureNameScheme = new NameScheme(
         isInstanceMember: true,
         className: name,
         isExtensionMember: false,
         extensionName: null,
-        libraryReference: referencesFromIndexed != null
-            ? referencesFromIndexed.library.reference
-            : libraryBuilder.library.reference);
+        libraryName: libraryName);
 
     Reference? constructorReference;
     Reference? tearOffReference;
@@ -226,7 +226,7 @@
       constructorReference =
           referencesFromIndexed.lookupConstructorReference(new Name(""));
       tearOffReference = referencesFromIndexed.lookupGetterReference(
-          constructorTearOffName("", referencesFromIndexed.library));
+          new Name(constructorTearOffName(""), referencesFromIndexed.library));
       toStringReference =
           referencesFromIndexed.lookupGetterReference(new Name("toString"));
       Name valuesName = new Name("values");
@@ -295,12 +295,13 @@
     // The default constructor is added if no generative or unnamed factory
     // constructors are declared.
     bool needsSynthesizedDefaultConstructor = true;
-    if (constructorScope.local.isNotEmpty) {
-      for (MemberBuilder constructorBuilder in constructorScope.local.values) {
-        if (!constructorBuilder.isFactory || constructorBuilder.name == "") {
-          needsSynthesizedDefaultConstructor = false;
-          break;
-        }
+    Iterator<MemberBuilder> iterator = constructorScope.filteredIterator(
+        includeDuplicates: false, includeAugmentations: true);
+    while (iterator.moveNext()) {
+      MemberBuilder constructorBuilder = iterator.current;
+      if (!constructorBuilder.isFactory || constructorBuilder.name == "") {
+        needsSynthesizedDefaultConstructor = false;
+        break;
       }
     }
 
@@ -342,7 +343,10 @@
           .registerInitializedField(valuesBuilder);
       constructors[""] = synthesizedDefaultConstructorBuilder;
     } else {
-      constructorScope.forEach((name, member) {
+      Iterator<MemberBuilder> iterator = constructorScope.filteredNameIterator(
+          includeDuplicates: false, includeAugmentations: true);
+      while (iterator.moveNext()) {
+        MemberBuilder member = iterator.current;
         if (member is DeclaredSourceConstructorBuilder) {
           member.ensureGrowableFormals();
           member.formals!.insert(
@@ -366,7 +370,7 @@
                   libraryBuilder,
                   charOffset));
         }
-      });
+      }
     }
 
     if (scope.lookupLocalMember("toString", setter: false) == null) {
@@ -496,7 +500,7 @@
             parent: scope.parent,
             debugName: "enum $name",
             isModifiable: false),
-        constructorScope..local.addAll(constructors),
+        constructorScope..addLocalMembers(constructors),
         cls,
         elementBuilders,
         enumConstantInfos,
@@ -522,15 +526,19 @@
     }
 
     members.forEach(setParent);
-    constructorScope.local.forEach(setParent);
+    constructorScope
+        .filteredNameIterator(
+            includeDuplicates: false, includeAugmentations: true)
+        .forEach(setParent);
     selfType.bind(libraryBuilder, enumBuilder);
 
-    if (constructorScope.local.isNotEmpty) {
-      for (MemberBuilder constructorBuilder in constructorScope.local.values) {
-        if (!constructorBuilder.isFactory && !constructorBuilder.isConst) {
-          libraryBuilder.addProblem(messageEnumNonConstConstructor,
-              constructorBuilder.charOffset, noLength, fileUri);
-        }
+    Iterator<MemberBuilder> constructorIterator = constructorScope
+        .filteredIterator(includeDuplicates: false, includeAugmentations: true);
+    while (constructorIterator.moveNext()) {
+      MemberBuilder constructorBuilder = constructorIterator.current;
+      if (!constructorBuilder.isFactory && !constructorBuilder.isConst) {
+        libraryBuilder.addProblem(messageEnumNonConstConstructor,
+            constructorBuilder.charOffset, noLength, fileUri);
       }
     }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
index 8c6fbad..8faedba 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -26,6 +26,7 @@
 import '../problems.dart';
 import '../scope.dart';
 import '../util/helpers.dart';
+import 'name_scheme.dart';
 import 'source_field_builder.dart';
 import 'source_library_builder.dart';
 import 'source_member_builder.dart';
@@ -49,10 +50,12 @@
 
   final ExtensionTypeShowHideClauseBuilder extensionTypeShowHideClauseBuilder;
 
+  final ExtensionName extensionName;
+
   SourceExtensionBuilder(
       List<MetadataBuilder>? metadata,
       int modifiers,
-      String name,
+      this.extensionName,
       this.typeParameters,
       this.onType,
       this.extensionTypeShowHideClauseBuilder,
@@ -64,14 +67,20 @@
       int endOffset,
       Extension? referenceFrom)
       : _extension = new Extension(
-            name: name,
+            name: extensionName.name,
             fileUri: parent.fileUri,
             typeParameters:
                 TypeVariableBuilder.typeParametersFromBuilders(typeParameters),
             reference: referenceFrom?.reference)
           ..isExtensionTypeDeclaration = isExtensionTypeDeclaration
+          ..isUnnamedExtension = extensionName.isUnnamedExtension
           ..fileOffset = nameOffset,
-        super(metadata, modifiers, name, parent, nameOffset, scope);
+        super(metadata, modifiers, extensionName.name, parent, nameOffset,
+            scope) {
+    extensionName.attachExtension(_extension);
+  }
+
+  bool get isUnnamedExtension => extensionName.isUnnamedExtension;
 
   @override
   SourceLibraryBuilder get libraryBuilder =>
@@ -241,16 +250,17 @@
 
   int buildBodyNodes({required bool addMembersToLibrary}) {
     int count = 0;
-    scope
-        .filteredIterator<SourceMemberBuilder>(
-            parent: this, includeDuplicates: false, includeAugmentations: true)
-        .forEach((SourceMemberBuilder declaration) {
+    Iterator<SourceMemberBuilder> iterator =
+        scope.filteredIterator<SourceMemberBuilder>(
+            parent: this, includeDuplicates: false, includeAugmentations: true);
+    while (iterator.moveNext()) {
+      SourceMemberBuilder declaration = iterator.current;
       count +=
           declaration.buildBodyNodes((Member member, BuiltMemberKind kind) {
         _buildMember(declaration, member, kind,
             addMembersToLibrary: addMembersToLibrary);
       });
-    });
+    }
     return count;
   }
 
@@ -289,15 +299,13 @@
       }
     }
 
-    void build(SourceMemberBuilder member) {
-      member.buildOutlineExpressions(
+    Iterator<SourceMemberBuilder> iterator =
+        scope.filteredIterator<SourceMemberBuilder>(
+            parent: this, includeDuplicates: false, includeAugmentations: true);
+    while (iterator.moveNext()) {
+      iterator.current.buildOutlineExpressions(
           classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
     }
-
-    scope
-        .filteredIterator<SourceMemberBuilder>(
-            parent: this, includeDuplicates: false, includeAugmentations: true)
-        .forEach(build);
   }
 }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
index c90fe39..4ffb430 100644
--- a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
@@ -45,8 +45,8 @@
   @override
   final TypeBuilder returnType;
 
-  final Procedure _procedureInternal;
-  final Procedure? _factoryTearOff;
+  late final Procedure _procedureInternal;
+  late final Procedure? _factoryTearOff;
 
   SourceFactoryBuilder? actualOrigin;
 
@@ -69,20 +69,20 @@
       AsyncMarker asyncModifier,
       NameScheme nameScheme,
       {String? nativeMethodName})
-      : _procedureInternal = new Procedure(
-            nameScheme.getProcedureName(ProcedureKind.Factory, name),
-            ProcedureKind.Factory,
-            new FunctionNode(null),
-            fileUri: libraryBuilder.fileUri,
-            reference: procedureReference)
-          ..fileStartOffset = startCharOffset
-          ..fileOffset = charOffset
-          ..fileEndOffset = charEndOffset
-          ..isNonNullableByDefault = libraryBuilder.isNonNullableByDefault,
-        _factoryTearOff = createFactoryTearOffProcedure(name, libraryBuilder,
-            libraryBuilder.fileUri, charOffset, tearOffReference),
-        super(metadata, modifiers, name, typeVariables, formals, libraryBuilder,
+      : super(metadata, modifiers, name, typeVariables, formals, libraryBuilder,
             charOffset, nativeMethodName) {
+    _procedureInternal = new Procedure(
+        dummyName, ProcedureKind.Factory, new FunctionNode(null),
+        fileUri: libraryBuilder.fileUri, reference: procedureReference)
+      ..fileStartOffset = startCharOffset
+      ..fileOffset = charOffset
+      ..fileEndOffset = charEndOffset
+      ..isNonNullableByDefault = libraryBuilder.isNonNullableByDefault;
+    nameScheme
+        .getProcedureMemberName(ProcedureKind.Factory, name)
+        .attachMember(_procedureInternal);
+    _factoryTearOff = createFactoryTearOffProcedure(name, libraryBuilder,
+        libraryBuilder.fileUri, charOffset, tearOffReference);
     this.asyncModifier = asyncModifier;
   }
 
@@ -148,7 +148,6 @@
     _procedureInternal.isAbstract = isAbstract;
     _procedureInternal.isExternal = isExternal;
     _procedureInternal.isConst = isConst;
-    updatePrivateMemberName(_procedureInternal, libraryBuilder);
     _procedureInternal.isStatic = isStatic;
 
     if (_factoryTearOff != null) {
@@ -364,7 +363,6 @@
               .build(libraryBuilder, TypeUse.redirectionTypeArgument),
           growable: false);
     }
-    updatePrivateMemberName(_procedureInternal, libraryBuilder);
     if (_factoryTearOff != null) {
       _tearOffTypeParameters =
           buildRedirectingFactoryTearOffProcedureParameters(
diff --git a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
index 6f1a6b7..2ac2115 100644
--- a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
@@ -481,35 +481,38 @@
       return fieldType;
     }
 
-    InferredType implicitFieldType = fieldType as InferredType;
-    DartType inferredType = implicitFieldType.computeType(hierarchy);
-    if (fieldType is InferredType) {
-      // `fieldType` may have changed if a circularity was detected when
-      // [inferredType] was computed.
-      if (!libraryBuilder.isNonNullableByDefault) {
-        inferredType = legacyErasure(inferredType);
-      }
-      type.registerInferredType(inferredType);
+    return libraryBuilder.loader.withUriForCrashReporting(fileUri, charOffset,
+        () {
+      InferredType implicitFieldType = fieldType as InferredType;
+      DartType inferredType = implicitFieldType.computeType(hierarchy);
+      if (fieldType is InferredType) {
+        // `fieldType` may have changed if a circularity was detected when
+        // [inferredType] was computed.
+        if (!libraryBuilder.isNonNullableByDefault) {
+          inferredType = legacyErasure(inferredType);
+        }
+        type.registerInferredType(inferredType);
 
-      IncludesTypeParametersNonCovariantly? needsCheckVisitor;
-      if (parent is ClassBuilder) {
-        Class enclosingClass = classBuilder!.cls;
-        if (enclosingClass.typeParameters.isNotEmpty) {
-          needsCheckVisitor = new IncludesTypeParametersNonCovariantly(
-              enclosingClass.typeParameters,
-              // We are checking the field type as if it is the type of the
-              // parameter of the implicit setter and this is a contravariant
-              // position.
-              initialVariance: Variance.contravariant);
+        IncludesTypeParametersNonCovariantly? needsCheckVisitor;
+        if (parent is ClassBuilder) {
+          Class enclosingClass = classBuilder!.cls;
+          if (enclosingClass.typeParameters.isNotEmpty) {
+            needsCheckVisitor = new IncludesTypeParametersNonCovariantly(
+                enclosingClass.typeParameters,
+                // We are checking the field type as if it is the type of the
+                // parameter of the implicit setter and this is a contravariant
+                // position.
+                initialVariance: Variance.contravariant);
+          }
+        }
+        if (needsCheckVisitor != null) {
+          if (fieldType.accept(needsCheckVisitor)) {
+            _fieldEncoding.setGenericCovariantImpl();
+          }
         }
       }
-      if (needsCheckVisitor != null) {
-        if (fieldType.accept(needsCheckVisitor)) {
-          _fieldEncoding.setGenericCovariantImpl();
-        }
-      }
-    }
-    return fieldType;
+      return fieldType;
+    });
   }
 
   @override
@@ -636,9 +639,7 @@
     bool isImmutable =
         isLate ? (isFinal && hasInitializer) : (isFinal || isConst);
     _field = isImmutable
-        ? new Field.immutable(
-            nameScheme.getFieldName(FieldNameType.Field, name,
-                isSynthesized: false),
+        ? new Field.immutable(dummyName,
             isFinal: isFinal,
             isConst: isConst,
             isLate: isLate,
@@ -646,15 +647,16 @@
             fieldReference: fieldReference,
             getterReference: getterReference,
             isEnumElement: isEnumElement)
-        : new Field.mutable(
-            nameScheme.getFieldName(FieldNameType.Field, name,
-                isSynthesized: false),
+        : new Field.mutable(dummyName,
             isFinal: isFinal,
             isLate: isLate,
             fileUri: fileUri,
             fieldReference: fieldReference,
             getterReference: getterReference,
             setterReference: setterReference);
+    nameScheme
+        .getFieldMemberName(FieldNameType.Field, name, isSynthesized: false)
+        .attachMember(_field);
     _field
       ..fileOffset = charOffset
       ..fileEndOffset = charEndOffset
@@ -702,7 +704,6 @@
         ..isExtensionMember = false;
     }
     _field.isLate = fieldBuilder.isLate;
-    updatePrivateMemberName(_field, libraryBuilder);
   }
 
   @override
@@ -851,8 +852,7 @@
         _isSetStrategy = isSetStrategy,
         _forceIncludeIsSetField =
             isSetStrategy == late_lowering.IsSetStrategy.forceUseIsSetField {
-    _field = new Field.mutable(
-        nameScheme.getFieldName(FieldNameType.Field, name, isSynthesized: true),
+    _field = new Field.mutable(dummyName,
         fileUri: fileUri,
         fieldReference: fieldReference,
         getterReference: fieldGetterReference,
@@ -861,6 +861,9 @@
       ..fileEndOffset = charEndOffset
       ..isNonNullableByDefault = true
       ..isInternalImplementation = true;
+    nameScheme
+        .getFieldMemberName(FieldNameType.Field, name, isSynthesized: true)
+        .attachMember(_field);
     switch (_isSetStrategy) {
       case late_lowering.IsSetStrategy.useSentinelOrNull:
       case late_lowering.IsSetStrategy.forceUseSentinel:
@@ -868,9 +871,7 @@
         break;
       case late_lowering.IsSetStrategy.forceUseIsSetField:
       case late_lowering.IsSetStrategy.useIsSetFieldOrNull:
-        _lateIsSetField = new Field.mutable(
-            nameScheme.getFieldName(FieldNameType.IsSetField, name,
-                isSynthesized: true),
+        _lateIsSetField = new Field.mutable(dummyName,
             fileUri: fileUri,
             fieldReference: lateIsSetFieldReference,
             getterReference: lateIsSetGetterReference,
@@ -879,11 +880,14 @@
           ..fileEndOffset = charEndOffset
           ..isNonNullableByDefault = true
           ..isInternalImplementation = true;
+        nameScheme
+            .getFieldMemberName(FieldNameType.IsSetField, name,
+                isSynthesized: true)
+            .attachMember(_lateIsSetField!);
         break;
     }
     _lateGetter = new Procedure(
-        nameScheme.getFieldName(FieldNameType.Getter, name,
-            isSynthesized: true),
+        dummyName,
         ProcedureKind.Getter,
         new FunctionNode(null)
           ..fileOffset = charOffset
@@ -893,13 +897,16 @@
       ..fileOffset = charOffset
       ..fileEndOffset = charEndOffset
       ..isNonNullableByDefault = true;
-    _lateSetter = _createSetter(
-        nameScheme.getFieldName(FieldNameType.Setter, name,
-            isSynthesized: true),
-        fileUri,
-        charOffset,
-        lateSetterReference,
+    nameScheme
+        .getFieldMemberName(FieldNameType.Getter, name, isSynthesized: true)
+        .attachMember(_lateGetter);
+    _lateSetter = _createSetter(fileUri, charOffset, lateSetterReference,
         isCovariantByDeclaration: isCovariantByDeclaration);
+    if (_lateSetter != null) {
+      nameScheme
+          .getFieldMemberName(FieldNameType.Setter, name, isSynthesized: true)
+          .attachMember(_lateSetter!);
+    }
   }
 
   late_lowering.IsSetEncoding get isSetEncoding {
@@ -1004,8 +1011,7 @@
   Statement _createGetterBody(
       CoreTypes coreTypes, String name, Expression? initializer);
 
-  Procedure? _createSetter(
-      Name name, Uri fileUri, int charOffset, Reference? reference,
+  Procedure? _createSetter(Uri fileUri, int charOffset, Reference? reference,
       {required bool isCovariantByDeclaration}) {
     // ignore: unnecessary_null_comparison
     assert(isCovariantByDeclaration != null);
@@ -1013,7 +1019,7 @@
       ..isCovariantByDeclaration = isCovariantByDeclaration
       ..fileOffset = fileOffset;
     return new Procedure(
-        name,
+        dummyName,
         ProcedureKind.Setter,
         new FunctionNode(null,
             positionalParameters: [parameter], returnType: const VoidType())
@@ -1102,7 +1108,6 @@
         ..isStatic = !isInstanceMember
         ..isExtensionMember = false;
     }
-    updatePrivateMemberName(_field, libraryBuilder);
     if (_lateIsSetField != null) {
       _lateIsSetField!
         ..isStatic = !isInstanceMember
@@ -1110,17 +1115,14 @@
         ..isExtensionMember = isExtensionMember
         ..type = libraryBuilder.loader
             .createCoreType('bool', Nullability.nonNullable);
-      updatePrivateMemberName(_lateIsSetField!, libraryBuilder);
     }
     _lateGetter
       ..isStatic = !isInstanceMember
       ..isExtensionMember = isExtensionMember;
-    updatePrivateMemberName(_lateGetter, libraryBuilder);
     if (_lateSetter != null) {
       _lateSetter!
         ..isStatic = !isInstanceMember
         ..isExtensionMember = isExtensionMember;
-      updatePrivateMemberName(_lateSetter!, libraryBuilder);
     }
   }
 
@@ -1407,8 +1409,7 @@
   }
 
   @override
-  Procedure? _createSetter(
-          Name name, Uri fileUri, int charOffset, Reference? reference,
+  Procedure? _createSetter(Uri fileUri, int charOffset, Reference? reference,
           {required bool isCovariantByDeclaration}) =>
       null;
 
@@ -1603,7 +1604,7 @@
             nameScheme.isInstanceMember {
     if (_isExtensionInstanceMember) {
       _getter = new Procedure(
-          nameScheme.getProcedureName(ProcedureKind.Getter, name),
+          dummyName,
           ProcedureKind.Method,
           new FunctionNode(null, positionalParameters: [
             new VariableDeclaration(extensionThisName)..fileOffset
@@ -1613,13 +1614,16 @@
         ..fileOffset = charOffset
         ..fileEndOffset = charEndOffset
         ..isNonNullableByDefault = isNonNullableByDefault;
+      nameScheme
+          .getProcedureMemberName(ProcedureKind.Getter, name)
+          .attachMember(_getter);
       if (!isFinal) {
         VariableDeclaration parameter =
             new VariableDeclaration("#externalFieldValue")
               ..isCovariantByDeclaration = isCovariantByDeclaration
               ..fileOffset = charOffset;
         _setter = new Procedure(
-            nameScheme.getProcedureName(ProcedureKind.Setter, name),
+            dummyName,
             ProcedureKind.Method,
             new FunctionNode(null,
                 positionalParameters: [
@@ -1634,26 +1638,27 @@
           ..fileOffset = charOffset
           ..fileEndOffset = charEndOffset
           ..isNonNullableByDefault = isNonNullableByDefault;
+        nameScheme
+            .getProcedureMemberName(ProcedureKind.Setter, name)
+            .attachMember(_setter!);
       }
     } else {
       _getter = new Procedure(
-          nameScheme.getFieldName(FieldNameType.Getter, name,
-              isSynthesized: true),
-          ProcedureKind.Getter,
-          new FunctionNode(null),
-          fileUri: fileUri,
-          reference: getterReference)
+          dummyName, ProcedureKind.Getter, new FunctionNode(null),
+          fileUri: fileUri, reference: getterReference)
         ..fileOffset = charOffset
         ..fileEndOffset = charEndOffset
         ..isNonNullableByDefault = isNonNullableByDefault;
+      nameScheme
+          .getFieldMemberName(FieldNameType.Getter, name, isSynthesized: true)
+          .attachMember(_getter);
       if (!isFinal) {
         VariableDeclaration parameter =
             new VariableDeclaration("#externalFieldValue")
               ..isCovariantByDeclaration = isCovariantByDeclaration
               ..fileOffset = charOffset;
         _setter = new Procedure(
-            nameScheme.getFieldName(FieldNameType.Setter, name,
-                isSynthesized: true),
+            dummyName,
             ProcedureKind.Setter,
             new FunctionNode(null,
                 positionalParameters: [parameter], returnType: const VoidType())
@@ -1664,6 +1669,9 @@
           ..fileOffset = charOffset
           ..fileEndOffset = charEndOffset
           ..isNonNullableByDefault = isNonNullableByDefault;
+        nameScheme
+            .getFieldMemberName(FieldNameType.Setter, name, isSynthesized: true)
+            .attachMember(_setter!);
       }
     }
   }
@@ -1755,7 +1763,6 @@
       ..isExtensionMember = isExtensionMember
       ..isAbstract = isAbstract && !isExternal
       ..isExternal = isExternal;
-    updatePrivateMemberName(_getter, libraryBuilder);
 
     if (_setter != null) {
       _setter!
@@ -1763,7 +1770,6 @@
         ..isExtensionMember = isExtensionMember
         ..isAbstract = isAbstract && !isExternal
         ..isExternal = isExternal;
-      updatePrivateMemberName(_setter!, libraryBuilder);
     }
   }
 
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 80d2746..a2f5939 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
@@ -174,6 +174,8 @@
   @override
   final Library library;
 
+  final LibraryName libraryName;
+
   final SourceLibraryBuilder? _immediateOrigin;
 
   final List<SourceFunctionBuilder> nativeMethods = <SourceFunctionBuilder>[];
@@ -313,6 +315,7 @@
             referencesFrom == null ? null : new IndexedLibrary(referencesFrom),
         _immediateOrigin = origin,
         _omittedTypeDeclarationBuilders = omittedTypes,
+        libraryName = new LibraryName(library.reference),
         super(
             fileUri,
             _libraryTypeParameterScopeBuilder.toScope(importScope,
@@ -625,6 +628,9 @@
         (name?.startsWith(currentTypeParameterScopeBuilder.name) ??
                 (name == currentTypeParameterScopeBuilder.name)) ||
             currentTypeParameterScopeBuilder.name == "operator" ||
+            (name == null &&
+                currentTypeParameterScopeBuilder.name ==
+                    UnnamedExtensionName.unnamedExtensionSentinel) ||
             identical(name, "<syntax-error>"),
         "${name} != ${currentTypeParameterScopeBuilder.name}");
     TypeParameterScopeBuilder previous = currentTypeParameterScopeBuilder;
@@ -841,13 +847,18 @@
     }
   }
 
-  Builder? addBuilder(String? name, Builder declaration, int charOffset,
+  Builder? addBuilder(String name, Builder declaration, int charOffset,
       {Reference? getterReference, Reference? setterReference}) {
     // TODO(ahe): Set the parent correctly here. Could then change the
     // implementation of MemberBuilder.isTopLevel to test explicitly for a
     // LibraryBuilder.
-    if (name == null) {
-      unhandled("null", "name", charOffset, fileUri);
+    if (declaration is SourceExtensionBuilder &&
+        declaration.isUnnamedExtension) {
+      assert(currentTypeParameterScopeBuilder ==
+          _libraryTypeParameterScopeBuilder);
+      declaration.parent = this;
+      currentTypeParameterScopeBuilder.extensions!.add(declaration);
+      return declaration;
     }
     if (getterReference != null) {
       loader.buildersCreatedWithReferences[getterReference] = declaration;
@@ -1299,6 +1310,7 @@
       }
       unresolvedNamedTypes.addAll(part.unresolvedNamedTypes);
       constructorReferences.addAll(part.constructorReferences);
+      part.libraryName.reference = libraryName.reference;
       part.partOfLibrary = this;
       part.scope.becomePartOf(scope);
       // TODO(ahe): Include metadata from part?
@@ -1385,18 +1397,19 @@
       import.finalizeImports(this);
     }
     if (!explicitCoreImport) {
-      loader.coreLibrary.exportScope
+      NameIterator<Builder> iterator = loader.coreLibrary.exportScope
           .filteredNameIterator(
-              includeDuplicates: false, includeAugmentations: false)
-          .forEach((String name, Builder member) {
-        addToScope(name, member, -1, true);
-      });
+              includeDuplicates: false, includeAugmentations: false);
+      while (iterator.moveNext()) {
+        addToScope(iterator.name, iterator.current, -1, true);
+      }
     }
 
-    exportScope
-        .filteredNameIterator(
-            includeDuplicates: false, includeAugmentations: false)
-        .forEach((String name, Builder member) {
+    NameIterator<Builder> iterator = exportScope.filteredNameIterator(
+        includeDuplicates: false, includeAugmentations: false);
+    while (iterator.moveNext()) {
+      String name = iterator.name;
+      Builder member = iterator.current;
       if (member.parent != this) {
         if (member is DynamicTypeDeclarationBuilder) {
           assert(name == 'dynamic',
@@ -1446,7 +1459,7 @@
           }
         }
       }
-    });
+    }
   }
 
   @override
@@ -1499,23 +1512,21 @@
       }
     }
 
-    Iterator<Builder> iterator = localMembersIterator;
+    Iterator<SourceClassBuilder> iterator = localMembersIteratorOfType();
     while (iterator.moveNext()) {
-      Builder declaration = iterator.current;
-      if (declaration is SourceClassBuilder) {
-        Class cls = declaration.cls;
-        if (cls != objectClass) {
-          cls.supertype ??= objectClass.asRawSupertype;
-          declaration.supertypeBuilder ??=
-              new NamedTypeBuilder.fromTypeDeclarationBuilder(
-                  objectClassBuilder, const NullabilityBuilder.omitted(),
-                  instanceTypeVariableAccess:
-                      InstanceTypeVariableAccessState.Unexpected);
-        }
-        if (declaration.isMixinApplication) {
-          cls.mixedInType =
-              declaration.mixedInTypeBuilder!.buildMixedInType(this);
-        }
+      SourceClassBuilder declaration = iterator.current;
+      Class cls = declaration.cls;
+      if (cls != objectClass) {
+        cls.supertype ??= objectClass.asRawSupertype;
+        declaration.supertypeBuilder ??=
+            new NamedTypeBuilder.fromTypeDeclarationBuilder(
+                objectClassBuilder, const NullabilityBuilder.omitted(),
+                instanceTypeVariableAccess:
+                    InstanceTypeVariableAccessState.Unexpected);
+      }
+      if (declaration.isMixinApplication) {
+        cls.mixedInType =
+            declaration.mixedInTypeBuilder!.buildMixedInType(this);
       }
     }
   }
@@ -1528,10 +1539,10 @@
       }
     }
 
-    Iterator<Builder> iterator = localMembersIterator;
+    Iterator<SourceClassBuilder> iterator = localMembersIteratorOfType();
     while (iterator.moveNext()) {
-      Builder member = iterator.current;
-      if (member is SourceClassBuilder && !member.isPatch) {
+      SourceClassBuilder member = iterator.current;
+      if (!member.isPatch) {
         sourceClasses.add(member);
       }
     }
@@ -1549,12 +1560,10 @@
       }
     }
 
-    Iterator<Builder> iterator = localMembersIterator;
+    Iterator<SourceClassBuilder> iterator = localMembersIteratorOfType();
     while (iterator.moveNext()) {
-      Builder builder = iterator.current;
-      if (builder is SourceClassBuilder) {
-        count += builder.resolveConstructors(this);
-      }
+      SourceClassBuilder builder = iterator.current;
+      count += builder.resolveConstructors(this);
     }
     return count;
   }
@@ -2049,7 +2058,7 @@
   void addExtensionDeclaration(
       List<MetadataBuilder>? metadata,
       int modifiers,
-      String extensionName,
+      String? name,
       List<TypeVariableBuilder>? typeVariables,
       TypeBuilder type,
       ExtensionTypeShowHideClauseBuilder extensionTypeShowHideClauseBuilder,
@@ -2058,9 +2067,9 @@
       int nameOffset,
       int endOffset) {
     // Nested declaration began in `OutlineBuilder.beginExtensionDeclaration`.
-    TypeParameterScopeBuilder declaration = endNestedDeclaration(
-        TypeParameterScopeKind.extensionDeclaration, extensionName)
-      ..resolveNamedTypes(typeVariables, this);
+    TypeParameterScopeBuilder declaration =
+        endNestedDeclaration(TypeParameterScopeKind.extensionDeclaration, name)
+          ..resolveNamedTypes(typeVariables, this);
     assert(declaration.parent == _libraryTypeParameterScopeBuilder);
     Map<String, Builder> members = declaration.members!;
     Map<String, MemberBuilder> constructors = declaration.constructors!;
@@ -2070,11 +2079,14 @@
         local: members,
         setters: setters,
         parent: scope.withTypeVariables(typeVariables),
-        debugName: "extension $extensionName",
+        debugName: "extension $name",
         isModifiable: false);
 
-    Extension? referenceFrom =
-        referencesFromIndexed?.lookupExtension(extensionName);
+    Extension? referenceFrom;
+    ExtensionName extensionName = declaration.extensionName!;
+    if (name != null) {
+      referenceFrom = referencesFromIndexed?.lookupExtension(name);
+    }
 
     ExtensionBuilder extensionBuilder = new SourceExtensionBuilder(
         metadata,
@@ -2120,7 +2132,7 @@
     members.forEach(setParentAndCheckConflicts);
     constructors.forEach(setParentAndCheckConflicts);
     setters.forEach(setParentAndCheckConflicts);
-    addBuilder(extensionName, extensionBuilder, nameOffset,
+    addBuilder(extensionBuilder.name, extensionBuilder, nameOffset,
         getterReference: referenceFrom?.reference);
   }
 
@@ -2483,10 +2495,8 @@
     }
     final bool isExtensionMember = currentTypeParameterScopeBuilder.kind ==
         TypeParameterScopeKind.extensionDeclaration;
-    String? extensionName;
-    if (isExtensionMember) {
-      extensionName = currentTypeParameterScopeBuilder.name;
-    }
+    ExtensionName? extensionName =
+        currentTypeParameterScopeBuilder.extensionName;
 
     Reference? fieldReference;
     Reference? fieldGetterReference;
@@ -2502,7 +2512,9 @@
         className: className,
         isExtensionMember: isExtensionMember,
         extensionName: extensionName,
-        libraryReference: referencesFrom?.reference ?? library.reference);
+        libraryName: referencesFrom != null
+            ? new LibraryName(referencesFrom!.reference)
+            : libraryName);
     if (referencesFrom != null) {
       IndexedContainer indexedContainer =
           (_currentClassReferencesFromIndexed ?? referencesFromIndexed)!;
@@ -2512,12 +2524,14 @@
         /// of top level methods using the extension instance member naming
         /// convention.
         fieldGetterReference = indexedContainer.lookupGetterReference(
-            nameScheme.getProcedureName(ProcedureKind.Getter, name));
+            nameScheme.getProcedureMemberName(ProcedureKind.Getter, name).name);
         fieldSetterReference = indexedContainer.lookupGetterReference(
-            nameScheme.getProcedureName(ProcedureKind.Setter, name));
+            nameScheme.getProcedureMemberName(ProcedureKind.Setter, name).name);
       } else {
-        Name nameToLookup = nameScheme.getFieldName(FieldNameType.Field, name,
-            isSynthesized: fieldIsLateWithLowering);
+        Name nameToLookup = nameScheme
+            .getFieldMemberName(FieldNameType.Field, name,
+                isSynthesized: fieldIsLateWithLowering)
+            .name;
         fieldReference = indexedContainer.lookupFieldReference(nameToLookup);
         fieldGetterReference =
             indexedContainer.lookupGetterReference(nameToLookup);
@@ -2526,21 +2540,24 @@
       }
 
       if (fieldIsLateWithLowering) {
-        Name lateIsSetName = nameScheme.getFieldName(
-            FieldNameType.IsSetField, name,
-            isSynthesized: fieldIsLateWithLowering);
+        Name lateIsSetName = nameScheme
+            .getFieldMemberName(FieldNameType.IsSetField, name,
+                isSynthesized: fieldIsLateWithLowering)
+            .name;
         lateIsSetFieldReference =
             indexedContainer.lookupFieldReference(lateIsSetName);
         lateIsSetGetterReference =
             indexedContainer.lookupGetterReference(lateIsSetName);
         lateIsSetSetterReference =
             indexedContainer.lookupSetterReference(lateIsSetName);
-        lateGetterReference = indexedContainer.lookupGetterReference(
-            nameScheme.getFieldName(FieldNameType.Getter, name,
-                isSynthesized: fieldIsLateWithLowering));
-        lateSetterReference = indexedContainer.lookupSetterReference(
-            nameScheme.getFieldName(FieldNameType.Setter, name,
-                isSynthesized: fieldIsLateWithLowering));
+        lateGetterReference = indexedContainer.lookupGetterReference(nameScheme
+            .getFieldMemberName(FieldNameType.Getter, name,
+                isSynthesized: fieldIsLateWithLowering)
+            .name);
+        lateSetterReference = indexedContainer.lookupSetterReference(nameScheme
+            .getFieldMemberName(FieldNameType.Setter, name,
+                isSynthesized: fieldIsLateWithLowering)
+            .name);
       }
     }
 
@@ -2590,8 +2607,9 @@
           .lookupConstructorReference(new Name(
               constructorName, _currentClassReferencesFromIndexed!.library));
       tearOffReference = _currentClassReferencesFromIndexed!
-          .lookupGetterReference(constructorTearOffName(
-              constructorName, _currentClassReferencesFromIndexed!.library));
+          .lookupGetterReference(new Name(
+              constructorTearOffName(constructorName),
+              _currentClassReferencesFromIndexed!.library));
     }
     DeclaredSourceConstructorBuilder constructorBuilder =
         new DeclaredSourceConstructorBuilder(
@@ -2656,14 +2674,17 @@
     String? className = (isInstanceMember && !isExtensionMember)
         ? currentTypeParameterScopeBuilder.name
         : null;
-    String? extensionName =
-        isExtensionMember ? currentTypeParameterScopeBuilder.name : null;
+    ExtensionName? extensionName = isExtensionMember
+        ? currentTypeParameterScopeBuilder.extensionName
+        : null;
     NameScheme nameScheme = new NameScheme(
         isExtensionMember: isExtensionMember,
         className: className,
         extensionName: extensionName,
         isInstanceMember: isInstanceMember,
-        libraryReference: referencesFrom?.reference ?? library.reference);
+        libraryName: referencesFrom != null
+            ? new LibraryName(referencesFrom!.reference)
+            : libraryName);
 
     if (returnType == null) {
       if (kind == ProcedureKind.Operator &&
@@ -2676,7 +2697,7 @@
     Reference? procedureReference;
     Reference? tearOffReference;
     if (referencesFrom != null) {
-      Name nameToLookup = nameScheme.getProcedureName(kind, name);
+      Name nameToLookup = nameScheme.getProcedureMemberName(kind, name).name;
       if (_currentClassReferencesFromIndexed != null) {
         if (kind == ProcedureKind.Setter) {
           procedureReference = _currentClassReferencesFromIndexed!
@@ -2697,7 +2718,9 @@
         }
         if (isExtensionMember && kind == ProcedureKind.Method) {
           tearOffReference = referencesFromIndexed!.lookupGetterReference(
-              nameScheme.getProcedureName(ProcedureKind.Getter, name));
+              nameScheme
+                  .getProcedureMemberName(ProcedureKind.Getter, name)
+                  .name);
         }
       }
     }
@@ -2775,11 +2798,12 @@
         className: null,
         extensionName: null,
         isInstanceMember: false,
-        libraryReference: referencesFrom != null
-            ? (_currentClassReferencesFromIndexed ?? referencesFromIndexed)!
-                .library
-                .reference
-            : library.reference);
+        libraryName: referencesFrom != null
+            ? new LibraryName(
+                (_currentClassReferencesFromIndexed ?? referencesFromIndexed)!
+                    .library
+                    .reference)
+            : libraryName);
 
     Reference? constructorReference;
     Reference? tearOffReference;
@@ -2788,8 +2812,8 @@
           .lookupConstructorReference(new Name(
               procedureName, _currentClassReferencesFromIndexed!.library));
       tearOffReference = _currentClassReferencesFromIndexed!
-          .lookupGetterReference(constructorTearOffName(
-              procedureName, _currentClassReferencesFromIndexed!.library));
+          .lookupGetterReference(new Name(constructorTearOffName(procedureName),
+              _currentClassReferencesFromIndexed!.library));
     }
 
     SourceFactoryBuilder procedureBuilder;
@@ -3099,6 +3123,10 @@
       Extension extension = declaration.build(coreLibrary,
           addMembersToLibrary: !declaration.isDuplicate);
       if (!declaration.isPatch && !declaration.isDuplicate) {
+        if (declaration.isUnnamedExtension) {
+          declaration.extensionName.name =
+              '_extension#${library.extensions.length}';
+        }
         library.addExtension(extension);
       }
     } else if (declaration is SourceMemberBuilder) {
@@ -3742,8 +3770,26 @@
       }
     }
 
-    for (Builder declaration
-        in _libraryTypeParameterScopeBuilder.members!.values) {
+    void processSourceProcedureBuilder(SourceProcedureBuilder member) {
+      List<NonSimplicityIssue> issues =
+          getNonSimplicityIssuesForTypeVariables(member.typeVariables);
+      if (member.formals != null && member.formals!.isNotEmpty) {
+        for (FormalParameterBuilder formal in member.formals!) {
+          issues.addAll(getInboundReferenceIssuesInType(formal.type));
+          _recursivelyReportGenericFunctionTypesAsBoundsForType(formal.type);
+        }
+      }
+      if (member.returnType is! OmittedTypeBuilder) {
+        issues.addAll(getInboundReferenceIssuesInType(member.returnType));
+        _recursivelyReportGenericFunctionTypesAsBoundsForType(
+            member.returnType);
+      }
+      reportIssues(issues);
+      count += computeDefaultTypesForVariables(member.typeVariables,
+          inErrorRecovery: issues.isNotEmpty);
+    }
+
+    void computeDefaultValuesForDeclaration(Builder declaration) {
       if (declaration is ClassBuilder) {
         {
           List<NonSimplicityIssue> issues =
@@ -3753,7 +3799,11 @@
           count += computeDefaultTypesForVariables(declaration.typeVariables,
               inErrorRecovery: issues.isNotEmpty);
 
-          declaration.constructorScope.forEach((String name, Builder member) {
+          Iterator<MemberBuilder> iterator = declaration.constructorScope
+              .filteredIterator(
+                  includeDuplicates: false, includeAugmentations: true);
+          while (iterator.moveNext()) {
+            MemberBuilder member = iterator.current;
             List<FormalParameterBuilder>? formals;
             if (member is SourceFactoryBuilder) {
               assert(member.isFactory,
@@ -3777,27 +3827,11 @@
                     formal.type);
               }
             }
-          });
+          }
         }
         declaration.forEach((String name, Builder member) {
           if (member is SourceProcedureBuilder) {
-            List<NonSimplicityIssue> issues =
-                getNonSimplicityIssuesForTypeVariables(member.typeVariables);
-            if (member.formals != null && member.formals!.isNotEmpty) {
-              for (FormalParameterBuilder formal in member.formals!) {
-                issues.addAll(getInboundReferenceIssuesInType(formal.type));
-                _recursivelyReportGenericFunctionTypesAsBoundsForType(
-                    formal.type);
-              }
-            }
-            if (member.returnType is! OmittedTypeBuilder) {
-              issues.addAll(getInboundReferenceIssuesInType(member.returnType));
-              _recursivelyReportGenericFunctionTypesAsBoundsForType(
-                  member.returnType);
-            }
-            reportIssues(issues);
-            count += computeDefaultTypesForVariables(member.typeVariables,
-                inErrorRecovery: issues.isNotEmpty);
+            processSourceProcedureBuilder(member);
           } else {
             assert(member is SourceFieldBuilder,
                 "Unexpected class member $member (${member.runtimeType}).");
@@ -3848,23 +3882,7 @@
         }
         declaration.forEach((String name, Builder member) {
           if (member is SourceProcedureBuilder) {
-            List<NonSimplicityIssue> issues =
-                getNonSimplicityIssuesForTypeVariables(member.typeVariables);
-            if (member.formals != null && member.formals!.isNotEmpty) {
-              for (FormalParameterBuilder formal in member.formals!) {
-                issues.addAll(getInboundReferenceIssuesInType(formal.type));
-                _recursivelyReportGenericFunctionTypesAsBoundsForType(
-                    formal.type);
-              }
-            }
-            if (member.returnType is! OmittedTypeBuilder) {
-              issues.addAll(getInboundReferenceIssuesInType(member.returnType));
-              _recursivelyReportGenericFunctionTypesAsBoundsForType(
-                  member.returnType);
-            }
-            reportIssues(issues);
-            count += computeDefaultTypesForVariables(member.typeVariables,
-                inErrorRecovery: issues.isNotEmpty);
+            processSourceProcedureBuilder(member);
           } else if (member is SourceFieldBuilder) {
             if (member.type is! OmittedTypeBuilder) {
               _recursivelyReportGenericFunctionTypesAsBoundsForType(
@@ -3892,19 +3910,20 @@
             "(${declaration.runtimeType}).");
       }
     }
+
+    for (Builder declaration
+        in _libraryTypeParameterScopeBuilder.members!.values) {
+      computeDefaultValuesForDeclaration(declaration);
+    }
     for (Builder declaration
         in _libraryTypeParameterScopeBuilder.setters!.values) {
-      assert(
-          declaration is SourceProcedureBuilder,
-          "Expected setter to be a ProcedureBuilder, "
-          "but got '${declaration.runtimeType}'");
-      if (declaration is SourceProcedureBuilder &&
-          declaration.formals != null &&
-          declaration.formals!.isNotEmpty) {
-        for (FormalParameterBuilder formal in declaration.formals!) {
-          reportIssues(getInboundReferenceIssuesInType(formal.type));
-          _recursivelyReportGenericFunctionTypesAsBoundsForType(formal.type);
-        }
+      computeDefaultValuesForDeclaration(declaration);
+    }
+    for (ExtensionBuilder declaration
+        in _libraryTypeParameterScopeBuilder.extensions!) {
+      if (declaration is SourceExtensionBuilder &&
+          declaration.isUnnamedExtension) {
+        computeDefaultValuesForDeclaration(declaration);
       }
     }
     return count;
@@ -4849,20 +4868,15 @@
       }
     }
 
-    Iterator<Builder> iterator = localMembersIterator;
+    Iterator<SourceTypeAliasBuilder> iterator = localMembersIteratorOfType();
     while (iterator.moveNext()) {
-      Builder? declaration = iterator.current;
-      while (declaration != null) {
-        if (declaration is SourceTypeAliasBuilder) {
-          declaration.buildTypedefTearOffs(this, (Procedure procedure) {
-            procedure.isStatic = true;
-            if (!declaration!.isPatch && !declaration.isDuplicate) {
-              library.addProcedure(procedure);
-            }
-          });
+      SourceTypeAliasBuilder declaration = iterator.current;
+      declaration.buildTypedefTearOffs(this, (Procedure procedure) {
+        procedure.isStatic = true;
+        if (!declaration.isPatch && !declaration.isDuplicate) {
+          library.addProcedure(procedure);
         }
-        declaration = declaration.next;
-      }
+      });
     }
   }
 }
@@ -4911,6 +4925,8 @@
   // kind.
   String _name;
 
+  ExtensionName? _extensionName;
+
   /// Offset of name token, updated by the outline builder along
   /// with the name as the current declaration changes.
   int _charOffset;
@@ -5004,14 +5020,21 @@
   /// Registers that this builder is preparing for an extension declaration with
   /// the given [name] and [typeVariables] located [charOffset].
   void markAsExtensionDeclaration(
-      String name, int charOffset, List<TypeVariableBuilder>? typeVariables) {
+      String? name, int charOffset, List<TypeVariableBuilder>? typeVariables) {
     assert(_kind == TypeParameterScopeKind.extensionDeclaration,
         "Unexpected declaration kind: $_kind");
-    _name = name;
+    _extensionName = name != null
+        ? new FixedExtensionName(name)
+        : new UnnamedExtensionName();
+    _name = _extensionName!.name;
     _charOffset = charOffset;
     _typeVariables = typeVariables;
   }
 
+  /// Returns `true` if this scope builder is for an unnamed extension
+  /// declaration.
+  bool get isUnnamedExtension => extensionName?.isUnnamedExtension ?? false;
+
   /// Registers that this builder is preparing for an enum declaration with
   /// the given [name] and [typeVariables] located [charOffset].
   void markAsEnumDeclaration(
@@ -5049,6 +5072,8 @@
 
   String get name => _name;
 
+  ExtensionName? get extensionName => _extensionName;
+
   int get charOffset => _charOffset;
 
   List<TypeVariableBuilder>? get typeVariables => _typeVariables;
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 7e46fcd..3047f4b 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -51,6 +51,7 @@
 import '../builder/library_builder.dart';
 import '../builder/member_builder.dart';
 import '../builder/modifier_builder.dart';
+import '../builder/name_iterator.dart';
 import '../builder/named_type_builder.dart';
 import '../builder/omitted_type_builder.dart';
 import '../builder/prefix_builder.dart';
@@ -85,6 +86,7 @@
 import '../ticker.dart' show Ticker;
 import '../type_inference/type_inference_engine.dart';
 import '../type_inference/type_inferrer.dart';
+import '../uri_offset.dart';
 import '../util/helpers.dart';
 import '../uris.dart';
 import 'diet_listener.dart' show DietListener;
@@ -228,7 +230,7 @@
 
   int byteCount = 0;
 
-  Uri? currentUriForCrashReporting;
+  UriOffset? currentUriForCrashReporting;
 
   ClassBuilder? _macroClassBuilder;
 
@@ -286,6 +288,16 @@
     _builders.clear();
   }
 
+  /// Run [f] with [uri] and [fileOffset] as the current uri/offset used for
+  /// reporting crashes.
+  T withUriForCrashReporting<T>(Uri uri, int fileOffset, T Function() f) {
+    UriOffset? oldUriForCrashReporting = currentUriForCrashReporting;
+    currentUriForCrashReporting = new UriOffset(uri, fileOffset);
+    T result = f();
+    currentUriForCrashReporting = oldUriForCrashReporting;
+    return result;
+  }
+
   @override
   LibraryBuilder get coreLibrary => _coreLibrary!;
 
@@ -658,7 +670,8 @@
   Future<Null> buildBodies(List<SourceLibraryBuilder> libraryBuilders) async {
     assert(_coreLibrary != null);
     for (SourceLibraryBuilder library in libraryBuilders) {
-      currentUriForCrashReporting = library.importUri;
+      currentUriForCrashReporting =
+          new UriOffset(library.importUri, TreeNode.noOffset);
       await buildBody(library);
     }
     // Workaround: This will return right away but avoid a "semi leak"
@@ -1005,7 +1018,8 @@
     _ensureCoreLibrary();
     while (_unparsedLibraries.isNotEmpty) {
       SourceLibraryBuilder library = _unparsedLibraries.removeFirst();
-      currentUriForCrashReporting = library.importUri;
+      currentUriForCrashReporting =
+          new UriOffset(library.importUri, TreeNode.noOffset);
       await buildOutline(library);
     }
     currentUriForCrashReporting = null;
@@ -1227,7 +1241,7 @@
             extensionName: null,
             isExtensionMember: false,
             isInstanceMember: false,
-            libraryReference: libraryBuilder.library.reference),
+            libraryName: libraryBuilder.libraryName),
         isInstanceMember: false,
         isExtensionMember: false)
       ..parent = parent;
@@ -1358,14 +1372,14 @@
       wasChanged = false;
       for (SourceLibraryBuilder exported in both) {
         for (Export export in exported.exporters) {
-          exported.exportScope
+          NameIterator<Builder> iterator = exported.exportScope
               .filteredNameIterator(
-                  includeDuplicates: false, includeAugmentations: false)
-              .forEach((String name, Builder member) {
-            if (export.addToExportScope(name, member)) {
+                  includeDuplicates: false, includeAugmentations: false);
+          while (iterator.moveNext()) {
+            if (export.addToExportScope(iterator.name, iterator.current)) {
               wasChanged = true;
             }
-          });
+          }
         }
       }
     } while (wasChanged);
@@ -1391,19 +1405,19 @@
     _builders.forEach((Uri uri, dynamic l) {
       SourceLibraryBuilder library = l;
       Set<Builder> members = new Set<Builder>();
-      Iterator<Builder> iterator = library.localMembersIterator;
-      while (iterator.moveNext()) {
-        members.add(iterator.current);
+      Iterator<Builder> memberIterator = library.localMembersIterator;
+      while (memberIterator.moveNext()) {
+        members.add(memberIterator.current);
       }
       List<String> exports = <String>[];
-      library.exportScope
+      NameIterator<Builder> exportsIterator = library.exportScope
           .filteredNameIterator(
-              includeDuplicates: true, includeAugmentations: false)
-          .forEach((String name, Builder member) {
-        if (!members.contains(member)) {
-          exports.add(name);
+              includeDuplicates: true, includeAugmentations: false);
+      while (exportsIterator.moveNext()) {
+        if (!members.contains(exportsIterator.current)) {
+          exports.add(exportsIterator.name);
         }
-      });
+      }
       if (exports.isNotEmpty) {
         print("$uri exports $exports");
       }
@@ -1447,10 +1461,11 @@
     Map<Uri, List<ClassBuilder>> macroLibraries = {};
 
     for (LibraryBuilder libraryBuilder in libraryBuilders) {
-      Iterator<Builder> iterator = libraryBuilder.localMembersIterator;
+      Iterator<ClassBuilder> iterator =
+          libraryBuilder.localMembersIteratorOfType();
       while (iterator.moveNext()) {
-        Builder builder = iterator.current;
-        if (builder is ClassBuilder && builder.isMacro) {
+        ClassBuilder builder = iterator.current;
+        if (builder.isMacro) {
           Uri libraryUri = builder.libraryBuilder.importUri;
           if (!target.context.options.macroExecutor
               .libraryIsRegistered(libraryUri)) {
@@ -1556,8 +1571,13 @@
           if (macroClasses != null) {
             Map<String, List<String>>? constructorMap;
             for (ClassBuilder macroClass in macroClasses) {
-              List<String> constructors =
-                  macroClass.constructorScope.local.keys.toList();
+              List<String> constructors = [];
+              NameIterator<MemberBuilder> iterator = macroClass.constructorScope
+                  .filteredNameIterator(
+                      includeDuplicates: false, includeAugmentations: true);
+              while (iterator.moveNext()) {
+                constructors.add(iterator.name);
+              }
               if (constructors.isNotEmpty) {
                 // TODO(johnniwinther): If there is no constructor here, it
                 // means the macro had no _explicit_ constructors. Since macro
@@ -1892,7 +1912,10 @@
 
   void _checkConstructorsForMixin(
       SourceClassBuilder cls, ClassBuilder builder) {
-    for (Builder constructor in builder.constructorScope.local.values) {
+    Iterator<MemberBuilder> iterator = builder.constructorScope
+        .filteredIterator(includeDuplicates: false, includeAugmentations: true);
+    while (iterator.moveNext()) {
+      MemberBuilder constructor = iterator.current;
       if (constructor.isConstructor && !constructor.isSynthetic) {
         cls.addProblem(
             templateIllegalMixinDueToConstructors
@@ -2683,7 +2706,7 @@
 class AbstractClassInstantiationError {}
 
 class NoSuchMethodError {
-  NoSuchMethodError.withInvocation(receiver, invocation);
+  factory NoSuchMethodError.withInvocation(receiver, invocation) => throw '';
 }
 
 class StackTrace {}
@@ -2795,8 +2818,8 @@
       bool Function(dynamic)? isValidKey}) => null;
 }
 
-class _CompactLinkedHashSet<E> {
-  _CompactLinkedHashSet();
+class _InternalLinkedHashSet<E> {
+  _InternalLinkedHashSet();
 }
 
 class _UnmodifiableSet {
diff --git a/pkg/front_end/lib/src/fasta/source/source_member_builder.dart b/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
index f2140a0..14adcf3 100644
--- a/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
@@ -11,7 +11,6 @@
 import '../../base/common.dart';
 import '../builder/builder.dart';
 import '../builder/declaration_builder.dart';
-import '../builder/library_builder.dart';
 import '../builder/member_builder.dart';
 import '../kernel/kernel_helper.dart';
 import '../modifier.dart';
@@ -188,16 +187,6 @@
   final InferenceDataForTesting inferenceData = new InferenceDataForTesting();
 }
 
-/// If the name of [member] is private, update it to use the library reference
-/// of [libraryBuilder].
-// TODO(johnniwinther): Avoid having to update private names by setting
-// the correct library reference when creating parts.
-void updatePrivateMemberName(Member member, LibraryBuilder libraryBuilder) {
-  if (member.name.isPrivate) {
-    member.name = new Name(member.name.text, libraryBuilder.library);
-  }
-}
-
 class AugmentSuperTarget {
   final SourceMemberBuilder declaration;
   final Member? readTarget;
diff --git a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
index d527c0b..2775428 100644
--- a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
@@ -98,7 +98,7 @@
         super(metadata, modifiers, name, typeVariables, formals, libraryBuilder,
             charOffset, nativeMethodName) {
     _procedure = new Procedure(
-        nameScheme.getProcedureName(kind, name),
+        dummyName,
         isExtensionInstanceMember ? ProcedureKind.Method : kind,
         new FunctionNode(null),
         fileUri: libraryBuilder.fileUri,
@@ -108,17 +108,19 @@
       ..fileOffset = charOffset
       ..fileEndOffset = charEndOffset
       ..isNonNullableByDefault = libraryBuilder.isNonNullableByDefault;
+    nameScheme.getProcedureMemberName(kind, name).attachMember(_procedure);
     this.asyncModifier = asyncModifier;
     if (isExtensionMember && isInstanceMember && kind == ProcedureKind.Method) {
-      _extensionTearOff ??= new Procedure(
-          nameScheme.getProcedureName(ProcedureKind.Getter, name),
-          ProcedureKind.Method,
-          new FunctionNode(null),
+      _extensionTearOff = new Procedure(
+          dummyName, ProcedureKind.Method, new FunctionNode(null),
           isStatic: true,
           isExtensionMember: true,
           reference: _tearOffReference,
           fileUri: fileUri)
         ..isNonNullableByDefault = libraryBuilder.isNonNullableByDefault;
+      nameScheme
+          .getProcedureMemberName(ProcedureKind.Getter, name)
+          .attachMember(_extensionTearOff!);
     }
   }
 
@@ -276,7 +278,6 @@
     _procedure.isAbstract = isAbstract;
     _procedure.isExternal = isExternal;
     _procedure.isConst = isConst;
-    updatePrivateMemberName(_procedure, libraryBuilder);
     if (isExtensionMethod) {
       _procedure.isExtensionMember = true;
       _procedure.isStatic = true;
@@ -288,7 +289,6 @@
     }
     if (extensionTearOff != null) {
       _buildExtensionTearOff(libraryBuilder, parent as ExtensionBuilder);
-      updatePrivateMemberName(extensionTearOff!, libraryBuilder);
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 499a0c9..b0a4b4b 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -289,9 +289,11 @@
               new Name(constructorName, declaration.libraryBuilder.library);
           Reference? tearOffReference;
           if (libraryBuilder.referencesFromIndexed != null) {
+            Name tearOffName = new Name(
+                typedefTearOffName(name, constructorName),
+                libraryBuilder.referencesFromIndexed!.library);
             tearOffReference = libraryBuilder.referencesFromIndexed!
-                .lookupGetterReference(typedefTearOffName(name, constructorName,
-                    libraryBuilder.referencesFromIndexed!.library));
+                .lookupGetterReference(tearOffName);
           }
 
           Procedure tearOff = tearOffs![targetName] =
diff --git a/pkg/front_end/lib/src/fasta/source/value_kinds.dart b/pkg/front_end/lib/src/fasta/source/value_kinds.dart
index 9df321b..1cab98e 100644
--- a/pkg/front_end/lib/src/fasta/source/value_kinds.dart
+++ b/pkg/front_end/lib/src/fasta/source/value_kinds.dart
@@ -97,6 +97,8 @@
       const UnionValueKind([Name, QualifiedName, Operator]);
   static const ValueKind NameOrParserRecovery =
       const UnionValueKind([Name, ParserRecovery]);
+  static const ValueKind NameOrParserRecoveryOrNull =
+      const UnionValueKind([NameOrNull, ParserRecovery]);
   static const ValueKind MetadataListOrNull =
       const SingleValueKind<List<type.MetadataBuilder>>(NullValue.Metadata);
   static const ValueKind ObjectList = const SingleValueKind<List<Object>>();
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
index 48b6064..b6ab581 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
@@ -35,6 +35,7 @@
 import '../names.dart';
 import '../problems.dart' show unhandled;
 import '../source/source_library_builder.dart';
+import '../uri_offset.dart';
 import 'closure_context.dart';
 import 'for_in.dart';
 import 'inference_helper.dart';
@@ -233,7 +234,7 @@
 
   /// Computes uri and offset for [node] for internal errors in a way that is
   /// safe for both top-level and full inference.
-  _UriOffset _computeUriOffset(TreeNode node) {
+  UriOffset _computeUriOffset(TreeNode node) {
     Uri uri;
     int fileOffset;
     if (!isTopLevel) {
@@ -252,12 +253,12 @@
         fileOffset = TreeNode.noOffset;
       }
     }
-    return new _UriOffset(uri, fileOffset);
+    return new UriOffset(uri, fileOffset);
   }
 
   ExpressionInferenceResult _unhandledExpression(
       Expression node, DartType typeContext) {
-    _UriOffset uriOffset = _computeUriOffset(node);
+    UriOffset uriOffset = _computeUriOffset(node);
     unhandled("${node.runtimeType}", "InferenceVisitor", uriOffset.fileOffset,
         uriOffset.uri);
   }
@@ -479,7 +480,7 @@
   }
 
   StatementInferenceResult _unhandledStatement(Statement node) {
-    _UriOffset uriOffset = _computeUriOffset(node);
+    UriOffset uriOffset = _computeUriOffset(node);
     return unhandled("${node.runtimeType}", "InferenceVisitor",
         uriOffset.fileOffset, uriOffset.uri);
   }
@@ -868,7 +869,7 @@
   @override
   ExpressionInferenceResult visitConstructorInvocation(
       ConstructorInvocation node, DartType typeContext) {
-    inferConstructorParameterTypes(node.target);
+    ensureMemberType(node.target);
     bool hadExplicitTypeArguments = hasExplicitTypeArguments(node.arguments);
     FunctionType functionType = node.target.function
         .computeThisFunctionType(libraryBuilder.nonNullable);
@@ -1182,12 +1183,50 @@
         result.inferredType, result.applyResult(resultNode));
   }
 
+  /// Returns the function type of [constructor] when called through [typedef].
+  FunctionType _computeAliasedConstructorFunctionType(
+      Constructor constructor, Typedef typedef) {
+    ensureMemberType(constructor);
+    FunctionNode function = constructor.function;
+    // We need create a copy of the list of type parameters, otherwise
+    // transformations like erasure don't work.
+    List<TypeParameter> classTypeParametersCopy =
+        new List.of(constructor.enclosingClass.typeParameters);
+    List<TypeParameter> typedefTypeParametersCopy =
+        new List.of(typedef.typeParameters);
+    List<DartType> asTypeArguments =
+        getAsTypeArguments(typedefTypeParametersCopy, libraryBuilder.library);
+    TypedefType typedefType = new TypedefType(
+        typedef, libraryBuilder.library.nonNullable, asTypeArguments);
+    DartType unaliasedTypedef = typedefType.unalias;
+    assert(unaliasedTypedef is InterfaceType,
+        "[typedef] is assumed to resolve to an interface type");
+    InterfaceType targetType = unaliasedTypedef as InterfaceType;
+    Substitution substitution = Substitution.fromPairs(
+        classTypeParametersCopy, targetType.typeArguments);
+    List<DartType> positional = function.positionalParameters
+        .map((VariableDeclaration decl) =>
+            substitution.substituteType(decl.type))
+        .toList(growable: false);
+    List<NamedType> named = function.namedParameters
+        .map((VariableDeclaration decl) => new NamedType(
+            decl.name!, substitution.substituteType(decl.type),
+            isRequired: decl.isRequired))
+        .toList(growable: false);
+    named.sort();
+    return new FunctionType(
+        positional, typedefType.unalias, libraryBuilder.library.nonNullable,
+        namedParameters: named,
+        typeParameters: typedefTypeParametersCopy,
+        requiredParameterCount: function.requiredParameterCount);
+  }
+
   ExpressionInferenceResult visitTypeAliasedConstructorInvocation(
       TypeAliasedConstructorInvocation node, DartType typeContext) {
     assert(getExplicitTypeArguments(node.arguments) == null);
     Typedef typedef = node.typeAliasBuilder.typedef;
-    FunctionType calleeType = node.target.function
-        .computeAliasedConstructorFunctionType(typedef, libraryBuilder.library);
+    FunctionType calleeType =
+        _computeAliasedConstructorFunctionType(node.target, typedef);
     calleeType = replaceReturnType(calleeType, calleeType.returnType.unalias);
     InvocationInferenceResult result = inferInvocation(this, typeContext,
         node.fileOffset, calleeType, node.arguments as ArgumentsImpl,
@@ -1206,12 +1245,51 @@
         result.inferredType, result.applyResult(resultNode));
   }
 
+  /// Returns the function type of [factory] when called through [typedef].
+  FunctionType _computeAliasedFactoryFunctionType(
+      Procedure factory, Typedef typedef) {
+    assert(factory.isFactory, "Only run this method on a factory");
+    ensureMemberType(factory);
+    FunctionNode function = factory.function;
+    // We need create a copy of the list of type parameters, otherwise
+    // transformations like erasure don't work.
+    List<TypeParameter> classTypeParametersCopy =
+        new List.of(function.typeParameters);
+    List<TypeParameter> typedefTypeParametersCopy =
+        new List.of(typedef.typeParameters);
+    List<DartType> asTypeArguments =
+        getAsTypeArguments(typedefTypeParametersCopy, libraryBuilder.library);
+    TypedefType typedefType = new TypedefType(
+        typedef, libraryBuilder.library.nonNullable, asTypeArguments);
+    DartType unaliasedTypedef = typedefType.unalias;
+    assert(unaliasedTypedef is InterfaceType,
+        "[typedef] is assumed to resolve to an interface type");
+    InterfaceType targetType = unaliasedTypedef as InterfaceType;
+    Substitution substitution = Substitution.fromPairs(
+        classTypeParametersCopy, targetType.typeArguments);
+    List<DartType> positional = function.positionalParameters
+        .map((VariableDeclaration decl) =>
+            substitution.substituteType(decl.type))
+        .toList(growable: false);
+    List<NamedType> named = function.namedParameters
+        .map((VariableDeclaration decl) => new NamedType(
+            decl.name!, substitution.substituteType(decl.type),
+            isRequired: decl.isRequired))
+        .toList(growable: false);
+    named.sort();
+    return new FunctionType(
+        positional, typedefType.unalias, libraryBuilder.library.nonNullable,
+        namedParameters: named,
+        typeParameters: typedefTypeParametersCopy,
+        requiredParameterCount: function.requiredParameterCount);
+  }
+
   ExpressionInferenceResult visitTypeAliasedFactoryInvocation(
       TypeAliasedFactoryInvocation node, DartType typeContext) {
     assert(getExplicitTypeArguments(node.arguments) == null);
     Typedef typedef = node.typeAliasBuilder.typedef;
-    FunctionType calleeType = node.target.function
-        .computeAliasedFactoryFunctionType(typedef, libraryBuilder.library);
+    FunctionType calleeType =
+        _computeAliasedFactoryFunctionType(node.target, typedef);
     calleeType = replaceReturnType(calleeType, calleeType.returnType.unalias);
     InvocationInferenceResult result = inferInvocation(this, typeContext,
         node.fileOffset, calleeType, node.arguments as ArgumentsImpl,
@@ -1364,7 +1442,7 @@
     } else if (syntheticAssignment is InvalidExpression || hasProblem) {
       return new InvalidForInVariable(syntheticAssignment);
     } else {
-      _UriOffset uriOffset = _computeUriOffset(syntheticAssignment!);
+      UriOffset uriOffset = _computeUriOffset(syntheticAssignment!);
       return unhandled(
           "${syntheticAssignment.runtimeType}",
           "handleForInStatementWithoutVariable",
@@ -6180,7 +6258,7 @@
   @override
   InitializerInferenceResult visitRedirectingInitializer(
       RedirectingInitializer node) {
-    inferConstructorParameterTypes(node.target);
+    ensureMemberType(node.target);
     List<TypeParameter> classTypeParameters =
         node.target.enclosingClass.typeParameters;
     List<DartType> typeArguments = new List<DartType>.generate(
@@ -6404,7 +6482,7 @@
 
   @override
   InitializerInferenceResult visitSuperInitializer(SuperInitializer node) {
-    inferConstructorParameterTypes(node.target);
+    ensureMemberType(node.target);
     Substitution substitution = Substitution.fromSupertype(
         classHierarchy.getClassAsInstanceOf(
             thisType!.classNode, node.target.enclosingClass)!);
@@ -6525,7 +6603,11 @@
     for (int caseIndex = 0; caseIndex < node.cases.length; ++caseIndex) {
       SwitchCaseImpl switchCase = node.cases[caseIndex] as SwitchCaseImpl;
       hasDefault = hasDefault || switchCase.isDefault;
-      flowAnalysis.switchStatement_beginCase(switchCase.hasLabel, node);
+      flowAnalysis.switchStatement_beginCase();
+      flowAnalysis.switchStatement_beginAlternatives();
+      flowAnalysis.switchStatement_endAlternative();
+      flowAnalysis.switchStatement_endAlternatives(node,
+          hasLabels: switchCase.hasLabel);
       for (int index = 0; index < switchCase.expressions.length; index++) {
         ExpressionInferenceResult caseExpressionResult = inferExpression(
             switchCase.expressions[index], expressionType, true,
@@ -7285,6 +7367,26 @@
     List<Object> originalElementOrder = node.originalElementOrder;
     List<VariableDeclaration>? hoistedExpressions;
 
+    List<DartType>? positionalTypeContexts;
+    Map<String, DartType>? namedTypeContexts;
+    if (typeContext is RecordType &&
+        typeContext.positional.length == positional.length &&
+        typeContext.named.length == named.length) {
+      bool sameNames = true;
+      for (int i = 0; sameNames && i < named.length; i++) {
+        if (typeContext.named[i].name != named[i].name) {
+          sameNames = false;
+        }
+      }
+      if (sameNames) {
+        positionalTypeContexts = typeContext.positional;
+        namedTypeContexts = <String, DartType>{};
+        for (NamedType namedType in typeContext.named) {
+          namedTypeContexts[namedType.name] = namedType.type;
+        }
+      }
+    }
+
     List<DartType> positionalTypes;
     // ignore: UNUSED_LOCAL_VARIABLE
     List<NamedType> namedTypes;
@@ -7294,11 +7396,8 @@
       namedTypes = [];
       for (int index = 0; index < positional.length; index++) {
         Expression expression = positional[index];
-        ExpressionInferenceResult expressionResult = inferExpression(
-            expression,
-            // TODO(johnniwinther,cstefantsova): Provide the right type context.
-            const UnknownType(),
-            true);
+        ExpressionInferenceResult expressionResult = inferExpression(expression,
+            positionalTypeContexts?[index] ?? const UnknownType(), true);
         positionalTypes.add(expressionResult.inferredType);
         positional[index] = expressionResult.expression;
       }
@@ -7317,6 +7416,12 @@
       // Index into [positional] of the positional element we find next.
       int positionalIndex = positional.length - 1;
 
+      // For const literals we don't hoist to avoid using let variables in
+      // inside constants. Since the elements of the literal must be constant
+      // themselves, we know that there is no side effects of performing
+      // constant evaluation out of order.
+      final bool enableHoisting = !node.isConst;
+
       // Set to `true` if we need to hoist all preceding elements.
       bool needsHoisting = false;
 
@@ -7333,9 +7438,7 @@
         if (element is NamedExpression) {
           ExpressionInferenceResult expressionResult = inferExpression(
               element.value,
-              // TODO(johnniwinther,cstefantsova): Provide the right type
-              //  context.
-              const UnknownType(),
+              namedTypeContexts?[element.name] ?? const UnknownType(),
               true);
           Expression expression = expressionResult.expression;
           DartType type = expressionResult.inferredType;
@@ -7355,15 +7458,13 @@
           if (!namedNeedsSorting && element.name != sortedNames[nameIndex]) {
             // Named elements are not sorted, so we need to hoist and sort them.
             namedNeedsSorting = true;
-            needsHoisting = true;
+            needsHoisting = enableHoisting;
           }
           nameIndex--;
         } else {
           ExpressionInferenceResult expressionResult = inferExpression(
               element as Expression,
-              // TODO(johnniwinther,cstefantsova): Provide the right type
-              //  context.
-              const UnknownType(),
+              positionalTypeContexts?[positionalIndex] ?? const UnknownType(),
               true);
           Expression expression = expressionResult.expression;
           DartType type = expressionResult.inferredType;
@@ -7381,7 +7482,7 @@
             if (nameIndex >= 0) {
               // We have not seen all named elements yet, so we must hoist the
               // remaining named elements and the preceding positional elements.
-              needsHoisting = true;
+              needsHoisting = enableHoisting;
             }
           }
           positionalTypes[positionalIndex] = type;
@@ -7418,8 +7519,7 @@
           named,
           type = new RecordType(
               positionalTypes, namedTypes, libraryBuilder.nonNullable),
-          // TODO(johnniwinther): Support const literals.
-          isConst: false)
+          isConst: node.isConst)
         ..fileOffset = node.fileOffset;
     }
     if (hoistedExpressions != null) {
@@ -7446,13 +7546,6 @@
   }
 }
 
-class _UriOffset {
-  final Uri uri;
-  final int fileOffset;
-
-  _UriOffset(this.uri, this.fileOffset);
-}
-
 /// Offset and type information collection in [InferenceVisitor.inferMapEntry].
 class _MapLiteralEntryOffsets {
   // Stores the offset of the map entry found by inferMapEntry.
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
index 58f249d..8da6afa 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
@@ -326,7 +326,7 @@
   /// Ensures that the type of [member] has been computed.
   void ensureMemberType(Member member) {
     if (member is Constructor) {
-      inferConstructorParameterTypes(member);
+      _inferConstructorParameterTypes(member);
     }
     TypeDependency? typeDependency = engine.typeDependencies.remove(member);
     if (typeDependency != null) {
@@ -336,7 +336,7 @@
   }
 
   /// Ensures that all parameter types of [constructor] have been inferred.
-  void inferConstructorParameterTypes(Constructor target) {
+  void _inferConstructorParameterTypes(Constructor target) {
     SourceConstructorBuilder? constructor = engine.beingInferred[target];
     if (constructor != null) {
       // There is a cyclic dependency where inferring the types of the
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
index a7b860e..8640b82 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
@@ -834,6 +834,37 @@
       _protoConstraints.length = baseConstraintCount;
     }
 
+    // A record type `(M0,..., Mk, {M{k+1} d{k+1}, ..., Mm dm])` is a subtype
+    // match for a record type `(N0,..., Nk, {N{k+1} d{k+1}, ..., Nm dm])` with
+    // respect to `L` under constraints `C0 + ... + Cm`
+    // If for `i` in `0...m`, `Mi` is a subtype match for `Ni` with respect to
+    // `L` under constraints `Ci`.
+    if (p is RecordType &&
+        q is RecordType &&
+        p.positional.length == q.positional.length &&
+        p.named.length == q.named.length) {
+      bool sameNames = true;
+      for (int i = 0; sameNames && i < p.named.length; i++) {
+        if (p.named[i] != p.named[i]) {
+          sameNames = false;
+        }
+      }
+      if (sameNames) {
+        bool isMatch = true;
+        for (int i = 0; isMatch && i < p.positional.length; i++) {
+          isMatch = isMatch &&
+              _isNullabilityAwareSubtypeMatch(p.positional[i], q.positional[i],
+                  constrainSupertype: constrainSupertype);
+        }
+        for (int i = 0; isMatch && i < p.named.length; i++) {
+          isMatch = isMatch &&
+              _isNullabilityAwareSubtypeMatch(p.named[i].type, q.named[i].type,
+                  constrainSupertype: constrainSupertype);
+        }
+        if (isMatch) return true;
+      }
+    }
+
     return false;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index d00e995..266c506 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -331,6 +331,9 @@
     return typeEnvironment.coreTypes.isBottom(type);
   }
 
+  @override
+  bool isPropertyPromotable(Object property) => false;
+
   // TODO(cstefantsova): Consider checking for mutual subtypes instead of ==.
   @override
   bool isSameType(DartType type1, DartType type2) => type1 == type2;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
index 50e3941..c86b4ec 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
@@ -2,19 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
 
-import 'package:kernel/ast.dart'
-    show
-        DartType,
-        DartTypeVisitor,
-        DartTypeVisitor1,
-        FunctionType,
-        FutureOrType,
-        InterfaceType,
-        NamedType,
-        Nullability,
-        TypedefType,
-        TypeParameter,
-        Visitor;
+import 'package:kernel/ast.dart';
 import 'package:kernel/src/assumptions.dart';
 import 'package:kernel/src/printer.dart';
 
@@ -108,13 +96,37 @@
 }
 
 /// Visitor that computes [isKnown].
-class _IsKnownVisitor extends DartTypeVisitor<bool> {
+class _IsKnownVisitor implements DartTypeVisitor<bool> {
   const _IsKnownVisitor();
 
   @override
   bool defaultDartType(DartType node) => node is! UnknownType;
 
   @override
+  bool visitDynamicType(DynamicType node) => true;
+
+  @override
+  bool visitExtensionType(ExtensionType node) => true;
+
+  @override
+  bool visitInvalidType(InvalidType node) => true;
+
+  @override
+  bool visitNeverType(NeverType node) => true;
+
+  @override
+  bool visitIntersectionType(IntersectionType node) => true;
+
+  @override
+  bool visitNullType(NullType node) => true;
+
+  @override
+  bool visitTypeParameterType(TypeParameterType node) => true;
+
+  @override
+  bool visitVoidType(VoidType node) => true;
+
+  @override
   bool visitFunctionType(FunctionType node) {
     if (!node.returnType.accept(this)) return false;
     for (DartType parameterType in node.positionalParameters) {
@@ -139,6 +151,17 @@
   }
 
   @override
+  bool visitRecordType(RecordType node) {
+    for (DartType positional in node.positional) {
+      if (!positional.accept(this)) return false;
+    }
+    for (NamedType named in node.named) {
+      if (!named.type.accept(this)) return false;
+    }
+    return true;
+  }
+
+  @override
   bool visitFutureOrType(FutureOrType node) {
     return node.typeArgument.accept(this);
   }
diff --git a/pkg/front_end/lib/src/fasta/uri_offset.dart b/pkg/front_end/lib/src/fasta/uri_offset.dart
new file mode 100644
index 0000000..dde7f18
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/uri_offset.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2022, 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.
+
+class UriOffset {
+  final Uri uri;
+  final int fileOffset;
+
+  UriOffset(this.uri, this.fileOffset);
+}
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
index dc29b16..d191021 100644
--- a/pkg/front_end/lib/src/fasta/util/parser_ast_helper.dart
+++ b/pkg/front_end/lib/src/fasta/util/parser_ast_helper.dart
@@ -54,6 +54,17 @@
   }
 
   @override
+  void handleExtractorPatternFields(
+      int count, Token beginToken, Token endToken) {
+    ExtractorPatternFieldsHandle data = new ExtractorPatternFieldsHandle(
+        ParserAstType.HANDLE,
+        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);
@@ -1275,9 +1286,9 @@
   }
 
   @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
     LibraryNameEnd data = new LibraryNameEnd(ParserAstType.END,
-        libraryKeyword: libraryKeyword, semicolon: semicolon);
+        libraryKeyword: libraryKeyword, semicolon: semicolon, hasName: hasName);
     seen(data);
   }
 
@@ -1289,6 +1300,13 @@
   }
 
   @override
+  void handleMapPatternEntry(Token colon, Token endToken) {
+    MapPatternEntryHandle data = new MapPatternEntryHandle(ParserAstType.HANDLE,
+        colon: colon, endToken: endToken);
+    seen(data);
+  }
+
+  @override
   void beginLiteralString(Token token) {
     LiteralStringBegin data =
         new LiteralStringBegin(ParserAstType.BEGIN, token: token);
@@ -1820,6 +1838,27 @@
   }
 
   @override
+  void handleNullAssertPattern(Token bang) {
+    NullAssertPatternHandle data =
+        new NullAssertPatternHandle(ParserAstType.HANDLE, bang: bang);
+    seen(data);
+  }
+
+  @override
+  void handleNullCheckPattern(Token question) {
+    NullCheckPatternHandle data =
+        new NullCheckPatternHandle(ParserAstType.HANDLE, question: question);
+    seen(data);
+  }
+
+  @override
+  void handleVariablePattern(Token? keyword, Token variable) {
+    VariablePatternHandle data = new VariablePatternHandle(ParserAstType.HANDLE,
+        keyword: keyword, variable: variable);
+    seen(data);
+  }
+
+  @override
   void handleNoName(Token token) {
     NoNameHandle data = new NoNameHandle(ParserAstType.HANDLE, token: token);
     seen(data);
@@ -2025,6 +2064,13 @@
   }
 
   @override
+  void handleCastPattern(Token operator) {
+    CastPatternHandle data =
+        new CastPatternHandle(ParserAstType.HANDLE, operator: operator);
+    seen(data);
+  }
+
+  @override
   void handleAssignmentExpression(Token token) {
     AssignmentExpressionHandle data =
         new AssignmentExpressionHandle(ParserAstType.HANDLE, token: token);
@@ -2046,6 +2092,20 @@
   }
 
   @override
+  void beginBinaryPattern(Token token) {
+    BinaryPatternBegin data =
+        new BinaryPatternBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endBinaryPattern(Token token) {
+    BinaryPatternEnd data =
+        new BinaryPatternEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
   void handleEndingBinaryExpression(Token token) {
     EndingBinaryExpressionHandle data =
         new EndingBinaryExpressionHandle(ParserAstType.HANDLE, token: token);
@@ -2303,6 +2363,13 @@
   }
 
   @override
+  void handleListPattern(int count, Token leftBracket, Token rightBracket) {
+    ListPatternHandle data = new ListPatternHandle(ParserAstType.HANDLE,
+        count: count, leftBracket: leftBracket, rightBracket: rightBracket);
+    seen(data);
+  }
+
+  @override
   void handleLiteralSetOrMap(
     int count,
     Token leftBrace,
@@ -2320,6 +2387,13 @@
   }
 
   @override
+  void handleMapPattern(int count, Token leftBrace, Token rightBrace) {
+    MapPatternHandle data = new MapPatternHandle(ParserAstType.HANDLE,
+        count: count, leftBrace: leftBrace, rightBrace: rightBrace);
+    seen(data);
+  }
+
+  @override
   void handleLiteralNull(Token token) {
     LiteralNullHandle data =
         new LiteralNullHandle(ParserAstType.HANDLE, token: token);
@@ -2341,6 +2415,13 @@
   }
 
   @override
+  void handlePatternField(Token? colon) {
+    PatternFieldHandle data =
+        new PatternFieldHandle(ParserAstType.HANDLE, colon: colon);
+    seen(data);
+  }
+
+  @override
   void handleNamedRecordField(Token colon) {
     NamedRecordFieldHandle data =
         new NamedRecordFieldHandle(ParserAstType.HANDLE, colon: colon);
@@ -2430,9 +2511,11 @@
   }
 
   @override
-  void handleParenthesizedCondition(Token token) {
-    ParenthesizedConditionHandle data =
-        new ParenthesizedConditionHandle(ParserAstType.HANDLE, token: token);
+  void handleParenthesizedCondition(Token token, Token? case_) {
+    ParenthesizedConditionHandle data = new ParenthesizedConditionHandle(
+        ParserAstType.HANDLE,
+        token: token,
+        case_: case_);
     seen(data);
   }
 
@@ -2445,9 +2528,16 @@
   }
 
   @override
-  void endRecordLiteral(Token token, int count) {
-    RecordLiteralEnd data =
-        new RecordLiteralEnd(ParserAstType.END, token: token, count: count);
+  void endRecordLiteral(Token token, int count, Token? constKeyword) {
+    RecordLiteralEnd data = new RecordLiteralEnd(ParserAstType.END,
+        token: token, count: count, constKeyword: constKeyword);
+    seen(data);
+  }
+
+  @override
+  void handleRecordPattern(Token token, int count) {
+    RecordPatternHandle data = new RecordPatternHandle(ParserAstType.HANDLE,
+        token: token, count: count);
     seen(data);
   }
 
@@ -2459,6 +2549,31 @@
   }
 
   @override
+  void handleParenthesizedPattern(Token token) {
+    ParenthesizedPatternHandle data =
+        new ParenthesizedPatternHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleConstantPattern(Token? constKeyword) {
+    ConstantPatternHandle data = new ConstantPatternHandle(ParserAstType.HANDLE,
+        constKeyword: constKeyword);
+    seen(data);
+  }
+
+  @override
+  void handleExtractorPattern(
+      Token firstIdentifier, Token? dot, Token? secondIdentifier) {
+    ExtractorPatternHandle data = new ExtractorPatternHandle(
+        ParserAstType.HANDLE,
+        firstIdentifier: firstIdentifier,
+        dot: dot,
+        secondIdentifier: secondIdentifier);
+    seen(data);
+  }
+
+  @override
   void handleQualified(Token period) {
     QualifiedHandle data =
         new QualifiedHandle(ParserAstType.HANDLE, period: period);
@@ -2542,6 +2657,13 @@
   }
 
   @override
+  void handleRelationalPattern(Token token) {
+    RelationalPatternHandle data =
+        new RelationalPatternHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
   void handleUnaryPrefixAssignmentExpression(Token token) {
     UnaryPrefixAssignmentExpressionHandle data =
         new UnaryPrefixAssignmentExpressionHandle(ParserAstType.HANDLE,
@@ -2745,6 +2867,23 @@
       };
 }
 
+class ExtractorPatternFieldsHandle extends ParserAstNode {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  ExtractorPatternFieldsHandle(ParserAstType type,
+      {required this.count, required this.beginToken, required this.endToken})
+      : super("ExtractorPatternFields", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
 class AsyncModifierHandle extends ParserAstNode {
   final Token? asyncToken;
   final Token? starToken;
@@ -4960,15 +5099,19 @@
 class LibraryNameEnd extends ParserAstNode {
   final Token libraryKeyword;
   final Token semicolon;
+  final bool hasName;
 
   LibraryNameEnd(ParserAstType type,
-      {required this.libraryKeyword, required this.semicolon})
+      {required this.libraryKeyword,
+      required this.semicolon,
+      required this.hasName})
       : super("LibraryName", type);
 
   @override
   Map<String, Object?> get deprecatedArguments => {
         "libraryKeyword": libraryKeyword,
         "semicolon": semicolon,
+        "hasName": hasName,
       };
 }
 
@@ -4987,6 +5130,21 @@
       };
 }
 
+class MapPatternEntryHandle extends ParserAstNode {
+  final Token colon;
+  final Token endToken;
+
+  MapPatternEntryHandle(ParserAstType type,
+      {required this.colon, required this.endToken})
+      : super("MapPatternEntry", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "colon": colon,
+        "endToken": endToken,
+      };
+}
+
 class LiteralStringBegin extends ParserAstNode {
   final Token token;
 
@@ -5956,6 +6114,45 @@
       };
 }
 
+class NullAssertPatternHandle extends ParserAstNode {
+  final Token bang;
+
+  NullAssertPatternHandle(ParserAstType type, {required this.bang})
+      : super("NullAssertPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "bang": bang,
+      };
+}
+
+class NullCheckPatternHandle extends ParserAstNode {
+  final Token question;
+
+  NullCheckPatternHandle(ParserAstType type, {required this.question})
+      : super("NullCheckPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "question": question,
+      };
+}
+
+class VariablePatternHandle extends ParserAstNode {
+  final Token? keyword;
+  final Token variable;
+
+  VariablePatternHandle(ParserAstType type,
+      {this.keyword, required this.variable})
+      : super("VariablePattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "keyword": keyword,
+        "variable": variable,
+      };
+}
+
 class NoNameHandle extends ParserAstNode {
   final Token token;
 
@@ -6321,6 +6518,18 @@
       };
 }
 
+class CastPatternHandle extends ParserAstNode {
+  final Token operator;
+
+  CastPatternHandle(ParserAstType type, {required this.operator})
+      : super("CastPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
 class AssignmentExpressionHandle extends ParserAstNode {
   final Token token;
 
@@ -6357,6 +6566,30 @@
       };
 }
 
+class BinaryPatternBegin extends ParserAstNode {
+  final Token token;
+
+  BinaryPatternBegin(ParserAstType type, {required this.token})
+      : super("BinaryPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class BinaryPatternEnd extends ParserAstNode {
+  final Token token;
+
+  BinaryPatternEnd(ParserAstType type, {required this.token})
+      : super("BinaryPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
 class EndingBinaryExpressionHandle extends ParserAstNode {
   final Token token;
 
@@ -6813,6 +7046,25 @@
       };
 }
 
+class ListPatternHandle extends ParserAstNode {
+  final int count;
+  final Token leftBracket;
+  final Token rightBracket;
+
+  ListPatternHandle(ParserAstType type,
+      {required this.count,
+      required this.leftBracket,
+      required this.rightBracket})
+      : super("ListPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "leftBracket": leftBracket,
+        "rightBracket": rightBracket,
+      };
+}
+
 class LiteralSetOrMapHandle extends ParserAstNode {
   final int count;
   final Token leftBrace;
@@ -6838,6 +7090,23 @@
       };
 }
 
+class MapPatternHandle extends ParserAstNode {
+  final int count;
+  final Token leftBrace;
+  final Token rightBrace;
+
+  MapPatternHandle(ParserAstType type,
+      {required this.count, required this.leftBrace, required this.rightBrace})
+      : super("MapPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "leftBrace": leftBrace,
+        "rightBrace": rightBrace,
+      };
+}
+
 class LiteralNullHandle extends ParserAstNode {
   final Token token;
 
@@ -6877,6 +7146,18 @@
       };
 }
 
+class PatternFieldHandle extends ParserAstNode {
+  final Token? colon;
+
+  PatternFieldHandle(ParserAstType type, {this.colon})
+      : super("PatternField", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "colon": colon,
+      };
+}
+
 class NamedRecordFieldHandle extends ParserAstNode {
   final Token colon;
 
@@ -7032,13 +7313,16 @@
 
 class ParenthesizedConditionHandle extends ParserAstNode {
   final Token token;
+  final Token? case_;
 
-  ParenthesizedConditionHandle(ParserAstType type, {required this.token})
+  ParenthesizedConditionHandle(ParserAstType type,
+      {required this.token, this.case_})
       : super("ParenthesizedCondition", type);
 
   @override
   Map<String, Object?> get deprecatedArguments => {
         "token": token,
+        "case_": case_,
       };
 }
 
@@ -7058,15 +7342,32 @@
 class RecordLiteralEnd extends ParserAstNode {
   final Token token;
   final int count;
+  final Token? constKeyword;
 
   RecordLiteralEnd(ParserAstType type,
-      {required this.token, required this.count})
+      {required this.token, required this.count, this.constKeyword})
       : super("RecordLiteral", type);
 
   @override
   Map<String, Object?> get deprecatedArguments => {
         "token": token,
         "count": count,
+        "constKeyword": constKeyword,
+      };
+}
+
+class RecordPatternHandle extends ParserAstNode {
+  final Token token;
+  final int count;
+
+  RecordPatternHandle(ParserAstType type,
+      {required this.token, required this.count})
+      : super("RecordPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "count": count,
       };
 }
 
@@ -7082,6 +7383,47 @@
       };
 }
 
+class ParenthesizedPatternHandle extends ParserAstNode {
+  final Token token;
+
+  ParenthesizedPatternHandle(ParserAstType type, {required this.token})
+      : super("ParenthesizedPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ConstantPatternHandle extends ParserAstNode {
+  final Token? constKeyword;
+
+  ConstantPatternHandle(ParserAstType type, {this.constKeyword})
+      : super("ConstantPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "constKeyword": constKeyword,
+      };
+}
+
+class ExtractorPatternHandle extends ParserAstNode {
+  final Token firstIdentifier;
+  final Token? dot;
+  final Token? secondIdentifier;
+
+  ExtractorPatternHandle(ParserAstType type,
+      {required this.firstIdentifier, this.dot, this.secondIdentifier})
+      : super("ExtractorPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "firstIdentifier": firstIdentifier,
+        "dot": dot,
+        "secondIdentifier": secondIdentifier,
+      };
+}
+
 class QualifiedHandle extends ParserAstNode {
   final Token period;
 
@@ -7230,6 +7572,18 @@
       };
 }
 
+class RelationalPatternHandle extends ParserAstNode {
+  final Token token;
+
+  RelationalPatternHandle(ParserAstType type, {required this.token})
+      : super("RelationalPattern", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
 class UnaryPrefixAssignmentExpressionHandle extends ParserAstNode {
   final 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 50d2d77..bac2bc0 100644
--- a/pkg/front_end/lib/src/fasta/util/textual_outline.dart
+++ b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
@@ -768,7 +768,7 @@
   }
 
   @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
     unsortableElementStartToChunk[libraryKeyword] =
         new _LibraryNameChunk(libraryKeyword, semicolon);
   }
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 17ce850..50b64d5 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -32,6 +32,7 @@
 import 'fasta/kernel/utils.dart' show printComponentText, serializeComponent;
 import 'fasta/kernel/verifier.dart' show verifyComponent;
 import 'fasta/source/source_loader.dart' show SourceLoader;
+import 'fasta/uri_offset.dart';
 import 'fasta/uri_translator.dart' show UriTranslator;
 
 /// Implementation for the
@@ -120,7 +121,10 @@
           includeHierarchyAndCoreTypes: includeHierarchyAndCoreTypes,
           retainDataForTesting: retainDataForTesting);
     }
-  }, () => sourceLoader?.currentUriForCrashReporting ?? options.inputs.first);
+  },
+      () =>
+          sourceLoader?.currentUriForCrashReporting ??
+          new UriOffset(options.inputs.first, TreeNode.noOffset));
 }
 
 Future<CompilerResult> _buildInternal(
diff --git a/pkg/front_end/lib/src/testing/id_testing_utils.dart b/pkg/front_end/lib/src/testing/id_testing_utils.dart
index d060831..243b43b 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -48,6 +48,11 @@
     if (library.importUri == uri) {
       return library;
     }
+    for (LibraryPart part in library.parts) {
+      if (library.fileUri.resolve(part.partUri) == uri) {
+        return library;
+      }
+    }
   }
   if (required) {
     throw new ArgumentError("Library '$uri' not found.");
@@ -160,8 +165,13 @@
   TypeParameterScopeBuilder libraryBuilder = lookupLibraryDeclarationBuilder(
       compilerResult, extension.enclosingLibrary,
       required: required);
-  ExtensionBuilder? extensionBuilder =
-      libraryBuilder.members![extension.name] as ExtensionBuilder?;
+  ExtensionBuilder? extensionBuilder;
+  for (ExtensionBuilder builder in libraryBuilder.extensions!) {
+    if (builder.extension == extension) {
+      extensionBuilder = builder;
+      break;
+    }
+  }
   if (extensionBuilder == null && required) {
     throw new ArgumentError("ExtensionBuilder for $extension not found.");
   }
@@ -178,7 +188,8 @@
   MemberBuilder? memberBuilder;
   if (classBuilder != null) {
     if (member is Constructor || member is Procedure && member.isFactory) {
-      memberBuilder = classBuilder.constructorScope.local[memberName];
+      memberBuilder =
+          classBuilder.constructorScope.lookupLocalMember(memberName);
     } else {
       memberBuilder = classBuilder.scope.lookupLocalMember(memberName,
           setter: member is Procedure && member.isSetter) as MemberBuilder?;
@@ -414,10 +425,10 @@
       sb.write(comma);
       sb.write('{');
       comma = '';
-      for (ConstantRecordNamedField namedField in node.named) {
+      for (MapEntry<String, Constant> entry in node.named.entries) {
         sb.write(comma);
-        sb.write('${namedField.name}:');
-        namedField.value.accept(this);
+        sb.write('${entry.key}:');
+        entry.value.accept(this);
         comma = ',';
       }
       sb.write('}');
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 41cd897..d90b483 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -217,10 +217,6 @@
 DuplicatedParameterName/example: Fail
 DuplicatedRecordLiteralFieldName/analyzerCode: Fail
 DuplicatedRecordTypeFieldName/analyzerCode: Fail
-EmptyRecordTypeFieldsList/part_wrapped_script: Crash # Missing subtyping for record types
-EmptyRecordTypeFieldsList/script: Crash # Missing subtyping for record types
-EmptyRecordTypeNamedFieldsList/part_wrapped_script: Crash # Missing subtyping for record types
-EmptyRecordTypeNamedFieldsList/script: Crash # Missing subtyping for record types
 Encoding/analyzerCode: Fail
 EnumAbstractMember/analyzerCode: Fail
 EnumAbstractMember/example: Fail
@@ -583,6 +579,20 @@
 JsInteropNonExternalMember/example: Fail # Web compiler specific
 JsInteropOperatorsNotSupported/analyzerCode: Fail # Web compiler specific
 JsInteropOperatorsNotSupported/example: Fail # Web compiler specific
+JsInteropStaticInteropMockExternalExtensionMemberConflict/analyzerCode: Fail # Web compiler specific
+JsInteropStaticInteropMockExternalExtensionMemberConflict/example: Fail # Web compiler specific
+JsInteropStaticInteropMockMemberNotSubtype/analyzerCode: Fail # Web compiler specific
+JsInteropStaticInteropMockMemberNotSubtype/example: Fail # Web compiler specific
+JsInteropStaticInteropMockMissingOverride/analyzerCode: Fail # Web compiler specific
+JsInteropStaticInteropMockMissingOverride/example: Fail # Web compiler specific
+JsInteropStaticInteropMockNotDartInterfaceType/analyzerCode: Fail # Web compiler specific
+JsInteropStaticInteropMockNotDartInterfaceType/example: Fail # Web compiler specific
+JsInteropStaticInteropMockNotStaticInteropType/analyzerCode: Fail # Web compiler specific
+JsInteropStaticInteropMockNotStaticInteropType/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
 JsInteropStaticInteropTrustTypesUsageNotAllowed/analyzerCode: Fail # Web compiler specific
 JsInteropStaticInteropTrustTypesUsageNotAllowed/example: Fail # Web compiler specific
 JsInteropStaticInteropTrustTypesUsedWithoutStaticInterop/analyzerCode: Fail # Web compiler specific
@@ -752,8 +762,6 @@
 NullableTearoffError/example: Fail
 NullableTearoffWarning/analyzerCode: Fail
 NullableTearoffWarning/example: Fail
-OnlyOneRecordTypeFieldsList/part_wrapped_script: Crash # Missing subtyping for record types
-OnlyOneRecordTypeFieldsList/script: Crash # Missing subtyping for record types
 OperatorMinusParameterMismatch/example: Fail
 OperatorParameterMismatch0/analyzerCode: Fail
 OperatorParameterMismatch0/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 49add4f..b194ebb 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -323,34 +323,48 @@
       foo();
     }
 
-EmptyRecordTypeFieldsList:
-  problemMessage: "Record type fields list cannot be empty."
-  correctionMessage: "Try adding a record type field to the list."
-  analyzerCode: "MISSING_IDENTIFIER"
+RecordLiteralOnePositionalFieldNoTrailingComma:
+  problemMessage: "Record literal with one field requires a trailing comma."
+  correctionMessage: "Try adding a trailing comma."
+  analyzerCode: ParserErrorCode.RECORD_LITERAL_ONE_POSITIONAL_NO_TRAILING_COMMA
+  index: 127
   experiments: records
   script: >
     main() {
-      (/*missing*/) record = (1, 2,);
+      var record = const (1);
+    }
+
+RecordLiteralEmpty:
+  problemMessage: "Record literal can't be empty."
+  correctionMessage: "Try adding elements or use 'Record.empty()' instead."
+  analyzerCode: ParserErrorCode.RECORD_LITERAL_EMPTY
+  index: 128
+  experiments: records
+  script: >
+    main() {
+      var record = const ();
     }
 
 EmptyRecordTypeNamedFieldsList:
-  problemMessage: "Record type named fields list cannot be empty."
+  problemMessage: "Record type named fields list can't be empty."
   correctionMessage: "Try adding a record type named field to the list."
-  analyzerCode: "MISSING_IDENTIFIER"
+  analyzerCode: ParserErrorCode.EMPTY_RECORD_TYPE_NAMED_FIELDS_LIST
+  index: 129
   experiments: records
   script: >
     main() {
       (int, int, {/*missing*/}) record = (1, 2,);
     }
 
-OnlyOneRecordTypeFieldsList:
-  problemMessage: "Record type fields list cannot contain only one element without a named field."
-  correctionMessage: "Try adding another record type field to the list or add a named field."
-  analyzerCode: "MISSING_IDENTIFIER"
+RecordTypeOnePositionalFieldNoTrailingComma:
+  problemMessage: "Record type with one entry requires a trailing comma."
+  correctionMessage: "Try adding a trailing comma."
+  analyzerCode: ParserErrorCode.RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA
+  index: 130
   experiments: records
   script: >
     main() {
-      (int /*missing*/) record = (1, 2,);
+      (int /* missing trailing comma */) record = const (1, );
     }
 
 DuplicatedRecordTypeFieldName:
@@ -5217,6 +5231,26 @@
 JsInteropInvalidStaticClassMemberName:
   problemMessage: "JS interop static class members cannot have '.' in their JS name."
 
+JsInteropStaticInteropMockExternalExtensionMemberConflict:
+  problemMessage: "External extension member with name '#name' is defined in the following extensions and none are more specific: #string."
+  correctionMessage: "Try using the `@JS` annotation to rename conflicting members."
+
+JsInteropStaticInteropMockMemberNotSubtype:
+  problemMessage: "Dart class member '#name.#name2' with type '#type' is not a subtype of `@staticInterop` external extension member '#name3.#name4' with type '#type2'."
+  correctionMessage: "Change '#name.#name2' to be a subtype of '#name3.#name4'."
+
+JsInteropStaticInteropMockMissingOverride:
+  problemMessage: "`@staticInterop` class '#name' has external extension member '#name2', but Dart class '#name3' does not have an overriding instance member."
+  correctionMessage: "Add a Dart instance member in '#name3' that overrides '#name.#name2'."
+
+JsInteropStaticInteropMockNotDartInterfaceType:
+  problemMessage: "Second type argument '#type' is not a Dart interface type."
+  correctionMessage: "Use a Dart class instead."
+
+JsInteropStaticInteropMockNotStaticInteropType:
+  problemMessage: "First type argument '#type' is not a `@staticInterop` type."
+  correctionMessage: "Use a `@staticInterop` class instead."
+
 JsInteropStaticInteropWithInstanceMembers:
   problemMessage: "JS interop class '#name' with `@staticInterop` annotation cannot declare instance members."
   correctionMessage: "Try moving the instance member to a static extension."
@@ -5503,14 +5537,14 @@
     late int x;
 
 CompilingWithSoundNullSafety:
-  problemMessage: "Compiling with sound null safety"
+  problemMessage: "Compiling with sound null safety."
   configuration: nnbd-strong,compile
   severity: INFO
   script: |
     main() {}
 
 CompilingWithoutSoundNullSafety:
-  problemMessage: "Compiling without sound null safety"
+  problemMessage: "Compiling without sound null safety!\nDart 3 will only support sound null safety, see https://dart.dev/null-safety"
   configuration: nnbd-weak,compile
   severity: INFO
   script: |
diff --git a/pkg/front_end/parser_testcases/augmentation/augment_super.dart.intertwined.expect b/pkg/front_end/parser_testcases/augmentation/augment_super.dart.intertwined.expect
index eb29931..6b2d911 100644
--- a/pkg/front_end/parser_testcases/augmentation/augment_super.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/augmentation/augment_super.dart.intertwined.expect
@@ -609,7 +609,7 @@
                             parseExpression(;)
                               parsePrecedenceExpression(;, 1, true)
                                 parseUnaryExpression(;, true)
-                                  parsePrecedenceExpression(--, 16, true)
+                                  parsePrecedenceExpression(--, 17, true)
                                     parseUnaryExpression(--, true)
                                       parsePrimary(--, expression)
                                         parseAugmentSuperExpression(--, expression)
@@ -625,7 +625,7 @@
                         parseExpression(return)
                           parsePrecedenceExpression(return, 1, true)
                             parseUnaryExpression(return, true)
-                              parsePrecedenceExpression(-, 16, true)
+                              parsePrecedenceExpression(-, 17, true)
                                 parseUnaryExpression(-, true)
                                   parsePrimary(-, expression)
                                     parseAugmentSuperExpression(-, expression)
diff --git a/pkg/front_end/parser_testcases/error_recovery/await_not_in_async.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/await_not_in_async.dart.intertwined.expect
index 4aa4e44..c633c93 100644
--- a/pkg/front_end/parser_testcases/error_recovery/await_not_in_async.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/await_not_in_async.dart.intertwined.expect
@@ -101,7 +101,7 @@
                         looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                       parseAwaitExpression({, true)
                         listener: beginAwaitExpression(await)
-                        parsePrecedenceExpression(await, 16, true)
+                        parsePrecedenceExpression(await, 17, true)
                           parseUnaryExpression(await, true)
                             parsePrimary(await, expression)
                               parseSendOrFunctionLiteral(await, expression)
diff --git a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_00.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_00.dart.intertwined.expect
index bc757e9..b385061 100644
--- a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_00.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_00.dart.intertwined.expect
@@ -43,7 +43,7 @@
                                   parseUnaryExpression([, true)
                                     parsePrimary([, expression)
                                       parseParenthesizedExpressionFunctionLiteralOrRecordLiteral([)
-                                        parseParenthesizedExpressionOrRecordLiteral([)
+                                        parseParenthesizedExpressionOrRecordLiteral([, null)
                                           listener: beginParenthesizedExpressionOrRecordLiteral(()
                                           parseExpression(()
                                             parsePrecedenceExpression((, 1, true)
@@ -102,7 +102,7 @@
                                   parseUnaryExpression([, true)
                                     parsePrimary([, expression)
                                       parseParenthesizedExpressionFunctionLiteralOrRecordLiteral([)
-                                        parseParenthesizedExpressionOrRecordLiteral([)
+                                        parseParenthesizedExpressionOrRecordLiteral([, null)
                                           listener: beginParenthesizedExpressionOrRecordLiteral(()
                                           parseExpression(()
                                             parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/error_recovery/extension_member_contributor_test_completion.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/extension_member_contributor_test_completion.dart.intertwined.expect
index c3effb6..f1fe4c7 100644
--- a/pkg/front_end/parser_testcases/error_recovery/extension_member_contributor_test_completion.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/extension_member_contributor_test_completion.dart.intertwined.expect
@@ -329,7 +329,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_26073.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_26073.dart.expect
index 6767fb4..3ede2bc 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_26073.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_26073.dart.expect
@@ -4,7 +4,7 @@
 typedef c = foo(int x); // error.
                ^
 
-parser/error_recovery/issue_26073:4:19: Record type fields list cannot contain only one element without a named field.
+parser/error_recovery/issue_26073:4:19: Record type with one entry requires a trailing comma.
 typedef d = (int x); // error.
                   ^
 
@@ -122,7 +122,7 @@
           handleType(int, null)
           handleIdentifier(x, recordFieldDeclaration)
         endRecordTypeEntry()
-        handleRecoverableError(OnlyOneRecordTypeFieldsList, ), ))
+        handleRecoverableError(RecordTypeOnePositionalFieldNoTrailingComma, ), ))
       endRecordType((, null, 1, false)
     endTypedef(typedef, =, ;)
   endTopLevelDeclaration(typedef)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_26073.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_26073.dart.intertwined.expect
index 8874f3a..97bcffe 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_26073.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_26073.dart.intertwined.expect
@@ -137,8 +137,8 @@
             ensureIdentifier(int, recordFieldDeclaration)
               listener: handleIdentifier(x, recordFieldDeclaration)
             listener: endRecordTypeEntry()
-          reportRecoverableError(), OnlyOneRecordTypeFieldsList)
-            listener: handleRecoverableError(OnlyOneRecordTypeFieldsList, ), ))
+          reportRecoverableError(), RecordTypeOnePositionalFieldNoTrailingComma)
+            listener: handleRecoverableError(RecordTypeOnePositionalFieldNoTrailingComma, ), ))
           listener: endRecordType((, null, 1, false)
         ensureSemicolon())
         listener: endTypedef(typedef, =, ;)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_26810.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_26810.dart.intertwined.expect
index e480ced..e80d7cd 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_26810.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_26810.dart.intertwined.expect
@@ -392,7 +392,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -428,7 +428,7 @@
                                 isNextIdentifier(.)
                                 ensureIdentifier(., expressionContinuation)
                                 parseArgumentsOpt(hashCode)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -453,7 +453,7 @@
                                 listener: handleSend(hashCode, +)
                           listener: handleEndingBinaryExpression(.)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -498,7 +498,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -540,7 +540,7 @@
                                 listener: handleSend(hashCode, +)
                           listener: handleEndingBinaryExpression(.)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -590,7 +590,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -626,7 +626,7 @@
                                     isNextIdentifier(.)
                                     ensureIdentifier(., expressionContinuation)
                                     parseArgumentsOpt(hashCode)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -651,7 +651,7 @@
                                     listener: handleSend(hashCode, +)
                               listener: handleEndingBinaryExpression(.)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -703,7 +703,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -745,7 +745,7 @@
                                     listener: handleSend(hashCode, +)
                               listener: handleEndingBinaryExpression(.)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -1463,7 +1463,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -1486,7 +1486,7 @@
                                   isNextIdentifier(^)
                                   ensureIdentifier(^, expression)
                                   parseArgumentsOpt(y)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -1507,7 +1507,7 @@
                                     listener: handleNoArguments(+)
                                   listener: handleSend(y, +)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -1579,7 +1579,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -1606,7 +1606,7 @@
                                     listener: handleNoArguments(+)
                                   listener: handleSend(y, +)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -1683,7 +1683,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -1706,7 +1706,7 @@
                                       isNextIdentifier(^)
                                       ensureIdentifier(^, expression)
                                       parseArgumentsOpt(y)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -1727,7 +1727,7 @@
                                         listener: handleNoArguments(+)
                                       listener: handleSend(y, +)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -1806,7 +1806,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -1833,7 +1833,7 @@
                                         listener: handleNoArguments(+)
                                       listener: handleSend(y, +)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_26810_and.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_26810_and.dart.intertwined.expect
index 93b2ee2..69fd837 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_26810_and.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_26810_and.dart.intertwined.expect
@@ -392,7 +392,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -429,7 +429,7 @@
                                 isNextIdentifier(.)
                                 ensureIdentifier(., expressionContinuation)
                                 parseArgumentsOpt(hashCode)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -454,7 +454,7 @@
                                 listener: handleSend(hashCode, +)
                           listener: handleEndingBinaryExpression(.)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -499,7 +499,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -541,7 +541,7 @@
                                 listener: handleSend(hashCode, +)
                           listener: handleEndingBinaryExpression(.)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -591,7 +591,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -628,7 +628,7 @@
                                     isNextIdentifier(.)
                                     ensureIdentifier(., expressionContinuation)
                                     parseArgumentsOpt(hashCode)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -653,7 +653,7 @@
                                     listener: handleSend(hashCode, +)
                               listener: handleEndingBinaryExpression(.)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -705,7 +705,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -747,7 +747,7 @@
                                     listener: handleSend(hashCode, +)
                               listener: handleEndingBinaryExpression(.)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -1465,7 +1465,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -1489,7 +1489,7 @@
                                   isNextIdentifier(&)
                                   ensureIdentifier(&, expression)
                                   parseArgumentsOpt(y)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -1510,7 +1510,7 @@
                                     listener: handleNoArguments(+)
                                   listener: handleSend(y, +)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -1582,7 +1582,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -1609,7 +1609,7 @@
                                     listener: handleNoArguments(+)
                                   listener: handleSend(y, +)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -1686,7 +1686,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -1710,7 +1710,7 @@
                                       isNextIdentifier(&)
                                       ensureIdentifier(&, expression)
                                       parseArgumentsOpt(y)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -1731,7 +1731,7 @@
                                         listener: handleNoArguments(+)
                                       listener: handleSend(y, +)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -1810,7 +1810,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -1837,7 +1837,7 @@
                                         listener: handleNoArguments(+)
                                       listener: handleSend(y, +)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_26810_or.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_26810_or.dart.intertwined.expect
index 897cffb..020bc6a 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_26810_or.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_26810_or.dart.intertwined.expect
@@ -392,7 +392,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -429,7 +429,7 @@
                                 isNextIdentifier(.)
                                 ensureIdentifier(., expressionContinuation)
                                 parseArgumentsOpt(hashCode)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -454,7 +454,7 @@
                                 listener: handleSend(hashCode, +)
                           listener: handleEndingBinaryExpression(.)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -499,7 +499,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -541,7 +541,7 @@
                                 listener: handleSend(hashCode, +)
                           listener: handleEndingBinaryExpression(.)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -591,7 +591,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -628,7 +628,7 @@
                                     isNextIdentifier(.)
                                     ensureIdentifier(., expressionContinuation)
                                     parseArgumentsOpt(hashCode)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -653,7 +653,7 @@
                                     listener: handleSend(hashCode, +)
                               listener: handleEndingBinaryExpression(.)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -705,7 +705,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -747,7 +747,7 @@
                                     listener: handleSend(hashCode, +)
                               listener: handleEndingBinaryExpression(.)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -1465,7 +1465,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -1489,7 +1489,7 @@
                                   isNextIdentifier(|)
                                   ensureIdentifier(|, expression)
                                   parseArgumentsOpt(y)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -1510,7 +1510,7 @@
                                     listener: handleNoArguments(+)
                                   listener: handleSend(y, +)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -1582,7 +1582,7 @@
                             parseLiteralInt(=>)
                               listener: handleLiteralInt(1)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseSendOrFunctionLiteral(+, expression)
@@ -1609,7 +1609,7 @@
                                     listener: handleNoArguments(+)
                                   listener: handleSend(y, +)
                           listener: beginBinaryExpression(+)
-                          parsePrecedenceExpression(+, 14, true)
+                          parsePrecedenceExpression(+, 15, true)
                             parseUnaryExpression(+, true)
                               parsePrimary(+, expression)
                                 parseLiteralInt(+)
@@ -1686,7 +1686,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -1710,7 +1710,7 @@
                                       isNextIdentifier(|)
                                       ensureIdentifier(|, expression)
                                       parseArgumentsOpt(y)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -1731,7 +1731,7 @@
                                         listener: handleNoArguments(+)
                                       listener: handleSend(y, +)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -1810,7 +1810,7 @@
                                 parseLiteralInt(return)
                                   listener: handleLiteralInt(1)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseSendOrFunctionLiteral(+, expression)
@@ -1837,7 +1837,7 @@
                                         listener: handleNoArguments(+)
                                       listener: handleSend(y, +)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_44785.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_44785.crash_dart.expect
index 9bf88cd..4f18963 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_44785.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_44785.crash_dart.expect
@@ -64,7 +64,7 @@
               handleLiteralNull(null)
             endBinaryExpression(==)
           endBinaryExpression(||)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               beginReturnStatement(return)
@@ -124,7 +124,7 @@
               handleLiteralNull(null)
             endBinaryExpression(==)
           endBinaryExpression(&&)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               beginReturnStatement(return)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_44785.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_44785.crash_dart.intertwined.expect
index c213cf0..81dc2fa 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_44785.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_44785.crash_dart.intertwined.expect
@@ -55,8 +55,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -125,7 +125,7 @@
                           listener: endBinaryExpression(==)
                         listener: endBinaryExpression(||)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
@@ -210,8 +210,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -280,7 +280,7 @@
                           listener: endBinaryExpression(==)
                         listener: endBinaryExpression(&&)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_1.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_1.crash_dart.expect
index bdc7f1e..5502e62 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_1.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_1.crash_dart.expect
@@ -72,7 +72,7 @@
               handleLiteralNull(null)
             endBinaryExpression(==)
           endBinaryExpression(||)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               beginReturnStatement(return)
@@ -150,7 +150,7 @@
               handleLiteralNull(null)
             endBinaryExpression(==)
           endBinaryExpression(||)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               beginReturnStatement(return)
@@ -209,7 +209,7 @@
               handleLiteralNull(null)
             endBinaryExpression(==)
           endBinaryExpression(&&)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               beginReturnStatement(return)
@@ -287,7 +287,7 @@
               handleLiteralNull(null)
             endBinaryExpression(==)
           endBinaryExpression(&&)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               beginReturnStatement(return)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_1.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_1.crash_dart.intertwined.expect
index 748a56f..dcb1164 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_1.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_1.crash_dart.intertwined.expect
@@ -55,8 +55,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -125,7 +125,7 @@
                           listener: endBinaryExpression(==)
                         listener: endBinaryExpression(||)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
@@ -219,8 +219,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -337,7 +337,7 @@
                           listener: endBinaryExpression(==)
                         listener: endBinaryExpression(||)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
@@ -419,8 +419,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -489,7 +489,7 @@
                           listener: endBinaryExpression(==)
                         listener: endBinaryExpression(&&)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
@@ -583,8 +583,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -701,7 +701,7 @@
                           listener: endBinaryExpression(==)
                         listener: endBinaryExpression(&&)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_2.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_2.crash_dart.expect
index 488b2e2..3be9ba3 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_2.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_2.crash_dart.expect
@@ -45,7 +45,7 @@
               handleLiteralNull(null)
             endBinaryExpression(==)
           endBinaryExpression(||)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               beginReturnStatement(return)
@@ -121,7 +121,7 @@
               handleLiteralNull(null)
             endBinaryExpression(==)
           endBinaryExpression(||)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               beginReturnStatement(return)
@@ -179,7 +179,7 @@
               handleLiteralNull(null)
             endBinaryExpression(==)
           endBinaryExpression(&&)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               beginReturnStatement(return)
@@ -255,7 +255,7 @@
               handleLiteralNull(null)
             endBinaryExpression(==)
           endBinaryExpression(&&)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               beginReturnStatement(return)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_2.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_2.crash_dart.intertwined.expect
index afefe42..41cfbb1 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_2.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_44785_prime_2.crash_dart.intertwined.expect
@@ -55,8 +55,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -99,7 +99,7 @@
                           listener: endBinaryExpression(==)
                         listener: endBinaryExpression(||)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
@@ -193,8 +193,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -258,7 +258,7 @@
                           listener: endBinaryExpression(==)
                         listener: endBinaryExpression(||)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
@@ -340,8 +340,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -384,7 +384,7 @@
                           listener: endBinaryExpression(==)
                         listener: endBinaryExpression(&&)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
@@ -478,8 +478,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -543,7 +543,7 @@
                           listener: endBinaryExpression(==)
                         listener: endBinaryExpression(&&)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.expect
index 2b53b35..6e9934d 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.expect
@@ -31,7 +31,7 @@
             handleType(int, null)
           endIsOperatorType(is)
           handleIsOperator(is, null)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(or)
             handleIdentifier(or, expression)
             handleNoTypeArguments(})
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.intertwined.expect
index d1c53b4..36cd599 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.intertwined.expect
@@ -31,8 +31,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -67,7 +67,7 @@
                                 parseArgumentsOpt()
                     ensureCloseParen(int, ()
                       rewriter()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(or)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.expect
index 4344e3d..7dd446d 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.expect
@@ -61,7 +61,7 @@
                   handleType(T, null)
                 endIsOperatorType(is)
                 handleIsOperator(is, !)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(or)
                   handleIdentifier(or, expression)
                   handleNoTypeArguments(})
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.intertwined.expect
index 4684887..31708ed 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.intertwined.expect
@@ -78,8 +78,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -114,7 +114,7 @@
                                         parseArgumentsOpt()
                             ensureCloseParen(T, ()
                               rewriter()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(or)
                         parseStatement())
                           parseStatementX())
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.expect
index 998ca28..341f6c5 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.expect
@@ -11,7 +11,7 @@
     beginLibraryName(library)
       handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
       handleIdentifier(enum, libraryName)
-    endLibraryName(library, ;)
+    endLibraryName(library, ;, true)
   endTopLevelDeclaration(main)
   beginMetadataStar(main)
   endMetadataStar(0)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.intertwined.expect
index 7fa7ad9..4520f30 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.intertwined.expect
@@ -16,7 +16,7 @@
               listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
             listener: handleIdentifier(enum, libraryName)
         ensureSemicolon(enum)
-        listener: endLibraryName(library, ;)
+        listener: endLibraryName(library, ;, true)
   listener: endTopLevelDeclaration(main)
   parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
     parseMetadataStar(;)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.intertwined.expect
index 9e7e4e6..f399346 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.intertwined.expect
@@ -135,7 +135,7 @@
                                                           listener: handleNoArguments(*)
                                                         listener: handleSend(x, *)
                                                 listener: beginBinaryExpression(*)
-                                                parsePrecedenceExpression(*, 15, true)
+                                                parsePrecedenceExpression(*, 16, true)
                                                   parseUnaryExpression(*, true)
                                                     parsePrimary(*, expression)
                                                       parseLiteralInt(*)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48411.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48411.dart.intertwined.expect
index 2cad8a9..891e77c 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_48411.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48411.dart.intertwined.expect
@@ -706,7 +706,7 @@
                                   parseLiteralInt(=)
                                     listener: handleLiteralInt(2)
                               listener: beginBinaryExpression(*)
-                              parsePrecedenceExpression(*, 15, true)
+                              parsePrecedenceExpression(*, 16, true)
                                 parseUnaryExpression(*, true)
                                   parsePrimary(*, expression)
                                     parseLiteralInt(*)
@@ -835,7 +835,7 @@
                                       listener: handleNoArguments(-)
                                     listener: handleSend(x, -)
                             listener: beginBinaryExpression(-)
-                            parsePrecedenceExpression(-, 14, true)
+                            parsePrecedenceExpression(-, 15, true)
                               parseUnaryExpression(-, true)
                                 parsePrimary(-, expression)
                                   parseLiteralInt(-)
@@ -1003,7 +1003,7 @@
                                         listener: handleNoArguments(*)
                                       listener: handleSend(x, *)
                               listener: beginBinaryExpression(*)
-                              parsePrecedenceExpression(*, 15, true)
+                              parsePrecedenceExpression(*, 16, true)
                                 parseUnaryExpression(*, true)
                                   parsePrimary(*, expression)
                                     parseLiteralInt(*)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48411_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48411_prime.dart.intertwined.expect
index baded31..483fb9c 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_48411_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48411_prime.dart.intertwined.expect
@@ -694,7 +694,7 @@
                                   parseLiteralInt(=)
                                     listener: handleLiteralInt(2)
                               listener: beginBinaryExpression(*)
-                              parsePrecedenceExpression(*, 15, true)
+                              parsePrecedenceExpression(*, 16, true)
                                 parseUnaryExpression(*, true)
                                   parsePrimary(*, expression)
                                     parseLiteralInt(*)
@@ -820,7 +820,7 @@
                                       listener: handleNoArguments(-)
                                     listener: handleSend(x, -)
                             listener: beginBinaryExpression(-)
-                            parsePrecedenceExpression(-, 14, true)
+                            parsePrecedenceExpression(-, 15, true)
                               parseUnaryExpression(-, true)
                                 parsePrimary(-, expression)
                                   parseLiteralInt(-)
@@ -985,7 +985,7 @@
                                         listener: handleNoArguments(*)
                                       listener: handleSend(x, *)
                               listener: beginBinaryExpression(*)
-                              parsePrecedenceExpression(*, 15, true)
+                              parsePrecedenceExpression(*, 16, true)
                                 parseUnaryExpression(*, true)
                                   parsePrimary(*, expression)
                                     parseLiteralInt(*)
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_49116.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_49116.dart.expect
index 931a453..98418e7 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_49116.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_49116.dart.expect
@@ -241,7 +241,7 @@
             handleSend(returnsFuture, ))
             handleRecoverableError(AwaitNotAsync, await, await)
           endInvalidAwaitExpression(await, ), AwaitNotAsync)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
             endBlock(0, {, }, BlockKind(statement))
@@ -257,7 +257,7 @@
                 handleRecoverableError(AwaitNotAsync, await, await)
               endInvalidAwaitExpression(await, ), AwaitNotAsync)
               handleUnaryPrefixExpression(!)
-              handleParenthesizedCondition(()
+              handleParenthesizedCondition((, null)
               beginThenStatement({)
                 beginBlock({, BlockKind(statement))
                 endBlock(0, {, }, BlockKind(statement))
@@ -519,7 +519,7 @@
             handleSend(f, ))
             handleRecoverableError(AwaitNotAsync, await, await)
           endInvalidAwaitExpression(await, ), AwaitNotAsync)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
             endBlock(0, {, }, BlockKind(statement))
@@ -534,7 +534,7 @@
                 handleRecoverableError(AwaitNotAsync, await, await)
               endInvalidAwaitExpression(await, ), AwaitNotAsync)
               handleUnaryPrefixExpression(!)
-              handleParenthesizedCondition(()
+              handleParenthesizedCondition((, null)
               beginThenStatement({)
                 beginBlock({, BlockKind(statement))
                 endBlock(0, {, }, BlockKind(statement))
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_49116.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_49116.dart.intertwined.expect
index bb92ce2..1198d37 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_49116.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_49116.dart.intertwined.expect
@@ -104,7 +104,7 @@
                         looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                       parseAwaitExpression({, true)
                         listener: beginAwaitExpression(await)
-                        parsePrecedenceExpression(await, 16, true)
+                        parsePrecedenceExpression(await, 17, true)
                           parseUnaryExpression(await, true)
                             parsePrimary(await, expression)
                               parseSendOrFunctionLiteral(await, expression)
@@ -131,8 +131,8 @@
             parseStatementX(;)
               parseIfStatement(;)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -141,7 +141,7 @@
                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                           parseAwaitExpression((, true)
                             listener: beginAwaitExpression(await)
-                            parsePrecedenceExpression(await, 16, true)
+                            parsePrecedenceExpression(await, 17, true)
                               parseUnaryExpression(await, true)
                                 parsePrimary(await, expression)
                                   parseSendOrFunctionLiteral(await, expression)
@@ -162,7 +162,7 @@
                               listener: handleRecoverableError(AwaitNotAsync, await, await)
                             listener: endInvalidAwaitExpression(await, ), AwaitNotAsync)
                     ensureCloseParen(), ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
@@ -177,19 +177,19 @@
                   parseStatementX(else)
                     parseIfStatement(else)
                       listener: beginIfStatement(if)
-                      ensureParenthesizedCondition(if)
-                        parseExpressionInParenthesisRest(()
+                      ensureParenthesizedCondition(if, allowCase: false)
+                        parseExpressionInParenthesisRest((, allowCase: false)
                           parseExpression(()
                             parsePrecedenceExpression((, 1, true)
                               parseUnaryExpression((, true)
-                                parsePrecedenceExpression(!, 16, true)
+                                parsePrecedenceExpression(!, 17, true)
                                   parseUnaryExpression(!, true)
                                     inPlainSync()
                                     looksLikeAwaitExpression(!, AwaitOrYieldContext.UnaryExpression)
                                       looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                     parseAwaitExpression(!, true)
                                       listener: beginAwaitExpression(await)
-                                      parsePrecedenceExpression(await, 16, true)
+                                      parsePrecedenceExpression(await, 17, true)
                                         parseUnaryExpression(await, true)
                                           parsePrimary(await, expression)
                                             parseSendOrFunctionLiteral(await, expression)
@@ -211,7 +211,7 @@
                                       listener: endInvalidAwaitExpression(await, ), AwaitNotAsync)
                                 listener: handleUnaryPrefixExpression(!)
                           ensureCloseParen(), ()
-                        listener: handleParenthesizedCondition(()
+                          listener: handleParenthesizedCondition((, null)
                       listener: beginThenStatement({)
                       parseStatement())
                         parseStatementX())
@@ -253,7 +253,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression((, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -306,7 +306,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression((, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -334,7 +334,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression(,, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -362,7 +362,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression(,, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -401,7 +401,7 @@
                         looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                       parseAwaitExpression(;, true)
                         listener: beginAwaitExpression(await)
-                        parsePrecedenceExpression(await, 16, true)
+                        parsePrecedenceExpression(await, 17, true)
                           parseUnaryExpression(await, true)
                             parsePrimary(await, expression)
                               parseSendOrFunctionLiteral(await, expression)
@@ -429,7 +429,7 @@
                           looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                         parseAwaitExpression(^, true)
                           listener: beginAwaitExpression(await)
-                          parsePrecedenceExpression(await, 16, true)
+                          parsePrecedenceExpression(await, 17, true)
                             parseUnaryExpression(await, true)
                               parsePrimary(await, expression)
                                 parseSendOrFunctionLiteral(await, expression)
@@ -481,7 +481,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression((, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -509,7 +509,7 @@
                                               looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                             parseAwaitExpression(^, true)
                                               listener: beginAwaitExpression(await)
-                                              parsePrecedenceExpression(await, 16, true)
+                                              parsePrecedenceExpression(await, 17, true)
                                                 parseUnaryExpression(await, true)
                                                   parsePrimary(await, expression)
                                                     parseSendOrFunctionLiteral(await, expression)
@@ -549,7 +549,7 @@
                         looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                       parseAwaitExpression(;, true)
                         listener: beginAwaitExpression(await)
-                        parsePrecedenceExpression(await, 16, true)
+                        parsePrecedenceExpression(await, 17, true)
                           parseUnaryExpression(await, true)
                             parsePrimary(await, expression)
                               parseSendOrFunctionLiteral(await, expression)
@@ -570,14 +570,14 @@
                           listener: handleRecoverableError(AwaitNotAsync, await, await)
                         listener: endInvalidAwaitExpression(await, +, AwaitNotAsync)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         inPlainSync()
                         looksLikeAwaitExpression(+, AwaitOrYieldContext.UnaryExpression)
                           looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                         parseAwaitExpression(+, true)
                           listener: beginAwaitExpression(await)
-                          parsePrecedenceExpression(await, 16, true)
+                          parsePrecedenceExpression(await, 17, true)
                             parseUnaryExpression(await, true)
                               parsePrimary(await, expression)
                                 parseSendOrFunctionLiteral(await, expression)
@@ -629,7 +629,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression((, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -650,14 +650,14 @@
                                               listener: handleRecoverableError(AwaitNotAsync, await, await)
                                             listener: endInvalidAwaitExpression(await, +, AwaitNotAsync)
                                         listener: beginBinaryExpression(+)
-                                        parsePrecedenceExpression(+, 14, true)
+                                        parsePrecedenceExpression(+, 15, true)
                                           parseUnaryExpression(+, true)
                                             inPlainSync()
                                             looksLikeAwaitExpression(+, AwaitOrYieldContext.UnaryExpression)
                                               looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                             parseAwaitExpression(+, true)
                                               listener: beginAwaitExpression(await)
-                                              parsePrecedenceExpression(await, 16, true)
+                                              parsePrecedenceExpression(await, 17, true)
                                                 parseUnaryExpression(await, true)
                                                   parsePrimary(await, expression)
                                                     parseSendOrFunctionLiteral(await, expression)
@@ -697,7 +697,7 @@
                         looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                       parseAwaitExpression(;, true)
                         listener: beginAwaitExpression(await)
-                        parsePrecedenceExpression(await, 16, true)
+                        parsePrecedenceExpression(await, 17, true)
                           parseUnaryExpression(await, true)
                             parsePrimary(await, expression)
                               parseSendOrFunctionLiteral(await, expression)
@@ -718,14 +718,14 @@
                           listener: handleRecoverableError(AwaitNotAsync, await, await)
                         listener: endInvalidAwaitExpression(await, -, AwaitNotAsync)
                     listener: beginBinaryExpression(-)
-                    parsePrecedenceExpression(-, 14, true)
+                    parsePrecedenceExpression(-, 15, true)
                       parseUnaryExpression(-, true)
                         inPlainSync()
                         looksLikeAwaitExpression(-, AwaitOrYieldContext.UnaryExpression)
                           looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                         parseAwaitExpression(-, true)
                           listener: beginAwaitExpression(await)
-                          parsePrecedenceExpression(await, 16, true)
+                          parsePrecedenceExpression(await, 17, true)
                             parseUnaryExpression(await, true)
                               parsePrimary(await, expression)
                                 parseSendOrFunctionLiteral(await, expression)
@@ -777,7 +777,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression((, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -798,14 +798,14 @@
                                               listener: handleRecoverableError(AwaitNotAsync, await, await)
                                             listener: endInvalidAwaitExpression(await, -, AwaitNotAsync)
                                         listener: beginBinaryExpression(-)
-                                        parsePrecedenceExpression(-, 14, true)
+                                        parsePrecedenceExpression(-, 15, true)
                                           parseUnaryExpression(-, true)
                                             inPlainSync()
                                             looksLikeAwaitExpression(-, AwaitOrYieldContext.UnaryExpression)
                                               looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                             parseAwaitExpression(-, true)
                                               listener: beginAwaitExpression(await)
-                                              parsePrecedenceExpression(await, 16, true)
+                                              parsePrecedenceExpression(await, 17, true)
                                                 parseUnaryExpression(await, true)
                                                   parsePrimary(await, expression)
                                                     parseSendOrFunctionLiteral(await, expression)
@@ -840,14 +840,14 @@
                     parseExpression(;)
                       parsePrecedenceExpression(;, 1, true)
                         parseUnaryExpression(;, true)
-                          parsePrecedenceExpression(!, 16, true)
+                          parsePrecedenceExpression(!, 17, true)
                             parseUnaryExpression(!, true)
                               inPlainSync()
                               looksLikeAwaitExpression(!, AwaitOrYieldContext.UnaryExpression)
                                 looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                               parseAwaitExpression(!, true)
                                 listener: beginAwaitExpression(await)
-                                parsePrecedenceExpression(await, 16, true)
+                                parsePrecedenceExpression(await, 17, true)
                                   parseUnaryExpression(await, true)
                                     parsePrimary(await, expression)
                                       parseSendOrFunctionLiteral(await, expression)
@@ -871,14 +871,14 @@
                         listener: beginBinaryExpression(^)
                         parsePrecedenceExpression(^, 11, true)
                           parseUnaryExpression(^, true)
-                            parsePrecedenceExpression(!, 16, true)
+                            parsePrecedenceExpression(!, 17, true)
                               parseUnaryExpression(!, true)
                                 inPlainSync()
                                 looksLikeAwaitExpression(!, AwaitOrYieldContext.UnaryExpression)
                                   looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                 parseAwaitExpression(!, true)
                                   listener: beginAwaitExpression(await)
-                                  parsePrecedenceExpression(await, 16, true)
+                                  parsePrecedenceExpression(await, 17, true)
                                     parseUnaryExpression(await, true)
                                       parsePrimary(await, expression)
                                         parseSendOrFunctionLiteral(await, expression)
@@ -926,14 +926,14 @@
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
                                         parseUnaryExpression((, true)
-                                          parsePrecedenceExpression(!, 16, true)
+                                          parsePrecedenceExpression(!, 17, true)
                                             parseUnaryExpression(!, true)
                                               inPlainSync()
                                               looksLikeAwaitExpression(!, AwaitOrYieldContext.UnaryExpression)
                                                 looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                               parseAwaitExpression(!, true)
                                                 listener: beginAwaitExpression(await)
-                                                parsePrecedenceExpression(await, 16, true)
+                                                parsePrecedenceExpression(await, 17, true)
                                                   parseUnaryExpression(await, true)
                                                     parsePrimary(await, expression)
                                                       parseSendOrFunctionLiteral(await, expression)
@@ -957,14 +957,14 @@
                                         listener: beginBinaryExpression(^)
                                         parsePrecedenceExpression(^, 11, true)
                                           parseUnaryExpression(^, true)
-                                            parsePrecedenceExpression(!, 16, true)
+                                            parsePrecedenceExpression(!, 17, true)
                                               parseUnaryExpression(!, true)
                                                 inPlainSync()
                                                 looksLikeAwaitExpression(!, AwaitOrYieldContext.UnaryExpression)
                                                   looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                                 parseAwaitExpression(!, true)
                                                   listener: beginAwaitExpression(await)
-                                                  parsePrecedenceExpression(await, 16, true)
+                                                  parsePrecedenceExpression(await, 17, true)
                                                     parseUnaryExpression(await, true)
                                                       parsePrimary(await, expression)
                                                         parseSendOrFunctionLiteral(await, expression)
@@ -1057,8 +1057,8 @@
             parseStatementX(;)
               parseIfStatement(;)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1067,7 +1067,7 @@
                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                           parseAwaitExpression((, true)
                             listener: beginAwaitExpression(await)
-                            parsePrecedenceExpression(await, 16, true)
+                            parsePrecedenceExpression(await, 17, true)
                               parseUnaryExpression(await, true)
                                 parsePrimary(await, expression)
                                   parseSendOrFunctionLiteral(await, expression)
@@ -1084,7 +1084,7 @@
                               listener: handleRecoverableError(AwaitNotAsync, await, await)
                             listener: endInvalidAwaitExpression(await, ), AwaitNotAsync)
                     ensureCloseParen(f, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
@@ -1099,19 +1099,19 @@
                   parseStatementX(else)
                     parseIfStatement(else)
                       listener: beginIfStatement(if)
-                      ensureParenthesizedCondition(if)
-                        parseExpressionInParenthesisRest(()
+                      ensureParenthesizedCondition(if, allowCase: false)
+                        parseExpressionInParenthesisRest((, allowCase: false)
                           parseExpression(()
                             parsePrecedenceExpression((, 1, true)
                               parseUnaryExpression((, true)
-                                parsePrecedenceExpression(!, 16, true)
+                                parsePrecedenceExpression(!, 17, true)
                                   parseUnaryExpression(!, true)
                                     inPlainSync()
                                     looksLikeAwaitExpression(!, AwaitOrYieldContext.UnaryExpression)
                                       looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                     parseAwaitExpression(!, true)
                                       listener: beginAwaitExpression(await)
-                                      parsePrecedenceExpression(await, 16, true)
+                                      parsePrecedenceExpression(await, 17, true)
                                         parseUnaryExpression(await, true)
                                           parsePrimary(await, expression)
                                             parseSendOrFunctionLiteral(await, expression)
@@ -1129,7 +1129,7 @@
                                       listener: endInvalidAwaitExpression(await, ), AwaitNotAsync)
                                 listener: handleUnaryPrefixExpression(!)
                           ensureCloseParen(f, ()
-                        listener: handleParenthesizedCondition(()
+                          listener: handleParenthesizedCondition((, null)
                       listener: beginThenStatement({)
                       parseStatement())
                         parseStatementX())
@@ -1171,7 +1171,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression((, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -1220,7 +1220,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression((, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -1244,7 +1244,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression(,, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -1268,7 +1268,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression(,, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -1303,7 +1303,7 @@
                         looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                       parseAwaitExpression(;, true)
                         listener: beginAwaitExpression(await)
-                        parsePrecedenceExpression(await, 16, true)
+                        parsePrecedenceExpression(await, 17, true)
                           parseUnaryExpression(await, true)
                             parsePrimary(await, expression)
                               parseSendOrFunctionLiteral(await, expression)
@@ -1327,7 +1327,7 @@
                           looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                         parseAwaitExpression(^, true)
                           listener: beginAwaitExpression(await)
-                          parsePrecedenceExpression(await, 16, true)
+                          parsePrecedenceExpression(await, 17, true)
                             parseUnaryExpression(await, true)
                               parsePrimary(await, expression)
                                 parseSendOrFunctionLiteral(await, expression)
@@ -1375,7 +1375,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression((, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -1399,7 +1399,7 @@
                                               looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                             parseAwaitExpression(^, true)
                                               listener: beginAwaitExpression(await)
-                                              parsePrecedenceExpression(await, 16, true)
+                                              parsePrecedenceExpression(await, 17, true)
                                                 parseUnaryExpression(await, true)
                                                   parsePrimary(await, expression)
                                                     parseSendOrFunctionLiteral(await, expression)
@@ -1435,7 +1435,7 @@
                         looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                       parseAwaitExpression(;, true)
                         listener: beginAwaitExpression(await)
-                        parsePrecedenceExpression(await, 16, true)
+                        parsePrecedenceExpression(await, 17, true)
                           parseUnaryExpression(await, true)
                             parsePrimary(await, expression)
                               parseSendOrFunctionLiteral(await, expression)
@@ -1452,14 +1452,14 @@
                           listener: handleRecoverableError(AwaitNotAsync, await, await)
                         listener: endInvalidAwaitExpression(await, +, AwaitNotAsync)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         inPlainSync()
                         looksLikeAwaitExpression(+, AwaitOrYieldContext.UnaryExpression)
                           looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                         parseAwaitExpression(+, true)
                           listener: beginAwaitExpression(await)
-                          parsePrecedenceExpression(await, 16, true)
+                          parsePrecedenceExpression(await, 17, true)
                             parseUnaryExpression(await, true)
                               parsePrimary(await, expression)
                                 parseSendOrFunctionLiteral(await, expression)
@@ -1507,7 +1507,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression((, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -1524,14 +1524,14 @@
                                               listener: handleRecoverableError(AwaitNotAsync, await, await)
                                             listener: endInvalidAwaitExpression(await, +, AwaitNotAsync)
                                         listener: beginBinaryExpression(+)
-                                        parsePrecedenceExpression(+, 14, true)
+                                        parsePrecedenceExpression(+, 15, true)
                                           parseUnaryExpression(+, true)
                                             inPlainSync()
                                             looksLikeAwaitExpression(+, AwaitOrYieldContext.UnaryExpression)
                                               looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                             parseAwaitExpression(+, true)
                                               listener: beginAwaitExpression(await)
-                                              parsePrecedenceExpression(await, 16, true)
+                                              parsePrecedenceExpression(await, 17, true)
                                                 parseUnaryExpression(await, true)
                                                   parsePrimary(await, expression)
                                                     parseSendOrFunctionLiteral(await, expression)
@@ -1567,7 +1567,7 @@
                         looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                       parseAwaitExpression(;, true)
                         listener: beginAwaitExpression(await)
-                        parsePrecedenceExpression(await, 16, true)
+                        parsePrecedenceExpression(await, 17, true)
                           parseUnaryExpression(await, true)
                             parsePrimary(await, expression)
                               parseSendOrFunctionLiteral(await, expression)
@@ -1584,14 +1584,14 @@
                           listener: handleRecoverableError(AwaitNotAsync, await, await)
                         listener: endInvalidAwaitExpression(await, -, AwaitNotAsync)
                     listener: beginBinaryExpression(-)
-                    parsePrecedenceExpression(-, 14, true)
+                    parsePrecedenceExpression(-, 15, true)
                       parseUnaryExpression(-, true)
                         inPlainSync()
                         looksLikeAwaitExpression(-, AwaitOrYieldContext.UnaryExpression)
                           looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                         parseAwaitExpression(-, true)
                           listener: beginAwaitExpression(await)
-                          parsePrecedenceExpression(await, 16, true)
+                          parsePrecedenceExpression(await, 17, true)
                             parseUnaryExpression(await, true)
                               parsePrimary(await, expression)
                                 parseSendOrFunctionLiteral(await, expression)
@@ -1639,7 +1639,7 @@
                                             looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                           parseAwaitExpression((, true)
                                             listener: beginAwaitExpression(await)
-                                            parsePrecedenceExpression(await, 16, true)
+                                            parsePrecedenceExpression(await, 17, true)
                                               parseUnaryExpression(await, true)
                                                 parsePrimary(await, expression)
                                                   parseSendOrFunctionLiteral(await, expression)
@@ -1656,14 +1656,14 @@
                                               listener: handleRecoverableError(AwaitNotAsync, await, await)
                                             listener: endInvalidAwaitExpression(await, -, AwaitNotAsync)
                                         listener: beginBinaryExpression(-)
-                                        parsePrecedenceExpression(-, 14, true)
+                                        parsePrecedenceExpression(-, 15, true)
                                           parseUnaryExpression(-, true)
                                             inPlainSync()
                                             looksLikeAwaitExpression(-, AwaitOrYieldContext.UnaryExpression)
                                               looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                             parseAwaitExpression(-, true)
                                               listener: beginAwaitExpression(await)
-                                              parsePrecedenceExpression(await, 16, true)
+                                              parsePrecedenceExpression(await, 17, true)
                                                 parseUnaryExpression(await, true)
                                                   parsePrimary(await, expression)
                                                     parseSendOrFunctionLiteral(await, expression)
@@ -1694,14 +1694,14 @@
                     parseExpression(;)
                       parsePrecedenceExpression(;, 1, true)
                         parseUnaryExpression(;, true)
-                          parsePrecedenceExpression(!, 16, true)
+                          parsePrecedenceExpression(!, 17, true)
                             parseUnaryExpression(!, true)
                               inPlainSync()
                               looksLikeAwaitExpression(!, AwaitOrYieldContext.UnaryExpression)
                                 looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                               parseAwaitExpression(!, true)
                                 listener: beginAwaitExpression(await)
-                                parsePrecedenceExpression(await, 16, true)
+                                parsePrecedenceExpression(await, 17, true)
                                   parseUnaryExpression(await, true)
                                     parsePrimary(await, expression)
                                       parseSendOrFunctionLiteral(await, expression)
@@ -1721,14 +1721,14 @@
                         listener: beginBinaryExpression(^)
                         parsePrecedenceExpression(^, 11, true)
                           parseUnaryExpression(^, true)
-                            parsePrecedenceExpression(!, 16, true)
+                            parsePrecedenceExpression(!, 17, true)
                               parseUnaryExpression(!, true)
                                 inPlainSync()
                                 looksLikeAwaitExpression(!, AwaitOrYieldContext.UnaryExpression)
                                   looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                 parseAwaitExpression(!, true)
                                   listener: beginAwaitExpression(await)
-                                  parsePrecedenceExpression(await, 16, true)
+                                  parsePrecedenceExpression(await, 17, true)
                                     parseUnaryExpression(await, true)
                                       parsePrimary(await, expression)
                                         parseSendOrFunctionLiteral(await, expression)
@@ -1772,14 +1772,14 @@
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
                                         parseUnaryExpression((, true)
-                                          parsePrecedenceExpression(!, 16, true)
+                                          parsePrecedenceExpression(!, 17, true)
                                             parseUnaryExpression(!, true)
                                               inPlainSync()
                                               looksLikeAwaitExpression(!, AwaitOrYieldContext.UnaryExpression)
                                                 looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                               parseAwaitExpression(!, true)
                                                 listener: beginAwaitExpression(await)
-                                                parsePrecedenceExpression(await, 16, true)
+                                                parsePrecedenceExpression(await, 17, true)
                                                   parseUnaryExpression(await, true)
                                                     parsePrimary(await, expression)
                                                       parseSendOrFunctionLiteral(await, expression)
@@ -1799,14 +1799,14 @@
                                         listener: beginBinaryExpression(^)
                                         parsePrecedenceExpression(^, 11, true)
                                           parseUnaryExpression(^, true)
-                                            parsePrecedenceExpression(!, 16, true)
+                                            parsePrecedenceExpression(!, 17, true)
                                               parseUnaryExpression(!, true)
                                                 inPlainSync()
                                                 looksLikeAwaitExpression(!, AwaitOrYieldContext.UnaryExpression)
                                                   looksLikeExpressionAfterAwaitOrYield(await, AwaitOrYieldContext.UnaryExpression)
                                                 parseAwaitExpression(!, true)
                                                   listener: beginAwaitExpression(await)
-                                                  parsePrecedenceExpression(await, 16, true)
+                                                  parsePrecedenceExpression(await, 17, true)
                                                     parseUnaryExpression(await, true)
                                                       parsePrimary(await, expression)
                                                         parseSendOrFunctionLiteral(await, expression)
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect
index dd2ec7f..3fe9eb2 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect
@@ -56,9 +56,9 @@
   int const(int x) {
       ^^^^^
 
-parser/error_recovery/keyword_named_class_methods:49:17: Expected an identifier, but got '('.
+parser/error_recovery/keyword_named_class_methods:49:21: Record literal with one field requires a trailing comma.
     return const(x-1) + 1;
-                ^
+                    ^
 
 parser/error_recovery/keyword_named_class_methods:52:7: 'continue' can't be used as an identifier because it's a keyword.
   int continue(int x) {
@@ -272,7 +272,7 @@
     return is(x-1) + 1;
                ^
 
-parser/error_recovery/keyword_named_class_methods:184:18: Record type fields list cannot contain only one element without a named field.
+parser/error_recovery/keyword_named_class_methods:184:18: Record type with one entry requires a trailing comma.
     return is(x-1) + 1;
                  ^
 
@@ -532,7 +532,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -590,7 +590,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -649,7 +649,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -705,7 +705,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -763,7 +763,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -822,7 +822,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -888,7 +888,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -948,7 +948,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1008,7 +1008,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1068,7 +1068,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1076,14 +1076,8 @@
                 endThenStatement(;)
               endIfStatement(if, null)
               beginReturnStatement(return)
-                beginConstExpression(const)
-                  handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., Try inserting an identifier before '('., {lexeme: (}], (, ()
-                  handleIdentifier(, constructorReference)
-                  beginConstructorReference()
-                    handleNoTypeArguments(()
-                    handleNoConstructorReferenceContinuationAfterTypeArguments(()
-                  endConstructorReference(, null, (, ConstructorReferenceContext.Const)
-                  beginArguments(()
+                beginConstLiteral(()
+                  beginParenthesizedExpressionOrRecordLiteral(()
                     handleIdentifier(x, expression)
                     handleNoTypeArguments(-)
                     handleNoArguments(-)
@@ -1091,8 +1085,9 @@
                     beginBinaryExpression(-)
                       handleLiteralInt(1)
                     endBinaryExpression(-)
-                  endArguments(1, (, ))
-                endConstExpression(const)
+                    handleRecoverableError(RecordLiteralOnePositionalFieldNoTrailingComma, ), ))
+                  endRecordLiteral((, 1, const)
+                endConstLiteral(+)
                 beginBinaryExpression(+)
                   handleLiteralInt(1)
                 endBinaryExpression(+)
@@ -1132,7 +1127,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1197,7 +1192,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1256,7 +1251,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1315,7 +1310,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1374,7 +1369,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1412,7 +1407,7 @@
                 handleNoTypeArguments())
                 handleNoArguments())
                 handleSend(, ))
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ;, ;)
               endDoWhileStatement(do, while, ;)
             endBlockFunctionBody(3, {, })
@@ -1449,7 +1444,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1508,7 +1503,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1579,7 +1574,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1638,7 +1633,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1697,7 +1692,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1756,7 +1751,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1814,7 +1809,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1872,7 +1867,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1931,7 +1926,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1990,7 +1985,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2077,7 +2072,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2137,7 +2132,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2216,7 +2211,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2274,7 +2269,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2332,7 +2327,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2391,7 +2386,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2414,7 +2409,7 @@
                 beginBinaryExpression(-)
                   handleLiteralInt(1)
                 endBinaryExpression(-)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(+)
                   handleRecoverableError(UnsupportedPrefixPlus, +, +)
                   handleIdentifier(, expression)
@@ -2461,7 +2456,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2519,7 +2514,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2578,7 +2573,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2637,7 +2632,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2695,7 +2690,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2754,7 +2749,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2778,7 +2773,7 @@
                       handleNoName(-)
                     endRecordTypeEntry()
                     handleRecoverableError(Message[ExpectedButGot, Expected ')' before this., null, {string: )}], -, -)
-                    handleRecoverableError(OnlyOneRecordTypeFieldsList, ), ))
+                    handleRecoverableError(RecordTypeOnePositionalFieldNoTrailingComma, ), ))
                   endRecordType((, null, 1, false)
                 endIsOperatorType(is)
                 handleIsOperator(is, null)
@@ -2827,7 +2822,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2885,7 +2880,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -2943,7 +2938,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3001,7 +2996,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3060,7 +3055,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3124,7 +3119,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3182,7 +3177,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3240,7 +3235,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3298,7 +3293,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3356,7 +3351,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3414,7 +3409,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3472,7 +3467,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3530,7 +3525,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3589,7 +3584,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3649,7 +3644,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3705,7 +3700,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3763,7 +3758,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3821,7 +3816,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3879,7 +3874,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -3949,7 +3944,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4008,7 +4003,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4031,7 +4026,7 @@
                 beginBinaryExpression(-)
                   handleLiteralInt(1)
                 endBinaryExpression(-)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 handleRecoverableError(Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}], ), ))
                 beginSwitchBlock({)
                 endSwitchBlock(0, {, })
@@ -4079,7 +4074,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4149,7 +4144,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4208,7 +4203,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4265,7 +4260,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4324,7 +4319,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4392,7 +4387,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4451,7 +4446,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4538,7 +4533,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4625,7 +4620,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4648,7 +4643,7 @@
                 beginBinaryExpression(-)
                   handleLiteralInt(1)
                 endBinaryExpression(-)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginWhileStatementBody(+)
                   handleRecoverableError(UnsupportedPrefixPlus, +, +)
                   handleIdentifier(, expression)
@@ -4696,7 +4691,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -4755,7 +4750,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect
index 0b04c27..cd997d0 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect
@@ -71,8 +71,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -94,7 +94,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -147,7 +147,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -156,7 +156,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(abstract, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -215,8 +215,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -238,7 +238,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -291,7 +291,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -300,7 +300,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(as, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -363,8 +363,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -386,7 +386,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -429,7 +429,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -439,7 +439,7 @@
                                     listener: handleRecoverableError(AssertAsExpression, assert, assert)
                                   listener: endAssert(assert, Assert.Expression, (, null, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -498,8 +498,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -521,7 +521,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -574,7 +574,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -583,7 +583,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(async, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -642,8 +642,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -665,7 +665,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -721,7 +721,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -730,7 +730,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(await, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -793,8 +793,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -816,7 +816,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -884,7 +884,7 @@
                                 parseUnaryExpression(;, true)
                                   parsePrimary(;, expression)
                                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                                      parseParenthesizedExpressionOrRecordLiteral(;)
+                                      parseParenthesizedExpressionOrRecordLiteral(;, null)
                                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                                         parseExpression(()
                                           parsePrecedenceExpression((, 1, true)
@@ -900,7 +900,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -909,7 +909,7 @@
                                         ensureCloseParen(1, ()
                                         listener: endParenthesizedExpression(()
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -971,8 +971,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -994,7 +994,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1046,7 +1046,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -1055,7 +1055,7 @@
                                         listener: endArguments(1, (, ))
                                   listener: handleSend(case, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -1118,8 +1118,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1141,7 +1141,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1193,7 +1193,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -1202,7 +1202,7 @@
                                         listener: endArguments(1, (, ))
                                   listener: handleSend(catch, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -1265,8 +1265,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1288,7 +1288,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1340,7 +1340,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -1349,7 +1349,7 @@
                                         listener: endArguments(1, (, ))
                                   listener: handleSend(class, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -1412,8 +1412,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1435,7 +1435,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1462,46 +1462,36 @@
                             parseUnaryExpression(return, true)
                               parsePrimary(return, expression)
                                 parseConstExpression(return)
-                                  listener: beginConstExpression(const)
-                                  parseConstructorReference(const, ConstructorReferenceContext.Const, null)
-                                    ensureIdentifier(const, constructorReference)
-                                      insertSyntheticIdentifier(const, constructorReference, message: Message[ExpectedIdentifier, Expected an identifier, but got '('., Try inserting an identifier before '('., {lexeme: (}], messageOnToken: null)
-                                        reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., Try inserting an identifier before '('., {lexeme: (}])
-                                          listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., Try inserting an identifier before '('., {lexeme: (}], (, ()
-                                        rewriter()
-                                      listener: handleIdentifier(, constructorReference)
-                                    listener: beginConstructorReference()
-                                    parseQualifiedRestOpt(, constructorReferenceContinuation)
-                                    listener: handleNoTypeArguments(()
-                                    listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
-                                    listener: endConstructorReference(, null, (, ConstructorReferenceContext.Const)
-                                  parseConstructorInvocationArguments()
-                                    parseArgumentsRest(()
-                                      listener: beginArguments(()
-                                      parseExpression(()
-                                        parsePrecedenceExpression((, 1, true)
-                                          parseUnaryExpression((, true)
-                                            parsePrimary((, expression)
-                                              parseSendOrFunctionLiteral((, expression)
-                                                parseSend((, expression)
-                                                  isNextIdentifier(()
-                                                  ensureIdentifier((, expression)
-                                                    listener: handleIdentifier(x, expression)
-                                                  listener: handleNoTypeArguments(-)
-                                                  parseArgumentsOpt(x)
-                                                    listener: handleNoArguments(-)
-                                                  listener: handleSend(x, -)
-                                          listener: beginBinaryExpression(-)
-                                          parsePrecedenceExpression(-, 14, true)
-                                            parseUnaryExpression(-, true)
-                                              parsePrimary(-, expression)
-                                                parseLiteralInt(-)
-                                                  listener: handleLiteralInt(1)
-                                          listener: endBinaryExpression(-)
-                                      listener: endArguments(1, (, ))
-                                  listener: endConstExpression(const)
+                                  listener: beginConstLiteral(()
+                                  parseParenthesizedExpressionOrRecordLiteral(const, const)
+                                    listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                isNextIdentifier(()
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(x, expression)
+                                                listener: handleNoTypeArguments(-)
+                                                parseArgumentsOpt(x)
+                                                  listener: handleNoArguments(-)
+                                                listener: handleSend(x, -)
+                                        listener: beginBinaryExpression(-)
+                                        parsePrecedenceExpression(-, 15, true)
+                                          parseUnaryExpression(-, true)
+                                            parsePrimary(-, expression)
+                                              parseLiteralInt(-)
+                                                listener: handleLiteralInt(1)
+                                        listener: endBinaryExpression(-)
+                                    ensureCloseParen(1, ()
+                                    reportRecoverableError(), RecordLiteralOnePositionalFieldNoTrailingComma)
+                                      listener: handleRecoverableError(RecordLiteralOnePositionalFieldNoTrailingComma, ), ))
+                                    listener: endRecordLiteral((, 1, const)
+                                  listener: endConstLiteral(+)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -1564,8 +1554,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1587,7 +1577,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1655,7 +1645,7 @@
                                 parseUnaryExpression(;, true)
                                   parsePrimary(;, expression)
                                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                                      parseParenthesizedExpressionOrRecordLiteral(;)
+                                      parseParenthesizedExpressionOrRecordLiteral(;, null)
                                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                                         parseExpression(()
                                           parsePrecedenceExpression((, 1, true)
@@ -1671,7 +1661,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -1680,7 +1670,7 @@
                                         ensureCloseParen(1, ()
                                         listener: endParenthesizedExpression(()
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -1738,8 +1728,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1761,7 +1751,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1814,7 +1804,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -1823,7 +1813,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(covariant, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -1886,8 +1876,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1909,7 +1899,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1961,7 +1951,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -1970,7 +1960,7 @@
                                         listener: endArguments(1, (, ))
                                   listener: handleSend(default, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -2029,8 +2019,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2052,7 +2042,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2105,7 +2095,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -2114,7 +2104,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(deferred, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -2177,8 +2167,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2200,7 +2190,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2261,7 +2251,7 @@
                                       parseUnaryExpression(do, true)
                                         parsePrimary(do, expression)
                                           parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(do)
-                                            parseParenthesizedExpressionOrRecordLiteral(do)
+                                            parseParenthesizedExpressionOrRecordLiteral(do, null)
                                               listener: beginParenthesizedExpressionOrRecordLiteral(()
                                               parseExpression(()
                                                 parsePrecedenceExpression((, 1, true)
@@ -2277,7 +2267,7 @@
                                                             listener: handleNoArguments(-)
                                                           listener: handleSend(x, -)
                                                   listener: beginBinaryExpression(-)
-                                                  parsePrecedenceExpression(-, 14, true)
+                                                  parsePrecedenceExpression(-, 15, true)
                                                     parseUnaryExpression(-, true)
                                                       parsePrimary(-, expression)
                                                         parseLiteralInt(-)
@@ -2286,7 +2276,7 @@
                                               ensureCloseParen(1, ()
                                               listener: endParenthesizedExpression(()
                                       listener: beginBinaryExpression(+)
-                                      parsePrecedenceExpression(+, 14, true)
+                                      parsePrecedenceExpression(+, 15, true)
                                         parseUnaryExpression(+, true)
                                           parsePrimary(+, expression)
                                             parseLiteralInt(+)
@@ -2298,11 +2288,11 @@
                         reportRecoverableError(}, Message[ExpectedButGot, Expected 'while' before this., null, {string: while}])
                           listener: handleRecoverableError(Message[ExpectedButGot, Expected 'while' before this., null, {string: while}], }, })
                         rewriter()
-                        ensureParenthesizedCondition(while)
+                        ensureParenthesizedCondition(while, allowCase: false)
                           reportRecoverableError(}, Message[ExpectedToken, Expected to find '('., null, {string: (}])
                             listener: handleRecoverableError(Message[ExpectedToken, Expected to find '('., null, {string: (}], }, })
                           rewriter()
-                          parseExpressionInParenthesisRest(()
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2319,7 +2309,7 @@
                                         listener: handleNoArguments())
                                       listener: handleSend(, ))
                             ensureCloseParen(, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         ensureSemicolon())
                           reportRecoverableError(;, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
                             listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ;, ;)
@@ -2375,8 +2365,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2398,7 +2388,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2451,7 +2441,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -2460,7 +2450,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(dynamic, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -2523,8 +2513,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2546,7 +2536,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2632,7 +2622,7 @@
                                 parseUnaryExpression(else, true)
                                   parsePrimary(else, expression)
                                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(else)
-                                      parseParenthesizedExpressionOrRecordLiteral(else)
+                                      parseParenthesizedExpressionOrRecordLiteral(else, null)
                                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                                         parseExpression(()
                                           parsePrecedenceExpression((, 1, true)
@@ -2648,7 +2638,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -2657,7 +2647,7 @@
                                         ensureCloseParen(1, ()
                                         listener: endParenthesizedExpression(()
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -2719,8 +2709,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2742,7 +2732,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2794,7 +2784,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -2803,7 +2793,7 @@
                                         listener: endArguments(1, (, ))
                                   listener: handleSend(enum, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -2862,8 +2852,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2885,7 +2875,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2938,7 +2928,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -2947,7 +2937,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(export, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -3010,8 +3000,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -3033,7 +3023,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -3085,7 +3075,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -3094,7 +3084,7 @@
                                         listener: endArguments(1, (, ))
                                   listener: handleSend(extends, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -3153,8 +3143,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -3176,7 +3166,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -3229,7 +3219,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -3238,7 +3228,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(extension, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -3297,8 +3287,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -3320,7 +3310,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -3373,7 +3363,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -3382,7 +3372,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(external, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -3441,8 +3431,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -3464,7 +3454,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -3517,7 +3507,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -3526,7 +3516,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(factory, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -3589,8 +3579,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -3612,7 +3602,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -3659,7 +3649,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -3668,7 +3658,7 @@
                                   listener: endArguments(1, (, ))
                               listener: handleSend((, ))
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -3731,8 +3721,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -3754,7 +3744,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -3843,7 +3833,7 @@
                                         listener: handleNoArguments(-)
                                       listener: handleSend(x, -)
                               listener: beginBinaryExpression(-)
-                              parsePrecedenceExpression(-, 14, true)
+                              parsePrecedenceExpression(-, 15, true)
                                 parseUnaryExpression(-, true)
                                   parsePrimary(-, expression)
                                     parseLiteralInt(-)
@@ -3908,7 +3898,7 @@
                                           listener: handleNoArguments(+)
                                         listener: handleSend(, +)
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -3970,8 +3960,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -3993,7 +3983,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -4045,7 +4035,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -4054,7 +4044,7 @@
                                         listener: endArguments(1, (, ))
                                   listener: handleSend(finally, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -4117,8 +4107,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -4140,7 +4130,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -4207,7 +4197,7 @@
                                         listener: handleNoArguments(-)
                                       listener: handleSend(x, -)
                               listener: beginBinaryExpression(-)
-                              parsePrecedenceExpression(-, 14, true)
+                              parsePrecedenceExpression(-, 15, true)
                                 parseUnaryExpression(-, true)
                                   parsePrimary(-, expression)
                                     parseLiteralInt(-)
@@ -4267,7 +4257,7 @@
                                                   listener: handleNoArguments(+)
                                                 listener: handleSend(, +)
                                         listener: beginBinaryExpression(+)
-                                        parsePrecedenceExpression(+, 14, true)
+                                        parsePrecedenceExpression(+, 15, true)
                                           parseUnaryExpression(+, true)
                                             parsePrimary(+, expression)
                                               parseLiteralInt(+)
@@ -4327,8 +4317,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -4350,7 +4340,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -4403,7 +4393,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -4412,7 +4402,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(Function, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -4472,8 +4462,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -4495,7 +4485,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -4548,7 +4538,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -4557,7 +4547,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(get, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -4616,8 +4606,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -4639,7 +4629,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -4692,7 +4682,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -4701,7 +4691,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(hide, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -4764,8 +4754,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -4787,7 +4777,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -4836,8 +4826,8 @@
                     parseStatementX(;)
                       parseIfStatement(;)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -4852,14 +4842,14 @@
                                           listener: handleNoArguments(-)
                                         listener: handleSend(x, -)
                                 listener: beginBinaryExpression(-)
-                                parsePrecedenceExpression(-, 14, true)
+                                parsePrecedenceExpression(-, 15, true)
                                   parseUnaryExpression(-, true)
                                     parsePrimary(-, expression)
                                       parseLiteralInt(-)
                                         listener: handleLiteralInt(1)
                                 listener: endBinaryExpression(-)
                             ensureCloseParen(1, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(+)
                         parseStatement())
                           parseStatementX())
@@ -4885,7 +4875,7 @@
                                                 listener: handleNoArguments(+)
                                               listener: handleSend(, +)
                                       listener: beginBinaryExpression(+)
-                                      parsePrecedenceExpression(+, 14, true)
+                                      parsePrecedenceExpression(+, 15, true)
                                         parseUnaryExpression(+, true)
                                           parsePrimary(+, expression)
                                             parseLiteralInt(+)
@@ -4945,8 +4935,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -4968,7 +4958,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -5021,7 +5011,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -5030,7 +5020,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(implements, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -5089,8 +5079,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -5112,7 +5102,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -5165,7 +5155,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -5174,7 +5164,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(import, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -5237,8 +5227,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -5260,7 +5250,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -5312,7 +5302,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -5321,7 +5311,7 @@
                                         listener: endArguments(1, (, ))
                                   listener: handleSend(in, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -5380,8 +5370,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -5403,7 +5393,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -5456,7 +5446,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -5465,7 +5455,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(inout, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -5524,8 +5514,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -5547,7 +5537,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -5600,7 +5590,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -5609,7 +5599,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(interface, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -5672,8 +5662,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -5695,7 +5685,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -5751,8 +5741,8 @@
                                 ensureCloseParen(x, ()
                                   reportRecoverableError(-, Message[ExpectedButGot, Expected ')' before this., null, {string: )}])
                                     listener: handleRecoverableError(Message[ExpectedButGot, Expected ')' before this., null, {string: )}], -, -)
-                                reportRecoverableError(), OnlyOneRecordTypeFieldsList)
-                                  listener: handleRecoverableError(OnlyOneRecordTypeFieldsList, ), ))
+                                reportRecoverableError(), RecordTypeOnePositionalFieldNoTrailingComma)
+                                  listener: handleRecoverableError(RecordTypeOnePositionalFieldNoTrailingComma, ), ))
                                 listener: endRecordType((, null, 1, false)
                               listener: endIsOperatorType(is)
                               listener: handleIsOperator(is, null)
@@ -5788,7 +5778,7 @@
                                           listener: handleNoArguments(+)
                                         listener: handleSend(, +)
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -5846,8 +5836,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -5869,7 +5859,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -5922,7 +5912,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -5931,7 +5921,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(late, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -5990,8 +5980,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -6013,7 +6003,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -6066,7 +6056,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -6075,7 +6065,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(library, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -6134,8 +6124,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -6157,7 +6147,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -6210,7 +6200,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -6219,7 +6209,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(mixin, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -6278,8 +6268,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -6301,7 +6291,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -6354,7 +6344,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -6363,7 +6353,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(native, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -6426,8 +6416,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -6449,7 +6439,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -6507,7 +6497,7 @@
                                                     listener: handleNoArguments(-)
                                                   listener: handleSend(x, -)
                                           listener: beginBinaryExpression(-)
-                                          parsePrecedenceExpression(-, 14, true)
+                                          parsePrecedenceExpression(-, 15, true)
                                             parseUnaryExpression(-, true)
                                               parsePrimary(-, expression)
                                                 parseLiteralInt(-)
@@ -6516,7 +6506,7 @@
                                       listener: endArguments(1, (, ))
                                   listener: endNewExpression(new)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -6579,8 +6569,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -6602,7 +6592,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -6649,7 +6639,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -6658,7 +6648,7 @@
                                   listener: endArguments(1, (, ))
                               listener: handleSend((, ))
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -6717,8 +6707,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -6740,7 +6730,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -6793,7 +6783,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -6802,7 +6792,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(of, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -6861,8 +6851,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -6884,7 +6874,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -6937,7 +6927,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -6946,7 +6936,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(on, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -7007,8 +6997,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -7030,7 +7020,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -7083,7 +7073,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -7092,7 +7082,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(operator, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -7151,8 +7141,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -7174,7 +7164,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -7227,7 +7217,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -7236,7 +7226,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(out, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -7295,8 +7285,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -7318,7 +7308,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -7371,7 +7361,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -7380,7 +7370,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(part, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -7439,8 +7429,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -7462,7 +7452,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -7515,7 +7505,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -7524,7 +7514,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(patch, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -7583,8 +7573,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -7606,7 +7596,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -7659,7 +7649,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -7668,7 +7658,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(required, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -7731,8 +7721,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -7754,7 +7744,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -7806,7 +7796,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -7815,7 +7805,7 @@
                                         listener: endArguments(1, (, ))
                                   listener: handleSend(rethrow, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -7878,8 +7868,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -7901,7 +7891,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -7932,7 +7922,7 @@
                                   listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'return'., null, {lexeme: return}], return, return)
                                 parsePrimary(return, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                                    parseParenthesizedExpressionOrRecordLiteral(return)
+                                    parseParenthesizedExpressionOrRecordLiteral(return, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -7948,7 +7938,7 @@
                                                     listener: handleNoArguments(-)
                                                   listener: handleSend(x, -)
                                           listener: beginBinaryExpression(-)
-                                          parsePrecedenceExpression(-, 14, true)
+                                          parsePrecedenceExpression(-, 15, true)
                                             parseUnaryExpression(-, true)
                                               parsePrimary(-, expression)
                                                 parseLiteralInt(-)
@@ -7957,7 +7947,7 @@
                                       ensureCloseParen(1, ()
                                       listener: endParenthesizedExpression(()
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -8017,8 +8007,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -8040,7 +8030,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -8093,7 +8083,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -8102,7 +8092,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(set, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -8161,8 +8151,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -8184,7 +8174,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -8237,7 +8227,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -8246,7 +8236,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(show, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -8305,8 +8295,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -8328,7 +8318,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -8381,7 +8371,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -8390,7 +8380,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(source, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -8449,8 +8439,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -8472,7 +8462,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -8525,7 +8515,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -8534,7 +8524,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(static, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -8620,8 +8610,8 @@
                       parseStatementX({)
                         parseIfStatement({)
                           listener: beginIfStatement(if)
-                          ensureParenthesizedCondition(if)
-                            parseExpressionInParenthesisRest(()
+                          ensureParenthesizedCondition(if, allowCase: false)
+                            parseExpressionInParenthesisRest((, allowCase: false)
                               parseExpression(()
                                 parsePrecedenceExpression((, 1, true)
                                   parseUnaryExpression((, true)
@@ -8643,7 +8633,7 @@
                                           listener: handleLiteralInt(0)
                                   listener: endBinaryExpression(==)
                               ensureCloseParen(0, ()
-                            listener: handleParenthesizedCondition(()
+                              listener: handleParenthesizedCondition((, null)
                           listener: beginThenStatement(return)
                           parseStatement())
                             parseStatementX())
@@ -8689,7 +8679,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -8698,7 +8688,7 @@
                                         listener: endArguments(1, (, ))
                                     listener: handleSend(super, +)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -8761,8 +8751,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -8784,7 +8774,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -8833,8 +8823,8 @@
                     parseStatementX(;)
                       parseSwitchStatement(;)
                         listener: beginSwitchStatement(switch)
-                        ensureParenthesizedCondition(switch)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(switch, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -8849,14 +8839,14 @@
                                           listener: handleNoArguments(-)
                                         listener: handleSend(x, -)
                                 listener: beginBinaryExpression(-)
-                                parsePrecedenceExpression(-, 14, true)
+                                parsePrecedenceExpression(-, 15, true)
                                   parseUnaryExpression(-, true)
                                     parsePrimary(-, expression)
                                       parseLiteralInt(-)
                                         listener: handleLiteralInt(1)
                                 listener: endBinaryExpression(-)
                             ensureCloseParen(1, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         parseSwitchBlock())
                           ensureBlock(), null, switch statement)
                             reportRecoverableError(), Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}])
@@ -8893,7 +8883,7 @@
                                           listener: handleNoArguments(+)
                                         listener: handleSend(, +)
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -8951,8 +8941,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -8974,7 +8964,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -9027,7 +9017,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -9036,7 +9026,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(sync, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -9122,8 +9112,8 @@
                       parseStatementX({)
                         parseIfStatement({)
                           listener: beginIfStatement(if)
-                          ensureParenthesizedCondition(if)
-                            parseExpressionInParenthesisRest(()
+                          ensureParenthesizedCondition(if, allowCase: false)
+                            parseExpressionInParenthesisRest((, allowCase: false)
                               parseExpression(()
                                 parsePrecedenceExpression((, 1, true)
                                   parseUnaryExpression((, true)
@@ -9145,7 +9135,7 @@
                                           listener: handleLiteralInt(0)
                                   listener: endBinaryExpression(==)
                               ensureCloseParen(0, ()
-                            listener: handleParenthesizedCondition(()
+                              listener: handleParenthesizedCondition((, null)
                           listener: beginThenStatement(return)
                           parseStatement())
                             parseStatementX())
@@ -9191,7 +9181,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -9200,7 +9190,7 @@
                                         listener: endArguments(1, (, ))
                                     listener: handleSend(this, +)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -9263,8 +9253,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -9286,7 +9276,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -9315,7 +9305,7 @@
                                 parseUnaryExpression(throw, true)
                                   parsePrimary(throw, expression)
                                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(throw)
-                                      parseParenthesizedExpressionOrRecordLiteral(throw)
+                                      parseParenthesizedExpressionOrRecordLiteral(throw, null)
                                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                                         parseExpression(()
                                           parsePrecedenceExpression((, 1, true)
@@ -9331,7 +9321,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -9340,7 +9330,7 @@
                                         ensureCloseParen(1, ()
                                         listener: endParenthesizedExpression(()
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -9404,8 +9394,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -9427,7 +9417,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -9474,7 +9464,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -9483,7 +9473,7 @@
                                   listener: endArguments(1, (, ))
                               listener: handleSend((, ))
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -9546,8 +9536,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -9569,7 +9559,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -9643,7 +9633,7 @@
                                 parseUnaryExpression(}, true)
                                   parsePrimary(}, expression)
                                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(})
-                                      parseParenthesizedExpressionOrRecordLiteral(})
+                                      parseParenthesizedExpressionOrRecordLiteral(}, null)
                                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                                         parseExpression(()
                                           parsePrecedenceExpression((, 1, true)
@@ -9659,7 +9649,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -9668,7 +9658,7 @@
                                         ensureCloseParen(1, ()
                                         listener: endParenthesizedExpression(()
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -9726,8 +9716,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -9749,7 +9739,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -9802,7 +9792,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -9811,7 +9801,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(typedef, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -9874,8 +9864,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -9897,7 +9887,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -9986,7 +9976,7 @@
                                         listener: handleNoArguments(-)
                                       listener: handleSend(x, -)
                               listener: beginBinaryExpression(-)
-                              parsePrecedenceExpression(-, 14, true)
+                              parsePrecedenceExpression(-, 15, true)
                                 parseUnaryExpression(-, true)
                                   parsePrimary(-, expression)
                                     parseLiteralInt(-)
@@ -10051,7 +10041,7 @@
                                           listener: handleNoArguments(+)
                                         listener: handleSend(, +)
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -10113,8 +10103,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -10136,7 +10126,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -10226,7 +10216,7 @@
                                         listener: handleNoArguments(-)
                                       listener: handleSend(x, -)
                               listener: beginBinaryExpression(-)
-                              parsePrecedenceExpression(-, 14, true)
+                              parsePrecedenceExpression(-, 15, true)
                                 parseUnaryExpression(-, true)
                                   parsePrimary(-, expression)
                                     parseLiteralInt(-)
@@ -10291,7 +10281,7 @@
                                           listener: handleNoArguments(+)
                                         listener: handleSend(, +)
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -10353,8 +10343,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -10376,7 +10366,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -10425,8 +10415,8 @@
                     parseStatementX(;)
                       parseWhileStatement(;)
                         listener: beginWhileStatement(while)
-                        ensureParenthesizedCondition(while)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(while, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -10441,14 +10431,14 @@
                                           listener: handleNoArguments(-)
                                         listener: handleSend(x, -)
                                 listener: beginBinaryExpression(-)
-                                parsePrecedenceExpression(-, 14, true)
+                                parsePrecedenceExpression(-, 15, true)
                                   parseUnaryExpression(-, true)
                                     parsePrimary(-, expression)
                                       parseLiteralInt(-)
                                         listener: handleLiteralInt(1)
                                 listener: endBinaryExpression(-)
                             ensureCloseParen(1, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginWhileStatementBody(+)
                         parseStatement())
                           parseStatementX())
@@ -10474,7 +10464,7 @@
                                                 listener: handleNoArguments(+)
                                               listener: handleSend(, +)
                                       listener: beginBinaryExpression(+)
-                                      parsePrecedenceExpression(+, 14, true)
+                                      parsePrecedenceExpression(+, 15, true)
                                         parseUnaryExpression(+, true)
                                           parsePrimary(+, expression)
                                             parseLiteralInt(+)
@@ -10538,8 +10528,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -10561,7 +10551,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -10613,7 +10603,7 @@
                                                       listener: handleNoArguments(-)
                                                     listener: handleSend(x, -)
                                             listener: beginBinaryExpression(-)
-                                            parsePrecedenceExpression(-, 14, true)
+                                            parsePrecedenceExpression(-, 15, true)
                                               parseUnaryExpression(-, true)
                                                 parsePrimary(-, expression)
                                                   parseLiteralInt(-)
@@ -10622,7 +10612,7 @@
                                         listener: endArguments(1, (, ))
                                   listener: handleSend(with, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -10681,8 +10671,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -10704,7 +10694,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -10757,7 +10747,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -10766,7 +10756,7 @@
                                           listener: endArguments(1, (, ))
                                     listener: handleSend(yield, +)
                             listener: beginBinaryExpression(+)
-                            parsePrecedenceExpression(+, 14, true)
+                            parsePrecedenceExpression(+, 15, true)
                               parseUnaryExpression(+, true)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.parser.expect
index 6496db3..6295405 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.parser.expect
@@ -48,7 +48,7 @@
 
 int const(int x) {
 if (x == 0) return 42;
-return const*synthetic*(x-1) + 1;
+return const(x-1) + 1;
 }
 
 int continue(int x) {
@@ -396,7 +396,7 @@
 
 int[StringToken] const[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
 if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
-return[KeywordToken] const[KeywordToken][SyntheticStringToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+return[KeywordToken] const[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
 }[SimpleToken]
 
 int[StringToken] continue[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.expect
index 3de814f..cbeddb4 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.expect
@@ -56,9 +56,9 @@
 int const(int x) {
     ^^^^^
 
-parser/error_recovery/keyword_named_top_level_methods:48:15: Expected an identifier, but got '('.
+parser/error_recovery/keyword_named_top_level_methods:48:19: Record literal with one field requires a trailing comma.
   return const(x-1) + 1;
-              ^
+                  ^
 
 parser/error_recovery/keyword_named_top_level_methods:51:5: 'continue' can't be used as an identifier because it's a keyword.
 int continue(int x) {
@@ -272,7 +272,7 @@
   return is(x-1) + 1;
              ^
 
-parser/error_recovery/keyword_named_top_level_methods:183:16: Record type fields list cannot contain only one element without a named field.
+parser/error_recovery/keyword_named_top_level_methods:183:16: Record type with one entry requires a trailing comma.
   return is(x-1) + 1;
                ^
 
@@ -503,7 +503,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -560,7 +560,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -618,7 +618,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -673,7 +673,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -730,7 +730,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -788,7 +788,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -853,7 +853,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -912,7 +912,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -971,7 +971,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1030,7 +1030,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1038,14 +1038,8 @@
           endThenStatement(;)
         endIfStatement(if, null)
         beginReturnStatement(return)
-          beginConstExpression(const)
-            handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., Try inserting an identifier before '('., {lexeme: (}], (, ()
-            handleIdentifier(, constructorReference)
-            beginConstructorReference()
-              handleNoTypeArguments(()
-              handleNoConstructorReferenceContinuationAfterTypeArguments(()
-            endConstructorReference(, null, (, ConstructorReferenceContext.Const)
-            beginArguments(()
+          beginConstLiteral(()
+            beginParenthesizedExpressionOrRecordLiteral(()
               handleIdentifier(x, expression)
               handleNoTypeArguments(-)
               handleNoArguments(-)
@@ -1053,8 +1047,9 @@
               beginBinaryExpression(-)
                 handleLiteralInt(1)
               endBinaryExpression(-)
-            endArguments(1, (, ))
-          endConstExpression(const)
+              handleRecoverableError(RecordLiteralOnePositionalFieldNoTrailingComma, ), ))
+            endRecordLiteral((, 1, const)
+          endConstLiteral(+)
           beginBinaryExpression(+)
             handleLiteralInt(1)
           endBinaryExpression(+)
@@ -1093,7 +1088,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1157,7 +1152,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1215,7 +1210,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1273,7 +1268,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1331,7 +1326,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1369,7 +1364,7 @@
           handleNoTypeArguments())
           handleNoArguments())
           handleSend(, ))
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ;, ;)
         endDoWhileStatement(do, while, ;)
       endBlockFunctionBody(3, {, })
@@ -1405,7 +1400,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1463,7 +1458,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1533,7 +1528,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1591,7 +1586,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1649,7 +1644,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1707,7 +1702,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1764,7 +1759,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1821,7 +1816,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1879,7 +1874,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1937,7 +1932,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2023,7 +2018,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2082,7 +2077,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2160,7 +2155,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2217,7 +2212,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2274,7 +2269,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2332,7 +2327,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2355,7 +2350,7 @@
           beginBinaryExpression(-)
             handleLiteralInt(1)
           endBinaryExpression(-)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(+)
             handleRecoverableError(UnsupportedPrefixPlus, +, +)
             handleIdentifier(, expression)
@@ -2401,7 +2396,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2458,7 +2453,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2516,7 +2511,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2574,7 +2569,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2631,7 +2626,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2689,7 +2684,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2713,7 +2708,7 @@
                 handleNoName(-)
               endRecordTypeEntry()
               handleRecoverableError(Message[ExpectedButGot, Expected ')' before this., null, {string: )}], -, -)
-              handleRecoverableError(OnlyOneRecordTypeFieldsList, ), ))
+              handleRecoverableError(RecordTypeOnePositionalFieldNoTrailingComma, ), ))
             endRecordType((, null, 1, false)
           endIsOperatorType(is)
           handleIsOperator(is, null)
@@ -2761,7 +2756,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2818,7 +2813,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2875,7 +2870,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2932,7 +2927,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -2990,7 +2985,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3053,7 +3048,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3110,7 +3105,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3167,7 +3162,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3224,7 +3219,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3281,7 +3276,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3338,7 +3333,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3395,7 +3390,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3452,7 +3447,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3510,7 +3505,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3569,7 +3564,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3624,7 +3619,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3681,7 +3676,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3738,7 +3733,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3795,7 +3790,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3853,7 +3848,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3911,7 +3906,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -3934,7 +3929,7 @@
           beginBinaryExpression(-)
             handleLiteralInt(1)
           endBinaryExpression(-)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           handleRecoverableError(Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}], ), ))
           beginSwitchBlock({)
           endSwitchBlock(0, {, })
@@ -3981,7 +3976,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -4039,7 +4034,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -4097,7 +4092,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -4153,7 +4148,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -4211,7 +4206,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -4278,7 +4273,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -4336,7 +4331,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -4422,7 +4417,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -4508,7 +4503,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -4531,7 +4526,7 @@
           beginBinaryExpression(-)
             handleLiteralInt(1)
           endBinaryExpression(-)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginWhileStatementBody(+)
             handleRecoverableError(UnsupportedPrefixPlus, +, +)
             handleIdentifier(, expression)
@@ -4578,7 +4573,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -4636,7 +4631,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.intertwined.expect
index adcb281..6855668 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.intertwined.expect
@@ -44,8 +44,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -67,7 +67,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -120,7 +120,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -129,7 +129,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(abstract, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -184,8 +184,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -207,7 +207,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -260,7 +260,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -269,7 +269,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(as, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -328,8 +328,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -351,7 +351,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -394,7 +394,7 @@
                                         listener: handleNoArguments(-)
                                       listener: handleSend(x, -)
                               listener: beginBinaryExpression(-)
-                              parsePrecedenceExpression(-, 14, true)
+                              parsePrecedenceExpression(-, 15, true)
                                 parseUnaryExpression(-, true)
                                   parsePrimary(-, expression)
                                     parseLiteralInt(-)
@@ -404,7 +404,7 @@
                             listener: handleRecoverableError(AssertAsExpression, assert, assert)
                           listener: endAssert(assert, Assert.Expression, (, null, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -459,8 +459,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -482,7 +482,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -535,7 +535,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -544,7 +544,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(async, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -599,8 +599,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -622,7 +622,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -678,7 +678,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -687,7 +687,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(await, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -746,8 +746,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -769,7 +769,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -837,7 +837,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -853,7 +853,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -862,7 +862,7 @@
                                 ensureCloseParen(1, ()
                                 listener: endParenthesizedExpression(()
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseLiteralInt(+)
@@ -920,8 +920,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -943,7 +943,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -995,7 +995,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -1004,7 +1004,7 @@
                                 listener: endArguments(1, (, ))
                           listener: handleSend(case, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -1063,8 +1063,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1086,7 +1086,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1138,7 +1138,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -1147,7 +1147,7 @@
                                 listener: endArguments(1, (, ))
                           listener: handleSend(catch, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -1206,8 +1206,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1229,7 +1229,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1281,7 +1281,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -1290,7 +1290,7 @@
                                 listener: endArguments(1, (, ))
                           listener: handleSend(class, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -1349,8 +1349,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1372,7 +1372,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1399,46 +1399,36 @@
                     parseUnaryExpression(return, true)
                       parsePrimary(return, expression)
                         parseConstExpression(return)
-                          listener: beginConstExpression(const)
-                          parseConstructorReference(const, ConstructorReferenceContext.Const, null)
-                            ensureIdentifier(const, constructorReference)
-                              insertSyntheticIdentifier(const, constructorReference, message: Message[ExpectedIdentifier, Expected an identifier, but got '('., Try inserting an identifier before '('., {lexeme: (}], messageOnToken: null)
-                                reportRecoverableError((, Message[ExpectedIdentifier, Expected an identifier, but got '('., Try inserting an identifier before '('., {lexeme: (}])
-                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., Try inserting an identifier before '('., {lexeme: (}], (, ()
-                                rewriter()
-                              listener: handleIdentifier(, constructorReference)
-                            listener: beginConstructorReference()
-                            parseQualifiedRestOpt(, constructorReferenceContinuation)
-                            listener: handleNoTypeArguments(()
-                            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
-                            listener: endConstructorReference(, null, (, ConstructorReferenceContext.Const)
-                          parseConstructorInvocationArguments()
-                            parseArgumentsRest(()
-                              listener: beginArguments(()
-                              parseExpression(()
-                                parsePrecedenceExpression((, 1, true)
-                                  parseUnaryExpression((, true)
-                                    parsePrimary((, expression)
-                                      parseSendOrFunctionLiteral((, expression)
-                                        parseSend((, expression)
-                                          isNextIdentifier(()
-                                          ensureIdentifier((, expression)
-                                            listener: handleIdentifier(x, expression)
-                                          listener: handleNoTypeArguments(-)
-                                          parseArgumentsOpt(x)
-                                            listener: handleNoArguments(-)
-                                          listener: handleSend(x, -)
-                                  listener: beginBinaryExpression(-)
-                                  parsePrecedenceExpression(-, 14, true)
-                                    parseUnaryExpression(-, true)
-                                      parsePrimary(-, expression)
-                                        parseLiteralInt(-)
-                                          listener: handleLiteralInt(1)
-                                  listener: endBinaryExpression(-)
-                              listener: endArguments(1, (, ))
-                          listener: endConstExpression(const)
+                          listener: beginConstLiteral(()
+                          parseParenthesizedExpressionOrRecordLiteral(const, const)
+                            listener: beginParenthesizedExpressionOrRecordLiteral(()
+                            parseExpression(()
+                              parsePrecedenceExpression((, 1, true)
+                                parseUnaryExpression((, true)
+                                  parsePrimary((, expression)
+                                    parseSendOrFunctionLiteral((, expression)
+                                      parseSend((, expression)
+                                        isNextIdentifier(()
+                                        ensureIdentifier((, expression)
+                                          listener: handleIdentifier(x, expression)
+                                        listener: handleNoTypeArguments(-)
+                                        parseArgumentsOpt(x)
+                                          listener: handleNoArguments(-)
+                                        listener: handleSend(x, -)
+                                listener: beginBinaryExpression(-)
+                                parsePrecedenceExpression(-, 15, true)
+                                  parseUnaryExpression(-, true)
+                                    parsePrimary(-, expression)
+                                      parseLiteralInt(-)
+                                        listener: handleLiteralInt(1)
+                                listener: endBinaryExpression(-)
+                            ensureCloseParen(1, ()
+                            reportRecoverableError(), RecordLiteralOnePositionalFieldNoTrailingComma)
+                              listener: handleRecoverableError(RecordLiteralOnePositionalFieldNoTrailingComma, ), ))
+                            listener: endRecordLiteral((, 1, const)
+                          listener: endConstLiteral(+)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -1497,8 +1487,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1520,7 +1510,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1588,7 +1578,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -1604,7 +1594,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -1613,7 +1603,7 @@
                                 ensureCloseParen(1, ()
                                 listener: endParenthesizedExpression(()
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseLiteralInt(+)
@@ -1667,8 +1657,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1690,7 +1680,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1743,7 +1733,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -1752,7 +1742,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(covariant, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -1811,8 +1801,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1834,7 +1824,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1886,7 +1876,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -1895,7 +1885,7 @@
                                 listener: endArguments(1, (, ))
                           listener: handleSend(default, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -1950,8 +1940,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1973,7 +1963,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2026,7 +2016,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -2035,7 +2025,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(deferred, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -2094,8 +2084,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2117,7 +2107,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2178,7 +2168,7 @@
                               parseUnaryExpression(do, true)
                                 parsePrimary(do, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(do)
-                                    parseParenthesizedExpressionOrRecordLiteral(do)
+                                    parseParenthesizedExpressionOrRecordLiteral(do, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -2194,7 +2184,7 @@
                                                     listener: handleNoArguments(-)
                                                   listener: handleSend(x, -)
                                           listener: beginBinaryExpression(-)
-                                          parsePrecedenceExpression(-, 14, true)
+                                          parsePrecedenceExpression(-, 15, true)
                                             parseUnaryExpression(-, true)
                                               parsePrimary(-, expression)
                                                 parseLiteralInt(-)
@@ -2203,7 +2193,7 @@
                                       ensureCloseParen(1, ()
                                       listener: endParenthesizedExpression(()
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -2215,11 +2205,11 @@
                 reportRecoverableError(}, Message[ExpectedButGot, Expected 'while' before this., null, {string: while}])
                   listener: handleRecoverableError(Message[ExpectedButGot, Expected 'while' before this., null, {string: while}], }, })
                 rewriter()
-                ensureParenthesizedCondition(while)
+                ensureParenthesizedCondition(while, allowCase: false)
                   reportRecoverableError(}, Message[ExpectedToken, Expected to find '('., null, {string: (}])
                     listener: handleRecoverableError(Message[ExpectedToken, Expected to find '('., null, {string: (}], }, })
                   rewriter()
-                  parseExpressionInParenthesisRest(()
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2236,7 +2226,7 @@
                                 listener: handleNoArguments())
                               listener: handleSend(, ))
                     ensureCloseParen(, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 ensureSemicolon())
                   reportRecoverableError(;, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
                     listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ;, ;)
@@ -2288,8 +2278,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2311,7 +2301,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2364,7 +2354,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -2373,7 +2363,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(dynamic, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -2432,8 +2422,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2455,7 +2445,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2541,7 +2531,7 @@
                         parseUnaryExpression(else, true)
                           parsePrimary(else, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(else)
-                              parseParenthesizedExpressionOrRecordLiteral(else)
+                              parseParenthesizedExpressionOrRecordLiteral(else, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -2557,7 +2547,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -2566,7 +2556,7 @@
                                 ensureCloseParen(1, ()
                                 listener: endParenthesizedExpression(()
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseLiteralInt(+)
@@ -2624,8 +2614,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2647,7 +2637,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2699,7 +2689,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -2708,7 +2698,7 @@
                                 listener: endArguments(1, (, ))
                           listener: handleSend(enum, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -2763,8 +2753,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2786,7 +2776,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2839,7 +2829,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -2848,7 +2838,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(export, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -2907,8 +2897,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2930,7 +2920,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2982,7 +2972,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -2991,7 +2981,7 @@
                                 listener: endArguments(1, (, ))
                           listener: handleSend(extends, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -3046,8 +3036,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -3069,7 +3059,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -3122,7 +3112,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -3131,7 +3121,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(extension, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -3186,8 +3176,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -3209,7 +3199,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -3262,7 +3252,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -3271,7 +3261,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(external, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -3326,8 +3316,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -3349,7 +3339,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -3402,7 +3392,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -3411,7 +3401,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(factory, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -3470,8 +3460,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -3493,7 +3483,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -3540,7 +3530,7 @@
                                         listener: handleNoArguments(-)
                                       listener: handleSend(x, -)
                               listener: beginBinaryExpression(-)
-                              parsePrecedenceExpression(-, 14, true)
+                              parsePrecedenceExpression(-, 15, true)
                                 parseUnaryExpression(-, true)
                                   parsePrimary(-, expression)
                                     parseLiteralInt(-)
@@ -3549,7 +3539,7 @@
                           listener: endArguments(1, (, ))
                       listener: handleSend((, ))
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -3608,8 +3598,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -3631,7 +3621,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -3720,7 +3710,7 @@
                                 listener: handleNoArguments(-)
                               listener: handleSend(x, -)
                       listener: beginBinaryExpression(-)
-                      parsePrecedenceExpression(-, 14, true)
+                      parsePrecedenceExpression(-, 15, true)
                         parseUnaryExpression(-, true)
                           parsePrimary(-, expression)
                             parseLiteralInt(-)
@@ -3785,7 +3775,7 @@
                                   listener: handleNoArguments(+)
                                 listener: handleSend(, +)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseLiteralInt(+)
@@ -3843,8 +3833,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -3866,7 +3856,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -3918,7 +3908,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -3927,7 +3917,7 @@
                                 listener: endArguments(1, (, ))
                           listener: handleSend(finally, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -3986,8 +3976,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -4009,7 +3999,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -4076,7 +4066,7 @@
                                 listener: handleNoArguments(-)
                               listener: handleSend(x, -)
                       listener: beginBinaryExpression(-)
-                      parsePrecedenceExpression(-, 14, true)
+                      parsePrecedenceExpression(-, 15, true)
                         parseUnaryExpression(-, true)
                           parsePrimary(-, expression)
                             parseLiteralInt(-)
@@ -4136,7 +4126,7 @@
                                           listener: handleNoArguments(+)
                                         listener: handleSend(, +)
                                 listener: beginBinaryExpression(+)
-                                parsePrecedenceExpression(+, 14, true)
+                                parsePrecedenceExpression(+, 15, true)
                                   parseUnaryExpression(+, true)
                                     parsePrimary(+, expression)
                                       parseLiteralInt(+)
@@ -4192,8 +4182,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -4215,7 +4205,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -4268,7 +4258,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -4277,7 +4267,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(Function, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -4332,8 +4322,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -4355,7 +4345,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -4408,7 +4398,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -4417,7 +4407,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(get, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -4472,8 +4462,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -4495,7 +4485,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -4548,7 +4538,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -4557,7 +4547,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(hide, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -4616,8 +4606,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -4639,7 +4629,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -4688,8 +4678,8 @@
             parseStatementX(;)
               parseIfStatement(;)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -4704,14 +4694,14 @@
                                   listener: handleNoArguments(-)
                                 listener: handleSend(x, -)
                         listener: beginBinaryExpression(-)
-                        parsePrecedenceExpression(-, 14, true)
+                        parsePrecedenceExpression(-, 15, true)
                           parseUnaryExpression(-, true)
                             parsePrimary(-, expression)
                               parseLiteralInt(-)
                                 listener: handleLiteralInt(1)
                         listener: endBinaryExpression(-)
                     ensureCloseParen(1, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(+)
                 parseStatement())
                   parseStatementX())
@@ -4737,7 +4727,7 @@
                                         listener: handleNoArguments(+)
                                       listener: handleSend(, +)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -4793,8 +4783,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -4816,7 +4806,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -4869,7 +4859,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -4878,7 +4868,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(implements, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -4933,8 +4923,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -4956,7 +4946,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -5009,7 +4999,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -5018,7 +5008,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(import, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -5077,8 +5067,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -5100,7 +5090,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -5152,7 +5142,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -5161,7 +5151,7 @@
                                 listener: endArguments(1, (, ))
                           listener: handleSend(in, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -5216,8 +5206,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -5239,7 +5229,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -5292,7 +5282,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -5301,7 +5291,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(inout, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -5356,8 +5346,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -5379,7 +5369,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -5432,7 +5422,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -5441,7 +5431,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(interface, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -5500,8 +5490,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -5523,7 +5513,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -5579,8 +5569,8 @@
                         ensureCloseParen(x, ()
                           reportRecoverableError(-, Message[ExpectedButGot, Expected ')' before this., null, {string: )}])
                             listener: handleRecoverableError(Message[ExpectedButGot, Expected ')' before this., null, {string: )}], -, -)
-                        reportRecoverableError(), OnlyOneRecordTypeFieldsList)
-                          listener: handleRecoverableError(OnlyOneRecordTypeFieldsList, ), ))
+                        reportRecoverableError(), RecordTypeOnePositionalFieldNoTrailingComma)
+                          listener: handleRecoverableError(RecordTypeOnePositionalFieldNoTrailingComma, ), ))
                         listener: endRecordType((, null, 1, false)
                       listener: endIsOperatorType(is)
                       listener: handleIsOperator(is, null)
@@ -5616,7 +5606,7 @@
                                   listener: handleNoArguments(+)
                                 listener: handleSend(, +)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseLiteralInt(+)
@@ -5670,8 +5660,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -5693,7 +5683,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -5746,7 +5736,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -5755,7 +5745,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(late, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -5810,8 +5800,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -5833,7 +5823,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -5886,7 +5876,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -5895,7 +5885,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(library, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -5950,8 +5940,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -5973,7 +5963,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -6026,7 +6016,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -6035,7 +6025,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(mixin, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -6090,8 +6080,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -6113,7 +6103,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -6166,7 +6156,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -6175,7 +6165,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(native, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -6234,8 +6224,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -6257,7 +6247,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -6315,7 +6305,7 @@
                                             listener: handleNoArguments(-)
                                           listener: handleSend(x, -)
                                   listener: beginBinaryExpression(-)
-                                  parsePrecedenceExpression(-, 14, true)
+                                  parsePrecedenceExpression(-, 15, true)
                                     parseUnaryExpression(-, true)
                                       parsePrimary(-, expression)
                                         parseLiteralInt(-)
@@ -6324,7 +6314,7 @@
                               listener: endArguments(1, (, ))
                           listener: endNewExpression(new)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -6383,8 +6373,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -6406,7 +6396,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -6453,7 +6443,7 @@
                                         listener: handleNoArguments(-)
                                       listener: handleSend(x, -)
                               listener: beginBinaryExpression(-)
-                              parsePrecedenceExpression(-, 14, true)
+                              parsePrecedenceExpression(-, 15, true)
                                 parseUnaryExpression(-, true)
                                   parsePrimary(-, expression)
                                     parseLiteralInt(-)
@@ -6462,7 +6452,7 @@
                           listener: endArguments(1, (, ))
                       listener: handleSend((, ))
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -6517,8 +6507,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -6540,7 +6530,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -6593,7 +6583,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -6602,7 +6592,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(of, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -6657,8 +6647,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -6680,7 +6670,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -6733,7 +6723,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -6742,7 +6732,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(on, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -6797,8 +6787,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -6820,7 +6810,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -6873,7 +6863,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -6882,7 +6872,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(operator, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -6937,8 +6927,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -6960,7 +6950,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -7013,7 +7003,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -7022,7 +7012,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(out, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -7077,8 +7067,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -7100,7 +7090,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -7153,7 +7143,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -7162,7 +7152,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(part, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -7217,8 +7207,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -7240,7 +7230,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -7293,7 +7283,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -7302,7 +7292,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(patch, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -7357,8 +7347,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -7380,7 +7370,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -7433,7 +7423,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -7442,7 +7432,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(required, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -7501,8 +7491,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -7524,7 +7514,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -7576,7 +7566,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -7585,7 +7575,7 @@
                                 listener: endArguments(1, (, ))
                           listener: handleSend(rethrow, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -7644,8 +7634,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -7667,7 +7657,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -7698,7 +7688,7 @@
                           listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'return'., null, {lexeme: return}], return, return)
                         parsePrimary(return, expression)
                           parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                            parseParenthesizedExpressionOrRecordLiteral(return)
+                            parseParenthesizedExpressionOrRecordLiteral(return, null)
                               listener: beginParenthesizedExpressionOrRecordLiteral(()
                               parseExpression(()
                                 parsePrecedenceExpression((, 1, true)
@@ -7714,7 +7704,7 @@
                                             listener: handleNoArguments(-)
                                           listener: handleSend(x, -)
                                   listener: beginBinaryExpression(-)
-                                  parsePrecedenceExpression(-, 14, true)
+                                  parsePrecedenceExpression(-, 15, true)
                                     parseUnaryExpression(-, true)
                                       parsePrimary(-, expression)
                                         parseLiteralInt(-)
@@ -7723,7 +7713,7 @@
                               ensureCloseParen(1, ()
                               listener: endParenthesizedExpression(()
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -7778,8 +7768,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -7801,7 +7791,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -7854,7 +7844,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -7863,7 +7853,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(set, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -7918,8 +7908,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -7941,7 +7931,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -7994,7 +7984,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -8003,7 +7993,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(show, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -8058,8 +8048,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -8081,7 +8071,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -8134,7 +8124,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -8143,7 +8133,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(source, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -8198,8 +8188,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -8221,7 +8211,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -8274,7 +8264,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -8283,7 +8273,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(static, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -8340,8 +8330,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -8363,7 +8353,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -8409,7 +8399,7 @@
                                             listener: handleNoArguments(-)
                                           listener: handleSend(x, -)
                                   listener: beginBinaryExpression(-)
-                                  parsePrecedenceExpression(-, 14, true)
+                                  parsePrecedenceExpression(-, 15, true)
                                     parseUnaryExpression(-, true)
                                       parsePrimary(-, expression)
                                         parseLiteralInt(-)
@@ -8418,7 +8408,7 @@
                               listener: endArguments(1, (, ))
                           listener: handleSend(super, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -8477,8 +8467,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -8500,7 +8490,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -8549,8 +8539,8 @@
             parseStatementX(;)
               parseSwitchStatement(;)
                 listener: beginSwitchStatement(switch)
-                ensureParenthesizedCondition(switch)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(switch, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -8565,14 +8555,14 @@
                                   listener: handleNoArguments(-)
                                 listener: handleSend(x, -)
                         listener: beginBinaryExpression(-)
-                        parsePrecedenceExpression(-, 14, true)
+                        parsePrecedenceExpression(-, 15, true)
                           parseUnaryExpression(-, true)
                             parsePrimary(-, expression)
                               parseLiteralInt(-)
                                 listener: handleLiteralInt(1)
                         listener: endBinaryExpression(-)
                     ensureCloseParen(1, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 parseSwitchBlock())
                   ensureBlock(), null, switch statement)
                     reportRecoverableError(), Message[ExpectedClassOrMixinBody, A switch statement must have a body, even if it is empty., Try adding an empty body., {string: switch statement}])
@@ -8609,7 +8599,7 @@
                                   listener: handleNoArguments(+)
                                 listener: handleSend(, +)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseLiteralInt(+)
@@ -8663,8 +8653,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -8686,7 +8676,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -8739,7 +8729,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -8748,7 +8738,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(sync, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -8805,8 +8795,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -8828,7 +8818,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -8874,7 +8864,7 @@
                                             listener: handleNoArguments(-)
                                           listener: handleSend(x, -)
                                   listener: beginBinaryExpression(-)
-                                  parsePrecedenceExpression(-, 14, true)
+                                  parsePrecedenceExpression(-, 15, true)
                                     parseUnaryExpression(-, true)
                                       parsePrimary(-, expression)
                                         parseLiteralInt(-)
@@ -8883,7 +8873,7 @@
                               listener: endArguments(1, (, ))
                           listener: handleSend(this, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -8942,8 +8932,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -8965,7 +8955,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -8994,7 +8984,7 @@
                         parseUnaryExpression(throw, true)
                           parsePrimary(throw, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(throw)
-                              parseParenthesizedExpressionOrRecordLiteral(throw)
+                              parseParenthesizedExpressionOrRecordLiteral(throw, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -9010,7 +9000,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -9019,7 +9009,7 @@
                                 ensureCloseParen(1, ()
                                 listener: endParenthesizedExpression(()
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseLiteralInt(+)
@@ -9079,8 +9069,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -9102,7 +9092,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -9149,7 +9139,7 @@
                                         listener: handleNoArguments(-)
                                       listener: handleSend(x, -)
                               listener: beginBinaryExpression(-)
-                              parsePrecedenceExpression(-, 14, true)
+                              parsePrecedenceExpression(-, 15, true)
                                 parseUnaryExpression(-, true)
                                   parsePrimary(-, expression)
                                     parseLiteralInt(-)
@@ -9158,7 +9148,7 @@
                           listener: endArguments(1, (, ))
                       listener: handleSend((, ))
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -9217,8 +9207,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -9240,7 +9230,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -9314,7 +9304,7 @@
                         parseUnaryExpression(}, true)
                           parsePrimary(}, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(})
-                              parseParenthesizedExpressionOrRecordLiteral(})
+                              parseParenthesizedExpressionOrRecordLiteral(}, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -9330,7 +9320,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -9339,7 +9329,7 @@
                                 ensureCloseParen(1, ()
                                 listener: endParenthesizedExpression(()
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseLiteralInt(+)
@@ -9393,8 +9383,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -9416,7 +9406,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -9469,7 +9459,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -9478,7 +9468,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(typedef, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -9537,8 +9527,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -9560,7 +9550,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -9649,7 +9639,7 @@
                                 listener: handleNoArguments(-)
                               listener: handleSend(x, -)
                       listener: beginBinaryExpression(-)
-                      parsePrecedenceExpression(-, 14, true)
+                      parsePrecedenceExpression(-, 15, true)
                         parseUnaryExpression(-, true)
                           parsePrimary(-, expression)
                             parseLiteralInt(-)
@@ -9714,7 +9704,7 @@
                                   listener: handleNoArguments(+)
                                 listener: handleSend(, +)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseLiteralInt(+)
@@ -9772,8 +9762,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -9795,7 +9785,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -9885,7 +9875,7 @@
                                 listener: handleNoArguments(-)
                               listener: handleSend(x, -)
                       listener: beginBinaryExpression(-)
-                      parsePrecedenceExpression(-, 14, true)
+                      parsePrecedenceExpression(-, 15, true)
                         parseUnaryExpression(-, true)
                           parsePrimary(-, expression)
                             parseLiteralInt(-)
@@ -9950,7 +9940,7 @@
                                   listener: handleNoArguments(+)
                                 listener: handleSend(, +)
                         listener: beginBinaryExpression(+)
-                        parsePrecedenceExpression(+, 14, true)
+                        parsePrecedenceExpression(+, 15, true)
                           parseUnaryExpression(+, true)
                             parsePrimary(+, expression)
                               parseLiteralInt(+)
@@ -10008,8 +9998,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -10031,7 +10021,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -10080,8 +10070,8 @@
             parseStatementX(;)
               parseWhileStatement(;)
                 listener: beginWhileStatement(while)
-                ensureParenthesizedCondition(while)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(while, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -10096,14 +10086,14 @@
                                   listener: handleNoArguments(-)
                                 listener: handleSend(x, -)
                         listener: beginBinaryExpression(-)
-                        parsePrecedenceExpression(-, 14, true)
+                        parsePrecedenceExpression(-, 15, true)
                           parseUnaryExpression(-, true)
                             parsePrimary(-, expression)
                               parseLiteralInt(-)
                                 listener: handleLiteralInt(1)
                         listener: endBinaryExpression(-)
                     ensureCloseParen(1, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginWhileStatementBody(+)
                 parseStatement())
                   parseStatementX())
@@ -10129,7 +10119,7 @@
                                         listener: handleNoArguments(+)
                                       listener: handleSend(, +)
                               listener: beginBinaryExpression(+)
-                              parsePrecedenceExpression(+, 14, true)
+                              parsePrecedenceExpression(+, 15, true)
                                 parseUnaryExpression(+, true)
                                   parsePrimary(+, expression)
                                     parseLiteralInt(+)
@@ -10189,8 +10179,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -10212,7 +10202,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -10264,7 +10254,7 @@
                                               listener: handleNoArguments(-)
                                             listener: handleSend(x, -)
                                     listener: beginBinaryExpression(-)
-                                    parsePrecedenceExpression(-, 14, true)
+                                    parsePrecedenceExpression(-, 15, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseLiteralInt(-)
@@ -10273,7 +10263,7 @@
                                 listener: endArguments(1, (, ))
                           listener: handleSend(with, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
@@ -10328,8 +10318,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -10351,7 +10341,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -10404,7 +10394,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -10413,7 +10403,7 @@
                                   listener: endArguments(1, (, ))
                             listener: handleSend(yield, +)
                     listener: beginBinaryExpression(+)
-                    parsePrecedenceExpression(+, 14, true)
+                    parsePrecedenceExpression(+, 15, true)
                       parseUnaryExpression(+, true)
                         parsePrimary(+, expression)
                           parseLiteralInt(+)
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.parser.expect
index 6237372..ddadbee 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.parser.expect
@@ -47,7 +47,7 @@
 
 int const(int x) {
 if (x == 0) return 42;
-return const*synthetic*(x-1) + 1;
+return const(x-1) + 1;
 }
 
 int continue(int x) {
@@ -393,7 +393,7 @@
 
 int[StringToken] const[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
 if[KeywordToken] ([BeginToken]x[StringToken] ==[SimpleToken] 0[StringToken])[SimpleToken] return[KeywordToken] 42[StringToken];[SimpleToken]
-return[KeywordToken] const[KeywordToken][SyntheticStringToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
+return[KeywordToken] const[KeywordToken]([BeginToken]x[StringToken]-[SimpleToken]1[StringToken])[SimpleToken] +[SimpleToken] 1[StringToken];[SimpleToken]
 }[SimpleToken]
 
 int[StringToken] continue[KeywordToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
diff --git a/pkg/front_end/parser_testcases/general/ambiguous_builder_01.dart.expect b/pkg/front_end/parser_testcases/general/ambiguous_builder_01.dart.expect
index 97f7555..499b90d 100644
--- a/pkg/front_end/parser_testcases/general/ambiguous_builder_01.dart.expect
+++ b/pkg/front_end/parser_testcases/general/ambiguous_builder_01.dart.expect
@@ -118,7 +118,7 @@
           beginBinaryExpression(!=)
             handleLiteralNull(null)
           endBinaryExpression(!=)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
             endBlock(0, {, }, BlockKind(statement))
diff --git a/pkg/front_end/parser_testcases/general/ambiguous_builder_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/ambiguous_builder_01.dart.intertwined.expect
index 7bf2cf8..934f38f 100644
--- a/pkg/front_end/parser_testcases/general/ambiguous_builder_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/ambiguous_builder_01.dart.intertwined.expect
@@ -170,8 +170,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -193,7 +193,7 @@
                                 listener: handleLiteralNull(null)
                         listener: endBinaryExpression(!=)
                     ensureCloseParen(null, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/general/augment_super.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/augment_super.dart.intertwined.expect
index 5e67d92..84a1789 100644
--- a/pkg/front_end/parser_testcases/general/augment_super.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/augment_super.dart.intertwined.expect
@@ -86,7 +86,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -599,7 +599,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -847,7 +847,7 @@
                                 parseUnaryExpression(;, true)
                                   parsePrimary(;, expression)
                                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                                      parseParenthesizedExpressionOrRecordLiteral(;)
+                                      parseParenthesizedExpressionOrRecordLiteral(;, null)
                                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                                         parseExpression(()
                                           parsePrecedenceExpression((, 1, true)
@@ -1073,7 +1073,7 @@
                             parseExpression(;)
                               parsePrecedenceExpression(;, 1, true)
                                 parseUnaryExpression(;, true)
-                                  parsePrecedenceExpression(++, 16, true)
+                                  parsePrecedenceExpression(++, 17, true)
                                     parseUnaryExpression(++, true)
                                       parsePrimary(++, expression)
                                         parseSend(++, expression)
@@ -1100,7 +1100,7 @@
                             parseExpression(;)
                               parsePrecedenceExpression(;, 1, true)
                                 parseUnaryExpression(;, true)
-                                  parsePrecedenceExpression(--, 16, true)
+                                  parsePrecedenceExpression(--, 17, true)
                                     parseUnaryExpression(--, true)
                                       parsePrimary(--, expression)
                                         parseSendOrFunctionLiteral(--, expression)
@@ -1141,7 +1141,7 @@
                         parseExpression(return)
                           parsePrecedenceExpression(return, 1, true)
                             parseUnaryExpression(return, true)
-                              parsePrecedenceExpression(-, 16, true)
+                              parsePrecedenceExpression(-, 17, true)
                                 parseUnaryExpression(-, true)
                                   parsePrimary(-, expression)
                                     parseSendOrFunctionLiteral(-, expression)
@@ -1347,7 +1347,7 @@
                                 parseUnaryExpression(;, true)
                                   parsePrimary(;, expression)
                                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                                      parseParenthesizedExpressionOrRecordLiteral(;)
+                                      parseParenthesizedExpressionOrRecordLiteral(;, null)
                                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                                         parseExpression(()
                                           parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect
index 54576a8..478e17d 100644
--- a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.expect
@@ -42,7 +42,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -97,7 +97,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -152,7 +152,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -207,7 +207,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -262,7 +262,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -317,7 +317,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -372,7 +372,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -427,7 +427,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -482,7 +482,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -537,7 +537,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -592,7 +592,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -647,7 +647,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -702,7 +702,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -757,7 +757,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -812,7 +812,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -867,7 +867,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -922,7 +922,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -977,7 +977,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1032,7 +1032,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
@@ -1087,7 +1087,7 @@
                 beginBinaryExpression(==)
                   handleLiteralInt(0)
                 endBinaryExpression(==)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement(return)
                   beginReturnStatement(return)
                     handleLiteralInt(42)
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect
index d53e616..c548ef1 100644
--- a/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_class_methods.dart.intertwined.expect
@@ -71,8 +71,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -94,7 +94,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -147,7 +147,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -208,8 +208,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -231,7 +231,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -284,7 +284,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -345,8 +345,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -368,7 +368,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -421,7 +421,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -482,8 +482,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -505,7 +505,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -558,7 +558,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -619,8 +619,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -642,7 +642,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -695,7 +695,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -756,8 +756,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -779,7 +779,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -832,7 +832,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -893,8 +893,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -916,7 +916,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -969,7 +969,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -1030,8 +1030,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1053,7 +1053,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1106,7 +1106,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -1167,8 +1167,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1190,7 +1190,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1243,7 +1243,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -1305,8 +1305,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1328,7 +1328,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1381,7 +1381,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -1442,8 +1442,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1465,7 +1465,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1518,7 +1518,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -1579,8 +1579,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1602,7 +1602,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1655,7 +1655,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -1716,8 +1716,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1739,7 +1739,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1792,7 +1792,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -1853,8 +1853,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -1876,7 +1876,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -1929,7 +1929,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -1992,8 +1992,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2015,7 +2015,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2068,7 +2068,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -2129,8 +2129,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2152,7 +2152,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2205,7 +2205,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -2266,8 +2266,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2289,7 +2289,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2342,7 +2342,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -2404,8 +2404,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2427,7 +2427,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2480,7 +2480,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -2541,8 +2541,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2564,7 +2564,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2617,7 +2617,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
@@ -2678,8 +2678,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -2701,7 +2701,7 @@
                                         listener: handleLiteralInt(0)
                                 listener: endBinaryExpression(==)
                             ensureCloseParen(0, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement(return)
                         parseStatement())
                           parseStatementX())
@@ -2754,7 +2754,7 @@
                                                         listener: handleNoArguments(-)
                                                       listener: handleSend(x, -)
                                               listener: beginBinaryExpression(-)
-                                              parsePrecedenceExpression(-, 14, true)
+                                              parsePrecedenceExpression(-, 15, true)
                                                 parseUnaryExpression(-, true)
                                                   parsePrimary(-, expression)
                                                     parseLiteralInt(-)
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.expect
index 09cc1ba..f10dcfb 100644
--- a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.expect
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.expect
@@ -29,7 +29,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -83,7 +83,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -137,7 +137,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -191,7 +191,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -245,7 +245,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -299,7 +299,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -353,7 +353,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -407,7 +407,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -461,7 +461,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -515,7 +515,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -569,7 +569,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -623,7 +623,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -677,7 +677,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -731,7 +731,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -785,7 +785,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -839,7 +839,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -893,7 +893,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -947,7 +947,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1001,7 +1001,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
@@ -1055,7 +1055,7 @@
           beginBinaryExpression(==)
             handleLiteralInt(0)
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               handleLiteralInt(42)
diff --git a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.intertwined.expect
index 9bc5625..c11eaeb 100644
--- a/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/built_in_identifier_top_level_methods.dart.intertwined.expect
@@ -44,8 +44,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -67,7 +67,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -120,7 +120,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -177,8 +177,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -200,7 +200,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -253,7 +253,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -310,8 +310,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -333,7 +333,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -386,7 +386,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -443,8 +443,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -466,7 +466,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -519,7 +519,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -576,8 +576,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -599,7 +599,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -652,7 +652,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -709,8 +709,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -732,7 +732,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -785,7 +785,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -842,8 +842,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -865,7 +865,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -918,7 +918,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -975,8 +975,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -998,7 +998,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1051,7 +1051,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -1108,8 +1108,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1131,7 +1131,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1184,7 +1184,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -1241,8 +1241,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1264,7 +1264,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1317,7 +1317,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -1374,8 +1374,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1397,7 +1397,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1450,7 +1450,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -1507,8 +1507,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1530,7 +1530,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1583,7 +1583,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -1640,8 +1640,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1663,7 +1663,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1716,7 +1716,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -1773,8 +1773,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1796,7 +1796,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1849,7 +1849,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -1906,8 +1906,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -1929,7 +1929,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -1982,7 +1982,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -2039,8 +2039,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2062,7 +2062,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2115,7 +2115,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -2172,8 +2172,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2195,7 +2195,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2248,7 +2248,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -2305,8 +2305,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2328,7 +2328,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2381,7 +2381,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -2438,8 +2438,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2461,7 +2461,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2514,7 +2514,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
@@ -2571,8 +2571,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -2594,7 +2594,7 @@
                                 listener: handleLiteralInt(0)
                         listener: endBinaryExpression(==)
                     ensureCloseParen(0, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -2647,7 +2647,7 @@
                                                 listener: handleNoArguments(-)
                                               listener: handleSend(x, -)
                                       listener: beginBinaryExpression(-)
-                                      parsePrecedenceExpression(-, 14, true)
+                                      parsePrecedenceExpression(-, 15, true)
                                         parseUnaryExpression(-, true)
                                           parsePrimary(-, expression)
                                             parseLiteralInt(-)
diff --git a/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart b/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart
index e92c5b9..3f71391 100644
--- a/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart
+++ b/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart
@@ -7,7 +7,11 @@
     ;
   }
 
-  on();
+  // With records "on()"  is no longer a call after a try block, but a on clause
+  // where the type is the empty record.
+  // See https://github.com/dart-lang/language/blob/master/accepted/future-releases/records/records-feature-specification.md#ambiguity-with-on-clauses
+  // This is a call though as (x) isn't a valid record type.
+  on(42);
 }
 
-void on() {}
+void on(e) {}
diff --git a/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.expect b/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.expect
index 0ed8d05..15e32f5 100644
--- a/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.expect
+++ b/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.expect
@@ -42,7 +42,8 @@
         handleIdentifier(on, expression)
         handleNoTypeArguments(()
         beginArguments(()
-        endArguments(0, (, ))
+          handleLiteralInt(42)
+        endArguments(1, (, ))
         handleSend(on, ;)
         handleExpressionStatement(;)
       endBlockFunctionBody(2, {, })
@@ -56,7 +57,14 @@
       handleIdentifier(on, topLevelFunctionDeclaration)
       handleNoTypeVariables(()
       beginFormalParameters((, MemberKind.TopLevelMethod)
-      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        beginMetadataStar(e)
+        endMetadataStar(0)
+        beginFormalParameter(e, MemberKind.TopLevelMethod, null, null, null)
+          handleNoType(()
+          handleIdentifier(e, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, null, e, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
       handleAsyncModifier(null, null)
       beginBlockFunctionBody({)
       endBlockFunctionBody(0, {, })
diff --git a/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.intertwined.expect
index 5ec70ff..84387f2 100644
--- a/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.intertwined.expect
@@ -108,7 +108,13 @@
                                   parseArguments(on)
                                     parseArgumentsRest(()
                                       listener: beginArguments(()
-                                      listener: endArguments(0, (, ))
+                                      parseExpression(()
+                                        parsePrecedenceExpression((, 1, true)
+                                          parseUnaryExpression((, true)
+                                            parsePrimary((, expression)
+                                              parseLiteralInt(()
+                                                listener: handleLiteralInt(42)
+                                      listener: endArguments(1, (, ))
                                 listener: handleSend(on, ;)
                     ensureSemicolon())
                     listener: handleExpressionStatement(;)
@@ -133,7 +139,17 @@
           parseFormalParameters(on, MemberKind.TopLevelMethod)
             parseFormalParametersRest((, MemberKind.TopLevelMethod)
               listener: beginFormalParameters((, MemberKind.TopLevelMethod)
-              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(e)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(e, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleNoType(()
+                ensureIdentifier((, formalParameterDeclaration)
+                  listener: handleIdentifier(e, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, null, e, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
         parseAsyncModifierOpt())
           listener: handleAsyncModifier(null, null)
           inPlainSync()
diff --git a/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.parser.expect b/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.parser.expect
index ae4a8fa..9fd2ce1 100644
--- a/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.parser.expect
@@ -7,10 +7,14 @@
 ;
 }
 
-on();
+
+
+
+
+on(42);
 }
 
-void on() {}
+void on(e) {}
 
 
 void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
@@ -22,8 +26,12 @@
 ;[SimpleToken]
 }[SimpleToken]
 
-on[KeywordToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+
+
+on[KeywordToken]([BeginToken]42[StringToken])[SimpleToken];[SimpleToken]
 }[SimpleToken]
 
-void[KeywordToken] on[KeywordToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+void[KeywordToken] on[KeywordToken]([BeginToken]e[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
 [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.scanner.expect b/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.scanner.expect
index ae4a8fa..9fd2ce1 100644
--- a/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.scanner.expect
+++ b/pkg/front_end/parser_testcases/general/call_on_after_try_block.dart.scanner.expect
@@ -7,10 +7,14 @@
 ;
 }
 
-on();
+
+
+
+
+on(42);
 }
 
-void on() {}
+void on(e) {}
 
 
 void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
@@ -22,8 +26,12 @@
 ;[SimpleToken]
 }[SimpleToken]
 
-on[KeywordToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+
+
+on[KeywordToken]([BeginToken]42[StringToken])[SimpleToken];[SimpleToken]
 }[SimpleToken]
 
-void[KeywordToken] on[KeywordToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+void[KeywordToken] on[KeywordToken]([BeginToken]e[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
 [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart b/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart
index 4313b11..2345c38 100644
--- a/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart
+++ b/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart
@@ -7,7 +7,7 @@
     ;
   }
 
-  onX();
+  onX(42);
 }
 
-void onX() {}
+void onX(e) {}
diff --git a/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.expect b/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.expect
index 8ebdaa9..0983a0b 100644
--- a/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.expect
+++ b/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.expect
@@ -42,7 +42,8 @@
         handleIdentifier(onX, expression)
         handleNoTypeArguments(()
         beginArguments(()
-        endArguments(0, (, ))
+          handleLiteralInt(42)
+        endArguments(1, (, ))
         handleSend(onX, ;)
         handleExpressionStatement(;)
       endBlockFunctionBody(2, {, })
@@ -56,7 +57,14 @@
       handleIdentifier(onX, topLevelFunctionDeclaration)
       handleNoTypeVariables(()
       beginFormalParameters((, MemberKind.TopLevelMethod)
-      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        beginMetadataStar(e)
+        endMetadataStar(0)
+        beginFormalParameter(e, MemberKind.TopLevelMethod, null, null, null)
+          handleNoType(()
+          handleIdentifier(e, formalParameterDeclaration)
+          handleFormalParameterWithoutValue())
+        endFormalParameter(null, null, null, e, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
       handleAsyncModifier(null, null)
       beginBlockFunctionBody({)
       endBlockFunctionBody(0, {, })
diff --git a/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.intertwined.expect
index 007fb4b..b7b15a2 100644
--- a/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.intertwined.expect
@@ -105,7 +105,13 @@
                                 parseArguments(onX)
                                   parseArgumentsRest(()
                                     listener: beginArguments(()
-                                    listener: endArguments(0, (, ))
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseLiteralInt(()
+                                              listener: handleLiteralInt(42)
+                                    listener: endArguments(1, (, ))
                               listener: handleSend(onX, ;)
                   ensureSemicolon())
                   listener: handleExpressionStatement(;)
@@ -130,7 +136,17 @@
           parseFormalParameters(onX, MemberKind.TopLevelMethod)
             parseFormalParametersRest((, MemberKind.TopLevelMethod)
               listener: beginFormalParameters((, MemberKind.TopLevelMethod)
-              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+              parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+                parseMetadataStar(()
+                  listener: beginMetadataStar(e)
+                  listener: endMetadataStar(0)
+                listener: beginFormalParameter(e, MemberKind.TopLevelMethod, null, null, null)
+                listener: handleNoType(()
+                ensureIdentifier((, formalParameterDeclaration)
+                  listener: handleIdentifier(e, formalParameterDeclaration)
+                listener: handleFormalParameterWithoutValue())
+                listener: endFormalParameter(null, null, null, e, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
         parseAsyncModifierOpt())
           listener: handleAsyncModifier(null, null)
           inPlainSync()
diff --git a/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.parser.expect b/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.parser.expect
index cb01c79..ba6b325 100644
--- a/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.parser.expect
@@ -7,10 +7,10 @@
 ;
 }
 
-onX();
+onX(42);
 }
 
-void onX() {}
+void onX(e) {}
 
 
 void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
@@ -22,8 +22,8 @@
 ;[SimpleToken]
 }[SimpleToken]
 
-onX[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+onX[StringToken]([BeginToken]42[StringToken])[SimpleToken];[SimpleToken]
 }[SimpleToken]
 
-void[KeywordToken] onX[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+void[KeywordToken] onX[StringToken]([BeginToken]e[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
 [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.scanner.expect b/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.scanner.expect
index cb01c79..ba6b325 100644
--- a/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.scanner.expect
+++ b/pkg/front_end/parser_testcases/general/call_on_after_try_block_prime.dart.scanner.expect
@@ -7,10 +7,10 @@
 ;
 }
 
-onX();
+onX(42);
 }
 
-void onX() {}
+void onX(e) {}
 
 
 void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
@@ -22,8 +22,8 @@
 ;[SimpleToken]
 }[SimpleToken]
 
-onX[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+onX[StringToken]([BeginToken]42[StringToken])[SimpleToken];[SimpleToken]
 }[SimpleToken]
 
-void[KeywordToken] onX[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+void[KeywordToken] onX[StringToken]([BeginToken]e[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
 [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/chained_call_05.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/chained_call_05.dart.intertwined.expect
index 9e8ca34..e0381e7b 100644
--- a/pkg/front_end/parser_testcases/general/chained_call_05.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/chained_call_05.dart.intertwined.expect
@@ -49,7 +49,7 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/chained_call_06.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/chained_call_06.dart.intertwined.expect
index e2b9b0c..ac7ecb6 100644
--- a/pkg/front_end/parser_testcases/general/chained_call_06.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/chained_call_06.dart.intertwined.expect
@@ -49,7 +49,7 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.intertwined.expect
index d32578d..d3513e2 100644
--- a/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.intertwined.expect
@@ -842,7 +842,7 @@
                                           listener: handleNoArguments(*)
                                         listener: handleSend(, *)
                                   listener: beginBinaryExpression(*)
-                                  parsePrecedenceExpression(*, 15, true)
+                                  parsePrecedenceExpression(*, 16, true)
                                     parseUnaryExpression(*, true)
                                       parsePrimary(*, expression)
                                         parseSendOrFunctionLiteral(*, expression)
@@ -932,7 +932,7 @@
                                 listener: beginBinaryExpression(>)
                                 parsePrecedenceExpression(>, 9, true)
                                   parseUnaryExpression(>, true)
-                                    parsePrecedenceExpression(!, 16, true)
+                                    parsePrecedenceExpression(!, 17, true)
                                       parseUnaryExpression(!, true)
                                         parsePrimary(!, expression)
                                           listener: handleNoTypeArguments([)
@@ -1029,11 +1029,11 @@
                                 listener: beginBinaryExpression(>)
                                 parsePrecedenceExpression(>, 9, true)
                                   parseUnaryExpression(>, true)
-                                    parsePrecedenceExpression(!, 16, true)
+                                    parsePrecedenceExpression(!, 17, true)
                                       parseUnaryExpression(!, true)
                                         parsePrimary(!, expression)
                                           parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(!)
-                                            parseParenthesizedExpressionOrRecordLiteral(!)
+                                            parseParenthesizedExpressionOrRecordLiteral(!, null)
                                               listener: beginParenthesizedExpressionOrRecordLiteral(()
                                               parseExpression(()
                                                 parsePrecedenceExpression((, 1, true)
@@ -1497,7 +1497,7 @@
                                 listener: beginBinaryExpression(>)
                                 parsePrecedenceExpression(>, 9, true)
                                   parseUnaryExpression(>, true)
-                                    parsePrecedenceExpression(-, 16, true)
+                                    parsePrecedenceExpression(-, 17, true)
                                       parseUnaryExpression(-, true)
                                         parsePrimary(-, expression)
                                           parseSendOrFunctionLiteral(-, expression)
@@ -1911,7 +1911,7 @@
                                           listener: handleNoArguments(%)
                                         listener: handleSend(, %)
                                   listener: beginBinaryExpression(%)
-                                  parsePrecedenceExpression(%, 15, true)
+                                  parsePrecedenceExpression(%, 16, true)
                                     parseUnaryExpression(%, true)
                                       parsePrimary(%, expression)
                                         parseSendOrFunctionLiteral(%, expression)
@@ -2121,7 +2121,7 @@
                                             listener: handleNoArguments(+)
                                           listener: handleSend(, +)
                                   listener: beginBinaryExpression(+)
-                                  parsePrecedenceExpression(+, 14, true)
+                                  parsePrecedenceExpression(+, 15, true)
                                     parseUnaryExpression(+, true)
                                       parsePrimary(+, expression)
                                         parseSendOrFunctionLiteral(+, expression)
@@ -2855,7 +2855,7 @@
                                           listener: handleNoArguments(/)
                                         listener: handleSend(, /)
                                   listener: beginBinaryExpression(/)
-                                  parsePrecedenceExpression(/, 15, true)
+                                  parsePrecedenceExpression(/, 16, true)
                                     parseUnaryExpression(/, true)
                                       parsePrimary(/, expression)
                                         parseSendOrFunctionLiteral(/, expression)
@@ -2958,7 +2958,7 @@
                                           listener: handleNoArguments(~/)
                                         listener: handleSend(, ~/)
                                   listener: beginBinaryExpression(~/)
-                                  parsePrecedenceExpression(~/, 15, true)
+                                  parsePrecedenceExpression(~/, 16, true)
                                     parseUnaryExpression(~/, true)
                                       parsePrimary(~/, expression)
                                         parseSendOrFunctionLiteral(~/, expression)
diff --git a/pkg/front_end/parser_testcases/general/issue_45848_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_45848_01.dart.intertwined.expect
index 5739221..16cf5a7 100644
--- a/pkg/front_end/parser_testcases/general/issue_45848_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_45848_01.dart.intertwined.expect
@@ -223,7 +223,7 @@
                                         parseUnaryExpression(,, true)
                                           parsePrimary(,, expression)
                                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(,)
-                                              parseParenthesizedExpressionOrRecordLiteral(,)
+                                              parseParenthesizedExpressionOrRecordLiteral(,, null)
                                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                 parseExpression(()
                                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/issue_45848_01_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_45848_01_prime.dart.intertwined.expect
index a488a13..4c8a941 100644
--- a/pkg/front_end/parser_testcases/general/issue_45848_01_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_45848_01_prime.dart.intertwined.expect
@@ -196,7 +196,7 @@
                                         parseUnaryExpression((, true)
                                           parsePrimary((, expression)
                                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                              parseParenthesizedExpressionOrRecordLiteral(()
+                                              parseParenthesizedExpressionOrRecordLiteral((, null)
                                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                 parseExpression(()
                                                   parsePrecedenceExpression((, 1, true)
@@ -232,7 +232,7 @@
                                         parseUnaryExpression(,, true)
                                           parsePrimary(,, expression)
                                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(,)
-                                              parseParenthesizedExpressionOrRecordLiteral(,)
+                                              parseParenthesizedExpressionOrRecordLiteral(,, null)
                                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                 parseExpression(()
                                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/issue_45848_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_45848_02.dart.intertwined.expect
index bbb86fc..a5f25b7 100644
--- a/pkg/front_end/parser_testcases/general/issue_45848_02.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_45848_02.dart.intertwined.expect
@@ -230,7 +230,7 @@
                                           parseUnaryExpression(>, true)
                                             parsePrimary(>, expression)
                                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>)
+                                                parseParenthesizedExpressionOrRecordLiteral(>, null)
                                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                   parseExpression(()
                                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/issue_45848_02_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_45848_02_prime.dart.intertwined.expect
index 974c9dc..9fccf81 100644
--- a/pkg/front_end/parser_testcases/general/issue_45848_02_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_45848_02_prime.dart.intertwined.expect
@@ -196,7 +196,7 @@
                                         parseUnaryExpression((, true)
                                           parsePrimary((, expression)
                                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                              parseParenthesizedExpressionOrRecordLiteral(()
+                                              parseParenthesizedExpressionOrRecordLiteral((, null)
                                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                 parseExpression(()
                                                   parsePrecedenceExpression((, 1, true)
@@ -238,7 +238,7 @@
                                           parseUnaryExpression(>, true)
                                             parsePrimary(>, expression)
                                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>)
+                                                parseParenthesizedExpressionOrRecordLiteral(>, null)
                                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                   parseExpression(()
                                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/issue_45848_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_45848_03.dart.intertwined.expect
index 9a37bbb..f4edee7 100644
--- a/pkg/front_end/parser_testcases/general/issue_45848_03.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_45848_03.dart.intertwined.expect
@@ -236,7 +236,7 @@
                                         parseUnaryExpression(,, true)
                                           parsePrimary(,, expression)
                                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(,)
-                                              parseParenthesizedExpressionOrRecordLiteral(,)
+                                              parseParenthesizedExpressionOrRecordLiteral(,, null)
                                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                 parseExpression(()
                                                   parsePrecedenceExpression((, 1, true)
@@ -267,7 +267,7 @@
                                           parseUnaryExpression(>, true)
                                             parsePrimary(>, expression)
                                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>)
+                                                parseParenthesizedExpressionOrRecordLiteral(>, null)
                                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                   parseExpression(()
                                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/issue_45848_03_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_45848_03_prime.dart.intertwined.expect
index 388720f..37ea9f9 100644
--- a/pkg/front_end/parser_testcases/general/issue_45848_03_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_45848_03_prime.dart.intertwined.expect
@@ -208,7 +208,7 @@
                                         parseUnaryExpression((, true)
                                           parsePrimary((, expression)
                                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                              parseParenthesizedExpressionOrRecordLiteral(()
+                                              parseParenthesizedExpressionOrRecordLiteral((, null)
                                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                 parseExpression(()
                                                   parsePrecedenceExpression((, 1, true)
@@ -244,7 +244,7 @@
                                         parseUnaryExpression(,, true)
                                           parsePrimary(,, expression)
                                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(,)
-                                              parseParenthesizedExpressionOrRecordLiteral(,)
+                                              parseParenthesizedExpressionOrRecordLiteral(,, null)
                                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                 parseExpression(()
                                                   parsePrecedenceExpression((, 1, true)
@@ -275,7 +275,7 @@
                                           parseUnaryExpression(>, true)
                                             parsePrimary(>, expression)
                                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>)
+                                                parseParenthesizedExpressionOrRecordLiteral(>, null)
                                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                   parseExpression(()
                                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/issue_45848_06.dart.expect b/pkg/front_end/parser_testcases/general/issue_45848_06.dart.expect
index f9861c4..79fe273 100644
--- a/pkg/front_end/parser_testcases/general/issue_45848_06.dart.expect
+++ b/pkg/front_end/parser_testcases/general/issue_45848_06.dart.expect
@@ -102,38 +102,35 @@
         handleNoTypeArguments(()
         beginArguments(()
           handleIdentifier(x, expression)
-          handleNoTypeArguments(<)
-          handleNoArguments(<)
-          handleSend(x, <)
-          beginBinaryExpression(<)
-            handleIdentifier(y, expression)
+          beginTypeArguments(<)
+            handleIdentifier(y, typeReference)
             handleNoTypeArguments(,)
-            handleNoArguments(,)
-            handleSend(y, ,)
-          endBinaryExpression(<)
-          beginParenthesizedExpressionOrRecordLiteral(()
-            beginAwaitExpression(await)
-              handleIdentifier(o, expression)
-              handleNoTypeArguments(,)
-              handleNoArguments(,)
-              handleSend(o, ,)
-            endAwaitExpression(await, ,)
-          endRecordLiteral((, 1)
-          beginBinaryExpression(>)
-            beginParenthesizedExpressionOrRecordLiteral(()
-              handleIdentifier(p, expression)
-              handleNoTypeArguments(as)
-              handleNoArguments(as)
-              handleSend(p, as)
-              beginAsOperatorType(as)
-                handleIdentifier(int, typeReference)
-                handleNoTypeArguments())
-                handleType(int, null)
-              endAsOperatorType(as)
-              handleAsOperator(as)
-            endParenthesizedExpression(()
-          endBinaryExpression(>)
-        endArguments(2, (, ))
+            handleType(y, null)
+            beginRecordType(()
+              beginRecordTypeEntry()
+                beginMetadataStar(await)
+                endMetadataStar(0)
+                handleIdentifier(await, typeReference)
+                handleNoTypeArguments(o)
+                handleType(await, null)
+                handleIdentifier(o, recordFieldDeclaration)
+              endRecordTypeEntry()
+            endRecordType((, null, 1, false)
+          endTypeArguments(2, <, >)
+          beginArguments(()
+            handleIdentifier(p, expression)
+            handleNoTypeArguments(as)
+            handleNoArguments(as)
+            handleSend(p, as)
+            beginAsOperatorType(as)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments())
+              handleType(int, null)
+            endAsOperatorType(as)
+            handleAsOperator(as)
+          endArguments(1, (, ))
+          handleSend(x, ))
+        endArguments(1, (, ))
         handleSend(f, ;)
         handleExpressionStatement(;)
       endBlockFunctionBody(1, {, })
diff --git a/pkg/front_end/parser_testcases/general/issue_45848_06.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_45848_06.dart.intertwined.expect
index f4b3114..62b0cc1 100644
--- a/pkg/front_end/parser_testcases/general/issue_45848_06.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_45848_06.dart.intertwined.expect
@@ -212,86 +212,54 @@
                                                 isNextIdentifier(()
                                                 ensureIdentifier((, expression)
                                                   listener: handleIdentifier(x, expression)
-                                                listener: handleNoTypeArguments(<)
-                                                parseArgumentsOpt(x)
-                                                  listener: handleNoArguments(<)
-                                                listener: handleSend(x, <)
-                                        listener: beginBinaryExpression(<)
-                                        parsePrecedenceExpression(<, 9, true)
-                                          parseUnaryExpression(<, true)
-                                            parsePrimary(<, expression)
-                                              parseSendOrFunctionLiteral(<, expression)
-                                                parseSend(<, expression)
-                                                  isNextIdentifier(<)
-                                                  ensureIdentifier(<, expression)
-                                                    listener: handleIdentifier(y, expression)
-                                                  listener: handleNoTypeArguments(,)
-                                                  parseArgumentsOpt(y)
-                                                    listener: handleNoArguments(,)
-                                                  listener: handleSend(y, ,)
-                                        listener: endBinaryExpression(<)
-                                    parseExpression(,)
-                                      parsePrecedenceExpression(,, 1, true)
-                                        parseUnaryExpression(,, true)
-                                          parsePrimary(,, expression)
-                                            parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(,)
-                                              parseParenthesizedExpressionOrRecordLiteral(,)
-                                                listener: beginParenthesizedExpressionOrRecordLiteral(()
-                                                parseExpression(()
-                                                  parsePrecedenceExpression((, 1, true)
-                                                    parseUnaryExpression((, true)
-                                                      inPlainSync()
-                                                      parseAwaitExpression((, true)
-                                                        listener: beginAwaitExpression(await)
-                                                        parsePrecedenceExpression(await, 16, true)
-                                                          parseUnaryExpression(await, true)
-                                                            parsePrimary(await, expression)
-                                                              parseSendOrFunctionLiteral(await, expression)
-                                                                parseSend(await, expression)
-                                                                  isNextIdentifier(await)
-                                                                  ensureIdentifier(await, expression)
-                                                                    listener: handleIdentifier(o, expression)
-                                                                  listener: handleNoTypeArguments(,)
-                                                                  parseArgumentsOpt(o)
-                                                                    listener: handleNoArguments(,)
-                                                                  listener: handleSend(o, ,)
-                                                        inAsync()
-                                                        listener: endAwaitExpression(await, ,)
-                                                ensureCloseParen(,, ()
-                                                listener: endRecordLiteral((, 1)
-                                        listener: beginBinaryExpression(>)
-                                        parsePrecedenceExpression(>, 9, true)
-                                          parseUnaryExpression(>, true)
-                                            parsePrimary(>, expression)
-                                              parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>)
-                                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
-                                                  parseExpression(()
-                                                    parsePrecedenceExpression((, 1, true)
-                                                      parseUnaryExpression((, true)
-                                                        parsePrimary((, expression)
-                                                          parseSendOrFunctionLiteral((, expression)
-                                                            parseSend((, expression)
-                                                              isNextIdentifier(()
-                                                              ensureIdentifier((, expression)
-                                                                listener: handleIdentifier(p, expression)
-                                                              listener: handleNoTypeArguments(as)
-                                                              parseArgumentsOpt(p)
-                                                                listener: handleNoArguments(as)
-                                                              listener: handleSend(p, as)
-                                                      parseAsOperatorRest(p)
-                                                        listener: beginAsOperatorType(as)
-                                                        computeTypeAfterIsOrAs(as)
-                                                        listener: handleIdentifier(int, typeReference)
-                                                        listener: handleNoTypeArguments())
-                                                        listener: handleType(int, null)
-                                                        listener: endAsOperatorType(as)
-                                                        listener: handleAsOperator(as)
-                                                        skipChainedAsIsOperators(int)
-                                                  ensureCloseParen(int, ()
-                                                  listener: endParenthesizedExpression(()
-                                        listener: endBinaryExpression(>)
-                                    listener: endArguments(2, (, ))
+                                                listener: beginTypeArguments(<)
+                                                listener: handleIdentifier(y, typeReference)
+                                                listener: handleNoTypeArguments(,)
+                                                listener: handleType(y, null)
+                                                parseRecordType((, ,)
+                                                  listener: beginRecordType(()
+                                                  parseRecordTypeField((, identifierIsOptional: true)
+                                                    listener: beginRecordTypeEntry()
+                                                    parseMetadataStar(()
+                                                      listener: beginMetadataStar(await)
+                                                      listener: endMetadataStar(0)
+                                                    listener: handleIdentifier(await, typeReference)
+                                                    listener: handleNoTypeArguments(o)
+                                                    listener: handleType(await, null)
+                                                    ensureIdentifier(await, recordFieldDeclaration)
+                                                      listener: handleIdentifier(o, recordFieldDeclaration)
+                                                    listener: endRecordTypeEntry()
+                                                  listener: endRecordType((, null, 1, false)
+                                                listener: endTypeArguments(2, <, >)
+                                                parseArgumentsOpt(>)
+                                                  parseArguments(>)
+                                                    parseArgumentsRest(()
+                                                      listener: beginArguments(()
+                                                      parseExpression(()
+                                                        parsePrecedenceExpression((, 1, true)
+                                                          parseUnaryExpression((, true)
+                                                            parsePrimary((, expression)
+                                                              parseSendOrFunctionLiteral((, expression)
+                                                                parseSend((, expression)
+                                                                  isNextIdentifier(()
+                                                                  ensureIdentifier((, expression)
+                                                                    listener: handleIdentifier(p, expression)
+                                                                  listener: handleNoTypeArguments(as)
+                                                                  parseArgumentsOpt(p)
+                                                                    listener: handleNoArguments(as)
+                                                                  listener: handleSend(p, as)
+                                                          parseAsOperatorRest(p)
+                                                            listener: beginAsOperatorType(as)
+                                                            computeTypeAfterIsOrAs(as)
+                                                            listener: handleIdentifier(int, typeReference)
+                                                            listener: handleNoTypeArguments())
+                                                            listener: handleType(int, null)
+                                                            listener: endAsOperatorType(as)
+                                                            listener: handleAsOperator(as)
+                                                            skipChainedAsIsOperators(int)
+                                                      listener: endArguments(1, (, ))
+                                                listener: handleSend(x, ))
+                                    listener: endArguments(1, (, ))
                               listener: handleSend(f, ;)
                   ensureSemicolon())
                   listener: handleExpressionStatement(;)
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_47008_01.dart.intertwined.expect
index 45bab8d..964c640 100644
--- a/pkg/front_end/parser_testcases/general/issue_47008_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_47008_01.dart.intertwined.expect
@@ -109,11 +109,11 @@
                                             parseLiteralInt(,)
                                               listener: handleLiteralInt(1)
                                         listener: beginBinaryExpression(>>)
-                                        parsePrecedenceExpression(>>, 13, true)
+                                        parsePrecedenceExpression(>>, 14, true)
                                           parseUnaryExpression(>>, true)
                                             parsePrimary(>>, expression)
                                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>>)
+                                                parseParenthesizedExpressionOrRecordLiteral(>>, null)
                                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                   parseExpression(()
                                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/issue_47008_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_47008_02.dart.intertwined.expect
index 0cfb7ed..d2e2217 100644
--- a/pkg/front_end/parser_testcases/general/issue_47008_02.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_47008_02.dart.intertwined.expect
@@ -136,11 +136,11 @@
                                             parseLiteralInt(,)
                                               listener: handleLiteralInt(1)
                                         listener: beginBinaryExpression(>>>)
-                                        parsePrecedenceExpression(>>>, 13, true)
+                                        parsePrecedenceExpression(>>>, 14, true)
                                           parseUnaryExpression(>>>, true)
                                             parsePrimary(>>>, expression)
                                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>>>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>>>)
+                                                parseParenthesizedExpressionOrRecordLiteral(>>>, null)
                                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                   parseExpression(()
                                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_47009_01.dart.intertwined.expect
index 5136298..e823422 100644
--- a/pkg/front_end/parser_testcases/general/issue_47009_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_47009_01.dart.intertwined.expect
@@ -95,7 +95,7 @@
                                           parseUnaryExpression(>, true)
                                             parsePrimary(>, expression)
                                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>)
+                                                parseParenthesizedExpressionOrRecordLiteral(>, null)
                                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                   parseExpression(()
                                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_47009_02.dart.intertwined.expect
index 42a1ecf..f62c0ca 100644
--- a/pkg/front_end/parser_testcases/general/issue_47009_02.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_47009_02.dart.intertwined.expect
@@ -118,11 +118,11 @@
                                                   listener: handleNoArguments(>>)
                                                 listener: handleSend(as, >>)
                                         listener: beginBinaryExpression(>>)
-                                        parsePrecedenceExpression(>>, 13, true)
+                                        parsePrecedenceExpression(>>, 14, true)
                                           parseUnaryExpression(>>, true)
                                             parsePrimary(>>, expression)
                                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>>)
+                                                parseParenthesizedExpressionOrRecordLiteral(>>, null)
                                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                   parseExpression(()
                                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/issue_47009_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_47009_03.dart.intertwined.expect
index 4194aa5..2eac2b3 100644
--- a/pkg/front_end/parser_testcases/general/issue_47009_03.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/issue_47009_03.dart.intertwined.expect
@@ -145,11 +145,11 @@
                                                   listener: handleNoArguments(>>>)
                                                 listener: handleSend(as, >>>)
                                         listener: beginBinaryExpression(>>>)
-                                        parsePrecedenceExpression(>>>, 13, true)
+                                        parsePrecedenceExpression(>>>, 14, true)
                                           parseUnaryExpression(>>>, true)
                                             parsePrimary(>>>, expression)
                                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>>>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>>>)
+                                                parseParenthesizedExpressionOrRecordLiteral(>>>, null)
                                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                   parseExpression(()
                                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart b/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart
new file mode 100644
index 0000000..e9928df
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart
@@ -0,0 +1,22 @@
+void main() {
+  try {
+    ;
+  } catch (e) {
+    ;
+  } on Foo {
+    ;
+  }
+
+  // With records this is no longer a call after a try block, but a on clause
+  // where the type is the empty record.
+  // See https://github.com/dart-lang/language/blob/master/accepted/future-releases/records/records-feature-specification.md#ambiguity-with-on-clauses
+  on() {
+    ;
+  } on(a, b) {
+    ;
+  } on(a, b, c) {
+    ;
+  }
+}
+
+void on([a, b, c]) {}
diff --git a/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.expect b/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.expect
new file mode 100644
index 0000000..f465753
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.expect
@@ -0,0 +1,146 @@
+beginCompilationUnit(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginTryStatement(try)
+          beginBlock({, BlockKind(try statement))
+            handleEmptyStatement(;)
+          endBlock(1, {, }, BlockKind(try statement))
+          beginCatchClause(catch)
+            beginFormalParameters((, MemberKind.Catch)
+              beginMetadataStar(e)
+              endMetadataStar(0)
+              beginFormalParameter(e, MemberKind.Catch, null, null, null)
+                handleNoType(()
+                handleIdentifier(e, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, null, e, null, null, FormalParameterKind.requiredPositional, MemberKind.Catch)
+            endFormalParameters(1, (, ), MemberKind.Catch)
+          endCatchClause({)
+          beginBlock({, BlockKind(catch clause))
+            handleEmptyStatement(;)
+          endBlock(1, {, }, BlockKind(catch clause))
+          handleCatchBlock(null, catch, null)
+          beginCatchClause(on)
+            handleIdentifier(Foo, typeReference)
+            handleNoTypeArguments({)
+            handleType(Foo, null)
+          endCatchClause({)
+          beginBlock({, BlockKind(catch clause))
+            handleEmptyStatement(;)
+          endBlock(1, {, }, BlockKind(catch clause))
+          handleCatchBlock(on, null, null)
+          beginCatchClause(on)
+            beginRecordType(()
+            endRecordType((, null, 0, false)
+          endCatchClause({)
+          beginBlock({, BlockKind(catch clause))
+            handleEmptyStatement(;)
+          endBlock(1, {, }, BlockKind(catch clause))
+          handleCatchBlock(on, null, null)
+          beginCatchClause(on)
+            beginRecordType(()
+              beginRecordTypeEntry()
+                beginMetadataStar(a)
+                endMetadataStar(0)
+                handleIdentifier(a, typeReference)
+                handleNoTypeArguments(,)
+                handleType(a, null)
+                handleNoName(,)
+              endRecordTypeEntry()
+              beginRecordTypeEntry()
+                beginMetadataStar(b)
+                endMetadataStar(0)
+                handleIdentifier(b, typeReference)
+                handleNoTypeArguments())
+                handleType(b, null)
+                handleNoName())
+              endRecordTypeEntry()
+            endRecordType((, null, 2, false)
+          endCatchClause({)
+          beginBlock({, BlockKind(catch clause))
+            handleEmptyStatement(;)
+          endBlock(1, {, }, BlockKind(catch clause))
+          handleCatchBlock(on, null, null)
+          beginCatchClause(on)
+            beginRecordType(()
+              beginRecordTypeEntry()
+                beginMetadataStar(a)
+                endMetadataStar(0)
+                handleIdentifier(a, typeReference)
+                handleNoTypeArguments(,)
+                handleType(a, null)
+                handleNoName(,)
+              endRecordTypeEntry()
+              beginRecordTypeEntry()
+                beginMetadataStar(b)
+                endMetadataStar(0)
+                handleIdentifier(b, typeReference)
+                handleNoTypeArguments(,)
+                handleType(b, null)
+                handleNoName(,)
+              endRecordTypeEntry()
+              beginRecordTypeEntry()
+                beginMetadataStar(c)
+                endMetadataStar(0)
+                handleIdentifier(c, typeReference)
+                handleNoTypeArguments())
+                handleType(c, null)
+                handleNoName())
+              endRecordTypeEntry()
+            endRecordType((, null, 3, false)
+          endCatchClause({)
+          beginBlock({, BlockKind(catch clause))
+            handleEmptyStatement(;)
+          endBlock(1, {, }, BlockKind(catch clause))
+          handleCatchBlock(on, null, null)
+        endTryStatement(5, try, null)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(}, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(on, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginOptionalFormalParameters([)
+          beginMetadataStar(a)
+          endMetadataStar(0)
+          beginFormalParameter(a, MemberKind.TopLevelMethod, null, null, null)
+            handleNoType([)
+            handleIdentifier(a, formalParameterDeclaration)
+            handleFormalParameterWithoutValue(,)
+          endFormalParameter(null, null, null, a, null, null, FormalParameterKind.optionalPositional, MemberKind.TopLevelMethod)
+          beginMetadataStar(b)
+          endMetadataStar(0)
+          beginFormalParameter(b, MemberKind.TopLevelMethod, null, null, null)
+            handleNoType(,)
+            handleIdentifier(b, formalParameterDeclaration)
+            handleFormalParameterWithoutValue(,)
+          endFormalParameter(null, null, null, b, null, null, FormalParameterKind.optionalPositional, MemberKind.TopLevelMethod)
+          beginMetadataStar(c)
+          endMetadataStar(0)
+          beginFormalParameter(c, MemberKind.TopLevelMethod, null, null, null)
+            handleNoType(,)
+            handleIdentifier(c, formalParameterDeclaration)
+            handleFormalParameterWithoutValue(])
+          endFormalParameter(null, null, null, c, null, null, FormalParameterKind.optionalPositional, MemberKind.TopLevelMethod)
+        endOptionalFormalParameters(3, [, ])
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+      endBlockFunctionBody(0, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.intertwined.expect
new file mode 100644
index 0000000..6b2e881
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.intertwined.expect
@@ -0,0 +1,251 @@
+parseUnit(void)
+  skipErrorTokens(void)
+  listener: beginCompilationUnit(void)
+  syntheticPreviousToken(void)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, main, false)
+        listener: beginTopLevelMethod(, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, try)
+          parseStatement({)
+            parseStatementX({)
+              parseTryStatement({)
+                listener: beginTryStatement(try)
+                parseBlock(try, BlockKind(try statement))
+                  ensureBlock(try, null, try statement)
+                  listener: beginBlock({, BlockKind(try statement))
+                  notEofOrValue(}, ;)
+                  parseStatement({)
+                    parseStatementX({)
+                      parseEmptyStatement({)
+                        listener: handleEmptyStatement(;)
+                  notEofOrValue(}, })
+                  listener: endBlock(1, {, }, BlockKind(try statement))
+                listener: beginCatchClause(catch)
+                parseFormalParameters(catch, MemberKind.Catch)
+                  parseFormalParametersRest((, MemberKind.Catch)
+                    listener: beginFormalParameters((, MemberKind.Catch)
+                    parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.Catch)
+                      parseMetadataStar(()
+                        listener: beginMetadataStar(e)
+                        listener: endMetadataStar(0)
+                      listener: beginFormalParameter(e, MemberKind.Catch, null, null, null)
+                      listener: handleNoType(()
+                      ensureIdentifier((, formalParameterDeclaration)
+                        listener: handleIdentifier(e, formalParameterDeclaration)
+                      listener: handleFormalParameterWithoutValue())
+                      listener: endFormalParameter(null, null, null, e, null, null, FormalParameterKind.requiredPositional, MemberKind.Catch)
+                    listener: endFormalParameters(1, (, ), MemberKind.Catch)
+                listener: endCatchClause({)
+                parseBlock(), BlockKind(catch clause))
+                  ensureBlock(), null, catch clause)
+                  listener: beginBlock({, BlockKind(catch clause))
+                  notEofOrValue(}, ;)
+                  parseStatement({)
+                    parseStatementX({)
+                      parseEmptyStatement({)
+                        listener: handleEmptyStatement(;)
+                  notEofOrValue(}, })
+                  listener: endBlock(1, {, }, BlockKind(catch clause))
+                listener: handleCatchBlock(null, catch, null)
+                listener: beginCatchClause(on)
+                listener: handleIdentifier(Foo, typeReference)
+                listener: handleNoTypeArguments({)
+                listener: handleType(Foo, null)
+                listener: endCatchClause({)
+                parseBlock(Foo, BlockKind(catch clause))
+                  ensureBlock(Foo, null, catch clause)
+                  listener: beginBlock({, BlockKind(catch clause))
+                  notEofOrValue(}, ;)
+                  parseStatement({)
+                    parseStatementX({)
+                      parseEmptyStatement({)
+                        listener: handleEmptyStatement(;)
+                  notEofOrValue(}, })
+                  listener: endBlock(1, {, }, BlockKind(catch clause))
+                listener: handleCatchBlock(on, null, null)
+                listener: beginCatchClause(on)
+                parseRecordType((, on)
+                  listener: beginRecordType(()
+                  listener: endRecordType((, null, 0, false)
+                listener: endCatchClause({)
+                parseBlock(), BlockKind(catch clause))
+                  ensureBlock(), null, catch clause)
+                  listener: beginBlock({, BlockKind(catch clause))
+                  notEofOrValue(}, ;)
+                  parseStatement({)
+                    parseStatementX({)
+                      parseEmptyStatement({)
+                        listener: handleEmptyStatement(;)
+                  notEofOrValue(}, })
+                  listener: endBlock(1, {, }, BlockKind(catch clause))
+                listener: handleCatchBlock(on, null, null)
+                listener: beginCatchClause(on)
+                parseRecordType((, on)
+                  listener: beginRecordType(()
+                  parseRecordTypeField((, identifierIsOptional: true)
+                    listener: beginRecordTypeEntry()
+                    parseMetadataStar(()
+                      listener: beginMetadataStar(a)
+                      listener: endMetadataStar(0)
+                    listener: handleIdentifier(a, typeReference)
+                    listener: handleNoTypeArguments(,)
+                    listener: handleType(a, null)
+                    listener: handleNoName(,)
+                    listener: endRecordTypeEntry()
+                  parseRecordTypeField(,, identifierIsOptional: true)
+                    listener: beginRecordTypeEntry()
+                    parseMetadataStar(,)
+                      listener: beginMetadataStar(b)
+                      listener: endMetadataStar(0)
+                    listener: handleIdentifier(b, typeReference)
+                    listener: handleNoTypeArguments())
+                    listener: handleType(b, null)
+                    listener: handleNoName())
+                    listener: endRecordTypeEntry()
+                  listener: endRecordType((, null, 2, false)
+                listener: endCatchClause({)
+                parseBlock(), BlockKind(catch clause))
+                  ensureBlock(), null, catch clause)
+                  listener: beginBlock({, BlockKind(catch clause))
+                  notEofOrValue(}, ;)
+                  parseStatement({)
+                    parseStatementX({)
+                      parseEmptyStatement({)
+                        listener: handleEmptyStatement(;)
+                  notEofOrValue(}, })
+                  listener: endBlock(1, {, }, BlockKind(catch clause))
+                listener: handleCatchBlock(on, null, null)
+                listener: beginCatchClause(on)
+                parseRecordType((, on)
+                  listener: beginRecordType(()
+                  parseRecordTypeField((, identifierIsOptional: true)
+                    listener: beginRecordTypeEntry()
+                    parseMetadataStar(()
+                      listener: beginMetadataStar(a)
+                      listener: endMetadataStar(0)
+                    listener: handleIdentifier(a, typeReference)
+                    listener: handleNoTypeArguments(,)
+                    listener: handleType(a, null)
+                    listener: handleNoName(,)
+                    listener: endRecordTypeEntry()
+                  parseRecordTypeField(,, identifierIsOptional: true)
+                    listener: beginRecordTypeEntry()
+                    parseMetadataStar(,)
+                      listener: beginMetadataStar(b)
+                      listener: endMetadataStar(0)
+                    listener: handleIdentifier(b, typeReference)
+                    listener: handleNoTypeArguments(,)
+                    listener: handleType(b, null)
+                    listener: handleNoName(,)
+                    listener: endRecordTypeEntry()
+                  parseRecordTypeField(,, identifierIsOptional: true)
+                    listener: beginRecordTypeEntry()
+                    parseMetadataStar(,)
+                      listener: beginMetadataStar(c)
+                      listener: endMetadataStar(0)
+                    listener: handleIdentifier(c, typeReference)
+                    listener: handleNoTypeArguments())
+                    listener: handleType(c, null)
+                    listener: handleNoName())
+                    listener: endRecordTypeEntry()
+                  listener: endRecordType((, null, 3, false)
+                listener: endCatchClause({)
+                parseBlock(), BlockKind(catch clause))
+                  ensureBlock(), null, catch clause)
+                  listener: beginBlock({, BlockKind(catch clause))
+                  notEofOrValue(}, ;)
+                  parseStatement({)
+                    parseStatementX({)
+                      parseEmptyStatement({)
+                        listener: handleEmptyStatement(;)
+                  notEofOrValue(}, })
+                  listener: endBlock(1, {, }, BlockKind(catch clause))
+                listener: handleCatchBlock(on, null, null)
+                listener: endTryStatement(5, try, null)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(void)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(}, null, null, }, Instance of 'VoidType', null, on, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(on, topLevelFunctionDeclaration)
+        parseMethodTypeVar(on)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(on, on, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(on, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseOptionalPositionalParameters((, MemberKind.TopLevelMethod)
+                listener: beginOptionalFormalParameters([)
+                parseFormalParameter([, FormalParameterKind.optionalPositional, MemberKind.TopLevelMethod)
+                  parseMetadataStar([)
+                    listener: beginMetadataStar(a)
+                    listener: endMetadataStar(0)
+                  listener: beginFormalParameter(a, MemberKind.TopLevelMethod, null, null, null)
+                  listener: handleNoType([)
+                  ensureIdentifier([, formalParameterDeclaration)
+                    listener: handleIdentifier(a, formalParameterDeclaration)
+                  listener: handleFormalParameterWithoutValue(,)
+                  listener: endFormalParameter(null, null, null, a, null, null, FormalParameterKind.optionalPositional, MemberKind.TopLevelMethod)
+                parseFormalParameter(,, FormalParameterKind.optionalPositional, MemberKind.TopLevelMethod)
+                  parseMetadataStar(,)
+                    listener: beginMetadataStar(b)
+                    listener: endMetadataStar(0)
+                  listener: beginFormalParameter(b, MemberKind.TopLevelMethod, null, null, null)
+                  listener: handleNoType(,)
+                  ensureIdentifier(,, formalParameterDeclaration)
+                    listener: handleIdentifier(b, formalParameterDeclaration)
+                  listener: handleFormalParameterWithoutValue(,)
+                  listener: endFormalParameter(null, null, null, b, null, null, FormalParameterKind.optionalPositional, MemberKind.TopLevelMethod)
+                parseFormalParameter(,, FormalParameterKind.optionalPositional, MemberKind.TopLevelMethod)
+                  parseMetadataStar(,)
+                    listener: beginMetadataStar(c)
+                    listener: endMetadataStar(0)
+                  listener: beginFormalParameter(c, MemberKind.TopLevelMethod, null, null, null)
+                  listener: handleNoType(,)
+                  ensureIdentifier(,, formalParameterDeclaration)
+                    listener: handleIdentifier(c, formalParameterDeclaration)
+                  listener: handleFormalParameterWithoutValue(])
+                  listener: endFormalParameter(null, null, null, c, null, null, FormalParameterKind.optionalPositional, MemberKind.TopLevelMethod)
+                listener: endOptionalFormalParameters(3, [, ])
+              ensureCloseParen(], ()
+              listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(0, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(void)
+  listener: endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.parser.expect b/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.parser.expect
new file mode 100644
index 0000000..b21639e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.parser.expect
@@ -0,0 +1,47 @@
+void main() {
+try {
+;
+} catch (e) {
+;
+} on Foo {
+;
+}
+
+
+
+
+on() {
+;
+} on(a, b) {
+;
+} on(a, b, c) {
+;
+}
+}
+
+void on([a, b, c]) {}
+
+
+void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+try[KeywordToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken] catch[KeywordToken] ([BeginToken]e[StringToken])[SimpleToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken] on[KeywordToken] Foo[StringToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken]
+
+
+
+
+on[KeywordToken]([BeginToken])[SimpleToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken] on[KeywordToken]([BeginToken]a[StringToken],[SimpleToken] b[StringToken])[SimpleToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken] on[KeywordToken]([BeginToken]a[StringToken],[SimpleToken] b[StringToken],[SimpleToken] c[StringToken])[SimpleToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+
+void[KeywordToken] on[KeywordToken]([BeginToken][[BeginToken]a[StringToken],[SimpleToken] b[StringToken],[SimpleToken] c[StringToken]][SimpleToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.scanner.expect b/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.scanner.expect
new file mode 100644
index 0000000..b21639e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/not_call_on_after_try_block.dart.scanner.expect
@@ -0,0 +1,47 @@
+void main() {
+try {
+;
+} catch (e) {
+;
+} on Foo {
+;
+}
+
+
+
+
+on() {
+;
+} on(a, b) {
+;
+} on(a, b, c) {
+;
+}
+}
+
+void on([a, b, c]) {}
+
+
+void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+try[KeywordToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken] catch[KeywordToken] ([BeginToken]e[StringToken])[SimpleToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken] on[KeywordToken] Foo[StringToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken]
+
+
+
+
+on[KeywordToken]([BeginToken])[SimpleToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken] on[KeywordToken]([BeginToken]a[StringToken],[SimpleToken] b[StringToken])[SimpleToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken] on[KeywordToken]([BeginToken]a[StringToken],[SimpleToken] b[StringToken],[SimpleToken] c[StringToken])[SimpleToken] {[BeginToken]
+;[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+
+void[KeywordToken] on[KeywordToken]([BeginToken][[BeginToken]a[StringToken],[SimpleToken] b[StringToken],[SimpleToken] c[StringToken]][SimpleToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/chained_call_05.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/chained_call_05.dart.intertwined.expect
index ea105b8..668b441 100644
--- a/pkg/front_end/parser_testcases/nnbd/chained_call_05.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/chained_call_05.dart.intertwined.expect
@@ -49,7 +49,7 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -101,7 +101,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/chained_call_06.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/chained_call_06.dart.intertwined.expect
index 91a81dd..e6a48a4 100644
--- a/pkg/front_end/parser_testcases/nnbd/chained_call_06.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/chained_call_06.dart.intertwined.expect
@@ -49,7 +49,7 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -108,7 +108,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.intertwined.expect
index 571fd2c..957b665 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39697_prime.dart.intertwined.expect
@@ -29,7 +29,7 @@
                 parseUnaryExpression(=>, true)
                   parsePrimary(=>, expression)
                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                      parseParenthesizedExpressionOrRecordLiteral(=>)
+                      parseParenthesizedExpressionOrRecordLiteral(=>, null)
                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                         parseExpression(()
                           parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect
index 22a3b76..4358f48 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect
@@ -154,7 +154,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -201,7 +201,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -244,7 +244,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -295,7 +295,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39776_prime2.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39776_prime2.dart.intertwined.expect
index 23982db..89c8310 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39776_prime2.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39776_prime2.dart.intertwined.expect
@@ -260,7 +260,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_01.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_01.dart.expect
index 7217bcd..c6d365e 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_01.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_01.dart.expect
@@ -15,7 +15,7 @@
           handleNoTypeArguments())
           handleNoArguments())
           handleSend(a, ))
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginSwitchBlock({)
             beginCaseExpression(case)
               handleIdentifier(b, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_01.dart.intertwined.expect
index 936ebb0..4b473a3 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_01.dart.intertwined.expect
@@ -31,8 +31,8 @@
             parseStatementX({)
               parseSwitchStatement({)
                 listener: beginSwitchStatement(switch)
-                ensureParenthesizedCondition(switch)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(switch, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -47,7 +47,7 @@
                                   listener: handleNoArguments())
                                 listener: handleSend(a, ))
                     ensureCloseParen(a, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 parseSwitchBlock())
                   ensureBlock(), null, switch statement)
                   listener: beginSwitchBlock({)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_02.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_02.dart.expect
index ab38809..609e0f3 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_02.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_02.dart.expect
@@ -15,7 +15,7 @@
           handleNoTypeArguments())
           handleNoArguments())
           handleSend(a, ))
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginSwitchBlock({)
             beginCaseExpression(case)
               handleIdentifier(b, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_02.dart.intertwined.expect
index 4a45768..2679778 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_02.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_02.dart.intertwined.expect
@@ -31,8 +31,8 @@
             parseStatementX({)
               parseSwitchStatement({)
                 listener: beginSwitchStatement(switch)
-                ensureParenthesizedCondition(switch)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(switch, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -47,7 +47,7 @@
                                   listener: handleNoArguments())
                                 listener: handleSend(a, ))
                     ensureCloseParen(a, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 parseSwitchBlock())
                   ensureBlock(), null, switch statement)
                   listener: beginSwitchBlock({)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_03.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_03.dart.expect
index fc31623..761442d 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_03.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_03.dart.expect
@@ -15,7 +15,7 @@
           handleNoTypeArguments())
           handleNoArguments())
           handleSend(a, ))
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginSwitchBlock({)
             beginCaseExpression(case)
               handleIdentifier(x, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_03.dart.intertwined.expect
index 85cbf83..b65d05f 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_03.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_03.dart.intertwined.expect
@@ -31,8 +31,8 @@
             parseStatementX({)
               parseSwitchStatement({)
                 listener: beginSwitchStatement(switch)
-                ensureParenthesizedCondition(switch)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(switch, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -47,7 +47,7 @@
                                   listener: handleNoArguments())
                                 listener: handleSend(a, ))
                     ensureCloseParen(a, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 parseSwitchBlock())
                   ensureBlock(), null, switch statement)
                   listener: beginSwitchBlock({)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_04.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_04.dart.expect
index 07986d7..9253eee 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_04.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_04.dart.expect
@@ -21,7 +21,7 @@
           handleNoTypeArguments())
           handleNoArguments())
           handleSend(a, ))
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginSwitchBlock({)
             beginCaseExpression(case)
               handleIdentifier(x, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_04.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_04.dart.intertwined.expect
index 178480e..0e9ebf8 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_04.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_04.dart.intertwined.expect
@@ -31,8 +31,8 @@
             parseStatementX({)
               parseSwitchStatement({)
                 listener: beginSwitchStatement(switch)
-                ensureParenthesizedCondition(switch)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(switch, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -47,7 +47,7 @@
                                   listener: handleNoArguments())
                                 listener: handleSend(a, ))
                     ensureCloseParen(a, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 parseSwitchBlock())
                   ensureBlock(), null, switch statement)
                   listener: beginSwitchBlock({)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_05.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_05.dart.expect
index a14690f..6b46016 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_05.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_05.dart.expect
@@ -15,7 +15,7 @@
           handleNoTypeArguments())
           handleNoArguments())
           handleSend(a, ))
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginSwitchBlock({)
             beginCaseExpression(case)
               handleIdentifier(x, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_05.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_05.dart.intertwined.expect
index fc65ecc..7428dee 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_case_05.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_case_05.dart.intertwined.expect
@@ -31,8 +31,8 @@
             parseStatementX({)
               parseSwitchStatement({)
                 listener: beginSwitchStatement(switch)
-                ensureParenthesizedCondition(switch)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(switch, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -47,7 +47,7 @@
                                   listener: handleNoArguments())
                                 listener: handleSend(a, ))
                     ensureCloseParen(a, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 parseSwitchBlock())
                   ensureBlock(), null, switch statement)
                   listener: beginSwitchBlock({)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_conditional.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_conditional.dart.intertwined.expect
index 15b1d71..6eaf362 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_conditional.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_conditional.dart.intertwined.expect
@@ -541,7 +541,7 @@
                             parseUnaryExpression(?, false)
                               parsePrimary(?, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(?)
-                                  parseParenthesizedExpressionOrRecordLiteral(?)
+                                  parseParenthesizedExpressionOrRecordLiteral(?, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -572,7 +572,7 @@
                             parseUnaryExpression(:, false)
                               parsePrimary(:, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(:)
-                                  parseParenthesizedExpressionOrRecordLiteral(:)
+                                  parseParenthesizedExpressionOrRecordLiteral(:, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_lookup_plus.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_lookup_plus.dart.intertwined.expect
index 7d451f6..2529a59 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_lookup_plus.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_lookup_plus.dart.intertwined.expect
@@ -68,7 +68,7 @@
                                       parseUnaryExpression([, true)
                                         parsePrimary([, expression)
                                           parseLiteralInt([)
-                            parsePrecedenceExpression(+, 14, false)
+                            parsePrecedenceExpression(+, 15, false)
                               parseUnaryExpression(+, false)
                                 parsePrimary(+, expression)
                                   parseLiteralInt(+)
@@ -81,7 +81,7 @@
                                   listener: handleLiteralInt(0)
                         listener: handleIndexedExpression(?, [, ])
                       listener: beginBinaryExpression(+)
-                      parsePrecedenceExpression(+, 14, true)
+                      parsePrecedenceExpression(+, 15, true)
                         parseUnaryExpression(+, true)
                           parsePrimary(+, expression)
                             parseLiteralInt(+)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_method_call_no_type_arguments.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_method_call_no_type_arguments.dart.intertwined.expect
index 4c3f2b3..e1fdd25 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_method_call_no_type_arguments.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_method_call_no_type_arguments.dart.intertwined.expect
@@ -127,7 +127,7 @@
                             parseUnaryExpression(?, false)
                               parsePrimary(?, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(?)
-                                  parseParenthesizedExpressionOrRecordLiteral(?)
+                                  parseParenthesizedExpressionOrRecordLiteral(?, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_plus_plus_lookup.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_plus_plus_lookup.dart.intertwined.expect
index e73d955..301cff4 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_plus_plus_lookup.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_plus_plus_lookup.dart.intertwined.expect
@@ -60,7 +60,7 @@
                     parseExpression({)
                       parsePrecedenceExpression({, 1, true)
                         parseUnaryExpression({, true)
-                          parsePrecedenceExpression(++, 16, true)
+                          parsePrecedenceExpression(++, 17, true)
                             parseUnaryExpression(++, true)
                               parsePrimary(++, expression)
                                 parseSendOrFunctionLiteral(++, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40793.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40793.dart.expect
index fa82b45..b82ebef 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40793.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40793.dart.expect
@@ -33,7 +33,7 @@
           beginBinaryExpression(<)
             handleLiteralInt(10)
           endBinaryExpression(<)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               handleIdentifier(print, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40793.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40793.dart.intertwined.expect
index db63fbb..591ae0f 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40793.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40793.dart.intertwined.expect
@@ -42,8 +42,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -77,7 +77,7 @@
                                 listener: handleLiteralInt(10)
                         listener: endBinaryExpression(<)
                     ensureCloseParen(10, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime.dart.expect
index e620851..2eaa8d2 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime.dart.expect
@@ -35,7 +35,7 @@
           beginBinaryExpression(<)
             handleLiteralInt(10)
           endBinaryExpression(<)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               handleIdentifier(print, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime.dart.intertwined.expect
index 645f9a0..5d5e67d 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime.dart.intertwined.expect
@@ -42,14 +42,14 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
                           parsePrimary((, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                              parseParenthesizedExpressionOrRecordLiteral(()
+                              parseParenthesizedExpressionOrRecordLiteral((, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -86,7 +86,7 @@
                                 listener: handleLiteralInt(10)
                         listener: endBinaryExpression(<)
                     ensureCloseParen(10, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime2.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime2.dart.expect
index cb9f057..33ff13e 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime2.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime2.dart.expect
@@ -34,7 +34,7 @@
           beginBinaryExpression(<)
             handleLiteralInt(10)
           endBinaryExpression(<)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               handleIdentifier(print, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime2.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime2.dart.intertwined.expect
index adf5186..272d637 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime2.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime2.dart.intertwined.expect
@@ -42,14 +42,14 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
                           parsePrimary((, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                              parseParenthesizedExpressionOrRecordLiteral(()
+                              parseParenthesizedExpressionOrRecordLiteral((, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -85,7 +85,7 @@
                                 listener: handleLiteralInt(10)
                         listener: endBinaryExpression(<)
                     ensureCloseParen(10, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime3.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime3.dart.expect
index 918518a..e4a1d9f 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime3.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime3.dart.expect
@@ -32,7 +32,7 @@
           beginBinaryExpression(<)
             handleLiteralInt(10)
           endBinaryExpression(<)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               handleIdentifier(print, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime3.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime3.dart.intertwined.expect
index 41a07ff..929529a 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40793_prime3.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40793_prime3.dart.intertwined.expect
@@ -42,8 +42,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -76,7 +76,7 @@
                                 listener: handleLiteralInt(10)
                         listener: endBinaryExpression(<)
                     ensureCloseParen(10, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect
index 01b9de6..798ed73 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.expect
@@ -133,7 +133,7 @@
                     handleLiteralInt(4)
                   endBinaryExpression(==)
                 endConditionalExpression(?, :)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement({)
                   beginBlock({, BlockKind(statement))
                     handleIdentifier(print, expression)
@@ -190,7 +190,7 @@
                     handleLiteralInt(4)
                   endBinaryExpression(==)
                 endConditionalExpression(?, :)
-                handleParenthesizedCondition(()
+                handleParenthesizedCondition((, null)
                 beginThenStatement({)
                   beginBlock({, BlockKind(statement))
                     handleIdentifier(print, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect
index b2028d4..70a1e40 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40834_03.dart.intertwined.expect
@@ -240,8 +240,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -289,7 +289,7 @@
                                       listener: endBinaryExpression(==)
                                   listener: endConditionalExpression(?, :)
                             ensureCloseParen(4, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement({)
                         parseStatement())
                           parseStatementX())
@@ -381,8 +381,8 @@
                     parseStatementX({)
                       parseIfStatement({)
                         listener: beginIfStatement(if)
-                        ensureParenthesizedCondition(if)
-                          parseExpressionInParenthesisRest(()
+                        ensureParenthesizedCondition(if, allowCase: false)
+                          parseExpressionInParenthesisRest((, allowCase: false)
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
                                 parseUnaryExpression((, true)
@@ -430,7 +430,7 @@
                                       listener: endBinaryExpression(==)
                                   listener: endConditionalExpression(?, :)
                             ensureCloseParen(4, ()
-                          listener: handleParenthesizedCondition(()
+                            listener: handleParenthesizedCondition((, null)
                         listener: beginThenStatement({)
                         parseStatement())
                           parseStatementX())
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41177.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_41177.dart.intertwined.expect
index 1ad767b..7a8c0d1 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_41177.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41177.dart.intertwined.expect
@@ -177,7 +177,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -290,7 +290,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect
index af76789..d0bd969 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect
@@ -161,7 +161,7 @@
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
                                         parseUnaryExpression((, true)
-                                          parsePrecedenceExpression(!, 16, true)
+                                          parsePrecedenceExpression(!, 17, true)
                                             parseUnaryExpression(!, true)
                                               parsePrimary(!, expression)
                                                 parseSendOrFunctionLiteral(!, expression)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.intertwined.expect
index 65386e2..208e218 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_42621.dart.intertwined.expect
@@ -418,7 +418,7 @@
                           parseUnaryExpression(=, false)
                             parsePrimary(=, expression)
                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                parseParenthesizedExpressionOrRecordLiteral(=)
+                                parseParenthesizedExpressionOrRecordLiteral(=, null)
                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                   parseExpression(()
                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_48999_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_48999_prime.dart.intertwined.expect
index 0cf156d..00f982c 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_48999_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_48999_prime.dart.intertwined.expect
@@ -87,7 +87,7 @@
                                                     parseUnaryExpression(${, true)
                                                       parsePrimary(${, expression)
                                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(${)
-                                                          parseParenthesizedExpressionOrRecordLiteral(${)
+                                                          parseParenthesizedExpressionOrRecordLiteral(${, null)
                                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                             parseExpression(()
                                                               parsePrecedenceExpression((, 1, true)
@@ -154,7 +154,7 @@
                                                     parseUnaryExpression(${, true)
                                                       parsePrimary(${, expression)
                                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(${)
-                                                          parseParenthesizedExpressionOrRecordLiteral(${)
+                                                          parseParenthesizedExpressionOrRecordLiteral(${, null)
                                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                             parseExpression(()
                                                               parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_49132_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_49132_prime.dart.intertwined.expect
index f0cf0da..a0fdfab 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_49132_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_49132_prime.dart.intertwined.expect
@@ -96,7 +96,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -144,7 +144,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -252,7 +252,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -300,7 +300,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -408,7 +408,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -456,7 +456,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -564,7 +564,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -612,7 +612,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -720,7 +720,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -768,7 +768,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -878,7 +878,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -926,7 +926,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -1036,7 +1036,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -1084,7 +1084,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -1194,7 +1194,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
@@ -1242,7 +1242,7 @@
                               parseUnaryExpression(=, true)
                                 parsePrimary(=, expression)
                                   parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                    parseParenthesizedExpressionOrRecordLiteral(=)
+                                    parseParenthesizedExpressionOrRecordLiteral(=, null)
                                       listener: beginParenthesizedExpressionOrRecordLiteral(()
                                       parseExpression(()
                                         parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_49678_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_49678_prime.dart.intertwined.expect
index 207432d..d338d40 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_49678_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_49678_prime.dart.intertwined.expect
@@ -114,7 +114,7 @@
                             parseUnaryExpression([, true)
                               parsePrimary([, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral([)
-                                  parseParenthesizedExpressionOrRecordLiteral([)
+                                  parseParenthesizedExpressionOrRecordLiteral([, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -170,7 +170,7 @@
                                     parseUnaryExpression([, true)
                                       parsePrimary([, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral([)
-                                          parseParenthesizedExpressionOrRecordLiteral([)
+                                          parseParenthesizedExpressionOrRecordLiteral([, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
@@ -201,7 +201,7 @@
                                     parseUnaryExpression(,, true)
                                       parsePrimary(,, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(,)
-                                          parseParenthesizedExpressionOrRecordLiteral(,)
+                                          parseParenthesizedExpressionOrRecordLiteral(,, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
@@ -232,7 +232,7 @@
                                     parseUnaryExpression(,, true)
                                       parsePrimary(,, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(,)
-                                          parseParenthesizedExpressionOrRecordLiteral(,)
+                                          parseParenthesizedExpressionOrRecordLiteral(,, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
@@ -290,7 +290,7 @@
                                     parseUnaryExpression([, true)
                                       parsePrimary([, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral([)
-                                          parseParenthesizedExpressionOrRecordLiteral([)
+                                          parseParenthesizedExpressionOrRecordLiteral([, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
@@ -321,7 +321,7 @@
                                     parseUnaryExpression(,, true)
                                       parsePrimary(,, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(,)
-                                          parseParenthesizedExpressionOrRecordLiteral(,)
+                                          parseParenthesizedExpressionOrRecordLiteral(,, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
@@ -352,7 +352,7 @@
                                     parseUnaryExpression(,, true)
                                       parsePrimary(,, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(,)
-                                          parseParenthesizedExpressionOrRecordLiteral(,)
+                                          parseParenthesizedExpressionOrRecordLiteral(,, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect
index d293a8a9..7567372 100644
--- a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect
@@ -38,7 +38,7 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect
index 0b33562..4ec4ae3 100644
--- a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect
@@ -38,21 +38,21 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
                                     parseUnaryExpression((, true)
                                       parsePrimary((, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                          parseParenthesizedExpressionOrRecordLiteral(()
+                                          parseParenthesizedExpressionOrRecordLiteral((, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
                                                 parseUnaryExpression((, true)
                                                   parsePrimary((, expression)
                                                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                                      parseParenthesizedExpressionOrRecordLiteral(()
+                                                      parseParenthesizedExpressionOrRecordLiteral((, null)
                                                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                         parseExpression(()
                                                           parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect
index 8b34fab..8978dc6 100644
--- a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect
@@ -38,7 +38,7 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect
index 21506db..c9540a8 100644
--- a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect
@@ -38,14 +38,14 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
                                     parseUnaryExpression((, true)
                                       parsePrimary((, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                          parseParenthesizedExpressionOrRecordLiteral(()
+                                          parseParenthesizedExpressionOrRecordLiteral((, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect
index 0a48a26..05d0b1a 100644
--- a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect
@@ -38,21 +38,21 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
                                     parseUnaryExpression((, true)
                                       parsePrimary((, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                          parseParenthesizedExpressionOrRecordLiteral(()
+                                          parseParenthesizedExpressionOrRecordLiteral((, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
                                                 parseUnaryExpression((, true)
                                                   parsePrimary((, expression)
                                                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                                      parseParenthesizedExpressionOrRecordLiteral(()
+                                                      parseParenthesizedExpressionOrRecordLiteral((, null)
                                                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                         parseExpression(()
                                                           parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect
index 53e472d..11bfe25 100644
--- a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect
@@ -38,28 +38,28 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
                                     parseUnaryExpression((, true)
                                       parsePrimary((, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                          parseParenthesizedExpressionOrRecordLiteral(()
+                                          parseParenthesizedExpressionOrRecordLiteral((, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
                                                 parseUnaryExpression((, true)
                                                   parsePrimary((, expression)
                                                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                                      parseParenthesizedExpressionOrRecordLiteral(()
+                                                      parseParenthesizedExpressionOrRecordLiteral((, null)
                                                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                         parseExpression(()
                                                           parsePrecedenceExpression((, 1, true)
                                                             parseUnaryExpression((, true)
                                                               parsePrimary((, expression)
                                                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                                                  parseParenthesizedExpressionOrRecordLiteral(()
+                                                                  parseParenthesizedExpressionOrRecordLiteral((, null)
                                                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                                     parseExpression(()
                                                                       parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect
index ea8920e..92bbb14 100644
--- a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect
@@ -38,7 +38,7 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method.dart.expect b/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method.dart.expect
index 3128078..0ad8cd1 100644
--- a/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method.dart.expect
+++ b/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method.dart.expect
@@ -145,7 +145,7 @@
             handleNoArguments())
             handleSend(foo, ))
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               handleIdentifier(print, expression)
diff --git a/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method.dart.intertwined.expect b/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method.dart.intertwined.expect
index 655103c..241b1f8 100644
--- a/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method.dart.intertwined.expect
@@ -170,7 +170,7 @@
                         listener: handleRecoverableError(Message[ExperimentNotEnabled, This requires the 'triple-shift' language feature to be enabled., Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'., {string: triple-shift, string2: 2.14}], >>, >)
                       rewriter()
                       listener: beginBinaryExpression(>>>)
-                      parsePrecedenceExpression(>>>, 13, true)
+                      parsePrecedenceExpression(>>>, 14, true)
                         parseUnaryExpression(>>>, true)
                           parsePrimary(>>>, expression)
                             parseLiteralInt(>>>)
@@ -216,7 +216,7 @@
                                           listener: handleRecoverableError(Message[ExperimentNotEnabled, This requires the 'triple-shift' language feature to be enabled., Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'., {string: triple-shift, string2: 2.14}], >>, >)
                                         rewriter()
                                         listener: beginBinaryExpression(>>>)
-                                        parsePrecedenceExpression(>>>, 13, true)
+                                        parsePrecedenceExpression(>>>, 14, true)
                                           parseUnaryExpression(>>>, true)
                                             parsePrimary(>>>, expression)
                                               parseLiteralInt(>>>)
@@ -278,14 +278,14 @@
             parseStatementX(;)
               parseIfStatement(;)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
                           parsePrimary((, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                              parseParenthesizedExpressionOrRecordLiteral(()
+                              parseParenthesizedExpressionOrRecordLiteral((, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -326,7 +326,7 @@
                                   listener: handleSend(foo, ))
                         listener: endBinaryExpression(==)
                     ensureCloseParen(foo, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method_prime.dart.expect b/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method_prime.dart.expect
index 8cdcc10..0c5d104 100644
--- a/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method_prime.dart.expect
+++ b/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method_prime.dart.expect
@@ -118,7 +118,7 @@
             handleNoArguments())
             handleSend(foo, ))
           endBinaryExpression(==)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement({)
             beginBlock({, BlockKind(statement))
               handleIdentifier(print, expression)
diff --git a/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method_prime.dart.intertwined.expect
index e226427..3a9ad1a 100644
--- a/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/no-triple-shift/define_triple_shift_method_prime.dart.intertwined.expect
@@ -164,7 +164,7 @@
                                 listener: handleNoArguments(>>)
                               listener: handleSend(foo, >>)
                       listener: beginBinaryExpression(>>)
-                      parsePrecedenceExpression(>>, 13, true)
+                      parsePrecedenceExpression(>>, 14, true)
                         parseUnaryExpression(>>, true)
                           parsePrimary(>>, expression)
                             parseLiteralInt(>>)
@@ -207,7 +207,7 @@
                                                   listener: handleNoArguments(>>)
                                                 listener: handleSend(foo, >>)
                                         listener: beginBinaryExpression(>>)
-                                        parsePrecedenceExpression(>>, 13, true)
+                                        parsePrecedenceExpression(>>, 14, true)
                                           parseUnaryExpression(>>, true)
                                             parsePrimary(>>, expression)
                                               parseLiteralInt(>>)
@@ -266,14 +266,14 @@
             parseStatementX(;)
               parseIfStatement(;)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
                           parsePrimary((, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                              parseParenthesizedExpressionOrRecordLiteral(()
+                              parseParenthesizedExpressionOrRecordLiteral((, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -311,7 +311,7 @@
                                   listener: handleSend(foo, ))
                         listener: endBinaryExpression(==)
                     ensureCloseParen(foo, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement({)
                 parseStatement())
                   parseStatementX())
diff --git a/pkg/front_end/parser_testcases/no-triple-shift/simple_attempted_usage_of_triple_shift.dart.intertwined.expect b/pkg/front_end/parser_testcases/no-triple-shift/simple_attempted_usage_of_triple_shift.dart.intertwined.expect
index f6c8349..ff0ffc9 100644
--- a/pkg/front_end/parser_testcases/no-triple-shift/simple_attempted_usage_of_triple_shift.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/no-triple-shift/simple_attempted_usage_of_triple_shift.dart.intertwined.expect
@@ -67,7 +67,7 @@
                             listener: handleRecoverableError(Message[ExperimentNotEnabled, This requires the 'triple-shift' language feature to be enabled., Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'., {string: triple-shift, string2: 2.14}], >>, >)
                           rewriter()
                           listener: beginBinaryExpression(>>>)
-                          parsePrecedenceExpression(>>>, 13, true)
+                          parsePrecedenceExpression(>>>, 14, true)
                             parseUnaryExpression(>>>, true)
                               parsePrimary(>>>, expression)
                                 parseLiteralInt(>>>)
diff --git a/pkg/front_end/parser_testcases/no-triple-shift/triple_shift_not_triple_shift.dart.intertwined.expect b/pkg/front_end/parser_testcases/no-triple-shift/triple_shift_not_triple_shift.dart.intertwined.expect
index 04b1a46..d01d700 100644
--- a/pkg/front_end/parser_testcases/no-triple-shift/triple_shift_not_triple_shift.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/no-triple-shift/triple_shift_not_triple_shift.dart.intertwined.expect
@@ -181,7 +181,7 @@
                                           parseUnaryExpression(>, true)
                                             parsePrimary(>, expression)
                                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(>)
-                                                parseParenthesizedExpressionOrRecordLiteral(>)
+                                                parseParenthesizedExpressionOrRecordLiteral(>, null)
                                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                   parseExpression(()
                                                     parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/non-nnbd/issue_40267_conditional.dart.intertwined.expect b/pkg/front_end/parser_testcases/non-nnbd/issue_40267_conditional.dart.intertwined.expect
index 15b1d71..6eaf362 100644
--- a/pkg/front_end/parser_testcases/non-nnbd/issue_40267_conditional.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/non-nnbd/issue_40267_conditional.dart.intertwined.expect
@@ -541,7 +541,7 @@
                             parseUnaryExpression(?, false)
                               parsePrimary(?, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(?)
-                                  parseParenthesizedExpressionOrRecordLiteral(?)
+                                  parseParenthesizedExpressionOrRecordLiteral(?, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -572,7 +572,7 @@
                             parseUnaryExpression(:, false)
                               parsePrimary(:, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(:)
-                                  parseParenthesizedExpressionOrRecordLiteral(:)
+                                  parseParenthesizedExpressionOrRecordLiteral(:, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
diff --git a/pkg/front_end/parser_testcases/non-nnbd/issue_40267_conditional_4.dart.intertwined.expect b/pkg/front_end/parser_testcases/non-nnbd/issue_40267_conditional_4.dart.intertwined.expect
index 1f44de0..da1493b 100644
--- a/pkg/front_end/parser_testcases/non-nnbd/issue_40267_conditional_4.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/non-nnbd/issue_40267_conditional_4.dart.intertwined.expect
@@ -82,7 +82,7 @@
                           parseExpression(()
                             parsePrecedenceExpression((, 1, true)
                               parseUnaryExpression((, true)
-                                parsePrecedenceExpression(!, 16, true)
+                                parsePrecedenceExpression(!, 17, true)
                                   parseUnaryExpression(!, true)
                                     parsePrimary(!, expression)
                                       parseSendOrFunctionLiteral(!, expression)
diff --git a/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart b/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart
new file mode 100644
index 0000000..f141ace
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart
@@ -0,0 +1,10 @@
+List<(int, int)> l1;
+List<List<(int, int)>> l2;
+List<List<List<(int, int)>>> l3;
+List<List<List<List<(int, int)>>>> l4;
+List<List<List<List<List<(int, int)>>>>> l5;
+List<List<List<List<List<List<(int, int)>>>>>> l6;
+List<List<List<List<List<List<List<(int, int)>>>>>>> l7;
+List<List<List<List<List<List<List<List<(int, int)>>>>>>>> l8;
+List<List<List<List<List<List<List<List<List<(int, int)>>>>>>>>> l9;
+List<List<List<List<List<List<List<List<List<List<(int, int)>>>>>>>>>> l10;
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.expect b/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.expect
new file mode 100644
index 0000000..382a6570
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.expect
@@ -0,0 +1,482 @@
+beginCompilationUnit(List)
+  beginMetadataStar(List)
+  endMetadataStar(0)
+  beginTopLevelMember(List)
+    beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, )
+      handleIdentifier(List, typeReference)
+      beginTypeArguments(<)
+        beginRecordType(()
+          beginRecordTypeEntry()
+            beginMetadataStar(int)
+            endMetadataStar(0)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(,)
+            handleType(int, null)
+            handleNoName(,)
+          endRecordTypeEntry()
+          beginRecordTypeEntry()
+            beginMetadataStar(int)
+            endMetadataStar(0)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+          endRecordTypeEntry()
+        endRecordType((, null, 2, false)
+      endTypeArguments(1, <, >)
+      handleType(List, null)
+      handleIdentifier(l1, topLevelVariableDeclaration)
+      handleNoFieldInitializer(;)
+    endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  endTopLevelDeclaration(List)
+  beginMetadataStar(List)
+  endMetadataStar(0)
+  beginTopLevelMember(List)
+    beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+      handleIdentifier(List, typeReference)
+      beginTypeArguments(<)
+        handleIdentifier(List, typeReference)
+        beginTypeArguments(<)
+          beginRecordType(()
+            beginRecordTypeEntry()
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(,)
+              handleType(int, null)
+              handleNoName(,)
+            endRecordTypeEntry()
+            beginRecordTypeEntry()
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments())
+              handleType(int, null)
+              handleNoName())
+            endRecordTypeEntry()
+          endRecordType((, null, 2, false)
+        endTypeArguments(1, <, >)
+        handleType(List, null)
+      endTypeArguments(1, <, >)
+      handleType(List, null)
+      handleIdentifier(l2, topLevelVariableDeclaration)
+      handleNoFieldInitializer(;)
+    endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  endTopLevelDeclaration(List)
+  beginMetadataStar(List)
+  endMetadataStar(0)
+  beginTopLevelMember(List)
+    beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+      handleIdentifier(List, typeReference)
+      beginTypeArguments(<)
+        handleIdentifier(List, typeReference)
+        beginTypeArguments(<)
+          handleIdentifier(List, typeReference)
+          beginTypeArguments(<)
+            beginRecordType(()
+              beginRecordTypeEntry()
+                beginMetadataStar(int)
+                endMetadataStar(0)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(,)
+                handleType(int, null)
+                handleNoName(,)
+              endRecordTypeEntry()
+              beginRecordTypeEntry()
+                beginMetadataStar(int)
+                endMetadataStar(0)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments())
+                handleType(int, null)
+                handleNoName())
+              endRecordTypeEntry()
+            endRecordType((, null, 2, false)
+          endTypeArguments(1, <, >)
+          handleType(List, null)
+        endTypeArguments(1, <, >)
+        handleType(List, null)
+      endTypeArguments(1, <, >)
+      handleType(List, null)
+      handleIdentifier(l3, topLevelVariableDeclaration)
+      handleNoFieldInitializer(;)
+    endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  endTopLevelDeclaration(List)
+  beginMetadataStar(List)
+  endMetadataStar(0)
+  beginTopLevelMember(List)
+    beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+      handleIdentifier(List, typeReference)
+      beginTypeArguments(<)
+        handleIdentifier(List, typeReference)
+        beginTypeArguments(<)
+          handleIdentifier(List, typeReference)
+          beginTypeArguments(<)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              beginRecordType(()
+                beginRecordTypeEntry()
+                  beginMetadataStar(int)
+                  endMetadataStar(0)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(,)
+                  handleType(int, null)
+                  handleNoName(,)
+                endRecordTypeEntry()
+                beginRecordTypeEntry()
+                  beginMetadataStar(int)
+                  endMetadataStar(0)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments())
+                  handleType(int, null)
+                  handleNoName())
+                endRecordTypeEntry()
+              endRecordType((, null, 2, false)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+          endTypeArguments(1, <, >)
+          handleType(List, null)
+        endTypeArguments(1, <, >)
+        handleType(List, null)
+      endTypeArguments(1, <, >)
+      handleType(List, null)
+      handleIdentifier(l4, topLevelVariableDeclaration)
+      handleNoFieldInitializer(;)
+    endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  endTopLevelDeclaration(List)
+  beginMetadataStar(List)
+  endMetadataStar(0)
+  beginTopLevelMember(List)
+    beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+      handleIdentifier(List, typeReference)
+      beginTypeArguments(<)
+        handleIdentifier(List, typeReference)
+        beginTypeArguments(<)
+          handleIdentifier(List, typeReference)
+          beginTypeArguments(<)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(List, typeReference)
+              beginTypeArguments(<)
+                beginRecordType(()
+                  beginRecordTypeEntry()
+                    beginMetadataStar(int)
+                    endMetadataStar(0)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(,)
+                    handleType(int, null)
+                    handleNoName(,)
+                  endRecordTypeEntry()
+                  beginRecordTypeEntry()
+                    beginMetadataStar(int)
+                    endMetadataStar(0)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments())
+                    handleType(int, null)
+                    handleNoName())
+                  endRecordTypeEntry()
+                endRecordType((, null, 2, false)
+              endTypeArguments(1, <, >)
+              handleType(List, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+          endTypeArguments(1, <, >)
+          handleType(List, null)
+        endTypeArguments(1, <, >)
+        handleType(List, null)
+      endTypeArguments(1, <, >)
+      handleType(List, null)
+      handleIdentifier(l5, topLevelVariableDeclaration)
+      handleNoFieldInitializer(;)
+    endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  endTopLevelDeclaration(List)
+  beginMetadataStar(List)
+  endMetadataStar(0)
+  beginTopLevelMember(List)
+    beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+      handleIdentifier(List, typeReference)
+      beginTypeArguments(<)
+        handleIdentifier(List, typeReference)
+        beginTypeArguments(<)
+          handleIdentifier(List, typeReference)
+          beginTypeArguments(<)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(List, typeReference)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  beginRecordType(()
+                    beginRecordTypeEntry()
+                      beginMetadataStar(int)
+                      endMetadataStar(0)
+                      handleIdentifier(int, typeReference)
+                      handleNoTypeArguments(,)
+                      handleType(int, null)
+                      handleNoName(,)
+                    endRecordTypeEntry()
+                    beginRecordTypeEntry()
+                      beginMetadataStar(int)
+                      endMetadataStar(0)
+                      handleIdentifier(int, typeReference)
+                      handleNoTypeArguments())
+                      handleType(int, null)
+                      handleNoName())
+                    endRecordTypeEntry()
+                  endRecordType((, null, 2, false)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleType(List, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+          endTypeArguments(1, <, >)
+          handleType(List, null)
+        endTypeArguments(1, <, >)
+        handleType(List, null)
+      endTypeArguments(1, <, >)
+      handleType(List, null)
+      handleIdentifier(l6, topLevelVariableDeclaration)
+      handleNoFieldInitializer(;)
+    endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  endTopLevelDeclaration(List)
+  beginMetadataStar(List)
+  endMetadataStar(0)
+  beginTopLevelMember(List)
+    beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+      handleIdentifier(List, typeReference)
+      beginTypeArguments(<)
+        handleIdentifier(List, typeReference)
+        beginTypeArguments(<)
+          handleIdentifier(List, typeReference)
+          beginTypeArguments(<)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(List, typeReference)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    beginRecordType(()
+                      beginRecordTypeEntry()
+                        beginMetadataStar(int)
+                        endMetadataStar(0)
+                        handleIdentifier(int, typeReference)
+                        handleNoTypeArguments(,)
+                        handleType(int, null)
+                        handleNoName(,)
+                      endRecordTypeEntry()
+                      beginRecordTypeEntry()
+                        beginMetadataStar(int)
+                        endMetadataStar(0)
+                        handleIdentifier(int, typeReference)
+                        handleNoTypeArguments())
+                        handleType(int, null)
+                        handleNoName())
+                      endRecordTypeEntry()
+                    endRecordType((, null, 2, false)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleType(List, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+          endTypeArguments(1, <, >)
+          handleType(List, null)
+        endTypeArguments(1, <, >)
+        handleType(List, null)
+      endTypeArguments(1, <, >)
+      handleType(List, null)
+      handleIdentifier(l7, topLevelVariableDeclaration)
+      handleNoFieldInitializer(;)
+    endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  endTopLevelDeclaration(List)
+  beginMetadataStar(List)
+  endMetadataStar(0)
+  beginTopLevelMember(List)
+    beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+      handleIdentifier(List, typeReference)
+      beginTypeArguments(<)
+        handleIdentifier(List, typeReference)
+        beginTypeArguments(<)
+          handleIdentifier(List, typeReference)
+          beginTypeArguments(<)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(List, typeReference)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(List, typeReference)
+                    beginTypeArguments(<)
+                      beginRecordType(()
+                        beginRecordTypeEntry()
+                          beginMetadataStar(int)
+                          endMetadataStar(0)
+                          handleIdentifier(int, typeReference)
+                          handleNoTypeArguments(,)
+                          handleType(int, null)
+                          handleNoName(,)
+                        endRecordTypeEntry()
+                        beginRecordTypeEntry()
+                          beginMetadataStar(int)
+                          endMetadataStar(0)
+                          handleIdentifier(int, typeReference)
+                          handleNoTypeArguments())
+                          handleType(int, null)
+                          handleNoName())
+                        endRecordTypeEntry()
+                      endRecordType((, null, 2, false)
+                    endTypeArguments(1, <, >)
+                    handleType(List, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleType(List, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+          endTypeArguments(1, <, >)
+          handleType(List, null)
+        endTypeArguments(1, <, >)
+        handleType(List, null)
+      endTypeArguments(1, <, >)
+      handleType(List, null)
+      handleIdentifier(l8, topLevelVariableDeclaration)
+      handleNoFieldInitializer(;)
+    endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  endTopLevelDeclaration(List)
+  beginMetadataStar(List)
+  endMetadataStar(0)
+  beginTopLevelMember(List)
+    beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+      handleIdentifier(List, typeReference)
+      beginTypeArguments(<)
+        handleIdentifier(List, typeReference)
+        beginTypeArguments(<)
+          handleIdentifier(List, typeReference)
+          beginTypeArguments(<)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(List, typeReference)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(List, typeReference)
+                    beginTypeArguments(<)
+                      handleIdentifier(List, typeReference)
+                      beginTypeArguments(<)
+                        beginRecordType(()
+                          beginRecordTypeEntry()
+                            beginMetadataStar(int)
+                            endMetadataStar(0)
+                            handleIdentifier(int, typeReference)
+                            handleNoTypeArguments(,)
+                            handleType(int, null)
+                            handleNoName(,)
+                          endRecordTypeEntry()
+                          beginRecordTypeEntry()
+                            beginMetadataStar(int)
+                            endMetadataStar(0)
+                            handleIdentifier(int, typeReference)
+                            handleNoTypeArguments())
+                            handleType(int, null)
+                            handleNoName())
+                          endRecordTypeEntry()
+                        endRecordType((, null, 2, false)
+                      endTypeArguments(1, <, >)
+                      handleType(List, null)
+                    endTypeArguments(1, <, >)
+                    handleType(List, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleType(List, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+          endTypeArguments(1, <, >)
+          handleType(List, null)
+        endTypeArguments(1, <, >)
+        handleType(List, null)
+      endTypeArguments(1, <, >)
+      handleType(List, null)
+      handleIdentifier(l9, topLevelVariableDeclaration)
+      handleNoFieldInitializer(;)
+    endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  endTopLevelDeclaration(List)
+  beginMetadataStar(List)
+  endMetadataStar(0)
+  beginTopLevelMember(List)
+    beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+      handleIdentifier(List, typeReference)
+      beginTypeArguments(<)
+        handleIdentifier(List, typeReference)
+        beginTypeArguments(<)
+          handleIdentifier(List, typeReference)
+          beginTypeArguments(<)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(List, typeReference)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(List, typeReference)
+                    beginTypeArguments(<)
+                      handleIdentifier(List, typeReference)
+                      beginTypeArguments(<)
+                        handleIdentifier(List, typeReference)
+                        beginTypeArguments(<)
+                          beginRecordType(()
+                            beginRecordTypeEntry()
+                              beginMetadataStar(int)
+                              endMetadataStar(0)
+                              handleIdentifier(int, typeReference)
+                              handleNoTypeArguments(,)
+                              handleType(int, null)
+                              handleNoName(,)
+                            endRecordTypeEntry()
+                            beginRecordTypeEntry()
+                              beginMetadataStar(int)
+                              endMetadataStar(0)
+                              handleIdentifier(int, typeReference)
+                              handleNoTypeArguments())
+                              handleType(int, null)
+                              handleNoName())
+                            endRecordTypeEntry()
+                          endRecordType((, null, 2, false)
+                        endTypeArguments(1, <, >)
+                        handleType(List, null)
+                      endTypeArguments(1, <, >)
+                      handleType(List, null)
+                    endTypeArguments(1, <, >)
+                    handleType(List, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleType(List, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+          endTypeArguments(1, <, >)
+          handleType(List, null)
+        endTypeArguments(1, <, >)
+        handleType(List, null)
+      endTypeArguments(1, <, >)
+      handleType(List, null)
+      handleIdentifier(l10, topLevelVariableDeclaration)
+      handleNoFieldInitializer(;)
+    endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  endTopLevelDeclaration()
+endCompilationUnit(10, )
diff --git a/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.intertwined.expect
new file mode 100644
index 0000000..dfe2f63
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.intertwined.expect
@@ -0,0 +1,651 @@
+parseUnit(List)
+  skipErrorTokens(List)
+  listener: beginCompilationUnit(List)
+  syntheticPreviousToken(List)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(List)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(List)
+      parseFields(, null, null, null, null, null, null, null, , Instance of 'ComplexTypeInfo', l1, DeclarationKind.TopLevel, null, false)
+        listener: beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, )
+        ensureIdentifier(, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        parseRecordType((, <)
+          listener: beginRecordType(()
+          parseRecordTypeField((, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(()
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleNoName(,)
+            listener: endRecordTypeEntry()
+          parseRecordTypeField(,, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(,)
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments())
+            listener: handleType(int, null)
+            listener: handleNoName())
+            listener: endRecordTypeEntry()
+          listener: endRecordType((, null, 2, false)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelVariableDeclaration, false)
+          listener: handleIdentifier(l1, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l1, l1, null, null, null, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  listener: endTopLevelDeclaration(List)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(List)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(List)
+      parseFields(;, null, null, null, null, null, null, null, ;, Instance of 'ComplexTypeInfo', l2, DeclarationKind.TopLevel, null, false)
+        listener: beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+        ensureIdentifier(;, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        parseRecordType((, <)
+          listener: beginRecordType(()
+          parseRecordTypeField((, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(()
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleNoName(,)
+            listener: endRecordTypeEntry()
+          parseRecordTypeField(,, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(,)
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments())
+            listener: handleType(int, null)
+            listener: handleNoName())
+            listener: endRecordTypeEntry()
+          listener: endRecordType((, null, 2, false)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelVariableDeclaration, false)
+          listener: handleIdentifier(l2, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l2, l2, null, null, null, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  listener: endTopLevelDeclaration(List)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(List)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(List)
+      parseFields(;, null, null, null, null, null, null, null, ;, Instance of 'ComplexTypeInfo', l3, DeclarationKind.TopLevel, null, false)
+        listener: beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+        ensureIdentifier(;, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        parseRecordType((, <)
+          listener: beginRecordType(()
+          parseRecordTypeField((, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(()
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleNoName(,)
+            listener: endRecordTypeEntry()
+          parseRecordTypeField(,, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(,)
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments())
+            listener: handleType(int, null)
+            listener: handleNoName())
+            listener: endRecordTypeEntry()
+          listener: endRecordType((, null, 2, false)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelVariableDeclaration, false)
+          listener: handleIdentifier(l3, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l3, l3, null, null, null, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  listener: endTopLevelDeclaration(List)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(List)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(List)
+      parseFields(;, null, null, null, null, null, null, null, ;, Instance of 'ComplexTypeInfo', l4, DeclarationKind.TopLevel, null, false)
+        listener: beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+        ensureIdentifier(;, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        parseRecordType((, <)
+          listener: beginRecordType(()
+          parseRecordTypeField((, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(()
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleNoName(,)
+            listener: endRecordTypeEntry()
+          parseRecordTypeField(,, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(,)
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments())
+            listener: handleType(int, null)
+            listener: handleNoName())
+            listener: endRecordTypeEntry()
+          listener: endRecordType((, null, 2, false)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelVariableDeclaration, false)
+          listener: handleIdentifier(l4, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l4, l4, null, null, null, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  listener: endTopLevelDeclaration(List)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(List)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(List)
+      parseFields(;, null, null, null, null, null, null, null, ;, Instance of 'ComplexTypeInfo', l5, DeclarationKind.TopLevel, null, false)
+        listener: beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+        ensureIdentifier(;, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        parseRecordType((, <)
+          listener: beginRecordType(()
+          parseRecordTypeField((, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(()
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleNoName(,)
+            listener: endRecordTypeEntry()
+          parseRecordTypeField(,, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(,)
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments())
+            listener: handleType(int, null)
+            listener: handleNoName())
+            listener: endRecordTypeEntry()
+          listener: endRecordType((, null, 2, false)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelVariableDeclaration, false)
+          listener: handleIdentifier(l5, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l5, l5, null, null, null, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  listener: endTopLevelDeclaration(List)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(List)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(List)
+      parseFields(;, null, null, null, null, null, null, null, ;, Instance of 'ComplexTypeInfo', l6, DeclarationKind.TopLevel, null, false)
+        listener: beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+        ensureIdentifier(;, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        parseRecordType((, <)
+          listener: beginRecordType(()
+          parseRecordTypeField((, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(()
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleNoName(,)
+            listener: endRecordTypeEntry()
+          parseRecordTypeField(,, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(,)
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments())
+            listener: handleType(int, null)
+            listener: handleNoName())
+            listener: endRecordTypeEntry()
+          listener: endRecordType((, null, 2, false)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelVariableDeclaration, false)
+          listener: handleIdentifier(l6, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l6, l6, null, null, null, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  listener: endTopLevelDeclaration(List)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(List)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(List)
+      parseFields(;, null, null, null, null, null, null, null, ;, Instance of 'ComplexTypeInfo', l7, DeclarationKind.TopLevel, null, false)
+        listener: beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+        ensureIdentifier(;, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        parseRecordType((, <)
+          listener: beginRecordType(()
+          parseRecordTypeField((, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(()
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleNoName(,)
+            listener: endRecordTypeEntry()
+          parseRecordTypeField(,, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(,)
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments())
+            listener: handleType(int, null)
+            listener: handleNoName())
+            listener: endRecordTypeEntry()
+          listener: endRecordType((, null, 2, false)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelVariableDeclaration, false)
+          listener: handleIdentifier(l7, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l7, l7, null, null, null, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  listener: endTopLevelDeclaration(List)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(List)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(List)
+      parseFields(;, null, null, null, null, null, null, null, ;, Instance of 'ComplexTypeInfo', l8, DeclarationKind.TopLevel, null, false)
+        listener: beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+        ensureIdentifier(;, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        parseRecordType((, <)
+          listener: beginRecordType(()
+          parseRecordTypeField((, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(()
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleNoName(,)
+            listener: endRecordTypeEntry()
+          parseRecordTypeField(,, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(,)
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments())
+            listener: handleType(int, null)
+            listener: handleNoName())
+            listener: endRecordTypeEntry()
+          listener: endRecordType((, null, 2, false)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelVariableDeclaration, false)
+          listener: handleIdentifier(l8, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l8, l8, null, null, null, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  listener: endTopLevelDeclaration(List)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(List)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(List)
+      parseFields(;, null, null, null, null, null, null, null, ;, Instance of 'ComplexTypeInfo', l9, DeclarationKind.TopLevel, null, false)
+        listener: beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+        ensureIdentifier(;, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        parseRecordType((, <)
+          listener: beginRecordType(()
+          parseRecordTypeField((, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(()
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleNoName(,)
+            listener: endRecordTypeEntry()
+          parseRecordTypeField(,, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(,)
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments())
+            listener: handleType(int, null)
+            listener: handleNoName())
+            listener: endRecordTypeEntry()
+          listener: endRecordType((, null, 2, false)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelVariableDeclaration, false)
+          listener: handleIdentifier(l9, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l9, l9, null, null, null, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  listener: endTopLevelDeclaration(List)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(List)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(List)
+      parseFields(;, null, null, null, null, null, null, null, ;, Instance of 'ComplexTypeInfo', l10, DeclarationKind.TopLevel, null, false)
+        listener: beginFields(DeclarationKind.TopLevel, null, null, null, null, null, null, null, ;)
+        ensureIdentifier(;, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        parseRecordType((, <)
+          listener: beginRecordType(()
+          parseRecordTypeField((, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(()
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleNoName(,)
+            listener: endRecordTypeEntry()
+          parseRecordTypeField(,, identifierIsOptional: true)
+            listener: beginRecordTypeEntry()
+            parseMetadataStar(,)
+              listener: beginMetadataStar(int)
+              listener: endMetadataStar(0)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments())
+            listener: handleType(int, null)
+            listener: handleNoName())
+            listener: endRecordTypeEntry()
+          listener: endRecordType((, null, 2, false)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelVariableDeclaration, false)
+          listener: handleIdentifier(l10, topLevelVariableDeclaration)
+        parseFieldInitializerOpt(l10, l10, null, null, null, null, null, DeclarationKind.TopLevel, null)
+          listener: handleNoFieldInitializer(;)
+        listener: endTopLevelFields(null, null, null, null, null, 1, List, ;)
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(List)
+  listener: endCompilationUnit(10, )
diff --git a/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.parser.expect b/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.parser.expect
new file mode 100644
index 0000000..2c47f1e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.parser.expect
@@ -0,0 +1,23 @@
+NOTICE: Stream was rewritten by parser!
+
+List<(int, int)> l1;
+List<List<(int, int)>> l2;
+List<List<List<(int, int)>>> l3;
+List<List<List<List<(int, int)>>>> l4;
+List<List<List<List<List<(int, int)>>>>> l5;
+List<List<List<List<List<List<(int, int)>>>>>> l6;
+List<List<List<List<List<List<List<(int, int)>>>>>>> l7;
+List<List<List<List<List<List<List<List<(int, int)>>>>>>>> l8;
+List<List<List<List<List<List<List<List<List<(int, int)>>>>>>>>> l9;
+List<List<List<List<List<List<List<List<List<List<(int, int)>>>>>>>>>> l10;
+
+List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken] l1[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken]>[SimpleToken] l2[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken] l3[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken] l4[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken] l5[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken] l6[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken] l7[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken] l8[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken] l9[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken]>[SimpleToken] l10[StringToken];[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.scanner.expect b/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.scanner.expect
new file mode 100644
index 0000000..2735973
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/nested_generics_with_records.dart.scanner.expect
@@ -0,0 +1,21 @@
+List<(int, int)> l1;
+List<List<(int, int)>> l2;
+List<List<List<(int, int)>>> l3;
+List<List<List<List<(int, int)>>>> l4;
+List<List<List<List<List<(int, int)>>>>> l5;
+List<List<List<List<List<List<(int, int)>>>>>> l6;
+List<List<List<List<List<List<List<(int, int)>>>>>>> l7;
+List<List<List<List<List<List<List<List<(int, int)>>>>>>>> l8;
+List<List<List<List<List<List<List<List<List<(int, int)>>>>>>>>> l9;
+List<List<List<List<List<List<List<List<List<List<(int, int)>>>>>>>>>> l10;
+
+List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>[SimpleToken] l1[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>>[SimpleToken] l2[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>>>[SimpleToken] l3[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>>>[SimpleToken]>[SimpleToken] l4[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>>>[SimpleToken]>>[SimpleToken] l5[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>>>[SimpleToken]>>>[SimpleToken] l6[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>>>[SimpleToken]>>>[SimpleToken]>[SimpleToken] l7[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>>>[SimpleToken]>>>[SimpleToken]>>[SimpleToken] l8[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>>>[SimpleToken]>>>[SimpleToken]>>>[SimpleToken] l9[StringToken];[SimpleToken]
+List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]>>>[SimpleToken]>>>[SimpleToken]>>>[SimpleToken]>[SimpleToken] l10[StringToken];[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/record_literal_01.dart b/pkg/front_end/parser_testcases/record/record_literal_01.dart
index f32a178..5f929a9 100644
--- a/pkg/front_end/parser_testcases/record/record_literal_01.dart
+++ b/pkg/front_end/parser_testcases/record/record_literal_01.dart
@@ -1,3 +1,8 @@
 void foo() {
-  var record = (1, 2, a: 3, b: 4);
+  var record1 = (1, 2, a: 3, b: 4);
+  var record2 = (1, a: 2, 3, b: 4);
+  print(record2.$0); // Prints "1".
+  print(record2.a);  // Prints "2".
+  print(record2.$1); // Prints "3".
+  print(record2.b);  // Prints "4".
 }
diff --git a/pkg/front_end/parser_testcases/record/record_literal_01.dart.expect b/pkg/front_end/parser_testcases/record/record_literal_01.dart.expect
index 8e0987f..8ce4d14 100644
--- a/pkg/front_end/parser_testcases/record/record_literal_01.dart.expect
+++ b/pkg/front_end/parser_testcases/record/record_literal_01.dart.expect
@@ -13,9 +13,9 @@
         beginMetadataStar(var)
         endMetadataStar(0)
         handleNoType(var)
-        beginVariablesDeclaration(record, null, var)
-          handleIdentifier(record, localVariableDeclaration)
-          beginInitializedIdentifier(record)
+        beginVariablesDeclaration(record1, null, var)
+          handleIdentifier(record1, localVariableDeclaration)
+          beginInitializedIdentifier(record1)
             beginVariableInitializer(=)
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(1)
@@ -26,11 +26,91 @@
                 handleIdentifier(b, namedRecordFieldReference)
                 handleLiteralInt(4)
                 handleNamedRecordField(:)
-              endRecordLiteral((, 4)
+              endRecordLiteral((, 4, null)
             endVariableInitializer(=)
-          endInitializedIdentifier(record)
+          endInitializedIdentifier(record1)
         endVariablesDeclaration(1, ;)
-      endBlockFunctionBody(1, {, })
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(record2, null, var)
+          handleIdentifier(record2, localVariableDeclaration)
+          beginInitializedIdentifier(record2)
+            beginVariableInitializer(=)
+              beginParenthesizedExpressionOrRecordLiteral(()
+                handleLiteralInt(1)
+                handleIdentifier(a, namedRecordFieldReference)
+                handleLiteralInt(2)
+                handleNamedRecordField(:)
+                handleLiteralInt(3)
+                handleIdentifier(b, namedRecordFieldReference)
+                handleLiteralInt(4)
+                handleNamedRecordField(:)
+              endRecordLiteral((, 4, null)
+            endVariableInitializer(=)
+          endInitializedIdentifier(record2)
+        endVariablesDeclaration(1, ;)
+        handleIdentifier(print, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(record2, expression)
+          handleNoTypeArguments(.)
+          handleNoArguments(.)
+          handleSend(record2, .)
+          handleIdentifier($0, expressionContinuation)
+          handleNoTypeArguments())
+          handleNoArguments())
+          handleSend($0, ))
+          handleEndingBinaryExpression(.)
+        endArguments(1, (, ))
+        handleSend(print, ;)
+        handleExpressionStatement(;)
+        handleIdentifier(print, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(record2, expression)
+          handleNoTypeArguments(.)
+          handleNoArguments(.)
+          handleSend(record2, .)
+          handleIdentifier(a, expressionContinuation)
+          handleNoTypeArguments())
+          handleNoArguments())
+          handleSend(a, ))
+          handleEndingBinaryExpression(.)
+        endArguments(1, (, ))
+        handleSend(print, ;)
+        handleExpressionStatement(;)
+        handleIdentifier(print, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(record2, expression)
+          handleNoTypeArguments(.)
+          handleNoArguments(.)
+          handleSend(record2, .)
+          handleIdentifier($1, expressionContinuation)
+          handleNoTypeArguments())
+          handleNoArguments())
+          handleSend($1, ))
+          handleEndingBinaryExpression(.)
+        endArguments(1, (, ))
+        handleSend(print, ;)
+        handleExpressionStatement(;)
+        handleIdentifier(print, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleIdentifier(record2, expression)
+          handleNoTypeArguments(.)
+          handleNoArguments(.)
+          handleSend(record2, .)
+          handleIdentifier(b, expressionContinuation)
+          handleNoTypeArguments())
+          handleNoArguments())
+          handleSend(b, ))
+          handleEndingBinaryExpression(.)
+        endArguments(1, (, ))
+        handleSend(print, ;)
+        handleExpressionStatement(;)
+      endBlockFunctionBody(6, {, })
     endTopLevelMethod(void, null, })
   endTopLevelDeclaration()
 endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/record/record_literal_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_literal_01.dart.intertwined.expect
index bce8911..4cd648f 100644
--- a/pkg/front_end/parser_testcases/record/record_literal_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/record/record_literal_01.dart.intertwined.expect
@@ -29,24 +29,24 @@
           parseStatement({)
             parseStatementX({)
               parseExpressionStatementOrDeclarationAfterModifiers(var, {, null, var, null, false)
-                looksLikeLocalFunction(record)
+                looksLikeLocalFunction(record1)
                 listener: beginMetadataStar(var)
                 listener: endMetadataStar(0)
                 listener: handleNoType(var)
-                listener: beginVariablesDeclaration(record, null, var)
+                listener: beginVariablesDeclaration(record1, null, var)
                 parseVariablesDeclarationRest(var, true)
                   parseOptionallyInitializedIdentifier(var)
                     ensureIdentifier(var, localVariableDeclaration)
-                      listener: handleIdentifier(record, localVariableDeclaration)
-                    listener: beginInitializedIdentifier(record)
-                    parseVariableInitializerOpt(record)
+                      listener: handleIdentifier(record1, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(record1)
+                    parseVariableInitializerOpt(record1)
                       listener: beginVariableInitializer(=)
                       parseExpression(=)
                         parsePrecedenceExpression(=, 1, true)
                           parseUnaryExpression(=, true)
                             parsePrimary(=, expression)
                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                parseParenthesizedExpressionOrRecordLiteral(=)
+                                parseParenthesizedExpressionOrRecordLiteral(=, null)
                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                   parseExpression(()
                                     parsePrecedenceExpression((, 1, true)
@@ -79,13 +79,268 @@
                                             listener: handleLiteralInt(4)
                                   listener: handleNamedRecordField(:)
                                   ensureCloseParen(4, ()
-                                  listener: endRecordLiteral((, 4)
+                                  listener: endRecordLiteral((, 4, null)
                       listener: endVariableInitializer(=)
-                    listener: endInitializedIdentifier(record)
+                    listener: endInitializedIdentifier(record1)
                   ensureSemicolon())
                   listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(record2)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(record2, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(record2, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(record2)
+                    parseVariableInitializerOpt(record2)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
+                                parseParenthesizedExpressionOrRecordLiteral(=, null)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseLiteralInt(()
+                                            listener: handleLiteralInt(1)
+                                  ensureIdentifier(,, namedRecordFieldReference)
+                                    listener: handleIdentifier(a, namedRecordFieldReference)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralInt(:)
+                                            listener: handleLiteralInt(2)
+                                  listener: handleNamedRecordField(:)
+                                  parseExpression(,)
+                                    parsePrecedenceExpression(,, 1, true)
+                                      parseUnaryExpression(,, true)
+                                        parsePrimary(,, expression)
+                                          parseLiteralInt(,)
+                                            listener: handleLiteralInt(3)
+                                  ensureIdentifier(,, namedRecordFieldReference)
+                                    listener: handleIdentifier(b, namedRecordFieldReference)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralInt(:)
+                                            listener: handleLiteralInt(4)
+                                  listener: handleNamedRecordField(:)
+                                  ensureCloseParen(4, ()
+                                  listener: endRecordLiteral((, 4, null)
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(record2)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, print)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(print)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(;, expression)
+                              isNextIdentifier(;)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(print, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(print)
+                                parseArguments(print)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                isNextIdentifier(()
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(record2, expression)
+                                                listener: handleNoTypeArguments(.)
+                                                parseArgumentsOpt(record2)
+                                                  listener: handleNoArguments(.)
+                                                listener: handleSend(record2, .)
+                                        parsePrimary(., expressionContinuation)
+                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                            parseSend(., expressionContinuation)
+                                              isNextIdentifier(.)
+                                              ensureIdentifier(., expressionContinuation)
+                                                listener: handleIdentifier($0, expressionContinuation)
+                                              listener: handleNoTypeArguments())
+                                              parseArgumentsOpt($0)
+                                                listener: handleNoArguments())
+                                              listener: handleSend($0, ))
+                                        listener: handleEndingBinaryExpression(.)
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(print, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, print)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(print)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(;, expression)
+                              isNextIdentifier(;)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(print, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(print)
+                                parseArguments(print)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                isNextIdentifier(()
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(record2, expression)
+                                                listener: handleNoTypeArguments(.)
+                                                parseArgumentsOpt(record2)
+                                                  listener: handleNoArguments(.)
+                                                listener: handleSend(record2, .)
+                                        parsePrimary(., expressionContinuation)
+                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                            parseSend(., expressionContinuation)
+                                              isNextIdentifier(.)
+                                              ensureIdentifier(., expressionContinuation)
+                                                listener: handleIdentifier(a, expressionContinuation)
+                                              listener: handleNoTypeArguments())
+                                              parseArgumentsOpt(a)
+                                                listener: handleNoArguments())
+                                              listener: handleSend(a, ))
+                                        listener: handleEndingBinaryExpression(.)
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(print, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, print)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(print)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(;, expression)
+                              isNextIdentifier(;)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(print, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(print)
+                                parseArguments(print)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                isNextIdentifier(()
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(record2, expression)
+                                                listener: handleNoTypeArguments(.)
+                                                parseArgumentsOpt(record2)
+                                                  listener: handleNoArguments(.)
+                                                listener: handleSend(record2, .)
+                                        parsePrimary(., expressionContinuation)
+                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                            parseSend(., expressionContinuation)
+                                              isNextIdentifier(.)
+                                              ensureIdentifier(., expressionContinuation)
+                                                listener: handleIdentifier($1, expressionContinuation)
+                                              listener: handleNoTypeArguments())
+                                              parseArgumentsOpt($1)
+                                                listener: handleNoArguments())
+                                              listener: handleSend($1, ))
+                                        listener: handleEndingBinaryExpression(.)
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(print, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, print)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(print)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(;, expression)
+                              isNextIdentifier(;)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(print, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(print)
+                                parseArguments(print)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                isNextIdentifier(()
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(record2, expression)
+                                                listener: handleNoTypeArguments(.)
+                                                parseArgumentsOpt(record2)
+                                                  listener: handleNoArguments(.)
+                                                listener: handleSend(record2, .)
+                                        parsePrimary(., expressionContinuation)
+                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                            parseSend(., expressionContinuation)
+                                              isNextIdentifier(.)
+                                              ensureIdentifier(., expressionContinuation)
+                                                listener: handleIdentifier(b, expressionContinuation)
+                                              listener: handleNoTypeArguments())
+                                              parseArgumentsOpt(b)
+                                                listener: handleNoArguments())
+                                              listener: handleSend(b, ))
+                                        listener: handleEndingBinaryExpression(.)
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(print, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
           notEofOrValue(}, })
-          listener: endBlockFunctionBody(1, {, })
+          listener: endBlockFunctionBody(6, {, })
         listener: endTopLevelMethod(void, null, })
   listener: endTopLevelDeclaration()
   reportAllErrorTokens(void)
diff --git a/pkg/front_end/parser_testcases/record/record_literal_01.dart.parser.expect b/pkg/front_end/parser_testcases/record/record_literal_01.dart.parser.expect
index 500ce14..53d2b1d 100644
--- a/pkg/front_end/parser_testcases/record/record_literal_01.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/record/record_literal_01.dart.parser.expect
@@ -1,9 +1,19 @@
 void foo() {
-var record = (1, 2, a: 3, b: 4);
+var record1 = (1, 2, a: 3, b: 4);
+var record2 = (1, a: 2, 3, b: 4);
+print(record2.$0);
+print(record2.a);
+print(record2.$1);
+print(record2.b);
 }
 
 
 void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
-var[KeywordToken] record[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] 2[StringToken],[SimpleToken] a[StringToken]:[SimpleToken] 3[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 4[StringToken])[SimpleToken];[SimpleToken]
+var[KeywordToken] record1[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] 2[StringToken],[SimpleToken] a[StringToken]:[SimpleToken] 3[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 4[StringToken])[SimpleToken];[SimpleToken]
+var[KeywordToken] record2[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] a[StringToken]:[SimpleToken] 2[StringToken],[SimpleToken] 3[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 4[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]record2[StringToken].[SimpleToken]$0[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]record2[StringToken].[SimpleToken]a[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]record2[StringToken].[SimpleToken]$1[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]record2[StringToken].[SimpleToken]b[StringToken])[SimpleToken];[SimpleToken]
 }[SimpleToken]
 [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/record_literal_01.dart.scanner.expect b/pkg/front_end/parser_testcases/record/record_literal_01.dart.scanner.expect
index 500ce14..53d2b1d 100644
--- a/pkg/front_end/parser_testcases/record/record_literal_01.dart.scanner.expect
+++ b/pkg/front_end/parser_testcases/record/record_literal_01.dart.scanner.expect
@@ -1,9 +1,19 @@
 void foo() {
-var record = (1, 2, a: 3, b: 4);
+var record1 = (1, 2, a: 3, b: 4);
+var record2 = (1, a: 2, 3, b: 4);
+print(record2.$0);
+print(record2.a);
+print(record2.$1);
+print(record2.b);
 }
 
 
 void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
-var[KeywordToken] record[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] 2[StringToken],[SimpleToken] a[StringToken]:[SimpleToken] 3[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 4[StringToken])[SimpleToken];[SimpleToken]
+var[KeywordToken] record1[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] 2[StringToken],[SimpleToken] a[StringToken]:[SimpleToken] 3[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 4[StringToken])[SimpleToken];[SimpleToken]
+var[KeywordToken] record2[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] a[StringToken]:[SimpleToken] 2[StringToken],[SimpleToken] 3[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 4[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]record2[StringToken].[SimpleToken]$0[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]record2[StringToken].[SimpleToken]a[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]record2[StringToken].[SimpleToken]$1[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]record2[StringToken].[SimpleToken]b[StringToken])[SimpleToken];[SimpleToken]
 }[SimpleToken]
 [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/record_literal_02.dart.expect b/pkg/front_end/parser_testcases/record/record_literal_02.dart.expect
index 30f102a..6958848 100644
--- a/pkg/front_end/parser_testcases/record/record_literal_02.dart.expect
+++ b/pkg/front_end/parser_testcases/record/record_literal_02.dart.expect
@@ -14,7 +14,7 @@
           handleLiteralInt(42)
           handleLiteralInt(42)
           handleLiteralInt(42)
-        endRecordLiteral((, 3)
+        endRecordLiteral((, 3, null)
         handleExpressionStatement(;)
         beginParenthesizedExpressionOrRecordLiteral(()
           handleIdentifier(foo, namedRecordFieldReference)
@@ -27,15 +27,15 @@
           handleIdentifier(baz, namedRecordFieldReference)
           handleLiteralInt(42)
           handleNamedRecordField(:)
-        endRecordLiteral((, 4)
+        endRecordLiteral((, 4, null)
         handleExpressionStatement(;)
         beginParenthesizedExpressionOrRecordLiteral(()
           beginParenthesizedExpressionOrRecordLiteral(()
             handleLiteralInt(42)
             handleLiteralInt(42)
-          endRecordLiteral((, 2)
+          endRecordLiteral((, 2, null)
           handleLiteralInt(42)
-        endRecordLiteral((, 2)
+        endRecordLiteral((, 2, null)
         handleExpressionStatement(;)
         beginParenthesizedExpressionOrRecordLiteral(()
           handleNoTypeVariables(()
@@ -61,7 +61,7 @@
             handleExpressionFunctionBody(=>, null)
           endFunctionExpression((, ,)
           handleLiteralInt(42)
-        endRecordLiteral((, 2)
+        endRecordLiteral((, 2, null)
         handleExpressionStatement(;)
       endBlockFunctionBody(4, {, })
     endTopLevelMethod(void, null, })
diff --git a/pkg/front_end/parser_testcases/record/record_literal_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_literal_02.dart.intertwined.expect
index a44d3f8f..59d7a9f 100644
--- a/pkg/front_end/parser_testcases/record/record_literal_02.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/record/record_literal_02.dart.intertwined.expect
@@ -37,7 +37,7 @@
                         parseUnaryExpression({, true)
                           parsePrimary({, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral({)
-                              parseParenthesizedExpressionOrRecordLiteral({)
+                              parseParenthesizedExpressionOrRecordLiteral({, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -58,7 +58,7 @@
                                         parseLiteralInt(,)
                                           listener: handleLiteralInt(42)
                                 ensureCloseParen(,, ()
-                                listener: endRecordLiteral((, 3)
+                                listener: endRecordLiteral((, 3, null)
                     ensureSemicolon())
                     listener: handleExpressionStatement(;)
           notEofOrValue(}, ()
@@ -73,7 +73,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 ensureIdentifier((, namedRecordFieldReference)
                                   listener: handleIdentifier(foo, namedRecordFieldReference)
@@ -109,7 +109,7 @@
                                           listener: handleLiteralInt(42)
                                 listener: handleNamedRecordField(:)
                                 ensureCloseParen(,, ()
-                                listener: endRecordLiteral((, 4)
+                                listener: endRecordLiteral((, 4, null)
                     ensureSemicolon())
                     listener: handleExpressionStatement(;)
           notEofOrValue(}, ()
@@ -124,14 +124,14 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
                                     parseUnaryExpression((, true)
                                       parsePrimary((, expression)
                                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                          parseParenthesizedExpressionOrRecordLiteral(()
+                                          parseParenthesizedExpressionOrRecordLiteral((, null)
                                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                                             parseExpression(()
                                               parsePrecedenceExpression((, 1, true)
@@ -146,7 +146,7 @@
                                                     parseLiteralInt(,)
                                                       listener: handleLiteralInt(42)
                                             ensureCloseParen(42, ()
-                                            listener: endRecordLiteral((, 2)
+                                            listener: endRecordLiteral((, 2, null)
                                 parseExpression(,)
                                   parsePrecedenceExpression(,, 1, true)
                                     parseUnaryExpression(,, true)
@@ -154,7 +154,7 @@
                                         parseLiteralInt(,)
                                           listener: handleLiteralInt(42)
                                 ensureCloseParen(42, ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionStatement(;)
           notEofOrValue(}, ()
@@ -169,7 +169,7 @@
                         parseUnaryExpression(;, true)
                           parsePrimary(;, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(;)
-                              parseParenthesizedExpressionOrRecordLiteral(;)
+                              parseParenthesizedExpressionOrRecordLiteral(;, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -225,7 +225,7 @@
                                         parseLiteralInt(,)
                                           listener: handleLiteralInt(42)
                                 ensureCloseParen(42, ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionStatement(;)
           notEofOrValue(}, })
diff --git a/pkg/front_end/parser_testcases/record/record_literal_03.dart b/pkg/front_end/parser_testcases/record/record_literal_03.dart
new file mode 100644
index 0000000..a3312a6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_literal_03.dart
@@ -0,0 +1,13 @@
+void foo() {
+  // Record: 1 record entry with trailing comma.
+  var r1 = (42, );
+
+  // Record: 1 named record entry without trailing comma.
+  var r2 = (hello: 42);
+
+  // Record: 1 named record entry with trailing comma.
+  var r3 = (hello: 42, );
+
+  // Not records: In parenthesis without trailing comma.
+  var r4 = (42);
+}
diff --git a/pkg/front_end/parser_testcases/record/record_literal_03.dart.expect b/pkg/front_end/parser_testcases/record/record_literal_03.dart.expect
new file mode 100644
index 0000000..6c27770
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_literal_03.dart.expect
@@ -0,0 +1,72 @@
+beginCompilationUnit(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(r1, null, var)
+          handleIdentifier(r1, localVariableDeclaration)
+          beginInitializedIdentifier(r1)
+            beginVariableInitializer(=)
+              beginParenthesizedExpressionOrRecordLiteral(()
+                handleLiteralInt(42)
+              endRecordLiteral((, 1, null)
+            endVariableInitializer(=)
+          endInitializedIdentifier(r1)
+        endVariablesDeclaration(1, ;)
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(r2, null, var)
+          handleIdentifier(r2, localVariableDeclaration)
+          beginInitializedIdentifier(r2)
+            beginVariableInitializer(=)
+              beginParenthesizedExpressionOrRecordLiteral(()
+                handleIdentifier(hello, namedRecordFieldReference)
+                handleLiteralInt(42)
+                handleNamedRecordField(:)
+              endRecordLiteral((, 1, null)
+            endVariableInitializer(=)
+          endInitializedIdentifier(r2)
+        endVariablesDeclaration(1, ;)
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(r3, null, var)
+          handleIdentifier(r3, localVariableDeclaration)
+          beginInitializedIdentifier(r3)
+            beginVariableInitializer(=)
+              beginParenthesizedExpressionOrRecordLiteral(()
+                handleIdentifier(hello, namedRecordFieldReference)
+                handleLiteralInt(42)
+                handleNamedRecordField(:)
+              endRecordLiteral((, 1, null)
+            endVariableInitializer(=)
+          endInitializedIdentifier(r3)
+        endVariablesDeclaration(1, ;)
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(r4, null, var)
+          handleIdentifier(r4, localVariableDeclaration)
+          beginInitializedIdentifier(r4)
+            beginVariableInitializer(=)
+              beginParenthesizedExpressionOrRecordLiteral(()
+                handleLiteralInt(42)
+              endParenthesizedExpression(()
+            endVariableInitializer(=)
+          endInitializedIdentifier(r4)
+        endVariablesDeclaration(1, ;)
+      endBlockFunctionBody(4, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/record/record_literal_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_literal_03.dart.intertwined.expect
new file mode 100644
index 0000000..31accb9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_literal_03.dart.intertwined.expect
@@ -0,0 +1,179 @@
+parseUnit(void)
+  skipErrorTokens(void)
+  listener: beginCompilationUnit(void)
+  syntheticPreviousToken(void)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, foo, false)
+        listener: beginTopLevelMethod(, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, var)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, {, null, var, null, false)
+                looksLikeLocalFunction(r1)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(r1, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(r1, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r1)
+                    parseVariableInitializerOpt(r1)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
+                                parseParenthesizedExpressionOrRecordLiteral(=, null)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseLiteralInt(()
+                                            listener: handleLiteralInt(42)
+                                  ensureCloseParen(,, ()
+                                  listener: endRecordLiteral((, 1, null)
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(r1)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(r2)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(r2, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(r2, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r2)
+                    parseVariableInitializerOpt(r2)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
+                                parseParenthesizedExpressionOrRecordLiteral(=, null)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  ensureIdentifier((, namedRecordFieldReference)
+                                    listener: handleIdentifier(hello, namedRecordFieldReference)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralInt(:)
+                                            listener: handleLiteralInt(42)
+                                  listener: handleNamedRecordField(:)
+                                  ensureCloseParen(42, ()
+                                  listener: endRecordLiteral((, 1, null)
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(r2)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(r3)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(r3, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(r3, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r3)
+                    parseVariableInitializerOpt(r3)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
+                                parseParenthesizedExpressionOrRecordLiteral(=, null)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  ensureIdentifier((, namedRecordFieldReference)
+                                    listener: handleIdentifier(hello, namedRecordFieldReference)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralInt(:)
+                                            listener: handleLiteralInt(42)
+                                  listener: handleNamedRecordField(:)
+                                  ensureCloseParen(,, ()
+                                  listener: endRecordLiteral((, 1, null)
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(r3)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(r4)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(r4, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(r4, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r4)
+                    parseVariableInitializerOpt(r4)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
+                                parseParenthesizedExpressionOrRecordLiteral(=, null)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseLiteralInt(()
+                                            listener: handleLiteralInt(42)
+                                  ensureCloseParen(42, ()
+                                  listener: endParenthesizedExpression(()
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(r4)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(4, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(void)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/record/record_literal_03.dart.parser.expect b/pkg/front_end/parser_testcases/record/record_literal_03.dart.parser.expect
new file mode 100644
index 0000000..c9f9b47
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_literal_03.dart.parser.expect
@@ -0,0 +1,29 @@
+void foo() {
+
+var r1 = (42, );
+
+
+var r2 = (hello: 42);
+
+
+var r3 = (hello: 42, );
+
+
+var r4 = (42);
+}
+
+
+void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+
+var[KeywordToken] r1[StringToken] =[SimpleToken] ([BeginToken]42[StringToken],[SimpleToken] )[SimpleToken];[SimpleToken]
+
+
+var[KeywordToken] r2[StringToken] =[SimpleToken] ([BeginToken]hello[StringToken]:[SimpleToken] 42[StringToken])[SimpleToken];[SimpleToken]
+
+
+var[KeywordToken] r3[StringToken] =[SimpleToken] ([BeginToken]hello[StringToken]:[SimpleToken] 42[StringToken],[SimpleToken] )[SimpleToken];[SimpleToken]
+
+
+var[KeywordToken] r4[StringToken] =[SimpleToken] ([BeginToken]42[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/record_literal_03.dart.scanner.expect b/pkg/front_end/parser_testcases/record/record_literal_03.dart.scanner.expect
new file mode 100644
index 0000000..c9f9b47
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_literal_03.dart.scanner.expect
@@ -0,0 +1,29 @@
+void foo() {
+
+var r1 = (42, );
+
+
+var r2 = (hello: 42);
+
+
+var r3 = (hello: 42, );
+
+
+var r4 = (42);
+}
+
+
+void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+
+var[KeywordToken] r1[StringToken] =[SimpleToken] ([BeginToken]42[StringToken],[SimpleToken] )[SimpleToken];[SimpleToken]
+
+
+var[KeywordToken] r2[StringToken] =[SimpleToken] ([BeginToken]hello[StringToken]:[SimpleToken] 42[StringToken])[SimpleToken];[SimpleToken]
+
+
+var[KeywordToken] r3[StringToken] =[SimpleToken] ([BeginToken]hello[StringToken]:[SimpleToken] 42[StringToken],[SimpleToken] )[SimpleToken];[SimpleToken]
+
+
+var[KeywordToken] r4[StringToken] =[SimpleToken] ([BeginToken]42[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/record_literal_04.dart b/pkg/front_end/parser_testcases/record/record_literal_04.dart
new file mode 100644
index 0000000..80a2b50
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_literal_04.dart
@@ -0,0 +1,17 @@
+void foo() {
+  // OK.
+  var r1 = const (42, );
+  var r2 = const (1, 2, a: 3, b: 4);
+  var r3 = const (1, a: 2, 3, b: 4);
+  var r4 = const (hello: 42);
+
+  // Error: Const makes it a record (I guess), but there's no trailing comma.
+  var r5 = const (42);
+
+  // Error: A record needs at least one element.
+  var r6 = const ();
+}
+
+void bar({dynamic record1 = (42, 42), dynamic record2 = const (42, 42)}) {
+  // Default record.
+}
diff --git a/pkg/front_end/parser_testcases/record/record_literal_04.dart.expect b/pkg/front_end/parser_testcases/record/record_literal_04.dart.expect
new file mode 100644
index 0000000..d56b116
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_literal_04.dart.expect
@@ -0,0 +1,181 @@
+Problems reported:
+
+parser/record/record_literal_04:9:21: Record literal with one field requires a trailing comma.
+  var r5 = const (42);
+                    ^
+
+parser/record/record_literal_04:12:19: Record literal can't be empty.
+  var r6 = const ();
+                  ^
+
+beginCompilationUnit(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(r1, null, var)
+          handleIdentifier(r1, localVariableDeclaration)
+          beginInitializedIdentifier(r1)
+            beginVariableInitializer(=)
+              beginConstLiteral(()
+                beginParenthesizedExpressionOrRecordLiteral(()
+                  handleLiteralInt(42)
+                endRecordLiteral((, 1, const)
+              endConstLiteral(;)
+            endVariableInitializer(=)
+          endInitializedIdentifier(r1)
+        endVariablesDeclaration(1, ;)
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(r2, null, var)
+          handleIdentifier(r2, localVariableDeclaration)
+          beginInitializedIdentifier(r2)
+            beginVariableInitializer(=)
+              beginConstLiteral(()
+                beginParenthesizedExpressionOrRecordLiteral(()
+                  handleLiteralInt(1)
+                  handleLiteralInt(2)
+                  handleIdentifier(a, namedRecordFieldReference)
+                  handleLiteralInt(3)
+                  handleNamedRecordField(:)
+                  handleIdentifier(b, namedRecordFieldReference)
+                  handleLiteralInt(4)
+                  handleNamedRecordField(:)
+                endRecordLiteral((, 4, const)
+              endConstLiteral(;)
+            endVariableInitializer(=)
+          endInitializedIdentifier(r2)
+        endVariablesDeclaration(1, ;)
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(r3, null, var)
+          handleIdentifier(r3, localVariableDeclaration)
+          beginInitializedIdentifier(r3)
+            beginVariableInitializer(=)
+              beginConstLiteral(()
+                beginParenthesizedExpressionOrRecordLiteral(()
+                  handleLiteralInt(1)
+                  handleIdentifier(a, namedRecordFieldReference)
+                  handleLiteralInt(2)
+                  handleNamedRecordField(:)
+                  handleLiteralInt(3)
+                  handleIdentifier(b, namedRecordFieldReference)
+                  handleLiteralInt(4)
+                  handleNamedRecordField(:)
+                endRecordLiteral((, 4, const)
+              endConstLiteral(;)
+            endVariableInitializer(=)
+          endInitializedIdentifier(r3)
+        endVariablesDeclaration(1, ;)
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(r4, null, var)
+          handleIdentifier(r4, localVariableDeclaration)
+          beginInitializedIdentifier(r4)
+            beginVariableInitializer(=)
+              beginConstLiteral(()
+                beginParenthesizedExpressionOrRecordLiteral(()
+                  handleIdentifier(hello, namedRecordFieldReference)
+                  handleLiteralInt(42)
+                  handleNamedRecordField(:)
+                endRecordLiteral((, 1, const)
+              endConstLiteral(;)
+            endVariableInitializer(=)
+          endInitializedIdentifier(r4)
+        endVariablesDeclaration(1, ;)
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(r5, null, var)
+          handleIdentifier(r5, localVariableDeclaration)
+          beginInitializedIdentifier(r5)
+            beginVariableInitializer(=)
+              beginConstLiteral(()
+                beginParenthesizedExpressionOrRecordLiteral(()
+                  handleLiteralInt(42)
+                  handleRecoverableError(RecordLiteralOnePositionalFieldNoTrailingComma, ), ))
+                endRecordLiteral((, 1, const)
+              endConstLiteral(;)
+            endVariableInitializer(=)
+          endInitializedIdentifier(r5)
+        endVariablesDeclaration(1, ;)
+        beginMetadataStar(var)
+        endMetadataStar(0)
+        handleNoType(var)
+        beginVariablesDeclaration(r6, null, var)
+          handleIdentifier(r6, localVariableDeclaration)
+          beginInitializedIdentifier(r6)
+            beginVariableInitializer(=)
+              beginConstLiteral(()
+                beginParenthesizedExpressionOrRecordLiteral(()
+                  handleRecoverableError(RecordLiteralEmpty, ), ))
+                endRecordLiteral((, 0, const)
+              endConstLiteral(;)
+            endVariableInitializer(=)
+          endInitializedIdentifier(r6)
+        endVariablesDeclaration(1, ;)
+      endBlockFunctionBody(6, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(}, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(bar, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+        beginOptionalFormalParameters({)
+          beginMetadataStar(dynamic)
+          endMetadataStar(0)
+          beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+            handleIdentifier(dynamic, typeReference)
+            handleNoTypeArguments(record1)
+            handleType(dynamic, null)
+            handleIdentifier(record1, formalParameterDeclaration)
+            beginFormalParameterDefaultValueExpression()
+              beginParenthesizedExpressionOrRecordLiteral(()
+                handleLiteralInt(42)
+                handleLiteralInt(42)
+              endRecordLiteral((, 2, null)
+            endFormalParameterDefaultValueExpression()
+            handleValuedFormalParameter(=, ,)
+          endFormalParameter(null, null, null, record1, (, ), FormalParameterKind.optionalNamed, MemberKind.TopLevelMethod)
+          beginMetadataStar(dynamic)
+          endMetadataStar(0)
+          beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+            handleIdentifier(dynamic, typeReference)
+            handleNoTypeArguments(record2)
+            handleType(dynamic, null)
+            handleIdentifier(record2, formalParameterDeclaration)
+            beginFormalParameterDefaultValueExpression()
+              beginConstLiteral(()
+                beginParenthesizedExpressionOrRecordLiteral(()
+                  handleLiteralInt(42)
+                  handleLiteralInt(42)
+                endRecordLiteral((, 2, const)
+              endConstLiteral(})
+            endFormalParameterDefaultValueExpression()
+            handleValuedFormalParameter(=, })
+          endFormalParameter(null, null, null, record2, const, ), FormalParameterKind.optionalNamed, MemberKind.TopLevelMethod)
+        endOptionalFormalParameters(2, {, })
+      endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+      endBlockFunctionBody(0, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/record/record_literal_04.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_literal_04.dart.intertwined.expect
new file mode 100644
index 0000000..87a505b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_literal_04.dart.intertwined.expect
@@ -0,0 +1,407 @@
+parseUnit(void)
+  skipErrorTokens(void)
+  listener: beginCompilationUnit(void)
+  syntheticPreviousToken(void)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, foo, false)
+        listener: beginTopLevelMethod(, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, var)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, {, null, var, null, false)
+                looksLikeLocalFunction(r1)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(r1, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(r1, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r1)
+                    parseVariableInitializerOpt(r1)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseConstExpression(=)
+                                listener: beginConstLiteral(()
+                                parseParenthesizedExpressionOrRecordLiteral(const, const)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseLiteralInt(()
+                                            listener: handleLiteralInt(42)
+                                  ensureCloseParen(,, ()
+                                  listener: endRecordLiteral((, 1, const)
+                                listener: endConstLiteral(;)
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(r1)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(r2)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(r2, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(r2, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r2)
+                    parseVariableInitializerOpt(r2)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseConstExpression(=)
+                                listener: beginConstLiteral(()
+                                parseParenthesizedExpressionOrRecordLiteral(const, const)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseLiteralInt(()
+                                            listener: handleLiteralInt(1)
+                                  parseExpression(,)
+                                    parsePrecedenceExpression(,, 1, true)
+                                      parseUnaryExpression(,, true)
+                                        parsePrimary(,, expression)
+                                          parseLiteralInt(,)
+                                            listener: handleLiteralInt(2)
+                                  ensureIdentifier(,, namedRecordFieldReference)
+                                    listener: handleIdentifier(a, namedRecordFieldReference)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralInt(:)
+                                            listener: handleLiteralInt(3)
+                                  listener: handleNamedRecordField(:)
+                                  ensureIdentifier(,, namedRecordFieldReference)
+                                    listener: handleIdentifier(b, namedRecordFieldReference)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralInt(:)
+                                            listener: handleLiteralInt(4)
+                                  listener: handleNamedRecordField(:)
+                                  ensureCloseParen(4, ()
+                                  listener: endRecordLiteral((, 4, const)
+                                listener: endConstLiteral(;)
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(r2)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(r3)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(r3, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(r3, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r3)
+                    parseVariableInitializerOpt(r3)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseConstExpression(=)
+                                listener: beginConstLiteral(()
+                                parseParenthesizedExpressionOrRecordLiteral(const, const)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseLiteralInt(()
+                                            listener: handleLiteralInt(1)
+                                  ensureIdentifier(,, namedRecordFieldReference)
+                                    listener: handleIdentifier(a, namedRecordFieldReference)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralInt(:)
+                                            listener: handleLiteralInt(2)
+                                  listener: handleNamedRecordField(:)
+                                  parseExpression(,)
+                                    parsePrecedenceExpression(,, 1, true)
+                                      parseUnaryExpression(,, true)
+                                        parsePrimary(,, expression)
+                                          parseLiteralInt(,)
+                                            listener: handleLiteralInt(3)
+                                  ensureIdentifier(,, namedRecordFieldReference)
+                                    listener: handleIdentifier(b, namedRecordFieldReference)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralInt(:)
+                                            listener: handleLiteralInt(4)
+                                  listener: handleNamedRecordField(:)
+                                  ensureCloseParen(4, ()
+                                  listener: endRecordLiteral((, 4, const)
+                                listener: endConstLiteral(;)
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(r3)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(r4)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(r4, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(r4, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r4)
+                    parseVariableInitializerOpt(r4)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseConstExpression(=)
+                                listener: beginConstLiteral(()
+                                parseParenthesizedExpressionOrRecordLiteral(const, const)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  ensureIdentifier((, namedRecordFieldReference)
+                                    listener: handleIdentifier(hello, namedRecordFieldReference)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralInt(:)
+                                            listener: handleLiteralInt(42)
+                                  listener: handleNamedRecordField(:)
+                                  ensureCloseParen(42, ()
+                                  listener: endRecordLiteral((, 1, const)
+                                listener: endConstLiteral(;)
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(r4)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(r5)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(r5, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(r5, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r5)
+                    parseVariableInitializerOpt(r5)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseConstExpression(=)
+                                listener: beginConstLiteral(()
+                                parseParenthesizedExpressionOrRecordLiteral(const, const)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseLiteralInt(()
+                                            listener: handleLiteralInt(42)
+                                  ensureCloseParen(42, ()
+                                  reportRecoverableError(), RecordLiteralOnePositionalFieldNoTrailingComma)
+                                    listener: handleRecoverableError(RecordLiteralOnePositionalFieldNoTrailingComma, ), ))
+                                  listener: endRecordLiteral((, 1, const)
+                                listener: endConstLiteral(;)
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(r5)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, var)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false)
+                looksLikeLocalFunction(r6)
+                listener: beginMetadataStar(var)
+                listener: endMetadataStar(0)
+                listener: handleNoType(var)
+                listener: beginVariablesDeclaration(r6, null, var)
+                parseVariablesDeclarationRest(var, true)
+                  parseOptionallyInitializedIdentifier(var)
+                    ensureIdentifier(var, localVariableDeclaration)
+                      listener: handleIdentifier(r6, localVariableDeclaration)
+                    listener: beginInitializedIdentifier(r6)
+                    parseVariableInitializerOpt(r6)
+                      listener: beginVariableInitializer(=)
+                      parseExpression(=)
+                        parsePrecedenceExpression(=, 1, true)
+                          parseUnaryExpression(=, true)
+                            parsePrimary(=, expression)
+                              parseConstExpression(=)
+                                listener: beginConstLiteral(()
+                                parseParenthesizedExpressionOrRecordLiteral(const, const)
+                                  listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                  ensureCloseParen((, ()
+                                  reportRecoverableError(), RecordLiteralEmpty)
+                                    listener: handleRecoverableError(RecordLiteralEmpty, ), ))
+                                  listener: endRecordLiteral((, 0, const)
+                                listener: endConstLiteral(;)
+                      listener: endVariableInitializer(=)
+                    listener: endInitializedIdentifier(r6)
+                  ensureSemicolon())
+                  listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(6, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(void)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(}, null, null, }, Instance of 'VoidType', null, bar, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(bar, topLevelFunctionDeclaration)
+        parseMethodTypeVar(bar)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(bar, bar, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(bar, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              parseOptionalNamedParameters((, MemberKind.TopLevelMethod)
+                listener: beginOptionalFormalParameters({)
+                parseFormalParameter({, FormalParameterKind.optionalNamed, MemberKind.TopLevelMethod)
+                  parseMetadataStar({)
+                    listener: beginMetadataStar(dynamic)
+                    listener: endMetadataStar(0)
+                  listener: beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+                  listener: handleIdentifier(dynamic, typeReference)
+                  listener: handleNoTypeArguments(record1)
+                  listener: handleType(dynamic, null)
+                  ensureIdentifier(dynamic, formalParameterDeclaration)
+                    listener: handleIdentifier(record1, formalParameterDeclaration)
+                  listener: beginFormalParameterDefaultValueExpression()
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
+                            parseParenthesizedExpressionOrRecordLiteral(=, null)
+                              listener: beginParenthesizedExpressionOrRecordLiteral(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseLiteralInt(()
+                                        listener: handleLiteralInt(42)
+                              parseExpression(,)
+                                parsePrecedenceExpression(,, 1, true)
+                                  parseUnaryExpression(,, true)
+                                    parsePrimary(,, expression)
+                                      parseLiteralInt(,)
+                                        listener: handleLiteralInt(42)
+                              ensureCloseParen(42, ()
+                              listener: endRecordLiteral((, 2, null)
+                  listener: endFormalParameterDefaultValueExpression()
+                  listener: handleValuedFormalParameter(=, ,)
+                  listener: endFormalParameter(null, null, null, record1, (, ), FormalParameterKind.optionalNamed, MemberKind.TopLevelMethod)
+                parseFormalParameter(,, FormalParameterKind.optionalNamed, MemberKind.TopLevelMethod)
+                  parseMetadataStar(,)
+                    listener: beginMetadataStar(dynamic)
+                    listener: endMetadataStar(0)
+                  listener: beginFormalParameter(dynamic, MemberKind.TopLevelMethod, null, null, null)
+                  listener: handleIdentifier(dynamic, typeReference)
+                  listener: handleNoTypeArguments(record2)
+                  listener: handleType(dynamic, null)
+                  ensureIdentifier(dynamic, formalParameterDeclaration)
+                    listener: handleIdentifier(record2, formalParameterDeclaration)
+                  listener: beginFormalParameterDefaultValueExpression()
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstLiteral(()
+                            parseParenthesizedExpressionOrRecordLiteral(const, const)
+                              listener: beginParenthesizedExpressionOrRecordLiteral(()
+                              parseExpression(()
+                                parsePrecedenceExpression((, 1, true)
+                                  parseUnaryExpression((, true)
+                                    parsePrimary((, expression)
+                                      parseLiteralInt(()
+                                        listener: handleLiteralInt(42)
+                              parseExpression(,)
+                                parsePrecedenceExpression(,, 1, true)
+                                  parseUnaryExpression(,, true)
+                                    parsePrimary(,, expression)
+                                      parseLiteralInt(,)
+                                        listener: handleLiteralInt(42)
+                              ensureCloseParen(42, ()
+                              listener: endRecordLiteral((, 2, const)
+                            listener: endConstLiteral(})
+                  listener: endFormalParameterDefaultValueExpression()
+                  listener: handleValuedFormalParameter(=, })
+                  listener: endFormalParameter(null, null, null, record2, const, ), FormalParameterKind.optionalNamed, MemberKind.TopLevelMethod)
+                listener: endOptionalFormalParameters(2, {, })
+              ensureCloseParen(}, ()
+              listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(0, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(void)
+  listener: endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/record/record_literal_04.dart.parser.expect b/pkg/front_end/parser_testcases/record/record_literal_04.dart.parser.expect
new file mode 100644
index 0000000..1530fe6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_literal_04.dart.parser.expect
@@ -0,0 +1,37 @@
+void foo() {
+
+var r1 = const (42, );
+var r2 = const (1, 2, a: 3, b: 4);
+var r3 = const (1, a: 2, 3, b: 4);
+var r4 = const (hello: 42);
+
+
+var r5 = const (42);
+
+
+var r6 = const ();
+}
+
+void bar({dynamic record1 = (42, 42), dynamic record2 = const (42, 42)}) {
+
+}
+
+
+void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+
+var[KeywordToken] r1[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]42[StringToken],[SimpleToken] )[SimpleToken];[SimpleToken]
+var[KeywordToken] r2[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]1[StringToken],[SimpleToken] 2[StringToken],[SimpleToken] a[StringToken]:[SimpleToken] 3[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 4[StringToken])[SimpleToken];[SimpleToken]
+var[KeywordToken] r3[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]1[StringToken],[SimpleToken] a[StringToken]:[SimpleToken] 2[StringToken],[SimpleToken] 3[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 4[StringToken])[SimpleToken];[SimpleToken]
+var[KeywordToken] r4[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]hello[StringToken]:[SimpleToken] 42[StringToken])[SimpleToken];[SimpleToken]
+
+
+var[KeywordToken] r5[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]42[StringToken])[SimpleToken];[SimpleToken]
+
+
+var[KeywordToken] r6[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+void[KeywordToken] bar[StringToken]([BeginToken]{[BeginToken]dynamic[KeywordToken] record1[StringToken] =[SimpleToken] ([BeginToken]42[StringToken],[SimpleToken] 42[StringToken])[SimpleToken],[SimpleToken] dynamic[KeywordToken] record2[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]42[StringToken],[SimpleToken] 42[StringToken])[SimpleToken]}[SimpleToken])[SimpleToken] {[BeginToken]
+
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/record_literal_04.dart.scanner.expect b/pkg/front_end/parser_testcases/record/record_literal_04.dart.scanner.expect
new file mode 100644
index 0000000..1530fe6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_literal_04.dart.scanner.expect
@@ -0,0 +1,37 @@
+void foo() {
+
+var r1 = const (42, );
+var r2 = const (1, 2, a: 3, b: 4);
+var r3 = const (1, a: 2, 3, b: 4);
+var r4 = const (hello: 42);
+
+
+var r5 = const (42);
+
+
+var r6 = const ();
+}
+
+void bar({dynamic record1 = (42, 42), dynamic record2 = const (42, 42)}) {
+
+}
+
+
+void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+
+var[KeywordToken] r1[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]42[StringToken],[SimpleToken] )[SimpleToken];[SimpleToken]
+var[KeywordToken] r2[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]1[StringToken],[SimpleToken] 2[StringToken],[SimpleToken] a[StringToken]:[SimpleToken] 3[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 4[StringToken])[SimpleToken];[SimpleToken]
+var[KeywordToken] r3[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]1[StringToken],[SimpleToken] a[StringToken]:[SimpleToken] 2[StringToken],[SimpleToken] 3[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 4[StringToken])[SimpleToken];[SimpleToken]
+var[KeywordToken] r4[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]hello[StringToken]:[SimpleToken] 42[StringToken])[SimpleToken];[SimpleToken]
+
+
+var[KeywordToken] r5[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]42[StringToken])[SimpleToken];[SimpleToken]
+
+
+var[KeywordToken] r6[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+void[KeywordToken] bar[StringToken]([BeginToken]{[BeginToken]dynamic[KeywordToken] record1[StringToken] =[SimpleToken] ([BeginToken]42[StringToken],[SimpleToken] 42[StringToken])[SimpleToken],[SimpleToken] dynamic[KeywordToken] record2[StringToken] =[SimpleToken] const[KeywordToken] ([BeginToken]42[StringToken],[SimpleToken] 42[StringToken])[SimpleToken]}[SimpleToken])[SimpleToken] {[BeginToken]
+
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/record_type_01.dart.expect b/pkg/front_end/parser_testcases/record/record_type_01.dart.expect
index 35ee8f3..eb5ab8c 100644
--- a/pkg/front_end/parser_testcases/record/record_type_01.dart.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_01.dart.expect
@@ -37,7 +37,7 @@
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(1)
                 handleLiteralInt(2)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record1)
         endVariablesDeclaration(1, ;)
@@ -68,7 +68,7 @@
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(1)
                 handleLiteralInt(2)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record1Named)
         endVariablesDeclaration(1, ;)
@@ -99,7 +99,7 @@
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(1)
                 handleLiteralInt(2)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record2)
         endVariablesDeclaration(1, ;)
@@ -130,7 +130,7 @@
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(1)
                 handleLiteralInt(2)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record2Named)
         endVariablesDeclaration(1, ;)
@@ -185,7 +185,7 @@
                 handleIdentifier(b, namedRecordFieldReference)
                 handleLiteralInt(4)
                 handleNamedRecordField(:)
-              endRecordLiteral((, 4)
+              endRecordLiteral((, 4, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record3)
         endVariablesDeclaration(1, ;)
@@ -240,7 +240,7 @@
                 handleIdentifier(b, namedRecordFieldReference)
                 handleLiteralInt(4)
                 handleNamedRecordField(:)
-              endRecordLiteral((, 4)
+              endRecordLiteral((, 4, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record3Named)
         endVariablesDeclaration(1, ;)
@@ -295,7 +295,7 @@
                 handleIdentifier(b, namedRecordFieldReference)
                 handleLiteralInt(4)
                 handleNamedRecordField(:)
-              endRecordLiteral((, 4)
+              endRecordLiteral((, 4, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record4)
         endVariablesDeclaration(1, ;)
@@ -350,7 +350,7 @@
                 handleIdentifier(b, namedRecordFieldReference)
                 handleLiteralInt(4)
                 handleNamedRecordField(:)
-              endRecordLiteral((, 4)
+              endRecordLiteral((, 4, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record4Named)
         endVariablesDeclaration(1, ;)
@@ -429,9 +429,9 @@
                 beginParenthesizedExpressionOrRecordLiteral(()
                   handleLiteralInt(1)
                   handleLiteralInt(2)
-                endRecordLiteral((, 2)
+                endRecordLiteral((, 2, null)
                 handleLiteralInt(2)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record5)
         endVariablesDeclaration(1, ;)
diff --git a/pkg/front_end/parser_testcases/record/record_type_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_type_01.dart.intertwined.expect
index 1328f9b..ecf632f 100644
--- a/pkg/front_end/parser_testcases/record/record_type_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_01.dart.intertwined.expect
@@ -69,7 +69,7 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -84,7 +84,7 @@
                                             parseLiteralInt(,)
                                               listener: handleLiteralInt(2)
                                     ensureCloseParen(2, ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record1)
                     ensureSemicolon())
@@ -135,7 +135,7 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -150,7 +150,7 @@
                                             parseLiteralInt(,)
                                               listener: handleLiteralInt(2)
                                     ensureCloseParen(2, ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record1Named)
                     ensureSemicolon())
@@ -199,7 +199,7 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -214,7 +214,7 @@
                                             parseLiteralInt(,)
                                               listener: handleLiteralInt(2)
                                     ensureCloseParen(2, ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record2)
                     ensureSemicolon())
@@ -265,7 +265,7 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -280,7 +280,7 @@
                                             parseLiteralInt(,)
                                               listener: handleLiteralInt(2)
                                     ensureCloseParen(2, ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record2Named)
                     ensureSemicolon())
@@ -355,7 +355,7 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -388,7 +388,7 @@
                                               listener: handleLiteralInt(4)
                                     listener: handleNamedRecordField(:)
                                     ensureCloseParen(4, ()
-                                    listener: endRecordLiteral((, 4)
+                                    listener: endRecordLiteral((, 4, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record3)
                     ensureSemicolon())
@@ -465,7 +465,7 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -498,7 +498,7 @@
                                               listener: handleLiteralInt(4)
                                     listener: handleNamedRecordField(:)
                                     ensureCloseParen(4, ()
-                                    listener: endRecordLiteral((, 4)
+                                    listener: endRecordLiteral((, 4, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record3Named)
                     ensureSemicolon())
@@ -573,7 +573,7 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -606,7 +606,7 @@
                                               listener: handleLiteralInt(4)
                                     listener: handleNamedRecordField(:)
                                     ensureCloseParen(4, ()
-                                    listener: endRecordLiteral((, 4)
+                                    listener: endRecordLiteral((, 4, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record4)
                     ensureSemicolon())
@@ -683,7 +683,7 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -716,7 +716,7 @@
                                               listener: handleLiteralInt(4)
                                     listener: handleNamedRecordField(:)
                                     ensureCloseParen(4, ()
-                                    listener: endRecordLiteral((, 4)
+                                    listener: endRecordLiteral((, 4, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record4Named)
                     ensureSemicolon())
@@ -834,14 +834,14 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
                                         parseUnaryExpression((, true)
                                           parsePrimary((, expression)
                                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(()
-                                              parseParenthesizedExpressionOrRecordLiteral(()
+                                              parseParenthesizedExpressionOrRecordLiteral((, null)
                                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                                 parseExpression(()
                                                   parsePrecedenceExpression((, 1, true)
@@ -856,7 +856,7 @@
                                                         parseLiteralInt(,)
                                                           listener: handleLiteralInt(2)
                                                 ensureCloseParen(2, ()
-                                                listener: endRecordLiteral((, 2)
+                                                listener: endRecordLiteral((, 2, null)
                                     parseExpression(,)
                                       parsePrecedenceExpression(,, 1, true)
                                         parseUnaryExpression(,, true)
@@ -864,7 +864,7 @@
                                             parseLiteralInt(,)
                                               listener: handleLiteralInt(2)
                                     ensureCloseParen(2, ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record5)
                     ensureSemicolon())
diff --git a/pkg/front_end/parser_testcases/record/record_type_02.dart b/pkg/front_end/parser_testcases/record/record_type_02.dart
index 449c8a2..3ef1eac 100644
--- a/pkg/front_end/parser_testcases/record/record_type_02.dart
+++ b/pkg/front_end/parser_testcases/record/record_type_02.dart
@@ -1,6 +1,10 @@
-void foo() {
+void errors() {
   (int, int, {/*missing*/}) record1 = (1, 2);
-  (int /* missing */ ) record2 = (1);
-  ({int ok}) record3 = (ok: 1);
-  (/*missing*/) record4 = ();
+  (int /* missing trailing comma */ ) record2 = (1, );
+}
+
+void ok() {
+  (int, ) record1 = (1, );
+  ({int ok}) record2 = (ok: 1);
+  () record3 = Record.empty;
 }
diff --git a/pkg/front_end/parser_testcases/record/record_type_02.dart.expect b/pkg/front_end/parser_testcases/record/record_type_02.dart.expect
index 4512e5b..fb6031a 100644
--- a/pkg/front_end/parser_testcases/record/record_type_02.dart.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_02.dart.expect
@@ -1,20 +1,12 @@
 Problems reported:
 
-parser/record/record_type_02:2:26: Record type named fields list cannot be empty.
+parser/record/record_type_02:2:26: Record type named fields list can't be empty.
   (int, int, {/*missing*/}) record1 = (1, 2);
                          ^
 
-parser/record/record_type_02:3:22: Record type fields list cannot contain only one element without a named field.
-  (int /* missing */ ) record2 = (1);
-                     ^
-
-parser/record/record_type_02:5:15: Record type fields list cannot be empty.
-  (/*missing*/) record4 = ();
-              ^
-
-parser/record/record_type_02:5:28: Expected an identifier, but got ')'.
-  (/*missing*/) record4 = ();
-                           ^
+parser/record/record_type_02:3:37: Record type with one entry requires a trailing comma.
+  (int /* missing trailing comma */ ) record2 = (1, );
+                                    ^
 
 beginCompilationUnit(void)
   beginMetadataStar(void)
@@ -22,7 +14,7 @@
   beginTopLevelMember(void)
     beginTopLevelMethod(, null, null)
       handleVoidKeyword(void)
-      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleIdentifier(errors, topLevelFunctionDeclaration)
       handleNoTypeVariables(()
       beginFormalParameters((, MemberKind.TopLevelMethod)
       endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
@@ -58,7 +50,7 @@
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(1)
                 handleLiteralInt(2)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record1)
         endVariablesDeclaration(1, ;)
@@ -73,7 +65,7 @@
             handleType(int, null)
             handleNoName())
           endRecordTypeEntry()
-          handleRecoverableError(OnlyOneRecordTypeFieldsList, ), ))
+          handleRecoverableError(RecordTypeOnePositionalFieldNoTrailingComma, ), ))
         endRecordType((, null, 1, false)
         beginVariablesDeclaration(record2, null, null)
           handleIdentifier(record2, localVariableDeclaration)
@@ -81,10 +73,46 @@
             beginVariableInitializer(=)
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(1)
-              endParenthesizedExpression(()
+              endRecordLiteral((, 1, null)
             endVariableInitializer(=)
           endInitializedIdentifier(record2)
         endVariablesDeclaration(1, ;)
+      endBlockFunctionBody(2, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(}, null, null)
+      handleVoidKeyword(void)
+      handleIdentifier(ok, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginMetadataStar(()
+        endMetadataStar(0)
+        beginRecordType(()
+          beginRecordTypeEntry()
+            beginMetadataStar(int)
+            endMetadataStar(0)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(,)
+            handleType(int, null)
+            handleNoName(,)
+          endRecordTypeEntry()
+        endRecordType((, null, 1, false)
+        beginVariablesDeclaration(record1, null, null)
+          handleIdentifier(record1, localVariableDeclaration)
+          beginInitializedIdentifier(record1)
+            beginVariableInitializer(=)
+              beginParenthesizedExpressionOrRecordLiteral(()
+                handleLiteralInt(1)
+              endRecordLiteral((, 1, null)
+            endVariableInitializer(=)
+          endInitializedIdentifier(record1)
+        endVariablesDeclaration(1, ;)
         beginMetadataStar(()
         endMetadataStar(0)
         beginRecordType(()
@@ -99,38 +127,39 @@
             endRecordTypeEntry()
           endRecordTypeNamedFields(1, {)
         endRecordType((, null, 1, true)
-        beginVariablesDeclaration(record3, null, null)
-          handleIdentifier(record3, localVariableDeclaration)
-          beginInitializedIdentifier(record3)
+        beginVariablesDeclaration(record2, null, null)
+          handleIdentifier(record2, localVariableDeclaration)
+          beginInitializedIdentifier(record2)
             beginVariableInitializer(=)
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleIdentifier(ok, namedRecordFieldReference)
                 handleLiteralInt(1)
                 handleNamedRecordField(:)
-              endRecordLiteral((, 1)
+              endRecordLiteral((, 1, null)
             endVariableInitializer(=)
-          endInitializedIdentifier(record3)
+          endInitializedIdentifier(record2)
         endVariablesDeclaration(1, ;)
         beginMetadataStar(()
         endMetadataStar(0)
         beginRecordType(()
-          handleRecoverableError(EmptyRecordTypeFieldsList, ), ))
         endRecordType((, null, 0, false)
-        beginVariablesDeclaration(record4, null, null)
-          handleIdentifier(record4, localVariableDeclaration)
-          beginInitializedIdentifier(record4)
+        beginVariablesDeclaration(record3, null, null)
+          handleIdentifier(record3, localVariableDeclaration)
+          beginInitializedIdentifier(record3)
             beginVariableInitializer(=)
-              beginParenthesizedExpressionOrRecordLiteral(()
-                handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., Try inserting an identifier before ')'., {lexeme: )}], ), ))
-                handleIdentifier(, expression)
-                handleNoTypeArguments())
-                handleNoArguments())
-                handleSend(, ))
-              endParenthesizedExpression(()
+              handleIdentifier(Record, expression)
+              handleNoTypeArguments(.)
+              handleNoArguments(.)
+              handleSend(Record, .)
+              handleIdentifier(empty, expressionContinuation)
+              handleNoTypeArguments(;)
+              handleNoArguments(;)
+              handleSend(empty, ;)
+              handleEndingBinaryExpression(.)
             endVariableInitializer(=)
-          endInitializedIdentifier(record4)
+          endInitializedIdentifier(record3)
         endVariablesDeclaration(1, ;)
-      endBlockFunctionBody(4, {, })
+      endBlockFunctionBody(3, {, })
     endTopLevelMethod(void, null, })
   endTopLevelDeclaration()
-endCompilationUnit(1, )
+endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/record/record_type_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_type_02.dart.intertwined.expect
index 46a5982d..6ffd80e 100644
--- a/pkg/front_end/parser_testcases/record/record_type_02.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_02.dart.intertwined.expect
@@ -8,15 +8,15 @@
       listener: endMetadataStar(0)
     parseTopLevelMemberImpl()
       listener: beginTopLevelMember(void)
-      parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, foo, false)
+      parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, errors, false)
         listener: beginTopLevelMethod(, null, null)
         listener: handleVoidKeyword(void)
         ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
-          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
-        parseMethodTypeVar(foo)
+          listener: handleIdentifier(errors, topLevelFunctionDeclaration)
+        parseMethodTypeVar(errors)
           listener: handleNoTypeVariables(()
-        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
-          parseFormalParameters(foo, MemberKind.TopLevelMethod)
+        parseGetterOrFormalParameters(errors, errors, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(errors, MemberKind.TopLevelMethod)
             parseFormalParametersRest((, MemberKind.TopLevelMethod)
               listener: beginFormalParameters((, MemberKind.TopLevelMethod)
               listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
@@ -75,7 +75,7 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -90,7 +90,7 @@
                                             parseLiteralInt(,)
                                               listener: handleLiteralInt(2)
                                     ensureCloseParen(2, ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record1)
                     ensureSemicolon())
@@ -115,8 +115,8 @@
                       listener: handleType(int, null)
                       listener: handleNoName())
                       listener: endRecordTypeEntry()
-                    reportRecoverableError(), OnlyOneRecordTypeFieldsList)
-                      listener: handleRecoverableError(OnlyOneRecordTypeFieldsList, ), ))
+                    reportRecoverableError(), RecordTypeOnePositionalFieldNoTrailingComma)
+                      listener: handleRecoverableError(RecordTypeOnePositionalFieldNoTrailingComma, ), ))
                     listener: endRecordType((, null, 1, false)
                   listener: beginVariablesDeclaration(record2, null, null)
                   parseVariablesDeclarationRest(), true)
@@ -131,7 +131,7 @@
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -139,18 +139,93 @@
                                           parsePrimary((, expression)
                                             parseLiteralInt(()
                                               listener: handleLiteralInt(1)
-                                    ensureCloseParen(1, ()
-                                    listener: endParenthesizedExpression(()
+                                    ensureCloseParen(,, ()
+                                    listener: endRecordLiteral((, 1, null)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record2)
                     ensureSemicolon())
                     listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(2, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration(void)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(}, null, null, }, Instance of 'VoidType', null, ok, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(ok, topLevelFunctionDeclaration)
+        parseMethodTypeVar(ok)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(ok, ok, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(ok, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(record1)
+                  listener: beginMetadataStar(()
+                  listener: endMetadataStar(0)
+                  parseRecordType((, {)
+                    listener: beginRecordType(()
+                    parseRecordTypeField((, identifierIsOptional: true)
+                      listener: beginRecordTypeEntry()
+                      parseMetadataStar(()
+                        listener: beginMetadataStar(int)
+                        listener: endMetadataStar(0)
+                      listener: handleIdentifier(int, typeReference)
+                      listener: handleNoTypeArguments(,)
+                      listener: handleType(int, null)
+                      listener: handleNoName(,)
+                      listener: endRecordTypeEntry()
+                    listener: endRecordType((, null, 1, false)
+                  listener: beginVariablesDeclaration(record1, null, null)
+                  parseVariablesDeclarationRest(), true)
+                    parseOptionallyInitializedIdentifier())
+                      ensureIdentifier(), localVariableDeclaration)
+                        listener: handleIdentifier(record1, localVariableDeclaration)
+                      listener: beginInitializedIdentifier(record1)
+                      parseVariableInitializerOpt(record1)
+                        listener: beginVariableInitializer(=)
+                        parseExpression(=)
+                          parsePrecedenceExpression(=, 1, true)
+                            parseUnaryExpression(=, true)
+                              parsePrimary(=, expression)
+                                parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
+                                    listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseLiteralInt(()
+                                              listener: handleLiteralInt(1)
+                                    ensureCloseParen(,, ()
+                                    listener: endRecordLiteral((, 1, null)
+                        listener: endVariableInitializer(=)
+                      listener: endInitializedIdentifier(record1)
+                    ensureSemicolon())
+                    listener: endVariablesDeclaration(1, ;)
           notEofOrValue(}, ()
           parseStatement(;)
             parseStatementX(;)
               parseExpressionStatementOrDeclaration(;, false)
                 parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
-                  looksLikeLocalFunction(record3)
+                  looksLikeLocalFunction(record2)
                   listener: beginMetadataStar(()
                   listener: endMetadataStar(0)
                   parseRecordType((, ;)
@@ -171,6 +246,47 @@
                       listener: endRecordTypeNamedFields(1, {)
                     ensureCloseParen(}, ()
                     listener: endRecordType((, null, 1, true)
+                  listener: beginVariablesDeclaration(record2, null, null)
+                  parseVariablesDeclarationRest(), true)
+                    parseOptionallyInitializedIdentifier())
+                      ensureIdentifier(), localVariableDeclaration)
+                        listener: handleIdentifier(record2, localVariableDeclaration)
+                      listener: beginInitializedIdentifier(record2)
+                      parseVariableInitializerOpt(record2)
+                        listener: beginVariableInitializer(=)
+                        parseExpression(=)
+                          parsePrecedenceExpression(=, 1, true)
+                            parseUnaryExpression(=, true)
+                              parsePrimary(=, expression)
+                                parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
+                                  parseParenthesizedExpressionOrRecordLiteral(=, null)
+                                    listener: beginParenthesizedExpressionOrRecordLiteral(()
+                                    ensureIdentifier((, namedRecordFieldReference)
+                                      listener: handleIdentifier(ok, namedRecordFieldReference)
+                                    parseExpression(:)
+                                      parsePrecedenceExpression(:, 1, true)
+                                        parseUnaryExpression(:, true)
+                                          parsePrimary(:, expression)
+                                            parseLiteralInt(:)
+                                              listener: handleLiteralInt(1)
+                                    listener: handleNamedRecordField(:)
+                                    ensureCloseParen(1, ()
+                                    listener: endRecordLiteral((, 1, null)
+                        listener: endVariableInitializer(=)
+                      listener: endInitializedIdentifier(record2)
+                    ensureSemicolon())
+                    listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, ()
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(record3)
+                  listener: beginMetadataStar(()
+                  listener: endMetadataStar(0)
+                  parseRecordType((, ;)
+                    listener: beginRecordType(()
+                    listener: endRecordType((, null, 0, false)
                   listener: beginVariablesDeclaration(record3, null, null)
                   parseVariablesDeclarationRest(), true)
                     parseOptionallyInitializedIdentifier())
@@ -183,76 +299,33 @@
                           parsePrecedenceExpression(=, 1, true)
                             parseUnaryExpression(=, true)
                               parsePrimary(=, expression)
-                                parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
-                                    listener: beginParenthesizedExpressionOrRecordLiteral(()
-                                    ensureIdentifier((, namedRecordFieldReference)
-                                      listener: handleIdentifier(ok, namedRecordFieldReference)
-                                    parseExpression(:)
-                                      parsePrecedenceExpression(:, 1, true)
-                                        parseUnaryExpression(:, true)
-                                          parsePrimary(:, expression)
-                                            parseLiteralInt(:)
-                                              listener: handleLiteralInt(1)
-                                    listener: handleNamedRecordField(:)
-                                    ensureCloseParen(1, ()
-                                    listener: endRecordLiteral((, 1)
+                                parseSendOrFunctionLiteral(=, expression)
+                                  parseSend(=, expression)
+                                    isNextIdentifier(=)
+                                    ensureIdentifier(=, expression)
+                                      listener: handleIdentifier(Record, expression)
+                                    listener: handleNoTypeArguments(.)
+                                    parseArgumentsOpt(Record)
+                                      listener: handleNoArguments(.)
+                                    listener: handleSend(Record, .)
+                            parsePrimary(., expressionContinuation)
+                              parseSendOrFunctionLiteral(., expressionContinuation)
+                                parseSend(., expressionContinuation)
+                                  isNextIdentifier(.)
+                                  ensureIdentifier(., expressionContinuation)
+                                    listener: handleIdentifier(empty, expressionContinuation)
+                                  listener: handleNoTypeArguments(;)
+                                  parseArgumentsOpt(empty)
+                                    listener: handleNoArguments(;)
+                                  listener: handleSend(empty, ;)
+                            listener: handleEndingBinaryExpression(.)
                         listener: endVariableInitializer(=)
                       listener: endInitializedIdentifier(record3)
-                    ensureSemicolon())
-                    listener: endVariablesDeclaration(1, ;)
-          notEofOrValue(}, ()
-          parseStatement(;)
-            parseStatementX(;)
-              parseExpressionStatementOrDeclaration(;, false)
-                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
-                  looksLikeLocalFunction(record4)
-                  listener: beginMetadataStar(()
-                  listener: endMetadataStar(0)
-                  parseRecordType((, ;)
-                    listener: beginRecordType(()
-                    reportRecoverableError(), EmptyRecordTypeFieldsList)
-                      listener: handleRecoverableError(EmptyRecordTypeFieldsList, ), ))
-                    listener: endRecordType((, null, 0, false)
-                  listener: beginVariablesDeclaration(record4, null, null)
-                  parseVariablesDeclarationRest(), true)
-                    parseOptionallyInitializedIdentifier())
-                      ensureIdentifier(), localVariableDeclaration)
-                        listener: handleIdentifier(record4, localVariableDeclaration)
-                      listener: beginInitializedIdentifier(record4)
-                      parseVariableInitializerOpt(record4)
-                        listener: beginVariableInitializer(=)
-                        parseExpression(=)
-                          parsePrecedenceExpression(=, 1, true)
-                            parseUnaryExpression(=, true)
-                              parsePrimary(=, expression)
-                                parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                                  parseParenthesizedExpressionOrRecordLiteral(=)
-                                    listener: beginParenthesizedExpressionOrRecordLiteral(()
-                                    parseExpression(()
-                                      parsePrecedenceExpression((, 1, true)
-                                        parseUnaryExpression((, true)
-                                          parsePrimary((, expression)
-                                            parseSend((, expression)
-                                              isNextIdentifier(()
-                                              ensureIdentifier((, expression)
-                                                reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
-                                                  listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., Try inserting an identifier before ')'., {lexeme: )}], ), ))
-                                                rewriter()
-                                                listener: handleIdentifier(, expression)
-                                              listener: handleNoTypeArguments())
-                                              parseArgumentsOpt()
-                                                listener: handleNoArguments())
-                                              listener: handleSend(, ))
-                                    ensureCloseParen(, ()
-                                    listener: endParenthesizedExpression(()
-                        listener: endVariableInitializer(=)
-                      listener: endInitializedIdentifier(record4)
-                    ensureSemicolon())
+                    ensureSemicolon(empty)
                     listener: endVariablesDeclaration(1, ;)
           notEofOrValue(}, })
-          listener: endBlockFunctionBody(4, {, })
+          listener: endBlockFunctionBody(3, {, })
         listener: endTopLevelMethod(void, null, })
   listener: endTopLevelDeclaration()
   reportAllErrorTokens(void)
-  listener: endCompilationUnit(1, )
+  listener: endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/record/record_type_02.dart.parser.expect b/pkg/front_end/parser_testcases/record/record_type_02.dart.parser.expect
index 3f49c38..92d366c 100644
--- a/pkg/front_end/parser_testcases/record/record_type_02.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_02.dart.parser.expect
@@ -1,17 +1,23 @@
-NOTICE: Stream was rewritten by parser!
-
-void foo() {
+void errors() {
 (int, int, { }) record1 = (1, 2);
-(int ) record2 = (1);
-({int ok}) record3 = (ok: 1);
-( ) record4 = (*synthetic*);
+(int ) record2 = (1, );
+}
+
+void ok() {
+(int, ) record1 = (1, );
+({int ok}) record2 = (ok: 1);
+() record3 = Record.empty;
 }
 
 
-void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+void[KeywordToken] errors[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 ([BeginToken]int[StringToken],[SimpleToken] int[StringToken],[SimpleToken] {[BeginToken] }[SimpleToken])[SimpleToken] record1[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] 2[StringToken])[SimpleToken];[SimpleToken]
-([BeginToken]int[StringToken] )[SimpleToken] record2[StringToken] =[SimpleToken] ([BeginToken]1[StringToken])[SimpleToken];[SimpleToken]
-([BeginToken]{[BeginToken]int[StringToken] ok[StringToken]}[SimpleToken])[SimpleToken] record3[StringToken] =[SimpleToken] ([BeginToken]ok[StringToken]:[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
-([BeginToken] )[SimpleToken] record4[StringToken] =[SimpleToken] ([BeginToken][SyntheticStringToken])[SimpleToken];[SimpleToken]
+([BeginToken]int[StringToken] )[SimpleToken] record2[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] )[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+void[KeywordToken] ok[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+([BeginToken]int[StringToken],[SimpleToken] )[SimpleToken] record1[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] )[SimpleToken];[SimpleToken]
+([BeginToken]{[BeginToken]int[StringToken] ok[StringToken]}[SimpleToken])[SimpleToken] record2[StringToken] =[SimpleToken] ([BeginToken]ok[StringToken]:[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+([BeginToken])[SimpleToken] record3[StringToken] =[SimpleToken] Record[StringToken].[SimpleToken]empty[StringToken];[SimpleToken]
 }[SimpleToken]
 [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/record_type_02.dart.scanner.expect b/pkg/front_end/parser_testcases/record/record_type_02.dart.scanner.expect
index e1a2d61..92d366c 100644
--- a/pkg/front_end/parser_testcases/record/record_type_02.dart.scanner.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_02.dart.scanner.expect
@@ -1,15 +1,23 @@
-void foo() {
+void errors() {
 (int, int, { }) record1 = (1, 2);
-(int ) record2 = (1);
-({int ok}) record3 = (ok: 1);
-( ) record4 = ();
+(int ) record2 = (1, );
+}
+
+void ok() {
+(int, ) record1 = (1, );
+({int ok}) record2 = (ok: 1);
+() record3 = Record.empty;
 }
 
 
-void[KeywordToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+void[KeywordToken] errors[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 ([BeginToken]int[StringToken],[SimpleToken] int[StringToken],[SimpleToken] {[BeginToken] }[SimpleToken])[SimpleToken] record1[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] 2[StringToken])[SimpleToken];[SimpleToken]
-([BeginToken]int[StringToken] )[SimpleToken] record2[StringToken] =[SimpleToken] ([BeginToken]1[StringToken])[SimpleToken];[SimpleToken]
-([BeginToken]{[BeginToken]int[StringToken] ok[StringToken]}[SimpleToken])[SimpleToken] record3[StringToken] =[SimpleToken] ([BeginToken]ok[StringToken]:[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
-([BeginToken] )[SimpleToken] record4[StringToken] =[SimpleToken] ([BeginToken])[SimpleToken];[SimpleToken]
+([BeginToken]int[StringToken] )[SimpleToken] record2[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] )[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+void[KeywordToken] ok[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+([BeginToken]int[StringToken],[SimpleToken] )[SimpleToken] record1[StringToken] =[SimpleToken] ([BeginToken]1[StringToken],[SimpleToken] )[SimpleToken];[SimpleToken]
+([BeginToken]{[BeginToken]int[StringToken] ok[StringToken]}[SimpleToken])[SimpleToken] record2[StringToken] =[SimpleToken] ([BeginToken]ok[StringToken]:[SimpleToken] 1[StringToken])[SimpleToken];[SimpleToken]
+([BeginToken])[SimpleToken] record3[StringToken] =[SimpleToken] Record[StringToken].[SimpleToken]empty[StringToken];[SimpleToken]
 }[SimpleToken]
 [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/record_type_03.dart.expect b/pkg/front_end/parser_testcases/record/record_type_03.dart.expect
index 46b0a73..2cf896d 100644
--- a/pkg/front_end/parser_testcases/record/record_type_03.dart.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_03.dart.expect
@@ -72,13 +72,13 @@
           handleNoArguments())
           handleSend(b, ))
           handleEndingBinaryExpression(.)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(42)
                 handleLiteralInt(42)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endReturnStatement(true, return, ;)
           endThenStatement(;)
         endIfStatement(if, null)
@@ -86,7 +86,7 @@
           beginParenthesizedExpressionOrRecordLiteral(()
             handleLiteralInt(1)
             handleLiteralInt(1)
-          endRecordLiteral((, 2)
+          endRecordLiteral((, 2, null)
         endReturnStatement(true, return, ;)
       endBlockFunctionBody(2, {, })
     endTopLevelMethod((, null, })
@@ -155,13 +155,13 @@
           handleNoArguments())
           handleSend(b, ))
           handleEndingBinaryExpression(.)
-          handleParenthesizedCondition(()
+          handleParenthesizedCondition((, null)
           beginThenStatement(return)
             beginReturnStatement(return)
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(42)
                 handleLiteralInt(42)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endReturnStatement(true, return, ;)
           endThenStatement(;)
         endIfStatement(if, null)
@@ -169,7 +169,7 @@
           beginParenthesizedExpressionOrRecordLiteral(()
             handleLiteralInt(1)
             handleLiteralInt(1)
-          endRecordLiteral((, 2)
+          endRecordLiteral((, 2, null)
         endReturnStatement(true, return, ;)
       endBlockFunctionBody(2, {, })
     endTopLevelMethod((, null, })
@@ -226,7 +226,7 @@
             beginParenthesizedExpressionOrRecordLiteral(()
               handleLiteralInt(42)
               handleLiteralInt(42)
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(null, (, (, null, ;)
         endMember()
diff --git a/pkg/front_end/parser_testcases/record/record_type_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_type_03.dart.intertwined.expect
index 944ef39..be5497e 100644
--- a/pkg/front_end/parser_testcases/record/record_type_03.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_03.dart.intertwined.expect
@@ -101,8 +101,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -128,7 +128,7 @@
                               listener: handleSend(b, ))
                         listener: handleEndingBinaryExpression(.)
                     ensureCloseParen(b, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -139,7 +139,7 @@
                           parseUnaryExpression(return, true)
                             parsePrimary(return, expression)
                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                                parseParenthesizedExpressionOrRecordLiteral(return)
+                                parseParenthesizedExpressionOrRecordLiteral(return, null)
                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                   parseExpression(()
                                     parsePrecedenceExpression((, 1, true)
@@ -154,7 +154,7 @@
                                           parseLiteralInt(,)
                                             listener: handleLiteralInt(42)
                                   ensureCloseParen(42, ()
-                                  listener: endRecordLiteral((, 2)
+                                  listener: endRecordLiteral((, 2, null)
                       ensureSemicolon())
                       listener: endReturnStatement(true, return, ;)
                       inGenerator()
@@ -170,7 +170,7 @@
                     parseUnaryExpression(return, true)
                       parsePrimary(return, expression)
                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                          parseParenthesizedExpressionOrRecordLiteral(return)
+                          parseParenthesizedExpressionOrRecordLiteral(return, null)
                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
@@ -185,7 +185,7 @@
                                     parseLiteralInt(,)
                                       listener: handleLiteralInt(1)
                             ensureCloseParen(,, ()
-                            listener: endRecordLiteral((, 2)
+                            listener: endRecordLiteral((, 2, null)
                 ensureSemicolon())
                 listener: endReturnStatement(true, return, ;)
                 inGenerator()
@@ -280,8 +280,8 @@
             parseStatementX({)
               parseIfStatement({)
                 listener: beginIfStatement(if)
-                ensureParenthesizedCondition(if)
-                  parseExpressionInParenthesisRest(()
+                ensureParenthesizedCondition(if, allowCase: false)
+                  parseExpressionInParenthesisRest((, allowCase: false)
                     parseExpression(()
                       parsePrecedenceExpression((, 1, true)
                         parseUnaryExpression((, true)
@@ -307,7 +307,7 @@
                               listener: handleSend(b, ))
                         listener: handleEndingBinaryExpression(.)
                     ensureCloseParen(b, ()
-                  listener: handleParenthesizedCondition(()
+                    listener: handleParenthesizedCondition((, null)
                 listener: beginThenStatement(return)
                 parseStatement())
                   parseStatementX())
@@ -318,7 +318,7 @@
                           parseUnaryExpression(return, true)
                             parsePrimary(return, expression)
                               parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                                parseParenthesizedExpressionOrRecordLiteral(return)
+                                parseParenthesizedExpressionOrRecordLiteral(return, null)
                                   listener: beginParenthesizedExpressionOrRecordLiteral(()
                                   parseExpression(()
                                     parsePrecedenceExpression((, 1, true)
@@ -333,7 +333,7 @@
                                           parseLiteralInt(,)
                                             listener: handleLiteralInt(42)
                                   ensureCloseParen(42, ()
-                                  listener: endRecordLiteral((, 2)
+                                  listener: endRecordLiteral((, 2, null)
                       ensureSemicolon())
                       listener: endReturnStatement(true, return, ;)
                       inGenerator()
@@ -349,7 +349,7 @@
                     parseUnaryExpression(return, true)
                       parsePrimary(return, expression)
                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                          parseParenthesizedExpressionOrRecordLiteral(return)
+                          parseParenthesizedExpressionOrRecordLiteral(return, null)
                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
@@ -364,7 +364,7 @@
                                     parseLiteralInt(,)
                                       listener: handleLiteralInt(1)
                             ensureCloseParen(,, ()
-                            listener: endRecordLiteral((, 2)
+                            listener: endRecordLiteral((, 2, null)
                 ensureSemicolon())
                 listener: endReturnStatement(true, return, ;)
                 inGenerator()
@@ -461,7 +461,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -476,7 +476,7 @@
                                         parseLiteralInt(,)
                                           listener: handleLiteralInt(42)
                                 ensureCloseParen(42, ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
diff --git a/pkg/front_end/parser_testcases/record/record_type_getter.dart.expect b/pkg/front_end/parser_testcases/record/record_type_getter.dart.expect
index 63ac4e9..37e1db2 100644
--- a/pkg/front_end/parser_testcases/record/record_type_getter.dart.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_getter.dart.expect
@@ -39,7 +39,7 @@
         handleLiteralInt(42)
         beginLiteralString("fortytwo")
         endLiteralString(0, ))
-      endRecordLiteral((, 2)
+      endRecordLiteral((, 2, null)
       handleExpressionFunctionBody(=>, ;)
     endTopLevelMethod((, null, ;)
   endTopLevelDeclaration(()
@@ -85,7 +85,7 @@
             handleLiteralInt(42)
             beginLiteralString("fortytwo")
             endLiteralString(0, ))
-          endRecordLiteral((, 2)
+          endRecordLiteral((, 2, null)
         endReturnStatement(true, return, ;)
       endBlockFunctionBody(1, {, })
     endTopLevelMethod((, null, })
@@ -120,7 +120,7 @@
         handleLiteralInt(42)
         beginLiteralString("fortytwo")
         endLiteralString(0, ))
-      endRecordLiteral((, 2)
+      endRecordLiteral((, 2, null)
       handleExpressionFunctionBody(=>, ;)
     endTopLevelMethod((, get, ;)
   endTopLevelDeclaration(()
@@ -156,7 +156,7 @@
             handleLiteralInt(42)
             beginLiteralString("fortytwo")
             endLiteralString(0, ))
-          endRecordLiteral((, 2)
+          endRecordLiteral((, 2, null)
         endReturnStatement(true, return, ;)
       endBlockFunctionBody(1, {, })
     endTopLevelMethod((, get, })
@@ -191,7 +191,7 @@
         handleLiteralInt(42)
         beginLiteralString("fortytwo")
         endLiteralString(0, ))
-      endRecordLiteral((, 2)
+      endRecordLiteral((, 2, null)
       handleExpressionFunctionBody(=>, ;)
     endTopLevelMethod((, get, ;)
   endTopLevelDeclaration(()
@@ -227,7 +227,7 @@
             handleLiteralInt(42)
             beginLiteralString("fortytwo")
             endLiteralString(0, ))
-          endRecordLiteral((, 2)
+          endRecordLiteral((, 2, null)
         endReturnStatement(true, return, ;)
       endBlockFunctionBody(1, {, })
     endTopLevelMethod((, get, })
@@ -285,7 +285,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(null, (, (, null, ;)
         endMember()
@@ -332,7 +332,7 @@
                   handleLiteralInt(42)
                   beginLiteralString("fortytwo")
                   endLiteralString(0, ))
-                endRecordLiteral((, 2)
+                endRecordLiteral((, 2, null)
               endReturnStatement(true, return, ;)
             endBlockFunctionBody(1, {, })
           endClassMethod(null, (, (, null, })
@@ -368,7 +368,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(get, (, =>, null, ;)
         endMember()
@@ -405,7 +405,7 @@
                   handleLiteralInt(42)
                   beginLiteralString("fortytwo")
                   endLiteralString(0, ))
-                endRecordLiteral((, 2)
+                endRecordLiteral((, 2, null)
               endReturnStatement(true, return, ;)
             endBlockFunctionBody(1, {, })
           endClassMethod(get, (, {, null, })
@@ -441,7 +441,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(get, (, =>, null, ;)
         endMember()
@@ -478,7 +478,7 @@
                   handleLiteralInt(42)
                   beginLiteralString("fortytwo")
                   endLiteralString(0, ))
-                endRecordLiteral((, 2)
+                endRecordLiteral((, 2, null)
               endReturnStatement(true, return, ;)
             endBlockFunctionBody(1, {, })
           endClassMethod(get, (, {, null, })
@@ -539,7 +539,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(null, static, (, null, ;)
         endMember()
@@ -586,7 +586,7 @@
                   handleLiteralInt(42)
                   beginLiteralString("fortytwo")
                   endLiteralString(0, ))
-                endRecordLiteral((, 2)
+                endRecordLiteral((, 2, null)
               endReturnStatement(true, return, ;)
             endBlockFunctionBody(1, {, })
           endClassMethod(null, static, (, null, })
@@ -622,7 +622,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(get, static, =>, null, ;)
         endMember()
@@ -659,7 +659,7 @@
                   handleLiteralInt(42)
                   beginLiteralString("fortytwo")
                   endLiteralString(0, ))
-                endRecordLiteral((, 2)
+                endRecordLiteral((, 2, null)
               endReturnStatement(true, return, ;)
             endBlockFunctionBody(1, {, })
           endClassMethod(get, static, {, null, })
@@ -695,7 +695,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(get, static, =>, null, ;)
         endMember()
@@ -732,7 +732,7 @@
                   handleLiteralInt(42)
                   beginLiteralString("fortytwo")
                   endLiteralString(0, ))
-                endRecordLiteral((, 2)
+                endRecordLiteral((, 2, null)
               endReturnStatement(true, return, ;)
             endBlockFunctionBody(1, {, })
           endClassMethod(get, static, {, null, })
diff --git a/pkg/front_end/parser_testcases/record/record_type_getter.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_type_getter.dart.intertwined.expect
index 99edfa5..0db2a36 100644
--- a/pkg/front_end/parser_testcases/record/record_type_getter.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_getter.dart.intertwined.expect
@@ -66,7 +66,7 @@
                 parseUnaryExpression(=>, true)
                   parsePrimary(=>, expression)
                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                      parseParenthesizedExpressionOrRecordLiteral(=>)
+                      parseParenthesizedExpressionOrRecordLiteral(=>, null)
                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                         parseExpression(()
                           parsePrecedenceExpression((, 1, true)
@@ -83,7 +83,7 @@
                                     listener: beginLiteralString("fortytwo")
                                     listener: endLiteralString(0, ))
                         ensureCloseParen("fortytwo", ()
-                        listener: endRecordLiteral((, 2)
+                        listener: endRecordLiteral((, 2, null)
             ensureSemicolon())
             listener: handleExpressionFunctionBody(=>, ;)
             inGenerator()
@@ -158,7 +158,7 @@
                     parseUnaryExpression(return, true)
                       parsePrimary(return, expression)
                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                          parseParenthesizedExpressionOrRecordLiteral(return)
+                          parseParenthesizedExpressionOrRecordLiteral(return, null)
                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
@@ -175,7 +175,7 @@
                                         listener: beginLiteralString("fortytwo")
                                         listener: endLiteralString(0, ))
                             ensureCloseParen("fortytwo", ()
-                            listener: endRecordLiteral((, 2)
+                            listener: endRecordLiteral((, 2, null)
                 ensureSemicolon())
                 listener: endReturnStatement(true, return, ;)
                 inGenerator()
@@ -232,7 +232,7 @@
                 parseUnaryExpression(=>, true)
                   parsePrimary(=>, expression)
                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                      parseParenthesizedExpressionOrRecordLiteral(=>)
+                      parseParenthesizedExpressionOrRecordLiteral(=>, null)
                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                         parseExpression(()
                           parsePrecedenceExpression((, 1, true)
@@ -249,7 +249,7 @@
                                     listener: beginLiteralString("fortytwo")
                                     listener: endLiteralString(0, ))
                         ensureCloseParen("fortytwo", ()
-                        listener: endRecordLiteral((, 2)
+                        listener: endRecordLiteral((, 2, null)
             ensureSemicolon())
             listener: handleExpressionFunctionBody(=>, ;)
             inGenerator()
@@ -309,7 +309,7 @@
                     parseUnaryExpression(return, true)
                       parsePrimary(return, expression)
                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                          parseParenthesizedExpressionOrRecordLiteral(return)
+                          parseParenthesizedExpressionOrRecordLiteral(return, null)
                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
@@ -326,7 +326,7 @@
                                         listener: beginLiteralString("fortytwo")
                                         listener: endLiteralString(0, ))
                             ensureCloseParen("fortytwo", ()
-                            listener: endRecordLiteral((, 2)
+                            listener: endRecordLiteral((, 2, null)
                 ensureSemicolon())
                 listener: endReturnStatement(true, return, ;)
                 inGenerator()
@@ -383,7 +383,7 @@
                 parseUnaryExpression(=>, true)
                   parsePrimary(=>, expression)
                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                      parseParenthesizedExpressionOrRecordLiteral(=>)
+                      parseParenthesizedExpressionOrRecordLiteral(=>, null)
                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                         parseExpression(()
                           parsePrecedenceExpression((, 1, true)
@@ -400,7 +400,7 @@
                                     listener: beginLiteralString("fortytwo")
                                     listener: endLiteralString(0, ))
                         ensureCloseParen("fortytwo", ()
-                        listener: endRecordLiteral((, 2)
+                        listener: endRecordLiteral((, 2, null)
             ensureSemicolon())
             listener: handleExpressionFunctionBody(=>, ;)
             inGenerator()
@@ -460,7 +460,7 @@
                     parseUnaryExpression(return, true)
                       parsePrimary(return, expression)
                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                          parseParenthesizedExpressionOrRecordLiteral(return)
+                          parseParenthesizedExpressionOrRecordLiteral(return, null)
                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
@@ -477,7 +477,7 @@
                                         listener: beginLiteralString("fortytwo")
                                         listener: endLiteralString(0, ))
                             ensureCloseParen("fortytwo", ()
-                            listener: endRecordLiteral((, 2)
+                            listener: endRecordLiteral((, 2, null)
                 ensureSemicolon())
                 listener: endReturnStatement(true, return, ;)
                 inGenerator()
@@ -577,7 +577,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -594,7 +594,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -674,7 +674,7 @@
                             parseUnaryExpression(return, true)
                               parsePrimary(return, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                                  parseParenthesizedExpressionOrRecordLiteral(return)
+                                  parseParenthesizedExpressionOrRecordLiteral(return, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -691,7 +691,7 @@
                                                 listener: beginLiteralString("fortytwo")
                                                 listener: endLiteralString(0, ))
                                     ensureCloseParen("fortytwo", ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         ensureSemicolon())
                         listener: endReturnStatement(true, return, ;)
                         inGenerator()
@@ -752,7 +752,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -769,7 +769,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -833,7 +833,7 @@
                             parseUnaryExpression(return, true)
                               parsePrimary(return, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                                  parseParenthesizedExpressionOrRecordLiteral(return)
+                                  parseParenthesizedExpressionOrRecordLiteral(return, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -850,7 +850,7 @@
                                                 listener: beginLiteralString("fortytwo")
                                                 listener: endLiteralString(0, ))
                                     ensureCloseParen("fortytwo", ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         ensureSemicolon())
                         listener: endReturnStatement(true, return, ;)
                         inGenerator()
@@ -911,7 +911,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -928,7 +928,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -992,7 +992,7 @@
                             parseUnaryExpression(return, true)
                               parsePrimary(return, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                                  parseParenthesizedExpressionOrRecordLiteral(return)
+                                  parseParenthesizedExpressionOrRecordLiteral(return, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -1009,7 +1009,7 @@
                                                 listener: beginLiteralString("fortytwo")
                                                 listener: endLiteralString(0, ))
                                     ensureCloseParen("fortytwo", ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         ensureSemicolon())
                         listener: endReturnStatement(true, return, ;)
                         inGenerator()
@@ -1112,7 +1112,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -1129,7 +1129,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -1208,7 +1208,7 @@
                             parseUnaryExpression(return, true)
                               parsePrimary(return, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                                  parseParenthesizedExpressionOrRecordLiteral(return)
+                                  parseParenthesizedExpressionOrRecordLiteral(return, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -1225,7 +1225,7 @@
                                                 listener: beginLiteralString("fortytwo")
                                                 listener: endLiteralString(0, ))
                                     ensureCloseParen("fortytwo", ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         ensureSemicolon())
                         listener: endReturnStatement(true, return, ;)
                         inGenerator()
@@ -1285,7 +1285,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -1302,7 +1302,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -1365,7 +1365,7 @@
                             parseUnaryExpression(return, true)
                               parsePrimary(return, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                                  parseParenthesizedExpressionOrRecordLiteral(return)
+                                  parseParenthesizedExpressionOrRecordLiteral(return, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -1382,7 +1382,7 @@
                                                 listener: beginLiteralString("fortytwo")
                                                 listener: endLiteralString(0, ))
                                     ensureCloseParen("fortytwo", ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         ensureSemicolon())
                         listener: endReturnStatement(true, return, ;)
                         inGenerator()
@@ -1442,7 +1442,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -1459,7 +1459,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -1522,7 +1522,7 @@
                             parseUnaryExpression(return, true)
                               parsePrimary(return, expression)
                                 parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                                  parseParenthesizedExpressionOrRecordLiteral(return)
+                                  parseParenthesizedExpressionOrRecordLiteral(return, null)
                                     listener: beginParenthesizedExpressionOrRecordLiteral(()
                                     parseExpression(()
                                       parsePrecedenceExpression((, 1, true)
@@ -1539,7 +1539,7 @@
                                                 listener: beginLiteralString("fortytwo")
                                                 listener: endLiteralString(0, ))
                                     ensureCloseParen("fortytwo", ()
-                                    listener: endRecordLiteral((, 2)
+                                    listener: endRecordLiteral((, 2, null)
                         ensureSemicolon())
                         listener: endReturnStatement(true, return, ;)
                         inGenerator()
diff --git a/pkg/front_end/parser_testcases/record/record_type_return_on_function_with_type_paremeter.dart.expect b/pkg/front_end/parser_testcases/record/record_type_return_on_function_with_type_paremeter.dart.expect
index 994395b..566b8f5 100644
--- a/pkg/front_end/parser_testcases/record/record_type_return_on_function_with_type_paremeter.dart.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_return_on_function_with_type_paremeter.dart.expect
@@ -51,7 +51,7 @@
             handleNoTypeArguments())
             handleNoArguments())
             handleSend(t, ))
-          endRecordLiteral((, 2)
+          endRecordLiteral((, 2, null)
         endReturnStatement(true, return, ;)
       endBlockFunctionBody(1, {, })
     endTopLevelMethod((, null, })
@@ -106,7 +106,7 @@
         handleNoTypeArguments())
         handleNoArguments())
         handleSend(t, ))
-      endRecordLiteral((, 2)
+      endRecordLiteral((, 2, null)
       handleExpressionFunctionBody(=>, ;)
     endTopLevelMethod((, null, ;)
   endTopLevelDeclaration()
diff --git a/pkg/front_end/parser_testcases/record/record_type_return_on_function_with_type_paremeter.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_type_return_on_function_with_type_paremeter.dart.intertwined.expect
index 088e1f0..bdc9346f 100644
--- a/pkg/front_end/parser_testcases/record/record_type_return_on_function_with_type_paremeter.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_return_on_function_with_type_paremeter.dart.intertwined.expect
@@ -77,7 +77,7 @@
                     parseUnaryExpression(return, true)
                       parsePrimary(return, expression)
                         parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
-                          parseParenthesizedExpressionOrRecordLiteral(return)
+                          parseParenthesizedExpressionOrRecordLiteral(return, null)
                             listener: beginParenthesizedExpressionOrRecordLiteral(()
                             parseExpression(()
                               parsePrecedenceExpression((, 1, true)
@@ -99,7 +99,7 @@
                                           listener: handleNoArguments())
                                         listener: handleSend(t, ))
                             ensureCloseParen(t, ()
-                            listener: endRecordLiteral((, 2)
+                            listener: endRecordLiteral((, 2, null)
                 ensureSemicolon())
                 listener: endReturnStatement(true, return, ;)
                 inGenerator()
@@ -177,7 +177,7 @@
                 parseUnaryExpression(=>, true)
                   parsePrimary(=>, expression)
                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                      parseParenthesizedExpressionOrRecordLiteral(=>)
+                      parseParenthesizedExpressionOrRecordLiteral(=>, null)
                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                         parseExpression(()
                           parsePrecedenceExpression((, 1, true)
@@ -199,7 +199,7 @@
                                       listener: handleNoArguments())
                                     listener: handleSend(t, ))
                         ensureCloseParen(t, ()
-                        listener: endRecordLiteral((, 2)
+                        listener: endRecordLiteral((, 2, null)
             ensureSemicolon())
             listener: handleExpressionFunctionBody(=>, ;)
             inGenerator()
diff --git a/pkg/front_end/parser_testcases/record/record_type_setter.dart.expect b/pkg/front_end/parser_testcases/record/record_type_setter.dart.expect
index 4378062..b5eb0af 100644
--- a/pkg/front_end/parser_testcases/record/record_type_setter.dart.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_setter.dart.expect
@@ -39,7 +39,7 @@
         handleLiteralInt(42)
         beginLiteralString("fortytwo")
         endLiteralString(0, ))
-      endRecordLiteral((, 2)
+      endRecordLiteral((, 2, null)
       handleExpressionFunctionBody(=>, ;)
     endTopLevelMethod((, null, ;)
   endTopLevelDeclaration(void)
@@ -81,7 +81,7 @@
         handleLiteralInt(42)
         beginLiteralString("fortytwo")
         endLiteralString(0, ))
-      endRecordLiteral((, 2)
+      endRecordLiteral((, 2, null)
       handleExpressionFunctionBody(=>, ;)
     endTopLevelMethod(void, set, ;)
   endTopLevelDeclaration(()
@@ -115,7 +115,7 @@
         handleLiteralInt(42)
         beginLiteralString("fortytwo")
         endLiteralString(0, ))
-      endRecordLiteral((, 2)
+      endRecordLiteral((, 2, null)
       handleExpressionFunctionBody(=>, ;)
     endTopLevelMethod((, get, ;)
   endTopLevelDeclaration(void)
@@ -157,7 +157,7 @@
         handleLiteralInt(42)
         beginLiteralString("fortytwo")
         endLiteralString(0, ))
-      endRecordLiteral((, 2)
+      endRecordLiteral((, 2, null)
       handleExpressionFunctionBody(=>, ;)
     endTopLevelMethod(void, set, ;)
   endTopLevelDeclaration(class)
@@ -214,7 +214,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(null, (, (, null, ;)
         endMember()
@@ -257,7 +257,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(set, void, (, null, ;)
         endMember()
@@ -292,7 +292,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(get, (, =>, null, ;)
         endMember()
@@ -335,7 +335,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(set, void, (, null, ;)
         endMember()
@@ -395,7 +395,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(null, static, (, null, ;)
         endMember()
@@ -438,7 +438,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(set, static, (, null, ;)
         endMember()
@@ -473,7 +473,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(get, static, =>, null, ;)
         endMember()
@@ -516,7 +516,7 @@
               handleLiteralInt(42)
               beginLiteralString("fortytwo")
               endLiteralString(0, ))
-            endRecordLiteral((, 2)
+            endRecordLiteral((, 2, null)
             handleExpressionFunctionBody(=>, ;)
           endClassMethod(set, static, (, null, ;)
         endMember()
diff --git a/pkg/front_end/parser_testcases/record/record_type_setter.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_type_setter.dart.intertwined.expect
index 2a1504e..aa67a32 100644
--- a/pkg/front_end/parser_testcases/record/record_type_setter.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_setter.dart.intertwined.expect
@@ -66,7 +66,7 @@
                 parseUnaryExpression(=>, true)
                   parsePrimary(=>, expression)
                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                      parseParenthesizedExpressionOrRecordLiteral(=>)
+                      parseParenthesizedExpressionOrRecordLiteral(=>, null)
                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                         parseExpression(()
                           parsePrecedenceExpression((, 1, true)
@@ -83,7 +83,7 @@
                                     listener: beginLiteralString("fortytwo")
                                     listener: endLiteralString(0, ))
                         ensureCloseParen("fortytwo", ()
-                        listener: endRecordLiteral((, 2)
+                        listener: endRecordLiteral((, 2, null)
             ensureSemicolon())
             listener: handleExpressionFunctionBody(=>, ;)
             inGenerator()
@@ -151,7 +151,7 @@
                 parseUnaryExpression(=>, true)
                   parsePrimary(=>, expression)
                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                      parseParenthesizedExpressionOrRecordLiteral(=>)
+                      parseParenthesizedExpressionOrRecordLiteral(=>, null)
                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                         parseExpression(()
                           parsePrecedenceExpression((, 1, true)
@@ -168,7 +168,7 @@
                                     listener: beginLiteralString("fortytwo")
                                     listener: endLiteralString(0, ))
                         ensureCloseParen("fortytwo", ()
-                        listener: endRecordLiteral((, 2)
+                        listener: endRecordLiteral((, 2, null)
             ensureSemicolon())
             listener: handleExpressionFunctionBody(=>, ;)
             inGenerator()
@@ -223,7 +223,7 @@
                 parseUnaryExpression(=>, true)
                   parsePrimary(=>, expression)
                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                      parseParenthesizedExpressionOrRecordLiteral(=>)
+                      parseParenthesizedExpressionOrRecordLiteral(=>, null)
                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                         parseExpression(()
                           parsePrecedenceExpression((, 1, true)
@@ -240,7 +240,7 @@
                                     listener: beginLiteralString("fortytwo")
                                     listener: endLiteralString(0, ))
                         ensureCloseParen("fortytwo", ()
-                        listener: endRecordLiteral((, 2)
+                        listener: endRecordLiteral((, 2, null)
             ensureSemicolon())
             listener: handleExpressionFunctionBody(=>, ;)
             inGenerator()
@@ -308,7 +308,7 @@
                 parseUnaryExpression(=>, true)
                   parsePrimary(=>, expression)
                     parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                      parseParenthesizedExpressionOrRecordLiteral(=>)
+                      parseParenthesizedExpressionOrRecordLiteral(=>, null)
                         listener: beginParenthesizedExpressionOrRecordLiteral(()
                         parseExpression(()
                           parsePrecedenceExpression((, 1, true)
@@ -325,7 +325,7 @@
                                     listener: beginLiteralString("fortytwo")
                                     listener: endLiteralString(0, ))
                         ensureCloseParen("fortytwo", ()
-                        listener: endRecordLiteral((, 2)
+                        listener: endRecordLiteral((, 2, null)
             ensureSemicolon())
             listener: handleExpressionFunctionBody(=>, ;)
             inGenerator()
@@ -423,7 +423,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -440,7 +440,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -512,7 +512,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -529,7 +529,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -588,7 +588,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -605,7 +605,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -677,7 +677,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -694,7 +694,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -795,7 +795,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -812,7 +812,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -883,7 +883,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -900,7 +900,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -958,7 +958,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -975,7 +975,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
@@ -1046,7 +1046,7 @@
                         parseUnaryExpression(=>, true)
                           parsePrimary(=>, expression)
                             parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=>)
-                              parseParenthesizedExpressionOrRecordLiteral(=>)
+                              parseParenthesizedExpressionOrRecordLiteral(=>, null)
                                 listener: beginParenthesizedExpressionOrRecordLiteral(()
                                 parseExpression(()
                                   parsePrecedenceExpression((, 1, true)
@@ -1063,7 +1063,7 @@
                                             listener: beginLiteralString("fortytwo")
                                             listener: endLiteralString(0, ))
                                 ensureCloseParen("fortytwo", ()
-                                listener: endRecordLiteral((, 2)
+                                listener: endRecordLiteral((, 2, null)
                     ensureSemicolon())
                     listener: handleExpressionFunctionBody(=>, ;)
                     inGenerator()
diff --git a/pkg/front_end/parser_testcases/record/record_type_with_modifiers.dart.expect b/pkg/front_end/parser_testcases/record/record_type_with_modifiers.dart.expect
index 40d36b2..2424804 100644
--- a/pkg/front_end/parser_testcases/record/record_type_with_modifiers.dart.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_with_modifiers.dart.expect
@@ -38,7 +38,7 @@
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(42)
                 handleLiteralInt(42)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endFieldInitializer(=, ;)
           endClassFields(null, null, null, null, null, null, final, 1, final, ;)
         endMember()
@@ -69,7 +69,7 @@
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(42)
                 handleLiteralInt(42)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endFieldInitializer(=, ;)
           endClassFields(null, null, null, static, null, null, null, 1, static, ;)
         endMember()
@@ -100,7 +100,7 @@
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(42)
                 handleLiteralInt(42)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endFieldInitializer(=, ;)
           endClassFields(null, null, null, static, null, null, final, 1, static, ;)
         endMember()
@@ -131,7 +131,7 @@
               beginParenthesizedExpressionOrRecordLiteral(()
                 handleLiteralInt(42)
                 handleLiteralInt(42)
-              endRecordLiteral((, 2)
+              endRecordLiteral((, 2, null)
             endFieldInitializer(=, ;)
           endClassFields(null, null, null, static, null, null, const, 1, static, ;)
         endMember()
diff --git a/pkg/front_end/parser_testcases/record/record_type_with_modifiers.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_type_with_modifiers.dart.intertwined.expect
index 8fcf896..700209c 100644
--- a/pkg/front_end/parser_testcases/record/record_type_with_modifiers.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/record/record_type_with_modifiers.dart.intertwined.expect
@@ -67,7 +67,7 @@
                       parseUnaryExpression(=, true)
                         parsePrimary(=, expression)
                           parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                            parseParenthesizedExpressionOrRecordLiteral(=)
+                            parseParenthesizedExpressionOrRecordLiteral(=, null)
                               listener: beginParenthesizedExpressionOrRecordLiteral(()
                               parseExpression(()
                                 parsePrecedenceExpression((, 1, true)
@@ -82,7 +82,7 @@
                                       parseLiteralInt(,)
                                         listener: handleLiteralInt(42)
                               ensureCloseParen(42, ()
-                              listener: endRecordLiteral((, 2)
+                              listener: endRecordLiteral((, 2, null)
                   listener: endFieldInitializer(=, ;)
                 listener: endClassFields(null, null, null, null, null, null, final, 1, final, ;)
               listener: endMember()
@@ -128,7 +128,7 @@
                       parseUnaryExpression(=, true)
                         parsePrimary(=, expression)
                           parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                            parseParenthesizedExpressionOrRecordLiteral(=)
+                            parseParenthesizedExpressionOrRecordLiteral(=, null)
                               listener: beginParenthesizedExpressionOrRecordLiteral(()
                               parseExpression(()
                                 parsePrecedenceExpression((, 1, true)
@@ -143,7 +143,7 @@
                                       parseLiteralInt(,)
                                         listener: handleLiteralInt(42)
                               ensureCloseParen(42, ()
-                              listener: endRecordLiteral((, 2)
+                              listener: endRecordLiteral((, 2, null)
                   listener: endFieldInitializer(=, ;)
                 listener: endClassFields(null, null, null, static, null, null, null, 1, static, ;)
               listener: endMember()
@@ -189,7 +189,7 @@
                       parseUnaryExpression(=, true)
                         parsePrimary(=, expression)
                           parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                            parseParenthesizedExpressionOrRecordLiteral(=)
+                            parseParenthesizedExpressionOrRecordLiteral(=, null)
                               listener: beginParenthesizedExpressionOrRecordLiteral(()
                               parseExpression(()
                                 parsePrecedenceExpression((, 1, true)
@@ -204,7 +204,7 @@
                                       parseLiteralInt(,)
                                         listener: handleLiteralInt(42)
                               ensureCloseParen(42, ()
-                              listener: endRecordLiteral((, 2)
+                              listener: endRecordLiteral((, 2, null)
                   listener: endFieldInitializer(=, ;)
                 listener: endClassFields(null, null, null, static, null, null, final, 1, static, ;)
               listener: endMember()
@@ -250,7 +250,7 @@
                       parseUnaryExpression(=, true)
                         parsePrimary(=, expression)
                           parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=)
-                            parseParenthesizedExpressionOrRecordLiteral(=)
+                            parseParenthesizedExpressionOrRecordLiteral(=, null)
                               listener: beginParenthesizedExpressionOrRecordLiteral(()
                               parseExpression(()
                                 parsePrecedenceExpression((, 1, true)
@@ -265,7 +265,7 @@
                                       parseLiteralInt(,)
                                         listener: handleLiteralInt(42)
                               ensureCloseParen(42, ()
-                              listener: endRecordLiteral((, 2)
+                              listener: endRecordLiteral((, 2, null)
                   listener: endFieldInitializer(=, ;)
                 listener: endClassFields(null, null, null, static, null, null, const, 1, static, ;)
               listener: endMember()
diff --git a/pkg/front_end/parser_testcases/record/record_typedef.dart b/pkg/front_end/parser_testcases/record/record_typedef.dart
new file mode 100644
index 0000000..3be95d6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_typedef.dart
@@ -0,0 +1 @@
+typedef ({int j}) R2();
diff --git a/pkg/front_end/parser_testcases/record/record_typedef.dart.expect b/pkg/front_end/parser_testcases/record/record_typedef.dart.expect
new file mode 100644
index 0000000..276008d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_typedef.dart.expect
@@ -0,0 +1,24 @@
+beginCompilationUnit(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginTypedef(typedef)
+      beginRecordType(()
+        beginRecordTypeNamedFields({)
+          beginRecordTypeEntry()
+            beginMetadataStar(int)
+            endMetadataStar(0)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(j)
+            handleType(int, null)
+            handleIdentifier(j, recordFieldDeclaration)
+          endRecordTypeEntry()
+        endRecordTypeNamedFields(1, {)
+      endRecordType((, null, 1, true)
+      handleIdentifier(R2, typedefDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.FunctionTypeAlias)
+      endFormalParameters(0, (, ), MemberKind.FunctionTypeAlias)
+    endTypedef(typedef, null, ;)
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/record/record_typedef.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/record_typedef.dart.intertwined.expect
new file mode 100644
index 0000000..db34d16
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_typedef.dart.intertwined.expect
@@ -0,0 +1,42 @@
+parseUnit(typedef)
+  skipErrorTokens(typedef)
+  listener: beginCompilationUnit(typedef)
+  syntheticPreviousToken(typedef)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, typedef, null, Instance of 'DirectiveContext')
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginTypedef(typedef)
+        parseRecordType((, typedef)
+          listener: beginRecordType(()
+          parseRecordTypeNamedFields(()
+            listener: beginRecordTypeNamedFields({)
+            parseRecordTypeField({, identifierIsOptional: false)
+              listener: beginRecordTypeEntry()
+              parseMetadataStar({)
+                listener: beginMetadataStar(int)
+                listener: endMetadataStar(0)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments(j)
+              listener: handleType(int, null)
+              ensureIdentifier(int, recordFieldDeclaration)
+                listener: handleIdentifier(j, recordFieldDeclaration)
+              listener: endRecordTypeEntry()
+            listener: endRecordTypeNamedFields(1, {)
+          ensureCloseParen(}, ()
+          listener: endRecordType((, null, 1, true)
+        ensureIdentifierPotentiallyRecovered(), typedefDeclaration, false)
+          listener: handleIdentifier(R2, typedefDeclaration)
+        listener: handleNoTypeVariables(()
+        parseFormalParametersRequiredOpt(R2, MemberKind.FunctionTypeAlias)
+          parseFormalParametersRest((, MemberKind.FunctionTypeAlias)
+            listener: beginFormalParameters((, MemberKind.FunctionTypeAlias)
+            listener: endFormalParameters(0, (, ), MemberKind.FunctionTypeAlias)
+        ensureSemicolon())
+        listener: endTypedef(typedef, null, ;)
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(typedef)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/record/record_typedef.dart.parser.expect b/pkg/front_end/parser_testcases/record/record_typedef.dart.parser.expect
new file mode 100644
index 0000000..4f18c63
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_typedef.dart.parser.expect
@@ -0,0 +1,5 @@
+typedef ({int j}) R2();
+
+
+typedef[KeywordToken] ([BeginToken]{[BeginToken]int[StringToken] j[StringToken]}[SimpleToken])[SimpleToken] R2[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/record/record_typedef.dart.scanner.expect b/pkg/front_end/parser_testcases/record/record_typedef.dart.scanner.expect
new file mode 100644
index 0000000..4f18c63
--- /dev/null
+++ b/pkg/front_end/parser_testcases/record/record_typedef.dart.scanner.expect
@@ -0,0 +1,5 @@
+typedef ({int j}) R2();
+
+
+typedef[KeywordToken] ([BeginToken]{[BeginToken]int[StringToken] j[StringToken]}[SimpleToken])[SimpleToken] R2[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/test/extensions/data/export_unnamed/lib.dart b/pkg/front_end/test/extensions/data/export_unnamed/lib.dart
index d8f08bf..55622e5 100644
--- a/pkg/front_end/test/extensions/data/export_unnamed/lib.dart
+++ b/pkg/front_end/test/extensions/data/export_unnamed/lib.dart
@@ -4,22 +4,22 @@
 
 /*library: scope=[
   NamedExtension,
-  _extension#0,
+  _extension#1,
   async.dart.FutureExtensions,
   core.dart.EnumByName,
   core.dart.EnumName]*/
 
-/*class: _extension#0:
- builder-name=_extension#0,
+/*class: _extension#1:
+ builder-name=_unnamed-extension_,
  builder-onType=String,
- extension-members=[static staticMethod=_extension#0|staticMethod],
- extension-name=_extension#0,
+ extension-members=[static staticMethod=_extension#1|staticMethod],
+ extension-name=_extension#1,
  extension-onType=String!
 */
 extension on String {
-  /*member: _extension#0|staticMethod:
+  /*member: _extension#1|staticMethod:
    builder-name=staticMethod,
-   member-name=_extension#0|staticMethod
+   member-name=_extension#1|staticMethod
   */
   static void staticMethod() {}
 }
diff --git a/pkg/front_end/test/extensions/data/part/main.dart b/pkg/front_end/test/extensions/data/part/main.dart
index 7f7a5c0..f1cb1e9 100644
--- a/pkg/front_end/test/extensions/data/part/main.dart
+++ b/pkg/front_end/test/extensions/data/part/main.dart
@@ -4,7 +4,7 @@
 
 /*library: scope=[
   Extension,
-  _extension#0,
+  _extension#1,
   async.dart.FutureExtensions,
   core.dart.EnumByName,
   core.dart.EnumName]*/
diff --git a/pkg/front_end/test/extensions/data/part/part.dart b/pkg/front_end/test/extensions/data/part/part.dart
index 468a7a7..e687fca 100644
--- a/pkg/front_end/test/extensions/data/part/part.dart
+++ b/pkg/front_end/test/extensions/data/part/part.dart
@@ -29,26 +29,26 @@
   intMethod() {}
 }
 
-/*class: _extension#0:
- builder-name=_extension#0,
+/*class: _extension#1:
+ builder-name=_unnamed-extension_,
  builder-onType=String,
  extension-members=[
-  stringMethod=_extension#0|stringMethod,
-  tearoff stringMethod=_extension#0|get#stringMethod],
- extension-name=_extension#0,
+  stringMethod=_extension#1|stringMethod,
+  tearoff stringMethod=_extension#1|get#stringMethod],
+ extension-name=_extension#1,
  extension-onType=String!
 */
 extension on String {
-  /*member: _extension#0|stringMethod:
+  /*member: _extension#1|get#stringMethod:
    builder-name=stringMethod,
    builder-params=[#this],
-   member-name=_extension#0|stringMethod,
+   member-name=_extension#1|get#stringMethod,
    member-params=[#this]
   */
-  /*member: _extension#0|get#stringMethod:
+  /*member: _extension#1|stringMethod:
    builder-name=stringMethod,
    builder-params=[#this],
-   member-name=_extension#0|get#stringMethod,
+   member-name=_extension#1|stringMethod,
    member-params=[#this]
   */
   stringMethod() {}
diff --git a/pkg/front_end/test/extensions/data/unnamed_declarations.dart b/pkg/front_end/test/extensions/data/unnamed_declarations.dart
index 8c5d73f..ee6e095 100644
--- a/pkg/front_end/test/extensions/data/unnamed_declarations.dart
+++ b/pkg/front_end/test/extensions/data/unnamed_declarations.dart
@@ -15,7 +15,7 @@
 class A1 {}
 
 /*class: _extension#0:
- builder-name=_extension#0,
+ builder-name=_unnamed-extension_,
  builder-onType=A1,
  extension-members=[
   method=_extension#0|method,
@@ -41,7 +41,7 @@
 }
 
 /*class: _extension#1:
- builder-name=_extension#1,
+ builder-name=_unnamed-extension_,
  builder-onType=A1,
  extension-members=[
   method=_extension#1|method,
@@ -69,7 +69,7 @@
 class B1<T> {}
 
 /*class: _extension#2:
- builder-name=_extension#2,
+ builder-name=_unnamed-extension_,
  builder-onType=B1<T>,
  builder-type-params=[T],
  extension-members=[
@@ -101,7 +101,7 @@
 }
 
 /*class: _extension#3:
- builder-name=_extension#3,
+ builder-name=_unnamed-extension_,
  builder-onType=B1<A1>,
  extension-members=[
   method=_extension#3|method,
@@ -127,7 +127,7 @@
 }
 
 /*class: _extension#4:
- builder-name=_extension#4,
+ builder-name=_unnamed-extension_,
  builder-onType=B1<T>,
  builder-type-params=[T extends A1],
  extension-members=[
diff --git a/pkg/front_end/test/extensions/extensions_test.dart b/pkg/front_end/test/extensions/extensions_test.dart
index 3face97..842cda7 100644
--- a/pkg/front_end/test/extensions/extensions_test.dart
+++ b/pkg/front_end/test/extensions/extensions_test.dart
@@ -141,7 +141,8 @@
       if (library != libraryBuilder) {
         libraryPrefix = '${library.fileUri.pathSegments.last}.';
       }
-      features.addElement(Tags.builderScope, '$libraryPrefix${extension.name}');
+      features.addElement(
+          Tags.builderScope, '$libraryPrefix${extension.extension.name}');
     });
     return features;
   }
diff --git a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
index 7e5d448..b68b540 100644
--- a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
@@ -1056,7 +1056,8 @@
   }
 
   @override
-  void handleParenthesizedCondition(Token token) {
+  void handleParenthesizedCondition(Token token, Token? case_) {
+    expect(case_, null);
     calls.add('handleParenthesizedCondition $token');
   }
 
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 0988fc1..d8b9fda 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -759,7 +759,10 @@
     String resolvedExecutable = Platform.environment['resolvedExecutable'] ??
         Platform.resolvedExecutable;
     Uri vm = Uri.base.resolveUri(new Uri.file(resolvedExecutable));
-    Map<ExperimentalFlag, bool> experimentalFlags = <ExperimentalFlag, bool>{};
+    Map<ExperimentalFlag, bool> experimentalFlags = <ExperimentalFlag, bool>{
+      // Force enable features in development.
+      ExperimentalFlag.records: true,
+    };
 
     void addForcedExperimentalFlag(String name, ExperimentalFlag flag) {
       if (environment.containsKey(name)) {
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
index 2e16cbb..6c8ff31 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
@@ -460,6 +460,36 @@
         lowerBound: "<Z extends FutureOr<dynamic>?>() -> void");
   }
 
+  void test_lower_bound_record() {
+    parseTestLibrary("""
+      class A;
+      class B extends A;
+    """);
+
+    checkLowerBound(type1: "(A, B)", type2: "(B, A)", lowerBound: "(B, B)");
+    checkLowerBound(
+        type1: "(A, {B b})", type2: "(B, {A b})", lowerBound: "(B, {B b})");
+    checkLowerBound(
+        type1: "(A, {(B, {A a}) b})",
+        type2: "(B, {(A, {B a}) b})",
+        lowerBound: "(B, {(B, {B a}) b})");
+    checkLowerBound(type1: "(A?, B)", type2: "(B, A?)", lowerBound: "(B, B)");
+    checkLowerBound(type1: "(A, B?)", type2: "(B?, A)", lowerBound: "(B, B)");
+
+    checkLowerBound(type1: "(A, A)", type2: "(A, A, A)", lowerBound: "Never");
+    checkLowerBound(type1: "(A, A)", type2: "(A, {A a})", lowerBound: "Never");
+    checkLowerBound(type1: "({A a})", type2: "(A, A)", lowerBound: "Never");
+    checkLowerBound(
+        type1: "({A a, B b})", type2: "({A a})", lowerBound: "Never");
+
+    checkLowerBound(type1: "(A, B)", type2: "Record", lowerBound: "(A, B)");
+    checkLowerBound(type2: "Record", type1: "(A, B)", lowerBound: "(A, B)");
+
+    checkLowerBound(
+        type1: "(A, B)", type2: "(A, B) -> void", lowerBound: "Never");
+    checkLowerBound(type1: "Record", type2: "A", lowerBound: "Never");
+  }
+
   void test_lower_bound_identical() {
     parseTestLibrary("class A;");
 
@@ -911,6 +941,36 @@
         upperBound: "([dynamic]) -> dynamic");
   }
 
+  void test_upper_bound_record() {
+    parseTestLibrary("""
+      class A;
+      class B extends A;
+    """);
+
+    checkUpperBound(type1: "(A, B)", type2: "(B, A)", upperBound: "(A, A)");
+    checkUpperBound(
+        type1: "(A, {B b})", type2: "(B, {A b})", upperBound: "(A, {A b})");
+    checkUpperBound(
+        type1: "(A, {(B, {A a}) b})",
+        type2: "(B, {(A, {B a}) b})",
+        upperBound: "(A, {(A, {A a}) b})");
+    checkUpperBound(type1: "(A?, B)", type2: "(B, A?)", upperBound: "(A?, A?)");
+    checkUpperBound(type1: "(A, B?)", type2: "(B?, A)", upperBound: "(A?, A?)");
+
+    checkUpperBound(type1: "(A, A)", type2: "(A, A, A)", upperBound: "Record");
+    checkUpperBound(type1: "(A, A)", type2: "(A, {A a})", upperBound: "Record");
+    checkUpperBound(type1: "({A a})", type2: "(A, A)", upperBound: "Record");
+    checkUpperBound(
+        type1: "({A a, B b})", type2: "({A a})", upperBound: "Record");
+
+    checkUpperBound(type1: "(A, B)", type2: "Record", upperBound: "Record");
+    checkUpperBound(type2: "Record", type1: "(A, B)", upperBound: "Record");
+
+    checkUpperBound(
+        type1: "(A, B)", type2: "(A, B) -> void", upperBound: "Object");
+    checkUpperBound(type1: "Record", type2: "A", upperBound: "Object");
+  }
+
   void test_upper_bound_identical() {
     parseTestLibrary("class A;");
 
diff --git a/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart b/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
index f6c6728..4104c32 100644
--- a/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
+++ b/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
@@ -76,6 +76,8 @@
 }
 class bool extends self::Object {
 }
+class Record extends self::Object {
+}
 class DefaultTypes<S extends self::Object? = dynamic, T extends self::Object, U extends self::List<self::DefaultTypes::S%> = self::List<dynamic>, V extends self::List<self::DefaultTypes::T> = self::List<self::Object>, W extends self::Comparable<self::DefaultTypes::W> = self::Comparable<dynamic>, X extends (self::DefaultTypes::W) → void = (Never) → void, Y extends () → self::DefaultTypes::W = () → self::Comparable<dynamic>> extends self::Object {
 }
 class Super extends self::Object implements self::Comparable<self::Sub> {
diff --git a/pkg/front_end/test/fasta/types/shared_type_tests.dart b/pkg/front_end/test/fasta/types/shared_type_tests.dart
index bf82544..34c71b3 100644
--- a/pkg/front_end/test/fasta/types/shared_type_tests.dart
+++ b/pkg/front_end/test/fasta/types/shared_type_tests.dart
@@ -1071,5 +1071,61 @@
     isSubtype("ExtendedClass", "Extension");
     isSubtype("ExtendedGenericClass<num>", "GenericExtension<num>");
     isSubtype("ExtendedSubclass", "Extension");
+
+    // Records.
+    isSubtype("Never", "(int, String)");
+    isSubtype("(int, String)", "Object");
+    isSubtype("(int, String)", "(Object, Object)");
+    isSubtype("(Never, Never)", "(int, String)");
+    isSubtype("(int, String)", "(num, Object)");
+    isSubtype("Never", "(int, {String foo})");
+    isSubtype("(int, {String foo})", "Object");
+    isSubtype("(int, {String foo})", "(Object, {Object foo})");
+    isSubtype("(Never, {Never foo})", "(int, {String foo})");
+    isSubtype("(int, {String foo})", "(num, {Object foo})");
+    isObliviousSubtype("Null", "(int, String)");
+    isNotSubtype("(int, String)", "Null");
+    isNotSubtype("(int, String, bool)", "(int, String)");
+    isNotSubtype("(int, String)", "(int, String, bool)");
+    isNotSubtype("(int, {String foo})", "(int, {String foo, bool bar})");
+    isNotSubtype("(int, {String foo, bool bar})", "(int, {String foo})");
+    isNotSubtype("(int, Never)", "Never");
+    isSubtype("((int, String), bool)", "((num, Object), Object)");
+    isNotSubtype("((int, String), bool)", "(num, (Object, Object))");
+    isSubtype("(int, String)", "Record");
+    isSubtype("(int, {String foo})", "Record");
+    isSubtype("({int foo, String bar})", "Record");
+    isNotSubtype("Record", "(int, String)");
+    isSubtype("Record", "Object");
+    isSubtype("Never", "Record");
+    isObliviousSubtype("Null", "Record");
+    isNotSubtype("(int, String)", "Function");
+    isNotSubtype("Function", "(int, String)");
+    isNotSubtype("(int, String)", "(int, String) -> void");
+    isNotSubtype("(int, String) -> void", "(int, String)");
+    isNotSubtype("(int, String)", "int");
+    isNotSubtype("int", "(int, String)");
+    isSubtype("(int, String)", "FutureOr<(int, String)>");
+    isNotSubtype("FutureOr<(int, String)>", "(int, String)");
+    isSubtype("T", "(int, String)", typeParameters: "T extends (int, String)");
+    isNotSubtype("(int, String)", "T",
+        typeParameters: "T extends (int, String)");
+    isSubtype("T & (int, String)", "(int, String)",
+        typeParameters: "T extends Record");
+    isSubtype("T & (int, String)", "(int, String)",
+        typeParameters: "T extends Object?");
+    isSubtype("T & (int, double)", "(num, num)",
+        typeParameters: "T extends Record");
+    isSubtype("T & (int, double)", "(num, num)",
+        typeParameters: "T extends Object?");
+    isNotSubtype("(int, String)", "T & (int, String)",
+        typeParameters: "T extends Record");
+    isNotSubtype("(int, String)", "T & (int, String)",
+        typeParameters: "T extends Object?");
+    isSubtype("(int, String)", "(int, String)?");
+    isObliviousSubtype("(int, String)?", "(int, String)");
+    isSubtype("Null", "(int, String)?");
+    isObliviousSubtype("Null", "(int, String)");
+    isObliviousSubtype("(int, String)?", "Record");
   }
 }
diff --git a/pkg/front_end/test/flutter_gallery_leak_tester.dart b/pkg/front_end/test/flutter_gallery_leak_tester.dart
index 68d066a..748bb96 100644
--- a/pkg/front_end/test/flutter_gallery_leak_tester.dart
+++ b/pkg/front_end/test/flutter_gallery_leak_tester.dart
@@ -178,7 +178,6 @@
     "$rootPath/flutter_patched_sdk/",
     "--incremental",
     "--target=flutter",
-    "--debugger-module-names",
     "--output-dill",
     "$rootPath/flutter_server_tmp.dill",
     "--packages",
diff --git a/pkg/front_end/test/incremental_suite.dart b/pkg/front_end/test/incremental_suite.dart
index 4ddfafa..492cc01 100644
--- a/pkg/front_end/test/incremental_suite.dart
+++ b/pkg/front_end/test/incremental_suite.dart
@@ -325,6 +325,10 @@
   static const Property<List<String>?> serializationShouldNotInclude =
       Property.optional(
           'serializationShouldNotInclude', ListValue(StringValue()));
+
+  static const Property<bool> checkConstantCoverageReferences =
+      Property.optional('checkConstantCoverageReferences', BoolValue(),
+          defaultValue: true);
 }
 
 /// Yaml properties for an [ExpressionCompilation] with a [World].
@@ -434,6 +438,10 @@
   {
     "name": "NNBDModeMismatch",
     "group": "Fail"
+  },
+  {
+    "name": "ConstantCoverageReferenceWithoutNode",
+    "group": "Fail"
   }
 ]
 ''';
@@ -476,6 +484,8 @@
 final Expectation InitializedFromDillMismatch =
     staticExpectationSet["InitializedFromDillMismatch"];
 final Expectation NNBDModeMismatch = staticExpectationSet["NNBDModeMismatch"];
+final Expectation ConstantCoverageReferenceWithoutNode =
+    staticExpectationSet["ConstantCoverageReferenceWithoutNode"];
 
 Future<Context> createContext(Chain suite, Map<String, String> environment) {
   const Set<String> knownEnvironmentKeys = {
@@ -842,6 +852,10 @@
 
   final List<String>? serializationShouldNotInclude;
 
+  /// Whether to check if the serialized constant coverage references
+  /// points to anything in itself.
+  final bool checkConstantCoverageReferences;
+
   World({
     required this.modules,
     required this.updateWorldType,
@@ -881,6 +895,7 @@
     required this.expectedContent,
     required this.incrementalSerializationDoesWork,
     required this.serializationShouldNotInclude,
+    required this.checkConstantCoverageReferences,
   });
 
   static World create(Map world) {
@@ -987,6 +1002,9 @@
     List<String>? serializationShouldNotInclude =
         WorldProperties.serializationShouldNotInclude.read(world, keys);
 
+    bool checkConstantCoverageReferences =
+        WorldProperties.checkConstantCoverageReferences.read(world, keys);
+
     if (keys.isNotEmpty) {
       throw "Unknown key(s) for World: $keys";
     }
@@ -1031,6 +1049,7 @@
       expectedContent: expectedContent,
       incrementalSerializationDoesWork: incrementalSerializationDoesWork,
       serializationShouldNotInclude: serializationShouldNotInclude,
+      checkConstantCoverageReferences: checkConstantCoverageReferences,
     );
   }
 }
@@ -1417,6 +1436,12 @@
       newestWholeComponentData = util.postProcess(component!);
       newestWholeComponent = component;
 
+      if (world.checkConstantCoverageReferences) {
+        Result<TestData>? result = checkConstantCoverageReferences(
+            newestWholeComponentData, omitPlatform, sdkSummaryData, data);
+        if (result != null) return result;
+      }
+
       if (world.uriToSourcesDoesntInclude != null) {
         for (String filename in world.uriToSourcesDoesntInclude!) {
           Uri uri = base.resolve(filename);
@@ -1776,6 +1801,38 @@
   }
 }
 
+Result<TestData>? checkConstantCoverageReferences(
+    List<int> newestWholeComponentData,
+    bool omitPlatform,
+    List<int> sdkSummaryData,
+    TestData data) {
+  // Note that this is in a method to avoid "semi-leaks".
+  Component loadedComponent = new Component();
+  if (omitPlatform) {
+    new BinaryBuilder(sdkSummaryData, filename: null)
+        .readComponent(loadedComponent);
+  }
+  new BinaryBuilder(newestWholeComponentData, filename: null)
+      .readComponent(loadedComponent);
+
+  for (MapEntry<Uri, Source> source in loadedComponent.uriToSource.entries) {
+    Set<Reference>? references = source.value.constantCoverageConstructors;
+    if (references != null) {
+      for (Reference reference in references) {
+        if (reference.node == null) {
+          return new Result<TestData>(
+              data,
+              ConstantCoverageReferenceWithoutNode,
+              "Constant coverage reference without node: "
+              "${reference.canonicalName} from ${source.value.importUri} "
+              "indexed in ${source.key}");
+        }
+      }
+    }
+  }
+  return null;
+}
+
 class Strategy extends EquivalenceStrategy {
   const Strategy();
 
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
index bd649ee..aa14a54 100644
--- a/pkg/front_end/test/parser_test_listener.dart
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -89,6 +89,17 @@
   }
 
   @override
+  void handleExtractorPatternFields(
+      int count, Token beginToken, Token endToken) {
+    seen(beginToken);
+    seen(endToken);
+    doPrint('handleExtractorPatternFields('
+        '$count, '
+        '$beginToken, '
+        '$endToken)');
+  }
+
+  @override
   void handleAsyncModifier(Token? asyncToken, Token? starToken) {
     seen(asyncToken);
     seen(starToken);
@@ -1387,11 +1398,11 @@
   }
 
   @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
+  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
     indent--;
     seen(libraryKeyword);
     seen(semicolon);
-    doPrint('endLibraryName(' '$libraryKeyword, ' '$semicolon)');
+    doPrint('endLibraryName(' '$libraryKeyword, ' '$semicolon, ' '$hasName)');
   }
 
   @override
@@ -1402,6 +1413,13 @@
   }
 
   @override
+  void handleMapPatternEntry(Token colon, Token endToken) {
+    seen(colon);
+    seen(endToken);
+    doPrint('handleMapPatternEntry(' '$colon, ' '$endToken)');
+  }
+
+  @override
   void beginLiteralString(Token token) {
     seen(token);
     doPrint('beginLiteralString(' '$token)');
@@ -1981,6 +1999,25 @@
   }
 
   @override
+  void handleNullAssertPattern(Token bang) {
+    seen(bang);
+    doPrint('handleNullAssertPattern(' '$bang)');
+  }
+
+  @override
+  void handleNullCheckPattern(Token question) {
+    seen(question);
+    doPrint('handleNullCheckPattern(' '$question)');
+  }
+
+  @override
+  void handleVariablePattern(Token? keyword, Token variable) {
+    seen(keyword);
+    seen(variable);
+    doPrint('handleVariablePattern(' '$keyword, ' '$variable)');
+  }
+
+  @override
   void handleNoName(Token token) {
     seen(token);
     doPrint('handleNoName(' '$token)');
@@ -2193,6 +2230,12 @@
   }
 
   @override
+  void handleCastPattern(Token operator) {
+    seen(operator);
+    doPrint('handleCastPattern(' '$operator)');
+  }
+
+  @override
   void handleAssignmentExpression(Token token) {
     seen(token);
     doPrint('handleAssignmentExpression(' '$token)');
@@ -2213,6 +2256,20 @@
   }
 
   @override
+  void beginBinaryPattern(Token token) {
+    seen(token);
+    doPrint('beginBinaryPattern(' '$token)');
+    indent++;
+  }
+
+  @override
+  void endBinaryPattern(Token token) {
+    indent--;
+    seen(token);
+    doPrint('endBinaryPattern(' '$token)');
+  }
+
+  @override
   void handleEndingBinaryExpression(Token token) {
     seen(token);
     doPrint('handleEndingBinaryExpression(' '$token)');
@@ -2461,6 +2518,13 @@
   }
 
   @override
+  void handleListPattern(int count, Token leftBracket, Token rightBracket) {
+    seen(leftBracket);
+    seen(rightBracket);
+    doPrint('handleListPattern(' '$count, ' '$leftBracket, ' '$rightBracket)');
+  }
+
+  @override
   void handleLiteralSetOrMap(
     int count,
     Token leftBrace,
@@ -2480,6 +2544,13 @@
   }
 
   @override
+  void handleMapPattern(int count, Token leftBrace, Token rightBrace) {
+    seen(leftBrace);
+    seen(rightBrace);
+    doPrint('handleMapPattern(' '$count, ' '$leftBrace, ' '$rightBrace)');
+  }
+
+  @override
   void handleLiteralNull(Token token) {
     seen(token);
     doPrint('handleLiteralNull(' '$token)');
@@ -2498,6 +2569,12 @@
   }
 
   @override
+  void handlePatternField(Token? colon) {
+    seen(colon);
+    doPrint('handlePatternField(' '$colon)');
+  }
+
+  @override
   void handleNamedRecordField(Token colon) {
     seen(colon);
     doPrint('handleNamedRecordField(' '$colon)');
@@ -2575,9 +2652,10 @@
   }
 
   @override
-  void handleParenthesizedCondition(Token token) {
+  void handleParenthesizedCondition(Token token, Token? case_) {
     seen(token);
-    doPrint('handleParenthesizedCondition(' '$token)');
+    seen(case_);
+    doPrint('handleParenthesizedCondition(' '$token, ' '$case_)');
   }
 
   @override
@@ -2588,10 +2666,17 @@
   }
 
   @override
-  void endRecordLiteral(Token token, int count) {
+  void endRecordLiteral(Token token, int count, Token? constKeyword) {
     indent--;
     seen(token);
-    doPrint('endRecordLiteral(' '$token, ' '$count)');
+    seen(constKeyword);
+    doPrint('endRecordLiteral(' '$token, ' '$count, ' '$constKeyword)');
+  }
+
+  @override
+  void handleRecordPattern(Token token, int count) {
+    seen(token);
+    doPrint('handleRecordPattern(' '$token, ' '$count)');
   }
 
   @override
@@ -2602,6 +2687,30 @@
   }
 
   @override
+  void handleParenthesizedPattern(Token token) {
+    seen(token);
+    doPrint('handleParenthesizedPattern(' '$token)');
+  }
+
+  @override
+  void handleConstantPattern(Token? constKeyword) {
+    seen(constKeyword);
+    doPrint('handleConstantPattern(' '$constKeyword)');
+  }
+
+  @override
+  void handleExtractorPattern(
+      Token firstIdentifier, Token? dot, Token? secondIdentifier) {
+    seen(firstIdentifier);
+    seen(dot);
+    seen(secondIdentifier);
+    doPrint('handleExtractorPattern('
+        '$firstIdentifier, '
+        '$dot, '
+        '$secondIdentifier)');
+  }
+
+  @override
   void handleQualified(Token period) {
     seen(period);
     doPrint('handleQualified(' '$period)');
@@ -2681,6 +2790,12 @@
   }
 
   @override
+  void handleRelationalPattern(Token token) {
+    seen(token);
+    doPrint('handleRelationalPattern(' '$token)');
+  }
+
+  @override
   void handleUnaryPrefixAssignmentExpression(Token token) {
     seen(token);
     doPrint('handleUnaryPrefixAssignmentExpression(' '$token)');
diff --git a/pkg/front_end/test/parser_test_parser.dart b/pkg/front_end/test/parser_test_parser.dart
index 0815a42..bf41fd3 100644
--- a/pkg/front_end/test/parser_test_parser.dart
+++ b/pkg/front_end/test/parser_test_parser.dart
@@ -1601,28 +1601,38 @@
   }
 
   @override
-  Token ensureParenthesizedCondition(Token token) {
-    doPrint('ensureParenthesizedCondition(' '$token)');
+  Token ensureParenthesizedCondition(Token token, {required bool allowCase}) {
+    doPrint(
+        'ensureParenthesizedCondition(' '$token, ' 'allowCase: $allowCase)');
     indent++;
-    var result = super.ensureParenthesizedCondition(token);
+    var result =
+        super.ensureParenthesizedCondition(token, allowCase: allowCase);
     indent--;
     return result;
   }
 
   @override
-  Token parseParenthesizedExpressionOrRecordLiteral(Token token) {
-    doPrint('parseParenthesizedExpressionOrRecordLiteral(' '$token)');
+  Token parseParenthesizedExpressionOrRecordLiteral(
+      Token token, Token? constKeywordForRecord) {
+    doPrint('parseParenthesizedExpressionOrRecordLiteral('
+        '$token, '
+        '$constKeywordForRecord)');
     indent++;
-    var result = super.parseParenthesizedExpressionOrRecordLiteral(token);
+    var result = super.parseParenthesizedExpressionOrRecordLiteral(
+        token, constKeywordForRecord);
     indent--;
     return result;
   }
 
   @override
-  Token parseExpressionInParenthesisRest(Token token) {
-    doPrint('parseExpressionInParenthesisRest(' '$token)');
+  Token parseExpressionInParenthesisRest(Token token,
+      {required bool allowCase}) {
+    doPrint('parseExpressionInParenthesisRest('
+        '$token, '
+        'allowCase: $allowCase)');
     indent++;
-    var result = super.parseExpressionInParenthesisRest(token);
+    var result =
+        super.parseExpressionInParenthesisRest(token, allowCase: allowCase);
     indent--;
     return result;
   }
@@ -2596,4 +2606,67 @@
     indent--;
     return result;
   }
+
+  @override
+  Token parsePattern(Token token, {int precedence = 1}) {
+    doPrint('parsePattern(' '$token, ' 'precedence: $precedence)');
+    indent++;
+    var result = super.parsePattern(token, precedence: precedence);
+    indent--;
+    return result;
+  }
+
+  @override
+  Token parsePrimaryPattern(Token token) {
+    doPrint('parsePrimaryPattern(' '$token)');
+    indent++;
+    var result = super.parsePrimaryPattern(token);
+    indent--;
+    return result;
+  }
+
+  @override
+  Token parseVariablePattern(Token token, {TypeInfo typeInfo = noType}) {
+    doPrint('parseVariablePattern(' '$token, ' 'typeInfo: $typeInfo)');
+    indent++;
+    var result = super.parseVariablePattern(token, typeInfo: typeInfo);
+    indent--;
+    return result;
+  }
+
+  @override
+  Token parseListPatternSuffix(Token token) {
+    doPrint('parseListPatternSuffix(' '$token)');
+    indent++;
+    var result = super.parseListPatternSuffix(token);
+    indent--;
+    return result;
+  }
+
+  @override
+  Token parseMapPatternSuffix(Token token) {
+    doPrint('parseMapPatternSuffix(' '$token)');
+    indent++;
+    var result = super.parseMapPatternSuffix(token);
+    indent--;
+    return result;
+  }
+
+  @override
+  Token parseParenthesizedPatternOrRecordPattern(Token token) {
+    doPrint('parseParenthesizedPatternOrRecordPattern(' '$token)');
+    indent++;
+    var result = super.parseParenthesizedPatternOrRecordPattern(token);
+    indent--;
+    return result;
+  }
+
+  @override
+  Token parseExtractorPatternRest(Token token) {
+    doPrint('parseExtractorPatternRest(' '$token)');
+    indent++;
+    var result = super.parseExtractorPatternRest(token);
+    indent--;
+    return result;
+  }
 }
diff --git a/pkg/front_end/test/patterns/desugaring_test.dart b/pkg/front_end/test/patterns/desugaring_test.dart
new file mode 100644
index 0000000..0ffd299
--- /dev/null
+++ b/pkg/front_end/test/patterns/desugaring_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2022, 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';
+import 'package:kernel/text/ast_to_text.dart';
+
+import 'package:front_end/src/fasta/kernel/internal_ast.dart';
+
+void runTests() {
+  checkExpected(
+      makeSimpleComponentWithPatternVariableDeclaration(
+          new PatternVariableDeclaration(
+              new ListBinder(const DynamicType(), [new WildcardBinder(null)]),
+              new IntLiteral(0))),
+      makeExpectationOfSimpleComponentWithPatternVariableDeclaration(
+          "PatternVariableDeclaration"));
+}
+
+Component makeSimpleComponentWithPatternVariableDeclaration(
+    PatternVariableDeclaration patternVariableDeclaration) {
+  Uri fileUri = Uri.parse("test:///test.dart");
+  Uri importUri = Uri.parse("test.dart");
+
+  Block body = new Block([patternVariableDeclaration]);
+  FunctionNode functionNode = new FunctionNode(body);
+  Procedure procedure = new Procedure(
+      new Name("test"), ProcedureKind.Method, functionNode,
+      fileUri: fileUri);
+  Library library =
+      new Library(importUri, procedures: [procedure], fileUri: fileUri);
+  Component component = new Component(libraries: [library]);
+  return component;
+}
+
+String makeExpectationOfSimpleComponentWithPatternVariableDeclaration(
+    String patternVariableDeclarationExpectation) {
+  return """
+main = <No Member>;
+library from "test.dart" as test {
+
+  method test() → dynamic {
+    ${patternVariableDeclarationExpectation}
+  }
+}
+""";
+}
+
+void checkExpected(Component component, String expected) {
+  String actual = componentToString(component);
+  if (actual != expected) {
+    // This is a very primitive substitute for the diff output of the actual
+    // expectation tests.
+    List<String> actualLines = actual.split("\n");
+    List<String> expectedLines = expected.split("\n");
+    StringBuffer output = new StringBuffer();
+    if (actualLines.length < expectedLines.length) {
+      output.writeln("Actual output is shorter than the expected.");
+    } else if (actualLines.length > expectedLines.length) {
+      output.writeln("Actual output is longer than the expected.");
+    }
+    int minLines = actualLines.length < expectedLines.length
+        ? actualLines.length
+        : expectedLines.length;
+    for (int i = 0; i < minLines; i++) {
+      // Include one line of the difference.
+      if (actualLines[i] != expectedLines[i]) {
+        output.writeln(
+            "Line $i is different in the actual output and the expected.\n"
+            "Actual  : ${actualLines[i]}\n"
+            "Expected: ${expectedLines[i]}");
+        break;
+      }
+    }
+    output.writeln("Full actual output:\n${'=' * 72}\n${actual}\n${'=' * 72}");
+    output.writeln(
+        "Full expected output:\n${'=' * 72}\n${expected}\n${'=' * 72}");
+    throw new StateError("${output}");
+  }
+}
+
+void main(List<String> args) {
+  runTests();
+}
diff --git a/pkg/front_end/test/precedence_info_test.dart b/pkg/front_end/test/precedence_info_test.dart
index e424059..44f2caf 100644
--- a/pkg/front_end/test/precedence_info_test.dart
+++ b/pkg/front_end/test/precedence_info_test.dart
@@ -369,12 +369,12 @@
   /// because it is interpreted as a minus token (precedence 13).
   void test_precedence() {
     const precedenceTable = const <int, List<String>>{
-      17: const <String>['.', '?.', '[', '('],
-      16: const <String>['++', '--'],
-      15: const <String>['!', '~'], // excluded '-', '++', '--'
-      14: const <String>['*', '/', '~/', '%'],
-      13: const <String>['+', '-'],
-      12: const <String>['<<', '>>'],
+      18: const <String>['.', '?.', '[', '('],
+      17: const <String>['++', '--'],
+      16: const <String>['!', '~'], // excluded '-', '++', '--'
+      15: const <String>['*', '/', '~/', '%'],
+      14: const <String>['+', '-'],
+      13: const <String>['<<', '>>'],
       11: const <String>['&'],
       10: const <String>['^'],
       9: const <String>['|'],
diff --git a/pkg/front_end/test/predicates/data/late.dart b/pkg/front_end/test/predicates/data/late.dart
index 1889a70..fa148d6 100644
--- a/pkg/front_end/test/predicates/data/late.dart
+++ b/pkg/front_end/test/predicates/data/late.dart
@@ -462,154 +462,154 @@
 }
 
 extension on int? {
-  /*member: _#_extension#0|unnamedExtensionNonNullableWithoutInitializer:
+  /*member: _#_extension#1|unnamedExtensionNonNullableWithoutInitializer:
    lateField,
-   lateFieldName=_extension#0|unnamedExtensionNonNullableWithoutInitializer,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithoutInitializer
+   lateFieldName=_extension#1|unnamedExtensionNonNullableWithoutInitializer,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNonNullableWithoutInitializer
   */
-  /*member: _extension#0|unnamedExtensionNonNullableWithoutInitializer:
+  /*member: _extension#1|unnamedExtensionNonNullableWithoutInitializer:
    lateFieldGetter,
-   lateFieldName=_extension#0|unnamedExtensionNonNullableWithoutInitializer,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithoutInitializer
+   lateFieldName=_extension#1|unnamedExtensionNonNullableWithoutInitializer,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNonNullableWithoutInitializer
   */
-  /*member: _extension#0|unnamedExtensionNonNullableWithoutInitializer=:
-   lateFieldName=_extension#0|unnamedExtensionNonNullableWithoutInitializer,
+  /*member: _extension#1|unnamedExtensionNonNullableWithoutInitializer=:
+   lateFieldName=_extension#1|unnamedExtensionNonNullableWithoutInitializer,
    lateFieldSetter,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithoutInitializer
+   lateFieldTarget=_#_extension#1|unnamedExtensionNonNullableWithoutInitializer
   */
   static late int unnamedExtensionNonNullableWithoutInitializer;
-  /*member: _#_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer:
+  /*member: _#_extension#1|finalUnnamedExtensionNonNullableWithoutInitializer:
    lateField,
-   lateFieldName=_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer
+   lateFieldName=_extension#1|finalUnnamedExtensionNonNullableWithoutInitializer,
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNonNullableWithoutInitializer
   */
-  /*member: _extension#0|finalUnnamedExtensionNonNullableWithoutInitializer:
+  /*member: _extension#1|finalUnnamedExtensionNonNullableWithoutInitializer:
    lateFieldGetter,
-   lateFieldName=_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer
+   lateFieldName=_extension#1|finalUnnamedExtensionNonNullableWithoutInitializer,
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNonNullableWithoutInitializer
   */
-  /*member: _extension#0|finalUnnamedExtensionNonNullableWithoutInitializer=:
-   lateFieldName=_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer,
+  /*member: _extension#1|finalUnnamedExtensionNonNullableWithoutInitializer=:
+   lateFieldName=_extension#1|finalUnnamedExtensionNonNullableWithoutInitializer,
    lateFieldSetter,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNonNullableWithoutInitializer
   */
   static late final int finalUnnamedExtensionNonNullableWithoutInitializer;
-  /*member: _#_extension#0|unnamedExtensionNullableWithoutInitializer:
+  /*member: _#_extension#1|unnamedExtensionNullableWithoutInitializer:
    lateField,
-   lateFieldName=_extension#0|unnamedExtensionNullableWithoutInitializer,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithoutInitializer
+   lateFieldName=_extension#1|unnamedExtensionNullableWithoutInitializer,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNullableWithoutInitializer
   */
-  /*is-null.member: _#_extension#0|unnamedExtensionNullableWithoutInitializer#isSet:
-   lateFieldName=_extension#0|unnamedExtensionNullableWithoutInitializer,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithoutInitializer,
+  /*is-null.member: _#_extension#1|unnamedExtensionNullableWithoutInitializer#isSet:
+   lateFieldName=_extension#1|unnamedExtensionNullableWithoutInitializer,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNullableWithoutInitializer,
    lateIsSetField
   */
-  /*member: _extension#0|unnamedExtensionNullableWithoutInitializer:
-   lateFieldGetter,
-   lateFieldName=_extension#0|unnamedExtensionNullableWithoutInitializer,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithoutInitializer
-  */
-  /*member: _extension#0|unnamedExtensionNullableWithoutInitializer=:
-   lateFieldName=_extension#0|unnamedExtensionNullableWithoutInitializer,
+  /*member: _extension#1|unnamedExtensionNullableWithoutInitializer=:
+   lateFieldName=_extension#1|unnamedExtensionNullableWithoutInitializer,
    lateFieldSetter,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithoutInitializer
+   lateFieldTarget=_#_extension#1|unnamedExtensionNullableWithoutInitializer
+  */
+  /*member: _extension#1|unnamedExtensionNullableWithoutInitializer:
+   lateFieldGetter,
+   lateFieldName=_extension#1|unnamedExtensionNullableWithoutInitializer,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNullableWithoutInitializer
   */
   static late int? unnamedExtensionNullableWithoutInitializer;
-  /*member: _#_extension#0|finalUnnamedExtensionNullableWithoutInitializer:
+  /*member: _#_extension#1|finalUnnamedExtensionNullableWithoutInitializer:
    lateField,
-   lateFieldName=_extension#0|finalUnnamedExtensionNullableWithoutInitializer,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithoutInitializer
+   lateFieldName=_extension#1|finalUnnamedExtensionNullableWithoutInitializer,
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNullableWithoutInitializer
   */
-  /*is-null.member: _#_extension#0|finalUnnamedExtensionNullableWithoutInitializer#isSet:
-   lateFieldName=_extension#0|finalUnnamedExtensionNullableWithoutInitializer,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithoutInitializer,
+  /*is-null.member: _#_extension#1|finalUnnamedExtensionNullableWithoutInitializer#isSet:
+   lateFieldName=_extension#1|finalUnnamedExtensionNullableWithoutInitializer,
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNullableWithoutInitializer,
    lateIsSetField
   */
-  /*member: _extension#0|finalUnnamedExtensionNullableWithoutInitializer:
+  /*member: _extension#1|finalUnnamedExtensionNullableWithoutInitializer:
    lateFieldGetter,
-   lateFieldName=_extension#0|finalUnnamedExtensionNullableWithoutInitializer,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithoutInitializer
+   lateFieldName=_extension#1|finalUnnamedExtensionNullableWithoutInitializer,
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNullableWithoutInitializer
   */
-  /*member: _extension#0|finalUnnamedExtensionNullableWithoutInitializer=:
-   lateFieldName=_extension#0|finalUnnamedExtensionNullableWithoutInitializer,
+  /*member: _extension#1|finalUnnamedExtensionNullableWithoutInitializer=:
+   lateFieldName=_extension#1|finalUnnamedExtensionNullableWithoutInitializer,
    lateFieldSetter,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithoutInitializer
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNullableWithoutInitializer
   */
   static late final int? finalUnnamedExtensionNullableWithoutInitializer;
-  /*member: _#_extension#0|unnamedExtensionNonNullableWithInitializer:
+  /*member: _#_extension#1|unnamedExtensionNonNullableWithInitializer:
    lateField,
    lateFieldInitializer=13,
-   lateFieldName=_extension#0|unnamedExtensionNonNullableWithInitializer,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithInitializer
+   lateFieldName=_extension#1|unnamedExtensionNonNullableWithInitializer,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNonNullableWithInitializer
   */
-  /*member: _extension#0|unnamedExtensionNonNullableWithInitializer:
+  /*member: _extension#1|unnamedExtensionNonNullableWithInitializer=:
+   lateFieldInitializer=13,
+   lateFieldName=_extension#1|unnamedExtensionNonNullableWithInitializer,
+   lateFieldSetter,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNonNullableWithInitializer
+  */
+  /*member: _extension#1|unnamedExtensionNonNullableWithInitializer:
    lateFieldGetter,
    lateFieldInitializer=13,
-   lateFieldName=_extension#0|unnamedExtensionNonNullableWithInitializer,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithInitializer
-  */
-  /*member: _extension#0|unnamedExtensionNonNullableWithInitializer=:
-   lateFieldInitializer=13,
-   lateFieldName=_extension#0|unnamedExtensionNonNullableWithInitializer,
-   lateFieldSetter,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithInitializer
+   lateFieldName=_extension#1|unnamedExtensionNonNullableWithInitializer,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNonNullableWithInitializer
   */
   static late int unnamedExtensionNonNullableWithInitializer = 13;
-  /*member: _#_extension#0|finalUnnamedExtensionNonNullableWithInitializer:
+  /*member: _#_extension#1|finalUnnamedExtensionNonNullableWithInitializer:
    lateField,
    lateFieldInitializer=14,
-   lateFieldName=_extension#0|finalUnnamedExtensionNonNullableWithInitializer,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNonNullableWithInitializer
+   lateFieldName=_extension#1|finalUnnamedExtensionNonNullableWithInitializer,
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNonNullableWithInitializer
   */
-  /*member: _extension#0|finalUnnamedExtensionNonNullableWithInitializer:
+  /*member: _extension#1|finalUnnamedExtensionNonNullableWithInitializer:
    lateFieldGetter,
    lateFieldInitializer=14,
-   lateFieldName=_extension#0|finalUnnamedExtensionNonNullableWithInitializer,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNonNullableWithInitializer
+   lateFieldName=_extension#1|finalUnnamedExtensionNonNullableWithInitializer,
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNonNullableWithInitializer
   */
   static late final int finalUnnamedExtensionNonNullableWithInitializer = 14;
-  /*member: _#_extension#0|unnamedExtensionNullableWithInitializer:
+  /*member: _#_extension#1|unnamedExtensionNullableWithInitializer:
    lateField,
    lateFieldInitializer=15,
-   lateFieldName=_extension#0|unnamedExtensionNullableWithInitializer,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithInitializer
+   lateFieldName=_extension#1|unnamedExtensionNullableWithInitializer,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNullableWithInitializer
   */
-  /*is-null.member: _#_extension#0|unnamedExtensionNullableWithInitializer#isSet:
+  /*is-null.member: _#_extension#1|unnamedExtensionNullableWithInitializer#isSet:
    lateFieldInitializer=15,
-   lateFieldName=_extension#0|unnamedExtensionNullableWithInitializer,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithInitializer,
+   lateFieldName=_extension#1|unnamedExtensionNullableWithInitializer,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNullableWithInitializer,
    lateIsSetField
   */
-  /*member: _extension#0|unnamedExtensionNullableWithInitializer:
+  /*member: _extension#1|unnamedExtensionNullableWithInitializer=:
+   lateFieldInitializer=15,
+   lateFieldName=_extension#1|unnamedExtensionNullableWithInitializer,
+   lateFieldSetter,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNullableWithInitializer
+  */
+  /*member: _extension#1|unnamedExtensionNullableWithInitializer:
    lateFieldGetter,
    lateFieldInitializer=15,
-   lateFieldName=_extension#0|unnamedExtensionNullableWithInitializer,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithInitializer
-  */
-  /*member: _extension#0|unnamedExtensionNullableWithInitializer=:
-   lateFieldInitializer=15,
-   lateFieldName=_extension#0|unnamedExtensionNullableWithInitializer,
-   lateFieldSetter,
-   lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithInitializer
+   lateFieldName=_extension#1|unnamedExtensionNullableWithInitializer,
+   lateFieldTarget=_#_extension#1|unnamedExtensionNullableWithInitializer
   */
   static late int? unnamedExtensionNullableWithInitializer = 15;
-  /*member: _#_extension#0|finalUnnamedExtensionNullableWithInitializer:
+  /*member: _#_extension#1|finalUnnamedExtensionNullableWithInitializer:
    lateField,
    lateFieldInitializer=16,
-   lateFieldName=_extension#0|finalUnnamedExtensionNullableWithInitializer,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithInitializer
+   lateFieldName=_extension#1|finalUnnamedExtensionNullableWithInitializer,
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNullableWithInitializer
   */
-  /*is-null.member: _#_extension#0|finalUnnamedExtensionNullableWithInitializer#isSet:
+  /*is-null.member: _#_extension#1|finalUnnamedExtensionNullableWithInitializer#isSet:
    lateFieldInitializer=16,
-   lateFieldName=_extension#0|finalUnnamedExtensionNullableWithInitializer,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithInitializer,
+   lateFieldName=_extension#1|finalUnnamedExtensionNullableWithInitializer,
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNullableWithInitializer,
    lateIsSetField
   */
-  /*member: _extension#0|finalUnnamedExtensionNullableWithInitializer:
+  /*member: _extension#1|finalUnnamedExtensionNullableWithInitializer:
    lateFieldGetter,
    lateFieldInitializer=16,
-   lateFieldName=_extension#0|finalUnnamedExtensionNullableWithInitializer,
-   lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithInitializer
+   lateFieldName=_extension#1|finalUnnamedExtensionNullableWithInitializer,
+   lateFieldTarget=_#_extension#1|finalUnnamedExtensionNullableWithInitializer
   */
   static late final int? finalUnnamedExtensionNullableWithInitializer = 16;
 }
diff --git a/pkg/front_end/test/predicates/data/late_names.dart b/pkg/front_end/test/predicates/data/late_names.dart
index c8de49a..c6dd3b4 100644
--- a/pkg/front_end/test/predicates/data/late_names.dart
+++ b/pkg/front_end/test/predicates/data/late_names.dart
@@ -337,67 +337,67 @@
 }
 
 extension on int? {
-  /*member: _#_extension#0|a:
+  /*member: _#_extension#1|a:
    lateField,
-   lateFieldName=_extension#0|a,
-   lateFieldTarget=_#_extension#0|a
+   lateFieldName=_extension#1|a,
+   lateFieldTarget=_#_extension#1|a
   */
-  /*is-null.member: _#_extension#0|a#isSet:
-   lateFieldName=_extension#0|a,
-   lateFieldTarget=_#_extension#0|a,
+  /*is-null.member: _#_extension#1|a#isSet:
+   lateFieldName=_extension#1|a,
+   lateFieldTarget=_#_extension#1|a,
    lateIsSetField
   */
-  /*member: _extension#0|a:
+  /*member: _extension#1|a:
    lateFieldGetter,
-   lateFieldName=_extension#0|a,
-   lateFieldTarget=_#_extension#0|a
+   lateFieldName=_extension#1|a,
+   lateFieldTarget=_#_extension#1|a
   */
-  /*member: _extension#0|a=:
-   lateFieldName=_extension#0|a,
+  /*member: _extension#1|a=:
+   lateFieldName=_extension#1|a,
    lateFieldSetter,
-   lateFieldTarget=_#_extension#0|a
+   lateFieldTarget=_#_extension#1|a
   */
   static late int? a;
-  /*member: _#_extension#0|aa:
+  /*member: _#_extension#1|aa:
    lateField,
-   lateFieldName=_extension#0|aa,
-   lateFieldTarget=_#_extension#0|aa
+   lateFieldName=_extension#1|aa,
+   lateFieldTarget=_#_extension#1|aa
   */
-  /*is-null.member: _#_extension#0|aa#isSet:
-   lateFieldName=_extension#0|aa,
-   lateFieldTarget=_#_extension#0|aa,
+  /*is-null.member: _#_extension#1|aa#isSet:
+   lateFieldName=_extension#1|aa,
+   lateFieldTarget=_#_extension#1|aa,
    lateIsSetField
   */
-  /*member: _extension#0|aa:
+  /*member: _extension#1|aa:
    lateFieldGetter,
-   lateFieldName=_extension#0|aa,
-   lateFieldTarget=_#_extension#0|aa
+   lateFieldName=_extension#1|aa,
+   lateFieldTarget=_#_extension#1|aa
   */
-  /*member: _extension#0|aa=:
-   lateFieldName=_extension#0|aa,
+  /*member: _extension#1|aa=:
+   lateFieldName=_extension#1|aa,
    lateFieldSetter,
-   lateFieldTarget=_#_extension#0|aa
+   lateFieldTarget=_#_extension#1|aa
   */
   static late int? aa;
-  /*member: _#_extension#0|_b:
+  /*member: _#_extension#1|_b:
    lateField,
-   lateFieldName=_extension#0|_b,
-   lateFieldTarget=_#_extension#0|_b
+   lateFieldName=_extension#1|_b,
+   lateFieldTarget=_#_extension#1|_b
   */
-  /*is-null.member: _#_extension#0|_b#isSet:
-   lateFieldName=_extension#0|_b,
-   lateFieldTarget=_#_extension#0|_b,
+  /*is-null.member: _#_extension#1|_b#isSet:
+   lateFieldName=_extension#1|_b,
+   lateFieldTarget=_#_extension#1|_b,
    lateIsSetField
   */
-  /*member: _extension#0|_b:
+  /*member: _extension#1|_b:
    lateFieldGetter,
-   lateFieldName=_extension#0|_b,
-   lateFieldTarget=_#_extension#0|_b
+   lateFieldName=_extension#1|_b,
+   lateFieldTarget=_#_extension#1|_b
   */
-  /*member: _extension#0|_b=:
-   lateFieldName=_extension#0|_b,
+  /*member: _extension#1|_b=:
+   lateFieldName=_extension#1|_b,
    lateFieldSetter,
-   lateFieldTarget=_#_extension#0|_b
+   lateFieldTarget=_#_extension#1|_b
   */
   static late int? _b;
 }
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 50ead00..21a0942 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -25,6 +25,7 @@
 actively
 adequate
 adi
+adjusts
 advantage
 affecting
 affords
@@ -43,6 +44,7 @@
 allocate
 allocator
 altered
+ambiguities
 analogous
 analogy
 analyzes
@@ -125,6 +127,7 @@
 bin
 binder
 binders
+bindings
 binds
 bj
 bk
@@ -205,6 +208,7 @@
 clamp
 clamped
 clarification
+clarify
 clashes
 class's
 clazz
@@ -213,6 +217,7 @@
 clil
 clock
 cls
+cm
 cn
 cnt
 co
@@ -245,6 +250,7 @@
 comprise
 concat
 concatenate
+conceptual
 concerned
 conciser
 cond
@@ -253,11 +259,15 @@
 configs
 configured
 connectivity
+consecutive
+considerable
 consideration
 considering
+constant's
 constness
 constraining
 consult
+consulted
 consumers
 container
 containers
@@ -356,6 +366,7 @@
 destructuring
 deterministic
 dev
+developed
 device
 dictates
 diff
@@ -376,11 +387,13 @@
 disambiguation
 disambiguator
 discovers
+discussion
 disjoint
 dispatched
 distribute
 diverged
 divided
+dm
 doc
 docs
 doesn\'t
@@ -445,6 +458,7 @@
 escalate
 establish
 established
+establishes
 estimate
 et
 eval
@@ -463,6 +477,7 @@
 expense
 experimentation
 explaining
+explicitness
 explore
 exportable
 exportee
@@ -478,6 +493,7 @@
 factor
 factored
 fairly
+falsity
 fangorn
 fasta
 favored
@@ -527,6 +543,7 @@
 fourth
 framework
 freed
+freedom
 freely
 freshly
 frontend
@@ -578,12 +595,15 @@
 hacky
 hadn't
 hang
+happening
 happy
 hardcode
+harmonize
 harness
 hashes
 hashing
 havoc
+heads
 heap
 height
 hello
@@ -598,6 +618,8 @@
 history
 hit
 hoc
+holes
+hook
 hopefully
 horizontal
 href
@@ -617,6 +639,8 @@
 idx
 iff
 il
+illegally
+illustrating
 imitate
 immutability
 impl
@@ -690,6 +714,7 @@
 invariants
 io
 ipv
+irrefutable
 isolate
 isolated
 isolates
@@ -747,6 +772,7 @@
 leafp
 leeway
 left's
+legitimately
 len
 lets
 letting
@@ -806,11 +832,13 @@
 masks
 master
 materialize
+matters
 mature
 mb
 mc
 md
 me
+meanings
 meeting
 merely
 meta
@@ -821,6 +849,7 @@
 migration
 mime
 min
+mini
 misuse
 mixers
 mk
@@ -857,6 +886,7 @@
 nine
 nj
 nk
+nm
 nnbd
 node's
 nomenclature
@@ -915,6 +945,7 @@
 outputting
 overlap
 overlapping
+overlaps
 overloader
 overlooked
 overshadowed
@@ -935,6 +966,7 @@
 parens
 parenteses
 parity
+participates
 particularly
 partof
 patchup
@@ -951,6 +983,7 @@
 permanently
 permit
 permits
+pertinent
 physically
 pi
 picking
@@ -983,6 +1016,7 @@
 precompiling
 preexisted
 preexisting
+preferably
 prefixing
 premark
 preorder
@@ -995,6 +1029,7 @@
 prev
 primarily
 prime
+principal
 printer
 printf
 println
@@ -1102,6 +1137,7 @@
 reflect
 reflectee
 reflective
+refutable
 reg
 regenerations
 regis
@@ -1137,6 +1173,7 @@
 repo
 repositories
 repurposed
+repurposing
 requesting
 requests
 requirement
@@ -1153,6 +1190,7 @@
 reusage
 reversible
 rewinds
+rework
 rewrites
 rewrote
 rf
@@ -1187,6 +1225,8 @@
 scheglov
 scoped
 scoping
+scrutinee
+scrutinee's
 sdk's
 seconds
 sections
@@ -1215,6 +1255,7 @@
 sha
 shadowed
 shallow
+shares
 shas
 shelf
 shifts
@@ -1265,6 +1306,7 @@
 spec
 spec'ed
 specialization
+specializations
 specially
 specifications
 specifics
@@ -1280,6 +1322,7 @@
 ssa
 st
 stability
+stacks
 stacktrace
 stacktraces
 stages
@@ -1324,6 +1367,7 @@
 subname
 subnode
 subnodes
+subpatterns
 subscription
 subsection
 subsections
@@ -1333,6 +1377,7 @@
 substed
 substitutes
 substitutor
+substructure
 subtracted
 subtracting
 subtraction
@@ -1349,6 +1394,7 @@
 supernode
 supers
 suppose
+surprising
 suspended
 svg
 sw
@@ -1391,6 +1437,7 @@
 textualized
 th
 therein
+thereof
 they'll
 thought
 ti
@@ -1398,6 +1445,7 @@
 ticker
 tid
 ties
+tighter
 tiki
 tilde
 till
@@ -1505,11 +1553,13 @@
 unsound
 unsubstituted
 untouched
+unusual
 unwrapper
 unwraps
 unwritten
 unzip
 upcast
+updatable
 ur
 uri's
 url
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index e7f6533..fb577ba 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -2247,7 +2247,6 @@
 portion
 position
 positional
-positionals
 positions
 positive
 positives
diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt
index bfbafd0..575ec3d 100644
--- a/pkg/front_end/test/spell_checking_list_messages.txt
+++ b/pkg/front_end/test/spell_checking_list_messages.txt
@@ -54,6 +54,7 @@
 n
 name.#name
 name.stack
+name3.#name
 nameokempty
 native('native
 nativefieldwrapperclass
@@ -72,6 +73,7 @@
 pubspec.yaml
 r
 re
+record.empty
 sdksummary
 size
 solutions
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index d8c0214..30a620d 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -12,6 +12,7 @@
 aa
 aaa
 abcompile
+ac
 adapter
 adaptor
 adopted
@@ -79,6 +80,7 @@
 bold
 boo
 bots
+boundaries
 boundarykey
 bowtie
 boz
@@ -100,6 +102,7 @@
 calloc
 camel
 capitalized
+carefully
 categorization
 causal
 cb
@@ -284,6 +287,7 @@
 forces
 foreground
 forrest
+forth
 forty
 fortytwo
 foundation
@@ -359,12 +363,14 @@
 instrument
 insufficient
 intdiv
+interactions
 interactive
 interchangeable
 internet
 interpolate
 introducer
 inv
+involves
 ioo
 ish
 it'll
@@ -439,6 +445,7 @@
 newworld
 ninja
 noisy
+nomatch
 nominal
 nondefault
 nonexisting
@@ -482,6 +489,7 @@
 party
 pause
 paused
+pays
 pc
 periodic
 periodically
@@ -556,6 +564,7 @@
 rk
 row
 rows
+ruin
 runtimes
 rv
 sanitize
@@ -594,6 +603,7 @@
 snull
 somehow
 sorter
+soundly
 spans
 spell
 spellcheck
@@ -626,6 +636,7 @@
 subtool
 subtools
 successes
+suggest
 summarization
 summarized
 sup
@@ -639,6 +650,7 @@
 tails
 templates
 theoretically
+thereby
 thereof
 thread
 ticks
@@ -688,6 +700,7 @@
 untrimmed
 unusual
 unversioned
+upgrade
 upload
 upward
 uuid
diff --git a/pkg/front_end/test/web_parser_git_test.dart b/pkg/front_end/test/web_parser_git_test.dart
new file mode 100644
index 0000000..073b68a
--- /dev/null
+++ b/pkg/front_end/test/web_parser_git_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2022, 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:io';
+
+import "utils/io_utils.dart";
+
+Future<void> main(List<String> args) async {
+  Uri dart = repoDir.resolve(
+      "tools/sdks/dart-sdk/bin/dart${Platform.isWindows ? ".exe" : ""}");
+  if (!new File.fromUri(dart).existsSync()) {
+    throw "Couldn't find $dart executable.";
+  }
+
+  Uri d8 = repoDir.resolve(_d8executable);
+  if (!new File.fromUri(d8).existsSync()) {
+    throw "Couldn't find $d8 executable.";
+  }
+
+  Uri fileHelper =
+      repoDir.resolve("pkg/front_end/test/web_parser_git_test_helper.dart");
+  if (!new File.fromUri(fileHelper).existsSync()) {
+    throw "Couldn't find $fileHelper file.";
+  }
+
+  Directory tempDir = Directory.systemTemp.createTempSync("web_parser_test");
+  try {
+    Uri outFile = tempDir.uri.resolve("out.js");
+    ProcessResult dartRun = Process.runSync(dart.toFilePath(), [
+      "compile",
+      "js",
+      "--output",
+      outFile.toFilePath(),
+      "--enable-asserts",
+      fileHelper.toFilePath()
+    ]);
+    if (dartRun.exitCode != 0) {
+      throw "---\n"
+          "Dart run returned ${dartRun.exitCode}.\n"
+          "stdout: ${dartRun.stdout}\n\n"
+          "stderr: ${dartRun.stderr}"
+          "---";
+    }
+    ProcessResult d8Run =
+        Process.runSync(d8.toFilePath(), [outFile.toFilePath()]);
+    if (d8Run.exitCode != 0) {
+      throw "---\n"
+          "D8 run returned ${d8Run.exitCode}.\n"
+          "stdout: ${d8Run.stdout}\n\n"
+          "stderr: ${d8Run.stderr}\n"
+          "---";
+    }
+  } finally {
+    tempDir.deleteSync(recursive: true);
+  }
+}
+
+final Uri repoDir = computeRepoDirUri();
+
+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.');
+}
diff --git a/pkg/front_end/test/web_parser_git_test_helper.dart b/pkg/front_end/test/web_parser_git_test_helper.dart
new file mode 100644
index 0000000..14871b8
--- /dev/null
+++ b/pkg/front_end/test/web_parser_git_test_helper.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2022, 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/forwarding_listener.dart'
+    show ForwardingListener;
+import 'package:_fe_analyzer_shared/src/parser/parser.dart' show Parser;
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
+    show ScannerConfiguration, StringScanner;
+import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
+
+void main(List<String> args) {
+  String source = """
+void main(List<String> args) {
+  print("Hello, World!");
+}
+""";
+
+  ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
+      enableExtensionMethods: true,
+      enableNonNullable: true,
+      enableTripleShift: true);
+
+  StringScanner scanner = new StringScanner(
+    source,
+    includeComments: true,
+    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();
+  ForwardingListener listener = new ForwardingListener();
+  Parser parser = new Parser(listener);
+  parser.parseUnit(firstToken);
+  print("--- End of parsing ---");
+}
diff --git a/pkg/front_end/testcases/dart2js/generic_usage_type_variable.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/generic_usage_type_variable.dart.weak.outline.expect
index 5ba3b99..552acbd 100644
--- a/pkg/front_end/testcases/dart2js/generic_usage_type_variable.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/dart2js/generic_usage_type_variable.dart.weak.outline.expect
@@ -82,15 +82,15 @@
 Extra constant evaluation status:
 Evaluated: ListLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:22:35 -> ListConstant(const <List<dynamic>*>[])
 Evaluated: ConstructorTearOff @ org-dartlang-testcase:///generic_usage_type_variable.dart:18:16 -> ConstructorTearOffConstant(C.name2)
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:26:17 -> MapConstant(const <String*, dynamic>{})
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:32:22 -> MapConstant(const <String*, dynamic>{})
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:25:14 -> MapConstant(const <String*, dynamic>{})
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:24:9 -> MapConstant(const <String*, dynamic>{})
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:35:19 -> MapConstant(const <String*, dynamic>{})
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:33:35 -> MapConstant(const <String*, dynamic>{})
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:25:14 -> MapConstant(const <String*, dynamic>{})
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:24:9 -> MapConstant(const <String*, dynamic>{})
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:34:7 -> MapConstant(const <String*, dynamic>{})
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:39:7 -> MapConstant(const <String*, dynamic>{})
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:39:7 -> MapConstant(const <String*, dynamic>{})
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:39:7 -> MapConstant(const <String*, dynamic>{})
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:39:7 -> MapConstant(const <String*, dynamic>{})
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:39:7 -> MapConstant(const <String*, dynamic>{})
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:39:7 -> MapConstant(const <String*, dynamic>{})
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:39:7 -> MapConstant(const <String*, dynamic>{})
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:39:7 -> MapConstant(const <String*, dynamic>{})
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:39:7 -> MapConstant(const <String*, dynamic>{})
 Evaluated: ListLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:15:23 -> ListConstant(const <C*>[])
 Evaluated: MapLiteral @ org-dartlang-testcase:///generic_usage_type_variable.dart:16:24 -> MapConstant(const <Type*, Type*>{dynamic: dynamic})
 Extra constant evaluation: evaluated: 93, effectively constant: 13
diff --git a/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.strong.expect b/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.strong.expect
index ce2f821..5f0f2b4 100644
--- a/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.strong.expect
+++ b/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.strong.expect
@@ -22,7 +22,6 @@
 @#C5
 class StaticJSClass extends core::Object {
   external constructor •() → sta::StaticJSClass
-    : super core::Object::•()
     ;
   static method _#new#tearOff() → _in::JavaScriptObject
     return new sta::StaticJSClass::•() as _in::JavaScriptObject;
diff --git a/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.strong.transformed.expect
index 03e64fd..89dfddf 100644
--- a/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.strong.transformed.expect
@@ -23,7 +23,6 @@
 @#C5
 class StaticJSClass extends core::Object {
   external constructor •() → sta::StaticJSClass
-    : super core::Object::•()
     ;
   static method _#new#tearOff() → _in::JavaScriptObject
     return new sta::StaticJSClass::•() as _in::JavaScriptObject;
diff --git a/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.weak.expect b/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.weak.expect
index ce2f821..5f0f2b4 100644
--- a/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.weak.expect
+++ b/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.weak.expect
@@ -22,7 +22,6 @@
 @#C5
 class StaticJSClass extends core::Object {
   external constructor •() → sta::StaticJSClass
-    : super core::Object::•()
     ;
   static method _#new#tearOff() → _in::JavaScriptObject
     return new sta::StaticJSClass::•() as _in::JavaScriptObject;
diff --git a/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.weak.transformed.expect b/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.weak.transformed.expect
index 03e64fd..89dfddf 100644
--- a/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/dartdevc/static_interop_erasure/main.dart.weak.transformed.expect
@@ -23,7 +23,6 @@
 @#C5
 class StaticJSClass extends core::Object {
   external constructor •() → sta::StaticJSClass
-    : super core::Object::•()
     ;
   static method _#new#tearOff() → _in::JavaScriptObject
     return new sta::StaticJSClass::•() as _in::JavaScriptObject;
diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.expect
index 3984e35..5764329 100644
--- a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.expect
+++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.expect
@@ -98,8 +98,8 @@
     ;
   get foo() → core::int
     return this.{core::Enum::index}{core::int};
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class B extends core::Object implements core::Enum {
   synthetic constructor •() → self::B
@@ -107,8 +107,8 @@
     ;
   get foo() → core::int
     return this.{core::Enum::index}{core::int};
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class EnumInterface extends core::Object implements core::Enum {
   synthetic constructor •() → self::EnumInterface
@@ -121,8 +121,8 @@
     ;
   get index() → core::int
     return 0;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class AbstractEnumClass extends self::EnumInterface {
   synthetic constructor •() → self::AbstractEnumClass
@@ -133,8 +133,8 @@
   synthetic constructor •() → self::EnumClass2
     : super self::AbstractEnumClass::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class EnumMixin extends core::Enum /*isMixinDeclaration*/  {
 }
@@ -152,8 +152,8 @@
   synthetic constructor •() → self::EnumClass3
     : super self::AbstractEnumClass2::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.transformed.expect
index f61139c..08b2611 100644
--- a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.transformed.expect
@@ -98,8 +98,8 @@
     ;
   get foo() → core::int
     return this.{core::Enum::index}{core::int};
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class B extends core::Object implements core::Enum {
   synthetic constructor •() → self::B
@@ -107,8 +107,8 @@
     ;
   get foo() → core::int
     return this.{core::Enum::index}{core::int};
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class EnumInterface extends core::Object implements core::Enum {
   synthetic constructor •() → self::EnumInterface
@@ -121,8 +121,8 @@
     ;
   get index() → core::int
     return 0;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class AbstractEnumClass extends self::EnumInterface {
   synthetic constructor •() → self::AbstractEnumClass
@@ -133,8 +133,8 @@
   synthetic constructor •() → self::EnumClass2
     : super self::AbstractEnumClass::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class EnumMixin extends core::Enum /*isMixinDeclaration*/  {
 }
@@ -152,8 +152,8 @@
   synthetic constructor •() → self::EnumClass3
     : super self::AbstractEnumClass2::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.expect
index 3984e35..5764329 100644
--- a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.expect
+++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.expect
@@ -98,8 +98,8 @@
     ;
   get foo() → core::int
     return this.{core::Enum::index}{core::int};
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class B extends core::Object implements core::Enum {
   synthetic constructor •() → self::B
@@ -107,8 +107,8 @@
     ;
   get foo() → core::int
     return this.{core::Enum::index}{core::int};
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class EnumInterface extends core::Object implements core::Enum {
   synthetic constructor •() → self::EnumInterface
@@ -121,8 +121,8 @@
     ;
   get index() → core::int
     return 0;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class AbstractEnumClass extends self::EnumInterface {
   synthetic constructor •() → self::AbstractEnumClass
@@ -133,8 +133,8 @@
   synthetic constructor •() → self::EnumClass2
     : super self::AbstractEnumClass::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class EnumMixin extends core::Enum /*isMixinDeclaration*/  {
 }
@@ -152,8 +152,8 @@
   synthetic constructor •() → self::EnumClass3
     : super self::AbstractEnumClass2::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.modular.expect
index 3984e35..5764329 100644
--- a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.modular.expect
@@ -98,8 +98,8 @@
     ;
   get foo() → core::int
     return this.{core::Enum::index}{core::int};
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class B extends core::Object implements core::Enum {
   synthetic constructor •() → self::B
@@ -107,8 +107,8 @@
     ;
   get foo() → core::int
     return this.{core::Enum::index}{core::int};
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class EnumInterface extends core::Object implements core::Enum {
   synthetic constructor •() → self::EnumInterface
@@ -121,8 +121,8 @@
     ;
   get index() → core::int
     return 0;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class AbstractEnumClass extends self::EnumInterface {
   synthetic constructor •() → self::AbstractEnumClass
@@ -133,8 +133,8 @@
   synthetic constructor •() → self::EnumClass2
     : super self::AbstractEnumClass::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class EnumMixin extends core::Enum /*isMixinDeclaration*/  {
 }
@@ -152,8 +152,8 @@
   synthetic constructor •() → self::EnumClass3
     : super self::AbstractEnumClass2::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.outline.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.outline.expect
index 8448a78..ee808c7 100644
--- a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.outline.expect
@@ -97,16 +97,16 @@
     ;
   get foo() → core::int
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_name, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_name, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 class B extends core::Object implements core::Enum {
   synthetic constructor •() → self::B
     ;
   get foo() → core::int
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_name, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_name, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 abstract class EnumInterface extends core::Object implements core::Enum {
   synthetic constructor •() → self::EnumInterface
@@ -117,8 +117,8 @@
     ;
   get index() → core::int
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_name, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_name, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 abstract class AbstractEnumClass extends self::EnumInterface {
   synthetic constructor •() → self::AbstractEnumClass
@@ -127,8 +127,8 @@
 class EnumClass2 extends self::AbstractEnumClass {
   synthetic constructor •() → self::EnumClass2
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_name, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_name, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 abstract class EnumMixin extends core::Enum /*isMixinDeclaration*/  {
 }
@@ -144,32 +144,32 @@
 class EnumClass3 extends self::AbstractEnumClass2 {
   synthetic constructor •() → self::EnumClass3
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_name, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_name, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 static method main() → dynamic
   ;
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> SymbolConstant(#_name)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> SymbolConstant(#_name)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> SymbolConstant(#_name)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> SymbolConstant(#_name)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> SymbolConstant(#_name)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:5:7 -> SymbolConstant(#_name)
+Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:5:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:5:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:5:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:9:7 -> SymbolConstant(#_name)
+Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:9:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:9:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:15:7 -> SymbolConstant(#_name)
+Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:15:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:15:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:15:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:21:7 -> SymbolConstant(#_name)
+Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:21:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:21:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:21:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:27:7 -> SymbolConstant(#_name)
+Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:27:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:27:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///enum_as_supertype_error.dart:27:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 45, effectively constant: 20
diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.transformed.expect
index f61139c..08b2611 100644
--- a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.transformed.expect
@@ -98,8 +98,8 @@
     ;
   get foo() → core::int
     return this.{core::Enum::index}{core::int};
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class B extends core::Object implements core::Enum {
   synthetic constructor •() → self::B
@@ -107,8 +107,8 @@
     ;
   get foo() → core::int
     return this.{core::Enum::index}{core::int};
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class EnumInterface extends core::Object implements core::Enum {
   synthetic constructor •() → self::EnumInterface
@@ -121,8 +121,8 @@
     ;
   get index() → core::int
     return 0;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class AbstractEnumClass extends self::EnumInterface {
   synthetic constructor •() → self::AbstractEnumClass
@@ -133,8 +133,8 @@
   synthetic constructor •() → self::EnumClass2
     : super self::AbstractEnumClass::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 abstract class EnumMixin extends core::Enum /*isMixinDeclaration*/  {
 }
@@ -152,8 +152,8 @@
   synthetic constructor •() → self::EnumClass3
     : super self::AbstractEnumClass2::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+  no-such-method-forwarder get _name() → core::String
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/expression/set_literal.expression.yaml.expect b/pkg/front_end/testcases/expression/set_literal.expression.yaml.expect
index 9fe5f50..e957ffa 100644
--- a/pkg/front_end/testcases/expression/set_literal.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/set_literal.expression.yaml.expect
@@ -2,6 +2,6 @@
 }
 method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
   return block {
-    final dart.core::Set<dart.core::String> #t1 = new dart.collection::_CompactLinkedHashSet::•<dart.core::String>();
+    final dart.core::Set<dart.core::String> #t1 = new dart.collection::_InternalLinkedHashSet::•<dart.core::String>();
     #t1.{dart.core::Set::add}{Invariant}("a"){(dart.core::String) → dart.core::bool};
   } =>#t1;
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.weak.expect b/pkg/front_end/testcases/extensions/call_methods.dart.weak.expect
index 4373c84..bac952d 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.weak.expect
@@ -89,13 +89,13 @@
   get call() → () → core::String
     return () → core::String => "My name is B";
 }
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   get call = self::_extension#0|get#call;
 }
-extension _extension#1 on core::num {
+extension /* unnamed */ _extension#1 on core::num {
   get call = self::_extension#1|get#call;
 }
-extension _extension#2 on core::String {
+extension /* unnamed */ _extension#2 on core::String {
   get call = self::_extension#2|get#call;
 }
 static field core::String topLevel1 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:29:18: Error: Too many positional arguments: 0 allowed, but 1 found.
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/call_methods.dart.weak.modular.expect
index 4373c84..bac952d 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.weak.modular.expect
@@ -89,13 +89,13 @@
   get call() → () → core::String
     return () → core::String => "My name is B";
 }
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   get call = self::_extension#0|get#call;
 }
-extension _extension#1 on core::num {
+extension /* unnamed */ _extension#1 on core::num {
   get call = self::_extension#1|get#call;
 }
-extension _extension#2 on core::String {
+extension /* unnamed */ _extension#2 on core::String {
   get call = self::_extension#2|get#call;
 }
 static field core::String topLevel1 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:29:18: Error: Too many positional arguments: 0 allowed, but 1 found.
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/call_methods.dart.weak.outline.expect
index 88c97e4..483543a 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.weak.outline.expect
@@ -14,13 +14,13 @@
   get call() → () → core::String
     ;
 }
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   get call = self::_extension#0|get#call;
 }
-extension _extension#1 on core::num {
+extension /* unnamed */ _extension#1 on core::num {
   get call = self::_extension#1|get#call;
 }
-extension _extension#2 on core::String {
+extension /* unnamed */ _extension#2 on core::String {
   get call = self::_extension#2|get#call;
 }
 static field core::String topLevel1;
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/call_methods.dart.weak.transformed.expect
index 4373c84..bac952d 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.weak.transformed.expect
@@ -89,13 +89,13 @@
   get call() → () → core::String
     return () → core::String => "My name is B";
 }
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   get call = self::_extension#0|get#call;
 }
-extension _extension#1 on core::num {
+extension /* unnamed */ _extension#1 on core::num {
   get call = self::_extension#1|get#call;
 }
-extension _extension#2 on core::String {
+extension /* unnamed */ _extension#2 on core::String {
   get call = self::_extension#2|get#call;
 }
 static field core::String topLevel1 = invalid-expression "pkg/front_end/testcases/extensions/call_methods.dart:29:18: Error: Too many positional arguments: 0 allowed, but 1 found.
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.expect
index 7a5b11f..50099bc 100644
--- a/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.expect
@@ -8,11 +8,11 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::Class {
+extension /* unnamed */ _extension#0 on self::Class {
   get property1 = self::_extension#0|get#property1;
   set property1 = self::_extension#0|set#property1;
 }
-extension _extension#1 on self::Class {
+extension /* unnamed */ _extension#1 on self::Class {
   get property2 = self::_extension#1|get#property2;
   set property2 = self::_extension#1|set#property2;
 }
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.modular.expect
index 7a5b11f..50099bc 100644
--- a/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.modular.expect
@@ -8,11 +8,11 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::Class {
+extension /* unnamed */ _extension#0 on self::Class {
   get property1 = self::_extension#0|get#property1;
   set property1 = self::_extension#0|set#property1;
 }
-extension _extension#1 on self::Class {
+extension /* unnamed */ _extension#1 on self::Class {
   get property2 = self::_extension#1|get#property2;
   set property2 = self::_extension#1|set#property2;
 }
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.outline.expect
index 0148103..ca93979 100644
--- a/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.outline.expect
@@ -7,11 +7,11 @@
   synthetic constructor •() → self::Class
     ;
 }
-extension _extension#0 on self::Class {
+extension /* unnamed */ _extension#0 on self::Class {
   get property1 = self::_extension#0|get#property1;
   set property1 = self::_extension#0|set#property1;
 }
-extension _extension#1 on self::Class {
+extension /* unnamed */ _extension#1 on self::Class {
   get property2 = self::_extension#1|get#property2;
   set property2 = self::_extension#1|set#property2;
 }
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.transformed.expect
index 06ac9e2..c457352 100644
--- a/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.weak.transformed.expect
@@ -8,11 +8,11 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::Class {
+extension /* unnamed */ _extension#0 on self::Class {
   get property1 = self::_extension#0|get#property1;
   set property1 = self::_extension#0|set#property1;
 }
-extension _extension#1 on self::Class {
+extension /* unnamed */ _extension#1 on self::Class {
   get property2 = self::_extension#1|get#property2;
   set property2 = self::_extension#1|set#property2;
 }
diff --git a/pkg/front_end/testcases/extensions/issue38600.dart.weak.expect b/pkg/front_end/testcases/extensions/issue38600.dart.weak.expect
index 0550755..bb46882 100644
--- a/pkg/front_end/testcases/extensions/issue38600.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/issue38600.dart.weak.expect
@@ -53,7 +53,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on invalid-type {
+extension /* unnamed */ _extension#0 on invalid-type {
 }
 static method try<T extends core::Object? = dynamic>() → dynamic {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/issue38600.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/issue38600.dart.weak.modular.expect
index 0550755..bb46882 100644
--- a/pkg/front_end/testcases/extensions/issue38600.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/issue38600.dart.weak.modular.expect
@@ -53,7 +53,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on invalid-type {
+extension /* unnamed */ _extension#0 on invalid-type {
 }
 static method try<T extends core::Object? = dynamic>() → dynamic {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/issue38600.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/issue38600.dart.weak.outline.expect
index 07a25e2..b09983f 100644
--- a/pkg/front_end/testcases/extensions/issue38600.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38600.dart.weak.outline.expect
@@ -52,7 +52,7 @@
   synthetic constructor •() → self::Class<self::Class::T%>
     ;
 }
-extension _extension#0 on invalid-type {
+extension /* unnamed */ _extension#0 on invalid-type {
 }
 static method try<T extends core::Object? = dynamic>() → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/issue38600.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/issue38600.dart.weak.transformed.expect
index 0550755..bb46882 100644
--- a/pkg/front_end/testcases/extensions/issue38600.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue38600.dart.weak.transformed.expect
@@ -53,7 +53,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on invalid-type {
+extension /* unnamed */ _extension#0 on invalid-type {
 }
 static method try<T extends core::Object? = dynamic>() → dynamic {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.weak.expect b/pkg/front_end/testcases/extensions/issue40816.dart.weak.expect
index e0cb3c1..0bbaeb3 100644
--- a/pkg/front_end/testcases/extensions/issue40816.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.weak.expect
@@ -12,7 +12,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::A {
+extension /* unnamed */ _extension#0 on self::A {
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/issue40816.dart.weak.modular.expect
index e0cb3c1..0bbaeb3 100644
--- a/pkg/front_end/testcases/extensions/issue40816.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.weak.modular.expect
@@ -12,7 +12,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::A {
+extension /* unnamed */ _extension#0 on self::A {
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/issue40816.dart.weak.outline.expect
index bbbf904..3c3b485 100644
--- a/pkg/front_end/testcases/extensions/issue40816.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.weak.outline.expect
@@ -10,7 +10,7 @@
   synthetic constructor •() → self::B
     ;
 }
-extension _extension#0 on self::A {
+extension /* unnamed */ _extension#0 on self::A {
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/issue40816.dart.weak.transformed.expect
index e0cb3c1..0bbaeb3 100644
--- a/pkg/front_end/testcases/extensions/issue40816.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.weak.transformed.expect
@@ -12,7 +12,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::A {
+extension /* unnamed */ _extension#0 on self::A {
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
diff --git a/pkg/front_end/testcases/extensions/issue44003.dart.weak.expect b/pkg/front_end/testcases/extensions/issue44003.dart.weak.expect
index 9d6b12e..73b24b3 100644
--- a/pkg/front_end/testcases/extensions/issue44003.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/issue44003.dart.weak.expect
@@ -18,7 +18,7 @@
 import self as self;
 import "dart:core" as core;
 
-extension _extension#0 on core::List<core::String> {
+extension /* unnamed */ _extension#0 on core::List<core::String> {
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
diff --git a/pkg/front_end/testcases/extensions/issue44003.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/issue44003.dart.weak.modular.expect
index 9d6b12e..73b24b3 100644
--- a/pkg/front_end/testcases/extensions/issue44003.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/issue44003.dart.weak.modular.expect
@@ -18,7 +18,7 @@
 import self as self;
 import "dart:core" as core;
 
-extension _extension#0 on core::List<core::String> {
+extension /* unnamed */ _extension#0 on core::List<core::String> {
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
diff --git a/pkg/front_end/testcases/extensions/issue44003.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/issue44003.dart.weak.outline.expect
index 13d2504..dea4c59 100644
--- a/pkg/front_end/testcases/extensions/issue44003.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue44003.dart.weak.outline.expect
@@ -12,7 +12,7 @@
 import self as self;
 import "dart:core" as core;
 
-extension _extension#0 on core::List<core::String> {
+extension /* unnamed */ _extension#0 on core::List<core::String> {
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
diff --git a/pkg/front_end/testcases/extensions/issue44003.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/issue44003.dart.weak.transformed.expect
index 9d6b12e..73b24b3 100644
--- a/pkg/front_end/testcases/extensions/issue44003.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue44003.dart.weak.transformed.expect
@@ -18,7 +18,7 @@
 import self as self;
 import "dart:core" as core;
 
-extension _extension#0 on core::List<core::String> {
+extension /* unnamed */ _extension#0 on core::List<core::String> {
   method foo = self::_extension#0|foo;
   tearoff foo = self::_extension#0|get#foo;
 }
diff --git a/pkg/front_end/testcases/extensions/issue44844.dart.weak.expect b/pkg/front_end/testcases/extensions/issue44844.dart.weak.expect
index 1066ec8..94590c7 100644
--- a/pkg/front_end/testcases/extensions/issue44844.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/issue44844.dart.weak.expect
@@ -17,7 +17,7 @@
 import self as self;
 import "dart:core" as core;
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   static field foo = self::_extension#0|foo;
 }
 static field core::int _extension#0|foo;
diff --git a/pkg/front_end/testcases/extensions/issue44844.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/issue44844.dart.weak.modular.expect
index 1066ec8..94590c7 100644
--- a/pkg/front_end/testcases/extensions/issue44844.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/issue44844.dart.weak.modular.expect
@@ -17,7 +17,7 @@
 import self as self;
 import "dart:core" as core;
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   static field foo = self::_extension#0|foo;
 }
 static field core::int _extension#0|foo;
diff --git a/pkg/front_end/testcases/extensions/issue44844.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/issue44844.dart.weak.outline.expect
index 7c45f04..aa25596 100644
--- a/pkg/front_end/testcases/extensions/issue44844.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue44844.dart.weak.outline.expect
@@ -12,7 +12,7 @@
 import self as self;
 import "dart:core" as core;
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   static field foo = self::_extension#0|foo;
 }
 static field core::int _extension#0|foo;
diff --git a/pkg/front_end/testcases/extensions/issue44844.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/issue44844.dart.weak.transformed.expect
index 1066ec8..94590c7 100644
--- a/pkg/front_end/testcases/extensions/issue44844.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue44844.dart.weak.transformed.expect
@@ -17,7 +17,7 @@
 import self as self;
 import "dart:core" as core;
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   static field foo = self::_extension#0|foo;
 }
 static field core::int _extension#0|foo;
diff --git a/pkg/front_end/testcases/extensions/issue47345.dart.weak.expect b/pkg/front_end/testcases/extensions/issue47345.dart.weak.expect
index 38d9756..8e2f48f 100644
--- a/pkg/front_end/testcases/extensions/issue47345.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/issue47345.dart.weak.expect
@@ -7,7 +7,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::Foo {
+extension /* unnamed */ _extension#0 on self::Foo {
   static field bar = self::_extension#0|bar;
   static field doubleBar = self::_extension#0|doubleBar;
 }
diff --git a/pkg/front_end/testcases/extensions/issue47345.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/issue47345.dart.weak.modular.expect
index 38d9756..8e2f48f 100644
--- a/pkg/front_end/testcases/extensions/issue47345.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/issue47345.dart.weak.modular.expect
@@ -7,7 +7,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::Foo {
+extension /* unnamed */ _extension#0 on self::Foo {
   static field bar = self::_extension#0|bar;
   static field doubleBar = self::_extension#0|doubleBar;
 }
diff --git a/pkg/front_end/testcases/extensions/issue47345.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/issue47345.dart.weak.outline.expect
index 38ae11a..011d325 100644
--- a/pkg/front_end/testcases/extensions/issue47345.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extensions/issue47345.dart.weak.outline.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::Foo
     ;
 }
-extension _extension#0 on self::Foo {
+extension /* unnamed */ _extension#0 on self::Foo {
   static field bar = self::_extension#0|bar;
   static field doubleBar = self::_extension#0|doubleBar;
 }
diff --git a/pkg/front_end/testcases/extensions/issue47345.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/issue47345.dart.weak.transformed.expect
index 38d9756..8e2f48f 100644
--- a/pkg/front_end/testcases/extensions/issue47345.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue47345.dart.weak.transformed.expect
@@ -7,7 +7,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::Foo {
+extension /* unnamed */ _extension#0 on self::Foo {
   static field bar = self::_extension#0|bar;
   static field doubleBar = self::_extension#0|doubleBar;
 }
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.weak.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.weak.expect
index 1c1d9b9..a764068 100644
--- a/pkg/front_end/testcases/extensions/on_function_type.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.weak.expect
@@ -12,11 +12,11 @@
     : super self::Class::•()
     ;
 }
-extension _extension#0<R extends core::Object? = dynamic, T extends core::Object? = dynamic> on (T%) → R% {
+extension /* unnamed */ _extension#0<R extends core::Object? = dynamic, T extends core::Object? = dynamic> on (T%) → R% {
   get returnType = self::_extension#0|get#returnType;
   get parameterType = self::_extension#0|get#parameterType;
 }
-extension _extension#1<T extends self::Class<T> = self::Class<dynamic>> on <S extends T = dynamic>(T, S) → dynamic {
+extension /* unnamed */ _extension#1<T extends self::Class<T> = self::Class<dynamic>> on <S extends T = dynamic>(T, S) → dynamic {
   get parameterType = self::_extension#1|get#parameterType;
 }
 static method _extension#0|get#returnType<R extends core::Object? = dynamic, T extends core::Object? = dynamic>(lowered final (self::_extension#0|get#returnType::T%) → self::_extension#0|get#returnType::R% #this) → core::Type
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.weak.modular.expect
index 1c1d9b9..a764068 100644
--- a/pkg/front_end/testcases/extensions/on_function_type.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.weak.modular.expect
@@ -12,11 +12,11 @@
     : super self::Class::•()
     ;
 }
-extension _extension#0<R extends core::Object? = dynamic, T extends core::Object? = dynamic> on (T%) → R% {
+extension /* unnamed */ _extension#0<R extends core::Object? = dynamic, T extends core::Object? = dynamic> on (T%) → R% {
   get returnType = self::_extension#0|get#returnType;
   get parameterType = self::_extension#0|get#parameterType;
 }
-extension _extension#1<T extends self::Class<T> = self::Class<dynamic>> on <S extends T = dynamic>(T, S) → dynamic {
+extension /* unnamed */ _extension#1<T extends self::Class<T> = self::Class<dynamic>> on <S extends T = dynamic>(T, S) → dynamic {
   get parameterType = self::_extension#1|get#parameterType;
 }
 static method _extension#0|get#returnType<R extends core::Object? = dynamic, T extends core::Object? = dynamic>(lowered final (self::_extension#0|get#returnType::T%) → self::_extension#0|get#returnType::R% #this) → core::Type
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.weak.outline.expect
index c49b6a0..522a84d 100644
--- a/pkg/front_end/testcases/extensions/on_function_type.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.weak.outline.expect
@@ -10,11 +10,11 @@
   synthetic constructor •() → self::Subclass
     ;
 }
-extension _extension#0<R extends core::Object? = dynamic, T extends core::Object? = dynamic> on (T%) → R% {
+extension /* unnamed */ _extension#0<R extends core::Object? = dynamic, T extends core::Object? = dynamic> on (T%) → R% {
   get returnType = self::_extension#0|get#returnType;
   get parameterType = self::_extension#0|get#parameterType;
 }
-extension _extension#1<T extends self::Class<T> = self::Class<dynamic>> on <S extends T = dynamic>(T, S) → dynamic {
+extension /* unnamed */ _extension#1<T extends self::Class<T> = self::Class<dynamic>> on <S extends T = dynamic>(T, S) → dynamic {
   get parameterType = self::_extension#1|get#parameterType;
 }
 static method _extension#0|get#returnType<R extends core::Object? = dynamic, T extends core::Object? = dynamic>(lowered final (self::_extension#0|get#returnType::T%) → self::_extension#0|get#returnType::R% #this) → core::Type
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.weak.transformed.expect
index 1c1d9b9..a764068 100644
--- a/pkg/front_end/testcases/extensions/on_function_type.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.weak.transformed.expect
@@ -12,11 +12,11 @@
     : super self::Class::•()
     ;
 }
-extension _extension#0<R extends core::Object? = dynamic, T extends core::Object? = dynamic> on (T%) → R% {
+extension /* unnamed */ _extension#0<R extends core::Object? = dynamic, T extends core::Object? = dynamic> on (T%) → R% {
   get returnType = self::_extension#0|get#returnType;
   get parameterType = self::_extension#0|get#parameterType;
 }
-extension _extension#1<T extends self::Class<T> = self::Class<dynamic>> on <S extends T = dynamic>(T, S) → dynamic {
+extension /* unnamed */ _extension#1<T extends self::Class<T> = self::Class<dynamic>> on <S extends T = dynamic>(T, S) → dynamic {
   get parameterType = self::_extension#1|get#parameterType;
 }
 static method _extension#0|get#returnType<R extends core::Object? = dynamic, T extends core::Object? = dynamic>(lowered final (self::_extension#0|get#returnType::T%) → self::_extension#0|get#returnType::R% #this) → core::Type
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.weak.expect b/pkg/front_end/testcases/extensions/private_members.dart.weak.expect
index b67ccfa..ea75037 100644
--- a/pkg/front_end/testcases/extensions/private_members.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/private_members.dart.weak.expect
@@ -127,15 +127,15 @@
   method test2 = pri::PublicExtension|test2;
   tearoff test2 = pri::PublicExtension|get#test2;
 }
-extension _extension#0 on core::String {
-  method publicMethod3 = pri::_extension#0|publicMethod3;
-  tearoff publicMethod3 = pri::_extension#0|get#publicMethod3;
-  method _privateMethod3 = pri::_extension#0|_privateMethod3;
-  tearoff _privateMethod3 = pri::_extension#0|get#_privateMethod3;
-  static method publicStaticMethod3 = pri::_extension#0|publicStaticMethod3;
-  static method _privateStaticMethod3 = pri::_extension#0|_privateStaticMethod3;
-  method test3 = pri::_extension#0|test3;
-  tearoff test3 = pri::_extension#0|get#test3;
+extension /* unnamed */ _extension#2 on core::String {
+  method publicMethod3 = pri::_extension#2|publicMethod3;
+  tearoff publicMethod3 = pri::_extension#2|get#publicMethod3;
+  method _privateMethod3 = pri::_extension#2|_privateMethod3;
+  tearoff _privateMethod3 = pri::_extension#2|get#_privateMethod3;
+  static method publicStaticMethod3 = pri::_extension#2|publicStaticMethod3;
+  static method _privateStaticMethod3 = pri::_extension#2|_privateStaticMethod3;
+  method test3 = pri::_extension#2|test3;
+  tearoff test3 = pri::_extension#2|get#test3;
 }
 static method _PrivateExtension|publicMethod1(lowered final core::String #this) → core::int
   return 42;
@@ -177,33 +177,33 @@
 }
 static method PublicExtension|get#test2(lowered final core::String #this) → () → dynamic
   return () → dynamic => pri::PublicExtension|test2(#this);
-static method _extension#0|publicMethod3(lowered final core::String #this) → core::int
+static method _extension#2|publicMethod3(lowered final core::String #this) → core::int
   return 473;
-static method _extension#0|get#publicMethod3(lowered final core::String #this) → () → core::int
-  return () → core::int => pri::_extension#0|publicMethod3(#this);
-static method _extension#0|_privateMethod3(lowered final core::String #this) → core::int
+static method _extension#2|get#publicMethod3(lowered final core::String #this) → () → core::int
+  return () → core::int => pri::_extension#2|publicMethod3(#this);
+static method _extension#2|_privateMethod3(lowered final core::String #this) → core::int
   return 586;
-static method _extension#0|get#_privateMethod3(lowered final core::String #this) → () → core::int
-  return () → core::int => pri::_extension#0|_privateMethod3(#this);
-static method _extension#0|publicStaticMethod3() → core::int
+static method _extension#2|get#_privateMethod3(lowered final core::String #this) → () → core::int
+  return () → core::int => pri::_extension#2|_privateMethod3(#this);
+static method _extension#2|publicStaticMethod3() → core::int
   return 374;
-static method _extension#0|_privateStaticMethod3() → core::int
+static method _extension#2|_privateStaticMethod3() → core::int
   return 685;
-static method _extension#0|test3(lowered final core::String #this) → dynamic {
-  pri::expect(473, pri::_extension#0|publicMethod3(#this));
-  pri::expect(586, pri::_extension#0|_privateMethod3(#this));
-  pri::expect(374, pri::_extension#0|publicStaticMethod3());
-  pri::expect(685, pri::_extension#0|_privateStaticMethod3());
+static method _extension#2|test3(lowered final core::String #this) → dynamic {
+  pri::expect(473, pri::_extension#2|publicMethod3(#this));
+  pri::expect(586, pri::_extension#2|_privateMethod3(#this));
+  pri::expect(374, pri::_extension#2|publicStaticMethod3());
+  pri::expect(685, pri::_extension#2|_privateStaticMethod3());
 }
-static method _extension#0|get#test3(lowered final core::String #this) → () → dynamic
-  return () → dynamic => pri::_extension#0|test3(#this);
+static method _extension#2|get#test3(lowered final core::String #this) → () → dynamic
+  return () → dynamic => pri::_extension#2|test3(#this);
 static method test() → dynamic {
   pri::expect(42, pri::_PrivateExtension|publicMethod1(""));
   pri::expect(87, pri::_PrivateExtension|_privateMethod1(""));
   pri::expect(123, pri::PublicExtension|publicMethod2(""));
   pri::expect(237, pri::PublicExtension|_privateMethod2(""));
-  pri::expect(473, pri::_extension#0|publicMethod3(""));
-  pri::expect(586, pri::_extension#0|_privateMethod3(""));
+  pri::expect(473, pri::_extension#2|publicMethod3(""));
+  pri::expect(586, pri::_extension#2|_privateMethod3(""));
   pri::expect(42, pri::_PrivateExtension|publicMethod1(""));
   pri::expect(87, pri::_PrivateExtension|_privateMethod1(""));
   pri::expect(123, pri::PublicExtension|publicMethod2(""));
@@ -214,7 +214,7 @@
   pri::expect(732, pri::PublicExtension|_privateStaticMethod2());
   pri::_PrivateExtension|test1("");
   pri::PublicExtension|test2("");
-  pri::_extension#0|test3("");
+  pri::_extension#2|test3("");
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/private_members.dart.weak.modular.expect
index b67ccfa..ea75037 100644
--- a/pkg/front_end/testcases/extensions/private_members.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/private_members.dart.weak.modular.expect
@@ -127,15 +127,15 @@
   method test2 = pri::PublicExtension|test2;
   tearoff test2 = pri::PublicExtension|get#test2;
 }
-extension _extension#0 on core::String {
-  method publicMethod3 = pri::_extension#0|publicMethod3;
-  tearoff publicMethod3 = pri::_extension#0|get#publicMethod3;
-  method _privateMethod3 = pri::_extension#0|_privateMethod3;
-  tearoff _privateMethod3 = pri::_extension#0|get#_privateMethod3;
-  static method publicStaticMethod3 = pri::_extension#0|publicStaticMethod3;
-  static method _privateStaticMethod3 = pri::_extension#0|_privateStaticMethod3;
-  method test3 = pri::_extension#0|test3;
-  tearoff test3 = pri::_extension#0|get#test3;
+extension /* unnamed */ _extension#2 on core::String {
+  method publicMethod3 = pri::_extension#2|publicMethod3;
+  tearoff publicMethod3 = pri::_extension#2|get#publicMethod3;
+  method _privateMethod3 = pri::_extension#2|_privateMethod3;
+  tearoff _privateMethod3 = pri::_extension#2|get#_privateMethod3;
+  static method publicStaticMethod3 = pri::_extension#2|publicStaticMethod3;
+  static method _privateStaticMethod3 = pri::_extension#2|_privateStaticMethod3;
+  method test3 = pri::_extension#2|test3;
+  tearoff test3 = pri::_extension#2|get#test3;
 }
 static method _PrivateExtension|publicMethod1(lowered final core::String #this) → core::int
   return 42;
@@ -177,33 +177,33 @@
 }
 static method PublicExtension|get#test2(lowered final core::String #this) → () → dynamic
   return () → dynamic => pri::PublicExtension|test2(#this);
-static method _extension#0|publicMethod3(lowered final core::String #this) → core::int
+static method _extension#2|publicMethod3(lowered final core::String #this) → core::int
   return 473;
-static method _extension#0|get#publicMethod3(lowered final core::String #this) → () → core::int
-  return () → core::int => pri::_extension#0|publicMethod3(#this);
-static method _extension#0|_privateMethod3(lowered final core::String #this) → core::int
+static method _extension#2|get#publicMethod3(lowered final core::String #this) → () → core::int
+  return () → core::int => pri::_extension#2|publicMethod3(#this);
+static method _extension#2|_privateMethod3(lowered final core::String #this) → core::int
   return 586;
-static method _extension#0|get#_privateMethod3(lowered final core::String #this) → () → core::int
-  return () → core::int => pri::_extension#0|_privateMethod3(#this);
-static method _extension#0|publicStaticMethod3() → core::int
+static method _extension#2|get#_privateMethod3(lowered final core::String #this) → () → core::int
+  return () → core::int => pri::_extension#2|_privateMethod3(#this);
+static method _extension#2|publicStaticMethod3() → core::int
   return 374;
-static method _extension#0|_privateStaticMethod3() → core::int
+static method _extension#2|_privateStaticMethod3() → core::int
   return 685;
-static method _extension#0|test3(lowered final core::String #this) → dynamic {
-  pri::expect(473, pri::_extension#0|publicMethod3(#this));
-  pri::expect(586, pri::_extension#0|_privateMethod3(#this));
-  pri::expect(374, pri::_extension#0|publicStaticMethod3());
-  pri::expect(685, pri::_extension#0|_privateStaticMethod3());
+static method _extension#2|test3(lowered final core::String #this) → dynamic {
+  pri::expect(473, pri::_extension#2|publicMethod3(#this));
+  pri::expect(586, pri::_extension#2|_privateMethod3(#this));
+  pri::expect(374, pri::_extension#2|publicStaticMethod3());
+  pri::expect(685, pri::_extension#2|_privateStaticMethod3());
 }
-static method _extension#0|get#test3(lowered final core::String #this) → () → dynamic
-  return () → dynamic => pri::_extension#0|test3(#this);
+static method _extension#2|get#test3(lowered final core::String #this) → () → dynamic
+  return () → dynamic => pri::_extension#2|test3(#this);
 static method test() → dynamic {
   pri::expect(42, pri::_PrivateExtension|publicMethod1(""));
   pri::expect(87, pri::_PrivateExtension|_privateMethod1(""));
   pri::expect(123, pri::PublicExtension|publicMethod2(""));
   pri::expect(237, pri::PublicExtension|_privateMethod2(""));
-  pri::expect(473, pri::_extension#0|publicMethod3(""));
-  pri::expect(586, pri::_extension#0|_privateMethod3(""));
+  pri::expect(473, pri::_extension#2|publicMethod3(""));
+  pri::expect(586, pri::_extension#2|_privateMethod3(""));
   pri::expect(42, pri::_PrivateExtension|publicMethod1(""));
   pri::expect(87, pri::_PrivateExtension|_privateMethod1(""));
   pri::expect(123, pri::PublicExtension|publicMethod2(""));
@@ -214,7 +214,7 @@
   pri::expect(732, pri::PublicExtension|_privateStaticMethod2());
   pri::_PrivateExtension|test1("");
   pri::PublicExtension|test2("");
-  pri::_extension#0|test3("");
+  pri::_extension#2|test3("");
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/private_members.dart.weak.outline.expect
index 58a8257..cdb1741 100644
--- a/pkg/front_end/testcases/extensions/private_members.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extensions/private_members.dart.weak.outline.expect
@@ -32,15 +32,15 @@
   method test2 = self2::PublicExtension|test2;
   tearoff test2 = self2::PublicExtension|get#test2;
 }
-extension _extension#0 on core::String {
-  method publicMethod3 = self2::_extension#0|publicMethod3;
-  tearoff publicMethod3 = self2::_extension#0|get#publicMethod3;
-  method _privateMethod3 = self2::_extension#0|_privateMethod3;
-  tearoff _privateMethod3 = self2::_extension#0|get#_privateMethod3;
-  static method publicStaticMethod3 = self2::_extension#0|publicStaticMethod3;
-  static method _privateStaticMethod3 = self2::_extension#0|_privateStaticMethod3;
-  method test3 = self2::_extension#0|test3;
-  tearoff test3 = self2::_extension#0|get#test3;
+extension /* unnamed */ _extension#2 on core::String {
+  method publicMethod3 = self2::_extension#2|publicMethod3;
+  tearoff publicMethod3 = self2::_extension#2|get#publicMethod3;
+  method _privateMethod3 = self2::_extension#2|_privateMethod3;
+  tearoff _privateMethod3 = self2::_extension#2|get#_privateMethod3;
+  static method publicStaticMethod3 = self2::_extension#2|publicStaticMethod3;
+  static method _privateStaticMethod3 = self2::_extension#2|_privateStaticMethod3;
+  method test3 = self2::_extension#2|test3;
+  tearoff test3 = self2::_extension#2|get#test3;
 }
 static method _PrivateExtension|publicMethod1(lowered final core::String #this) → core::int
   ;
@@ -74,22 +74,22 @@
   ;
 static method PublicExtension|get#test2(lowered final core::String #this) → () → dynamic
   return () → dynamic => self2::PublicExtension|test2(#this);
-static method _extension#0|publicMethod3(lowered final core::String #this) → core::int
+static method _extension#2|publicMethod3(lowered final core::String #this) → core::int
   ;
-static method _extension#0|get#publicMethod3(lowered final core::String #this) → () → core::int
-  return () → core::int => self2::_extension#0|publicMethod3(#this);
-static method _extension#0|_privateMethod3(lowered final core::String #this) → core::int
+static method _extension#2|get#publicMethod3(lowered final core::String #this) → () → core::int
+  return () → core::int => self2::_extension#2|publicMethod3(#this);
+static method _extension#2|_privateMethod3(lowered final core::String #this) → core::int
   ;
-static method _extension#0|get#_privateMethod3(lowered final core::String #this) → () → core::int
-  return () → core::int => self2::_extension#0|_privateMethod3(#this);
-static method _extension#0|publicStaticMethod3() → core::int
+static method _extension#2|get#_privateMethod3(lowered final core::String #this) → () → core::int
+  return () → core::int => self2::_extension#2|_privateMethod3(#this);
+static method _extension#2|publicStaticMethod3() → core::int
   ;
-static method _extension#0|_privateStaticMethod3() → core::int
+static method _extension#2|_privateStaticMethod3() → core::int
   ;
-static method _extension#0|test3(lowered final core::String #this) → dynamic
+static method _extension#2|test3(lowered final core::String #this) → dynamic
   ;
-static method _extension#0|get#test3(lowered final core::String #this) → () → dynamic
-  return () → dynamic => self2::_extension#0|test3(#this);
+static method _extension#2|get#test3(lowered final core::String #this) → () → dynamic
+  return () → dynamic => self2::_extension#2|test3(#this);
 static method test() → dynamic
   ;
 static method expect(dynamic expected, dynamic actual) → dynamic
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/private_members.dart.weak.transformed.expect
index b67ccfa..ea75037 100644
--- a/pkg/front_end/testcases/extensions/private_members.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/private_members.dart.weak.transformed.expect
@@ -127,15 +127,15 @@
   method test2 = pri::PublicExtension|test2;
   tearoff test2 = pri::PublicExtension|get#test2;
 }
-extension _extension#0 on core::String {
-  method publicMethod3 = pri::_extension#0|publicMethod3;
-  tearoff publicMethod3 = pri::_extension#0|get#publicMethod3;
-  method _privateMethod3 = pri::_extension#0|_privateMethod3;
-  tearoff _privateMethod3 = pri::_extension#0|get#_privateMethod3;
-  static method publicStaticMethod3 = pri::_extension#0|publicStaticMethod3;
-  static method _privateStaticMethod3 = pri::_extension#0|_privateStaticMethod3;
-  method test3 = pri::_extension#0|test3;
-  tearoff test3 = pri::_extension#0|get#test3;
+extension /* unnamed */ _extension#2 on core::String {
+  method publicMethod3 = pri::_extension#2|publicMethod3;
+  tearoff publicMethod3 = pri::_extension#2|get#publicMethod3;
+  method _privateMethod3 = pri::_extension#2|_privateMethod3;
+  tearoff _privateMethod3 = pri::_extension#2|get#_privateMethod3;
+  static method publicStaticMethod3 = pri::_extension#2|publicStaticMethod3;
+  static method _privateStaticMethod3 = pri::_extension#2|_privateStaticMethod3;
+  method test3 = pri::_extension#2|test3;
+  tearoff test3 = pri::_extension#2|get#test3;
 }
 static method _PrivateExtension|publicMethod1(lowered final core::String #this) → core::int
   return 42;
@@ -177,33 +177,33 @@
 }
 static method PublicExtension|get#test2(lowered final core::String #this) → () → dynamic
   return () → dynamic => pri::PublicExtension|test2(#this);
-static method _extension#0|publicMethod3(lowered final core::String #this) → core::int
+static method _extension#2|publicMethod3(lowered final core::String #this) → core::int
   return 473;
-static method _extension#0|get#publicMethod3(lowered final core::String #this) → () → core::int
-  return () → core::int => pri::_extension#0|publicMethod3(#this);
-static method _extension#0|_privateMethod3(lowered final core::String #this) → core::int
+static method _extension#2|get#publicMethod3(lowered final core::String #this) → () → core::int
+  return () → core::int => pri::_extension#2|publicMethod3(#this);
+static method _extension#2|_privateMethod3(lowered final core::String #this) → core::int
   return 586;
-static method _extension#0|get#_privateMethod3(lowered final core::String #this) → () → core::int
-  return () → core::int => pri::_extension#0|_privateMethod3(#this);
-static method _extension#0|publicStaticMethod3() → core::int
+static method _extension#2|get#_privateMethod3(lowered final core::String #this) → () → core::int
+  return () → core::int => pri::_extension#2|_privateMethod3(#this);
+static method _extension#2|publicStaticMethod3() → core::int
   return 374;
-static method _extension#0|_privateStaticMethod3() → core::int
+static method _extension#2|_privateStaticMethod3() → core::int
   return 685;
-static method _extension#0|test3(lowered final core::String #this) → dynamic {
-  pri::expect(473, pri::_extension#0|publicMethod3(#this));
-  pri::expect(586, pri::_extension#0|_privateMethod3(#this));
-  pri::expect(374, pri::_extension#0|publicStaticMethod3());
-  pri::expect(685, pri::_extension#0|_privateStaticMethod3());
+static method _extension#2|test3(lowered final core::String #this) → dynamic {
+  pri::expect(473, pri::_extension#2|publicMethod3(#this));
+  pri::expect(586, pri::_extension#2|_privateMethod3(#this));
+  pri::expect(374, pri::_extension#2|publicStaticMethod3());
+  pri::expect(685, pri::_extension#2|_privateStaticMethod3());
 }
-static method _extension#0|get#test3(lowered final core::String #this) → () → dynamic
-  return () → dynamic => pri::_extension#0|test3(#this);
+static method _extension#2|get#test3(lowered final core::String #this) → () → dynamic
+  return () → dynamic => pri::_extension#2|test3(#this);
 static method test() → dynamic {
   pri::expect(42, pri::_PrivateExtension|publicMethod1(""));
   pri::expect(87, pri::_PrivateExtension|_privateMethod1(""));
   pri::expect(123, pri::PublicExtension|publicMethod2(""));
   pri::expect(237, pri::PublicExtension|_privateMethod2(""));
-  pri::expect(473, pri::_extension#0|publicMethod3(""));
-  pri::expect(586, pri::_extension#0|_privateMethod3(""));
+  pri::expect(473, pri::_extension#2|publicMethod3(""));
+  pri::expect(586, pri::_extension#2|_privateMethod3(""));
   pri::expect(42, pri::_PrivateExtension|publicMethod1(""));
   pri::expect(87, pri::_PrivateExtension|_privateMethod1(""));
   pri::expect(123, pri::PublicExtension|publicMethod2(""));
@@ -214,7 +214,7 @@
   pri::expect(732, pri::PublicExtension|_privateStaticMethod2());
   pri::_PrivateExtension|test1("");
   pri::PublicExtension|test2("");
-  pri::_extension#0|test3("");
+  pri::_extension#2|test3("");
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.expect
index d69a033..4f176fc 100644
--- a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.expect
@@ -18,7 +18,7 @@
   method toString() → core::String
     return "Class2(${this.{self::Class2::field}{core::int}})";
 }
-extension _extension#0 on self::Class1 {
+extension /* unnamed */ _extension#0 on self::Class1 {
   method method = self::_extension#0|method;
   tearoff method = self::_extension#0|get#method;
   method genericMethod = self::_extension#0|genericMethod;
@@ -26,7 +26,7 @@
   get property = self::_extension#0|get#property;
   set property = self::_extension#0|set#property;
 }
-extension _extension#1 on self::Class2 {
+extension /* unnamed */ _extension#1 on self::Class2 {
   method method = self::_extension#1|method;
   tearoff method = self::_extension#1|get#method;
   method genericMethod = self::_extension#1|genericMethod;
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.modular.expect
index d69a033..4f176fc 100644
--- a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.modular.expect
@@ -18,7 +18,7 @@
   method toString() → core::String
     return "Class2(${this.{self::Class2::field}{core::int}})";
 }
-extension _extension#0 on self::Class1 {
+extension /* unnamed */ _extension#0 on self::Class1 {
   method method = self::_extension#0|method;
   tearoff method = self::_extension#0|get#method;
   method genericMethod = self::_extension#0|genericMethod;
@@ -26,7 +26,7 @@
   get property = self::_extension#0|get#property;
   set property = self::_extension#0|set#property;
 }
-extension _extension#1 on self::Class2 {
+extension /* unnamed */ _extension#1 on self::Class2 {
   method method = self::_extension#1|method;
   tearoff method = self::_extension#1|get#method;
   method genericMethod = self::_extension#1|genericMethod;
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.outline.expect
index fd6ebb3..13ce203 100644
--- a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.outline.expect
@@ -16,7 +16,7 @@
   method toString() → core::String
     ;
 }
-extension _extension#0 on self::Class1 {
+extension /* unnamed */ _extension#0 on self::Class1 {
   method method = self::_extension#0|method;
   tearoff method = self::_extension#0|get#method;
   method genericMethod = self::_extension#0|genericMethod;
@@ -24,7 +24,7 @@
   get property = self::_extension#0|get#property;
   set property = self::_extension#0|set#property;
 }
-extension _extension#1 on self::Class2 {
+extension /* unnamed */ _extension#1 on self::Class2 {
   method method = self::_extension#1|method;
   tearoff method = self::_extension#1|get#method;
   method genericMethod = self::_extension#1|genericMethod;
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.transformed.expect
index 82dee77..2704cd9 100644
--- a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.weak.transformed.expect
@@ -18,7 +18,7 @@
   method toString() → core::String
     return "Class2(${this.{self::Class2::field}{core::int}})";
 }
-extension _extension#0 on self::Class1 {
+extension /* unnamed */ _extension#0 on self::Class1 {
   method method = self::_extension#0|method;
   tearoff method = self::_extension#0|get#method;
   method genericMethod = self::_extension#0|genericMethod;
@@ -26,7 +26,7 @@
   get property = self::_extension#0|get#property;
   set property = self::_extension#0|set#property;
 }
-extension _extension#1 on self::Class2 {
+extension /* unnamed */ _extension#1 on self::Class2 {
   method method = self::_extension#1|method;
   tearoff method = self::_extension#1|get#method;
   method genericMethod = self::_extension#1|genericMethod;
diff --git a/pkg/front_end/testcases/general/abstract_members.dart.weak.outline.expect b/pkg/front_end/testcases/general/abstract_members.dart.weak.outline.expect
index ed720cb..c136166 100644
--- a/pkg/front_end/testcases/general/abstract_members.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/abstract_members.dart.weak.outline.expect
@@ -325,32 +325,32 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:10:8 -> SymbolConstant(#interfaceMethod2)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:10:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:10:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:10:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:21:3 -> SymbolConstant(#abstractMethod)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:21:3 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:21:3 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:21:3 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:6:8 -> SymbolConstant(#interfaceMethod1)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:6:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:6:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:6:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:16:8 -> SymbolConstant(#interfaceMethod3)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:16:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:16:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:16:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:24:12 -> SymbolConstant(#property3=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:24:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:24:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:12:7 -> SymbolConstant(#interfaceMethod1=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:12:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:12:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:22:12 -> SymbolConstant(#property1=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:22:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:22:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:23:12 -> SymbolConstant(#property2=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:23:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:23:12 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> SymbolConstant(#interfaceMethod2)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> SymbolConstant(#abstractMethod)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> SymbolConstant(#interfaceMethod1)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> SymbolConstant(#interfaceMethod3)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> SymbolConstant(#property3=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> SymbolConstant(#interfaceMethod1=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> SymbolConstant(#property1=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> SymbolConstant(#property2=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_members.dart:42:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 73, effectively constant: 28
diff --git a/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.weak.outline.expect b/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.weak.outline.expect
index 0686850..6e7230a 100644
--- a/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.weak.outline.expect
@@ -30,8 +30,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_overrides_concrete_with_no_such_method.dart:10:5 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_overrides_concrete_with_no_such_method.dart:10:5 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_overrides_concrete_with_no_such_method.dart:10:5 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_overrides_concrete_with_no_such_method.dart:10:5 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_overrides_concrete_with_no_such_method.dart:17:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_overrides_concrete_with_no_such_method.dart:17:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_overrides_concrete_with_no_such_method.dart:17:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_overrides_concrete_with_no_such_method.dart:17:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 9, effectively constant: 4
diff --git a/pkg/front_end/testcases/general/bounds_literals.dart.weak.transformed.expect b/pkg/front_end/testcases/general/bounds_literals.dart.weak.transformed.expect
index 5c630d7..c308cd0 100644
--- a/pkg/front_end/testcases/general/bounds_literals.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/bounds_literals.dart.weak.transformed.expect
@@ -146,52 +146,52 @@
   <self::G<self::ConcreteClass>, self::G<self::Class<self::ConcreteClass>>>{};
   <self::G<core::Object>, self::G<core::int>>{};
   block {
-    final core::Set<self::Class<dynamic>> #t1 = new col::_CompactLinkedHashSet::•<self::Class<dynamic>>();
+    final core::Set<self::Class<dynamic>> #t1 = new col::_InternalLinkedHashSet::•<self::Class<dynamic>>();
   } =>#t1;
   block {
-    final core::Set<dynamic> #t2 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t2 = new col::_InternalLinkedHashSet::•<dynamic>();
   } =>#t2;
   block {
-    final core::Set<self::Class<dynamic>> #t3 = new col::_CompactLinkedHashSet::•<self::Class<dynamic>>();
+    final core::Set<self::Class<dynamic>> #t3 = new col::_InternalLinkedHashSet::•<self::Class<dynamic>>();
   } =>#t3;
   block {
-    final core::Set<self::Class<dynamic>> #t4 = new col::_CompactLinkedHashSet::•<self::Class<dynamic>>();
+    final core::Set<self::Class<dynamic>> #t4 = new col::_InternalLinkedHashSet::•<self::Class<dynamic>>();
   } =>#t4;
   block {
-    final core::Set<core::Object> #t5 = new col::_CompactLinkedHashSet::•<core::Object>();
+    final core::Set<core::Object> #t5 = new col::_InternalLinkedHashSet::•<core::Object>();
   } =>#t5;
   block {
-    final core::Set<core::int> #t6 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t6 = new col::_InternalLinkedHashSet::•<core::int>();
   } =>#t6;
   block {
-    final core::Set<self::ConcreteClass> #t7 = new col::_CompactLinkedHashSet::•<self::ConcreteClass>();
+    final core::Set<self::ConcreteClass> #t7 = new col::_InternalLinkedHashSet::•<self::ConcreteClass>();
   } =>#t7;
   block {
-    final core::Set<self::Class<self::ConcreteClass>> #t8 = new col::_CompactLinkedHashSet::•<self::Class<self::ConcreteClass>>();
+    final core::Set<self::Class<self::ConcreteClass>> #t8 = new col::_InternalLinkedHashSet::•<self::Class<self::ConcreteClass>>();
   } =>#t8;
   block {
-    final core::Set<self::G<self::Class<dynamic>>> #t9 = new col::_CompactLinkedHashSet::•<self::G<self::Class<dynamic>>>();
+    final core::Set<self::G<self::Class<dynamic>>> #t9 = new col::_InternalLinkedHashSet::•<self::G<self::Class<dynamic>>>();
   } =>#t9;
   block {
-    final core::Set<self::G<self::Class<dynamic>>> #t10 = new col::_CompactLinkedHashSet::•<self::G<self::Class<dynamic>>>();
+    final core::Set<self::G<self::Class<dynamic>>> #t10 = new col::_InternalLinkedHashSet::•<self::G<self::Class<dynamic>>>();
   } =>#t10;
   block {
-    final core::Set<self::G<self::Class<dynamic>>> #t11 = new col::_CompactLinkedHashSet::•<self::G<self::Class<dynamic>>>();
+    final core::Set<self::G<self::Class<dynamic>>> #t11 = new col::_InternalLinkedHashSet::•<self::G<self::Class<dynamic>>>();
   } =>#t11;
   block {
-    final core::Set<self::G<self::Class<dynamic>>> #t12 = new col::_CompactLinkedHashSet::•<self::G<self::Class<dynamic>>>();
+    final core::Set<self::G<self::Class<dynamic>>> #t12 = new col::_InternalLinkedHashSet::•<self::G<self::Class<dynamic>>>();
   } =>#t12;
   block {
-    final core::Set<self::G<self::ConcreteClass>> #t13 = new col::_CompactLinkedHashSet::•<self::G<self::ConcreteClass>>();
+    final core::Set<self::G<self::ConcreteClass>> #t13 = new col::_InternalLinkedHashSet::•<self::G<self::ConcreteClass>>();
   } =>#t13;
   block {
-    final core::Set<self::G<self::Class<self::ConcreteClass>>> #t14 = new col::_CompactLinkedHashSet::•<self::G<self::Class<self::ConcreteClass>>>();
+    final core::Set<self::G<self::Class<self::ConcreteClass>>> #t14 = new col::_InternalLinkedHashSet::•<self::G<self::Class<self::ConcreteClass>>>();
   } =>#t14;
   block {
-    final core::Set<self::G<core::Object>> #t15 = new col::_CompactLinkedHashSet::•<self::G<core::Object>>();
+    final core::Set<self::G<core::Object>> #t15 = new col::_InternalLinkedHashSet::•<self::G<core::Object>>();
   } =>#t15;
   block {
-    final core::Set<self::G<core::int>> #t16 = new col::_CompactLinkedHashSet::•<self::G<core::int>>();
+    final core::Set<self::G<core::int>> #t16 = new col::_InternalLinkedHashSet::•<self::G<core::int>>();
   } =>#t16;
   core::_GrowableList::•<self::Class<dynamic>>(0);
   core::_GrowableList::•<dynamic>(0);
diff --git a/pkg/front_end/testcases/general/constants/const_collections.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/const_collections.dart.weak.transformed.expect
index 2b18bc2..9dec79d 100644
--- a/pkg/front_end/testcases/general/constants/const_collections.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/constants/const_collections.dart.weak.transformed.expect
@@ -354,7 +354,7 @@
   core::print(#C11);
   core::print(#C14);
   core::print( block {
-    final core::Set<core::String> #t2 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Set<core::String> #t2 = new col::_InternalLinkedHashSet::•<core::String>();
     #t2.{core::Set::add}{Invariant}("hello"){(core::String) → core::bool};
   } =>#t2);
   core::print(#C16);
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.expect b/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.expect
index 2fa40d9..0ee60d7 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.expect
@@ -19,7 +19,6 @@
 @#C3
 class ParallaxOptions extends core::Object /*hasConstConstructor*/  {
   external const constructor •() → self::ParallaxOptions
-    : super core::Object::•()
     ;
   static method _#new#tearOff() → self::ParallaxOptions
     return new self::ParallaxOptions::•();
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.modular.expect b/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.modular.expect
index 2fa40d9..0ee60d7 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.modular.expect
@@ -19,7 +19,6 @@
 @#C3
 class ParallaxOptions extends core::Object /*hasConstConstructor*/  {
   external const constructor •() → self::ParallaxOptions
-    : super core::Object::•()
     ;
   static method _#new#tearOff() → self::ParallaxOptions
     return new self::ParallaxOptions::•();
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.outline.expect
index 5576ed1..407241d 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.outline.expect
@@ -9,7 +9,6 @@
 @js::anonymous
 class ParallaxOptions extends core::Object /*hasConstConstructor*/  {
   external const constructor •() → self::ParallaxOptions
-    : super core::Object::•()
     ;
   static method _#new#tearOff() → self::ParallaxOptions
     return new self::ParallaxOptions::•();
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.transformed.expect
index 2fa40d9..0ee60d7 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/issue46123b.dart.weak.transformed.expect
@@ -19,7 +19,6 @@
 @#C3
 class ParallaxOptions extends core::Object /*hasConstConstructor*/  {
   external const constructor •() → self::ParallaxOptions
-    : super core::Object::•()
     ;
   static method _#new#tearOff() → self::ParallaxOptions
     return new self::ParallaxOptions::•();
diff --git a/pkg/front_end/testcases/general/control_flow_collection.dart.weak.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection.dart.weak.transformed.expect
index a903507..20261613 100644
--- a/pkg/front_end/testcases/general/control_flow_collection.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection.dart.weak.transformed.expect
@@ -34,7 +34,7 @@
       #t1.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t1;
   final core::Set<core::int> aSet = block {
-    final core::Set<core::int> #t2 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t2 = new col::_InternalLinkedHashSet::•<core::int>();
     #t2.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     if(self::oracle() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t2.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.transformed.expect
index 5316e10..e710cb1 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.transformed.expect
@@ -457,7 +457,7 @@
       #t1.{core::List::add}{Invariant}(42){(core::int*) →* void};
   } =>#t1;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t2 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t2 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t2.{core::Set::add}{Invariant}(42){(core::int*) →* core::bool*};
     #t2.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
@@ -474,7 +474,7 @@
       #t4.{core::List::add}{Invariant}(dynVar){(dynamic) →* void};
   } =>#t4;
   core::Set<dynamic>* set11 = block {
-    final core::Set<dynamic>* #t5 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t5 = new col::_InternalLinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t5.{core::Set::add}{Invariant}(dynVar){(dynamic) →* core::bool*};
     #t5.{core::Set::add}{Invariant}(null){(dynamic) →* core::bool*};
@@ -491,7 +491,7 @@
       #t7.{core::List::add}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::List<core::int*>*) →* void};
   } =>#t7;
   core::Set<core::List<core::int*>*>* set12 = block {
-    final core::Set<core::List<core::int*>*>* #t8 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t8 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t8.{core::Set::add}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::List<core::int*>*) →* core::bool*};
     #t8.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -508,7 +508,7 @@
       #t10.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::Iterable<core::int*>*) →* void};
   } =>#t10;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t11 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t11 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t11.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::Iterable<core::int*>*) →* void};
     #t11.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
@@ -525,7 +525,7 @@
       #t13.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>*) →* void};
   } =>#t13;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t14 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t14 = new col::_InternalLinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t14.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>*) →* void};
     #t14.{core::Set::add}{Invariant}(null){(dynamic) →* core::bool*};
@@ -542,7 +542,7 @@
       #t16.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::_literal1<core::int*>(42))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t16;
   core::Set<core::List<core::int*>*>* set22 = block {
-    final core::Set<core::List<core::int*>*>* #t17 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t17 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t17.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::_literal1<core::int*>(42))){(core::Iterable<core::List<core::int*>*>*) →* void};
     #t17.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -560,7 +560,7 @@
         #t19.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::Iterable<core::int*>*) →* void};
   } =>#t19;
   core::Set<core::int*>* set30 = block {
-    final core::Set<core::int*>* #t20 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t20 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t20.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::Iterable<core::int*>*) →* void};
@@ -580,7 +580,7 @@
         #t22.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>*) →* void};
   } =>#t22;
   core::Set<dynamic>* set31 = block {
-    final core::Set<dynamic>* #t23 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t23 = new col::_InternalLinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t23.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>*) →* void};
@@ -600,7 +600,7 @@
         #t25.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::_literal1<core::int*>(42))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t25;
   core::Set<core::List<core::int*>*>* set33 = block {
-    final core::Set<core::List<core::int*>*>* #t26 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t26 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t26.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::_literal1<core::int*>(42))){(core::Iterable<core::List<core::int*>*>*) →* void};
@@ -619,7 +619,7 @@
       #t28.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t28;
   core::Set<core::List<core::int*>*>* set40 = block {
-    final core::Set<core::List<core::int*>*>* #t29 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t29 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t29.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
     #t29.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -631,15 +631,15 @@
     final core::List<core::List<core::int*>*>* #t30 = core::_GrowableList::•<core::List<core::int*>*>(0);
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t30.{core::List::addAll}{Invariant}( block {
-        final core::Set<core::List<core::int*>*>* #t31 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        final core::Set<core::List<core::int*>*>* #t31 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
         #t31.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* core::bool*};
       } =>#t31){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t30;
   core::Set<core::List<core::int*>*>* set41 = block {
-    final core::Set<core::List<core::int*>*>* #t32 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t32 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t32.{core::Set::addAll}{Invariant}( block {
-        final core::Set<core::List<core::int*>*>* #t33 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        final core::Set<core::List<core::int*>*>* #t33 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
         #t33.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* core::bool*};
       } =>#t33){(core::Iterable<core::List<core::int*>*>*) →* void};
     #t32.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -651,7 +651,7 @@
         #t34.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t34;
   core::Set<core::List<core::int*>*>* set42 = block {
-    final core::Set<core::List<core::int*>*>* #t35 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t35 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t35.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
@@ -670,7 +670,7 @@
       #t37.{core::List::addAll}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::Iterable<core::int*>*) →* void};
   } =>#t37;
   core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t38 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t38 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t38.{core::Set::addAll}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::Iterable<core::int*>*) →* void};
     #t38.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
@@ -685,14 +685,14 @@
     final core::List<core::int*>* #t40 = core::_GrowableList::•<core::int*>(0);
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t40.{core::List::addAll}{Invariant}( block {
-        final core::Set<core::int*>* #t41 = new col::_CompactLinkedHashSet::•<core::int*>();
+        final core::Set<core::int*>* #t41 = new col::_InternalLinkedHashSet::•<core::int*>();
       } =>#t41){(core::Iterable<core::int*>*) →* void};
   } =>#t40;
   core::Set<core::int*>* set51 = block {
-    final core::Set<core::int*>* #t42 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t42 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t42.{core::Set::addAll}{Invariant}( block {
-        final core::Set<core::int*>* #t43 = new col::_CompactLinkedHashSet::•<core::int*>();
+        final core::Set<core::int*>* #t43 = new col::_InternalLinkedHashSet::•<core::int*>();
       } =>#t43){(core::Iterable<core::int*>*) →* void};
     #t42.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
   } =>#t42;
@@ -703,7 +703,7 @@
         #t44.{core::List::addAll}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::Iterable<core::int*>*) →* void};
   } =>#t44;
   core::Set<core::int*>* set52 = block {
-    final core::Set<core::int*>* #t45 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t45 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t45.{core::Set::addAll}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::Iterable<core::int*>*) →* void};
@@ -722,7 +722,7 @@
       #t47.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t47;
   core::Set<core::List<core::int*>*>* set60 = block {
-    final core::Set<core::List<core::int*>*>* #t48 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t48 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t48.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
     #t48.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -740,7 +740,7 @@
         #t50.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t50;
   core::Set<core::List<core::int*>*>* set61 = block {
-    final core::Set<core::List<core::int*>*>* #t51 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t51 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t51.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
@@ -759,7 +759,7 @@
       #t53.{core::List::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* void};
   } =>#t53;
   core::Set<core::List<core::int*>*>* set70 = block {
-    final core::Set<core::List<core::int*>*>* #t54 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t54 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t54.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* core::bool*};
     #t54.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -771,7 +771,7 @@
         #t55.{core::List::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* void};
   } =>#t55;
   core::Set<core::List<core::int*>*>* set71 = block {
-    final core::Set<core::List<core::int*>*>* #t56 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t56 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t56.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* core::bool*};
@@ -785,7 +785,7 @@
       #t57.{core::List::add}{Invariant}(3.14){(core::num*) →* void};
   } =>#t57;
   core::Set<core::num*>* set80 = block {
-    final core::Set<core::num*>* #t58 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t58 = new col::_InternalLinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t58.{core::Set::add}{Invariant}(42){(core::num*) →* core::bool*};
     else
@@ -808,7 +808,7 @@
       #t60.{core::List::addAll}{Invariant}(listDouble){(core::Iterable<core::num*>*) →* void};
   } =>#t60;
   core::Set<core::num*>* set81 = block {
-    final core::Set<core::num*>* #t61 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t61 = new col::_InternalLinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t61.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<core::num*>*) →* void};
     else
@@ -831,7 +831,7 @@
       #t63.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*){(core::Iterable<dynamic>*) →* void};
   } =>#t63;
   core::Set<dynamic>* set82 = block {
-    final core::Set<dynamic>* #t64 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t64 = new col::_InternalLinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t64.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<dynamic>*) →* void};
     else
@@ -839,7 +839,7 @@
     #t64.{core::Set::add}{Invariant}(null){(dynamic) →* core::bool*};
   } =>#t64;
   core::Set<dynamic>* map82 = block {
-    final core::Set<dynamic>* #t65 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t65 = new col::_InternalLinkedHashSet::•<dynamic>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t65.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:73:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
@@ -857,7 +857,7 @@
       #t66.{core::List::addAll}{Invariant}(listDouble){(core::Iterable<core::num*>*) →* void};
   } =>#t66;
   core::Set<core::num*>* set83 = block {
-    final core::Set<core::num*>* #t67 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t67 = new col::_InternalLinkedHashSet::•<core::num*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t67.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<core::num*>*) →* void};
     else
@@ -878,7 +878,7 @@
       #t69.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*){(core::int*) →* void};
   } =>#t69;
   core::Set<core::int*>* set90 = block {
-    final core::Set<core::int*>* #t70 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t70 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t70.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*){(core::int*) →* core::bool*};
     #t70.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
@@ -903,7 +903,7 @@
     }
   } =>#t72;
   core::Set<core::int*>* set91 = block {
-    final core::Set<core::int*>* #t75 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t75 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*) {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator}{core::Iterator<dynamic>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -937,7 +937,7 @@
       #t82.{core::List::add}{Invariant}(42){(core::int*) →* void};
   } =>#t82;
   core::Set<core::int*>* set100 = block {
-    final core::Set<core::int*>* #t83 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t83 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(dynVar as{TypeError,ForDynamic} core::bool*)
       #t83.{core::Set::add}{Invariant}(42){(core::int*) →* core::bool*};
   } =>#t83;
@@ -956,7 +956,7 @@
                            ^" in "bar" as{TypeError} core::int*){(core::int*) →* void};
   } =>#t85;
   block {
-    final core::Set<core::int*>* #t86 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t86 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t86.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) \"bar\", null};
@@ -979,7 +979,7 @@
                                ^" in "bar" as{TypeError} core::int*)){(core::Iterable<core::int*>*) →* void};
   } =>#t88;
   block {
-    final core::Set<core::int*>* #t89 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t89 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t89.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int*>(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:93:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
@@ -1003,7 +1003,7 @@
                               ^"){(core::int*) →* void};
   } =>#t91;
   block {
-    final core::Set<core::int*>* #t92 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t92 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t92.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
@@ -1030,7 +1030,7 @@
                                       ^" in 3.14 as{TypeError} core::String*){(core::String*) →* void};
   } =>#t93;
   block {
-    final core::Set<core::String*>* #t94 = new col::_CompactLinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t94 = new col::_InternalLinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t94.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:99:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
@@ -1064,7 +1064,7 @@
       #t96.{core::List::add}{Invariant}(42){(core::int*) →* void};
   } =>#t96;
   block {
-    final core::Set<core::int*>* #t97 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t97 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t97.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:102:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
@@ -1092,7 +1092,7 @@
                                       ^"){(core::int*) →* void};
   } =>#t98;
   block {
-    final core::Set<core::int*>* #t99 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t99 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t99.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:105:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
@@ -1135,7 +1135,7 @@
       #t100.{core::List::add}{Invariant}(42){(core::int*) →* void};
   } =>#t100;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t101 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t101 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   Set<int> set20 = {if (42) 42};
                         ^" in 42 as{TypeError} core::bool*)
@@ -1160,7 +1160,7 @@
                                                               ^" in 42 as{TypeError} core::String*){(core::String*) →* void};
   } =>#t103;
   core::Set<core::String*>* set40 = block {
-    final core::Set<core::String*>* #t104 = new col::_CompactLinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t104 = new col::_InternalLinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*)
       #t104.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
@@ -1200,7 +1200,7 @@
       #t107.{core::List::add}{Invariant}(42){(core::int*) →* void};
   } =>#t107;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t108 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t108 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t108.{core::Set::add}{Invariant}(42){(core::int*) →* core::bool*};
     #t108.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
@@ -1217,7 +1217,7 @@
       #t110.{core::List::add}{Invariant}(dynVar){(dynamic) →* void};
   } =>#t110;
   core::Set<dynamic>* set11 = block {
-    final core::Set<dynamic>* #t111 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t111 = new col::_InternalLinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t111.{core::Set::add}{Invariant}(dynVar){(dynamic) →* core::bool*};
     #t111.{core::Set::add}{Invariant}(null){(dynamic) →* core::bool*};
@@ -1234,7 +1234,7 @@
       #t113.{core::List::add}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::List<core::int*>*) →* void};
   } =>#t113;
   core::Set<core::List<core::int*>*>* set12 = block {
-    final core::Set<core::List<core::int*>*>* #t114 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t114 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t114.{core::Set::add}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::List<core::int*>*) →* core::bool*};
     #t114.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -1251,7 +1251,7 @@
       #t116.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::Iterable<core::int*>*) →* void};
   } =>#t116;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t117 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t117 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t117.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::Iterable<core::int*>*) →* void};
     #t117.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
@@ -1268,7 +1268,7 @@
       #t119.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>*) →* void};
   } =>#t119;
   core::Set<dynamic>* set21 = block {
-    final core::Set<dynamic>* #t120 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t120 = new col::_InternalLinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t120.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>*) →* void};
     #t120.{core::Set::add}{Invariant}(null){(dynamic) →* core::bool*};
@@ -1285,7 +1285,7 @@
       #t122.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::_literal1<core::int*>(42))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t122;
   core::Set<core::List<core::int*>*>* set22 = block {
-    final core::Set<core::List<core::int*>*>* #t123 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t123 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t123.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::_literal1<core::int*>(42))){(core::Iterable<core::List<core::int*>*>*) →* void};
     #t123.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -1303,7 +1303,7 @@
         #t125.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::Iterable<core::int*>*) →* void};
   } =>#t125;
   core::Set<core::int*>* set30 = block {
-    final core::Set<core::int*>* #t126 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t126 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t126.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int*>(42)){(core::Iterable<core::int*>*) →* void};
@@ -1323,7 +1323,7 @@
         #t128.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>*) →* void};
   } =>#t128;
   core::Set<dynamic>* set31 = block {
-    final core::Set<dynamic>* #t129 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t129 = new col::_InternalLinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t129.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>*) →* void};
@@ -1343,7 +1343,7 @@
         #t131.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::_literal1<core::int*>(42))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t131;
   core::Set<core::List<core::int*>*>* set33 = block {
-    final core::Set<core::List<core::int*>*>* #t132 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t132 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t132.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::_literal1<core::int*>(42))){(core::Iterable<core::List<core::int*>*>*) →* void};
@@ -1362,7 +1362,7 @@
       #t134.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t134;
   core::Set<core::List<core::int*>*>* set40 = block {
-    final core::Set<core::List<core::int*>*>* #t135 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t135 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t135.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
     #t135.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -1377,15 +1377,15 @@
     final core::List<core::List<core::int*>*>* #t137 = core::_GrowableList::•<core::List<core::int*>*>(0);
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t137.{core::List::addAll}{Invariant}( block {
-        final core::Set<core::List<core::int*>*>* #t138 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        final core::Set<core::List<core::int*>*>* #t138 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
         #t138.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* core::bool*};
       } =>#t138){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t137;
   core::Set<core::List<core::int*>*>* set41 = block {
-    final core::Set<core::List<core::int*>*>* #t139 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t139 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t139.{core::Set::addAll}{Invariant}( block {
-        final core::Set<core::List<core::int*>*>* #t140 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+        final core::Set<core::List<core::int*>*>* #t140 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
         #t140.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* core::bool*};
       } =>#t140){(core::Iterable<core::List<core::int*>*>*) →* void};
     #t139.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -1397,7 +1397,7 @@
         #t141.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t141;
   core::Set<core::List<core::int*>*>* set42 = block {
-    final core::Set<core::List<core::int*>*>* #t142 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t142 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t142.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
@@ -1416,7 +1416,7 @@
       #t144.{core::List::addAll}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::Iterable<core::int*>*) →* void};
   } =>#t144;
   core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t145 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t145 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t145.{core::Set::addAll}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::Iterable<core::int*>*) →* void};
     #t145.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
@@ -1431,14 +1431,14 @@
     final core::List<core::int*>* #t147 = core::_GrowableList::•<core::int*>(0);
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t147.{core::List::addAll}{Invariant}( block {
-        final core::Set<core::int*>* #t148 = new col::_CompactLinkedHashSet::•<core::int*>();
+        final core::Set<core::int*>* #t148 = new col::_InternalLinkedHashSet::•<core::int*>();
       } =>#t148){(core::Iterable<core::int*>*) →* void};
   } =>#t147;
   core::Set<core::int*>* set51 = block {
-    final core::Set<core::int*>* #t149 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t149 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t149.{core::Set::addAll}{Invariant}( block {
-        final core::Set<core::int*>* #t150 = new col::_CompactLinkedHashSet::•<core::int*>();
+        final core::Set<core::int*>* #t150 = new col::_InternalLinkedHashSet::•<core::int*>();
       } =>#t150){(core::Iterable<core::int*>*) →* void};
     #t149.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
   } =>#t149;
@@ -1449,7 +1449,7 @@
         #t151.{core::List::addAll}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::Iterable<core::int*>*) →* void};
   } =>#t151;
   core::Set<core::int*>* set52 = block {
-    final core::Set<core::int*>* #t152 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t152 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t152.{core::Set::addAll}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::Iterable<core::int*>*) →* void};
@@ -1461,7 +1461,7 @@
       #t153.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t153;
   core::Set<core::List<core::int*>*>* set60 = block {
-    final core::Set<core::List<core::int*>*>* #t154 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t154 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t154.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
     #t154.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -1479,7 +1479,7 @@
         #t156.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
   } =>#t156;
   core::Set<core::List<core::int*>*>* set61 = block {
-    final core::Set<core::List<core::int*>*>* #t157 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t157 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t157.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int*>*>(core::_GrowableList::•<core::int*>(0))){(core::Iterable<core::List<core::int*>*>*) →* void};
@@ -1498,7 +1498,7 @@
       #t159.{core::List::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* void};
   } =>#t159;
   core::Set<core::List<core::int*>*>* set70 = block {
-    final core::Set<core::List<core::int*>*>* #t160 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t160 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t160.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* core::bool*};
     #t160.{core::Set::add}{Invariant}(null){(core::List<core::int*>*) →* core::bool*};
@@ -1516,7 +1516,7 @@
         #t162.{core::List::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* void};
   } =>#t162;
   core::Set<core::List<core::int*>*>* set71 = block {
-    final core::Set<core::List<core::int*>*>* #t163 = new col::_CompactLinkedHashSet::•<core::List<core::int*>*>();
+    final core::Set<core::List<core::int*>*>* #t163 = new col::_InternalLinkedHashSet::•<core::List<core::int*>*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t163.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int*>(0)){(core::List<core::int*>*) →* core::bool*};
@@ -1538,7 +1538,7 @@
         #t165.{core::List::add}{Invariant}(3.14){(core::num*) →* void};
   } =>#t165;
   core::Set<core::num*>* set80 = block {
-    final core::Set<core::num*>* #t166 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t166 = new col::_InternalLinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t166.{core::Set::add}{Invariant}(42){(core::num*) →* core::bool*};
@@ -1564,7 +1564,7 @@
         #t168.{core::List::addAll}{Invariant}(listDouble){(core::Iterable<core::num*>*) →* void};
   } =>#t168;
   core::Set<core::num*>* set81 = block {
-    final core::Set<core::num*>* #t169 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t169 = new col::_InternalLinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t169.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<core::num*>*) →* void};
@@ -1590,7 +1590,7 @@
         #t171.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*){(core::Iterable<dynamic>*) →* void};
   } =>#t171;
   core::Set<dynamic>* set82 = block {
-    final core::Set<dynamic>* #t172 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t172 = new col::_InternalLinkedHashSet::•<dynamic>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t172.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<dynamic>*) →* void};
@@ -1616,7 +1616,7 @@
         #t174.{core::List::addAll}{Invariant}(listDouble){(core::Iterable<core::num*>*) →* void};
   } =>#t174;
   core::Set<core::num*>* set83 = block {
-    final core::Set<core::num*>* #t175 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t175 = new col::_InternalLinkedHashSet::•<core::num*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t175.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<core::num*>*) →* void};
@@ -1639,7 +1639,7 @@
       #t177.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*){(core::int*) →* void};
   } =>#t177;
   core::Set<core::int*>* set90 = block {
-    final core::Set<core::int*>* #t178 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t178 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t178.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic} core::int*){(core::int*) →* core::bool*};
     #t178.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
@@ -1664,7 +1664,7 @@
     }
   } =>#t180;
   core::Set<core::int*>* set91 = block {
-    final core::Set<core::int*>* #t183 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t183 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*}) {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator}{core::Iterator<dynamic>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -1698,7 +1698,7 @@
       #t190.{core::List::add}{Invariant}(42){(core::int*) →* void};
   } =>#t190;
   core::Set<core::int*>* set100 = block {
-    final core::Set<core::int*>* #t192 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t192 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (final core::int* #t193 = index = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; index = index.{core::num::+}(1){(core::num*) →* core::int*})
       #t192.{core::Set::add}{Invariant}(42){(core::int*) →* core::bool*};
   } =>#t192;
@@ -1718,7 +1718,7 @@
     }
   } =>#t196;
   core::Set<core::int*>* set110 = block {
-    final core::Set<core::int*>* #t197 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t197 = new col::_InternalLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::int*>* :sync-for-iterator = core::_GrowableList::_literal3<core::int*>(1, 2, 3).{core::Iterable::iterator}{core::Iterator<core::int*>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -1750,7 +1750,7 @@
     }
   } =>#t199;
   core::Set<core::int*>* set120 = block {
-    final core::Set<core::int*>* #t200 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t200 = new col::_InternalLinkedHashSet::•<core::int*>();
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynVar as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator}{core::Iterator<dynamic>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -1777,7 +1777,7 @@
       #t202.{core::List::add}{Invariant}(i){(core::int*) →* void};
   } =>#t202;
   core::Set<core::int*>* set130 = block {
-    final core::Set<core::int*>* #t203 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t203 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 1; i.{core::num::<}(2){(core::num*) →* core::bool*}; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t203.{core::Set::add}{Invariant}(i){(core::int*) →* core::bool*};
   } =>#t203;
@@ -1796,7 +1796,7 @@
                                             ^" in "bar" as{TypeError} core::int*){(core::int*) →* void};
   } =>#t205;
   block {
-    final core::Set<core::int*>* #t206 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t206 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t206.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null};
@@ -1823,7 +1823,7 @@
                                                 ^" in "bar" as{TypeError} core::int*)){(core::Iterable<core::int*>*) →* void};
   } =>#t208;
   block {
-    final core::Set<core::int*>* #t209 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t209 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t209.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int*>(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:216:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
@@ -1851,7 +1851,7 @@
                                                ^"){(core::int*) →* void};
   } =>#t211;
   block {
-    final core::Set<core::int*>* #t212 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t212 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       #t212.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
@@ -1879,7 +1879,7 @@
                                                                      ^" in 3.14 as{TypeError} core::String*){(core::String*) →* void};
   } =>#t213;
   block {
-    final core::Set<core::String*>* #t214 = new col::_CompactLinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t214 = new col::_InternalLinkedHashSet::•<core::String*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t214.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:222:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
@@ -1916,7 +1916,7 @@
         #t216.{core::List::add}{Invariant}(42){(core::int*) →* void};
   } =>#t216;
   block {
-    final core::Set<core::int*>* #t217 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t217 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t217.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:225:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
@@ -1946,7 +1946,7 @@
                                                                      ^"){(core::int*) →* void};
   } =>#t218;
   block {
-    final core::Set<core::int*>* #t219 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t219 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic} core::bool*)
         #t219.{core::Set::add}{Invariant}(42){(core::int*) →* core::bool*};
@@ -1981,7 +1981,7 @@
     }
   } =>#t220;
   block {
-    final core::Set<core::int*>* #t222 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t222 = new col::_InternalLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::int*>* :sync-for-iterator = core::_GrowableList::_literal1<core::int*>(1).{core::Iterable::iterator}{core::Iterator<core::int*>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -2026,7 +2026,7 @@
     }
   } =>#t226;
   core::Set<dynamic>* set10 = block {
-    final core::Set<dynamic>* #t227 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t227 = new col::_InternalLinkedHashSet::•<dynamic>();
     {
       core::Iterator<Never>* :sync-for-iterator = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
@@ -2068,7 +2068,7 @@
     }
   } =>#t229;
   core::Set<core::int*>* set20 = block {
-    final core::Set<core::int*>* #t230 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t230 = new col::_InternalLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::int*>* :sync-for-iterator = core::_GrowableList::_literal2<core::int*>(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:240:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
@@ -2116,7 +2116,7 @@
     }
   } =>#t232;
   core::Set<dynamic>* set30 = block {
-    final core::Set<dynamic>* #t234 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t234 = new col::_InternalLinkedHashSet::•<dynamic>();
     {
       Never :stream = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
@@ -2173,7 +2173,7 @@
     }
   } =>#t238;
   core::Set<core::int*>* set40 = block {
-    final core::Set<core::int*>* #t240 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t240 = new col::_InternalLinkedHashSet::•<core::int*>();
     {
       asy::Stream<core::int*> :stream = asy::Stream::fromIterable<core::int*>(core::_GrowableList::_literal2<core::int*>(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:246:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
@@ -2218,7 +2218,7 @@
       #t244.{core::List::add}{Invariant}(42){(core::int*) →* void};
   } =>#t244;
   core::Set<core::int*>* set50 = block {
-    final core::Set<core::int*>* #t245 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t245 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (; ; )
       #t245.{core::Set::add}{Invariant}(42){(core::int*) →* core::bool*};
     #t245.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
@@ -2237,7 +2237,7 @@
       #t247.{core::List::add}{Invariant}(42){(core::int*) →* void};
   } =>#t247;
   core::Set<core::int*>* set60 = block {
-    final core::Set<core::int*>* #t248 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t248 = new col::_InternalLinkedHashSet::•<core::int*>();
     for (; invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:252:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError} core::bool*; )
@@ -2260,7 +2260,7 @@
       #t250.{core::List::add}{Invariant}(i){(core::int*) →* void};
   } =>#t250;
   block {
-    final core::Set<core::int*>* #t251 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t251 = new col::_InternalLinkedHashSet::•<core::int*>();
     await for (core::int* i in stream)
       #t251.{core::Set::add}{Invariant}(i){(core::int*) →* core::bool*};
   } =>#t251;
@@ -2277,7 +2277,7 @@
       #t253.{core::List::add}{Invariant}(a{self::B*}.{self::B::foo}{core::int*}){(core::int*) →* void};
   } =>#t253;
   core::Set<core::int*>* set10 = block {
-    final core::Set<core::int*>* #t254 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t254 = new col::_InternalLinkedHashSet::•<core::int*>();
     if(a is self::B*)
       #t254.{core::Set::add}{Invariant}(a{self::B*}.{self::B::foo}{core::int*}){(core::int*) →* core::bool*};
   } =>#t254;
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.transformed.expect
index e90b8eb..58aec66 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.transformed.expect
@@ -447,7 +447,7 @@
       #t1.{core::List::add}{Invariant}(42){(core::int) → void};
   } =>#t1;
   core::Set<core::int?> set10 = block {
-    final core::Set<core::int?> #t2 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t2 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t2.{core::Set::add}{Invariant}(42){(core::int?) → core::bool};
     #t2.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
@@ -464,7 +464,7 @@
       #t4.{core::List::add}{Invariant}(dynVar){(dynamic) → void};
   } =>#t4;
   core::Set<dynamic> set11 = block {
-    final core::Set<dynamic> #t5 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t5 = new col::_InternalLinkedHashSet::•<dynamic>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t5.{core::Set::add}{Invariant}(dynVar){(dynamic) → core::bool};
     #t5.{core::Set::add}{Invariant}(null){(dynamic) → core::bool};
@@ -481,7 +481,7 @@
       #t7.{core::List::add}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::List<core::int>) → void};
   } =>#t7;
   core::Set<core::List<core::int>?> set12 = block {
-    final core::Set<core::List<core::int>?> #t8 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t8 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t8.{core::Set::add}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::List<core::int>?) → core::bool};
     #t8.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -498,7 +498,7 @@
       #t10.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::Iterable<core::int>) → void};
   } =>#t10;
   core::Set<core::int?> set20 = block {
-    final core::Set<core::int?> #t11 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t11 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t11.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::Iterable<core::int?>) → void};
     #t11.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
@@ -515,7 +515,7 @@
       #t13.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>) → void};
   } =>#t13;
   core::Set<dynamic> set21 = block {
-    final core::Set<dynamic> #t14 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t14 = new col::_InternalLinkedHashSet::•<dynamic>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t14.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>) → void};
     #t14.{core::Set::add}{Invariant}(null){(dynamic) → core::bool};
@@ -532,7 +532,7 @@
       #t16.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(42))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t16;
   core::Set<core::List<core::int>?> set22 = block {
-    final core::Set<core::List<core::int>?> #t17 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t17 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t17.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(42))){(core::Iterable<core::List<core::int>?>) → void};
     #t17.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -550,7 +550,7 @@
         #t19.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::Iterable<core::int>) → void};
   } =>#t19;
   core::Set<core::int?> set30 = block {
-    final core::Set<core::int?> #t20 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t20 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t20.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::Iterable<core::int?>) → void};
@@ -570,7 +570,7 @@
         #t22.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>) → void};
   } =>#t22;
   core::Set<dynamic> set31 = block {
-    final core::Set<dynamic> #t23 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t23 = new col::_InternalLinkedHashSet::•<dynamic>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t23.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>) → void};
@@ -590,7 +590,7 @@
         #t25.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(42))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t25;
   core::Set<core::List<core::int>?> set33 = block {
-    final core::Set<core::List<core::int>?> #t26 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t26 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t26.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(42))){(core::Iterable<core::List<core::int>?>) → void};
@@ -609,7 +609,7 @@
       #t28.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t28;
   core::Set<core::List<core::int>?> set40 = block {
-    final core::Set<core::List<core::int>?> #t29 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t29 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t29.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>?>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>?>) → void};
     #t29.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -621,15 +621,15 @@
     final core::List<core::List<core::int>> #t30 = core::_GrowableList::•<core::List<core::int>>(0);
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t30.{core::List::addAll}{Invariant}( block {
-        final core::Set<core::List<core::int>> #t31 = new col::_CompactLinkedHashSet::•<core::List<core::int>>();
+        final core::Set<core::List<core::int>> #t31 = new col::_InternalLinkedHashSet::•<core::List<core::int>>();
         #t31.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>) → core::bool};
       } =>#t31){(core::Iterable<core::List<core::int>>) → void};
   } =>#t30;
   core::Set<core::List<core::int>?> set41 = block {
-    final core::Set<core::List<core::int>?> #t32 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t32 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t32.{core::Set::addAll}{Invariant}( block {
-        final core::Set<core::List<core::int>?> #t33 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+        final core::Set<core::List<core::int>?> #t33 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
         #t33.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>?) → core::bool};
       } =>#t33){(core::Iterable<core::List<core::int>?>) → void};
     #t32.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -641,7 +641,7 @@
         #t34.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t34;
   core::Set<core::List<core::int>?> set42 = block {
-    final core::Set<core::List<core::int>?> #t35 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t35 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t35.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>?>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>?>) → void};
@@ -660,7 +660,7 @@
       #t37.{core::List::addAll}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::Iterable<core::int>) → void};
   } =>#t37;
   core::Set<core::int?> set50 = block {
-    final core::Set<core::int?> #t38 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t38 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t38.{core::Set::addAll}{Invariant}(core::_GrowableList::•<core::int?>(0)){(core::Iterable<core::int?>) → void};
     #t38.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
@@ -675,14 +675,14 @@
     final core::List<core::int> #t40 = core::_GrowableList::•<core::int>(0);
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t40.{core::List::addAll}{Invariant}( block {
-        final core::Set<core::int> #t41 = new col::_CompactLinkedHashSet::•<core::int>();
+        final core::Set<core::int> #t41 = new col::_InternalLinkedHashSet::•<core::int>();
       } =>#t41){(core::Iterable<core::int>) → void};
   } =>#t40;
   core::Set<core::int?> set51 = block {
-    final core::Set<core::int?> #t42 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t42 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t42.{core::Set::addAll}{Invariant}( block {
-        final core::Set<core::int?> #t43 = new col::_CompactLinkedHashSet::•<core::int?>();
+        final core::Set<core::int?> #t43 = new col::_InternalLinkedHashSet::•<core::int?>();
       } =>#t43){(core::Iterable<core::int?>) → void};
     #t42.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
   } =>#t42;
@@ -693,7 +693,7 @@
         #t44.{core::List::addAll}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::Iterable<core::int>) → void};
   } =>#t44;
   core::Set<core::int?> set52 = block {
-    final core::Set<core::int?> #t45 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t45 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t45.{core::Set::addAll}{Invariant}(core::_GrowableList::•<core::int?>(0)){(core::Iterable<core::int?>) → void};
@@ -712,7 +712,7 @@
       #t47.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t47;
   core::Set<core::List<core::int>?> set60 = block {
-    final core::Set<core::List<core::int>?> #t48 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t48 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t48.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>?>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>?>) → void};
     #t48.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -730,7 +730,7 @@
         #t50.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t50;
   core::Set<core::List<core::int>?> set61 = block {
-    final core::Set<core::List<core::int>?> #t51 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t51 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t51.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>?>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>?>) → void};
@@ -749,7 +749,7 @@
       #t53.{core::List::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>) → void};
   } =>#t53;
   core::Set<core::List<core::int>?> set70 = block {
-    final core::Set<core::List<core::int>?> #t54 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t54 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t54.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>?) → core::bool};
     #t54.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -761,7 +761,7 @@
         #t55.{core::List::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>) → void};
   } =>#t55;
   core::Set<core::List<core::int>?> set71 = block {
-    final core::Set<core::List<core::int>?> #t56 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t56 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t56.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>?) → core::bool};
@@ -775,7 +775,7 @@
       #t57.{core::List::add}{Invariant}(3.14){(core::num) → void};
   } =>#t57;
   core::Set<core::num?> set80 = block {
-    final core::Set<core::num?> #t58 = new col::_CompactLinkedHashSet::•<core::num?>();
+    final core::Set<core::num?> #t58 = new col::_InternalLinkedHashSet::•<core::num?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t58.{core::Set::add}{Invariant}(42){(core::num?) → core::bool};
     else
@@ -798,7 +798,7 @@
       #t60.{core::List::addAll}{Invariant}(listDouble){(core::Iterable<core::num>) → void};
   } =>#t60;
   core::Set<core::num?> set81 = block {
-    final core::Set<core::num?> #t61 = new col::_CompactLinkedHashSet::•<core::num?>();
+    final core::Set<core::num?> #t61 = new col::_InternalLinkedHashSet::•<core::num?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t61.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<core::num?>) → void};
     else
@@ -821,7 +821,7 @@
       #t63.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>){(core::Iterable<dynamic>) → void};
   } =>#t63;
   core::Set<dynamic> set82 = block {
-    final core::Set<dynamic> #t64 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t64 = new col::_InternalLinkedHashSet::•<dynamic>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t64.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<dynamic>) → void};
     else
@@ -829,7 +829,7 @@
     #t64.{core::Set::add}{Invariant}(null){(dynamic) → core::bool};
   } =>#t64;
   core::Set<dynamic> map82 = block {
-    final core::Set<dynamic> #t65 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t65 = new col::_InternalLinkedHashSet::•<dynamic>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t65.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:71:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
@@ -847,7 +847,7 @@
       #t66.{core::List::addAll}{Invariant}(listDouble){(core::Iterable<core::num>) → void};
   } =>#t66;
   core::Set<core::num?> set83 = block {
-    final core::Set<core::num?> #t67 = new col::_CompactLinkedHashSet::•<core::num?>();
+    final core::Set<core::num?> #t67 = new col::_InternalLinkedHashSet::•<core::num?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t67.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<core::num?>) → void};
     else
@@ -868,7 +868,7 @@
       #t69.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic,ForNonNullableByDefault} core::int){(core::int) → void};
   } =>#t69;
   core::Set<core::int?> set90 = block {
-    final core::Set<core::int?> #t70 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t70 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t70.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?){(core::int?) → core::bool};
     #t70.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
@@ -893,7 +893,7 @@
     }
   } =>#t72;
   core::Set<core::int?> set91 = block {
-    final core::Set<core::int?> #t75 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t75 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool) {
       core::Iterator<dynamic> :sync-for-iterator = (dynVar as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -927,7 +927,7 @@
       #t82.{core::List::add}{Invariant}(42){(core::int) → void};
   } =>#t82;
   core::Set<core::int> set100 = block {
-    final core::Set<core::int> #t83 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t83 = new col::_InternalLinkedHashSet::•<core::int>();
     if(dynVar as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t83.{core::Set::add}{Invariant}(42){(core::int) → core::bool};
   } =>#t83;
@@ -946,7 +946,7 @@
                            ^" in "bar" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → void};
   } =>#t85;
   block {
-    final core::Set<core::int?> #t86 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t86 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t86.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:88:29: Error: A value of type 'String' can't be assigned to a variable of type 'int?'.
   <int?>{if (oracle(\"foo\")) \"bar\", null};
@@ -969,7 +969,7 @@
                                ^" in "bar" as{TypeError,ForNonNullableByDefault} core::int)){(core::Iterable<core::int>) → void};
   } =>#t88;
   block {
-    final core::Set<core::int?> #t89 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t89 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t89.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int?>(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:91:33: Error: A value of type 'String' can't be assigned to a variable of type 'int?'.
   <int?>{if (oracle(\"foo\")) ...[\"bar\"], null};
@@ -993,7 +993,7 @@
                               ^"){(core::int) → void};
   } =>#t91;
   block {
-    final core::Set<core::int?> #t92 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t92 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t92.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:94:32: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
@@ -1020,7 +1020,7 @@
                                       ^" in 3.14 as{TypeError,ForNonNullableByDefault} core::String){(core::String) → void};
   } =>#t93;
   block {
-    final core::Set<core::String?> #t94 = new col::_CompactLinkedHashSet::•<core::String?>();
+    final core::Set<core::String?> #t94 = new col::_InternalLinkedHashSet::•<core::String?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t94.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:97:32: Error: A value of type 'int' can't be assigned to a variable of type 'String?'.
   <String?>{if (oracle(\"foo\")) 42 else 3.14, null};
@@ -1054,7 +1054,7 @@
       #t96.{core::List::add}{Invariant}(42){(core::int) → void};
   } =>#t96;
   block {
-    final core::Set<core::int?> #t97 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t97 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t97.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:100:32: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
@@ -1082,7 +1082,7 @@
                                       ^"){(core::int) → void};
   } =>#t98;
   block {
-    final core::Set<core::int?> #t99 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t99 = new col::_InternalLinkedHashSet::•<core::int?>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t99.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:103:32: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
@@ -1125,7 +1125,7 @@
       #t100.{core::List::add}{Invariant}(42){(core::int) → void};
   } =>#t100;
   core::Set<core::int> set20 = block {
-    final core::Set<core::int> #t101 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t101 = new col::_InternalLinkedHashSet::•<core::int>();
     if(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
   Set<int> set20 = {if (42) 42};
                         ^" in 42 as{TypeError,ForNonNullableByDefault} core::bool)
@@ -1150,7 +1150,7 @@
                                                               ^" in 42 as{TypeError,ForNonNullableByDefault} core::String){(core::String) → void};
   } =>#t103;
   core::Set<core::String> set40 = block {
-    final core::Set<core::String> #t104 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Set<core::String> #t104 = new col::_InternalLinkedHashSet::•<core::String>();
     if(self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
       #t104.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
@@ -1190,7 +1190,7 @@
       #t107.{core::List::add}{Invariant}(42){(core::int) → void};
   } =>#t107;
   core::Set<core::int?> set10 = block {
-    final core::Set<core::int?> #t108 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t108 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t108.{core::Set::add}{Invariant}(42){(core::int?) → core::bool};
     #t108.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
@@ -1207,7 +1207,7 @@
       #t110.{core::List::add}{Invariant}(dynVar){(dynamic) → void};
   } =>#t110;
   core::Set<dynamic> set11 = block {
-    final core::Set<dynamic> #t111 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t111 = new col::_InternalLinkedHashSet::•<dynamic>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t111.{core::Set::add}{Invariant}(dynVar){(dynamic) → core::bool};
     #t111.{core::Set::add}{Invariant}(null){(dynamic) → core::bool};
@@ -1224,7 +1224,7 @@
       #t113.{core::List::add}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::List<core::int>) → void};
   } =>#t113;
   core::Set<core::List<core::int>?> set12 = block {
-    final core::Set<core::List<core::int>?> #t114 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t114 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t114.{core::Set::add}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::List<core::int>?) → core::bool};
     #t114.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -1241,7 +1241,7 @@
       #t116.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::Iterable<core::int>) → void};
   } =>#t116;
   core::Set<core::int?> set20 = block {
-    final core::Set<core::int?> #t117 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t117 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t117.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::Iterable<core::int?>) → void};
     #t117.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
@@ -1258,7 +1258,7 @@
       #t119.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>) → void};
   } =>#t119;
   core::Set<dynamic> set21 = block {
-    final core::Set<dynamic> #t120 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t120 = new col::_InternalLinkedHashSet::•<dynamic>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t120.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>) → void};
     #t120.{core::Set::add}{Invariant}(null){(dynamic) → core::bool};
@@ -1275,7 +1275,7 @@
       #t122.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(42))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t122;
   core::Set<core::List<core::int>?> set22 = block {
-    final core::Set<core::List<core::int>?> #t123 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t123 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t123.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(42))){(core::Iterable<core::List<core::int>?>) → void};
     #t123.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -1293,7 +1293,7 @@
         #t125.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::Iterable<core::int>) → void};
   } =>#t125;
   core::Set<core::int?> set30 = block {
-    final core::Set<core::int?> #t126 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t126 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t126.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int>(42)){(core::Iterable<core::int?>) → void};
@@ -1313,7 +1313,7 @@
         #t128.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>) → void};
   } =>#t128;
   core::Set<dynamic> set31 = block {
-    final core::Set<dynamic> #t129 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t129 = new col::_InternalLinkedHashSet::•<dynamic>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t129.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<dynamic>(dynVar)){(core::Iterable<dynamic>) → void};
@@ -1333,7 +1333,7 @@
         #t131.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(42))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t131;
   core::Set<core::List<core::int>?> set33 = block {
-    final core::Set<core::List<core::int>?> #t132 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t132 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t132.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(42))){(core::Iterable<core::List<core::int>?>) → void};
@@ -1352,7 +1352,7 @@
       #t134.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t134;
   core::Set<core::List<core::int>?> set40 = block {
-    final core::Set<core::List<core::int>?> #t135 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t135 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t135.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>?>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>?>) → void};
     #t135.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -1367,15 +1367,15 @@
     final core::List<core::List<core::int>> #t137 = core::_GrowableList::•<core::List<core::int>>(0);
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t137.{core::List::addAll}{Invariant}( block {
-        final core::Set<core::List<core::int>> #t138 = new col::_CompactLinkedHashSet::•<core::List<core::int>>();
+        final core::Set<core::List<core::int>> #t138 = new col::_InternalLinkedHashSet::•<core::List<core::int>>();
         #t138.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>) → core::bool};
       } =>#t138){(core::Iterable<core::List<core::int>>) → void};
   } =>#t137;
   core::Set<core::List<core::int>?> set41 = block {
-    final core::Set<core::List<core::int>?> #t139 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t139 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t139.{core::Set::addAll}{Invariant}( block {
-        final core::Set<core::List<core::int>?> #t140 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+        final core::Set<core::List<core::int>?> #t140 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
         #t140.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>?) → core::bool};
       } =>#t140){(core::Iterable<core::List<core::int>?>) → void};
     #t139.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -1387,7 +1387,7 @@
         #t141.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t141;
   core::Set<core::List<core::int>?> set42 = block {
-    final core::Set<core::List<core::int>?> #t142 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t142 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t142.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>?>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>?>) → void};
@@ -1406,7 +1406,7 @@
       #t144.{core::List::addAll}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::Iterable<core::int>) → void};
   } =>#t144;
   core::Set<core::int?> set50 = block {
-    final core::Set<core::int?> #t145 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t145 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t145.{core::Set::addAll}{Invariant}(core::_GrowableList::•<core::int?>(0)){(core::Iterable<core::int?>) → void};
     #t145.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
@@ -1421,14 +1421,14 @@
     final core::List<core::int> #t147 = core::_GrowableList::•<core::int>(0);
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t147.{core::List::addAll}{Invariant}( block {
-        final core::Set<core::int> #t148 = new col::_CompactLinkedHashSet::•<core::int>();
+        final core::Set<core::int> #t148 = new col::_InternalLinkedHashSet::•<core::int>();
       } =>#t148){(core::Iterable<core::int>) → void};
   } =>#t147;
   core::Set<core::int?> set51 = block {
-    final core::Set<core::int?> #t149 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t149 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t149.{core::Set::addAll}{Invariant}( block {
-        final core::Set<core::int?> #t150 = new col::_CompactLinkedHashSet::•<core::int?>();
+        final core::Set<core::int?> #t150 = new col::_InternalLinkedHashSet::•<core::int?>();
       } =>#t150){(core::Iterable<core::int?>) → void};
     #t149.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
   } =>#t149;
@@ -1439,7 +1439,7 @@
         #t151.{core::List::addAll}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::Iterable<core::int>) → void};
   } =>#t151;
   core::Set<core::int?> set52 = block {
-    final core::Set<core::int?> #t152 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t152 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t152.{core::Set::addAll}{Invariant}(core::_GrowableList::•<core::int?>(0)){(core::Iterable<core::int?>) → void};
@@ -1451,7 +1451,7 @@
       #t153.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t153;
   core::Set<core::List<core::int>?> set60 = block {
-    final core::Set<core::List<core::int>?> #t154 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t154 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t154.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>?>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>?>) → void};
     #t154.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -1469,7 +1469,7 @@
         #t156.{core::List::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>>) → void};
   } =>#t156;
   core::Set<core::List<core::int>?> set61 = block {
-    final core::Set<core::List<core::int>?> #t157 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t157 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t157.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::List<core::int>?>(core::_GrowableList::•<core::int>(0))){(core::Iterable<core::List<core::int>?>) → void};
@@ -1488,7 +1488,7 @@
       #t159.{core::List::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>) → void};
   } =>#t159;
   core::Set<core::List<core::int>?> set70 = block {
-    final core::Set<core::List<core::int>?> #t160 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t160 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t160.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>?) → core::bool};
     #t160.{core::Set::add}{Invariant}(null){(core::List<core::int>?) → core::bool};
@@ -1506,7 +1506,7 @@
         #t162.{core::List::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>) → void};
   } =>#t162;
   core::Set<core::List<core::int>?> set71 = block {
-    final core::Set<core::List<core::int>?> #t163 = new col::_CompactLinkedHashSet::•<core::List<core::int>?>();
+    final core::Set<core::List<core::int>?> #t163 = new col::_InternalLinkedHashSet::•<core::List<core::int>?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t163.{core::Set::add}{Invariant}(core::_GrowableList::•<core::int>(0)){(core::List<core::int>?) → core::bool};
@@ -1528,7 +1528,7 @@
         #t165.{core::List::add}{Invariant}(3.14){(core::num) → void};
   } =>#t165;
   core::Set<core::num?> set80 = block {
-    final core::Set<core::num?> #t166 = new col::_CompactLinkedHashSet::•<core::num?>();
+    final core::Set<core::num?> #t166 = new col::_InternalLinkedHashSet::•<core::num?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t166.{core::Set::add}{Invariant}(42){(core::num?) → core::bool};
@@ -1554,7 +1554,7 @@
         #t168.{core::List::addAll}{Invariant}(listDouble){(core::Iterable<core::num>) → void};
   } =>#t168;
   core::Set<core::num?> set81 = block {
-    final core::Set<core::num?> #t169 = new col::_CompactLinkedHashSet::•<core::num?>();
+    final core::Set<core::num?> #t169 = new col::_InternalLinkedHashSet::•<core::num?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t169.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<core::num?>) → void};
@@ -1580,7 +1580,7 @@
         #t171.{core::List::addAll}{Invariant}(dynVar as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>){(core::Iterable<dynamic>) → void};
   } =>#t171;
   core::Set<dynamic> set82 = block {
-    final core::Set<dynamic> #t172 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t172 = new col::_InternalLinkedHashSet::•<dynamic>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t172.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<dynamic>) → void};
@@ -1606,7 +1606,7 @@
         #t174.{core::List::addAll}{Invariant}(listDouble){(core::Iterable<core::num>) → void};
   } =>#t174;
   core::Set<core::num?> set83 = block {
-    final core::Set<core::num?> #t175 = new col::_CompactLinkedHashSet::•<core::num?>();
+    final core::Set<core::num?> #t175 = new col::_InternalLinkedHashSet::•<core::num?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t175.{core::Set::addAll}{Invariant}(listInt){(core::Iterable<core::num?>) → void};
@@ -1629,7 +1629,7 @@
       #t177.{core::List::add}{Invariant}(dynVar as{TypeError,ForDynamic,ForNonNullableByDefault} core::int){(core::int) → void};
   } =>#t177;
   core::Set<core::int?> set90 = block {
-    final core::Set<core::int?> #t178 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t178 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t178.{core::Set::add}{Invariant}(dynVar as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?){(core::int?) → core::bool};
     #t178.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
@@ -1654,7 +1654,7 @@
     }
   } =>#t180;
   core::Set<core::int?> set91 = block {
-    final core::Set<core::int?> #t183 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t183 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<dynamic> :sync-for-iterator = (dynVar as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -1688,7 +1688,7 @@
       #t190.{core::List::add}{Invariant}(42){(core::int) → void};
   } =>#t190;
   core::Set<core::int> set100 = block {
-    final core::Set<core::int> #t192 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t192 = new col::_InternalLinkedHashSet::•<core::int>();
     for (final core::int #t193 = index = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; index = index.{core::num::+}(1){(core::num) → core::int})
       #t192.{core::Set::add}{Invariant}(42){(core::int) → core::bool};
   } =>#t192;
@@ -1708,7 +1708,7 @@
     }
   } =>#t196;
   core::Set<core::int?> set110 = block {
-    final core::Set<core::int?> #t197 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t197 = new col::_InternalLinkedHashSet::•<core::int?>();
     {
       core::Iterator<core::int> :sync-for-iterator = core::_GrowableList::_literal3<core::int>(1, 2, 3).{core::Iterable::iterator}{core::Iterator<core::int>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -1740,7 +1740,7 @@
     }
   } =>#t199;
   core::Set<core::int?> set120 = block {
-    final core::Set<core::int?> #t200 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t200 = new col::_InternalLinkedHashSet::•<core::int?>();
     {
       core::Iterator<dynamic> :sync-for-iterator = (dynVar as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -1767,7 +1767,7 @@
       #t202.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t202;
   core::Set<core::int> set130 = block {
-    final core::Set<core::int> #t203 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t203 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 1; i.{core::num::<}(2){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int})
       #t203.{core::Set::add}{Invariant}(i){(core::int) → core::bool};
   } =>#t203;
@@ -1786,7 +1786,7 @@
                                             ^" in "bar" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → void};
   } =>#t205;
   block {
-    final core::Set<core::int?> #t206 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t206 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t206.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:211:46: Error: A value of type 'String' can't be assigned to a variable of type 'int?'.
   <int?>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null};
@@ -1813,7 +1813,7 @@
                                                 ^" in "bar" as{TypeError,ForNonNullableByDefault} core::int)){(core::Iterable<core::int>) → void};
   } =>#t208;
   block {
-    final core::Set<core::int?> #t209 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t209 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t209.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int?>(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:214:50: Error: A value of type 'String' can't be assigned to a variable of type 'int?'.
   <int?>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
@@ -1841,7 +1841,7 @@
                                                ^"){(core::int) → void};
   } =>#t211;
   block {
-    final core::Set<core::int?> #t212 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t212 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       #t212.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:217:49: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
@@ -1869,7 +1869,7 @@
                                                                      ^" in 3.14 as{TypeError,ForNonNullableByDefault} core::String){(core::String) → void};
   } =>#t213;
   block {
-    final core::Set<core::String?> #t214 = new col::_CompactLinkedHashSet::•<core::String?>();
+    final core::Set<core::String?> #t214 = new col::_InternalLinkedHashSet::•<core::String?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t214.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:220:63: Error: A value of type 'int' can't be assigned to a variable of type 'String?'.
@@ -1906,7 +1906,7 @@
         #t216.{core::List::add}{Invariant}(42){(core::int) → void};
   } =>#t216;
   block {
-    final core::Set<core::int?> #t217 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t217 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t217.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:223:63: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
@@ -1936,7 +1936,7 @@
                                                                      ^"){(core::int) → void};
   } =>#t218;
   block {
-    final core::Set<core::int?> #t219 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t219 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
       if(self::oracle<dynamic>() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool)
         #t219.{core::Set::add}{Invariant}(42){(core::int?) → core::bool};
@@ -1971,7 +1971,7 @@
     }
   } =>#t220;
   block {
-    final core::Set<core::int?> #t222 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t222 = new col::_InternalLinkedHashSet::•<core::int?>();
     {
       core::Iterator<core::int> :sync-for-iterator = core::_GrowableList::_literal1<core::int>(1).{core::Iterable::iterator}{core::Iterator<core::int>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -2016,7 +2016,7 @@
     }
   } =>#t226;
   core::Set<dynamic> set10 = block {
-    final core::Set<dynamic> #t227 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t227 = new col::_InternalLinkedHashSet::•<dynamic>();
     {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
@@ -2058,7 +2058,7 @@
     }
   } =>#t229;
   core::Set<core::int?> set20 = block {
-    final core::Set<core::int?> #t230 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t230 = new col::_InternalLinkedHashSet::•<core::int?>();
     {
       core::Iterator<core::int> :sync-for-iterator = core::_GrowableList::_literal2<core::int>(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
@@ -2106,7 +2106,7 @@
     }
   } =>#t232;
   core::Set<dynamic> set30 = block {
-    final core::Set<dynamic> #t234 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t234 = new col::_InternalLinkedHashSet::•<dynamic>();
     {
       Never :stream = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
@@ -2163,7 +2163,7 @@
     }
   } =>#t238;
   core::Set<core::int?> set40 = block {
-    final core::Set<core::int?> #t240 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t240 = new col::_InternalLinkedHashSet::•<core::int?>();
     {
       asy::Stream<core::int> :stream = asy::Stream::fromIterable<core::int>(core::_GrowableList::_literal2<core::int>(invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
@@ -2208,7 +2208,7 @@
       #t244.{core::List::add}{Invariant}(42){(core::int) → void};
   } =>#t244;
   core::Set<core::int?> set50 = block {
-    final core::Set<core::int?> #t245 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t245 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (; ; )
       #t245.{core::Set::add}{Invariant}(42){(core::int?) → core::bool};
     #t245.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
@@ -2227,7 +2227,7 @@
       #t247.{core::List::add}{Invariant}(42){(core::int) → void};
   } =>#t247;
   core::Set<core::int?> set60 = block {
-    final core::Set<core::int?> #t248 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t248 = new col::_InternalLinkedHashSet::•<core::int?>();
     for (; invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference2.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError,ForNonNullableByDefault} core::bool; )
@@ -2250,7 +2250,7 @@
       #t250.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t250;
   block {
-    final core::Set<core::int> #t251 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t251 = new col::_InternalLinkedHashSet::•<core::int>();
     await for (core::int i in stream)
       #t251.{core::Set::add}{Invariant}(i){(core::int) → core::bool};
   } =>#t251;
@@ -2267,7 +2267,7 @@
       #t253.{core::List::add}{Invariant}(a{self::B}.{self::B::foo}{core::int}){(core::int) → void};
   } =>#t253;
   core::Set<core::int> set10 = block {
-    final core::Set<core::int> #t254 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t254 = new col::_InternalLinkedHashSet::•<core::int>();
     if(a is{ForNonNullableByDefault} self::B)
       #t254.{core::Set::add}{Invariant}(a{self::B}.{self::B::foo}{core::int}){(core::int) → core::bool};
   } =>#t254;
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.expect
index 1aab9b0..b09b381 100644
--- a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.expect
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.expect
@@ -4,7 +4,7 @@
 
 import "org-dartlang-testcase:///weekly_bot_91_failure_lib.dart";
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _foo = self::_extension#0|_foo;
   tearoff _foo = self::_extension#0|get#_foo;
 }
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.modular.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.modular.expect
index 1aab9b0..b09b381 100644
--- a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.modular.expect
@@ -4,7 +4,7 @@
 
 import "org-dartlang-testcase:///weekly_bot_91_failure_lib.dart";
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _foo = self::_extension#0|_foo;
   tearoff _foo = self::_extension#0|get#_foo;
 }
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.outline.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.outline.expect
index d05e48f..5965269 100644
--- a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.outline.expect
@@ -4,7 +4,7 @@
 
 import "org-dartlang-testcase:///weekly_bot_91_failure_lib.dart";
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _foo = self::_extension#0|_foo;
   tearoff _foo = self::_extension#0|get#_foo;
 }
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.transformed.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.transformed.expect
index 1aab9b0..b09b381 100644
--- a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.transformed.expect
@@ -4,7 +4,7 @@
 
 import "org-dartlang-testcase:///weekly_bot_91_failure_lib.dart";
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _foo = self::_extension#0|_foo;
   tearoff _foo = self::_extension#0|get#_foo;
 }
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.expect
index 7e86e82..729c272 100644
--- a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.expect
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.expect
@@ -4,7 +4,7 @@
 
 import "org-dartlang-testcase:///weekly_bot_91_failure_variation_1_lib.dart";
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _foo = self::_extension#0|_foo;
   tearoff _foo = self::_extension#0|get#_foo;
 }
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.modular.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.modular.expect
index 7e86e82..729c272 100644
--- a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.modular.expect
@@ -4,7 +4,7 @@
 
 import "org-dartlang-testcase:///weekly_bot_91_failure_variation_1_lib.dart";
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _foo = self::_extension#0|_foo;
   tearoff _foo = self::_extension#0|get#_foo;
 }
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.outline.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.outline.expect
index e74ddb8..e4a8616 100644
--- a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.outline.expect
@@ -4,7 +4,7 @@
 
 import "org-dartlang-testcase:///weekly_bot_91_failure_variation_1_lib.dart";
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _foo = self::_extension#0|_foo;
   tearoff _foo = self::_extension#0|get#_foo;
 }
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.transformed.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.transformed.expect
index 7e86e82..729c272 100644
--- a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_variation_1.dart.weak.transformed.expect
@@ -4,7 +4,7 @@
 
 import "org-dartlang-testcase:///weekly_bot_91_failure_variation_1_lib.dart";
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _foo = self::_extension#0|_foo;
   tearoff _foo = self::_extension#0|get#_foo;
 }
diff --git a/pkg/front_end/testcases/general/if_null_in_set_literal.dart.weak.transformed.expect b/pkg/front_end/testcases/general/if_null_in_set_literal.dart.weak.transformed.expect
index ba90659..82d3ba7 100644
--- a/pkg/front_end/testcases/general/if_null_in_set_literal.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/if_null_in_set_literal.dart.weak.transformed.expect
@@ -7,7 +7,7 @@
   core::Object? a;
   core::Object? b;
   return block {
-    final core::Set<core::Object?> #t1 = new col::_CompactLinkedHashSet::•<core::Object?>();
+    final core::Set<core::Object?> #t1 = new col::_InternalLinkedHashSet::•<core::Object?>();
     #t1.{core::Set::add}{Invariant}(let final core::Object? #t2 = a in #t2 == null ?{core::Object?} b : #t2{core::Object}){(core::Object?) → core::bool};
   } =>#t1;
 }
diff --git a/pkg/front_end/testcases/general/inferred_generic_function_type_argument.dart.weak.transformed.expect b/pkg/front_end/testcases/general/inferred_generic_function_type_argument.dart.weak.transformed.expect
index ccf2bce..fdf9534 100644
--- a/pkg/front_end/testcases/general/inferred_generic_function_type_argument.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/inferred_generic_function_type_argument.dart.weak.transformed.expect
@@ -38,7 +38,7 @@
   f = self::method<<T extends core::Object? = dynamic>() → void>();
   core::List<<T extends core::Object? = dynamic>() → void> list = core::_GrowableList::_literal1<<T extends core::Object? = dynamic>() → void>(f);
   core::Set<<T extends core::Object? = dynamic>() → void> set = block {
-    final core::Set<<T extends core::Object? = dynamic>() → void> #t1 = new col::_CompactLinkedHashSet::•<<T extends core::Object? = dynamic>() → void>();
+    final core::Set<<T extends core::Object? = dynamic>() → void> #t1 = new col::_InternalLinkedHashSet::•<<T extends core::Object? = dynamic>() → void>();
     #t1.{core::Set::add}{Invariant}(f){(<T extends core::Object? = dynamic>() → void) → core::bool};
   } =>#t1;
   core::Map<<T extends core::Object? = dynamic>() → void, core::int> map1 = <<T extends core::Object? = dynamic>() → void, core::int>{f: 1};
diff --git a/pkg/front_end/testcases/general/initialzation_errors.dart b/pkg/front_end/testcases/general/initialization_errors.dart
similarity index 100%
rename from pkg/front_end/testcases/general/initialzation_errors.dart
rename to pkg/front_end/testcases/general/initialization_errors.dart
diff --git a/pkg/front_end/testcases/general/initialzation_errors.dart.textual_outline.expect b/pkg/front_end/testcases/general/initialization_errors.dart.textual_outline.expect
similarity index 100%
rename from pkg/front_end/testcases/general/initialzation_errors.dart.textual_outline.expect
rename to pkg/front_end/testcases/general/initialization_errors.dart.textual_outline.expect
diff --git a/pkg/front_end/testcases/general/initialzation_errors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/initialization_errors.dart.textual_outline_modelled.expect
similarity index 100%
rename from pkg/front_end/testcases/general/initialzation_errors.dart.textual_outline_modelled.expect
rename to pkg/front_end/testcases/general/initialization_errors.dart.textual_outline_modelled.expect
diff --git a/pkg/front_end/testcases/general/initialization_errors.dart.weak.expect b/pkg/front_end/testcases/general/initialization_errors.dart.weak.expect
new file mode 100644
index 0000000..46c83fa
--- /dev/null
+++ b/pkg/front_end/testcases/general/initialization_errors.dart.weak.expect
@@ -0,0 +1,221 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
+//         this.x = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
+//         this.x = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:22:16: Error: 'x' is a final instance variable that was initialized at the declaration.
+//       : this.x = 41,
+//                ^
+// pkg/front_end/testcases/general/initialization_errors.dart:20:13: Context: 'x' was initialized here.
+//   final int x = 2;
+//             ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
+//         this.x = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
+//       : this.x = 41,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
+//         this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 2 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
+//       : this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 2;
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
+//       : super(),
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:55:16: Error: Can't have initializers after 'super'.
+//         this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:56:16: Error: Can't have initializers after 'super'.
+//         this.y = 2;
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
+//       : this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 2,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
+//       : assert(true),
+//         ^^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
+//         assert(true);
+//         ^^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
+//         super() {}
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
+//       : super(),
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
+//         super() {}
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
+//         this.named();
+//              ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
+//         super() {}
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:101:16: Error: Can't have initializers after 'super'.
+//         this.x = 42 {}
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x;
+  constructor •() → self::A
+    : self::A::x = 41, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+class B extends core::Object {
+  final field core::int x;
+  constructor •() → self::B
+    : self::B::x = 41, final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+class C extends core::Object {
+  final field core::int x = 2;
+  constructor •() → self::C
+    : final dynamic #t3 = throw new core::_DuplicatedFieldInitializerError::•("x"), final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+class D extends core::Object {
+  final field core::int x;
+  final field core::int y;
+  constructor •() → self::D
+    : final dynamic #t5 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
+      : this.x = 41,
+               ^", final dynamic #t6 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 42 {}
+               ^", this self::D::named() {}
+  constructor named() → self::D
+    : self::D::x = 41, self::D::y = 42, super core::Object::•() {}
+}
+class E extends core::Object {
+  final field core::int x;
+  final field core::int y;
+  constructor •() → self::E
+    : final dynamic #t7 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
+        this.x = 1,
+               ^", final dynamic #t8 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 2 {}
+               ^", this self::E::named() {}
+  constructor named() → self::E
+    : self::E::x = 41, self::E::y = 42, super core::Object::•() {}
+  constructor named2() → self::E
+    : final dynamic #t9 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
+      : this.x = 1,
+               ^", final dynamic #t10 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 2;
+               ^", this self::E::named()
+    ;
+  constructor named3() → self::E
+    : final dynamic #t11 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
+      : super(),
+        ^^^^^", final dynamic #t12 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:55:16: Error: Can't have initializers after 'super'.
+        this.x = 1,
+               ^", final dynamic #t13 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:56:16: Error: Can't have initializers after 'super'.
+        this.y = 2;
+               ^", super core::Object::•()
+    ;
+  constructor named4() → self::E
+    : final dynamic #t14 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
+      : this.x = 1,
+               ^", final dynamic #t15 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 2,
+               ^", this self::E::named()
+    ;
+  constructor named5() → self::E
+    : final dynamic #t16 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
+      : assert(true),
+        ^^^^^^", this self::E::named()
+    ;
+  constructor named6() → self::E
+    : final dynamic #t17 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
+        assert(true);
+        ^^^^^^", this self::E::named()
+    ;
+}
+class F extends core::Object {
+  constructor •() → self::F
+    : final dynamic #t18 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
+        super() {}
+        ^^^^^", this self::F::named() {}
+  constructor named() → self::F
+    : super core::Object::•() {}
+}
+class G extends core::Object {
+  constructor •() → self::G
+    : final dynamic #t19 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
+      : super(),
+        ^^^^^", final dynamic #t20 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
+        super() {}
+        ^^^^^", super core::Object::•() {}
+  constructor named() → self::G
+    : super core::Object::•() {}
+}
+class H extends core::Object {
+  constructor •() → self::H
+    : final dynamic #t21 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
+        this.named();
+             ^", this self::H::named()
+    ;
+  constructor named() → self::H
+    : super core::Object::•() {}
+}
+class I extends core::Object {
+  constructor •() → self::I
+    : final dynamic #t22 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
+        super() {}
+        ^^^^^", super core::Object::•() {}
+}
+class J extends core::Object {
+  field core::int x;
+  constructor •() → self::J
+    : final dynamic #t23 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:101:16: Error: Can't have initializers after 'super'.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/initialization_errors.dart.weak.modular.expect b/pkg/front_end/testcases/general/initialization_errors.dart.weak.modular.expect
new file mode 100644
index 0000000..46c83fa
--- /dev/null
+++ b/pkg/front_end/testcases/general/initialization_errors.dart.weak.modular.expect
@@ -0,0 +1,221 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
+//         this.x = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
+//         this.x = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:22:16: Error: 'x' is a final instance variable that was initialized at the declaration.
+//       : this.x = 41,
+//                ^
+// pkg/front_end/testcases/general/initialization_errors.dart:20:13: Context: 'x' was initialized here.
+//   final int x = 2;
+//             ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
+//         this.x = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
+//       : this.x = 41,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
+//         this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 2 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
+//       : this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 2;
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
+//       : super(),
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:55:16: Error: Can't have initializers after 'super'.
+//         this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:56:16: Error: Can't have initializers after 'super'.
+//         this.y = 2;
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
+//       : this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 2,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
+//       : assert(true),
+//         ^^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
+//         assert(true);
+//         ^^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
+//         super() {}
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
+//       : super(),
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
+//         super() {}
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
+//         this.named();
+//              ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
+//         super() {}
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:101:16: Error: Can't have initializers after 'super'.
+//         this.x = 42 {}
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x;
+  constructor •() → self::A
+    : self::A::x = 41, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+class B extends core::Object {
+  final field core::int x;
+  constructor •() → self::B
+    : self::B::x = 41, final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+class C extends core::Object {
+  final field core::int x = 2;
+  constructor •() → self::C
+    : final dynamic #t3 = throw new core::_DuplicatedFieldInitializerError::•("x"), final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+class D extends core::Object {
+  final field core::int x;
+  final field core::int y;
+  constructor •() → self::D
+    : final dynamic #t5 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
+      : this.x = 41,
+               ^", final dynamic #t6 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 42 {}
+               ^", this self::D::named() {}
+  constructor named() → self::D
+    : self::D::x = 41, self::D::y = 42, super core::Object::•() {}
+}
+class E extends core::Object {
+  final field core::int x;
+  final field core::int y;
+  constructor •() → self::E
+    : final dynamic #t7 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
+        this.x = 1,
+               ^", final dynamic #t8 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 2 {}
+               ^", this self::E::named() {}
+  constructor named() → self::E
+    : self::E::x = 41, self::E::y = 42, super core::Object::•() {}
+  constructor named2() → self::E
+    : final dynamic #t9 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
+      : this.x = 1,
+               ^", final dynamic #t10 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 2;
+               ^", this self::E::named()
+    ;
+  constructor named3() → self::E
+    : final dynamic #t11 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
+      : super(),
+        ^^^^^", final dynamic #t12 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:55:16: Error: Can't have initializers after 'super'.
+        this.x = 1,
+               ^", final dynamic #t13 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:56:16: Error: Can't have initializers after 'super'.
+        this.y = 2;
+               ^", super core::Object::•()
+    ;
+  constructor named4() → self::E
+    : final dynamic #t14 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
+      : this.x = 1,
+               ^", final dynamic #t15 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 2,
+               ^", this self::E::named()
+    ;
+  constructor named5() → self::E
+    : final dynamic #t16 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
+      : assert(true),
+        ^^^^^^", this self::E::named()
+    ;
+  constructor named6() → self::E
+    : final dynamic #t17 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
+        assert(true);
+        ^^^^^^", this self::E::named()
+    ;
+}
+class F extends core::Object {
+  constructor •() → self::F
+    : final dynamic #t18 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
+        super() {}
+        ^^^^^", this self::F::named() {}
+  constructor named() → self::F
+    : super core::Object::•() {}
+}
+class G extends core::Object {
+  constructor •() → self::G
+    : final dynamic #t19 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
+      : super(),
+        ^^^^^", final dynamic #t20 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
+        super() {}
+        ^^^^^", super core::Object::•() {}
+  constructor named() → self::G
+    : super core::Object::•() {}
+}
+class H extends core::Object {
+  constructor •() → self::H
+    : final dynamic #t21 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
+        this.named();
+             ^", this self::H::named()
+    ;
+  constructor named() → self::H
+    : super core::Object::•() {}
+}
+class I extends core::Object {
+  constructor •() → self::I
+    : final dynamic #t22 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
+        super() {}
+        ^^^^^", super core::Object::•() {}
+}
+class J extends core::Object {
+  field core::int x;
+  constructor •() → self::J
+    : final dynamic #t23 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:101:16: Error: Can't have initializers after 'super'.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/initialzation_errors.dart.weak.outline.expect b/pkg/front_end/testcases/general/initialization_errors.dart.weak.outline.expect
similarity index 100%
rename from pkg/front_end/testcases/general/initialzation_errors.dart.weak.outline.expect
rename to pkg/front_end/testcases/general/initialization_errors.dart.weak.outline.expect
diff --git a/pkg/front_end/testcases/general/initialization_errors.dart.weak.transformed.expect b/pkg/front_end/testcases/general/initialization_errors.dart.weak.transformed.expect
new file mode 100644
index 0000000..46c83fa
--- /dev/null
+++ b/pkg/front_end/testcases/general/initialization_errors.dart.weak.transformed.expect
@@ -0,0 +1,221 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
+//         this.x = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
+//         this.x = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:22:16: Error: 'x' is a final instance variable that was initialized at the declaration.
+//       : this.x = 41,
+//                ^
+// pkg/front_end/testcases/general/initialization_errors.dart:20:13: Context: 'x' was initialized here.
+//   final int x = 2;
+//             ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
+//         this.x = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
+//       : this.x = 41,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 42 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
+//         this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 2 {}
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
+//       : this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 2;
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
+//       : super(),
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:55:16: Error: Can't have initializers after 'super'.
+//         this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:56:16: Error: Can't have initializers after 'super'.
+//         this.y = 2;
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
+//       : this.x = 1,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
+//         this.y = 2,
+//                ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
+//       : assert(true),
+//         ^^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
+//         assert(true);
+//         ^^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
+//         super() {}
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
+//       : super(),
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
+//         super() {}
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
+//         this.named();
+//              ^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
+//         super() {}
+//         ^^^^^
+//
+// pkg/front_end/testcases/general/initialization_errors.dart:101:16: Error: Can't have initializers after 'super'.
+//         this.x = 42 {}
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x;
+  constructor •() → self::A
+    : self::A::x = 41, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+class B extends core::Object {
+  final field core::int x;
+  constructor •() → self::B
+    : self::B::x = 41, final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+class C extends core::Object {
+  final field core::int x = 2;
+  constructor •() → self::C
+    : final dynamic #t3 = throw new core::_DuplicatedFieldInitializerError::•("x"), final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+class D extends core::Object {
+  final field core::int x;
+  final field core::int y;
+  constructor •() → self::D
+    : final dynamic #t5 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
+      : this.x = 41,
+               ^", final dynamic #t6 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 42 {}
+               ^", this self::D::named() {}
+  constructor named() → self::D
+    : self::D::x = 41, self::D::y = 42, super core::Object::•() {}
+}
+class E extends core::Object {
+  final field core::int x;
+  final field core::int y;
+  constructor •() → self::E
+    : final dynamic #t7 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
+        this.x = 1,
+               ^", final dynamic #t8 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 2 {}
+               ^", this self::E::named() {}
+  constructor named() → self::E
+    : self::E::x = 41, self::E::y = 42, super core::Object::•() {}
+  constructor named2() → self::E
+    : final dynamic #t9 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
+      : this.x = 1,
+               ^", final dynamic #t10 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 2;
+               ^", this self::E::named()
+    ;
+  constructor named3() → self::E
+    : final dynamic #t11 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
+      : super(),
+        ^^^^^", final dynamic #t12 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:55:16: Error: Can't have initializers after 'super'.
+        this.x = 1,
+               ^", final dynamic #t13 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:56:16: Error: Can't have initializers after 'super'.
+        this.y = 2;
+               ^", super core::Object::•()
+    ;
+  constructor named4() → self::E
+    : final dynamic #t14 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
+      : this.x = 1,
+               ^", final dynamic #t15 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
+        this.y = 2,
+               ^", this self::E::named()
+    ;
+  constructor named5() → self::E
+    : final dynamic #t16 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
+      : assert(true),
+        ^^^^^^", this self::E::named()
+    ;
+  constructor named6() → self::E
+    : final dynamic #t17 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
+        assert(true);
+        ^^^^^^", this self::E::named()
+    ;
+}
+class F extends core::Object {
+  constructor •() → self::F
+    : final dynamic #t18 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
+        super() {}
+        ^^^^^", this self::F::named() {}
+  constructor named() → self::F
+    : super core::Object::•() {}
+}
+class G extends core::Object {
+  constructor •() → self::G
+    : final dynamic #t19 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
+      : super(),
+        ^^^^^", final dynamic #t20 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
+        super() {}
+        ^^^^^", super core::Object::•() {}
+  constructor named() → self::G
+    : super core::Object::•() {}
+}
+class H extends core::Object {
+  constructor •() → self::H
+    : final dynamic #t21 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
+        this.named();
+             ^", this self::H::named()
+    ;
+  constructor named() → self::H
+    : super core::Object::•() {}
+}
+class I extends core::Object {
+  constructor •() → self::I
+    : final dynamic #t22 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
+        super() {}
+        ^^^^^", super core::Object::•() {}
+}
+class J extends core::Object {
+  field core::int x;
+  constructor •() → self::J
+    : final dynamic #t23 = invalid-expression "pkg/front_end/testcases/general/initialization_errors.dart:101:16: Error: Can't have initializers after 'super'.
+        this.x = 42 {}
+               ^", super core::Object::•() {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/initialzation_errors.dart.weak.expect b/pkg/front_end/testcases/general/initialzation_errors.dart.weak.expect
deleted file mode 100644
index f69f20c..0000000
--- a/pkg/front_end/testcases/general/initialzation_errors.dart.weak.expect
+++ /dev/null
@@ -1,221 +0,0 @@
-library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
-//         this.x = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
-//         this.x = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:22:16: Error: 'x' is a final instance variable that was initialized at the declaration.
-//       : this.x = 41,
-//                ^
-// pkg/front_end/testcases/general/initialzation_errors.dart:20:13: Context: 'x' was initialized here.
-//   final int x = 2;
-//             ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
-//         this.x = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
-//       : this.x = 41,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
-//         this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 2 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
-//       : this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 2;
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
-//       : super(),
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:55:16: Error: Can't have initializers after 'super'.
-//         this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:56:16: Error: Can't have initializers after 'super'.
-//         this.y = 2;
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
-//       : this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 2,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
-//       : assert(true),
-//         ^^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
-//         assert(true);
-//         ^^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
-//         super() {}
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
-//       : super(),
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
-//         super() {}
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
-//         this.named();
-//              ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
-//         super() {}
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:101:16: Error: Can't have initializers after 'super'.
-//         this.x = 42 {}
-//                ^
-//
-import self as self;
-import "dart:core" as core;
-
-class A extends core::Object {
-  field core::int x;
-  constructor •() → self::A
-    : self::A::x = 41, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-class B extends core::Object {
-  final field core::int x;
-  constructor •() → self::B
-    : self::B::x = 41, final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-class C extends core::Object {
-  final field core::int x = 2;
-  constructor •() → self::C
-    : final dynamic #t3 = throw new core::_DuplicatedFieldInitializerError::•("x"), final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-class D extends core::Object {
-  final field core::int x;
-  final field core::int y;
-  constructor •() → self::D
-    : final dynamic #t5 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
-      : this.x = 41,
-               ^", final dynamic #t6 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 42 {}
-               ^", this self::D::named() {}
-  constructor named() → self::D
-    : self::D::x = 41, self::D::y = 42, super core::Object::•() {}
-}
-class E extends core::Object {
-  final field core::int x;
-  final field core::int y;
-  constructor •() → self::E
-    : final dynamic #t7 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
-        this.x = 1,
-               ^", final dynamic #t8 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 2 {}
-               ^", this self::E::named() {}
-  constructor named() → self::E
-    : self::E::x = 41, self::E::y = 42, super core::Object::•() {}
-  constructor named2() → self::E
-    : final dynamic #t9 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
-      : this.x = 1,
-               ^", final dynamic #t10 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 2;
-               ^", this self::E::named()
-    ;
-  constructor named3() → self::E
-    : final dynamic #t11 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
-      : super(),
-        ^^^^^", final dynamic #t12 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:55:16: Error: Can't have initializers after 'super'.
-        this.x = 1,
-               ^", final dynamic #t13 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:56:16: Error: Can't have initializers after 'super'.
-        this.y = 2;
-               ^", super core::Object::•()
-    ;
-  constructor named4() → self::E
-    : final dynamic #t14 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
-      : this.x = 1,
-               ^", final dynamic #t15 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 2,
-               ^", this self::E::named()
-    ;
-  constructor named5() → self::E
-    : final dynamic #t16 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
-      : assert(true),
-        ^^^^^^", this self::E::named()
-    ;
-  constructor named6() → self::E
-    : final dynamic #t17 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
-        assert(true);
-        ^^^^^^", this self::E::named()
-    ;
-}
-class F extends core::Object {
-  constructor •() → self::F
-    : final dynamic #t18 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
-        super() {}
-        ^^^^^", this self::F::named() {}
-  constructor named() → self::F
-    : super core::Object::•() {}
-}
-class G extends core::Object {
-  constructor •() → self::G
-    : final dynamic #t19 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
-      : super(),
-        ^^^^^", final dynamic #t20 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
-        super() {}
-        ^^^^^", super core::Object::•() {}
-  constructor named() → self::G
-    : super core::Object::•() {}
-}
-class H extends core::Object {
-  constructor •() → self::H
-    : final dynamic #t21 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
-        this.named();
-             ^", this self::H::named()
-    ;
-  constructor named() → self::H
-    : super core::Object::•() {}
-}
-class I extends core::Object {
-  constructor •() → self::I
-    : final dynamic #t22 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
-        super() {}
-        ^^^^^", super core::Object::•() {}
-}
-class J extends core::Object {
-  field core::int x;
-  constructor •() → self::J
-    : final dynamic #t23 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:101:16: Error: Can't have initializers after 'super'.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/initialzation_errors.dart.weak.modular.expect b/pkg/front_end/testcases/general/initialzation_errors.dart.weak.modular.expect
deleted file mode 100644
index f69f20c..0000000
--- a/pkg/front_end/testcases/general/initialzation_errors.dart.weak.modular.expect
+++ /dev/null
@@ -1,221 +0,0 @@
-library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
-//         this.x = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
-//         this.x = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:22:16: Error: 'x' is a final instance variable that was initialized at the declaration.
-//       : this.x = 41,
-//                ^
-// pkg/front_end/testcases/general/initialzation_errors.dart:20:13: Context: 'x' was initialized here.
-//   final int x = 2;
-//             ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
-//         this.x = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
-//       : this.x = 41,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
-//         this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 2 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
-//       : this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 2;
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
-//       : super(),
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:55:16: Error: Can't have initializers after 'super'.
-//         this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:56:16: Error: Can't have initializers after 'super'.
-//         this.y = 2;
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
-//       : this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 2,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
-//       : assert(true),
-//         ^^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
-//         assert(true);
-//         ^^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
-//         super() {}
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
-//       : super(),
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
-//         super() {}
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
-//         this.named();
-//              ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
-//         super() {}
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:101:16: Error: Can't have initializers after 'super'.
-//         this.x = 42 {}
-//                ^
-//
-import self as self;
-import "dart:core" as core;
-
-class A extends core::Object {
-  field core::int x;
-  constructor •() → self::A
-    : self::A::x = 41, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-class B extends core::Object {
-  final field core::int x;
-  constructor •() → self::B
-    : self::B::x = 41, final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-class C extends core::Object {
-  final field core::int x = 2;
-  constructor •() → self::C
-    : final dynamic #t3 = throw new core::_DuplicatedFieldInitializerError::•("x"), final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-class D extends core::Object {
-  final field core::int x;
-  final field core::int y;
-  constructor •() → self::D
-    : final dynamic #t5 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
-      : this.x = 41,
-               ^", final dynamic #t6 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 42 {}
-               ^", this self::D::named() {}
-  constructor named() → self::D
-    : self::D::x = 41, self::D::y = 42, super core::Object::•() {}
-}
-class E extends core::Object {
-  final field core::int x;
-  final field core::int y;
-  constructor •() → self::E
-    : final dynamic #t7 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
-        this.x = 1,
-               ^", final dynamic #t8 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 2 {}
-               ^", this self::E::named() {}
-  constructor named() → self::E
-    : self::E::x = 41, self::E::y = 42, super core::Object::•() {}
-  constructor named2() → self::E
-    : final dynamic #t9 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
-      : this.x = 1,
-               ^", final dynamic #t10 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 2;
-               ^", this self::E::named()
-    ;
-  constructor named3() → self::E
-    : final dynamic #t11 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
-      : super(),
-        ^^^^^", final dynamic #t12 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:55:16: Error: Can't have initializers after 'super'.
-        this.x = 1,
-               ^", final dynamic #t13 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:56:16: Error: Can't have initializers after 'super'.
-        this.y = 2;
-               ^", super core::Object::•()
-    ;
-  constructor named4() → self::E
-    : final dynamic #t14 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
-      : this.x = 1,
-               ^", final dynamic #t15 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 2,
-               ^", this self::E::named()
-    ;
-  constructor named5() → self::E
-    : final dynamic #t16 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
-      : assert(true),
-        ^^^^^^", this self::E::named()
-    ;
-  constructor named6() → self::E
-    : final dynamic #t17 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
-        assert(true);
-        ^^^^^^", this self::E::named()
-    ;
-}
-class F extends core::Object {
-  constructor •() → self::F
-    : final dynamic #t18 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
-        super() {}
-        ^^^^^", this self::F::named() {}
-  constructor named() → self::F
-    : super core::Object::•() {}
-}
-class G extends core::Object {
-  constructor •() → self::G
-    : final dynamic #t19 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
-      : super(),
-        ^^^^^", final dynamic #t20 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
-        super() {}
-        ^^^^^", super core::Object::•() {}
-  constructor named() → self::G
-    : super core::Object::•() {}
-}
-class H extends core::Object {
-  constructor •() → self::H
-    : final dynamic #t21 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
-        this.named();
-             ^", this self::H::named()
-    ;
-  constructor named() → self::H
-    : super core::Object::•() {}
-}
-class I extends core::Object {
-  constructor •() → self::I
-    : final dynamic #t22 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
-        super() {}
-        ^^^^^", super core::Object::•() {}
-}
-class J extends core::Object {
-  field core::int x;
-  constructor •() → self::J
-    : final dynamic #t23 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:101:16: Error: Can't have initializers after 'super'.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/initialzation_errors.dart.weak.transformed.expect b/pkg/front_end/testcases/general/initialzation_errors.dart.weak.transformed.expect
deleted file mode 100644
index f69f20c..0000000
--- a/pkg/front_end/testcases/general/initialzation_errors.dart.weak.transformed.expect
+++ /dev/null
@@ -1,221 +0,0 @@
-library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
-//         this.x = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
-//         this.x = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:22:16: Error: 'x' is a final instance variable that was initialized at the declaration.
-//       : this.x = 41,
-//                ^
-// pkg/front_end/testcases/general/initialzation_errors.dart:20:13: Context: 'x' was initialized here.
-//   final int x = 2;
-//             ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
-//         this.x = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
-//       : this.x = 41,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 42 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
-//         this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 2 {}
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
-//       : this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 2;
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
-//       : super(),
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:55:16: Error: Can't have initializers after 'super'.
-//         this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:56:16: Error: Can't have initializers after 'super'.
-//         this.y = 2;
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
-//       : this.x = 1,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
-//         this.y = 2,
-//                ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
-//       : assert(true),
-//         ^^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
-//         assert(true);
-//         ^^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
-//         super() {}
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
-//       : super(),
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
-//         super() {}
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
-//         this.named();
-//              ^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
-//         super() {}
-//         ^^^^^
-//
-// pkg/front_end/testcases/general/initialzation_errors.dart:101:16: Error: Can't have initializers after 'super'.
-//         this.x = 42 {}
-//                ^
-//
-import self as self;
-import "dart:core" as core;
-
-class A extends core::Object {
-  field core::int x;
-  constructor •() → self::A
-    : self::A::x = 41, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:9:16: Error: 'x' was already initialized by this constructor.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-class B extends core::Object {
-  final field core::int x;
-  constructor •() → self::B
-    : self::B::x = 41, final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:16:16: Error: 'x' was already initialized by this constructor.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-class C extends core::Object {
-  final field core::int x = 2;
-  constructor •() → self::C
-    : final dynamic #t3 = throw new core::_DuplicatedFieldInitializerError::•("x"), final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:23:16: Error: 'x' was already initialized by this constructor.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-class D extends core::Object {
-  final field core::int x;
-  final field core::int y;
-  constructor •() → self::D
-    : final dynamic #t5 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:30:16: Error: A redirecting constructor can't have other initializers.
-      : this.x = 41,
-               ^", final dynamic #t6 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:32:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 42 {}
-               ^", this self::D::named() {}
-  constructor named() → self::D
-    : self::D::x = 41, self::D::y = 42, super core::Object::•() {}
-}
-class E extends core::Object {
-  final field core::int x;
-  final field core::int y;
-  constructor •() → self::E
-    : final dynamic #t7 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:43:16: Error: A redirecting constructor can't have other initializers.
-        this.x = 1,
-               ^", final dynamic #t8 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:44:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 2 {}
-               ^", this self::E::named() {}
-  constructor named() → self::E
-    : self::E::x = 41, self::E::y = 42, super core::Object::•() {}
-  constructor named2() → self::E
-    : final dynamic #t9 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:49:16: Error: A redirecting constructor can't have other initializers.
-      : this.x = 1,
-               ^", final dynamic #t10 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:51:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 2;
-               ^", this self::E::named()
-    ;
-  constructor named3() → self::E
-    : final dynamic #t11 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:53:9: Error: A redirecting constructor can't have a 'super' initializer.
-      : super(),
-        ^^^^^", final dynamic #t12 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:55:16: Error: Can't have initializers after 'super'.
-        this.x = 1,
-               ^", final dynamic #t13 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:56:16: Error: Can't have initializers after 'super'.
-        this.y = 2;
-               ^", super core::Object::•()
-    ;
-  constructor named4() → self::E
-    : final dynamic #t14 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:58:16: Error: A redirecting constructor can't have other initializers.
-      : this.x = 1,
-               ^", final dynamic #t15 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:59:16: Error: A redirecting constructor can't have other initializers.
-        this.y = 2,
-               ^", this self::E::named()
-    ;
-  constructor named5() → self::E
-    : final dynamic #t16 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:62:9: Error: A redirecting constructor can't have other initializers.
-      : assert(true),
-        ^^^^^^", this self::E::named()
-    ;
-  constructor named6() → self::E
-    : final dynamic #t17 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:66:9: Error: A redirecting constructor can't have other initializers.
-        assert(true);
-        ^^^^^^", this self::E::named()
-    ;
-}
-class F extends core::Object {
-  constructor •() → self::F
-    : final dynamic #t18 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:72:9: Error: A redirecting constructor can't have a 'super' initializer.
-        super() {}
-        ^^^^^", this self::F::named() {}
-  constructor named() → self::F
-    : super core::Object::•() {}
-}
-class G extends core::Object {
-  constructor •() → self::G
-    : final dynamic #t19 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:78:9: Error: A redirecting constructor can't have a 'super' initializer.
-      : super(),
-        ^^^^^", final dynamic #t20 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:80:9: Error: Can't have more than one 'super' initializer.
-        super() {}
-        ^^^^^", super core::Object::•() {}
-  constructor named() → self::G
-    : super core::Object::•() {}
-}
-class H extends core::Object {
-  constructor •() → self::H
-    : final dynamic #t21 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:87:14: Error: A redirecting constructor can't have more than one redirection.
-        this.named();
-             ^", this self::H::named()
-    ;
-  constructor named() → self::H
-    : super core::Object::•() {}
-}
-class I extends core::Object {
-  constructor •() → self::I
-    : final dynamic #t22 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:94:9: Error: Can't have more than one 'super' initializer.
-        super() {}
-        ^^^^^", super core::Object::•() {}
-}
-class J extends core::Object {
-  field core::int x;
-  constructor •() → self::J
-    : final dynamic #t23 = invalid-expression "pkg/front_end/testcases/general/initialzation_errors.dart:101:16: Error: Can't have initializers after 'super'.
-        this.x = 42 {}
-               ^", super core::Object::•() {}
-}
-static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue28565.dart b/pkg/front_end/testcases/general/issue28565.dart
new file mode 100644
index 0000000..db1fd5e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue28565.dart
@@ -0,0 +1,30 @@
+// 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.
+
+class A {
+  external A();
+}
+
+class B {
+  external const B();
+}
+
+class C {
+  external C.named();
+}
+
+class D {
+  external const D.named();
+}
+
+class E {
+  external E() : super();
+  external E.redirect() : this();
+}
+
+class F {
+  external F() {
+    print("I have a body");
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/issue28565.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue28565.dart.textual_outline.expect
new file mode 100644
index 0000000..0c64648
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue28565.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class A {
+  external A();
+}
+class B {
+  external const B();
+}
+class C {
+  external C.named();
+}
+class D {
+  external const D.named();
+}
+class E {
+  external E() : super();
+  external E.redirect() : this();
+}
+class F {
+  external F() {}
+}
diff --git a/pkg/front_end/testcases/general/issue28565.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue28565.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1ef429
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue28565.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A {
+  external A();
+}
+
+class B {
+  external const B();
+}
+
+class C {
+  external C.named();
+}
+
+class D {
+  external const D.named();
+}
diff --git a/pkg/front_end/testcases/general/issue28565.dart.weak.expect b/pkg/front_end/testcases/general/issue28565.dart.weak.expect
new file mode 100644
index 0000000..8b563dc
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue28565.dart.weak.expect
@@ -0,0 +1,51 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue28565.dart:22:16: Error: An external constructor can't have any initializers.
+//   external E() : super();
+//                ^
+//
+// pkg/front_end/testcases/general/issue28565.dart:23:25: Error: An external constructor can't have any initializers.
+//   external E.redirect() : this();
+//                         ^
+//
+// pkg/front_end/testcases/general/issue28565.dart:27:16: Error: An external or native method can't have a body.
+//   external F() {
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  external constructor •() → self::A
+    ;
+}
+class B extends core::Object /*hasConstConstructor*/  {
+  external const constructor •() → self::B
+    ;
+}
+class C extends core::Object {
+  external constructor named() → self::C
+    ;
+}
+class D extends core::Object /*hasConstConstructor*/  {
+  external const constructor named() → self::D
+    ;
+}
+class E extends core::Object {
+  external constructor •() → self::E
+    ;
+  external constructor redirect() → self::E
+    ;
+}
+class F extends core::Object {
+  external constructor •() → self::F {
+    invalid-expression "pkg/front_end/testcases/general/issue28565.dart:27:16: Error: An external or native method can't have a body.
+  external F() {
+               ^";
+    {
+      core::print("I have a body");
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/general/issue28565.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue28565.dart.weak.modular.expect
new file mode 100644
index 0000000..8b563dc
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue28565.dart.weak.modular.expect
@@ -0,0 +1,51 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue28565.dart:22:16: Error: An external constructor can't have any initializers.
+//   external E() : super();
+//                ^
+//
+// pkg/front_end/testcases/general/issue28565.dart:23:25: Error: An external constructor can't have any initializers.
+//   external E.redirect() : this();
+//                         ^
+//
+// pkg/front_end/testcases/general/issue28565.dart:27:16: Error: An external or native method can't have a body.
+//   external F() {
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  external constructor •() → self::A
+    ;
+}
+class B extends core::Object /*hasConstConstructor*/  {
+  external const constructor •() → self::B
+    ;
+}
+class C extends core::Object {
+  external constructor named() → self::C
+    ;
+}
+class D extends core::Object /*hasConstConstructor*/  {
+  external const constructor named() → self::D
+    ;
+}
+class E extends core::Object {
+  external constructor •() → self::E
+    ;
+  external constructor redirect() → self::E
+    ;
+}
+class F extends core::Object {
+  external constructor •() → self::F {
+    invalid-expression "pkg/front_end/testcases/general/issue28565.dart:27:16: Error: An external or native method can't have a body.
+  external F() {
+               ^";
+    {
+      core::print("I have a body");
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/general/issue28565.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue28565.dart.weak.outline.expect
new file mode 100644
index 0000000..180e18d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue28565.dart.weak.outline.expect
@@ -0,0 +1,45 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue28565.dart:22:16: Error: An external constructor can't have any initializers.
+//   external E() : super();
+//                ^
+//
+// pkg/front_end/testcases/general/issue28565.dart:23:25: Error: An external constructor can't have any initializers.
+//   external E.redirect() : this();
+//                         ^
+//
+// pkg/front_end/testcases/general/issue28565.dart:27:16: Error: An external or native method can't have a body.
+//   external F() {
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  external constructor •() → self::A
+    ;
+}
+class B extends core::Object /*hasConstConstructor*/  {
+  external const constructor •() → self::B
+    ;
+}
+class C extends core::Object {
+  external constructor named() → self::C
+    ;
+}
+class D extends core::Object /*hasConstConstructor*/  {
+  external const constructor named() → self::D
+    ;
+}
+class E extends core::Object {
+  external constructor •() → self::E
+    ;
+  external constructor redirect() → self::E
+    ;
+}
+class F extends core::Object {
+  external constructor •() → self::F
+    ;
+}
diff --git a/pkg/front_end/testcases/general/issue28565.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue28565.dart.weak.transformed.expect
new file mode 100644
index 0000000..8b563dc
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue28565.dart.weak.transformed.expect
@@ -0,0 +1,51 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue28565.dart:22:16: Error: An external constructor can't have any initializers.
+//   external E() : super();
+//                ^
+//
+// pkg/front_end/testcases/general/issue28565.dart:23:25: Error: An external constructor can't have any initializers.
+//   external E.redirect() : this();
+//                         ^
+//
+// pkg/front_end/testcases/general/issue28565.dart:27:16: Error: An external or native method can't have a body.
+//   external F() {
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  external constructor •() → self::A
+    ;
+}
+class B extends core::Object /*hasConstConstructor*/  {
+  external const constructor •() → self::B
+    ;
+}
+class C extends core::Object {
+  external constructor named() → self::C
+    ;
+}
+class D extends core::Object /*hasConstConstructor*/  {
+  external const constructor named() → self::D
+    ;
+}
+class E extends core::Object {
+  external constructor •() → self::E
+    ;
+  external constructor redirect() → self::E
+    ;
+}
+class F extends core::Object {
+  external constructor •() → self::F {
+    invalid-expression "pkg/front_end/testcases/general/issue28565.dart:27:16: Error: An external or native method can't have a body.
+  external F() {
+               ^";
+    {
+      core::print("I have a body");
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/general/issue37027.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue37027.dart.weak.transformed.expect
index ea3bc5b..c2874a4 100644
--- a/pkg/front_end/testcases/general/issue37027.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue37027.dart.weak.transformed.expect
@@ -7,7 +7,7 @@
   final field core::Set<core::int> s;
   constructor •(core::List<core::int> ell) → self::C
     : self::C::s = block {
-      final core::Set<core::int> #t1 = new col::_CompactLinkedHashSet::•<core::int>();
+      final core::Set<core::int> #t1 = new col::_InternalLinkedHashSet::•<core::int>();
       {
         core::Iterator<core::int> :sync-for-iterator = ell.{core::Iterable::iterator}{core::Iterator<core::int>};
         for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
diff --git a/pkg/front_end/testcases/general/issue48765.dart b/pkg/front_end/testcases/general/issue48765.dart
new file mode 100644
index 0000000..6b737c5
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48765.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, 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.
+
+part 'issue48765_part1.dart';
+part 'issue48765_part2.dart';
+
+void main() {
+  _Ac().method();
+  _Bc().method();
+}
diff --git a/pkg/front_end/testcases/general/issue48765.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue48765.dart.textual_outline.expect
new file mode 100644
index 0000000..9896e00
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48765.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+part 'issue48765_part1.dart';
+part 'issue48765_part2.dart';
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue48765.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue48765.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9896e00
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48765.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+part 'issue48765_part1.dart';
+part 'issue48765_part2.dart';
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue48765.dart.weak.expect b/pkg/front_end/testcases/general/issue48765.dart.weak.expect
new file mode 100644
index 0000000..af64132
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48765.dart.weak.expect
@@ -0,0 +1,52 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+part issue48765_part1.dart;
+part issue48765_part2.dart;
+abstract class _A extends core::Object { // from org-dartlang-testcase:///issue48765_part1.dart
+  synthetic constructor •() → self::_A
+    : super core::Object::•()
+    ;
+}
+class _Ac extends core::Object implements self::_A { // from org-dartlang-testcase:///issue48765_part1.dart
+  synthetic constructor •() → self::_Ac
+    : super core::Object::•()
+    ;
+}
+abstract class _B extends core::Object { // from org-dartlang-testcase:///issue48765_part2.dart
+  synthetic constructor •() → self::_B
+    : super core::Object::•()
+    ;
+}
+class _Bc extends core::Object implements self::_B { // from org-dartlang-testcase:///issue48765_part2.dart
+  synthetic constructor •() → self::_Bc
+    : super core::Object::•()
+    ;
+}
+extension /* unnamed */ _extension#0 on self::_A { // from org-dartlang-testcase:///issue48765_part1.dart
+  static field field = self::_extension#0|field;
+  method method = self::_extension#0|method;
+  tearoff method = self::_extension#0|get#method;
+}
+extension /* unnamed */ _extension#1 on self::_B { // from org-dartlang-testcase:///issue48765_part2.dart
+  static field field = self::_extension#1|field;
+  method method = self::_extension#1|method;
+  tearoff method = self::_extension#1|get#method;
+}
+static field core::int _extension#0|field = 0 /* from org-dartlang-testcase:///issue48765_part1.dart */;
+static field core::int _extension#1|field = 0 /* from org-dartlang-testcase:///issue48765_part2.dart */;
+static method main() → void {
+  self::_extension#0|method(new self::_Ac::•());
+  self::_extension#1|method(new self::_Bc::•());
+}
+static method /* from org-dartlang-testcase:///issue48765_part1.dart */ _extension#0|method(lowered final self::_A #this) → void {
+  self::_extension#0|field = self::_extension#0|field.{core::num::+}(1){(core::num) → core::int};
+}
+static method /* from org-dartlang-testcase:///issue48765_part1.dart */ _extension#0|get#method(lowered final self::_A #this) → () → void
+  return () → void => self::_extension#0|method(#this);
+static method /* from org-dartlang-testcase:///issue48765_part2.dart */ _extension#1|method(lowered final self::_B #this) → void {
+  self::_extension#1|field = self::_extension#1|field.{core::num::+}(1){(core::num) → core::int};
+}
+static method /* from org-dartlang-testcase:///issue48765_part2.dart */ _extension#1|get#method(lowered final self::_B #this) → () → void
+  return () → void => self::_extension#1|method(#this);
diff --git a/pkg/front_end/testcases/general/issue48765.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue48765.dart.weak.modular.expect
new file mode 100644
index 0000000..af64132
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48765.dart.weak.modular.expect
@@ -0,0 +1,52 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+part issue48765_part1.dart;
+part issue48765_part2.dart;
+abstract class _A extends core::Object { // from org-dartlang-testcase:///issue48765_part1.dart
+  synthetic constructor •() → self::_A
+    : super core::Object::•()
+    ;
+}
+class _Ac extends core::Object implements self::_A { // from org-dartlang-testcase:///issue48765_part1.dart
+  synthetic constructor •() → self::_Ac
+    : super core::Object::•()
+    ;
+}
+abstract class _B extends core::Object { // from org-dartlang-testcase:///issue48765_part2.dart
+  synthetic constructor •() → self::_B
+    : super core::Object::•()
+    ;
+}
+class _Bc extends core::Object implements self::_B { // from org-dartlang-testcase:///issue48765_part2.dart
+  synthetic constructor •() → self::_Bc
+    : super core::Object::•()
+    ;
+}
+extension /* unnamed */ _extension#0 on self::_A { // from org-dartlang-testcase:///issue48765_part1.dart
+  static field field = self::_extension#0|field;
+  method method = self::_extension#0|method;
+  tearoff method = self::_extension#0|get#method;
+}
+extension /* unnamed */ _extension#1 on self::_B { // from org-dartlang-testcase:///issue48765_part2.dart
+  static field field = self::_extension#1|field;
+  method method = self::_extension#1|method;
+  tearoff method = self::_extension#1|get#method;
+}
+static field core::int _extension#0|field = 0 /* from org-dartlang-testcase:///issue48765_part1.dart */;
+static field core::int _extension#1|field = 0 /* from org-dartlang-testcase:///issue48765_part2.dart */;
+static method main() → void {
+  self::_extension#0|method(new self::_Ac::•());
+  self::_extension#1|method(new self::_Bc::•());
+}
+static method /* from org-dartlang-testcase:///issue48765_part1.dart */ _extension#0|method(lowered final self::_A #this) → void {
+  self::_extension#0|field = self::_extension#0|field.{core::num::+}(1){(core::num) → core::int};
+}
+static method /* from org-dartlang-testcase:///issue48765_part1.dart */ _extension#0|get#method(lowered final self::_A #this) → () → void
+  return () → void => self::_extension#0|method(#this);
+static method /* from org-dartlang-testcase:///issue48765_part2.dart */ _extension#1|method(lowered final self::_B #this) → void {
+  self::_extension#1|field = self::_extension#1|field.{core::num::+}(1){(core::num) → core::int};
+}
+static method /* from org-dartlang-testcase:///issue48765_part2.dart */ _extension#1|get#method(lowered final self::_B #this) → () → void
+  return () → void => self::_extension#1|method(#this);
diff --git a/pkg/front_end/testcases/general/issue48765.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue48765.dart.weak.outline.expect
new file mode 100644
index 0000000..a598c2c
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48765.dart.weak.outline.expect
@@ -0,0 +1,44 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+part issue48765_part1.dart;
+part issue48765_part2.dart;
+abstract class _A extends core::Object { // from org-dartlang-testcase:///issue48765_part1.dart
+  synthetic constructor •() → self::_A
+    ;
+}
+class _Ac extends core::Object implements self::_A { // from org-dartlang-testcase:///issue48765_part1.dart
+  synthetic constructor •() → self::_Ac
+    ;
+}
+abstract class _B extends core::Object { // from org-dartlang-testcase:///issue48765_part2.dart
+  synthetic constructor •() → self::_B
+    ;
+}
+class _Bc extends core::Object implements self::_B { // from org-dartlang-testcase:///issue48765_part2.dart
+  synthetic constructor •() → self::_Bc
+    ;
+}
+extension /* unnamed */ _extension#0 on self::_A { // from org-dartlang-testcase:///issue48765_part1.dart
+  static field field = self::_extension#0|field;
+  method method = self::_extension#0|method;
+  tearoff method = self::_extension#0|get#method;
+}
+extension /* unnamed */ _extension#1 on self::_B { // from org-dartlang-testcase:///issue48765_part2.dart
+  static field field = self::_extension#1|field;
+  method method = self::_extension#1|method;
+  tearoff method = self::_extension#1|get#method;
+}
+static field core::int _extension#0|field /* from org-dartlang-testcase:///issue48765_part1.dart */;
+static field core::int _extension#1|field /* from org-dartlang-testcase:///issue48765_part2.dart */;
+static method main() → void
+  ;
+static method /* from org-dartlang-testcase:///issue48765_part1.dart */ _extension#0|method(lowered final self::_A #this) → void
+  ;
+static method /* from org-dartlang-testcase:///issue48765_part1.dart */ _extension#0|get#method(lowered final self::_A #this) → () → void
+  return () → void => self::_extension#0|method(#this);
+static method /* from org-dartlang-testcase:///issue48765_part2.dart */ _extension#1|method(lowered final self::_B #this) → void
+  ;
+static method /* from org-dartlang-testcase:///issue48765_part2.dart */ _extension#1|get#method(lowered final self::_B #this) → () → void
+  return () → void => self::_extension#1|method(#this);
diff --git a/pkg/front_end/testcases/general/issue48765.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue48765.dart.weak.transformed.expect
new file mode 100644
index 0000000..af64132
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48765.dart.weak.transformed.expect
@@ -0,0 +1,52 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+part issue48765_part1.dart;
+part issue48765_part2.dart;
+abstract class _A extends core::Object { // from org-dartlang-testcase:///issue48765_part1.dart
+  synthetic constructor •() → self::_A
+    : super core::Object::•()
+    ;
+}
+class _Ac extends core::Object implements self::_A { // from org-dartlang-testcase:///issue48765_part1.dart
+  synthetic constructor •() → self::_Ac
+    : super core::Object::•()
+    ;
+}
+abstract class _B extends core::Object { // from org-dartlang-testcase:///issue48765_part2.dart
+  synthetic constructor •() → self::_B
+    : super core::Object::•()
+    ;
+}
+class _Bc extends core::Object implements self::_B { // from org-dartlang-testcase:///issue48765_part2.dart
+  synthetic constructor •() → self::_Bc
+    : super core::Object::•()
+    ;
+}
+extension /* unnamed */ _extension#0 on self::_A { // from org-dartlang-testcase:///issue48765_part1.dart
+  static field field = self::_extension#0|field;
+  method method = self::_extension#0|method;
+  tearoff method = self::_extension#0|get#method;
+}
+extension /* unnamed */ _extension#1 on self::_B { // from org-dartlang-testcase:///issue48765_part2.dart
+  static field field = self::_extension#1|field;
+  method method = self::_extension#1|method;
+  tearoff method = self::_extension#1|get#method;
+}
+static field core::int _extension#0|field = 0 /* from org-dartlang-testcase:///issue48765_part1.dart */;
+static field core::int _extension#1|field = 0 /* from org-dartlang-testcase:///issue48765_part2.dart */;
+static method main() → void {
+  self::_extension#0|method(new self::_Ac::•());
+  self::_extension#1|method(new self::_Bc::•());
+}
+static method /* from org-dartlang-testcase:///issue48765_part1.dart */ _extension#0|method(lowered final self::_A #this) → void {
+  self::_extension#0|field = self::_extension#0|field.{core::num::+}(1){(core::num) → core::int};
+}
+static method /* from org-dartlang-testcase:///issue48765_part1.dart */ _extension#0|get#method(lowered final self::_A #this) → () → void
+  return () → void => self::_extension#0|method(#this);
+static method /* from org-dartlang-testcase:///issue48765_part2.dart */ _extension#1|method(lowered final self::_B #this) → void {
+  self::_extension#1|field = self::_extension#1|field.{core::num::+}(1){(core::num) → core::int};
+}
+static method /* from org-dartlang-testcase:///issue48765_part2.dart */ _extension#1|get#method(lowered final self::_B #this) → () → void
+  return () → void => self::_extension#1|method(#this);
diff --git a/pkg/front_end/testcases/general/issue48765_part1.dart b/pkg/front_end/testcases/general/issue48765_part1.dart
new file mode 100644
index 0000000..8bd8e0b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48765_part1.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, 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.
+
+part of 'issue48765.dart';
+
+abstract class _A {}
+
+class _Ac implements _A {}
+
+extension on _A {
+  static int field = 0;
+  void method() {
+    field++;
+  }
+}
diff --git a/pkg/front_end/testcases/general/issue48765_part2.dart b/pkg/front_end/testcases/general/issue48765_part2.dart
new file mode 100644
index 0000000..6d724ba
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48765_part2.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, 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.
+
+part of 'issue48765.dart';
+
+abstract class _B {}
+
+class _Bc implements _B {}
+
+extension on _B {
+  static int field = 0;
+  void method() {
+    field++;
+  }
+}
diff --git a/pkg/front_end/testcases/general/issue49357a.dart b/pkg/front_end/testcases/general/issue49357a.dart
new file mode 100644
index 0000000..681b9b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357a.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, 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.
+
+abstract class A extends B {
+  A({
+    required super.field,
+  });
+}
+
+class C {
+  void method(list) {
+    for (final element in list) {
+    //}
+  }
+}
diff --git a/pkg/front_end/testcases/general/issue49357a.dart.weak.expect b/pkg/front_end/testcases/general/issue49357a.dart.weak.expect
new file mode 100644
index 0000000..b67db6d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357a.dart.weak.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49357a.dart:11:9: Error: Can't find '}' to match '{'.
+// class C {
+//         ^
+//
+// pkg/front_end/testcases/general/issue49357a.dart:5:26: Error: Type 'B' not found.
+// abstract class A extends B {
+//                          ^
+//
+// pkg/front_end/testcases/general/issue49357a.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+//   A({
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  constructor •({required invalid-type field = #C1}) → self::A
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue49357a.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+  A({
+  ^"
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method method(dynamic list) → void {
+    for (final dynamic element in list as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+    }
+  }
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue49357a.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue49357a.dart.weak.modular.expect
new file mode 100644
index 0000000..b67db6d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357a.dart.weak.modular.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49357a.dart:11:9: Error: Can't find '}' to match '{'.
+// class C {
+//         ^
+//
+// pkg/front_end/testcases/general/issue49357a.dart:5:26: Error: Type 'B' not found.
+// abstract class A extends B {
+//                          ^
+//
+// pkg/front_end/testcases/general/issue49357a.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+//   A({
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  constructor •({required invalid-type field = #C1}) → self::A
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue49357a.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+  A({
+  ^"
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method method(dynamic list) → void {
+    for (final dynamic element in list as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
+    }
+  }
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue49357a.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue49357a.dart.weak.outline.expect
new file mode 100644
index 0000000..c5eda15
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357a.dart.weak.outline.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49357a.dart:11:9: Error: Can't find '}' to match '{'.
+// class C {
+//         ^
+//
+// pkg/front_end/testcases/general/issue49357a.dart:5:26: Error: Type 'B' not found.
+// abstract class A extends B {
+//                          ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  constructor •({required invalid-type field = null}) → self::A
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+  method method(dynamic list) → void
+    ;
+}
diff --git a/pkg/front_end/testcases/general/issue49357a.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue49357a.dart.weak.transformed.expect
new file mode 100644
index 0000000..cce0bd0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357a.dart.weak.transformed.expect
@@ -0,0 +1,44 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49357a.dart:11:9: Error: Can't find '}' to match '{'.
+// class C {
+//         ^
+//
+// pkg/front_end/testcases/general/issue49357a.dart:5:26: Error: Type 'B' not found.
+// abstract class A extends B {
+//                          ^
+//
+// pkg/front_end/testcases/general/issue49357a.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+//   A({
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  constructor •({required invalid-type field = #C1}) → self::A
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue49357a.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+  A({
+  ^"
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method method(dynamic list) → void {
+    {
+      core::Iterator<dynamic> :sync-for-iterator = (list as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator}{core::Iterator<dynamic>};
+      for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
+        final dynamic element = :sync-for-iterator.{core::Iterator::current}{dynamic};
+        {}
+      }
+    }
+  }
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue49357b.dart b/pkg/front_end/testcases/general/issue49357b.dart
new file mode 100644
index 0000000..59c6cca
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357b.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, 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.
+
+class A extends B {
+  A({required super.field});
+}
+
+class B {
+  final int field;
+
+  B.named({required this.field});
+}
diff --git a/pkg/front_end/testcases/general/issue49357b.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue49357b.dart.textual_outline.expect
new file mode 100644
index 0000000..f4f5614
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357b.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A extends B {
+  A({required super.field});
+}
+
+class B {
+  final int field;
+  B.named({required this.field});
+}
diff --git a/pkg/front_end/testcases/general/issue49357b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue49357b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..455e4b4
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357b.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A extends B {
+  A({required super.field});
+}
+
+class B {
+  B.named({required this.field});
+  final int field;
+}
diff --git a/pkg/front_end/testcases/general/issue49357b.dart.weak.expect b/pkg/front_end/testcases/general/issue49357b.dart.weak.expect
new file mode 100644
index 0000000..7252bbd7
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357b.dart.weak.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49357b.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+//   A({required super.field});
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends self::B {
+  constructor •({required invalid-type field = #C1}) → self::A
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue49357b.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+  A({required super.field});
+  ^"
+    ;
+}
+class B extends core::Object {
+  final field core::int field;
+  constructor named({required core::int field = #C1}) → self::B
+    : self::B::field = field, super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue49357b.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue49357b.dart.weak.modular.expect
new file mode 100644
index 0000000..7252bbd7
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357b.dart.weak.modular.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49357b.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+//   A({required super.field});
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends self::B {
+  constructor •({required invalid-type field = #C1}) → self::A
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue49357b.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+  A({required super.field});
+  ^"
+    ;
+}
+class B extends core::Object {
+  final field core::int field;
+  constructor named({required core::int field = #C1}) → self::B
+    : self::B::field = field, super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue49357b.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue49357b.dart.weak.outline.expect
new file mode 100644
index 0000000..a47e5e1
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357b.dart.weak.outline.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends self::B {
+  constructor •({required invalid-type field = null}) → self::A
+    ;
+}
+class B extends core::Object {
+  final field core::int field;
+  constructor named({required core::int field = null}) → self::B
+    ;
+}
diff --git a/pkg/front_end/testcases/general/issue49357b.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue49357b.dart.weak.transformed.expect
new file mode 100644
index 0000000..7252bbd7
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49357b.dart.weak.transformed.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49357b.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+//   A({required super.field});
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends self::B {
+  constructor •({required invalid-type field = #C1}) → self::A
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue49357b.dart:6:3: Error: The superclass, 'B', has no unnamed constructor that takes no arguments.
+  A({required super.field});
+  ^"
+    ;
+}
+class B extends core::Object {
+  final field core::int field;
+  constructor named({required core::int field = #C1}) → self::B
+    : self::B::field = field, super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue49908.dart b/pkg/front_end/testcases/general/issue49908.dart
new file mode 100644
index 0000000..1faf35a
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49908.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, 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.
+
+foo<T, S>(bool b, T t, S s) {
+  if (t is Object) {
+    return b ? t : s; // The upper bound is supposed to be nullable.
+  } else {
+    return null;
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49908.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue49908.dart.textual_outline.expect
new file mode 100644
index 0000000..06df806
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49908.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo<T, S>(bool b, T t, S s) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49908.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue49908.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..06df806
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49908.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo<T, S>(bool b, T t, S s) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49908.dart.weak.expect b/pkg/front_end/testcases/general/issue49908.dart.weak.expect
new file mode 100644
index 0000000..5f28614
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49908.dart.weak.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method foo<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(core::bool b, self::foo::T% t, self::foo::S% s) → dynamic {
+  if(t is{ForNonNullableByDefault} core::Object) {
+    return b ?{core::Object?} t{self::foo::T% & core::Object /* '%' & '!' = '!' */} : s;
+  }
+  else {
+    return null;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue49908.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue49908.dart.weak.modular.expect
new file mode 100644
index 0000000..5f28614
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49908.dart.weak.modular.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method foo<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(core::bool b, self::foo::T% t, self::foo::S% s) → dynamic {
+  if(t is{ForNonNullableByDefault} core::Object) {
+    return b ?{core::Object?} t{self::foo::T% & core::Object /* '%' & '!' = '!' */} : s;
+  }
+  else {
+    return null;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue49908.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue49908.dart.weak.outline.expect
new file mode 100644
index 0000000..cbbfc1e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49908.dart.weak.outline.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method foo<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(core::bool b, self::foo::T% t, self::foo::S% s) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue49908.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue49908.dart.weak.transformed.expect
new file mode 100644
index 0000000..5f28614
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49908.dart.weak.transformed.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method foo<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(core::bool b, self::foo::T% t, self::foo::S% s) → dynamic {
+  if(t is{ForNonNullableByDefault} core::Object) {
+    return b ?{core::Object?} t{self::foo::T% & core::Object /* '%' & '!' = '!' */} : s;
+  }
+  else {
+    return null;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue49985.dart b/pkg/front_end/testcases/general/issue49985.dart
new file mode 100644
index 0000000..cc2b5ef
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49985.dart
@@ -0,0 +1,13 @@
+typedef A<T> = C<T, int>;
+
+class B<X, Y> {
+  X x;
+
+  B(this.x);
+}
+
+mixin Mixin {}
+
+class C<X, Y> = B<X, Y> with Mixin;
+
+var field = A((a, b) => 42);
diff --git a/pkg/front_end/testcases/general/issue49985.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue49985.dart.textual_outline.expect
new file mode 100644
index 0000000..815e327
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49985.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+typedef A<T> = C<T, int>;
+
+class B<X, Y> {
+  X x;
+  B(this.x);
+}
+
+mixin Mixin {}
+class C<X, Y> = B<X, Y> with Mixin;
+var field = A((a, b) => 42);
diff --git a/pkg/front_end/testcases/general/issue49985.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue49985.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ea2ec01
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49985.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class B<X, Y> {
+  B(this.x);
+  X x;
+}
+
+class C<X, Y> = B<X, Y> with Mixin;
+mixin Mixin {}
+typedef A<T> = C<T, int>;
+var field = A((a, b) => 42);
diff --git a/pkg/front_end/testcases/general/issue49985.dart.weak.expect b/pkg/front_end/testcases/general/issue49985.dart.weak.expect
new file mode 100644
index 0000000..2d2bfe3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49985.dart.weak.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object? = dynamic> = self::C<T%, core::int>;
+class B<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object {
+  covariant-by-class field self::B::X% x;
+  constructor •(self::B::X% x) → self::B<self::B::X%, self::B::Y%>
+    : self::B::x = x, super core::Object::•()
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+}
+class C<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = self::B<self::C::X%, self::C::Y%> with self::Mixin {
+  synthetic constructor •(self::C::X% x) → self::C<self::C::X%, self::C::Y%>
+    : super self::B::•(x)
+    ;
+}
+static field self::C<(dynamic, dynamic) → core::int, core::int> field = new self::C::•<(dynamic, dynamic) → core::int, core::int>((dynamic a, dynamic b) → core::int => 42);
+static method _#A#new#tearOff<T extends core::Object? = dynamic>(self::_#A#new#tearOff::T% x) → self::C<self::_#A#new#tearOff::T%, core::int>
+  return new self::C::•<self::_#A#new#tearOff::T%, core::int>(x);
diff --git a/pkg/front_end/testcases/general/issue49985.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue49985.dart.weak.modular.expect
new file mode 100644
index 0000000..2d2bfe3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49985.dart.weak.modular.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object? = dynamic> = self::C<T%, core::int>;
+class B<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object {
+  covariant-by-class field self::B::X% x;
+  constructor •(self::B::X% x) → self::B<self::B::X%, self::B::Y%>
+    : self::B::x = x, super core::Object::•()
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+}
+class C<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = self::B<self::C::X%, self::C::Y%> with self::Mixin {
+  synthetic constructor •(self::C::X% x) → self::C<self::C::X%, self::C::Y%>
+    : super self::B::•(x)
+    ;
+}
+static field self::C<(dynamic, dynamic) → core::int, core::int> field = new self::C::•<(dynamic, dynamic) → core::int, core::int>((dynamic a, dynamic b) → core::int => 42);
+static method _#A#new#tearOff<T extends core::Object? = dynamic>(self::_#A#new#tearOff::T% x) → self::C<self::_#A#new#tearOff::T%, core::int>
+  return new self::C::•<self::_#A#new#tearOff::T%, core::int>(x);
diff --git a/pkg/front_end/testcases/general/issue49985.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue49985.dart.weak.outline.expect
new file mode 100644
index 0000000..29f9fe8
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49985.dart.weak.outline.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object? = dynamic> = self::C<T%, core::int>;
+class B<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object {
+  covariant-by-class field self::B::X% x;
+  constructor •(self::B::X% x) → self::B<self::B::X%, self::B::Y%>
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+}
+class C<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> = self::B<self::C::X%, self::C::Y%> with self::Mixin {
+  synthetic constructor •(self::C::X% x) → self::C<self::C::X%, self::C::Y%>
+    : super self::B::•(x)
+    ;
+}
+static field self::C<(dynamic, dynamic) → core::int, core::int> field;
+static method _#A#new#tearOff<T extends core::Object? = dynamic>(self::_#A#new#tearOff::T% x) → self::C<self::_#A#new#tearOff::T%, core::int>
+  return new self::C::•<self::_#A#new#tearOff::T%, core::int>(x);
diff --git a/pkg/front_end/testcases/general/issue49985.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue49985.dart.weak.transformed.expect
new file mode 100644
index 0000000..26eaf08
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49985.dart.weak.transformed.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object? = dynamic> = self::C<T%, core::int>;
+class B<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object {
+  covariant-by-class field self::B::X% x;
+  constructor •(self::B::X% x) → self::B<self::B::X%, self::B::Y%>
+    : self::B::x = x, super core::Object::•()
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+}
+class C<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends self::B<self::C::X%, self::C::Y%> implements self::Mixin /*isEliminatedMixin*/  {
+  synthetic constructor •(self::C::X% x) → self::C<self::C::X%, self::C::Y%>
+    : super self::B::•(x)
+    ;
+}
+static field self::C<(dynamic, dynamic) → core::int, core::int> field = new self::C::•<(dynamic, dynamic) → core::int, core::int>((dynamic a, dynamic b) → core::int => 42);
+static method _#A#new#tearOff<T extends core::Object? = dynamic>(self::_#A#new#tearOff::T% x) → self::C<self::_#A#new#tearOff::T%, core::int>
+  return new self::C::•<self::_#A#new#tearOff::T%, core::int>(x);
diff --git a/pkg/front_end/testcases/general/issue_46886.dart.weak.expect b/pkg/front_end/testcases/general/issue_46886.dart.weak.expect
index e64cce5..79ee147 100644
--- a/pkg/front_end/testcases/general/issue_46886.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue_46886.dart.weak.expect
@@ -52,7 +52,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on core::Symbol {
+extension /* unnamed */ _extension#0 on core::Symbol {
   operator > = self::_extension#0|>;
   method call = self::_extension#0|call;
   tearoff call = self::_extension#0|get#call;
diff --git a/pkg/front_end/testcases/general/issue_46886.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue_46886.dart.weak.modular.expect
index e64cce5..79ee147 100644
--- a/pkg/front_end/testcases/general/issue_46886.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/issue_46886.dart.weak.modular.expect
@@ -52,7 +52,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on core::Symbol {
+extension /* unnamed */ _extension#0 on core::Symbol {
   operator > = self::_extension#0|>;
   method call = self::_extension#0|call;
   tearoff call = self::_extension#0|get#call;
diff --git a/pkg/front_end/testcases/general/issue_46886.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue_46886.dart.weak.outline.expect
index 73a7e48..0f34aaf 100644
--- a/pkg/front_end/testcases/general/issue_46886.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/issue_46886.dart.weak.outline.expect
@@ -20,7 +20,7 @@
   synthetic constructor •() → self::Bar
     ;
 }
-extension _extension#0 on core::Symbol {
+extension /* unnamed */ _extension#0 on core::Symbol {
   operator > = self::_extension#0|>;
   method call = self::_extension#0|call;
   tearoff call = self::_extension#0|get#call;
diff --git a/pkg/front_end/testcases/general/issue_46886.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue_46886.dart.weak.transformed.expect
index ab49a67..a18c385 100644
--- a/pkg/front_end/testcases/general/issue_46886.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue_46886.dart.weak.transformed.expect
@@ -52,7 +52,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on core::Symbol {
+extension /* unnamed */ _extension#0 on core::Symbol {
   operator > = self::_extension#0|>;
   method call = self::_extension#0|call;
   tearoff call = self::_extension#0|get#call;
diff --git a/pkg/front_end/testcases/general/issue_47541.dart b/pkg/front_end/testcases/general/issue_47541.dart
index 23b18a7..dc35efa 100644
--- a/pkg/front_end/testcases/general/issue_47541.dart
+++ b/pkg/front_end/testcases/general/issue_47541.dart
@@ -14,7 +14,14 @@
     ;
   }
 
-  on();
+  // With records this is no longer a call after a try block, but a on clause
+  // where the type is the empty record.
+  on () {
+    ;
+  }
+
+  // This is a call though.
+  on(42);
 }
 
 void b() {
@@ -54,6 +61,6 @@
   on.toString();
 }
 
-void on() {}
+void on(e) {}
 
 class Foo {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/issue_47541.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue_47541.dart.textual_outline.expect
index ef29dd0..13455d1 100644
--- a/pkg/front_end/testcases/general/issue_47541.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/general/issue_47541.dart.textual_outline.expect
@@ -3,6 +3,6 @@
 void b() {}
 void c(int on) {}
 void d(int on) {}
-void on() {}
+void on(e) {}
 
 class Foo {}
diff --git a/pkg/front_end/testcases/general/issue_47541.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue_47541.dart.textual_outline_modelled.expect
index 1dc83da..1d6f1f5f 100644
--- a/pkg/front_end/testcases/general/issue_47541.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/general/issue_47541.dart.textual_outline_modelled.expect
@@ -5,4 +5,4 @@
 void c(int on) {}
 void d(int on) {}
 void main() {}
-void on() {}
+void on(e) {}
diff --git a/pkg/front_end/testcases/general/issue_47541.dart.weak.expect b/pkg/front_end/testcases/general/issue_47541.dart.weak.expect
index f57dd6f..6285340 100644
--- a/pkg/front_end/testcases/general/issue_47541.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue_47541.dart.weak.expect
@@ -23,7 +23,10 @@
   on self::Foo catch(no-exception-var) {
     ;
   }
-  self::on();
+  on() catch(no-exception-var) {
+    ;
+  }
+  self::on(42);
 }
 static method b() → void {
   try {
@@ -64,4 +67,4 @@
   }
   on.{core::int::toString}(){() → core::String};
 }
-static method on() → void {}
+static method on(dynamic e) → void {}
diff --git a/pkg/front_end/testcases/general/issue_47541.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue_47541.dart.weak.modular.expect
index f57dd6f..6285340 100644
--- a/pkg/front_end/testcases/general/issue_47541.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/issue_47541.dart.weak.modular.expect
@@ -23,7 +23,10 @@
   on self::Foo catch(no-exception-var) {
     ;
   }
-  self::on();
+  on() catch(no-exception-var) {
+    ;
+  }
+  self::on(42);
 }
 static method b() → void {
   try {
@@ -64,4 +67,4 @@
   }
   on.{core::int::toString}(){() → core::String};
 }
-static method on() → void {}
+static method on(dynamic e) → void {}
diff --git a/pkg/front_end/testcases/general/issue_47541.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue_47541.dart.weak.outline.expect
index 8eaa23a..a872055 100644
--- a/pkg/front_end/testcases/general/issue_47541.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/issue_47541.dart.weak.outline.expect
@@ -16,5 +16,5 @@
   ;
 static method d(core::int on) → void
   ;
-static method on() → void
+static method on(dynamic e) → void
   ;
diff --git a/pkg/front_end/testcases/general/issue_47541.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue_47541.dart.weak.transformed.expect
index f57dd6f..6285340 100644
--- a/pkg/front_end/testcases/general/issue_47541.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue_47541.dart.weak.transformed.expect
@@ -23,7 +23,10 @@
   on self::Foo catch(no-exception-var) {
     ;
   }
-  self::on();
+  on() catch(no-exception-var) {
+    ;
+  }
+  self::on(42);
 }
 static method b() → void {
   try {
@@ -64,4 +67,4 @@
   }
   on.{core::int::toString}(){() → core::String};
 }
-static method on() → void {}
+static method on(dynamic e) → void {}
diff --git a/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.expect b/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.expect
index 05b2295..1e7f693 100644
--- a/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.expect
+++ b/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.expect
@@ -12,13 +12,6 @@
 }
 
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/general/mixin_from_patch/origin_lib.dart:14:12: Error: The superclass, 'Class with Mixin', has no unnamed constructor that takes no arguments.
-//   external SubClass.patched();
-//            ^^^^^^^
-//
 import self as test;
 import "dart:_internal" as _in;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.modular.expect b/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.modular.expect
index 05b2295..1e7f693 100644
--- a/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.modular.expect
@@ -12,13 +12,6 @@
 }
 
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/general/mixin_from_patch/origin_lib.dart:14:12: Error: The superclass, 'Class with Mixin', has no unnamed constructor that takes no arguments.
-//   external SubClass.patched();
-//            ^^^^^^^
-//
 import self as test;
 import "dart:_internal" as _in;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.transformed.expect b/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.transformed.expect
index a940761..e3cd7b0 100644
--- a/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.transformed.expect
@@ -12,13 +12,6 @@
 }
 
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/general/mixin_from_patch/origin_lib.dart:14:12: Error: The superclass, 'Class with Mixin', has no unnamed constructor that takes no arguments.
-//   external SubClass.patched();
-//            ^^^^^^^
-//
 import self as test;
 import "dart:_internal" as _in;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/libraries.json b/pkg/front_end/testcases/general/multiple_class_patches/libraries.json
new file mode 100644
index 0000000..8621f1d
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/libraries.json
@@ -0,0 +1,13 @@
+{
+  "none": {
+    "libraries": {
+      "test": {
+        "patches": [
+          "patch_lib1.dart",
+          "patch_lib2.dart"
+        ],
+        "uri": "origin_lib.dart"
+      }
+    }
+  }
+}
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/main.dart b/pkg/front_end/testcases/general/multiple_class_patches/main.dart
new file mode 100644
index 0000000..bfca532
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/main.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2022, 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:test';
+
+main() {
+  Class c = new Class();
+  expect(42, c.method1());
+  expect(87, c.method2());
+  expect(123, c.method3());
+}
+
+expect(expected, actual) {
+  if (expected != actual) {
+    throw 'Expected $expected, actual $actual';
+  }
+}
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.textual_outline.expect
new file mode 100644
index 0000000..a6150ab2
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:test';
+
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e14d79b
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'dart:test';
+
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.expect b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.expect
new file mode 100644
index 0000000..0f8a5da
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.expect
@@ -0,0 +1,66 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:test" as test;
+import "dart:core" as core;
+
+import "dart:test";
+
+static method main() → dynamic {
+  test::Class c = new test::Class::•();
+  self::expect(42, c.{test::Class::method1}(){() → core::int});
+  self::expect(87, c.{test::Class::method2}(){() → core::int});
+  self::expect(123, c.{test::Class::method3}(){() → core::int});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/multiple_class_patches/patch_lib2.dart:9:7: Error: 'Class' is already declared in this scope.
+// class Class {
+//       ^^^^^
+// pkg/front_end/testcases/general/multiple_class_patches/patch_lib1.dart:9:7: Context: Previous declaration of 'Class'.
+// class Class {
+//       ^^^^^
+//
+import self as test;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+import "dart:_internal";
+
+@#C1
+class Class#1#1 extends core::Object { // from org-dartlang-testcase:///patch_lib2.dart
+  synthetic constructor •() → test::Class#1#1
+    : super core::Object::•()
+    ;
+  @#C1
+  method method2() → core::int
+    return 87;
+  @#C1
+  method method3() → core::int
+    return 123;
+}
+@#C1
+class Class extends core::Object {
+  synthetic constructor •() → test::Class
+    : super core::Object::•()
+    ;
+  @#C1
+  method /* from org-dartlang-testcase:///patch_lib1.dart */ method1() → core::int
+    return 42;
+  external method method2() → core::int;
+  @#C1
+  method /* from org-dartlang-testcase:///patch_lib1.dart */ method3() → core::int
+    return 321;
+}
+
+constants  {
+  #C1 = _in::_Patch {}
+}
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.modular.expect b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.modular.expect
new file mode 100644
index 0000000..0f8a5da
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.modular.expect
@@ -0,0 +1,66 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:test" as test;
+import "dart:core" as core;
+
+import "dart:test";
+
+static method main() → dynamic {
+  test::Class c = new test::Class::•();
+  self::expect(42, c.{test::Class::method1}(){() → core::int});
+  self::expect(87, c.{test::Class::method2}(){() → core::int});
+  self::expect(123, c.{test::Class::method3}(){() → core::int});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/multiple_class_patches/patch_lib2.dart:9:7: Error: 'Class' is already declared in this scope.
+// class Class {
+//       ^^^^^
+// pkg/front_end/testcases/general/multiple_class_patches/patch_lib1.dart:9:7: Context: Previous declaration of 'Class'.
+// class Class {
+//       ^^^^^
+//
+import self as test;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+import "dart:_internal";
+
+@#C1
+class Class#1#1 extends core::Object { // from org-dartlang-testcase:///patch_lib2.dart
+  synthetic constructor •() → test::Class#1#1
+    : super core::Object::•()
+    ;
+  @#C1
+  method method2() → core::int
+    return 87;
+  @#C1
+  method method3() → core::int
+    return 123;
+}
+@#C1
+class Class extends core::Object {
+  synthetic constructor •() → test::Class
+    : super core::Object::•()
+    ;
+  @#C1
+  method /* from org-dartlang-testcase:///patch_lib1.dart */ method1() → core::int
+    return 42;
+  external method method2() → core::int;
+  @#C1
+  method /* from org-dartlang-testcase:///patch_lib1.dart */ method3() → core::int
+    return 321;
+}
+
+constants  {
+  #C1 = _in::_Patch {}
+}
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.outline.expect b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.outline.expect
new file mode 100644
index 0000000..769015a
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.outline.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "dart:test";
+
+static method main() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/multiple_class_patches/patch_lib2.dart:9:7: Error: 'Class' is already declared in this scope.
+// class Class {
+//       ^^^^^
+// pkg/front_end/testcases/general/multiple_class_patches/patch_lib1.dart:9:7: Context: Previous declaration of 'Class'.
+// class Class {
+//       ^^^^^
+//
+import self as self2;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+import "dart:_internal";
+
+@_in::patch
+class Class#1#1 extends core::Object { // from org-dartlang-testcase:///patch_lib2.dart
+  synthetic constructor •() → self2::Class#1#1
+    ;
+  @_in::patch
+  method method2() → core::int
+    ;
+  @_in::patch
+  method method3() → core::int
+    ;
+}
+@_in::patch
+class Class extends core::Object {
+  synthetic constructor •() → self2::Class
+    ;
+  @_in::patch
+  external method method1() → core::int;
+  external method method2() → core::int;
+  @_in::patch
+  external method method3() → core::int;
+}
+
+
+Extra constant evaluation status:
+Evaluated: StaticGet @ org-dartlang-testcase:///patch_lib2.dart:8:2 -> InstanceConstant(const _Patch{})
+Evaluated: StaticGet @ org-dartlang-testcase:///patch_lib2.dart:10:4 -> InstanceConstant(const _Patch{})
+Evaluated: StaticGet @ org-dartlang-testcase:///patch_lib2.dart:13:4 -> InstanceConstant(const _Patch{})
+Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:7:23 -> InstanceConstant(const _Patch{})
+Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:8:20 -> InstanceConstant(const _Patch{})
+Evaluated: StaticGet @ (unknown position in org-dartlang-testcase:///origin_lib.dart) -> InstanceConstant(const _Patch{})
+Extra constant evaluation: evaluated: 6, effectively constant: 6
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.transformed.expect b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..0f8a5da
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/main.dart.weak.transformed.expect
@@ -0,0 +1,66 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:test" as test;
+import "dart:core" as core;
+
+import "dart:test";
+
+static method main() → dynamic {
+  test::Class c = new test::Class::•();
+  self::expect(42, c.{test::Class::method1}(){() → core::int});
+  self::expect(87, c.{test::Class::method2}(){() → core::int});
+  self::expect(123, c.{test::Class::method3}(){() → core::int});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/multiple_class_patches/patch_lib2.dart:9:7: Error: 'Class' is already declared in this scope.
+// class Class {
+//       ^^^^^
+// pkg/front_end/testcases/general/multiple_class_patches/patch_lib1.dart:9:7: Context: Previous declaration of 'Class'.
+// class Class {
+//       ^^^^^
+//
+import self as test;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+import "dart:_internal";
+
+@#C1
+class Class#1#1 extends core::Object { // from org-dartlang-testcase:///patch_lib2.dart
+  synthetic constructor •() → test::Class#1#1
+    : super core::Object::•()
+    ;
+  @#C1
+  method method2() → core::int
+    return 87;
+  @#C1
+  method method3() → core::int
+    return 123;
+}
+@#C1
+class Class extends core::Object {
+  synthetic constructor •() → test::Class
+    : super core::Object::•()
+    ;
+  @#C1
+  method /* from org-dartlang-testcase:///patch_lib1.dart */ method1() → core::int
+    return 42;
+  external method method2() → core::int;
+  @#C1
+  method /* from org-dartlang-testcase:///patch_lib1.dart */ method3() → core::int
+    return 321;
+}
+
+constants  {
+  #C1 = _in::_Patch {}
+}
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/origin_lib.dart b/pkg/front_end/testcases/general/multiple_class_patches/origin_lib.dart
new file mode 100644
index 0000000..cccced9
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/origin_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, 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.
+
+class Class {
+  external int method1();
+  external int method2();
+  external int method3();
+}
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/patch_lib1.dart b/pkg/front_end/testcases/general/multiple_class_patches/patch_lib1.dart
new file mode 100644
index 0000000..1220b53
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/patch_lib1.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// ignore: import_internal_library
+import 'dart:_internal';
+
+@patch
+class Class {
+  @patch
+  int method1() => 42;
+
+  @patch
+  int method3() => 321;
+}
diff --git a/pkg/front_end/testcases/general/multiple_class_patches/patch_lib2.dart b/pkg/front_end/testcases/general/multiple_class_patches/patch_lib2.dart
new file mode 100644
index 0000000..645e96a
--- /dev/null
+++ b/pkg/front_end/testcases/general/multiple_class_patches/patch_lib2.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// ignore: import_internal_library
+import 'dart:_internal';
+
+@patch
+class Class {
+  @patch
+  int method2() => 87;
+
+  @patch
+  int method3() => 123;
+}
diff --git a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.outline.expect b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.outline.expect
index d466ed3..e0ddf11 100644
--- a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.outline.expect
@@ -25,12 +25,12 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:6:8 -> SymbolConstant(#_foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:6:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:6:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:6:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:11:8 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:11:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:11:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:11:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:14:7 -> SymbolConstant(#_foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:14:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:14:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:14:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:14:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:14:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:14:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method_forwarder.dart:14:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 16, effectively constant: 8
diff --git a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.expect b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.expect
index ad96a5d..ea8a751 100644
--- a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.expect
+++ b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.expect
@@ -9,10 +9,10 @@
   synthetic constructor •() → self::Foo
     : super core::Object::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///no_such_method_private_setter_lib.dart */ _x() → core::int
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///no_such_method_private_setter_lib.dart */ _x(core::int value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _x() → core::int
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _x(core::int value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {
   no_::baz(new self::Foo::•());
diff --git a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.modular.expect b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.modular.expect
index ad96a5d..ea8a751 100644
--- a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.modular.expect
@@ -9,10 +9,10 @@
   synthetic constructor •() → self::Foo
     : super core::Object::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///no_such_method_private_setter_lib.dart */ _x() → core::int
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///no_such_method_private_setter_lib.dart */ _x(core::int value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _x() → core::int
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _x(core::int value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {
   no_::baz(new self::Foo::•());
diff --git a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.outline.expect b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.outline.expect
index 9750dcc..ed6c2c9 100644
--- a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.outline.expect
@@ -8,10 +8,10 @@
 class Foo extends core::Object implements no_::Bar {
   synthetic constructor •() → self::Foo
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///no_such_method_private_setter_lib.dart */ _x() → core::int
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_x, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///no_such_method_private_setter_lib.dart */ _x(core::int value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_x=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _x() → core::int
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_x, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
+  no-such-method-forwarder set _x(core::int value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_x=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 static method main() → dynamic
   ;
@@ -30,11 +30,11 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method_private_setter_lib.dart:8:7 -> SymbolConstant(#_x)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_private_setter_lib.dart:8:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_private_setter_lib.dart:8:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method_private_setter_lib.dart:8:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method_private_setter_lib.dart:8:7 -> SymbolConstant(#_x=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_private_setter_lib.dart:8:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method_private_setter_lib.dart:8:7 -> MapConstant(const <Symbol*, dynamic>{})
-Extra constant evaluation: evaluated: 19, effectively constant: 7
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method_private_setter.dart:10:7 -> SymbolConstant(#_x)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_private_setter.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_private_setter.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method_private_setter.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method_private_setter.dart:10:7 -> SymbolConstant(#_x=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method_private_setter.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method_private_setter.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Extra constant evaluation: evaluated: 20, effectively constant: 7
diff --git a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.transformed.expect b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.transformed.expect
index 48b88df..5217704 100644
--- a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.weak.transformed.expect
@@ -9,10 +9,10 @@
   synthetic constructor •() → self::Foo
     : super core::Object::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///no_such_method_private_setter_lib.dart */ _x() → core::int
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///no_such_method_private_setter_lib.dart */ _x(core::int value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _x() → core::int
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _x(core::int value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {
   no_::baz(new self::Foo::•());
diff --git a/pkg/front_end/testcases/general/nsm_covariance.dart.weak.expect b/pkg/front_end/testcases/general/nsm_covariance.dart.weak.expect
index 5fc1606..6b2e6a2 100644
--- a/pkg/front_end/testcases/general/nsm_covariance.dart.weak.expect
+++ b/pkg/front_end/testcases/general/nsm_covariance.dart.weak.expect
@@ -31,13 +31,13 @@
   method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   no-such-method-forwarder method _method1(core::int a, covariant-by-declaration core::int b, covariant-by-class core::int c, covariant-by-declaration covariant-by-class core::int d) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[a, b, c, d]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[a, b, c, d]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method2({core::int a = #C1, covariant-by-declaration core::int b = #C1, covariant-by-class core::int c = #C1, covariant-by-declaration covariant-by-class core::int d = #C1}) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d})));
   no-such-method-forwarder method _method3(covariant-by-declaration core::int a, covariant-by-class core::int b) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[a, b]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[a, b]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method4({covariant-by-declaration core::int a = #C1, covariant-by-class core::int b = #C1}) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b})));
 }
 class D4 extends core::Object implements nsm::B, nsm::A<core::int> {
   synthetic constructor •() → self::D4
@@ -47,13 +47,13 @@
   method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   no-such-method-forwarder method _method1(core::int x, covariant-by-declaration core::int y, covariant-by-class core::int z, covariant-by-declaration covariant-by-class core::int w) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[x, y, z, w]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[x, y, z, w]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method2({core::int a = #C1, covariant-by-declaration core::int b = #C1, covariant-by-class core::int c = #C1, covariant-by-declaration covariant-by-class core::int d = #C1}) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d})));
   no-such-method-forwarder method _method3(covariant-by-declaration core::int x, covariant-by-class core::int y) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[x, y]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[x, y]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method4({covariant-by-declaration core::int a = #C1, covariant-by-class core::int b = #C1}) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b})));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/general/nsm_covariance.dart.weak.modular.expect b/pkg/front_end/testcases/general/nsm_covariance.dart.weak.modular.expect
index 5fc1606..6b2e6a2 100644
--- a/pkg/front_end/testcases/general/nsm_covariance.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/nsm_covariance.dart.weak.modular.expect
@@ -31,13 +31,13 @@
   method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   no-such-method-forwarder method _method1(core::int a, covariant-by-declaration core::int b, covariant-by-class core::int c, covariant-by-declaration covariant-by-class core::int d) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[a, b, c, d]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[a, b, c, d]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method2({core::int a = #C1, covariant-by-declaration core::int b = #C1, covariant-by-class core::int c = #C1, covariant-by-declaration covariant-by-class core::int d = #C1}) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d})));
   no-such-method-forwarder method _method3(covariant-by-declaration core::int a, covariant-by-class core::int b) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[a, b]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[a, b]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method4({covariant-by-declaration core::int a = #C1, covariant-by-class core::int b = #C1}) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b})));
 }
 class D4 extends core::Object implements nsm::B, nsm::A<core::int> {
   synthetic constructor •() → self::D4
@@ -47,13 +47,13 @@
   method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   no-such-method-forwarder method _method1(core::int x, covariant-by-declaration core::int y, covariant-by-class core::int z, covariant-by-declaration covariant-by-class core::int w) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[x, y, z, w]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[x, y, z, w]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method2({core::int a = #C1, covariant-by-declaration core::int b = #C1, covariant-by-class core::int c = #C1, covariant-by-declaration covariant-by-class core::int d = #C1}) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d})));
   no-such-method-forwarder method _method3(covariant-by-declaration core::int x, covariant-by-class core::int y) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[x, y]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(<dynamic>[x, y]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method4({covariant-by-declaration core::int a = #C1, covariant-by-class core::int b = #C1}) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b})));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/general/nsm_covariance.dart.weak.outline.expect b/pkg/front_end/testcases/general/nsm_covariance.dart.weak.outline.expect
index 6a88f7b..e591801 100644
--- a/pkg/front_end/testcases/general/nsm_covariance.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/nsm_covariance.dart.weak.outline.expect
@@ -28,13 +28,13 @@
   method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   no-such-method-forwarder method _method1(core::int a, covariant-by-declaration core::int b, covariant-by-class core::int c, covariant-by-declaration covariant-by-class core::int d) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#_method1, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[a, b, c, d]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_method1, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[a, b, c, d]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
   no-such-method-forwarder method _method2({core::int a, covariant-by-declaration core::int b, covariant-by-class core::int c, covariant-by-declaration covariant-by-class core::int d}) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#_method2, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#a: a, #b: b, #c: c, #d: d}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_method2, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#a: a, #b: b, #c: c, #d: d})));
   no-such-method-forwarder method _method3(covariant-by-declaration core::int a, covariant-by-class core::int b) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#_method3, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[a, b]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_method3, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[a, b]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
   no-such-method-forwarder method _method4({covariant-by-declaration core::int a, covariant-by-class core::int b}) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#_method4, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#a: a, #b: b}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_method4, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#a: a, #b: b})));
 }
 class D4 extends core::Object implements nsm::B, nsm::A<core::int> {
   synthetic constructor •() → self::D4
@@ -43,13 +43,13 @@
   method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   no-such-method-forwarder method _method1(core::int x, covariant-by-declaration core::int y, covariant-by-class core::int z, covariant-by-declaration covariant-by-class core::int w) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#_method1, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[x, y, z, w]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_method1, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[x, y, z, w]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
   no-such-method-forwarder method _method2({core::int a, covariant-by-declaration core::int b, covariant-by-class core::int c, covariant-by-declaration covariant-by-class core::int d}) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#_method2, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#a: a, #b: b, #c: c, #d: d}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_method2, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#a: a, #b: b, #c: c, #d: d})));
   no-such-method-forwarder method _method3(covariant-by-declaration core::int x, covariant-by-class core::int y) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#_method3, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[x, y]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_method3, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[x, y]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
   no-such-method-forwarder method _method4({covariant-by-declaration core::int a, covariant-by-class core::int b}) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#_method4, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#a: a, #b: b}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_method4, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#a: a, #b: b})));
 }
 static method main() → dynamic
   ;
@@ -199,4 +199,4 @@
 Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance_lib.dart:28:7 -> ListConstant(const <dynamic>[])
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance_lib.dart:28:7 -> SymbolConstant(#a)
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance_lib.dart:28:7 -> SymbolConstant(#b)
-Extra constant evaluation: evaluated: 212, effectively constant: 76
+Extra constant evaluation: evaluated: 220, effectively constant: 76
diff --git a/pkg/front_end/testcases/general/nsm_covariance.dart.weak.transformed.expect b/pkg/front_end/testcases/general/nsm_covariance.dart.weak.transformed.expect
index 7e269dc..4e195da 100644
--- a/pkg/front_end/testcases/general/nsm_covariance.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/nsm_covariance.dart.weak.transformed.expect
@@ -31,13 +31,13 @@
   method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   no-such-method-forwarder method _method1(core::int a, covariant-by-declaration core::int b, covariant-by-class core::int c, covariant-by-declaration covariant-by-class core::int d) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal4<dynamic>(a, b, c, d)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal4<dynamic>(a, b, c, d)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method2({core::int a = #C1, covariant-by-declaration core::int b = #C1, covariant-by-class core::int c = #C1, covariant-by-declaration covariant-by-class core::int d = #C1}) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d})));
   no-such-method-forwarder method _method3(covariant-by-declaration core::int a, covariant-by-class core::int b) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal2<dynamic>(a, b)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal2<dynamic>(a, b)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method4({covariant-by-declaration core::int a = #C1, covariant-by-class core::int b = #C1}) → void
-    return this.{self::D3::noSuchMethod}(new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b})));
 }
 class D4 extends core::Object implements nsm::B, nsm::A<core::int> {
   synthetic constructor •() → self::D4
@@ -47,13 +47,13 @@
   method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   no-such-method-forwarder method _method1(core::int x, covariant-by-declaration core::int y, covariant-by-class core::int z, covariant-by-declaration covariant-by-class core::int w) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal4<dynamic>(x, y, z, w)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C3, 0, #C4, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal4<dynamic>(x, y, z, w)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method2({core::int a = #C1, covariant-by-declaration core::int b = #C1, covariant-by-class core::int c = #C1, covariant-by-declaration covariant-by-class core::int d = #C1}) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b, #C10: c, #C11: d})));
   no-such-method-forwarder method _method3(covariant-by-declaration core::int x, covariant-by-class core::int y) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal2<dynamic>(x, y)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C12, 0, #C4, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal2<dynamic>(x, y)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
   no-such-method-forwarder method _method4({covariant-by-declaration core::int a = #C1, covariant-by-class core::int b = #C1}) → void
-    return this.{self::D4::noSuchMethod}(new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b}))){(core::Invocation) → dynamic};
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C13, 0, #C4, #C7, core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: a, #C9: b})));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/general/null_aware_spread.dart.weak.transformed.expect b/pkg/front_end/testcases/general/null_aware_spread.dart.weak.transformed.expect
index 35da272..0c398d4 100644
--- a/pkg/front_end/testcases/general/null_aware_spread.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/null_aware_spread.dart.weak.transformed.expect
@@ -13,7 +13,7 @@
 }
 static method nullAwareSetSpread(core::Set<core::String*>* set) → dynamic {
   set = block {
-    final core::Set<core::String*>* #t3 = new col::_CompactLinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t3 = new col::_InternalLinkedHashSet::•<core::String*>();
     #t3.{core::Set::add}{Invariant}("foo"){(core::String*) →* core::bool*};
     final core::Iterable<core::String*>* #t4 = set;
     if(!(#t4 == null))
diff --git a/pkg/front_end/testcases/general/null_aware_spread2.dart.weak.transformed.expect b/pkg/front_end/testcases/general/null_aware_spread2.dart.weak.transformed.expect
index 7d2fd80..9f28c26 100644
--- a/pkg/front_end/testcases/general/null_aware_spread2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/null_aware_spread2.dart.weak.transformed.expect
@@ -13,7 +13,7 @@
 }
 static method nullAwareSetSpread(core::Set<core::String>? set) → dynamic {
   set = block {
-    final core::Set<core::String> #t3 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Set<core::String> #t3 = new col::_InternalLinkedHashSet::•<core::String>();
     #t3.{core::Set::add}{Invariant}("foo"){(core::String) → core::bool};
     final core::Iterable<core::String>? #t4 = set;
     if(!(#t4 == null))
diff --git a/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.transformed.expect b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.transformed.expect
index 3580a9b..9fb8711 100644
--- a/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.transformed.expect
@@ -16,7 +16,7 @@
   method setElement(covariant-by-class self::Class::E? element) → void {
     if(!(this.{self::Class::element}{self::Class::E?} =={core::Object::==}{(core::Object) → core::bool} element)) {
       this.{self::Class::element} = element;
-      core::Set<self::Element> elements = new col::_CompactLinkedHashSet::•<self::Element>();
+      core::Set<self::Element> elements = new col::_InternalLinkedHashSet::•<self::Element>();
       if(!(element == null)) {
         elements.{core::Set::add}(element{self::Class::E% & self::Element /* '%' & '!' = '!' */}){(self::Element) → core::bool};
       }
diff --git a/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.expect b/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.expect
index 74f9325..4912b54 100644
--- a/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.expect
+++ b/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.expect
@@ -9,8 +9,8 @@
   synthetic constructor •() → self::Foo
     : super core::Object::•()
     ;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_method_tearoff_lib.dart */ _f() → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder method _f() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class Baz extends self::Foo {
   synthetic constructor •() → self::Baz
diff --git a/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.modular.expect b/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.modular.expect
index 74f9325..4912b54 100644
--- a/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.modular.expect
@@ -9,8 +9,8 @@
   synthetic constructor •() → self::Foo
     : super core::Object::•()
     ;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_method_tearoff_lib.dart */ _f() → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder method _f() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class Baz extends self::Foo {
   synthetic constructor •() → self::Baz
diff --git a/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.outline.expect b/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.outline.expect
index a8acd44..d69d880 100644
--- a/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.outline.expect
@@ -8,8 +8,8 @@
 class Foo extends core::Object implements pri::Bar {
   synthetic constructor •() → self::Foo
     ;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_method_tearoff_lib.dart */ _f() → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_f, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic};
+  no-such-method-forwarder method _f() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_f, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 class Baz extends self::Foo {
   synthetic constructor •() → self::Baz
@@ -33,8 +33,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///private_method_tearoff_lib.dart:8:8 -> SymbolConstant(#_f)
-Evaluated: ListLiteral @ org-dartlang-testcase:///private_method_tearoff_lib.dart:8:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///private_method_tearoff_lib.dart:8:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///private_method_tearoff_lib.dart:8:8 -> MapConstant(const <Symbol*, dynamic>{})
-Extra constant evaluation: evaluated: 8, effectively constant: 4
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///private_method_tearoff.dart:11:7 -> SymbolConstant(#_f)
+Evaluated: ListLiteral @ org-dartlang-testcase:///private_method_tearoff.dart:11:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///private_method_tearoff.dart:11:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///private_method_tearoff.dart:11:7 -> MapConstant(const <Symbol*, dynamic>{})
+Extra constant evaluation: evaluated: 9, effectively constant: 4
diff --git a/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.transformed.expect b/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.transformed.expect
index 74f9325..4912b54 100644
--- a/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/private_method_tearoff.dart.weak.transformed.expect
@@ -9,8 +9,8 @@
   synthetic constructor •() → self::Foo
     : super core::Object::•()
     ;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_method_tearoff_lib.dart */ _f() → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder method _f() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class Baz extends self::Foo {
   synthetic constructor •() → self::Baz
diff --git a/pkg/front_end/testcases/general/records.dart b/pkg/front_end/testcases/general/records.dart
new file mode 100644
index 0000000..a1815eb
--- /dev/null
+++ b/pkg/front_end/testcases/general/records.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2022, 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.
+
+(int, String) method1(int a, String b) => (a, b);
+int method2([(int, String) record = const (0, '')]) => record.$0;
+String method3([(int, String) record = const (0, '')]) => record.$1;
+({int a, String b}) method4(int a, String b) => (a: a, b: b);
+int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
diff --git a/pkg/front_end/testcases/general/records.dart.textual_outline.expect b/pkg/front_end/testcases/general/records.dart.textual_outline.expect
new file mode 100644
index 0000000..c2069db
--- /dev/null
+++ b/pkg/front_end/testcases/general/records.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+(int, String) method1(int a, String b) => (a, b);
+int method2([(int, String) record = const (0, '')]) => record.$0;
+String method3([(int, String) record = const (0, '')]) => record.$1;
+({int a, String b}) method4(int a, String b) => (a: a, b: b);
+int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
diff --git a/pkg/front_end/testcases/general/records.dart.weak.expect b/pkg/front_end/testcases/general/records.dart.weak.expect
new file mode 100644
index 0000000..e6f9d48
--- /dev/null
+++ b/pkg/front_end/testcases/general/records.dart.weak.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method method1(core::int a, core::String b) → (core::int, core::String)
+  return (a, b);
+static method method2([(core::int, core::String) record = #C3]) → core::int
+  return record.$0{core::int};
+static method method3([(core::int, core::String) record = #C3]) → core::String
+  return record.$1{core::String};
+static method method4(core::int a, core::String b) → ({required a: core::int, required b: core::String})
+  return ({a: a, b: b});
+static method method5([({required a: core::int, required b: core::String}) record = #C4]) → core::int
+  return record.a{core::int};
+static method method6([({required a: core::int, required b: core::String}) record = #C4]) → core::String
+  return record.b{core::String};
+
+constants  {
+  #C1 = 0
+  #C2 = ""
+const (#C1, #C2)
+const ({a:#C1, b:#C2})
+}
diff --git a/pkg/front_end/testcases/general/records.dart.weak.modular.expect b/pkg/front_end/testcases/general/records.dart.weak.modular.expect
new file mode 100644
index 0000000..e6f9d48
--- /dev/null
+++ b/pkg/front_end/testcases/general/records.dart.weak.modular.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method method1(core::int a, core::String b) → (core::int, core::String)
+  return (a, b);
+static method method2([(core::int, core::String) record = #C3]) → core::int
+  return record.$0{core::int};
+static method method3([(core::int, core::String) record = #C3]) → core::String
+  return record.$1{core::String};
+static method method4(core::int a, core::String b) → ({required a: core::int, required b: core::String})
+  return ({a: a, b: b});
+static method method5([({required a: core::int, required b: core::String}) record = #C4]) → core::int
+  return record.a{core::int};
+static method method6([({required a: core::int, required b: core::String}) record = #C4]) → core::String
+  return record.b{core::String};
+
+constants  {
+  #C1 = 0
+  #C2 = ""
+const (#C1, #C2)
+const ({a:#C1, b:#C2})
+}
diff --git a/pkg/front_end/testcases/general/records.dart.weak.outline.expect b/pkg/front_end/testcases/general/records.dart.weak.outline.expect
new file mode 100644
index 0000000..1e2bf5c
--- /dev/null
+++ b/pkg/front_end/testcases/general/records.dart.weak.outline.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method method1(core::int a, core::String b) → (core::int, core::String)
+  ;
+static method method2([has-declared-initializer(core::int, core::String) record]) → core::int
+  ;
+static method method3([has-declared-initializer(core::int, core::String) record]) → core::String
+  ;
+static method method4(core::int a, core::String b) → ({required a: core::int, required b: core::String})
+  ;
+static method method5([has-declared-initializer({required a: core::int, required b: core::String}) record]) → core::int
+  ;
+static method method6([has-declared-initializer({required a: core::int, required b: core::String}) record]) → core::String
+  ;
diff --git a/pkg/front_end/testcases/general/records.dart.weak.transformed.expect b/pkg/front_end/testcases/general/records.dart.weak.transformed.expect
new file mode 100644
index 0000000..e6f9d48
--- /dev/null
+++ b/pkg/front_end/testcases/general/records.dart.weak.transformed.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method method1(core::int a, core::String b) → (core::int, core::String)
+  return (a, b);
+static method method2([(core::int, core::String) record = #C3]) → core::int
+  return record.$0{core::int};
+static method method3([(core::int, core::String) record = #C3]) → core::String
+  return record.$1{core::String};
+static method method4(core::int a, core::String b) → ({required a: core::int, required b: core::String})
+  return ({a: a, b: b});
+static method method5([({required a: core::int, required b: core::String}) record = #C4]) → core::int
+  return record.a{core::int};
+static method method6([({required a: core::int, required b: core::String}) record = #C4]) → core::String
+  return record.b{core::String};
+
+constants  {
+  #C1 = 0
+  #C2 = ""
+const (#C1, #C2)
+const ({a:#C1, b:#C2})
+}
diff --git a/pkg/front_end/testcases/general/records_opt_out.dart b/pkg/front_end/testcases/general/records_opt_out.dart
new file mode 100644
index 0000000..30fb132
--- /dev/null
+++ b/pkg/front_end/testcases/general/records_opt_out.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, 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.18
+
+(int, String) method1(int a, String b) => (a, b);
+int method2([(int, String) record = const (0, '')]) => record.$0;
+String method3([(int, String) record = const (0, '')]) => record.$1;
+({int a, String b}) method4(int a, String b) => (a: a, b: b);
+int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
diff --git a/pkg/front_end/testcases/general/records_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/general/records_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..e1eecae
--- /dev/null
+++ b/pkg/front_end/testcases/general/records_opt_out.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.18
+(int, String) method1(int a, String b) => (a, b);
+int method2([(int, String) record = const (0, '')]) => record.$0;
+String method3([(int, String) record = const (0, '')]) => record.$1;
+({int a, String b}) method4(int a, String b) => (a: a, b: b);
+int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
diff --git a/pkg/front_end/testcases/general/records_opt_out.dart.weak.expect b/pkg/front_end/testcases/general/records_opt_out.dart.weak.expect
new file mode 100644
index 0000000..2f8545c
--- /dev/null
+++ b/pkg/front_end/testcases/general/records_opt_out.dart.weak.expect
@@ -0,0 +1,79 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:7:1: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// (int, String) method1(int a, String b) => (a, b);
+// ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:8:14: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method2([(int, String) record = const (0, '')]) => record.$0;
+//              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:9:17: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method3([(int, String) record = const (0, '')]) => record.$1;
+//                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:10:1: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// ({int a, String b}) method4(int a, String b) => (a: a, b: b);
+// ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:11:14: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+//              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:12:17: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
+//                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:7:43: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// (int, String) method1(int a, String b) => (a, b);
+//                                           ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:8:43: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method2([(int, String) record = const (0, '')]) => record.$0;
+//                                           ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:9:46: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method3([(int, String) record = const (0, '')]) => record.$1;
+//                                              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:10:49: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// ({int a, String b}) method4(int a, String b) => (a: a, b: b);
+//                                                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:11:49: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+//                                                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:12:52: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
+//                                                    ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method method1(core::int a, core::String b) → invalid-type
+  return invalid-expression "This requires the experimental 'records' language feature to be enabled.";
+static method method2([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::int
+  return record{<invalid>}.$0;
+static method method3([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::String
+  return record{<invalid>}.$1;
+static method method4(core::int a, core::String b) → invalid-type
+  return invalid-expression "This requires the experimental 'records' language feature to be enabled.";
+static method method5([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::int
+  return record{<invalid>}.a;
+static method method6([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::String
+  return record{<invalid>}.b;
diff --git a/pkg/front_end/testcases/general/records_opt_out.dart.weak.modular.expect b/pkg/front_end/testcases/general/records_opt_out.dart.weak.modular.expect
new file mode 100644
index 0000000..2f8545c
--- /dev/null
+++ b/pkg/front_end/testcases/general/records_opt_out.dart.weak.modular.expect
@@ -0,0 +1,79 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:7:1: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// (int, String) method1(int a, String b) => (a, b);
+// ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:8:14: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method2([(int, String) record = const (0, '')]) => record.$0;
+//              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:9:17: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method3([(int, String) record = const (0, '')]) => record.$1;
+//                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:10:1: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// ({int a, String b}) method4(int a, String b) => (a: a, b: b);
+// ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:11:14: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+//              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:12:17: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
+//                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:7:43: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// (int, String) method1(int a, String b) => (a, b);
+//                                           ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:8:43: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method2([(int, String) record = const (0, '')]) => record.$0;
+//                                           ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:9:46: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method3([(int, String) record = const (0, '')]) => record.$1;
+//                                              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:10:49: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// ({int a, String b}) method4(int a, String b) => (a: a, b: b);
+//                                                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:11:49: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+//                                                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:12:52: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
+//                                                    ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method method1(core::int a, core::String b) → invalid-type
+  return invalid-expression "This requires the experimental 'records' language feature to be enabled.";
+static method method2([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::int
+  return record{<invalid>}.$0;
+static method method3([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::String
+  return record{<invalid>}.$1;
+static method method4(core::int a, core::String b) → invalid-type
+  return invalid-expression "This requires the experimental 'records' language feature to be enabled.";
+static method method5([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::int
+  return record{<invalid>}.a;
+static method method6([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::String
+  return record{<invalid>}.b;
diff --git a/pkg/front_end/testcases/general/records_opt_out.dart.weak.outline.expect b/pkg/front_end/testcases/general/records_opt_out.dart.weak.outline.expect
new file mode 100644
index 0000000..b96ec5f
--- /dev/null
+++ b/pkg/front_end/testcases/general/records_opt_out.dart.weak.outline.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:7:1: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// (int, String) method1(int a, String b) => (a, b);
+// ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:8:14: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method2([(int, String) record = const (0, '')]) => record.$0;
+//              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:9:17: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method3([(int, String) record = const (0, '')]) => record.$1;
+//                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:10:1: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// ({int a, String b}) method4(int a, String b) => (a: a, b: b);
+// ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:11:14: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+//              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:12:17: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
+//                 ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method method1(core::int a, core::String b) → invalid-type
+  ;
+static method method2([has-declared-initializer invalid-type record]) → core::int
+  ;
+static method method3([has-declared-initializer invalid-type record]) → core::String
+  ;
+static method method4(core::int a, core::String b) → invalid-type
+  ;
+static method method5([has-declared-initializer invalid-type record]) → core::int
+  ;
+static method method6([has-declared-initializer invalid-type record]) → core::String
+  ;
diff --git a/pkg/front_end/testcases/general/records_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/general/records_opt_out.dart.weak.transformed.expect
new file mode 100644
index 0000000..2f8545c
--- /dev/null
+++ b/pkg/front_end/testcases/general/records_opt_out.dart.weak.transformed.expect
@@ -0,0 +1,79 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:7:1: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// (int, String) method1(int a, String b) => (a, b);
+// ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:8:14: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method2([(int, String) record = const (0, '')]) => record.$0;
+//              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:9:17: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method3([(int, String) record = const (0, '')]) => record.$1;
+//                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:10:1: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// ({int a, String b}) method4(int a, String b) => (a: a, b: b);
+// ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:11:14: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+//              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:12:17: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
+//                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:7:43: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// (int, String) method1(int a, String b) => (a, b);
+//                                           ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:8:43: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method2([(int, String) record = const (0, '')]) => record.$0;
+//                                           ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:9:46: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method3([(int, String) record = const (0, '')]) => record.$1;
+//                                              ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:10:49: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// ({int a, String b}) method4(int a, String b) => (a: a, b: b);
+//                                                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:11:49: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// int method5([({int a, String b}) record = const (a: 0, b: '')]) => record.a;
+//                                                 ^
+//
+// pkg/front_end/testcases/general/records_opt_out.dart:12:52: Error: This requires the experimental 'records' language feature to be enabled.
+// Try passing the '--enable-experiment=records' command line option.
+// String method6([({int a, String b}) record = const (a: 0, b: '')]) => record.b;
+//                                                    ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method method1(core::int a, core::String b) → invalid-type
+  return invalid-expression "This requires the experimental 'records' language feature to be enabled.";
+static method method2([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::int
+  return record{<invalid>}.$0;
+static method method3([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::String
+  return record{<invalid>}.$1;
+static method method4(core::int a, core::String b) → invalid-type
+  return invalid-expression "This requires the experimental 'records' language feature to be enabled.";
+static method method5([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::int
+  return record{<invalid>}.a;
+static method method6([invalid-type record = invalid-expression "This requires the experimental 'records' language feature to be enabled."]) → core::String
+  return record{<invalid>}.b;
diff --git a/pkg/front_end/testcases/general/spread_collection.dart.weak.transformed.expect b/pkg/front_end/testcases/general/spread_collection.dart.weak.transformed.expect
index a50001f..4d89f56 100644
--- a/pkg/front_end/testcases/general/spread_collection.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/spread_collection.dart.weak.transformed.expect
@@ -30,7 +30,7 @@
       #t3.{core::Map::addAll}{Invariant}(#t4{core::Map<core::int, core::int>}){(core::Map<core::int, core::int>) → void};
   } =>#t3;
   final core::Set<core::int> aSet = block {
-    final core::Set<core::int> #t5 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t5 = new col::_InternalLinkedHashSet::•<core::int>();
     #t5.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t5.{core::Set::addAll}{Invariant}(core::_GrowableList::_literal1<core::int>(2)){(core::Iterable<core::int>) → void};
     final core::Iterable<core::int>? #t6 = self::nullableList;
diff --git a/pkg/front_end/testcases/general/spread_collection_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/general/spread_collection_inference.dart.weak.transformed.expect
index 84fcc62..3d689d6 100644
--- a/pkg/front_end/testcases/general/spread_collection_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/spread_collection_inference.dart.weak.transformed.expect
@@ -214,7 +214,7 @@
   List<dynamic> lhs40 = <dynamic>[...notSpreadInt];
                                      ^");
   core::Set<dynamic>* set40 = block {
-    final core::Set<dynamic>* #t26 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t26 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t26.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:115:37: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set40 = <dynamic>{...notSpreadInt};
                                     ^"){(dynamic) →* core::bool*};
@@ -226,7 +226,7 @@
   List<dynamic> lhs50 = <dynamic>[...notSpreadFunction];
                                      ^");
   core::Set<dynamic>* set50 = block {
-    final core::Set<dynamic>* #t27 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t27 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t27.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:121:37: Error: Unexpected type 'int Function()' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set50 = <dynamic>{...notSpreadFunction};
                                     ^"){(dynamic) →* core::bool*};
@@ -238,7 +238,7 @@
   List<String> lhs60 = <String>[...spread];
                                    ^");
   core::Set<core::String*>* set60 = block {
-    final core::Set<core::String*>* #t28 = new col::_CompactLinkedHashSet::•<core::String*>();
+    final core::Set<core::String*>* #t28 = new col::_InternalLinkedHashSet::•<core::String*>();
     #t28.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:127:35: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
   Set<String> set60 = <String>{...spread};
                                   ^"){(core::String*) →* core::bool*};
@@ -253,13 +253,13 @@
   List<int> lhs70 = <int>[...null];
                              ^");
   core::Set<core::int*>* set70 = block {
-    final core::Set<core::int*>* #t29 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t29 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t29.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:135:29: Error: Can't spread a value with static type 'Null'.
   Set<int> set70 = <int>{...null};
                             ^"){(core::int*) →* core::bool*};
   } =>#t29;
   core::Set<dynamic>* set71ambiguous = block {
-    final core::Set<dynamic>* #t30 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t30 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t30.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:139:8: Error: Can't spread a value with static type 'Null'.
     ...null,
        ^"){(dynamic) →* core::bool*};
@@ -275,13 +275,13 @@
       #t31.{core::List::addAll}{Invariant}(#t32){(core::Iterable<core::int*>*) →* void};
   } =>#t31;
   core::Set<core::int*>* set80 = block {
-    final core::Set<core::int*>* #t33 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t33 = new col::_InternalLinkedHashSet::•<core::int*>();
     final has-declared-initializer core::Iterable<core::int*>* #t34 = null;
     if(!(#t34 == null))
       #t33.{core::Set::addAll}{Invariant}(#t34){(core::Iterable<core::int*>*) →* void};
   } =>#t33;
   core::Set<dynamic>* set81ambiguous = block {
-    final core::Set<dynamic>* #t35 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t35 = new col::_InternalLinkedHashSet::•<dynamic>();
     final has-declared-initializer core::Iterable<dynamic>* #t36 = null;
     if(!(#t36 == null))
       #t35.{core::Set::addAll}{Invariant}(#t36){(core::Iterable<dynamic>*) →* void};
diff --git a/pkg/front_end/testcases/general/spread_collection_inference2.dart.weak.transformed.expect b/pkg/front_end/testcases/general/spread_collection_inference2.dart.weak.transformed.expect
index 2c70c54..bee42b0 100644
--- a/pkg/front_end/testcases/general/spread_collection_inference2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/spread_collection_inference2.dart.weak.transformed.expect
@@ -230,7 +230,7 @@
   List<dynamic> lhs40 = <dynamic>[...notSpreadInt];
                                      ^");
   core::Set<dynamic> set40 = block {
-    final core::Set<dynamic> #t26 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t26 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t26.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference2.dart:109:37: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set40 = <dynamic>{...notSpreadInt};
                                     ^"){(dynamic) → core::bool};
@@ -242,7 +242,7 @@
   List<dynamic> lhs50 = <dynamic>[...notSpreadFunction];
                                      ^");
   core::Set<dynamic> set50 = block {
-    final core::Set<dynamic> #t27 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t27 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t27.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference2.dart:115:37: Error: Unexpected type 'int Function()?' of a spread.  Expected 'dynamic' or an Iterable.
   Set<dynamic> set50 = <dynamic>{...notSpreadFunction};
                                     ^"){(dynamic) → core::bool};
@@ -254,7 +254,7 @@
   List<String> lhs60 = <String>[...spread];
                                    ^");
   core::Set<core::String> set60 = block {
-    final core::Set<core::String> #t28 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Set<core::String> #t28 = new col::_InternalLinkedHashSet::•<core::String>();
     #t28.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference2.dart:121:35: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
   Set<String> set60 = <String>{...spread};
                                   ^"){(core::String) → core::bool};
@@ -269,13 +269,13 @@
   List<int> lhs70 = <int>[...null];
                              ^");
   core::Set<core::int> set70 = block {
-    final core::Set<core::int> #t29 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t29 = new col::_InternalLinkedHashSet::•<core::int>();
     #t29.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference2.dart:129:29: Error: Can't spread a value with static type 'Null'.
   Set<int> set70 = <int>{...null};
                             ^"){(core::int) → core::bool};
   } =>#t29;
   core::Set<dynamic> set71ambiguous = block {
-    final core::Set<dynamic> #t30 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t30 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t30.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/general/spread_collection_inference2.dart:133:8: Error: Can't spread a value with static type 'Null'.
     ...null,
        ^"){(dynamic) → core::bool};
@@ -291,13 +291,13 @@
       #t31.{core::List::addAll}{Invariant}(#t32{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t31;
   core::Set<core::int> set80 = block {
-    final core::Set<core::int> #t33 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t33 = new col::_InternalLinkedHashSet::•<core::int>();
     final has-declared-initializer core::Iterable<core::int>? #t34 = null;
     if(!(#t34 == null))
       #t33.{core::Set::addAll}{Invariant}(#t34{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t33;
   core::Set<dynamic> set81ambiguous = block {
-    final core::Set<dynamic> #t35 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t35 = new col::_InternalLinkedHashSet::•<dynamic>();
     final has-declared-initializer core::Iterable<dynamic>? #t36 = null;
     if(!(#t36 == null))
       #t35.{core::Set::addAll}{Invariant}(#t36{core::Iterable<dynamic>}){(core::Iterable<dynamic>) → void};
diff --git a/pkg/front_end/testcases/general/super_nsm.dart.weak.outline.expect b/pkg/front_end/testcases/general/super_nsm.dart.weak.outline.expect
index a2bcec4..79b7c9f 100644
--- a/pkg/front_end/testcases/general/super_nsm.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/super_nsm.dart.weak.outline.expect
@@ -28,8 +28,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///super_nsm.dart:6:3 -> SymbolConstant(#interfaceMethod)
-Evaluated: ListLiteral @ org-dartlang-testcase:///super_nsm.dart:6:3 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///super_nsm.dart:6:3 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///super_nsm.dart:6:3 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///super_nsm.dart:9:7 -> SymbolConstant(#interfaceMethod)
+Evaluated: ListLiteral @ org-dartlang-testcase:///super_nsm.dart:9:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///super_nsm.dart:9:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///super_nsm.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 9, effectively constant: 4
diff --git a/pkg/front_end/testcases/general/top_level_map_literal_error.dart.weak.transformed.expect b/pkg/front_end/testcases/general/top_level_map_literal_error.dart.weak.transformed.expect
index d5e3691..d2f3c8a 100644
--- a/pkg/front_end/testcases/general/top_level_map_literal_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/top_level_map_literal_error.dart.weak.transformed.expect
@@ -11,7 +11,7 @@
 import "dart:collection" as col;
 
 static field core::Set<core::int> a = block {
-  final core::Set<core::int> #t1 = new col::_CompactLinkedHashSet::•<core::int>();
+  final core::Set<core::int> #t1 = new col::_InternalLinkedHashSet::•<core::int>();
   #t1.{core::Set::add}{Invariant}(0){(core::int) → core::bool};
 } =>#t1;
 static field core::Map<core::int, core::int> b = <core::int, core::int>{0: 1};
diff --git a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect
index 4a42619..6eb4f2d 100644
--- a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect
@@ -14,7 +14,7 @@
   self::A<<Z extends core::Object? = dynamic>(dynamic) → Never> x = self::foo<<Z extends core::Object? = dynamic>(dynamic) → Never>(<Z extends core::Object? = dynamic>(dynamic Z) → Never => throw 42);
   core::List<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> y = core::_GrowableList::_literal1<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>(#C1);
   core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> z = block {
-    final core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> #t1 = new col::_CompactLinkedHashSet::•<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>();
+    final core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> #t1 = new col::_InternalLinkedHashSet::•<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>();
     #t1.{core::Set::add}{Invariant}(y.{core::Iterable::first}{<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>}){(<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>) → core::bool};
   } =>#t1;
 }
diff --git a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect
index 4a42619..6eb4f2d 100644
--- a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect
@@ -14,7 +14,7 @@
   self::A<<Z extends core::Object? = dynamic>(dynamic) → Never> x = self::foo<<Z extends core::Object? = dynamic>(dynamic) → Never>(<Z extends core::Object? = dynamic>(dynamic Z) → Never => throw 42);
   core::List<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> y = core::_GrowableList::_literal1<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>(#C1);
   core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> z = block {
-    final core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> #t1 = new col::_CompactLinkedHashSet::•<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>();
+    final core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> #t1 = new col::_InternalLinkedHashSet::•<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>();
     #t1.{core::Set::add}{Invariant}(y.{core::Iterable::first}{<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>}){(<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>) → core::bool};
   } =>#t1;
 }
diff --git a/pkg/front_end/testcases/incremental.status b/pkg/front_end/testcases/incremental.status
index aa3f9c4..87a2512 100644
--- a/pkg/front_end/testcases/incremental.status
+++ b/pkg/front_end/testcases/incremental.status
@@ -8,9 +8,9 @@
 #strongmode_mixins_2: Crash
 
 changing_modules_16: Crash
-late_lowering: EquivalenceError
 constant_fileoffset_and_typedef: EquivalenceError
 no_such_method_forwarder: EquivalenceError
 changing_nullability_on_recompile: EquivalenceError
 initializer_not_copied: EquivalenceError
 changed_error: EquivalenceError
+issue_49968: ConstantCoverageReferenceWithoutNode
diff --git a/pkg/front_end/testcases/incremental/bad_sdk_uri.yaml b/pkg/front_end/testcases/incremental/bad_sdk_uri.yaml
index aace4d7..148bde9 100644
--- a/pkg/front_end/testcases/incremental/bad_sdk_uri.yaml
+++ b/pkg/front_end/testcases/incremental/bad_sdk_uri.yaml
@@ -46,6 +46,10 @@
     # result (shouldn't matter considering this is an exceptional case).
     noFullComponent: true
 
+    # this skips checking constant coverage references as they fail because
+    # of wrong sdk loaded in this check.
+    checkConstantCoverageReferences: false
+
     invalidate:
       - main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental/issue_49968.yaml b/pkg/front_end/testcases/incremental/issue_49968.yaml
new file mode 100644
index 0000000..b85692c
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/issue_49968.yaml
@@ -0,0 +1,46 @@
+# Copyright (c) 2022, 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.md file.
+
+# Reproduce bad references which can crash the VM.
+
+type: newworld
+worlds:
+  - entry: test/a.dart
+    sources:
+      .dart_tool/package_config.json: |
+        {
+          "configVersion": 2,
+          "packages": [
+            {
+              "name": "foo",
+              "rootUri": "../",
+              "packageUri": "lib"
+            }
+          ]
+        }
+      test/a.dart: |
+        // Import same file twice.
+        import 'package:foo/foo.dart';
+        import '../lib/foo.dart';
+
+        void main() {}
+      lib/foo.dart: |
+        class Foo {
+          const Foo();
+        }
+        const foo = const Foo();
+    expectedLibraryCount: 3 # "foo.dart" is there twice.
+    checkConstantCoverageReferences: true
+
+  - entry: test/b.dart
+    worldType: updated
+    expectInitializeFromDill: false
+    sources:
+      test/b.dart: |
+        import '../lib/foo.dart';
+
+        void main() {}
+    expectedLibraryCount: 2
+    advancedInvalidation: noDirectlyInvalidated
+    checkConstantCoverageReferences: true
diff --git a/pkg/front_end/testcases/incremental/issue_49968.yaml.world.1.expect b/pkg/front_end/testcases/incremental/issue_49968.yaml.world.1.expect
new file mode 100644
index 0000000..cafd7ef
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/issue_49968.yaml.world.1.expect
@@ -0,0 +1,38 @@
+main = a::main;
+library from "org-dartlang-test:///lib/foo.dart" as foo {
+
+  class Foo extends dart.core::Object /*hasConstConstructor*/  {
+    const constructor •() → foo::Foo
+      : super dart.core::Object::•()
+      ;
+  }
+  static const field foo::Foo foo = #C1;
+}
+library from "package:foo/foo.dart" as foo2 {
+
+  class Foo extends dart.core::Object /*hasConstConstructor*/  {
+    const constructor •() → foo2::Foo
+      : super dart.core::Object::•()
+      ;
+  }
+  static const field foo2::Foo foo = #C2;
+}
+library from "org-dartlang-test:///test/a.dart" as a {
+
+  import "package:foo/foo.dart";
+  import "org-dartlang-test:///lib/foo.dart";
+
+  static method main() → void {}
+}
+constants  {
+  #C1 = foo::Foo {}
+  #C2 = foo2::Foo {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-test:///lib/foo.dart:
+- Foo. (from org-dartlang-test:///lib/foo.dart:2:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
+- Foo. (from org-dartlang-test:///lib/foo.dart:2:9)
+
diff --git a/pkg/front_end/testcases/incremental/issue_49968.yaml.world.2.expect b/pkg/front_end/testcases/incremental/issue_49968.yaml.world.2.expect
new file mode 100644
index 0000000..804b910
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/issue_49968.yaml.world.2.expect
@@ -0,0 +1,27 @@
+main = b::main;
+library from "org-dartlang-test:///lib/foo.dart" as foo {
+
+  class Foo extends dart.core::Object /*hasConstConstructor*/  {
+    const constructor •() → foo::Foo
+      : super dart.core::Object::•()
+      ;
+  }
+  static const field foo::Foo foo = #C1;
+}
+library from "org-dartlang-test:///test/b.dart" as b {
+
+  import "org-dartlang-test:///lib/foo.dart";
+
+  static method main() → void {}
+}
+constants  {
+  #C1 = foo::Foo {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-test:///lib/foo.dart:
+- Foo. (from org-dartlang-test:///lib/foo.dart:2:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
+- Foo. (from org-dartlang-test:///lib/foo.dart:2:9)
+
diff --git a/pkg/front_end/testcases/incremental/js_interop_change.yaml.world.1.expect b/pkg/front_end/testcases/incremental/js_interop_change.yaml.world.1.expect
index 61903b1..e5da04e 100644
--- a/pkg/front_end/testcases/incremental/js_interop_change.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/js_interop_change.yaml.world.1.expect
@@ -54,7 +54,6 @@
   @#C2
   class StaticJSClass extends dart.core::Object {
     external constructor •() → sta::StaticJSClass
-      : super dart.core::Object::•()
       ;
     static method _#new#tearOff() → dart._interceptors::JavaScriptObject
       return new sta::StaticJSClass::•() as dart._interceptors::JavaScriptObject;
diff --git a/pkg/front_end/testcases/incremental/js_interop_change.yaml.world.2.expect b/pkg/front_end/testcases/incremental/js_interop_change.yaml.world.2.expect
index 2ce98c3..3909961 100644
--- a/pkg/front_end/testcases/incremental/js_interop_change.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/js_interop_change.yaml.world.2.expect
@@ -54,7 +54,6 @@
   @#C2
   class StaticJSClass extends dart.core::Object {
     external constructor •() → sta::StaticJSClass
-      : super dart.core::Object::•()
       ;
     static method _#new#tearOff() → dart._interceptors::JavaScriptObject
       return new sta::StaticJSClass::•() as dart._interceptors::JavaScriptObject;
diff --git a/pkg/front_end/testcases/incremental/late_lowering.yaml.world.1.expect b/pkg/front_end/testcases/incremental/late_lowering.yaml.world.1.expect
index ce71355..2fda094 100644
--- a/pkg/front_end/testcases/incremental/late_lowering.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/late_lowering.yaml.world.1.expect
@@ -15,9 +15,9 @@
       }
       return let final dart.core::int? #t1 = this.{main::_Class::_#_Class#_privateField}{dart.core::int?} in #t1{dart.core::int};
     }
-    set _privateField(dart.core::int library org-dartlang-test:///part.dart::_privateField#param) → void {
+    set _privateField(dart.core::int _privateField#param) → void {
       this.{main::_Class::_#_Class#_privateField#isSet} = true;
-      this.{main::_Class::_#_Class#_privateField} = library org-dartlang-test:///part.dart::_privateField#param;
+      this.{main::_Class::_#_Class#_privateField} = _privateField#param;
     }
   }
   static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/incremental/late_lowering.yaml.world.2.expect b/pkg/front_end/testcases/incremental/late_lowering.yaml.world.2.expect
index 3537fb6..2fda094 100644
--- a/pkg/front_end/testcases/incremental/late_lowering.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/late_lowering.yaml.world.2.expect
@@ -15,9 +15,9 @@
       }
       return let final dart.core::int? #t1 = this.{main::_Class::_#_Class#_privateField}{dart.core::int?} in #t1{dart.core::int};
     }
-    set _privateField(dart.core::int library org-dartlang-test:///main.dart::_privateField#param) → void {
+    set _privateField(dart.core::int _privateField#param) → void {
       this.{main::_Class::_#_Class#_privateField#isSet} = true;
-      this.{main::_Class::_#_Class#_privateField} = library org-dartlang-test:///main.dart::_privateField#param;
+      this.{main::_Class::_#_Class#_privateField} = _privateField#param;
     }
   }
   static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/incremental/no_change_but_changed_type_02.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_change_but_changed_type_02.yaml.world.1.expect
index 2ac1aeb..61002e1 100644
--- a/pkg/front_end/testcases/incremental/no_change_but_changed_type_02.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_change_but_changed_type_02.yaml.world.1.expect
@@ -24,14 +24,14 @@
     synthetic constructor •() → main::B
       : super dart.core::Object::•()
       ;
-    no-such-method-forwarder get /* from org-dartlang-test:///lib.dart */ _#A#x#isSet() → dart.core::bool
-      return this.{dart.core::Object::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} dart.core::bool;
-    no-such-method-forwarder get /* from org-dartlang-test:///lib.dart */ _#A#x() → dart.core::int?
-      return this.{dart.core::Object::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} dart.core::int?;
-    no-such-method-forwarder set /* from org-dartlang-test:///lib.dart */ _#A#x#isSet(dart.core::bool value) → void
-      return this.{dart.core::Object::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C6, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(value)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
-    no-such-method-forwarder set /* from org-dartlang-test:///lib.dart */ _#A#x(dart.core::int? value) → void
-      return this.{dart.core::Object::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C7, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(value)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
+    no-such-method-forwarder get _#A#x#isSet() → dart.core::bool
+      return throw dart.core::NoSuchMethodError::withInvocation(this, new dart.core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4)));
+    no-such-method-forwarder get _#A#x() → dart.core::int?
+      return throw dart.core::NoSuchMethodError::withInvocation(this, new dart.core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4)));
+    no-such-method-forwarder set _#A#x#isSet(dart.core::bool value) → void
+      return throw dart.core::NoSuchMethodError::withInvocation(this, new dart.core::_InvocationMirror::_withType(#C6, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(value)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4)));
+    no-such-method-forwarder set _#A#x(dart.core::int? value) → void
+      return throw dart.core::NoSuchMethodError::withInvocation(this, new dart.core::_InvocationMirror::_withType(#C7, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(value)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4)));
   }
 }
 constants  {
diff --git a/pkg/front_end/testcases/incremental/no_change_but_changed_type_02.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_change_but_changed_type_02.yaml.world.2.expect
index 2ac1aeb..61002e1 100644
--- a/pkg/front_end/testcases/incremental/no_change_but_changed_type_02.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_change_but_changed_type_02.yaml.world.2.expect
@@ -24,14 +24,14 @@
     synthetic constructor •() → main::B
       : super dart.core::Object::•()
       ;
-    no-such-method-forwarder get /* from org-dartlang-test:///lib.dart */ _#A#x#isSet() → dart.core::bool
-      return this.{dart.core::Object::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} dart.core::bool;
-    no-such-method-forwarder get /* from org-dartlang-test:///lib.dart */ _#A#x() → dart.core::int?
-      return this.{dart.core::Object::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} dart.core::int?;
-    no-such-method-forwarder set /* from org-dartlang-test:///lib.dart */ _#A#x#isSet(dart.core::bool value) → void
-      return this.{dart.core::Object::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C6, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(value)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
-    no-such-method-forwarder set /* from org-dartlang-test:///lib.dart */ _#A#x(dart.core::int? value) → void
-      return this.{dart.core::Object::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C7, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(value)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
+    no-such-method-forwarder get _#A#x#isSet() → dart.core::bool
+      return throw dart.core::NoSuchMethodError::withInvocation(this, new dart.core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4)));
+    no-such-method-forwarder get _#A#x() → dart.core::int?
+      return throw dart.core::NoSuchMethodError::withInvocation(this, new dart.core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4)));
+    no-such-method-forwarder set _#A#x#isSet(dart.core::bool value) → void
+      return throw dart.core::NoSuchMethodError::withInvocation(this, new dart.core::_InvocationMirror::_withType(#C6, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(value)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4)));
+    no-such-method-forwarder set _#A#x(dart.core::int? value) → void
+      return throw dart.core::NoSuchMethodError::withInvocation(this, new dart.core::_InvocationMirror::_withType(#C7, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(value)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4)));
   }
 }
 constants  {
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_16.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_16.yaml.world.1.expect
index c1df2f5..aa33d6f 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_16.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_16.yaml.world.1.expect
@@ -22,11 +22,11 @@
     method noSuchMethod(dart.core::Invocation msg) → dynamic {
       dart.core::print("noSouchMethod!");
     }
-    no-such-method-forwarder get /* from org-dartlang-test:///lib1.dart */ getter() → dart.core::bool
+    no-such-method-forwarder get getter() → dart.core::bool
       return this.{main::Foo1::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} dart.core::bool;
-    no-such-method-forwarder method /* from org-dartlang-test:///lib1.dart */ method() → void
+    no-such-method-forwarder method method() → void
       return this.{main::Foo1::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C5, 0, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
-    no-such-method-forwarder set /* from org-dartlang-test:///lib1.dart */ setter(dart.core::bool b) → void
+    no-such-method-forwarder set setter(dart.core::bool b) → void
       return this.{main::Foo1::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C6, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(b)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
   }
   class Foo2 extends dart.core::Object implements lib1::Bar {
@@ -36,15 +36,15 @@
     method noSuchMethod(dart.core::Invocation msg) → dynamic {
       dart.core::print("noSouchMethod!");
     }
-    no-such-method-forwarder get /* from org-dartlang-test:///lib1.dart */ getter() → dart.core::bool
+    no-such-method-forwarder get getter() → dart.core::bool
       return this.{main::Foo2::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} dart.core::bool;
-    no-such-method-forwarder get /* from org-dartlang-test:///lib1.dart */ field() → dart.core::bool
+    no-such-method-forwarder get field() → dart.core::bool
       return this.{main::Foo2::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C7, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} dart.core::bool;
-    no-such-method-forwarder method /* from org-dartlang-test:///lib1.dart */ method() → void
+    no-such-method-forwarder method method() → void
       return this.{main::Foo2::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C5, 0, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
-    no-such-method-forwarder set /* from org-dartlang-test:///lib1.dart */ setter(dart.core::bool b) → void
+    no-such-method-forwarder set setter(dart.core::bool b) → void
       return this.{main::Foo2::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C6, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(b)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
-    no-such-method-forwarder set /* from org-dartlang-test:///lib1.dart */ field(dart.core::bool value) → void
+    no-such-method-forwarder set field(dart.core::bool value) → void
       return this.{main::Foo2::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C8, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(value)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
   }
 }
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_16.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_16.yaml.world.2.expect
index 91bbef7..284e37c 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_16.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_16.yaml.world.2.expect
@@ -22,11 +22,11 @@
     method noSuchMethod(dart.core::Invocation msg) → dynamic {
       dart.core::print("noSouchMethod!!");
     }
-    no-such-method-forwarder get /* from org-dartlang-test:///lib1.dart */ getter() → dart.core::bool
+    no-such-method-forwarder get getter() → dart.core::bool
       return this.{main::Foo1::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} dart.core::bool;
-    no-such-method-forwarder method /* from org-dartlang-test:///lib1.dart */ method() → void
+    no-such-method-forwarder method method() → void
       return this.{main::Foo1::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C5, 0, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
-    no-such-method-forwarder set /* from org-dartlang-test:///lib1.dart */ setter(dart.core::bool b) → void
+    no-such-method-forwarder set setter(dart.core::bool b) → void
       return this.{main::Foo1::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C6, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(b)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
   }
   class Foo2 extends dart.core::Object implements lib1::Bar {
@@ -36,15 +36,15 @@
     method noSuchMethod(dart.core::Invocation msg) → dynamic {
       dart.core::print("noSouchMethod!!");
     }
-    no-such-method-forwarder get /* from org-dartlang-test:///lib1.dart */ getter() → dart.core::bool
+    no-such-method-forwarder get getter() → dart.core::bool
       return this.{main::Foo2::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} dart.core::bool;
-    no-such-method-forwarder get /* from org-dartlang-test:///lib1.dart */ field() → dart.core::bool
+    no-such-method-forwarder get field() → dart.core::bool
       return this.{main::Foo2::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C7, 1, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} dart.core::bool;
-    no-such-method-forwarder method /* from org-dartlang-test:///lib1.dart */ method() → void
+    no-such-method-forwarder method method() → void
       return this.{main::Foo2::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C5, 0, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
-    no-such-method-forwarder set /* from org-dartlang-test:///lib1.dart */ setter(dart.core::bool b) → void
+    no-such-method-forwarder set setter(dart.core::bool b) → void
       return this.{main::Foo2::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C6, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(b)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
-    no-such-method-forwarder set /* from org-dartlang-test:///lib1.dart */ field(dart.core::bool value) → void
+    no-such-method-forwarder set field(dart.core::bool value) → void
       return this.{main::Foo2::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C8, 2, #C2, dart.core::List::unmodifiable<dynamic>(dart.core::_GrowableList::_literal1<dynamic>(value)), dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → dynamic};
   }
 }
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_20.yaml b/pkg/front_end/testcases/incremental/no_outline_change_20.yaml
index f55d38d..6c1e794 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_20.yaml
+++ b/pkg/front_end/testcases/incremental/no_outline_change_20.yaml
@@ -23,6 +23,7 @@
           }
           static String get getter2 => "42!";
           static void set setter2(String s) {}
+          static int field = 42;
         }
     expectedLibraryCount: 1
   - entry: main.dart
@@ -45,6 +46,7 @@
           }
           static String get getter2 => "42!";
           static void set setter2(String s) {}
+          static int field = 42;
         }
     expectedLibraryCount: 1
     advancedInvalidation: bodiesOnly
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_20.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_20.yaml.world.1.expect
index 46083ff..cb4f3b1 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_20.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_20.yaml.world.1.expect
@@ -6,15 +6,17 @@
       : super dart.core::Object::•()
       ;
   }
-  extension _extension#0 on main::A1 {
+  extension /* unnamed */ _extension#0 on main::A1 {
     method method1 = main::_extension#0|method1;
     tearoff method1 = main::_extension#0|get#method1;
     get getter1 = main::_extension#0|get#getter1;
     static method method2 = main::_extension#0|method2;
     static get getter2 = get main::_extension#0|getter2;
+    static field field = main::_extension#0|field;
     set setter1 = main::_extension#0|set#setter1;
     static set setter2 = set main::_extension#0|setter2;
   }
+  static field dart.core::int _extension#0|field = 42;
   static method _extension#0|method1(lowered final main::A1 #this) → main::A1 {
     return #this;
   }
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_20.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_20.yaml.world.2.expect
index 46083ff..cb4f3b1 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_20.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_20.yaml.world.2.expect
@@ -6,15 +6,17 @@
       : super dart.core::Object::•()
       ;
   }
-  extension _extension#0 on main::A1 {
+  extension /* unnamed */ _extension#0 on main::A1 {
     method method1 = main::_extension#0|method1;
     tearoff method1 = main::_extension#0|get#method1;
     get getter1 = main::_extension#0|get#getter1;
     static method method2 = main::_extension#0|method2;
     static get getter2 = get main::_extension#0|getter2;
+    static field field = main::_extension#0|field;
     set setter1 = main::_extension#0|set#setter1;
     static set setter2 = set main::_extension#0|setter2;
   }
+  static field dart.core::int _extension#0|field = 42;
   static method _extension#0|method1(lowered final main::A1 #this) → main::A1 {
     return #this;
   }
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.1.expect
index 168470b..f71d67e 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.1.expect
@@ -199,7 +199,7 @@
       return result;
     }
     method /* from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toSet() → dart.core::Set<dart.core::int> {
-      dart.core::Set<dart.core::int> result = new dart.collection::_CompactLinkedHashSet::•<dart.core::int>();
+      dart.core::Set<dart.core::int> result = new dart.collection::_InternalLinkedHashSet::•<dart.core::int>();
       for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}{dart.core::int}){(dart.core::num) → dart.core::bool}; i = i.{dart.core::num::+}(1){(dart.core::num) → dart.core::int}) {
         result.{dart.core::Set::add}(this.{dart.core::List::[]}(i){(dart.core::int) → dart.core::int}){(dart.core::int) → dart.core::bool};
       }
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.2.expect
index 168470b..f71d67e 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_22.yaml.world.2.expect
@@ -199,7 +199,7 @@
       return result;
     }
     method /* from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toSet() → dart.core::Set<dart.core::int> {
-      dart.core::Set<dart.core::int> result = new dart.collection::_CompactLinkedHashSet::•<dart.core::int>();
+      dart.core::Set<dart.core::int> result = new dart.collection::_InternalLinkedHashSet::•<dart.core::int>();
       for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}{dart.core::int}){(dart.core::num) → dart.core::bool}; i = i.{dart.core::num::+}(1){(dart.core::num) → dart.core::int}) {
         result.{dart.core::Set::add}(this.{dart.core::List::[]}(i){(dart.core::int) → dart.core::int}){(dart.core::int) → dart.core::bool};
       }
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_31.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_31.yaml.world.1.expect
index 374b144..85a31ea 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_31.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_31.yaml.world.1.expect
@@ -6,7 +6,7 @@
       : super dart.core::Object::•()
       ;
   }
-  extension _extension#0 on main::C {
+  extension /* unnamed */ _extension#0 on main::C {
     static field field5 = main::_#_extension#0|field5;
     static field field5 = main::_#_extension#0|field5#isSet;
     static get field5 = get main::_extension#0|field5;
@@ -82,15 +82,15 @@
     }
     return main::_#_extension#0|field5;
   }
-  static set _extension#0|field5(dart.core::int? library org-dartlang-test:///main.dart::_extension#0|field5#param) → void {
+  static set _extension#0|field5(dart.core::int? field5#param) → void {
     main::_#_extension#0|field5#isSet = true;
-    main::_#_extension#0|field5 = library org-dartlang-test:///main.dart::_extension#0|field5#param;
+    main::_#_extension#0|field5 = field5#param;
   }
   static get _extension#0|field6() → dart.core::int?
     return main::_#_extension#0|field6#isSet ?{dart.core::int?} main::_#_extension#0|field6 : throw new dart._internal::LateError::fieldNI("field6");
-  static set _extension#0|field6(dart.core::int? library org-dartlang-test:///main.dart::_extension#0|field6#param) → void {
+  static set _extension#0|field6(dart.core::int? field6#param) → void {
     main::_#_extension#0|field6#isSet = true;
-    main::_#_extension#0|field6 = library org-dartlang-test:///main.dart::_extension#0|field6#param;
+    main::_#_extension#0|field6 = field6#param;
   }
   static get _extension#0|field7() → dart.core::int? {
     if(!main::_#_extension#0|field7#isSet) {
@@ -104,12 +104,12 @@
   }
   static get _extension#0|field8() → dart.core::int?
     return main::_#_extension#0|field8#isSet ?{dart.core::int?} main::_#_extension#0|field8 : throw new dart._internal::LateError::fieldNI("field8");
-  static set _extension#0|field8(dart.core::int? library org-dartlang-test:///main.dart::_extension#0|field8#param) → void
+  static set _extension#0|field8(dart.core::int? field8#param) → void
     if(main::_#_extension#0|field8#isSet)
       throw new dart._internal::LateError::fieldAI("field8");
     else {
       main::_#_extension#0|field8#isSet = true;
-      main::_#_extension#0|field8 = library org-dartlang-test:///main.dart::_extension#0|field8#param;
+      main::_#_extension#0|field8 = field8#param;
     }
   static method main() → dynamic {
     main::field1 = 43;
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_31.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_31.yaml.world.2.expect
index 65c62a4..dd9557c 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_31.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_31.yaml.world.2.expect
@@ -6,7 +6,7 @@
       : super dart.core::Object::•()
       ;
   }
-  extension _extension#0 on main::C {
+  extension /* unnamed */ _extension#0 on main::C {
     static field field5 = main::_#_extension#0|field5;
     static field field5 = main::_#_extension#0|field5#isSet;
     static get field5 = get main::_extension#0|field5;
@@ -82,15 +82,15 @@
     }
     return main::_#_extension#0|field5;
   }
-  static set _extension#0|field5(dart.core::int? library org-dartlang-test:///main.dart::_extension#0|field5#param) → void {
+  static set _extension#0|field5(dart.core::int? field5#param) → void {
     main::_#_extension#0|field5#isSet = true;
-    main::_#_extension#0|field5 = library org-dartlang-test:///main.dart::_extension#0|field5#param;
+    main::_#_extension#0|field5 = field5#param;
   }
   static get _extension#0|field6() → dart.core::int?
     return main::_#_extension#0|field6#isSet ?{dart.core::int?} main::_#_extension#0|field6 : throw new dart._internal::LateError::fieldNI("field6");
-  static set _extension#0|field6(dart.core::int? library org-dartlang-test:///main.dart::_extension#0|field6#param) → void {
+  static set _extension#0|field6(dart.core::int? field6#param) → void {
     main::_#_extension#0|field6#isSet = true;
-    main::_#_extension#0|field6 = library org-dartlang-test:///main.dart::_extension#0|field6#param;
+    main::_#_extension#0|field6 = field6#param;
   }
   static get _extension#0|field7() → dart.core::int? {
     if(!main::_#_extension#0|field7#isSet) {
@@ -104,12 +104,12 @@
   }
   static get _extension#0|field8() → dart.core::int?
     return main::_#_extension#0|field8#isSet ?{dart.core::int?} main::_#_extension#0|field8 : throw new dart._internal::LateError::fieldNI("field8");
-  static set _extension#0|field8(dart.core::int? library org-dartlang-test:///main.dart::_extension#0|field8#param) → void
+  static set _extension#0|field8(dart.core::int? field8#param) → void
     if(main::_#_extension#0|field8#isSet)
       throw new dart._internal::LateError::fieldAI("field8");
     else {
       main::_#_extension#0|field8#isSet = true;
-      main::_#_extension#0|field8 = library org-dartlang-test:///main.dart::_extension#0|field8#param;
+      main::_#_extension#0|field8 = field8#param;
     }
   static method main() → dynamic {
     main::field1 = 44;
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_32.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_32.yaml.world.1.expect
index 6e4cb7b..b1841ec 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_32.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_32.yaml.world.1.expect
@@ -6,7 +6,7 @@
       : super dart.core::Object::•()
       ;
   }
-  extension _extension#0 on main::C {
+  extension /* unnamed */ _extension#0 on main::C {
     static field field5 = main::_extension#0|field5;
     static field field6 = main::_extension#0|field6;
     static field field7 = main::_extension#0|field7;
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_32.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_32.yaml.world.2.expect
index 4e6c63f..2924ff9 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_32.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_32.yaml.world.2.expect
@@ -6,7 +6,7 @@
       : super dart.core::Object::•()
       ;
   }
-  extension _extension#0 on main::C {
+  extension /* unnamed */ _extension#0 on main::C {
     static field field5 = main::_extension#0|field5;
     static field field6 = main::_extension#0|field6;
     static field field7 = main::_extension#0|field7;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.weak.expect b/pkg/front_end/testcases/inference/future_then.dart.weak.expect
index c7f957d..7a8de8e 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.weak.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then.dart.weak.modular.expect
index c7f957d..7a8de8e 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.weak.modular.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then.dart.weak.outline.expect
index c0befdd..28ddca6 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.weak.transformed.expect
index 59040bd..5a23be8 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.weak.transformed.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_2.dart.weak.expect
index 24bbd71..89df77a 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.weak.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_2.dart.weak.modular.expect
index 24bbd71..89df77a 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.weak.modular.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_2.dart.weak.outline.expect
index c0befdd..0408212 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.weak.transformed.expect
index 799dbca..d833972 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.weak.transformed.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_3.dart.weak.expect
index e2c59bb..88390dc 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.weak.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_3.dart.weak.modular.expect
index e2c59bb..88390dc 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.weak.modular.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_3.dart.weak.outline.expect
index c0befdd..bfea426 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_3.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.weak.transformed.expect
index a49af5d..480e47b 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.weak.transformed.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_4.dart.weak.expect
index fc93c1c..8d4ae42 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.weak.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_4.dart.weak.modular.expect
index fc93c1c..8d4ae42 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.weak.modular.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_4.dart.weak.outline.expect
index c0befdd..9298200 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_4.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.weak.transformed.expect
index 45d285d..513fb78 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.weak.transformed.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_5.dart.weak.expect
index a3d1342..028e355 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.weak.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_5.dart.weak.modular.expect
index a3d1342..028e355 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.weak.modular.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_5.dart.weak.outline.expect
index dcbf3b8..900bdcb 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<dynamic> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_5.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.weak.transformed.expect
index 4b4a41f..1c005c2 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.weak.transformed.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_6.dart.weak.expect
index 076e9b4..10e338b 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.weak.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_6.dart.weak.modular.expect
index 076e9b4..10e338b 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.weak.modular.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_6.dart.weak.outline.expect
index dcbf3b8..cfeb924 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<dynamic> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_6.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.weak.transformed.expect
index dccede5..2d812a7 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.weak.transformed.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<dynamic> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.expect
index dc8d05e..9564bff 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.modular.expect
index dc8d05e..9564bff 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.modular.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.outline.expect
index eede603..a09b7d8 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.transformed.expect
index 77bf58c..a935810 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2.dart.weak.transformed.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.expect
index 9ae1043..769b2a3 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.modular.expect
index 9ae1043..769b2a3 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.modular.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.outline.expect
index eede603..ae9f603 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2_2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.transformed.expect
index ce018e4..e3dd962 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_2.dart.weak.transformed.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.expect
index 88f1310..7c26982 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.modular.expect
index 88f1310..7c26982 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.modular.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.outline.expect
index eede603..946e85a 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2_3.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.transformed.expect
index b0ac878..2d9eeea 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_3.dart.weak.transformed.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.expect
index ff4e173..64f088e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.modular.expect
index ff4e173..64f088e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.modular.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.outline.expect
index eede603..9d754d4 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2_4.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.transformed.expect
index 1420955..7075ec8 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_4.dart.weak.transformed.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.expect
index efa8914..7bee781 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.modular.expect
index efa8914..7bee781 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.modular.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.outline.expect
index 65754eb..63459fc 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<core::bool> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2_5.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.transformed.expect
index 3ef32de..75aa017 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_5.dart.weak.transformed.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.expect
index c7c7f3e..b131fba 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.modular.expect
index c7c7f3e..b131fba 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.modular.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.outline.expect
index 65754eb..ef6d704 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<core::bool> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_conditional2_6.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.transformed.expect
index cf18067..d74181c 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional2_6.dart.weak.transformed.expect
@@ -33,13 +33,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(asy::Future<core::bool> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.expect
index 12108cf..bb47b58 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.expect
@@ -49,13 +49,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::int> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.modular.expect
index 12108cf..bb47b58 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.modular.expect
@@ -49,13 +49,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::int> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.outline.expect
index d4975b57..724c048 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::int> f) → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_ifNull2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.transformed.expect
index 68c0668..6add2b3 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull2.dart.weak.transformed.expect
@@ -49,13 +49,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test(self::MyFuture<core::int> f) → void {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.expect
index c54b258..582c112 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.expect
@@ -23,13 +23,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.modular.expect
index c54b258..582c112 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.modular.expect
@@ -23,13 +23,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.outline.expect
index 95a470d..2fe6542 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_upwards.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.transformed.expect
index 0df67f2..1eb8761 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.weak.transformed.expect
@@ -23,13 +23,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.expect
index cdc2635..c50e776 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.expect
@@ -22,13 +22,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.modular.expect
index cdc2635..c50e776 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.modular.expect
@@ -22,13 +22,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.outline.expect
index 95a470d..44e7662 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void
@@ -30,17 +30,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_upwards_2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.transformed.expect
index 97e9554..ee7ee1d 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.weak.transformed.expect
@@ -22,13 +22,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.expect
index eda2025..62b0220 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.expect
@@ -22,13 +22,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.modular.expect
index eda2025..62b0220 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.modular.expect
@@ -22,13 +22,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.outline.expect
index cf476b4..096d49a 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void
@@ -32,17 +32,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_then_upwards_3.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.transformed.expect
index 79b6308..9889eea 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.weak.transformed.expect
@@ -22,13 +22,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.expect
index 06325b8..5d8e000 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.expect
@@ -35,13 +35,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async /* futureValueType= core::int */ {
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.modular.expect
index 06325b8..5d8e000 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.modular.expect
@@ -35,13 +35,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async /* futureValueType= core::int */ {
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.outline.expect
index 1340fd2..d8a0dbb 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async 
@@ -34,17 +34,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_async_conditional2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.transformed.expect
index 069d3a0..fd570c8 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional2.dart.weak.transformed.expect
@@ -35,13 +35,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async /* futureValueType= core::int */ {
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.expect
index 75d79fb..2879cda 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.expect
@@ -35,13 +35,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async /* futureValueType= core::int */ {
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.modular.expect
index 75d79fb..2879cda 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.modular.expect
@@ -35,13 +35,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async /* futureValueType= core::int */ {
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.outline.expect
index 1340fd2..4da4367 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async 
@@ -34,17 +34,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_async_conditional_2_2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.transformed.expect
index b7502eb..e691c7d 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2_2.dart.weak.transformed.expect
@@ -35,13 +35,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async /* futureValueType= core::int */ {
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.expect
index 986056a..78f544b 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.expect
@@ -21,13 +21,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field self::MyFuture<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.modular.expect
index 986056a..78f544b 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.modular.expect
@@ -21,13 +21,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field self::MyFuture<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.outline.expect
index 5607d26..3049355 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field self::MyFuture<dynamic> f;
@@ -35,17 +35,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_downwards.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.transformed.expect
index f36588c..b63b8ef 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.transformed.expect
@@ -21,13 +21,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field self::MyFuture<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.expect
index 6427ffa..1c798c1 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field self::MyFuture<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.modular.expect
index 6427ffa..1c798c1 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.modular.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field self::MyFuture<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.outline.expect
index 5607d26..3c52d43 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field self::MyFuture<dynamic> f;
@@ -35,17 +35,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_downwards_2.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.transformed.expect
index e3d49b7..420d41b 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.transformed.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field self::MyFuture<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.expect
index e195bf1..23ff091 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.expect
@@ -21,13 +21,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field asy::Future<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.modular.expect
index e195bf1..23ff091 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.modular.expect
@@ -21,13 +21,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field asy::Future<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.outline.expect
index de936c2..480ae17 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field asy::Future<dynamic> f;
@@ -35,17 +35,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_downwards_3.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.transformed.expect
index 1c2a48f..8ac3abc 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.transformed.expect
@@ -21,13 +21,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field asy::Future<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.expect
index 780b5a0..361ead2 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field asy::Future<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.modular.expect
index 780b5a0..361ead2 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.modular.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field asy::Future<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.outline.expect
index de936c2..6653302 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.outline.expect
@@ -14,13 +14,13 @@
     ;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = null}) → self::MyFuture<self::MyFuture::then::S%>
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field asy::Future<dynamic> f;
@@ -35,17 +35,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///future_union_downwards_4.dart:10:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 46, effectively constant: 13
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.transformed.expect
index 025e2eb..1460259 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.transformed.expect
@@ -14,13 +14,13 @@
     return null;
   method then<S extends core::Object? = dynamic>((self::MyFuture::T%) → FutureOr<self::MyFuture::then::S%>f, {core::Function? onError = #C1}) → self::MyFuture<self::MyFuture::then::S%>
     return throw "";
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::MyFuture::T%>onTimeout = #C1}) → asy::Future<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::MyFuture::T%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T%>
+  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T%>
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, #C10, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::MyFuture::T%>;
 }
 static field asy::Future<dynamic> f = throw "";
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.weak.transformed.expect
index d2f3381..0d843e9 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.weak.transformed.expect
@@ -128,7 +128,7 @@
  - 'List' is from 'dart:core'.
   c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
                                                           ^" in ( block {
-    final core::Set<dynamic> #t2 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t2 = new col::_InternalLinkedHashSet::•<dynamic>();
   } =>#t2) as{TypeError,ForNonNullableByDefault} core::List<dynamic>;
   self::c2 = core::_GrowableList::•<dynamic>(0);
   self::c2 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
@@ -136,7 +136,7 @@
  - 'List' is from 'dart:core'.
   c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
                                                           ^" in ( block {
-    final core::Set<dynamic> #t3 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t3 = new col::_InternalLinkedHashSet::•<dynamic>();
   } =>#t3) as{TypeError,ForNonNullableByDefault} core::List<dynamic>;
   self::d = <dynamic, dynamic>{};
   self::d = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference.dart.weak.transformed.expect
index e9c3697..96c1436 100644
--- a/pkg/front_end/testcases/inference_update_1/horizontal_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference.dart.weak.transformed.expect
@@ -51,13 +51,13 @@
 }
 static method testLongDependencyChain(<T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V% f) → dynamic {
   f<core::List<core::int>, core::int, core::Set<core::int>>(() → core::List<core::int> => core::_GrowableList::_literal1<core::int>(0), (core::List<core::int> x) → core::int => x.{core::Iterable::single}{core::int}, (core::int y) → core::Set<core::int> => block {
-    final core::Set<core::int> #t2 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t2 = new col::_InternalLinkedHashSet::•<core::int>();
     #t2.{core::Set::add}{Invariant}(y){(core::int) → core::bool};
   } =>#t2){(() → core::List<core::int>, (core::List<core::int>) → core::int, (core::int) → core::Set<core::int>) → core::Set<core::int>};
 }
 static method testDependencyCycle(<T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T%, (T%) → U%) → core::Map<T%, U%> f) → dynamic {
   f<core::List<core::Object?>, core::Set<core::Object?>>((core::Object? x) → core::List<core::Object?> => core::_GrowableList::_literal1<core::Object?>(x), (core::Object? y) → core::Set<core::Object?> => block {
-    final core::Set<core::Object?> #t3 = new col::_CompactLinkedHashSet::•<core::Object?>();
+    final core::Set<core::Object?> #t3 = new col::_InternalLinkedHashSet::•<core::Object?>();
     #t3.{core::Set::add}{Invariant}(y){(core::Object?) → core::bool};
   } =>#t3){((core::Set<core::Object?>) → core::List<core::Object?>, (core::List<core::Object?>) → core::Set<core::Object?>) → core::Map<core::List<core::Object?>, core::Set<core::Object?>>};
 }
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.expect
index e09a14c..c4b314b 100644
--- a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.expect
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _laterUnnamedParameter = self::_extension#0|_laterUnnamedParameter;
   tearoff _laterUnnamedParameter = self::_extension#0|get#_laterUnnamedParameter;
   method _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter;
@@ -153,14 +153,14 @@
   return throw "";
 static method _extension#0|get#_earlierUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, T%) → void
   return <T extends core::Object? = dynamic>((T%) → void x, T% y) → void => self::_extension#0|_earlierUnnamedParameter<T%>(#this, x, y);
-static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a = #C1, required (self::_extension#0|_laterNamedParameter::T%) → void b = #C1}) → void
-  return throw "";
 static method _extension#0|get#_laterNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
   return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_laterNamedParameter<T%>(#this, a: a, b: b);
-static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a = #C1, required self::_extension#0|_earlierNamedParameter::T% b = #C1}) → void
+static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a = #C1, required (self::_extension#0|_laterNamedParameter::T%) → void b = #C1}) → void
   return throw "";
 static method _extension#0|get#_earlierNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: (T%) → void, b: T%}) → void
   return <T extends core::Object? = dynamic>({(T%) → void a = #C1, T% b = #C1}) → void => self::_extension#0|_earlierNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a = #C1, required self::_extension#0|_earlierNamedParameter::T% b = #C1}) → void
+  return throw "";
 static method _extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T% b, {required (self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T%) → void a = #C1}) → void
   return throw "";
 static method _extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, {a: (T%) → void}) → void
@@ -177,14 +177,14 @@
   return throw "";
 static method _extension#0|get#_propagateToEarlierClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U%, () → T%) → U%
   return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U% x, () → T% y) → U% => self::_extension#0|_propagateToEarlierClosure<T%, U%>(#this, x, y);
-static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
-  return throw "";
 static method _extension#0|get#_propagateToLaterClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, (T%) → U%) → U%
   return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToLaterClosure<T%, U%>(#this, x, y);
-static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
-  return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
+static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
+  return throw "";
 static method _extension#0|_longDependencyChain<T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_longDependencyChain::T% x, (self::_extension#0|_longDependencyChain::T%) → self::_extension#0|_longDependencyChain::U% y, (self::_extension#0|_longDependencyChain::U%) → self::_extension#0|_longDependencyChain::V% z) → self::_extension#0|_longDependencyChain::V%
   return throw "";
+static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
+  return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
 static method _extension#0|_dependencyCycle<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_dependencyCycle::U%) → self::_extension#0|_dependencyCycle::T% x, (self::_extension#0|_dependencyCycle::T%) → self::_extension#0|_dependencyCycle::U% y) → core::Map<self::_extension#0|_dependencyCycle::T%, self::_extension#0|_dependencyCycle::U%>
   return throw "";
 static method _extension#0|get#_dependencyCycle(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T%, (T%) → U%) → core::Map<T%, U%>
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.modular.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.modular.expect
index e09a14c..c4b314b 100644
--- a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.modular.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _laterUnnamedParameter = self::_extension#0|_laterUnnamedParameter;
   tearoff _laterUnnamedParameter = self::_extension#0|get#_laterUnnamedParameter;
   method _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter;
@@ -153,14 +153,14 @@
   return throw "";
 static method _extension#0|get#_earlierUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, T%) → void
   return <T extends core::Object? = dynamic>((T%) → void x, T% y) → void => self::_extension#0|_earlierUnnamedParameter<T%>(#this, x, y);
-static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a = #C1, required (self::_extension#0|_laterNamedParameter::T%) → void b = #C1}) → void
-  return throw "";
 static method _extension#0|get#_laterNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
   return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_laterNamedParameter<T%>(#this, a: a, b: b);
-static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a = #C1, required self::_extension#0|_earlierNamedParameter::T% b = #C1}) → void
+static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a = #C1, required (self::_extension#0|_laterNamedParameter::T%) → void b = #C1}) → void
   return throw "";
 static method _extension#0|get#_earlierNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: (T%) → void, b: T%}) → void
   return <T extends core::Object? = dynamic>({(T%) → void a = #C1, T% b = #C1}) → void => self::_extension#0|_earlierNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a = #C1, required self::_extension#0|_earlierNamedParameter::T% b = #C1}) → void
+  return throw "";
 static method _extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T% b, {required (self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T%) → void a = #C1}) → void
   return throw "";
 static method _extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, {a: (T%) → void}) → void
@@ -177,14 +177,14 @@
   return throw "";
 static method _extension#0|get#_propagateToEarlierClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U%, () → T%) → U%
   return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U% x, () → T% y) → U% => self::_extension#0|_propagateToEarlierClosure<T%, U%>(#this, x, y);
-static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
-  return throw "";
 static method _extension#0|get#_propagateToLaterClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, (T%) → U%) → U%
   return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToLaterClosure<T%, U%>(#this, x, y);
-static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
-  return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
+static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
+  return throw "";
 static method _extension#0|_longDependencyChain<T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_longDependencyChain::T% x, (self::_extension#0|_longDependencyChain::T%) → self::_extension#0|_longDependencyChain::U% y, (self::_extension#0|_longDependencyChain::U%) → self::_extension#0|_longDependencyChain::V% z) → self::_extension#0|_longDependencyChain::V%
   return throw "";
+static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
+  return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
 static method _extension#0|_dependencyCycle<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_dependencyCycle::U%) → self::_extension#0|_dependencyCycle::T% x, (self::_extension#0|_dependencyCycle::T%) → self::_extension#0|_dependencyCycle::U% y) → core::Map<self::_extension#0|_dependencyCycle::T%, self::_extension#0|_dependencyCycle::U%>
   return throw "";
 static method _extension#0|get#_dependencyCycle(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T%, (T%) → U%) → core::Map<T%, U%>
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.outline.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.outline.expect
index dae2ab4..e68db24 100644
--- a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.outline.expect
@@ -2,7 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _laterUnnamedParameter = self::_extension#0|_laterUnnamedParameter;
   tearoff _laterUnnamedParameter = self::_extension#0|get#_laterUnnamedParameter;
   method _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter;
@@ -100,14 +100,14 @@
   ;
 static method _extension#0|get#_earlierUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, T%) → void
   return <T extends core::Object? = dynamic>((T%) → void x, T% y) → void => self::_extension#0|_earlierUnnamedParameter<T%>(#this, x, y);
-static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a, required (self::_extension#0|_laterNamedParameter::T%) → void b}) → void
-  ;
 static method _extension#0|get#_laterNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
   return <T extends core::Object? = dynamic>({T% a, (T%) → void b}) → void => self::_extension#0|_laterNamedParameter<T%>(#this, a: a, b: b);
-static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a, required self::_extension#0|_earlierNamedParameter::T% b}) → void
+static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a, required (self::_extension#0|_laterNamedParameter::T%) → void b}) → void
   ;
 static method _extension#0|get#_earlierNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: (T%) → void, b: T%}) → void
   return <T extends core::Object? = dynamic>({(T%) → void a, T% b}) → void => self::_extension#0|_earlierNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a, required self::_extension#0|_earlierNamedParameter::T% b}) → void
+  ;
 static method _extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T% b, {required (self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T%) → void a}) → void
   ;
 static method _extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, {a: (T%) → void}) → void
@@ -124,14 +124,14 @@
   ;
 static method _extension#0|get#_propagateToEarlierClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U%, () → T%) → U%
   return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U% x, () → T% y) → U% => self::_extension#0|_propagateToEarlierClosure<T%, U%>(#this, x, y);
-static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
-  ;
 static method _extension#0|get#_propagateToLaterClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, (T%) → U%) → U%
   return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToLaterClosure<T%, U%>(#this, x, y);
-static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
-  return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
+static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
+  ;
 static method _extension#0|_longDependencyChain<T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_longDependencyChain::T% x, (self::_extension#0|_longDependencyChain::T%) → self::_extension#0|_longDependencyChain::U% y, (self::_extension#0|_longDependencyChain::U%) → self::_extension#0|_longDependencyChain::V% z) → self::_extension#0|_longDependencyChain::V%
   ;
+static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
+  return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
 static method _extension#0|_dependencyCycle<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_dependencyCycle::U%) → self::_extension#0|_dependencyCycle::T% x, (self::_extension#0|_dependencyCycle::T%) → self::_extension#0|_dependencyCycle::U% y) → core::Map<self::_extension#0|_dependencyCycle::T%, self::_extension#0|_dependencyCycle::U%>
   ;
 static method _extension#0|get#_dependencyCycle(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T%, (T%) → U%) → core::Map<T%, U%>
diff --git a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.transformed.expect b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.transformed.expect
index af2047a..32016ec 100644
--- a/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference_update_1/horizontal_inference_extension_method.dart.weak.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
-extension _extension#0 on core::int {
+extension /* unnamed */ _extension#0 on core::int {
   method _laterUnnamedParameter = self::_extension#0|_laterUnnamedParameter;
   tearoff _laterUnnamedParameter = self::_extension#0|get#_laterUnnamedParameter;
   method _laterUnnamedParameterDependsOnNamedParameter = self::_extension#0|_laterUnnamedParameterDependsOnNamedParameter;
@@ -91,13 +91,13 @@
 }
 static method testLongDependencyChain(core::int i) → dynamic {
   self::_extension#0|_longDependencyChain<core::List<core::int>, core::int, core::Set<core::int>>(i, () → core::List<core::int> => core::_GrowableList::_literal1<core::int>(0), (core::List<core::int> x) → core::int => x.{core::Iterable::single}{core::int}, (core::int y) → core::Set<core::int> => block {
-    final core::Set<core::int> #t1 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t1 = new col::_InternalLinkedHashSet::•<core::int>();
     #t1.{core::Set::add}{Invariant}(y){(core::int) → core::bool};
   } =>#t1);
 }
 static method testDependencyCycle(core::int i) → dynamic {
   self::_extension#0|_dependencyCycle<core::List<core::Object?>, core::Set<core::Object?>>(i, (core::Object? x) → core::List<core::Object?> => core::_GrowableList::_literal1<core::Object?>(x), (core::Object? y) → core::Set<core::Object?> => block {
-    final core::Set<core::Object?> #t2 = new col::_CompactLinkedHashSet::•<core::Object?>();
+    final core::Set<core::Object?> #t2 = new col::_InternalLinkedHashSet::•<core::Object?>();
     #t2.{core::Set::add}{Invariant}(y){(core::Object?) → core::bool};
   } =>#t2);
 }
@@ -153,14 +153,14 @@
   return throw "";
 static method _extension#0|get#_earlierUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, T%) → void
   return <T extends core::Object? = dynamic>((T%) → void x, T% y) → void => self::_extension#0|_earlierUnnamedParameter<T%>(#this, x, y);
-static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a = #C1, required (self::_extension#0|_laterNamedParameter::T%) → void b = #C1}) → void
-  return throw "";
 static method _extension#0|get#_laterNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: T%, b: (T%) → void}) → void
   return <T extends core::Object? = dynamic>({T% a = #C1, (T%) → void b = #C1}) → void => self::_extension#0|_laterNamedParameter<T%>(#this, a: a, b: b);
-static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a = #C1, required self::_extension#0|_earlierNamedParameter::T% b = #C1}) → void
+static method _extension#0|_laterNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required self::_extension#0|_laterNamedParameter::T% a = #C1, required (self::_extension#0|_laterNamedParameter::T%) → void b = #C1}) → void
   return throw "";
 static method _extension#0|get#_earlierNamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>({a: (T%) → void, b: T%}) → void
   return <T extends core::Object? = dynamic>({(T%) → void a = #C1, T% b = #C1}) → void => self::_extension#0|_earlierNamedParameter<T%>(#this, a: a, b: b);
+static method _extension#0|_earlierNamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, {required (self::_extension#0|_earlierNamedParameter::T%) → void a = #C1, required self::_extension#0|_earlierNamedParameter::T% b = #C1}) → void
+  return throw "";
 static method _extension#0|_earlierNamedParameterDependsOnUnnamedParameter<T extends core::Object? = dynamic>(lowered final core::int #this, self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T% b, {required (self::_extension#0|_earlierNamedParameterDependsOnUnnamedParameter::T%) → void a = #C1}) → void
   return throw "";
 static method _extension#0|get#_earlierNamedParameterDependsOnUnnamedParameter(lowered final core::int #this) → <T extends core::Object? = dynamic>(T%, {a: (T%) → void}) → void
@@ -177,14 +177,14 @@
   return throw "";
 static method _extension#0|get#_propagateToEarlierClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U%, () → T%) → U%
   return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((T%) → U% x, () → T% y) → U% => self::_extension#0|_propagateToEarlierClosure<T%, U%>(#this, x, y);
-static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
-  return throw "";
 static method _extension#0|get#_propagateToLaterClosure(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T%, (T%) → U%) → U%
   return <T extends core::Object? = dynamic, U extends core::Object? = dynamic>(() → T% x, (T%) → U% y) → U% => self::_extension#0|_propagateToLaterClosure<T%, U%>(#this, x, y);
-static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
-  return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
+static method _extension#0|_propagateToLaterClosure<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_propagateToLaterClosure::T% x, (self::_extension#0|_propagateToLaterClosure::T%) → self::_extension#0|_propagateToLaterClosure::U% y) → self::_extension#0|_propagateToLaterClosure::U%
+  return throw "";
 static method _extension#0|_longDependencyChain<T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(lowered final core::int #this, () → self::_extension#0|_longDependencyChain::T% x, (self::_extension#0|_longDependencyChain::T%) → self::_extension#0|_longDependencyChain::U% y, (self::_extension#0|_longDependencyChain::U%) → self::_extension#0|_longDependencyChain::V% z) → self::_extension#0|_longDependencyChain::V%
   return throw "";
+static method _extension#0|get#_longDependencyChain(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T%, (T%) → U%, (U%) → V%) → V%
+  return <T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic>(() → T% x, (T%) → U% y, (U%) → V% z) → V% => self::_extension#0|_longDependencyChain<T%, U%, V%>(#this, x, y, z);
 static method _extension#0|_dependencyCycle<T extends core::Object? = dynamic, U extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_dependencyCycle::U%) → self::_extension#0|_dependencyCycle::T% x, (self::_extension#0|_dependencyCycle::T%) → self::_extension#0|_dependencyCycle::U% y) → core::Map<self::_extension#0|_dependencyCycle::T%, self::_extension#0|_dependencyCycle::U%>
   return throw "";
 static method _extension#0|get#_dependencyCycle(lowered final core::int #this) → <T extends core::Object? = dynamic, U extends core::Object? = dynamic>((U%) → T%, (T%) → U%) → core::Map<T%, U%>
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.strong.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.strong.expect
index 37756b5..7560dbd 100644
--- a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.strong.expect
@@ -9,10 +9,10 @@
   synthetic constructor •() → self::C
     : super iss::B::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _#A#x() → core::int?
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _#A#x(core::int? value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {
   new self::C::•();
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.strong.transformed.expect
index 07d36fd..ce15d05 100644
--- a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.strong.transformed.expect
@@ -9,10 +9,10 @@
   synthetic constructor •() → self::C
     : super iss::B::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _#A#x() → core::int?
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _#A#x(core::int? value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {
   new self::C::•();
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.expect
index 8fe6ee7..cb2b033 100644
--- a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.expect
@@ -9,14 +9,14 @@
   synthetic constructor •() → self::C
     : super iss::B::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x#isSet() → core::bool
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x#isSet(core::bool value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _#A#x#isSet() → core::bool
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder get _#A#x() → core::int?
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _#A#x#isSet(core::bool value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _#A#x(core::int? value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C7, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {
   new self::C::•();
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.modular.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.modular.expect
index 4a82ef6..8b3d404 100644
--- a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.modular.expect
@@ -9,14 +9,14 @@
   synthetic constructor •() → self::C
     : super iss::B::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x#isSet() → core::bool
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x#isSet(core::bool value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _#A#x#isSet() → core::bool
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder get _#A#x() → core::int?
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _#A#x#isSet(core::bool value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _#A#x(core::int? value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C7, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {
   new self::C::•();
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.outline.expect
index ae337d4..2a88d98 100644
--- a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.outline.expect
@@ -8,14 +8,14 @@
 class C extends iss::B {
   synthetic constructor •() → self::C
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x#isSet() → core::bool
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_#A#x#isSet, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_#A#x, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x#isSet(core::bool value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_#A#x#isSet=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_#A#x=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _#A#x#isSet() → core::bool
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_#A#x#isSet, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
+  no-such-method-forwarder get _#A#x() → core::int?
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_#A#x, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
+  no-such-method-forwarder set _#A#x#isSet(core::bool value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_#A#x#isSet=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
+  no-such-method-forwarder set _#A#x(core::int? value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_#A#x=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 static method main() → dynamic
   ;
@@ -40,18 +40,18 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> SymbolConstant(#_#A#x#isSet)
-Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> SymbolConstant(#_#A#x)
-Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> SymbolConstant(#_#A#x#isSet=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> SymbolConstant(#_#A#x=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///issue41436c_lib.dart:6:12 -> MapConstant(const <Symbol*, dynamic>{})
-Extra constant evaluation: evaluated: 38, effectively constant: 14
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> SymbolConstant(#_#A#x#isSet)
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> SymbolConstant(#_#A#x)
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> SymbolConstant(#_#A#x#isSet=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> SymbolConstant(#_#A#x=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///issue41436c.dart:7:7 -> MapConstant(const <Symbol*, dynamic>{})
+Extra constant evaluation: evaluated: 40, effectively constant: 14
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.transformed.expect
index fdea894..8f7587a 100644
--- a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.weak.transformed.expect
@@ -9,14 +9,14 @@
   synthetic constructor •() → self::C
     : super iss::B::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x#isSet() → core::bool
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x#isSet(core::bool value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _#A#x#isSet() → core::bool
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder get _#A#x() → core::int?
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _#A#x#isSet(core::bool value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _#A#x(core::int? value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C7, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {
   new self::C::•();
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.expect
index 31bd3e7..1d6091d 100644
--- a/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.expect
@@ -151,15 +151,15 @@
 static get Extension|extensionStaticField() → core::int
   return let final core::int? #t23 = self::_#Extension|extensionStaticField in #t23 == null ?{core::int} throw new _in::LateError::fieldNI("extensionStaticField") : #t23{core::int};
 @#C1
-static set Extension|extensionStaticField(core::int Extension|extensionStaticField#param) → void
-  self::_#Extension|extensionStaticField = Extension|extensionStaticField#param;
+static set Extension|extensionStaticField(core::int extensionStaticField#param) → void
+  self::_#Extension|extensionStaticField = extensionStaticField#param;
 @#C1
 static get Extension|finalExtensionStaticField() → core::int
   return let final core::int? #t24 = self::_#Extension|finalExtensionStaticField in #t24 == null ?{core::int} throw new _in::LateError::fieldNI("finalExtensionStaticField") : #t24{core::int};
 @#C1
-static set Extension|finalExtensionStaticField(core::int Extension|finalExtensionStaticField#param) → void
+static set Extension|finalExtensionStaticField(core::int finalExtensionStaticField#param) → void
   if(self::_#Extension|finalExtensionStaticField == null)
-    self::_#Extension|finalExtensionStaticField = Extension|finalExtensionStaticField#param;
+    self::_#Extension|finalExtensionStaticField = finalExtensionStaticField#param;
   else
     throw new _in::LateError::fieldAI("finalExtensionStaticField");
 @#C1
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.transformed.expect
index d25c6e8..98b090b 100644
--- a/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.transformed.expect
@@ -151,15 +151,15 @@
 static get Extension|extensionStaticField() → core::int
   return let final core::int? #t23 = self::_#Extension|extensionStaticField in #t23 == null ?{core::int} throw new _in::LateError::fieldNI("extensionStaticField") : #t23{core::int};
 @#C1
-static set Extension|extensionStaticField(core::int Extension|extensionStaticField#param) → void
-  self::_#Extension|extensionStaticField = Extension|extensionStaticField#param;
+static set Extension|extensionStaticField(core::int extensionStaticField#param) → void
+  self::_#Extension|extensionStaticField = extensionStaticField#param;
 @#C1
 static get Extension|finalExtensionStaticField() → core::int
   return let final core::int? #t24 = self::_#Extension|finalExtensionStaticField in #t24 == null ?{core::int} throw new _in::LateError::fieldNI("finalExtensionStaticField") : #t24{core::int};
 @#C1
-static set Extension|finalExtensionStaticField(core::int Extension|finalExtensionStaticField#param) → void
+static set Extension|finalExtensionStaticField(core::int finalExtensionStaticField#param) → void
   if(self::_#Extension|finalExtensionStaticField == null)
-    self::_#Extension|finalExtensionStaticField = Extension|finalExtensionStaticField#param;
+    self::_#Extension|finalExtensionStaticField = finalExtensionStaticField#param;
   else
     throw new _in::LateError::fieldAI("finalExtensionStaticField");
 @#C1
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.expect
index c6d998f..2a97ef5 100644
--- a/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.expect
@@ -238,20 +238,20 @@
 static get Extension|extensionStaticField() → core::int
   return self::_#Extension|extensionStaticField#isSet ?{core::int} let final core::int? #t23 = self::_#Extension|extensionStaticField in #t23{core::int} : throw new _in::LateError::fieldNI("extensionStaticField");
 @#C1
-static set Extension|extensionStaticField(core::int Extension|extensionStaticField#param) → void {
+static set Extension|extensionStaticField(core::int extensionStaticField#param) → void {
   self::_#Extension|extensionStaticField#isSet = true;
-  self::_#Extension|extensionStaticField = Extension|extensionStaticField#param;
+  self::_#Extension|extensionStaticField = extensionStaticField#param;
 }
 @#C1
 static get Extension|finalExtensionStaticField() → core::int
   return self::_#Extension|finalExtensionStaticField#isSet ?{core::int} let final core::int? #t24 = self::_#Extension|finalExtensionStaticField in #t24{core::int} : throw new _in::LateError::fieldNI("finalExtensionStaticField");
 @#C1
-static set Extension|finalExtensionStaticField(core::int Extension|finalExtensionStaticField#param) → void
+static set Extension|finalExtensionStaticField(core::int finalExtensionStaticField#param) → void
   if(self::_#Extension|finalExtensionStaticField#isSet)
     throw new _in::LateError::fieldAI("finalExtensionStaticField");
   else {
     self::_#Extension|finalExtensionStaticField#isSet = true;
-    self::_#Extension|finalExtensionStaticField = Extension|finalExtensionStaticField#param;
+    self::_#Extension|finalExtensionStaticField = finalExtensionStaticField#param;
   }
 @#C1
 static get Extension|finalExtensionStaticFieldWithInitializer() → core::int {
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.modular.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.modular.expect
index c6d998f..2a97ef5 100644
--- a/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.modular.expect
@@ -238,20 +238,20 @@
 static get Extension|extensionStaticField() → core::int
   return self::_#Extension|extensionStaticField#isSet ?{core::int} let final core::int? #t23 = self::_#Extension|extensionStaticField in #t23{core::int} : throw new _in::LateError::fieldNI("extensionStaticField");
 @#C1
-static set Extension|extensionStaticField(core::int Extension|extensionStaticField#param) → void {
+static set Extension|extensionStaticField(core::int extensionStaticField#param) → void {
   self::_#Extension|extensionStaticField#isSet = true;
-  self::_#Extension|extensionStaticField = Extension|extensionStaticField#param;
+  self::_#Extension|extensionStaticField = extensionStaticField#param;
 }
 @#C1
 static get Extension|finalExtensionStaticField() → core::int
   return self::_#Extension|finalExtensionStaticField#isSet ?{core::int} let final core::int? #t24 = self::_#Extension|finalExtensionStaticField in #t24{core::int} : throw new _in::LateError::fieldNI("finalExtensionStaticField");
 @#C1
-static set Extension|finalExtensionStaticField(core::int Extension|finalExtensionStaticField#param) → void
+static set Extension|finalExtensionStaticField(core::int finalExtensionStaticField#param) → void
   if(self::_#Extension|finalExtensionStaticField#isSet)
     throw new _in::LateError::fieldAI("finalExtensionStaticField");
   else {
     self::_#Extension|finalExtensionStaticField#isSet = true;
-    self::_#Extension|finalExtensionStaticField = Extension|finalExtensionStaticField#param;
+    self::_#Extension|finalExtensionStaticField = finalExtensionStaticField#param;
   }
 @#C1
 static get Extension|finalExtensionStaticFieldWithInitializer() → core::int {
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.outline.expect
index 6f107ab..d0ada11 100644
--- a/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.outline.expect
@@ -127,11 +127,11 @@
 @self::Annotation::•()
 static get Extension|extensionStaticField() → core::int;
 @self::Annotation::•()
-static set Extension|extensionStaticField(core::int Extension|extensionStaticField#param) → void;
+static set Extension|extensionStaticField(core::int extensionStaticField#param) → void;
 @self::Annotation::•()
 static get Extension|finalExtensionStaticField() → core::int;
 @self::Annotation::•()
-static set Extension|finalExtensionStaticField(core::int Extension|finalExtensionStaticField#param) → void;
+static set Extension|finalExtensionStaticField(core::int finalExtensionStaticField#param) → void;
 @self::Annotation::•()
 static get Extension|finalExtensionStaticFieldWithInitializer() → core::int;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.transformed.expect
index c6d998f..2a97ef5 100644
--- a/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.transformed.expect
@@ -238,20 +238,20 @@
 static get Extension|extensionStaticField() → core::int
   return self::_#Extension|extensionStaticField#isSet ?{core::int} let final core::int? #t23 = self::_#Extension|extensionStaticField in #t23{core::int} : throw new _in::LateError::fieldNI("extensionStaticField");
 @#C1
-static set Extension|extensionStaticField(core::int Extension|extensionStaticField#param) → void {
+static set Extension|extensionStaticField(core::int extensionStaticField#param) → void {
   self::_#Extension|extensionStaticField#isSet = true;
-  self::_#Extension|extensionStaticField = Extension|extensionStaticField#param;
+  self::_#Extension|extensionStaticField = extensionStaticField#param;
 }
 @#C1
 static get Extension|finalExtensionStaticField() → core::int
   return self::_#Extension|finalExtensionStaticField#isSet ?{core::int} let final core::int? #t24 = self::_#Extension|finalExtensionStaticField in #t24{core::int} : throw new _in::LateError::fieldNI("finalExtensionStaticField");
 @#C1
-static set Extension|finalExtensionStaticField(core::int Extension|finalExtensionStaticField#param) → void
+static set Extension|finalExtensionStaticField(core::int finalExtensionStaticField#param) → void
   if(self::_#Extension|finalExtensionStaticField#isSet)
     throw new _in::LateError::fieldAI("finalExtensionStaticField");
   else {
     self::_#Extension|finalExtensionStaticField#isSet = true;
-    self::_#Extension|finalExtensionStaticField = Extension|finalExtensionStaticField#param;
+    self::_#Extension|finalExtensionStaticField = finalExtensionStaticField#param;
   }
 @#C1
 static get Extension|finalExtensionStaticFieldWithInitializer() → core::int {
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect
index da328ed..1aa5a22 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect
@@ -82,12 +82,12 @@
   self::_#lateTopLevelField1 = lateTopLevelField1#param;
 static get Extension|lateExtensionField1() → core::int
   return let final core::int? #t7 = self::_#Extension|lateExtensionField1 in #t7 == null ?{core::int} self::_#Extension|lateExtensionField1 = 87 : #t7{core::int};
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 static get Extension|lateExtensionField2() → core::int
   return let final core::int? #t8 = self::_#Extension|lateExtensionField2 in #t8 == null ?{core::int} self::_#Extension|lateExtensionField2 = 42 : #t8{core::int};
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 static method Extension|staticMethod() → dynamic {
   self::expect(42, self::Extension|lateExtensionField2);
   self::Extension|lateExtensionField2 = 43;
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect
index da328ed..1aa5a22 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect
@@ -82,12 +82,12 @@
   self::_#lateTopLevelField1 = lateTopLevelField1#param;
 static get Extension|lateExtensionField1() → core::int
   return let final core::int? #t7 = self::_#Extension|lateExtensionField1 in #t7 == null ?{core::int} self::_#Extension|lateExtensionField1 = 87 : #t7{core::int};
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 static get Extension|lateExtensionField2() → core::int
   return let final core::int? #t8 = self::_#Extension|lateExtensionField2 in #t8 == null ?{core::int} self::_#Extension|lateExtensionField2 = 42 : #t8{core::int};
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 static method Extension|staticMethod() → dynamic {
   self::expect(42, self::Extension|lateExtensionField2);
   self::Extension|lateExtensionField2 = 43;
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.expect
index 5d41a8a..c2741b96 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.expect
@@ -123,9 +123,9 @@
   }
   return let final core::int? #t7 = self::_#Extension|lateExtensionField1 in #t7{core::int};
 }
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int {
   if(!self::_#Extension|lateExtensionField2#isSet) {
@@ -134,9 +134,9 @@
   }
   return let final core::int? #t8 = self::_#Extension|lateExtensionField2 in #t8{core::int};
 }
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::expect(42, self::Extension|lateExtensionField2);
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.modular.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.modular.expect
index 5d41a8a..c2741b96 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.modular.expect
@@ -123,9 +123,9 @@
   }
   return let final core::int? #t7 = self::_#Extension|lateExtensionField1 in #t7{core::int};
 }
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int {
   if(!self::_#Extension|lateExtensionField2#isSet) {
@@ -134,9 +134,9 @@
   }
   return let final core::int? #t8 = self::_#Extension|lateExtensionField2 in #t8{core::int};
 }
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::expect(42, self::Extension|lateExtensionField2);
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.outline.expect
index d8734f1..b01151c 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.outline.expect
@@ -51,9 +51,9 @@
 static get lateTopLevelField1() → core::int;
 static set lateTopLevelField1(core::int lateTopLevelField1#param) → void;
 static get Extension|lateExtensionField1() → core::int;
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void;
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void;
 static get Extension|lateExtensionField2() → core::int;
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void;
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void;
 static method Extension|staticMethod() → dynamic
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.transformed.expect
index 5d41a8a..c2741b96 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.transformed.expect
@@ -123,9 +123,9 @@
   }
   return let final core::int? #t7 = self::_#Extension|lateExtensionField1 in #t7{core::int};
 }
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int {
   if(!self::_#Extension|lateExtensionField2#isSet) {
@@ -134,9 +134,9 @@
   }
   return let final core::int? #t8 = self::_#Extension|lateExtensionField2 in #t8{core::int};
 }
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::expect(42, self::Extension|lateExtensionField2);
diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.expect
index bb6521e..66acc73 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.expect
@@ -62,12 +62,12 @@
   self::_#lateTopLevelField = lateTopLevelField#param;
 static get Extension|lateExtensionField1() → core::int
   return let final core::int? #t6 = self::_#Extension|lateExtensionField1 in #t6 == null ?{core::int} throw new _in::LateError::fieldNI("lateExtensionField1") : #t6{core::int};
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 static get Extension|lateExtensionField2() → core::int
   return let final core::int? #t7 = self::_#Extension|lateExtensionField2 in #t7 == null ?{core::int} throw new _in::LateError::fieldNI("lateExtensionField2") : #t7{core::int};
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
   self::Extension|lateExtensionField2 = 42;
diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.transformed.expect
index bb6521e..66acc73 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.transformed.expect
@@ -62,12 +62,12 @@
   self::_#lateTopLevelField = lateTopLevelField#param;
 static get Extension|lateExtensionField1() → core::int
   return let final core::int? #t6 = self::_#Extension|lateExtensionField1 in #t6 == null ?{core::int} throw new _in::LateError::fieldNI("lateExtensionField1") : #t6{core::int};
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 static get Extension|lateExtensionField2() → core::int
   return let final core::int? #t7 = self::_#Extension|lateExtensionField2 in #t7 == null ?{core::int} throw new _in::LateError::fieldNI("lateExtensionField2") : #t7{core::int};
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
   self::Extension|lateExtensionField2 = 42;
diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.expect
index 57271db..ba73d5b 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.expect
@@ -78,15 +78,15 @@
 }
 static get Extension|lateExtensionField1() → core::int
   return self::_#Extension|lateExtensionField1#isSet ?{core::int} let final core::int? #t6 = self::_#Extension|lateExtensionField1 in #t6{core::int} : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int
   return self::_#Extension|lateExtensionField2#isSet ?{core::int} let final core::int? #t7 = self::_#Extension|lateExtensionField2 in #t7{core::int} : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.modular.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.modular.expect
index 57271db..ba73d5b 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.modular.expect
@@ -78,15 +78,15 @@
 }
 static get Extension|lateExtensionField1() → core::int
   return self::_#Extension|lateExtensionField1#isSet ?{core::int} let final core::int? #t6 = self::_#Extension|lateExtensionField1 in #t6{core::int} : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int
   return self::_#Extension|lateExtensionField2#isSet ?{core::int} let final core::int? #t7 = self::_#Extension|lateExtensionField2 in #t7{core::int} : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.outline.expect
index 808100e..1c11810 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.outline.expect
@@ -46,9 +46,9 @@
 static get lateTopLevelField() → core::int;
 static set lateTopLevelField(core::int lateTopLevelField#param) → void;
 static get Extension|lateExtensionField1() → core::int;
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void;
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void;
 static get Extension|lateExtensionField2() → core::int;
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void;
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void;
 static method Extension|staticMethod() → dynamic
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.transformed.expect
index 57271db..ba73d5b 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.weak.transformed.expect
@@ -78,15 +78,15 @@
 }
 static get Extension|lateExtensionField1() → core::int
   return self::_#Extension|lateExtensionField1#isSet ?{core::int} let final core::int? #t6 = self::_#Extension|lateExtensionField1 in #t6{core::int} : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int
   return self::_#Extension|lateExtensionField2#isSet ?{core::int} let final core::int? #t7 = self::_#Extension|lateExtensionField2 in #t7{core::int} : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.expect
index 207a31e..1604557 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.expect
@@ -65,16 +65,16 @@
     throw new _in::LateError::fieldAI("lateTopLevelField");
 static get Extension|lateExtensionField1() → core::int
   return let final core::int? #t5 = self::_#Extension|lateExtensionField1 in #t5 == null ?{core::int} throw new _in::LateError::fieldNI("lateExtensionField1") : #t5{core::int};
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void
   if(self::_#Extension|lateExtensionField1 == null)
-    self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+    self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
   else
     throw new _in::LateError::fieldAI("lateExtensionField1");
 static get Extension|lateExtensionField2() → core::int
   return let final core::int? #t6 = self::_#Extension|lateExtensionField2 in #t6 == null ?{core::int} throw new _in::LateError::fieldNI("lateExtensionField2") : #t6{core::int};
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void
   if(self::_#Extension|lateExtensionField2 == null)
-    self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+    self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
   else
     throw new _in::LateError::fieldAI("lateExtensionField2");
 static method Extension|staticMethod() → dynamic {
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.transformed.expect
index 207a31e..1604557 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.transformed.expect
@@ -65,16 +65,16 @@
     throw new _in::LateError::fieldAI("lateTopLevelField");
 static get Extension|lateExtensionField1() → core::int
   return let final core::int? #t5 = self::_#Extension|lateExtensionField1 in #t5 == null ?{core::int} throw new _in::LateError::fieldNI("lateExtensionField1") : #t5{core::int};
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void
   if(self::_#Extension|lateExtensionField1 == null)
-    self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+    self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
   else
     throw new _in::LateError::fieldAI("lateExtensionField1");
 static get Extension|lateExtensionField2() → core::int
   return let final core::int? #t6 = self::_#Extension|lateExtensionField2 in #t6 == null ?{core::int} throw new _in::LateError::fieldNI("lateExtensionField2") : #t6{core::int};
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void
   if(self::_#Extension|lateExtensionField2 == null)
-    self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+    self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
   else
     throw new _in::LateError::fieldAI("lateExtensionField2");
 static method Extension|staticMethod() → dynamic {
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.expect
index ab8252e..c92986c 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.expect
@@ -81,21 +81,21 @@
   }
 static get Extension|lateExtensionField1() → core::int
   return self::_#Extension|lateExtensionField1#isSet ?{core::int} let final core::int? #t5 = self::_#Extension|lateExtensionField1 in #t5{core::int} : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void
   if(self::_#Extension|lateExtensionField1#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField1");
   else {
     self::_#Extension|lateExtensionField1#isSet = true;
-    self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+    self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
   }
 static get Extension|lateExtensionField2() → core::int
   return self::_#Extension|lateExtensionField2#isSet ?{core::int} let final core::int? #t6 = self::_#Extension|lateExtensionField2 in #t6{core::int} : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void
   if(self::_#Extension|lateExtensionField2#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField2");
   else {
     self::_#Extension|lateExtensionField2#isSet = true;
-    self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+    self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
   }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.modular.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.modular.expect
index ab8252e..c92986c 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.modular.expect
@@ -81,21 +81,21 @@
   }
 static get Extension|lateExtensionField1() → core::int
   return self::_#Extension|lateExtensionField1#isSet ?{core::int} let final core::int? #t5 = self::_#Extension|lateExtensionField1 in #t5{core::int} : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void
   if(self::_#Extension|lateExtensionField1#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField1");
   else {
     self::_#Extension|lateExtensionField1#isSet = true;
-    self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+    self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
   }
 static get Extension|lateExtensionField2() → core::int
   return self::_#Extension|lateExtensionField2#isSet ?{core::int} let final core::int? #t6 = self::_#Extension|lateExtensionField2 in #t6{core::int} : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void
   if(self::_#Extension|lateExtensionField2#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField2");
   else {
     self::_#Extension|lateExtensionField2#isSet = true;
-    self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+    self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
   }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.outline.expect
index 3081907..718cac6 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.outline.expect
@@ -42,9 +42,9 @@
 static get lateTopLevelField() → core::int;
 static set lateTopLevelField(core::int lateTopLevelField#param) → void;
 static get Extension|lateExtensionField1() → core::int;
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void;
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void;
 static get Extension|lateExtensionField2() → core::int;
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void;
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void;
 static method Extension|staticMethod() → dynamic
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.transformed.expect
index ab8252e..c92986c 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.weak.transformed.expect
@@ -81,21 +81,21 @@
   }
 static get Extension|lateExtensionField1() → core::int
   return self::_#Extension|lateExtensionField1#isSet ?{core::int} let final core::int? #t5 = self::_#Extension|lateExtensionField1 in #t5{core::int} : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int Extension|lateExtensionField1#param) → void
+static set Extension|lateExtensionField1(core::int lateExtensionField1#param) → void
   if(self::_#Extension|lateExtensionField1#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField1");
   else {
     self::_#Extension|lateExtensionField1#isSet = true;
-    self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+    self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
   }
 static get Extension|lateExtensionField2() → core::int
   return self::_#Extension|lateExtensionField2#isSet ?{core::int} let final core::int? #t6 = self::_#Extension|lateExtensionField2 in #t6{core::int} : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int Extension|lateExtensionField2#param) → void
+static set Extension|lateExtensionField2(core::int lateExtensionField2#param) → void
   if(self::_#Extension|lateExtensionField2#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField2");
   else {
     self::_#Extension|lateExtensionField2#isSet = true;
-    self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+    self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
   }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.expect
index fb2d8d3..6794b26 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.expect
@@ -96,21 +96,21 @@
   }
 static get Extension|lateExtensionField1() → core::int?
   return self::_#Extension|lateExtensionField1#isSet ?{core::int?} self::_#Extension|lateExtensionField1 : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void
   if(self::_#Extension|lateExtensionField1#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField1");
   else {
     self::_#Extension|lateExtensionField1#isSet = true;
-    self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+    self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
   }
 static get Extension|lateExtensionField2() → core::int?
   return self::_#Extension|lateExtensionField2#isSet ?{core::int?} self::_#Extension|lateExtensionField2 : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void
   if(self::_#Extension|lateExtensionField2#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField2");
   else {
     self::_#Extension|lateExtensionField2#isSet = true;
-    self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+    self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
   }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int? => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.transformed.expect
index fb2d8d3..6794b26 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.transformed.expect
@@ -96,21 +96,21 @@
   }
 static get Extension|lateExtensionField1() → core::int?
   return self::_#Extension|lateExtensionField1#isSet ?{core::int?} self::_#Extension|lateExtensionField1 : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void
   if(self::_#Extension|lateExtensionField1#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField1");
   else {
     self::_#Extension|lateExtensionField1#isSet = true;
-    self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+    self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
   }
 static get Extension|lateExtensionField2() → core::int?
   return self::_#Extension|lateExtensionField2#isSet ?{core::int?} self::_#Extension|lateExtensionField2 : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void
   if(self::_#Extension|lateExtensionField2#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField2");
   else {
     self::_#Extension|lateExtensionField2#isSet = true;
-    self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+    self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
   }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int? => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.expect
index fb2d8d3..6794b26 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.expect
@@ -96,21 +96,21 @@
   }
 static get Extension|lateExtensionField1() → core::int?
   return self::_#Extension|lateExtensionField1#isSet ?{core::int?} self::_#Extension|lateExtensionField1 : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void
   if(self::_#Extension|lateExtensionField1#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField1");
   else {
     self::_#Extension|lateExtensionField1#isSet = true;
-    self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+    self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
   }
 static get Extension|lateExtensionField2() → core::int?
   return self::_#Extension|lateExtensionField2#isSet ?{core::int?} self::_#Extension|lateExtensionField2 : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void
   if(self::_#Extension|lateExtensionField2#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField2");
   else {
     self::_#Extension|lateExtensionField2#isSet = true;
-    self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+    self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
   }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int? => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.modular.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.modular.expect
index fb2d8d3..6794b26 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.modular.expect
@@ -96,21 +96,21 @@
   }
 static get Extension|lateExtensionField1() → core::int?
   return self::_#Extension|lateExtensionField1#isSet ?{core::int?} self::_#Extension|lateExtensionField1 : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void
   if(self::_#Extension|lateExtensionField1#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField1");
   else {
     self::_#Extension|lateExtensionField1#isSet = true;
-    self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+    self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
   }
 static get Extension|lateExtensionField2() → core::int?
   return self::_#Extension|lateExtensionField2#isSet ?{core::int?} self::_#Extension|lateExtensionField2 : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void
   if(self::_#Extension|lateExtensionField2#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField2");
   else {
     self::_#Extension|lateExtensionField2#isSet = true;
-    self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+    self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
   }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int? => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.outline.expect
index 96a8d71..37c4dc8 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.outline.expect
@@ -46,9 +46,9 @@
 static get lateTopLevelField() → core::int?;
 static set lateTopLevelField(core::int? lateTopLevelField#param) → void;
 static get Extension|lateExtensionField1() → core::int?;
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void;
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void;
 static get Extension|lateExtensionField2() → core::int?;
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void;
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void;
 static method Extension|staticMethod() → dynamic
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.transformed.expect
index fb2d8d3..6794b26 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.weak.transformed.expect
@@ -96,21 +96,21 @@
   }
 static get Extension|lateExtensionField1() → core::int?
   return self::_#Extension|lateExtensionField1#isSet ?{core::int?} self::_#Extension|lateExtensionField1 : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void
   if(self::_#Extension|lateExtensionField1#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField1");
   else {
     self::_#Extension|lateExtensionField1#isSet = true;
-    self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+    self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
   }
 static get Extension|lateExtensionField2() → core::int?
   return self::_#Extension|lateExtensionField2#isSet ?{core::int?} self::_#Extension|lateExtensionField2 : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void
   if(self::_#Extension|lateExtensionField2#isSet)
     throw new _in::LateError::fieldAI("lateExtensionField2");
   else {
     self::_#Extension|lateExtensionField2#isSet = true;
-    self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+    self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
   }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int? => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect
index 6af11b6..245c0c0 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect
@@ -122,9 +122,9 @@
   }
   return self::_#Extension|lateExtensionField1;
 }
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static method Extension|lateExtensionField2Init() → core::int?
   return 42;
@@ -135,9 +135,9 @@
   }
   return self::_#Extension|lateExtensionField2;
 }
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::expect(42, self::Extension|lateExtensionField2);
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect
index 6af11b6..245c0c0 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect
@@ -122,9 +122,9 @@
   }
   return self::_#Extension|lateExtensionField1;
 }
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static method Extension|lateExtensionField2Init() → core::int?
   return 42;
@@ -135,9 +135,9 @@
   }
   return self::_#Extension|lateExtensionField2;
 }
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::expect(42, self::Extension|lateExtensionField2);
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.expect
index 6af11b6..245c0c0 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.expect
@@ -122,9 +122,9 @@
   }
   return self::_#Extension|lateExtensionField1;
 }
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static method Extension|lateExtensionField2Init() → core::int?
   return 42;
@@ -135,9 +135,9 @@
   }
   return self::_#Extension|lateExtensionField2;
 }
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::expect(42, self::Extension|lateExtensionField2);
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.modular.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.modular.expect
index 6af11b6..245c0c0 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.modular.expect
@@ -122,9 +122,9 @@
   }
   return self::_#Extension|lateExtensionField1;
 }
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static method Extension|lateExtensionField2Init() → core::int?
   return 42;
@@ -135,9 +135,9 @@
   }
   return self::_#Extension|lateExtensionField2;
 }
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::expect(42, self::Extension|lateExtensionField2);
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.outline.expect
index c2d9df2..60fbdd2 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.outline.expect
@@ -61,11 +61,11 @@
 static method Extension|lateExtensionField1Init() → core::int?
   ;
 static get Extension|lateExtensionField1() → core::int?;
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void;
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void;
 static method Extension|lateExtensionField2Init() → core::int?
   ;
 static get Extension|lateExtensionField2() → core::int?;
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void;
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void;
 static method Extension|staticMethod() → dynamic
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.transformed.expect
index 6af11b6..245c0c0 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.transformed.expect
@@ -122,9 +122,9 @@
   }
   return self::_#Extension|lateExtensionField1;
 }
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static method Extension|lateExtensionField2Init() → core::int?
   return 42;
@@ -135,9 +135,9 @@
   }
   return self::_#Extension|lateExtensionField2;
 }
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::expect(42, self::Extension|lateExtensionField2);
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.expect
index e2d2b39..c212d4b 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.expect
@@ -78,15 +78,15 @@
 }
 static get Extension|lateExtensionField1() → core::int?
   return self::_#Extension|lateExtensionField1#isSet ?{core::int?} self::_#Extension|lateExtensionField1 : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int?
   return self::_#Extension|lateExtensionField2#isSet ?{core::int?} self::_#Extension|lateExtensionField2 : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int? => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.transformed.expect
index e2d2b39..c212d4b 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.transformed.expect
@@ -78,15 +78,15 @@
 }
 static get Extension|lateExtensionField1() → core::int?
   return self::_#Extension|lateExtensionField1#isSet ?{core::int?} self::_#Extension|lateExtensionField1 : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int?
   return self::_#Extension|lateExtensionField2#isSet ?{core::int?} self::_#Extension|lateExtensionField2 : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int? => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.expect
index e2d2b39..c212d4b 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.expect
@@ -78,15 +78,15 @@
 }
 static get Extension|lateExtensionField1() → core::int?
   return self::_#Extension|lateExtensionField1#isSet ?{core::int?} self::_#Extension|lateExtensionField1 : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int?
   return self::_#Extension|lateExtensionField2#isSet ?{core::int?} self::_#Extension|lateExtensionField2 : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int? => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.modular.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.modular.expect
index e2d2b39..c212d4b 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.modular.expect
@@ -78,15 +78,15 @@
 }
 static get Extension|lateExtensionField1() → core::int?
   return self::_#Extension|lateExtensionField1#isSet ?{core::int?} self::_#Extension|lateExtensionField1 : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int?
   return self::_#Extension|lateExtensionField2#isSet ?{core::int?} self::_#Extension|lateExtensionField2 : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int? => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.outline.expect
index daef161..8d53a49 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.outline.expect
@@ -46,9 +46,9 @@
 static get lateTopLevelField() → core::int?;
 static set lateTopLevelField(core::int? lateTopLevelField#param) → void;
 static get Extension|lateExtensionField1() → core::int?;
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void;
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void;
 static get Extension|lateExtensionField2() → core::int?;
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void;
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void;
 static method Extension|staticMethod() → dynamic
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.transformed.expect
index e2d2b39..c212d4b 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.weak.transformed.expect
@@ -78,15 +78,15 @@
 }
 static get Extension|lateExtensionField1() → core::int?
   return self::_#Extension|lateExtensionField1#isSet ?{core::int?} self::_#Extension|lateExtensionField1 : throw new _in::LateError::fieldNI("lateExtensionField1");
-static set Extension|lateExtensionField1(core::int? Extension|lateExtensionField1#param) → void {
+static set Extension|lateExtensionField1(core::int? lateExtensionField1#param) → void {
   self::_#Extension|lateExtensionField1#isSet = true;
-  self::_#Extension|lateExtensionField1 = Extension|lateExtensionField1#param;
+  self::_#Extension|lateExtensionField1 = lateExtensionField1#param;
 }
 static get Extension|lateExtensionField2() → core::int?
   return self::_#Extension|lateExtensionField2#isSet ?{core::int?} self::_#Extension|lateExtensionField2 : throw new _in::LateError::fieldNI("lateExtensionField2");
-static set Extension|lateExtensionField2(core::int? Extension|lateExtensionField2#param) → void {
+static set Extension|lateExtensionField2(core::int? lateExtensionField2#param) → void {
   self::_#Extension|lateExtensionField2#isSet = true;
-  self::_#Extension|lateExtensionField2 = Extension|lateExtensionField2#param;
+  self::_#Extension|lateExtensionField2 = lateExtensionField2#param;
 }
 static method Extension|staticMethod() → dynamic {
   self::throws(() → core::int? => self::Extension|lateExtensionField2, "Read value from uninitialized Class.lateExtensionField2");
diff --git a/pkg/front_end/testcases/late_lowering/private_members.dart.strong.expect b/pkg/front_end/testcases/late_lowering/private_members.dart.strong.expect
index 4a3aa95..5c5aca9 100644
--- a/pkg/front_end/testcases/late_lowering/private_members.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/private_members.dart.strong.expect
@@ -15,8 +15,8 @@
     ;
   get _privateField1() → core::int
     return let final core::int? #t1 = this.{self::_Class::_#_Class#_privateField1}{core::int?} in #t1 == null ?{core::int} this.{self::_Class::_#_Class#_privateField1} = 1 : #t1{core::int};
-  set _privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateField1#param) → void
-    this.{self::_Class::_#_Class#_privateField1} = library org-dartlang-testcase:///private_members_part.dart::_privateField1#param;
+  set _privateField1(core::int _privateField1#param) → void
+    this.{self::_Class::_#_Class#_privateField1} = _privateField1#param;
   get _privateField2() → core::int? {
     if(!this.{self::_Class::_#_Class#_privateField2#isSet}{core::bool}) {
       this.{self::_Class::_#_Class#_privateField2} = 1;
@@ -24,14 +24,14 @@
     }
     return this.{self::_Class::_#_Class#_privateField2}{core::int?};
   }
-  set _privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateField2#param) → void {
+  set _privateField2(core::int? _privateField2#param) → void {
     this.{self::_Class::_#_Class#_privateField2#isSet} = true;
-    this.{self::_Class::_#_Class#_privateField2} = library org-dartlang-testcase:///private_members_part.dart::_privateField2#param;
+    this.{self::_Class::_#_Class#_privateField2} = _privateField2#param;
   }
   get _privateFinalField1() → core::int
     return let final core::int? #t2 = this.{self::_Class::_#_Class#_privateFinalField1}{core::int?} in #t2 == null ?{core::int} this.{self::_Class::_#_Class#_privateFinalField1} = 1 : #t2{core::int};
-  set _privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param) → void
-    this.{self::_Class::_#_Class#_privateFinalField1} = library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param;
+  set _privateFinalField1(core::int _privateFinalField1#param) → void
+    this.{self::_Class::_#_Class#_privateFinalField1} = _privateFinalField1#param;
   get _privateFinalField2() → core::int? {
     if(!this.{self::_Class::_#_Class#_privateFinalField2#isSet}{core::bool}) {
       this.{self::_Class::_#_Class#_privateFinalField2} = 1;
@@ -39,9 +39,9 @@
     }
     return this.{self::_Class::_#_Class#_privateFinalField2}{core::int?};
   }
-  set _privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param) → void {
+  set _privateFinalField2(core::int? _privateFinalField2#param) → void {
     this.{self::_Class::_#_Class#_privateFinalField2#isSet} = true;
-    this.{self::_Class::_#_Class#_privateFinalField2} = library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param;
+    this.{self::_Class::_#_Class#_privateFinalField2} = _privateFinalField2#param;
   }
 }
 extension _Extension on core::int { // from org-dartlang-testcase:///private_members_part.dart
@@ -79,8 +79,8 @@
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1() → core::int
   return let final core::int? #t3 = self::_#_Extension|_privateField1 in #t3 == null ?{core::int} self::_#_Extension|_privateField1 = 1 : #t3{core::int};
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param) → void
-  self::_#_Extension|_privateField1 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param;
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int _privateField1#param) → void
+  self::_#_Extension|_privateField1 = _privateField1#param;
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2() → core::int? {
   if(!self::_#_Extension|_privateField2#isSet) {
     self::_#_Extension|_privateField2 = 1;
@@ -88,14 +88,14 @@
   }
   return self::_#_Extension|_privateField2;
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? _privateField2#param) → void {
   self::_#_Extension|_privateField2#isSet = true;
-  self::_#_Extension|_privateField2 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param;
+  self::_#_Extension|_privateField2 = _privateField2#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1() → core::int
   return let final core::int? #t4 = self::_#_Extension|_privateFinalField1 in #t4 == null ?{core::int} self::_#_Extension|_privateFinalField1 = 1 : #t4{core::int};
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param) → void
-  self::_#_Extension|_privateFinalField1 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param;
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int _privateFinalField1#param) → void
+  self::_#_Extension|_privateFinalField1 = _privateFinalField1#param;
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2() → core::int? {
   if(!self::_#_Extension|_privateFinalField2#isSet) {
     self::_#_Extension|_privateFinalField2 = 1;
@@ -103,7 +103,7 @@
   }
   return self::_#_Extension|_privateFinalField2;
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? _privateFinalField2#param) → void {
   self::_#_Extension|_privateFinalField2#isSet = true;
-  self::_#_Extension|_privateFinalField2 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param;
+  self::_#_Extension|_privateFinalField2 = _privateFinalField2#param;
 }
diff --git a/pkg/front_end/testcases/late_lowering/private_members.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/private_members.dart.strong.transformed.expect
index 4a3aa95..5c5aca9 100644
--- a/pkg/front_end/testcases/late_lowering/private_members.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/private_members.dart.strong.transformed.expect
@@ -15,8 +15,8 @@
     ;
   get _privateField1() → core::int
     return let final core::int? #t1 = this.{self::_Class::_#_Class#_privateField1}{core::int?} in #t1 == null ?{core::int} this.{self::_Class::_#_Class#_privateField1} = 1 : #t1{core::int};
-  set _privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateField1#param) → void
-    this.{self::_Class::_#_Class#_privateField1} = library org-dartlang-testcase:///private_members_part.dart::_privateField1#param;
+  set _privateField1(core::int _privateField1#param) → void
+    this.{self::_Class::_#_Class#_privateField1} = _privateField1#param;
   get _privateField2() → core::int? {
     if(!this.{self::_Class::_#_Class#_privateField2#isSet}{core::bool}) {
       this.{self::_Class::_#_Class#_privateField2} = 1;
@@ -24,14 +24,14 @@
     }
     return this.{self::_Class::_#_Class#_privateField2}{core::int?};
   }
-  set _privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateField2#param) → void {
+  set _privateField2(core::int? _privateField2#param) → void {
     this.{self::_Class::_#_Class#_privateField2#isSet} = true;
-    this.{self::_Class::_#_Class#_privateField2} = library org-dartlang-testcase:///private_members_part.dart::_privateField2#param;
+    this.{self::_Class::_#_Class#_privateField2} = _privateField2#param;
   }
   get _privateFinalField1() → core::int
     return let final core::int? #t2 = this.{self::_Class::_#_Class#_privateFinalField1}{core::int?} in #t2 == null ?{core::int} this.{self::_Class::_#_Class#_privateFinalField1} = 1 : #t2{core::int};
-  set _privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param) → void
-    this.{self::_Class::_#_Class#_privateFinalField1} = library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param;
+  set _privateFinalField1(core::int _privateFinalField1#param) → void
+    this.{self::_Class::_#_Class#_privateFinalField1} = _privateFinalField1#param;
   get _privateFinalField2() → core::int? {
     if(!this.{self::_Class::_#_Class#_privateFinalField2#isSet}{core::bool}) {
       this.{self::_Class::_#_Class#_privateFinalField2} = 1;
@@ -39,9 +39,9 @@
     }
     return this.{self::_Class::_#_Class#_privateFinalField2}{core::int?};
   }
-  set _privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param) → void {
+  set _privateFinalField2(core::int? _privateFinalField2#param) → void {
     this.{self::_Class::_#_Class#_privateFinalField2#isSet} = true;
-    this.{self::_Class::_#_Class#_privateFinalField2} = library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param;
+    this.{self::_Class::_#_Class#_privateFinalField2} = _privateFinalField2#param;
   }
 }
 extension _Extension on core::int { // from org-dartlang-testcase:///private_members_part.dart
@@ -79,8 +79,8 @@
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1() → core::int
   return let final core::int? #t3 = self::_#_Extension|_privateField1 in #t3 == null ?{core::int} self::_#_Extension|_privateField1 = 1 : #t3{core::int};
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param) → void
-  self::_#_Extension|_privateField1 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param;
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int _privateField1#param) → void
+  self::_#_Extension|_privateField1 = _privateField1#param;
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2() → core::int? {
   if(!self::_#_Extension|_privateField2#isSet) {
     self::_#_Extension|_privateField2 = 1;
@@ -88,14 +88,14 @@
   }
   return self::_#_Extension|_privateField2;
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? _privateField2#param) → void {
   self::_#_Extension|_privateField2#isSet = true;
-  self::_#_Extension|_privateField2 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param;
+  self::_#_Extension|_privateField2 = _privateField2#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1() → core::int
   return let final core::int? #t4 = self::_#_Extension|_privateFinalField1 in #t4 == null ?{core::int} self::_#_Extension|_privateFinalField1 = 1 : #t4{core::int};
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param) → void
-  self::_#_Extension|_privateFinalField1 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param;
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int _privateFinalField1#param) → void
+  self::_#_Extension|_privateFinalField1 = _privateFinalField1#param;
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2() → core::int? {
   if(!self::_#_Extension|_privateFinalField2#isSet) {
     self::_#_Extension|_privateFinalField2 = 1;
@@ -103,7 +103,7 @@
   }
   return self::_#_Extension|_privateFinalField2;
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? _privateFinalField2#param) → void {
   self::_#_Extension|_privateFinalField2#isSet = true;
-  self::_#_Extension|_privateFinalField2 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param;
+  self::_#_Extension|_privateFinalField2 = _privateFinalField2#param;
 }
diff --git a/pkg/front_end/testcases/late_lowering/private_members.dart.weak.expect b/pkg/front_end/testcases/late_lowering/private_members.dart.weak.expect
index 97f7725..ebc8eed 100644
--- a/pkg/front_end/testcases/late_lowering/private_members.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/private_members.dart.weak.expect
@@ -22,9 +22,9 @@
     }
     return let final core::int? #t1 = this.{self::_Class::_#_Class#_privateField1}{core::int?} in #t1{core::int};
   }
-  set _privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateField1#param) → void {
+  set _privateField1(core::int _privateField1#param) → void {
     this.{self::_Class::_#_Class#_privateField1#isSet} = true;
-    this.{self::_Class::_#_Class#_privateField1} = library org-dartlang-testcase:///private_members_part.dart::_privateField1#param;
+    this.{self::_Class::_#_Class#_privateField1} = _privateField1#param;
   }
   get _privateField2() → core::int? {
     if(!this.{self::_Class::_#_Class#_privateField2#isSet}{core::bool}) {
@@ -33,9 +33,9 @@
     }
     return this.{self::_Class::_#_Class#_privateField2}{core::int?};
   }
-  set _privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateField2#param) → void {
+  set _privateField2(core::int? _privateField2#param) → void {
     this.{self::_Class::_#_Class#_privateField2#isSet} = true;
-    this.{self::_Class::_#_Class#_privateField2} = library org-dartlang-testcase:///private_members_part.dart::_privateField2#param;
+    this.{self::_Class::_#_Class#_privateField2} = _privateField2#param;
   }
   get _privateFinalField1() → core::int {
     if(!this.{self::_Class::_#_Class#_privateFinalField1#isSet}{core::bool}) {
@@ -44,9 +44,9 @@
     }
     return let final core::int? #t2 = this.{self::_Class::_#_Class#_privateFinalField1}{core::int?} in #t2{core::int};
   }
-  set _privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param) → void {
+  set _privateFinalField1(core::int _privateFinalField1#param) → void {
     this.{self::_Class::_#_Class#_privateFinalField1#isSet} = true;
-    this.{self::_Class::_#_Class#_privateFinalField1} = library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param;
+    this.{self::_Class::_#_Class#_privateFinalField1} = _privateFinalField1#param;
   }
   get _privateFinalField2() → core::int? {
     if(!this.{self::_Class::_#_Class#_privateFinalField2#isSet}{core::bool}) {
@@ -55,9 +55,9 @@
     }
     return this.{self::_Class::_#_Class#_privateFinalField2}{core::int?};
   }
-  set _privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param) → void {
+  set _privateFinalField2(core::int? _privateFinalField2#param) → void {
     this.{self::_Class::_#_Class#_privateFinalField2#isSet} = true;
-    this.{self::_Class::_#_Class#_privateFinalField2} = library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param;
+    this.{self::_Class::_#_Class#_privateFinalField2} = _privateFinalField2#param;
   }
 }
 extension _Extension on core::int { // from org-dartlang-testcase:///private_members_part.dart
@@ -104,9 +104,9 @@
   }
   return let final core::int? #t3 = self::_#_Extension|_privateField1 in #t3{core::int};
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int _privateField1#param) → void {
   self::_#_Extension|_privateField1#isSet = true;
-  self::_#_Extension|_privateField1 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param;
+  self::_#_Extension|_privateField1 = _privateField1#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2() → core::int? {
   if(!self::_#_Extension|_privateField2#isSet) {
@@ -115,9 +115,9 @@
   }
   return self::_#_Extension|_privateField2;
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? _privateField2#param) → void {
   self::_#_Extension|_privateField2#isSet = true;
-  self::_#_Extension|_privateField2 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param;
+  self::_#_Extension|_privateField2 = _privateField2#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1() → core::int {
   if(!self::_#_Extension|_privateFinalField1#isSet) {
@@ -126,9 +126,9 @@
   }
   return let final core::int? #t4 = self::_#_Extension|_privateFinalField1 in #t4{core::int};
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int _privateFinalField1#param) → void {
   self::_#_Extension|_privateFinalField1#isSet = true;
-  self::_#_Extension|_privateFinalField1 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param;
+  self::_#_Extension|_privateFinalField1 = _privateFinalField1#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2() → core::int? {
   if(!self::_#_Extension|_privateFinalField2#isSet) {
@@ -137,7 +137,7 @@
   }
   return self::_#_Extension|_privateFinalField2;
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? _privateFinalField2#param) → void {
   self::_#_Extension|_privateFinalField2#isSet = true;
-  self::_#_Extension|_privateFinalField2 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param;
+  self::_#_Extension|_privateFinalField2 = _privateFinalField2#param;
 }
diff --git a/pkg/front_end/testcases/late_lowering/private_members.dart.weak.modular.expect b/pkg/front_end/testcases/late_lowering/private_members.dart.weak.modular.expect
index 97f7725..ebc8eed 100644
--- a/pkg/front_end/testcases/late_lowering/private_members.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/late_lowering/private_members.dart.weak.modular.expect
@@ -22,9 +22,9 @@
     }
     return let final core::int? #t1 = this.{self::_Class::_#_Class#_privateField1}{core::int?} in #t1{core::int};
   }
-  set _privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateField1#param) → void {
+  set _privateField1(core::int _privateField1#param) → void {
     this.{self::_Class::_#_Class#_privateField1#isSet} = true;
-    this.{self::_Class::_#_Class#_privateField1} = library org-dartlang-testcase:///private_members_part.dart::_privateField1#param;
+    this.{self::_Class::_#_Class#_privateField1} = _privateField1#param;
   }
   get _privateField2() → core::int? {
     if(!this.{self::_Class::_#_Class#_privateField2#isSet}{core::bool}) {
@@ -33,9 +33,9 @@
     }
     return this.{self::_Class::_#_Class#_privateField2}{core::int?};
   }
-  set _privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateField2#param) → void {
+  set _privateField2(core::int? _privateField2#param) → void {
     this.{self::_Class::_#_Class#_privateField2#isSet} = true;
-    this.{self::_Class::_#_Class#_privateField2} = library org-dartlang-testcase:///private_members_part.dart::_privateField2#param;
+    this.{self::_Class::_#_Class#_privateField2} = _privateField2#param;
   }
   get _privateFinalField1() → core::int {
     if(!this.{self::_Class::_#_Class#_privateFinalField1#isSet}{core::bool}) {
@@ -44,9 +44,9 @@
     }
     return let final core::int? #t2 = this.{self::_Class::_#_Class#_privateFinalField1}{core::int?} in #t2{core::int};
   }
-  set _privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param) → void {
+  set _privateFinalField1(core::int _privateFinalField1#param) → void {
     this.{self::_Class::_#_Class#_privateFinalField1#isSet} = true;
-    this.{self::_Class::_#_Class#_privateFinalField1} = library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param;
+    this.{self::_Class::_#_Class#_privateFinalField1} = _privateFinalField1#param;
   }
   get _privateFinalField2() → core::int? {
     if(!this.{self::_Class::_#_Class#_privateFinalField2#isSet}{core::bool}) {
@@ -55,9 +55,9 @@
     }
     return this.{self::_Class::_#_Class#_privateFinalField2}{core::int?};
   }
-  set _privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param) → void {
+  set _privateFinalField2(core::int? _privateFinalField2#param) → void {
     this.{self::_Class::_#_Class#_privateFinalField2#isSet} = true;
-    this.{self::_Class::_#_Class#_privateFinalField2} = library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param;
+    this.{self::_Class::_#_Class#_privateFinalField2} = _privateFinalField2#param;
   }
 }
 extension _Extension on core::int { // from org-dartlang-testcase:///private_members_part.dart
@@ -104,9 +104,9 @@
   }
   return let final core::int? #t3 = self::_#_Extension|_privateField1 in #t3{core::int};
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int _privateField1#param) → void {
   self::_#_Extension|_privateField1#isSet = true;
-  self::_#_Extension|_privateField1 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param;
+  self::_#_Extension|_privateField1 = _privateField1#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2() → core::int? {
   if(!self::_#_Extension|_privateField2#isSet) {
@@ -115,9 +115,9 @@
   }
   return self::_#_Extension|_privateField2;
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? _privateField2#param) → void {
   self::_#_Extension|_privateField2#isSet = true;
-  self::_#_Extension|_privateField2 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param;
+  self::_#_Extension|_privateField2 = _privateField2#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1() → core::int {
   if(!self::_#_Extension|_privateFinalField1#isSet) {
@@ -126,9 +126,9 @@
   }
   return let final core::int? #t4 = self::_#_Extension|_privateFinalField1 in #t4{core::int};
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int _privateFinalField1#param) → void {
   self::_#_Extension|_privateFinalField1#isSet = true;
-  self::_#_Extension|_privateFinalField1 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param;
+  self::_#_Extension|_privateFinalField1 = _privateFinalField1#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2() → core::int? {
   if(!self::_#_Extension|_privateFinalField2#isSet) {
@@ -137,7 +137,7 @@
   }
   return self::_#_Extension|_privateFinalField2;
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? _privateFinalField2#param) → void {
   self::_#_Extension|_privateFinalField2#isSet = true;
-  self::_#_Extension|_privateFinalField2 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param;
+  self::_#_Extension|_privateFinalField2 = _privateFinalField2#param;
 }
diff --git a/pkg/front_end/testcases/late_lowering/private_members.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/private_members.dart.weak.outline.expect
index 2d4f5abd..cd2e0ec 100644
--- a/pkg/front_end/testcases/late_lowering/private_members.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/private_members.dart.weak.outline.expect
@@ -15,13 +15,13 @@
   synthetic constructor •() → self::_Class
     ;
   get _privateField1() → core::int;
-  set _privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateField1#param) → void;
+  set _privateField1(core::int _privateField1#param) → void;
   get _privateField2() → core::int?;
-  set _privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateField2#param) → void;
+  set _privateField2(core::int? _privateField2#param) → void;
   get _privateFinalField1() → core::int;
-  set _privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param) → void;
+  set _privateFinalField1(core::int _privateFinalField1#param) → void;
   get _privateFinalField2() → core::int?;
-  set _privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param) → void;
+  set _privateFinalField2(core::int? _privateFinalField2#param) → void;
 }
 extension _Extension on core::int { // from org-dartlang-testcase:///private_members_part.dart
   static field _privateField1 = self::_#_Extension|_privateField1;
@@ -52,10 +52,10 @@
 static method main() → dynamic
   ;
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1() → core::int;
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param) → void;
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int _privateField1#param) → void;
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2() → core::int?;
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param) → void;
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? _privateField2#param) → void;
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1() → core::int;
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param) → void;
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int _privateFinalField1#param) → void;
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2() → core::int?;
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param) → void;
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? _privateFinalField2#param) → void;
diff --git a/pkg/front_end/testcases/late_lowering/private_members.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/private_members.dart.weak.transformed.expect
index 97f7725..ebc8eed 100644
--- a/pkg/front_end/testcases/late_lowering/private_members.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/private_members.dart.weak.transformed.expect
@@ -22,9 +22,9 @@
     }
     return let final core::int? #t1 = this.{self::_Class::_#_Class#_privateField1}{core::int?} in #t1{core::int};
   }
-  set _privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateField1#param) → void {
+  set _privateField1(core::int _privateField1#param) → void {
     this.{self::_Class::_#_Class#_privateField1#isSet} = true;
-    this.{self::_Class::_#_Class#_privateField1} = library org-dartlang-testcase:///private_members_part.dart::_privateField1#param;
+    this.{self::_Class::_#_Class#_privateField1} = _privateField1#param;
   }
   get _privateField2() → core::int? {
     if(!this.{self::_Class::_#_Class#_privateField2#isSet}{core::bool}) {
@@ -33,9 +33,9 @@
     }
     return this.{self::_Class::_#_Class#_privateField2}{core::int?};
   }
-  set _privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateField2#param) → void {
+  set _privateField2(core::int? _privateField2#param) → void {
     this.{self::_Class::_#_Class#_privateField2#isSet} = true;
-    this.{self::_Class::_#_Class#_privateField2} = library org-dartlang-testcase:///private_members_part.dart::_privateField2#param;
+    this.{self::_Class::_#_Class#_privateField2} = _privateField2#param;
   }
   get _privateFinalField1() → core::int {
     if(!this.{self::_Class::_#_Class#_privateFinalField1#isSet}{core::bool}) {
@@ -44,9 +44,9 @@
     }
     return let final core::int? #t2 = this.{self::_Class::_#_Class#_privateFinalField1}{core::int?} in #t2{core::int};
   }
-  set _privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param) → void {
+  set _privateFinalField1(core::int _privateFinalField1#param) → void {
     this.{self::_Class::_#_Class#_privateFinalField1#isSet} = true;
-    this.{self::_Class::_#_Class#_privateFinalField1} = library org-dartlang-testcase:///private_members_part.dart::_privateFinalField1#param;
+    this.{self::_Class::_#_Class#_privateFinalField1} = _privateFinalField1#param;
   }
   get _privateFinalField2() → core::int? {
     if(!this.{self::_Class::_#_Class#_privateFinalField2#isSet}{core::bool}) {
@@ -55,9 +55,9 @@
     }
     return this.{self::_Class::_#_Class#_privateFinalField2}{core::int?};
   }
-  set _privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param) → void {
+  set _privateFinalField2(core::int? _privateFinalField2#param) → void {
     this.{self::_Class::_#_Class#_privateFinalField2#isSet} = true;
-    this.{self::_Class::_#_Class#_privateFinalField2} = library org-dartlang-testcase:///private_members_part.dart::_privateFinalField2#param;
+    this.{self::_Class::_#_Class#_privateFinalField2} = _privateFinalField2#param;
   }
 }
 extension _Extension on core::int { // from org-dartlang-testcase:///private_members_part.dart
@@ -104,9 +104,9 @@
   }
   return let final core::int? #t3 = self::_#_Extension|_privateField1 in #t3{core::int};
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField1(core::int _privateField1#param) → void {
   self::_#_Extension|_privateField1#isSet = true;
-  self::_#_Extension|_privateField1 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField1#param;
+  self::_#_Extension|_privateField1 = _privateField1#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2() → core::int? {
   if(!self::_#_Extension|_privateField2#isSet) {
@@ -115,9 +115,9 @@
   }
   return self::_#_Extension|_privateField2;
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateField2(core::int? _privateField2#param) → void {
   self::_#_Extension|_privateField2#isSet = true;
-  self::_#_Extension|_privateField2 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateField2#param;
+  self::_#_Extension|_privateField2 = _privateField2#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1() → core::int {
   if(!self::_#_Extension|_privateFinalField1#isSet) {
@@ -126,9 +126,9 @@
   }
   return let final core::int? #t4 = self::_#_Extension|_privateFinalField1 in #t4{core::int};
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField1(core::int _privateFinalField1#param) → void {
   self::_#_Extension|_privateFinalField1#isSet = true;
-  self::_#_Extension|_privateFinalField1 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField1#param;
+  self::_#_Extension|_privateFinalField1 = _privateFinalField1#param;
 }
 static get /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2() → core::int? {
   if(!self::_#_Extension|_privateFinalField2#isSet) {
@@ -137,7 +137,7 @@
   }
   return self::_#_Extension|_privateFinalField2;
 }
-static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param) → void {
+static set /* from org-dartlang-testcase:///private_members_part.dart */ _Extension|_privateFinalField2(core::int? _privateFinalField2#param) → void {
   self::_#_Extension|_privateFinalField2#isSet = true;
-  self::_#_Extension|_privateFinalField2 = library org-dartlang-testcase:///private_members_part.dart::_Extension|_privateFinalField2#param;
+  self::_#_Extension|_privateFinalField2 = _privateFinalField2#param;
 }
diff --git a/pkg/front_end/testcases/macros/duplicate_augment.dart b/pkg/front_end/testcases/macros/duplicate_augment.dart
new file mode 100644
index 0000000..9f19520
--- /dev/null
+++ b/pkg/front_end/testcases/macros/duplicate_augment.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, 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 augment 'duplicate_augment_lib.dart';
+
+void augmentedTopLevelMethod() {}
+
+class AugmentedClass {
+  void augmentedInstanceMethod() {}
+  static void augmentedStaticMethod() {}
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/macros/duplicate_augment.dart.strong.expect b/pkg/front_end/testcases/macros/duplicate_augment.dart.strong.expect
new file mode 100644
index 0000000..79663e1
--- /dev/null
+++ b/pkg/front_end/testcases/macros/duplicate_augment.dart.strong.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:9:14: Error: 'augmentedTopLevelMethod' is already declared in this scope.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:5:14: Context: Previous declaration of 'augmentedTopLevelMethod'.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:22:15: Error: 'AugmentedClass' is already declared in this scope.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:13:15: Context: Previous declaration of 'AugmentedClass'.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///duplicate_augment.dart";
+
+class AugmentedClass#1#1 extends core::Object { // from org-dartlang-testcase:///duplicate_augment_lib.dart
+  synthetic constructor •() → self::AugmentedClass#1#1
+    : super core::Object::•()
+    ;
+  method augmentedInstanceMethod() → void {
+    core::print("augmentedInstanceMethod#2");
+  }
+  static method augmentedStaticMethod() → void {
+    core::print("augmentedStaticMethod#2");
+  }
+}
+class AugmentedClass extends core::Object {
+  synthetic constructor •() → self::AugmentedClass
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedInstanceMethod() → void {
+    core::print("augmentedInstanceMethod#1");
+  }
+  static method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedStaticMethod() → void {
+    core::print("augmentedStaticMethod#1");
+  }
+}
+static method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedTopLevelMethod() → void {
+  core::print("augmentedTopLevelMethod#1");
+}
diff --git a/pkg/front_end/testcases/macros/duplicate_augment.dart.strong.transformed.expect b/pkg/front_end/testcases/macros/duplicate_augment.dart.strong.transformed.expect
new file mode 100644
index 0000000..79663e1
--- /dev/null
+++ b/pkg/front_end/testcases/macros/duplicate_augment.dart.strong.transformed.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:9:14: Error: 'augmentedTopLevelMethod' is already declared in this scope.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:5:14: Context: Previous declaration of 'augmentedTopLevelMethod'.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:22:15: Error: 'AugmentedClass' is already declared in this scope.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:13:15: Context: Previous declaration of 'AugmentedClass'.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///duplicate_augment.dart";
+
+class AugmentedClass#1#1 extends core::Object { // from org-dartlang-testcase:///duplicate_augment_lib.dart
+  synthetic constructor •() → self::AugmentedClass#1#1
+    : super core::Object::•()
+    ;
+  method augmentedInstanceMethod() → void {
+    core::print("augmentedInstanceMethod#2");
+  }
+  static method augmentedStaticMethod() → void {
+    core::print("augmentedStaticMethod#2");
+  }
+}
+class AugmentedClass extends core::Object {
+  synthetic constructor •() → self::AugmentedClass
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedInstanceMethod() → void {
+    core::print("augmentedInstanceMethod#1");
+  }
+  static method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedStaticMethod() → void {
+    core::print("augmentedStaticMethod#1");
+  }
+}
+static method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedTopLevelMethod() → void {
+  core::print("augmentedTopLevelMethod#1");
+}
diff --git a/pkg/front_end/testcases/macros/duplicate_augment.dart.textual_outline.expect b/pkg/front_end/testcases/macros/duplicate_augment.dart.textual_outline.expect
new file mode 100644
index 0000000..65489d0
--- /dev/null
+++ b/pkg/front_end/testcases/macros/duplicate_augment.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import augment 'duplicate_augment_lib.dart';
+void augmentedTopLevelMethod() {}
+class AugmentedClass {
+  void augmentedInstanceMethod() {}
+  static void augmentedStaticMethod() {}
+}
diff --git a/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.expect b/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.expect
new file mode 100644
index 0000000..79663e1
--- /dev/null
+++ b/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:9:14: Error: 'augmentedTopLevelMethod' is already declared in this scope.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:5:14: Context: Previous declaration of 'augmentedTopLevelMethod'.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:22:15: Error: 'AugmentedClass' is already declared in this scope.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:13:15: Context: Previous declaration of 'AugmentedClass'.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///duplicate_augment.dart";
+
+class AugmentedClass#1#1 extends core::Object { // from org-dartlang-testcase:///duplicate_augment_lib.dart
+  synthetic constructor •() → self::AugmentedClass#1#1
+    : super core::Object::•()
+    ;
+  method augmentedInstanceMethod() → void {
+    core::print("augmentedInstanceMethod#2");
+  }
+  static method augmentedStaticMethod() → void {
+    core::print("augmentedStaticMethod#2");
+  }
+}
+class AugmentedClass extends core::Object {
+  synthetic constructor •() → self::AugmentedClass
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedInstanceMethod() → void {
+    core::print("augmentedInstanceMethod#1");
+  }
+  static method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedStaticMethod() → void {
+    core::print("augmentedStaticMethod#1");
+  }
+}
+static method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedTopLevelMethod() → void {
+  core::print("augmentedTopLevelMethod#1");
+}
diff --git a/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.modular.expect b/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.modular.expect
new file mode 100644
index 0000000..79663e1
--- /dev/null
+++ b/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.modular.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:9:14: Error: 'augmentedTopLevelMethod' is already declared in this scope.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:5:14: Context: Previous declaration of 'augmentedTopLevelMethod'.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:22:15: Error: 'AugmentedClass' is already declared in this scope.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:13:15: Context: Previous declaration of 'AugmentedClass'.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///duplicate_augment.dart";
+
+class AugmentedClass#1#1 extends core::Object { // from org-dartlang-testcase:///duplicate_augment_lib.dart
+  synthetic constructor •() → self::AugmentedClass#1#1
+    : super core::Object::•()
+    ;
+  method augmentedInstanceMethod() → void {
+    core::print("augmentedInstanceMethod#2");
+  }
+  static method augmentedStaticMethod() → void {
+    core::print("augmentedStaticMethod#2");
+  }
+}
+class AugmentedClass extends core::Object {
+  synthetic constructor •() → self::AugmentedClass
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedInstanceMethod() → void {
+    core::print("augmentedInstanceMethod#1");
+  }
+  static method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedStaticMethod() → void {
+    core::print("augmentedStaticMethod#1");
+  }
+}
+static method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedTopLevelMethod() → void {
+  core::print("augmentedTopLevelMethod#1");
+}
diff --git a/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.outline.expect b/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.outline.expect
new file mode 100644
index 0000000..f133d5b
--- /dev/null
+++ b/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.outline.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:9:14: Error: 'augmentedTopLevelMethod' is already declared in this scope.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:5:14: Context: Previous declaration of 'augmentedTopLevelMethod'.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:22:15: Error: 'AugmentedClass' is already declared in this scope.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:13:15: Context: Previous declaration of 'AugmentedClass'.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///duplicate_augment.dart";
+
+class AugmentedClass#1#1 extends core::Object { // from org-dartlang-testcase:///duplicate_augment_lib.dart
+  synthetic constructor •() → self::AugmentedClass#1#1
+    ;
+  method augmentedInstanceMethod() → void
+    ;
+  static method augmentedStaticMethod() → void
+    ;
+}
+class AugmentedClass extends core::Object {
+  synthetic constructor •() → self::AugmentedClass
+    ;
+  method augmentedInstanceMethod() → void
+    ;
+  static method augmentedStaticMethod() → void
+    ;
+}
+static method augmentedTopLevelMethod() → void
+  ;
diff --git a/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.transformed.expect b/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.transformed.expect
new file mode 100644
index 0000000..79663e1
--- /dev/null
+++ b/pkg/front_end/testcases/macros/duplicate_augment.dart.weak.transformed.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:9:14: Error: 'augmentedTopLevelMethod' is already declared in this scope.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:5:14: Context: Previous declaration of 'augmentedTopLevelMethod'.
+// augment void augmentedTopLevelMethod() {
+//              ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:22:15: Error: 'AugmentedClass' is already declared in this scope.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/macros/duplicate_augment_lib.dart:13:15: Context: Previous declaration of 'AugmentedClass'.
+// augment class AugmentedClass {
+//               ^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///duplicate_augment.dart";
+
+class AugmentedClass#1#1 extends core::Object { // from org-dartlang-testcase:///duplicate_augment_lib.dart
+  synthetic constructor •() → self::AugmentedClass#1#1
+    : super core::Object::•()
+    ;
+  method augmentedInstanceMethod() → void {
+    core::print("augmentedInstanceMethod#2");
+  }
+  static method augmentedStaticMethod() → void {
+    core::print("augmentedStaticMethod#2");
+  }
+}
+class AugmentedClass extends core::Object {
+  synthetic constructor •() → self::AugmentedClass
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedInstanceMethod() → void {
+    core::print("augmentedInstanceMethod#1");
+  }
+  static method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedStaticMethod() → void {
+    core::print("augmentedStaticMethod#1");
+  }
+}
+static method /* from org-dartlang-testcase:///duplicate_augment_lib.dart */ augmentedTopLevelMethod() → void {
+  core::print("augmentedTopLevelMethod#1");
+}
diff --git a/pkg/front_end/testcases/macros/duplicate_augment_lib.dart b/pkg/front_end/testcases/macros/duplicate_augment_lib.dart
new file mode 100644
index 0000000..6ab100d
--- /dev/null
+++ b/pkg/front_end/testcases/macros/duplicate_augment_lib.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2022, 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.
+
+augment void augmentedTopLevelMethod() {
+  print('augmentedTopLevelMethod#1');
+}
+
+augment void augmentedTopLevelMethod() {
+  print('augmentedTopLevelMethod#2');
+}
+
+augment class AugmentedClass {
+  augment void augmentedInstanceMethod() {
+    print('augmentedInstanceMethod#1');
+  }
+  augment static void augmentedStaticMethod() {
+    print('augmentedStaticMethod#1');
+  }
+}
+
+augment class AugmentedClass {
+  augment void augmentedInstanceMethod() {
+    print('augmentedInstanceMethod#2');
+  }
+  augment static void augmentedStaticMethod() {
+    print('augmentedStaticMethod#2');
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/macros/multiple_augment_class.dart b/pkg/front_end/testcases/macros/multiple_augment_class.dart
new file mode 100644
index 0000000..68c153d
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_augment_class.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2022, 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 augment 'multiple_augment_class_lib1.dart';
+import augment 'multiple_augment_class_lib2.dart';
+
+class Class {
+  external int method1();
+  external int method2();
+  external int method3();
+}
+
+main() {
+  Class c = new Class();
+  expect(42, c.method1());
+  expect(87, c.method2());
+  expect(123, c.method3());
+}
+
+expect(expected, actual) {
+  if (expected != actual) {
+    throw 'Expected $expected, actual $actual';
+  }
+}
diff --git a/pkg/front_end/testcases/macros/multiple_augment_class.dart.strong.expect b/pkg/front_end/testcases/macros/multiple_augment_class.dart.strong.expect
new file mode 100644
index 0000000..732d315
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_augment_class.dart.strong.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib1.dart */ method1() → core::int
+    return 42;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib2.dart */ method2() → core::int
+    return 87;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib2.dart */ method3() → core::int
+    return 123;
+}
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  self::expect(42, c.{self::Class::method1}(){() → core::int});
+  self::expect(87, c.{self::Class::method2}(){() → core::int});
+  self::expect(123, c.{self::Class::method3}(){() → core::int});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
diff --git a/pkg/front_end/testcases/macros/multiple_augment_class.dart.strong.transformed.expect b/pkg/front_end/testcases/macros/multiple_augment_class.dart.strong.transformed.expect
new file mode 100644
index 0000000..732d315
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_augment_class.dart.strong.transformed.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib1.dart */ method1() → core::int
+    return 42;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib2.dart */ method2() → core::int
+    return 87;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib2.dart */ method3() → core::int
+    return 123;
+}
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  self::expect(42, c.{self::Class::method1}(){() → core::int});
+  self::expect(87, c.{self::Class::method2}(){() → core::int});
+  self::expect(123, c.{self::Class::method3}(){() → core::int});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
diff --git a/pkg/front_end/testcases/macros/multiple_augment_class.dart.textual_outline.expect b/pkg/front_end/testcases/macros/multiple_augment_class.dart.textual_outline.expect
new file mode 100644
index 0000000..8cef7dc
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_augment_class.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import augment 'multiple_augment_class_lib1.dart';
+import augment 'multiple_augment_class_lib2.dart';
+class Class {
+  external int method1();
+  external int method2();
+  external int method3();
+}
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.expect b/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.expect
new file mode 100644
index 0000000..732d315
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib1.dart */ method1() → core::int
+    return 42;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib2.dart */ method2() → core::int
+    return 87;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib2.dart */ method3() → core::int
+    return 123;
+}
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  self::expect(42, c.{self::Class::method1}(){() → core::int});
+  self::expect(87, c.{self::Class::method2}(){() → core::int});
+  self::expect(123, c.{self::Class::method3}(){() → core::int});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
diff --git a/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.modular.expect b/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.modular.expect
new file mode 100644
index 0000000..732d315
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.modular.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib1.dart */ method1() → core::int
+    return 42;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib2.dart */ method2() → core::int
+    return 87;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib2.dart */ method3() → core::int
+    return 123;
+}
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  self::expect(42, c.{self::Class::method1}(){() → core::int});
+  self::expect(87, c.{self::Class::method2}(){() → core::int});
+  self::expect(123, c.{self::Class::method3}(){() → core::int});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
diff --git a/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.outline.expect b/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.outline.expect
new file mode 100644
index 0000000..8195b2746
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.outline.expect
@@ -0,0 +1,18 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    ;
+  external method method1() → core::int;
+  external method method2() → core::int;
+  external method method3() → core::int;
+}
+static method main() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.transformed.expect b/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.transformed.expect
new file mode 100644
index 0000000..732d315
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_augment_class.dart.weak.transformed.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+import "org-dartlang-testcase:///multiple_augment_class.dart";
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib1.dart */ method1() → core::int
+    return 42;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib2.dart */ method2() → core::int
+    return 87;
+  method /* from org-dartlang-testcase:///multiple_augment_class_lib2.dart */ method3() → core::int
+    return 123;
+}
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  self::expect(42, c.{self::Class::method1}(){() → core::int});
+  self::expect(87, c.{self::Class::method2}(){() → core::int});
+  self::expect(123, c.{self::Class::method3}(){() → core::int});
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
diff --git a/pkg/front_end/testcases/macros/multiple_augment_class_lib1.dart b/pkg/front_end/testcases/macros/multiple_augment_class_lib1.dart
new file mode 100644
index 0000000..f396fe9
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_augment_class_lib1.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2022, 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.
+
+augment class Class {
+  augment int method1() => 42;
+  augment int method3() => 321;
+}
diff --git a/pkg/front_end/testcases/macros/multiple_augment_class_lib2.dart b/pkg/front_end/testcases/macros/multiple_augment_class_lib2.dart
new file mode 100644
index 0000000..7dcc285
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_augment_class_lib2.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2022, 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.
+
+augment class Class {
+  augment int method2() => 87;
+  augment int method3() => 123;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.strong.expect
index b233a23..6ed0762 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.strong.expect
@@ -130,10 +130,8 @@
     : self::A::i = i, super core::Object::•()
     ;
   external constructor constructor8([core::int i = #C6]) → self::A
-    : super core::Object::•()
     ;
   external constructor constructor9({core::int i = #C6}) → self::A
-    : super core::Object::•()
     ;
   static factory factory3([core::int i = #C6]) → self::A
     return new self::A::constructor3(i);
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect
index 0c4486a..67740f0 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.strong.transformed.expect
@@ -130,10 +130,8 @@
     : self::A::i = i, super core::Object::•()
     ;
   external constructor constructor8([core::int i = #C6]) → self::A
-    : super core::Object::•()
     ;
   external constructor constructor9({core::int i = #C6}) → self::A
-    : super core::Object::•()
     ;
   static factory factory3([core::int i = #C6]) → self::A
     return new self::A::constructor3(i);
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.weak.expect
index b233a23..6ed0762 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.weak.expect
@@ -130,10 +130,8 @@
     : self::A::i = i, super core::Object::•()
     ;
   external constructor constructor8([core::int i = #C6]) → self::A
-    : super core::Object::•()
     ;
   external constructor constructor9({core::int i = #C6}) → self::A
-    : super core::Object::•()
     ;
   static factory factory3([core::int i = #C6]) → self::A
     return new self::A::constructor3(i);
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.weak.modular.expect
index b233a23..6ed0762 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.weak.modular.expect
@@ -130,10 +130,8 @@
     : self::A::i = i, super core::Object::•()
     ;
   external constructor constructor8([core::int i = #C6]) → self::A
-    : super core::Object::•()
     ;
   external constructor constructor9({core::int i = #C6}) → self::A
-    : super core::Object::•()
     ;
   static factory factory3([core::int i = #C6]) → self::A
     return new self::A::constructor3(i);
diff --git a/pkg/front_end/testcases/nnbd/issue42362.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42362.dart.weak.transformed.expect
index 8ee747f..b721af1 100644
--- a/pkg/front_end/testcases/nnbd/issue42362.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42362.dart.weak.transformed.expect
@@ -130,10 +130,8 @@
     : self::A::i = i, super core::Object::•()
     ;
   external constructor constructor8([core::int i = #C6]) → self::A
-    : super core::Object::•()
     ;
   external constructor constructor9({core::int i = #C6}) → self::A
-    : super core::Object::•()
     ;
   static factory factory3([core::int i = #C6]) → self::A
     return new self::A::constructor3(i);
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect
index 64a0fed..70915c1 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect
@@ -26,15 +26,15 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     return super.{core::Object::noSuchMethod}(invocation);
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
+  no-such-method-forwarder method then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, core::List::unmodifiable<core::Type*>(<core::Type*>[self::Divergent::then::R%]), core::List::unmodifiable<dynamic>(<dynamic>[onValue]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onError}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent::then::R%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 0, #C3, #C12, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
 static method test() → dynamic async /* futureValueType= dynamic */ {
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect
index 8c665cc..e9db26f 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect
@@ -26,15 +26,15 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     return super.{core::Object::noSuchMethod}(invocation);
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
+  no-such-method-forwarder method then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, core::List::unmodifiable<core::Type*>(core::_GrowableList::_literal1<core::Type*>(self::Divergent::then::R%)), core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onValue)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onError}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent::then::R%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 0, #C3, #C12, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
 static method test() → dynamic async /* futureValueType= dynamic */ {
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect
index 64a0fed..70915c1 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect
@@ -26,15 +26,15 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     return super.{core::Object::noSuchMethod}(invocation);
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
+  no-such-method-forwarder method then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, core::List::unmodifiable<core::Type*>(<core::Type*>[self::Divergent::then::R%]), core::List::unmodifiable<dynamic>(<dynamic>[onValue]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onError}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent::then::R%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 0, #C3, #C12, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
 static method test() → dynamic async /* futureValueType= dynamic */ {
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.modular.expect
index 64a0fed..70915c1 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.modular.expect
@@ -26,15 +26,15 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     return super.{core::Object::noSuchMethod}(invocation);
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
+  no-such-method-forwarder method then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, core::List::unmodifiable<core::Type*>(<core::Type*>[self::Divergent::then::R%]), core::List::unmodifiable<dynamic>(<dynamic>[onValue]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onError}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent::then::R%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 0, #C3, #C12, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
 static method test() → dynamic async /* futureValueType= dynamic */ {
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
index e218902..2172a07 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
@@ -10,15 +10,15 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     ;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#catchError, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#test: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#whenComplete, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#timeout, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onTimeout: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError}) → asy::Future<self::Divergent::then::R%>
+  no-such-method-forwarder method then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError}) → asy::Future<self::Divergent::then::R%>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#then, 0, core::List::unmodifiable<core::Type*>(<core::Type*>[self::Divergent::then::R%]), core::List::unmodifiable<dynamic>(<dynamic>[onValue]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#onError: onError}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent::then::R%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#asStream, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
 static method test() → dynamic async 
@@ -28,19 +28,19 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:770:13 -> SymbolConstant(#then)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:770:13 -> SymbolConstant(#onError)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> SymbolConstant(#then)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> SymbolConstant(#onError)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///issue42546.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 61, effectively constant: 15
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect
index 8c665cc..e9db26f 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect
@@ -26,15 +26,15 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     return super.{core::Object::noSuchMethod}(invocation);
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onTimeout}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
+  no-such-method-forwarder method then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, core::List::unmodifiable<core::Type*>(core::_GrowableList::_literal1<core::Type*>(self::Divergent::then::R%)), core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onValue)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onError}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent::then::R%>;
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
+  no-such-method-forwarder method asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 0, #C3, #C12, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
 static method test() → dynamic async /* futureValueType= dynamic */ {
diff --git a/pkg/front_end/testcases/nnbd/issue42758.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42758.dart.strong.transformed.expect
index 6b29462..fc3cda0 100644
--- a/pkg/front_end/testcases/nnbd/issue42758.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42758.dart.strong.transformed.expect
@@ -111,35 +111,35 @@
     #t8.{core::Set::add}{Invariant}(n1){(Never) → core::bool};
   } =>#t8;
   core::Set<Never> s2 = block {
-    final core::Set<Never> #t9 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Set<Never> #t9 = new col::_InternalLinkedHashSet::•<Never>();
     final core::Iterable<Never>? #t10 = n1;
     if(!(#t10 == null))
       #t9.{core::Set::addAll}{Invariant}(#t10{core::Iterable<Never>}){(core::Iterable<Never>) → void};
     #t9.{core::Set::add}{Invariant}(n1){(Never) → core::bool};
   } =>#t9;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t11 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t11 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t11.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'.
   var s3 = {...n2, n1};
                ^"){(dynamic) → core::bool};
     #t11.{core::Set::add}{Invariant}(n1){(dynamic) → core::bool};
   } =>#t11;
   core::Set<Never> s4 = block {
-    final core::Set<Never> #t12 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Set<Never> #t12 = new col::_InternalLinkedHashSet::•<Never>();
     final core::Iterable<Never>? #t13 = n2;
     if(!(#t13 == null))
       #t12.{core::Set::addAll}{Invariant}(#t13{core::Iterable<Never>}){(core::Iterable<Never>) → void};
     #t12.{core::Set::add}{Invariant}(n1){(Never) → core::bool};
   } =>#t12;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t14 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t14 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t14.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'.
   var s5 = {...n3, n1};
                ^"){(dynamic) → core::bool};
     #t14.{core::Set::add}{Invariant}(n1){(dynamic) → core::bool};
   } =>#t14;
   core::Set<Never> s6 = block {
-    final core::Set<Never> #t15 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Set<Never> #t15 = new col::_InternalLinkedHashSet::•<Never>();
     final core::Iterable<Never>? #t16 = n3;
     if(!(#t16 == null))
       #t15.{core::Set::addAll}{Invariant}(#t16{core::Iterable<Never>}){(core::Iterable<Never>) → void};
@@ -210,35 +210,35 @@
     #t31.{core::Set::add}{Invariant}(n1){(self::test2::N1) → core::bool};
   } =>#t31;
   core::Set<self::test2::N1> s2 = block {
-    final core::Set<self::test2::N1> #t32 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Set<self::test2::N1> #t32 = new col::_InternalLinkedHashSet::•<self::test2::N1>();
     final core::Iterable<self::test2::N1>? #t33 = n1;
     if(!(#t33 == null))
       #t32.{core::Set::addAll}{Invariant}(#t33{core::Iterable<self::test2::N1>}){(core::Iterable<self::test2::N1>) → void};
     #t32.{core::Set::add}{Invariant}(n1){(self::test2::N1) → core::bool};
   } =>#t32;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t34 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t34 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t34.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'.
   var s3 = {...n2, n1};
                ^"){(dynamic) → core::bool};
     #t34.{core::Set::add}{Invariant}(n1){(dynamic) → core::bool};
   } =>#t34;
   core::Set<self::test2::N1> s4 = block {
-    final core::Set<self::test2::N1> #t35 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Set<self::test2::N1> #t35 = new col::_InternalLinkedHashSet::•<self::test2::N1>();
     final core::Iterable<self::test2::N1>? #t36 = n2;
     if(!(#t36 == null))
       #t35.{core::Set::addAll}{Invariant}(#t36{core::Iterable<self::test2::N1>}){(core::Iterable<self::test2::N1>) → void};
     #t35.{core::Set::add}{Invariant}(n1){(self::test2::N1) → core::bool};
   } =>#t35;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t37 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t37 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t37.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'.
   var s5 = {...n3, n1};
                ^"){(dynamic) → core::bool};
     #t37.{core::Set::add}{Invariant}(n1){(dynamic) → core::bool};
   } =>#t37;
   core::Set<self::test2::N1> s6 = block {
-    final core::Set<self::test2::N1> #t38 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Set<self::test2::N1> #t38 = new col::_InternalLinkedHashSet::•<self::test2::N1>();
     final core::Iterable<self::test2::N1>? #t39 = n3;
     if(!(#t39 == null))
       #t38.{core::Set::addAll}{Invariant}(#t39{core::Iterable<self::test2::N1>}){(core::Iterable<self::test2::N1>) → void};
diff --git a/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect
index 0512d64..16928b3 100644
--- a/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect
@@ -112,35 +112,35 @@
     #t10.{core::Set::add}{Invariant}(let final Never #t12 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){(Never) → core::bool};
   } =>#t10;
   core::Set<Never> s2 = block {
-    final core::Set<Never> #t13 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Set<Never> #t13 = new col::_InternalLinkedHashSet::•<Never>();
     final core::Iterable<Never>? #t14 = let final Never #t15 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
     if(!(#t14 == null))
       #t13.{core::Set::addAll}{Invariant}(#t14{core::Iterable<Never>}){(core::Iterable<Never>) → void};
     #t13.{core::Set::add}{Invariant}(let final Never #t16 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){(Never) → core::bool};
   } =>#t13;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t17 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t17 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t17.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'.
   var s3 = {...n2, n1};
                ^"){(dynamic) → core::bool};
     #t17.{core::Set::add}{Invariant}(let final Never #t18 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){(dynamic) → core::bool};
   } =>#t17;
   core::Set<Never> s4 = block {
-    final core::Set<Never> #t19 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Set<Never> #t19 = new col::_InternalLinkedHashSet::•<Never>();
     final core::Iterable<Never>? #t20 = n2;
     if(!(#t20 == null))
       #t19.{core::Set::addAll}{Invariant}(#t20{core::Iterable<Never>}){(core::Iterable<Never>) → void};
     #t19.{core::Set::add}{Invariant}(let final Never #t21 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){(Never) → core::bool};
   } =>#t19;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t22 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t22 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t22.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'.
   var s5 = {...n3, n1};
                ^"){(dynamic) → core::bool};
     #t22.{core::Set::add}{Invariant}(let final Never #t23 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){(dynamic) → core::bool};
   } =>#t22;
   core::Set<Never> s6 = block {
-    final core::Set<Never> #t24 = new col::_CompactLinkedHashSet::•<Never>();
+    final core::Set<Never> #t24 = new col::_InternalLinkedHashSet::•<Never>();
     final core::Iterable<Never>? #t25 = n3;
     if(!(#t25 == null))
       #t24.{core::Set::addAll}{Invariant}(#t25{core::Iterable<Never>}){(core::Iterable<Never>) → void};
@@ -211,35 +211,35 @@
     #t57.{core::Set::add}{Invariant}(let final self::test2::N1 #t59 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){(self::test2::N1) → core::bool};
   } =>#t57;
   core::Set<self::test2::N1> s2 = block {
-    final core::Set<self::test2::N1> #t60 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Set<self::test2::N1> #t60 = new col::_InternalLinkedHashSet::•<self::test2::N1>();
     final core::Iterable<self::test2::N1>? #t61 = let final self::test2::N1 #t62 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
     if(!(#t61 == null))
       #t60.{core::Set::addAll}{Invariant}(#t61{core::Iterable<self::test2::N1>}){(core::Iterable<self::test2::N1>) → void};
     #t60.{core::Set::add}{Invariant}(let final self::test2::N1 #t63 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){(self::test2::N1) → core::bool};
   } =>#t60;
   core::Set<dynamic> s3 = block {
-    final core::Set<dynamic> #t64 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t64 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t64.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'.
   var s3 = {...n2, n1};
                ^"){(dynamic) → core::bool};
     #t64.{core::Set::add}{Invariant}(let final self::test2::N1 #t65 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){(dynamic) → core::bool};
   } =>#t64;
   core::Set<self::test2::N1> s4 = block {
-    final core::Set<self::test2::N1> #t66 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Set<self::test2::N1> #t66 = new col::_InternalLinkedHashSet::•<self::test2::N1>();
     final core::Iterable<self::test2::N1>? #t67 = n2;
     if(!(#t67 == null))
       #t66.{core::Set::addAll}{Invariant}(#t67{core::Iterable<self::test2::N1>}){(core::Iterable<self::test2::N1>) → void};
     #t66.{core::Set::add}{Invariant}(let final self::test2::N1 #t68 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){(self::test2::N1) → core::bool};
   } =>#t66;
   core::Set<dynamic> s5 = block {
-    final core::Set<dynamic> #t69 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t69 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t69.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'.
   var s5 = {...n3, n1};
                ^"){(dynamic) → core::bool};
     #t69.{core::Set::add}{Invariant}(let final self::test2::N1 #t70 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")){(dynamic) → core::bool};
   } =>#t69;
   core::Set<self::test2::N1> s6 = block {
-    final core::Set<self::test2::N1> #t71 = new col::_CompactLinkedHashSet::•<self::test2::N1>();
+    final core::Set<self::test2::N1> #t71 = new col::_InternalLinkedHashSet::•<self::test2::N1>();
     final core::Iterable<self::test2::N1>? #t72 = n3;
     if(!(#t72 == null))
       #t71.{core::Set::addAll}{Invariant}(#t72{core::Iterable<self::test2::N1>}){(core::Iterable<self::test2::N1>) → void};
diff --git a/pkg/front_end/testcases/nnbd/issue43256.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43256.dart.strong.transformed.expect
index a6b1a18..985b3f4 100644
--- a/pkg/front_end/testcases/nnbd/issue43256.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43256.dart.strong.transformed.expect
@@ -67,7 +67,7 @@
     #t1.{core::Map::addAll}{Invariant}(self::nullableMap!){(core::Map<dynamic, dynamic>) → void};
 } =>#t1;
 static field core::Set<dynamic> set1 = block {
-  final core::Set<dynamic> #t2 = new col::_CompactLinkedHashSet::•<dynamic>();
+  final core::Set<dynamic> #t2 = new col::_InternalLinkedHashSet::•<dynamic>();
   #t2.{core::Set::add}{Invariant}(0){(dynamic) → core::bool};
   if(self::i.{core::num::>}(0){(core::num) → core::bool})
     #t2.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:23:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
@@ -108,7 +108,7 @@
 }
 static method testIterables<X extends dynamic, Y extends core::List<core::int>?, Z extends core::List<core::int>>(self::testIterables::X% x, self::testIterables::Y% y, self::testIterables::Z z) → dynamic {
   core::Set<dynamic> set2 = block {
-    final core::Set<dynamic> #t5 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t5 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t5.{core::Set::add}{Invariant}(0){(dynamic) → core::bool};
     if(self::i.{core::num::>}(0){(core::num) → core::bool})
       #t5.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:48:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
diff --git a/pkg/front_end/testcases/nnbd/issue43256.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue43256.dart.weak.transformed.expect
index a6b1a18..985b3f4 100644
--- a/pkg/front_end/testcases/nnbd/issue43256.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43256.dart.weak.transformed.expect
@@ -67,7 +67,7 @@
     #t1.{core::Map::addAll}{Invariant}(self::nullableMap!){(core::Map<dynamic, dynamic>) → void};
 } =>#t1;
 static field core::Set<dynamic> set1 = block {
-  final core::Set<dynamic> #t2 = new col::_CompactLinkedHashSet::•<dynamic>();
+  final core::Set<dynamic> #t2 = new col::_InternalLinkedHashSet::•<dynamic>();
   #t2.{core::Set::add}{Invariant}(0){(dynamic) → core::bool};
   if(self::i.{core::num::>}(0){(core::num) → core::bool})
     #t2.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:23:17: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
@@ -108,7 +108,7 @@
 }
 static method testIterables<X extends dynamic, Y extends core::List<core::int>?, Z extends core::List<core::int>>(self::testIterables::X% x, self::testIterables::Y% y, self::testIterables::Z z) → dynamic {
   core::Set<dynamic> set2 = block {
-    final core::Set<dynamic> #t5 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t5 = new col::_InternalLinkedHashSet::•<dynamic>();
     #t5.{core::Set::add}{Invariant}(0){(dynamic) → core::bool};
     if(self::i.{core::num::>}(0){(core::num) → core::bool})
       #t5.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43256.dart:48:19: Error: Unexpected type 'X' of a spread.  Expected 'dynamic' or an Iterable.
diff --git a/pkg/front_end/testcases/nnbd/issue43455.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43455.dart.strong.transformed.expect
index bccc51e..53a4e60 100644
--- a/pkg/front_end/testcases/nnbd/issue43455.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43455.dart.strong.transformed.expect
@@ -9,22 +9,22 @@
     ;
   method test(covariant-by-class self::C::X% x, covariant-by-class self::C::Y? y) → dynamic {
     core::Set<core::Object?> v = block {
-      final core::Set<core::Object?> #t1 = new col::_CompactLinkedHashSet::•<core::Object?>();
+      final core::Set<core::Object?> #t1 = new col::_InternalLinkedHashSet::•<core::Object?>();
       #t1.{core::Set::add}{Invariant}(x){(core::Object?) → core::bool};
       #t1.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
     } =>#t1;
     core::Set<core::Object?> w = block {
-      final core::Set<core::Object?> #t2 = new col::_CompactLinkedHashSet::•<core::Object?>();
+      final core::Set<core::Object?> #t2 = new col::_InternalLinkedHashSet::•<core::Object?>();
       #t2.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
       #t2.{core::Set::add}{Invariant}(x){(core::Object?) → core::bool};
     } =>#t2;
     core::Set<core::Object?> p = block {
-      final core::Set<core::Object?> #t3 = new col::_CompactLinkedHashSet::•<core::Object?>();
+      final core::Set<core::Object?> #t3 = new col::_InternalLinkedHashSet::•<core::Object?>();
       #t3.{core::Set::add}{Invariant}(y){(core::Object?) → core::bool};
       #t3.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
     } =>#t3;
     core::Set<core::Object?> q = block {
-      final core::Set<core::Object?> #t4 = new col::_CompactLinkedHashSet::•<core::Object?>();
+      final core::Set<core::Object?> #t4 = new col::_InternalLinkedHashSet::•<core::Object?>();
       #t4.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
       #t4.{core::Set::add}{Invariant}(y){(core::Object?) → core::bool};
     } =>#t4;
@@ -38,12 +38,12 @@
     self::assertLeftSubtype<core::Set<core::Object?>>(q);
     if(x is{ForNonNullableByDefault} core::Object?) {
       core::Set<core::Object?> v = block {
-        final core::Set<core::Object?> #t5 = new col::_CompactLinkedHashSet::•<core::Object?>();
+        final core::Set<core::Object?> #t5 = new col::_InternalLinkedHashSet::•<core::Object?>();
         #t5.{core::Set::add}{Invariant}(x{self::C::X% & core::Object? /* '%' & '?' = '%' */}){(core::Object?) → core::bool};
         #t5.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
       } =>#t5;
       core::Set<core::Object?> w = block {
-        final core::Set<core::Object?> #t6 = new col::_CompactLinkedHashSet::•<core::Object?>();
+        final core::Set<core::Object?> #t6 = new col::_InternalLinkedHashSet::•<core::Object?>();
         #t6.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
         #t6.{core::Set::add}{Invariant}(x{self::C::X% & core::Object? /* '%' & '?' = '%' */}){(core::Object?) → core::bool};
       } =>#t6;
@@ -58,7 +58,7 @@
   x as{ForNonNullableByDefault} core::Set<core::Object?>;
 }
 static method assertLeftSubtype<X extends core::Object? = dynamic>(self::assertLeftSubtype::X% x) → dynamic {
-  new col::_CompactLinkedHashSet::•<core::Object?>() as{ForNonNullableByDefault} self::assertLeftSubtype::X%;
+  new col::_InternalLinkedHashSet::•<core::Object?>() as{ForNonNullableByDefault} self::assertLeftSubtype::X%;
 }
 static method main() → dynamic {
   new self::C::•<core::int?, core::int>().{self::C::test}(42, null){(core::int?, core::int?) → dynamic};
diff --git a/pkg/front_end/testcases/nnbd/issue43455.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue43455.dart.weak.transformed.expect
index bccc51e..53a4e60 100644
--- a/pkg/front_end/testcases/nnbd/issue43455.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43455.dart.weak.transformed.expect
@@ -9,22 +9,22 @@
     ;
   method test(covariant-by-class self::C::X% x, covariant-by-class self::C::Y? y) → dynamic {
     core::Set<core::Object?> v = block {
-      final core::Set<core::Object?> #t1 = new col::_CompactLinkedHashSet::•<core::Object?>();
+      final core::Set<core::Object?> #t1 = new col::_InternalLinkedHashSet::•<core::Object?>();
       #t1.{core::Set::add}{Invariant}(x){(core::Object?) → core::bool};
       #t1.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
     } =>#t1;
     core::Set<core::Object?> w = block {
-      final core::Set<core::Object?> #t2 = new col::_CompactLinkedHashSet::•<core::Object?>();
+      final core::Set<core::Object?> #t2 = new col::_InternalLinkedHashSet::•<core::Object?>();
       #t2.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
       #t2.{core::Set::add}{Invariant}(x){(core::Object?) → core::bool};
     } =>#t2;
     core::Set<core::Object?> p = block {
-      final core::Set<core::Object?> #t3 = new col::_CompactLinkedHashSet::•<core::Object?>();
+      final core::Set<core::Object?> #t3 = new col::_InternalLinkedHashSet::•<core::Object?>();
       #t3.{core::Set::add}{Invariant}(y){(core::Object?) → core::bool};
       #t3.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
     } =>#t3;
     core::Set<core::Object?> q = block {
-      final core::Set<core::Object?> #t4 = new col::_CompactLinkedHashSet::•<core::Object?>();
+      final core::Set<core::Object?> #t4 = new col::_InternalLinkedHashSet::•<core::Object?>();
       #t4.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
       #t4.{core::Set::add}{Invariant}(y){(core::Object?) → core::bool};
     } =>#t4;
@@ -38,12 +38,12 @@
     self::assertLeftSubtype<core::Set<core::Object?>>(q);
     if(x is{ForNonNullableByDefault} core::Object?) {
       core::Set<core::Object?> v = block {
-        final core::Set<core::Object?> #t5 = new col::_CompactLinkedHashSet::•<core::Object?>();
+        final core::Set<core::Object?> #t5 = new col::_InternalLinkedHashSet::•<core::Object?>();
         #t5.{core::Set::add}{Invariant}(x{self::C::X% & core::Object? /* '%' & '?' = '%' */}){(core::Object?) → core::bool};
         #t5.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
       } =>#t5;
       core::Set<core::Object?> w = block {
-        final core::Set<core::Object?> #t6 = new col::_CompactLinkedHashSet::•<core::Object?>();
+        final core::Set<core::Object?> #t6 = new col::_InternalLinkedHashSet::•<core::Object?>();
         #t6.{core::Set::add}{Invariant}(42){(core::Object?) → core::bool};
         #t6.{core::Set::add}{Invariant}(x{self::C::X% & core::Object? /* '%' & '?' = '%' */}){(core::Object?) → core::bool};
       } =>#t6;
@@ -58,7 +58,7 @@
   x as{ForNonNullableByDefault} core::Set<core::Object?>;
 }
 static method assertLeftSubtype<X extends core::Object? = dynamic>(self::assertLeftSubtype::X% x) → dynamic {
-  new col::_CompactLinkedHashSet::•<core::Object?>() as{ForNonNullableByDefault} self::assertLeftSubtype::X%;
+  new col::_InternalLinkedHashSet::•<core::Object?>() as{ForNonNullableByDefault} self::assertLeftSubtype::X%;
 }
 static method main() → dynamic {
   new self::C::•<core::int?, core::int>().{self::C::test}(42, null){(core::int?, core::int?) → dynamic};
diff --git a/pkg/front_end/testcases/nnbd/issue43495.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue43495.dart.strong.transformed.expect
index 80cf8ea..f91d345 100644
--- a/pkg/front_end/testcases/nnbd/issue43495.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43495.dart.strong.transformed.expect
@@ -187,13 +187,13 @@
  - 'List' is from 'dart:core'.
     <int, int>{...a}, // Error.
                   ^": null}, block {
-    final core::Set<core::int> #t4 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t4 = new col::_InternalLinkedHashSet::•<core::int>();
     #t4.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:13:14: Error: Unexpected type 'Map<int, int>?' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
     <int>{...d}, // Error.
              ^"){(core::int) → core::bool};
   } =>#t4, block {
-    final core::Set<core::int> #t5 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t5 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:14:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...a}, // Error.
@@ -207,7 +207,7 @@
       }
     }
   } =>#t5, block {
-    final core::Set<core::int> #t8 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t8 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:15:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...b}, // Error.
@@ -221,7 +221,7 @@
       }
     }
   } =>#t8, block {
-    final core::Set<core::int> #t11 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t11 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:16:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...c}, // Error.
@@ -241,7 +241,7 @@
     {if (condition) ...d}, // Error.
                        ^", null){(core::int, core::int) → void};
   } =>#t14, block {
-    final core::Set<core::int> #t15 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t15 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -261,7 +261,7 @@
       }
     }
   } =>#t15, block {
-    final core::Set<core::int> #t18 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t18 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -281,7 +281,7 @@
       }
     }
   } =>#t18, block {
-    final core::Set<core::int> #t21 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t21 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -312,7 +312,7 @@
       }
     }
   } =>#t24, block {
-    final core::Set<core::int> #t25 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t25 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:22:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...a}, // Error.
@@ -326,7 +326,7 @@
       }
     }
   } =>#t25, block {
-    final core::Set<core::int> #t28 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t28 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:23:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...b}, // Error.
@@ -340,7 +340,7 @@
       }
     }
   } =>#t28, block {
-    final core::Set<core::int> #t31 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t31 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:24:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...c}, // Error.
@@ -360,17 +360,17 @@
     {for (int i = 0; i < 42; ++i) ...d}, // Error.
                                      ^", null){(core::int, core::int) → void};
   } =>#t34, block {
-    final core::Set<core::int> #t35 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t35 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t36 = a;
     if(!(#t36 == null))
       #t35.{core::Set::addAll}{Invariant}(#t36{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t35, block {
-    final core::Set<core::int> #t37 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t37 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t38 = b;
     if(!(#t38 == null))
       #t37.{core::Set::addAll}{Invariant}(#t38{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t37, block {
-    final core::Set<core::int> #t39 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t39 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t40 = c;
     if(!(#t40 == null))
       #t39.{core::Set::addAll}{Invariant}(#t40{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
@@ -380,7 +380,7 @@
     if(!(#t42 == null))
       #t41.{core::Map::addAll}{Invariant}(#t42{core::Map<core::int, core::int>}){(core::Map<core::int, core::int>) → void};
   } =>#t41, block {
-    final core::Set<core::int> #t43 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t43 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t44 = a;
       if(!(#t44 == null)) {
@@ -395,7 +395,7 @@
       }
     }
   } =>#t43, block {
-    final core::Set<core::int> #t47 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t47 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t48 = b;
       if(!(#t48 == null)) {
@@ -410,7 +410,7 @@
       }
     }
   } =>#t47, block {
-    final core::Set<core::int> #t51 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t51 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t52 = c;
       if(!(#t52 == null)) {
@@ -432,7 +432,7 @@
         #t55.{core::Map::addAll}{Invariant}(#t56{core::Map<core::int, core::int>}){(core::Map<core::int, core::int>) → void};
     }
   } =>#t55, block {
-    final core::Set<core::int> #t57 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t57 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -453,7 +453,7 @@
       }
     }
   } =>#t57, block {
-    final core::Set<core::int> #t61 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t61 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -474,7 +474,7 @@
       }
     }
   } =>#t61, block {
-    final core::Set<core::int> #t65 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t65 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -508,7 +508,7 @@
       }
     }
   } =>#t69, block {
-    final core::Set<core::int> #t71 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t71 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t72 = a;
       if(!(#t72 == null)) {
@@ -523,7 +523,7 @@
       }
     }
   } =>#t71, block {
-    final core::Set<core::int> #t75 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t75 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t76 = b;
       if(!(#t76 == null)) {
@@ -538,7 +538,7 @@
       }
     }
   } =>#t75, block {
-    final core::Set<core::int> #t79 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t79 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t80 = c;
       if(!(#t80 == null)) {
@@ -579,12 +579,12 @@
         ^": null}, <core::int, core::int>{invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:54:19: Error: Unexpected type 'X' of a map spread entry.  Expected 'dynamic' or a Map.
     <int, int>{...x}, // Error.
                   ^": null}, block {
-    final core::Set<core::int> #t88 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t88 = new col::_InternalLinkedHashSet::•<core::int>();
     #t88.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:55:14: Error: Unexpected type 'W' of a spread.  Expected 'dynamic' or an Iterable.
     <int>{...w}, // Error.
              ^"){(core::int) → core::bool};
   } =>#t88, block {
-    final core::Set<core::int> #t89 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t89 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:56:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...x}, // Error.
@@ -598,7 +598,7 @@
       }
     }
   } =>#t89, block {
-    final core::Set<core::int> #t92 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t92 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:57:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...y}, // Error.
@@ -612,7 +612,7 @@
       }
     }
   } =>#t92, block {
-    final core::Set<core::int> #t95 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t95 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:58:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...z}, // Error.
@@ -632,7 +632,7 @@
     {if (condition) ...w}, // Error.
                        ^", null){(core::int, core::int) → void};
   } =>#t98, block {
-    final core::Set<core::int> #t99 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t99 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -652,7 +652,7 @@
       }
     }
   } =>#t99, block {
-    final core::Set<core::int> #t102 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t102 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -672,7 +672,7 @@
       }
     }
   } =>#t102, block {
-    final core::Set<core::int> #t105 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t105 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -703,7 +703,7 @@
       }
     }
   } =>#t108, block {
-    final core::Set<core::int> #t109 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t109 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:64:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...x}, // Error.
@@ -717,7 +717,7 @@
       }
     }
   } =>#t109, block {
-    final core::Set<core::int> #t112 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t112 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:65:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...y}, // Error.
@@ -731,7 +731,7 @@
       }
     }
   } =>#t112, block {
-    final core::Set<core::int> #t115 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t115 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:66:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...z}, // Error.
@@ -751,17 +751,17 @@
     {for (int i = 0; i < 42; ++i) ...w}, // Error.
                                      ^", null){(core::int, core::int) → void};
   } =>#t118, block {
-    final core::Set<core::int> #t119 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t119 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t120 = x;
     if(!(#t120 == null))
       #t119.{core::Set::addAll}{Invariant}(#t120{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t119, block {
-    final core::Set<core::int> #t121 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t121 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t122 = y;
     if(!(#t122 == null))
       #t121.{core::Set::addAll}{Invariant}(#t122{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t121, block {
-    final core::Set<core::int> #t123 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t123 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t124 = z;
     if(!(#t124 == null))
       #t123.{core::Set::addAll}{Invariant}(#t124{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
@@ -771,7 +771,7 @@
     if(!(#t126 == null))
       #t125.{core::Map::addAll}{Invariant}(#t126{core::Map<core::int, core::int>}){(core::Map<core::int, core::int>) → void};
   } =>#t125, block {
-    final core::Set<core::int> #t127 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t127 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t128 = x;
       if(!(#t128 == null)) {
@@ -786,7 +786,7 @@
       }
     }
   } =>#t127, block {
-    final core::Set<core::int> #t131 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t131 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t132 = y;
       if(!(#t132 == null)) {
@@ -801,7 +801,7 @@
       }
     }
   } =>#t131, block {
-    final core::Set<core::int> #t135 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t135 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t136 = z;
       if(!(#t136 == null)) {
@@ -823,7 +823,7 @@
         #t139.{core::Map::addAll}{Invariant}(#t140{core::Map<core::int, core::int>}){(core::Map<core::int, core::int>) → void};
     }
   } =>#t139, block {
-    final core::Set<core::int> #t141 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t141 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -844,7 +844,7 @@
       }
     }
   } =>#t141, block {
-    final core::Set<core::int> #t145 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t145 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -865,7 +865,7 @@
       }
     }
   } =>#t145, block {
-    final core::Set<core::int> #t149 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t149 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -899,7 +899,7 @@
       }
     }
   } =>#t153, block {
-    final core::Set<core::int> #t155 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t155 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t156 = x;
       if(!(#t156 == null)) {
@@ -914,7 +914,7 @@
       }
     }
   } =>#t155, block {
-    final core::Set<core::int> #t159 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t159 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t160 = y;
       if(!(#t160 == null)) {
@@ -929,7 +929,7 @@
       }
     }
   } =>#t159, block {
-    final core::Set<core::int> #t163 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t163 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t164 = z;
       if(!(#t164 == null)) {
diff --git a/pkg/front_end/testcases/nnbd/issue43495.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue43495.dart.weak.transformed.expect
index 80cf8ea..f91d345 100644
--- a/pkg/front_end/testcases/nnbd/issue43495.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43495.dart.weak.transformed.expect
@@ -187,13 +187,13 @@
  - 'List' is from 'dart:core'.
     <int, int>{...a}, // Error.
                   ^": null}, block {
-    final core::Set<core::int> #t4 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t4 = new col::_InternalLinkedHashSet::•<core::int>();
     #t4.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:13:14: Error: Unexpected type 'Map<int, int>?' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
     <int>{...d}, // Error.
              ^"){(core::int) → core::bool};
   } =>#t4, block {
-    final core::Set<core::int> #t5 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t5 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:14:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...a}, // Error.
@@ -207,7 +207,7 @@
       }
     }
   } =>#t5, block {
-    final core::Set<core::int> #t8 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t8 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:15:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...b}, // Error.
@@ -221,7 +221,7 @@
       }
     }
   } =>#t8, block {
-    final core::Set<core::int> #t11 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t11 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:16:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...c}, // Error.
@@ -241,7 +241,7 @@
     {if (condition) ...d}, // Error.
                        ^", null){(core::int, core::int) → void};
   } =>#t14, block {
-    final core::Set<core::int> #t15 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t15 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -261,7 +261,7 @@
       }
     }
   } =>#t15, block {
-    final core::Set<core::int> #t18 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t18 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -281,7 +281,7 @@
       }
     }
   } =>#t18, block {
-    final core::Set<core::int> #t21 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t21 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -312,7 +312,7 @@
       }
     }
   } =>#t24, block {
-    final core::Set<core::int> #t25 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t25 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:22:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...a}, // Error.
@@ -326,7 +326,7 @@
       }
     }
   } =>#t25, block {
-    final core::Set<core::int> #t28 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t28 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:23:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...b}, // Error.
@@ -340,7 +340,7 @@
       }
     }
   } =>#t28, block {
-    final core::Set<core::int> #t31 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t31 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:24:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...c}, // Error.
@@ -360,17 +360,17 @@
     {for (int i = 0; i < 42; ++i) ...d}, // Error.
                                      ^", null){(core::int, core::int) → void};
   } =>#t34, block {
-    final core::Set<core::int> #t35 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t35 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t36 = a;
     if(!(#t36 == null))
       #t35.{core::Set::addAll}{Invariant}(#t36{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t35, block {
-    final core::Set<core::int> #t37 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t37 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t38 = b;
     if(!(#t38 == null))
       #t37.{core::Set::addAll}{Invariant}(#t38{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t37, block {
-    final core::Set<core::int> #t39 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t39 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t40 = c;
     if(!(#t40 == null))
       #t39.{core::Set::addAll}{Invariant}(#t40{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
@@ -380,7 +380,7 @@
     if(!(#t42 == null))
       #t41.{core::Map::addAll}{Invariant}(#t42{core::Map<core::int, core::int>}){(core::Map<core::int, core::int>) → void};
   } =>#t41, block {
-    final core::Set<core::int> #t43 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t43 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t44 = a;
       if(!(#t44 == null)) {
@@ -395,7 +395,7 @@
       }
     }
   } =>#t43, block {
-    final core::Set<core::int> #t47 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t47 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t48 = b;
       if(!(#t48 == null)) {
@@ -410,7 +410,7 @@
       }
     }
   } =>#t47, block {
-    final core::Set<core::int> #t51 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t51 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t52 = c;
       if(!(#t52 == null)) {
@@ -432,7 +432,7 @@
         #t55.{core::Map::addAll}{Invariant}(#t56{core::Map<core::int, core::int>}){(core::Map<core::int, core::int>) → void};
     }
   } =>#t55, block {
-    final core::Set<core::int> #t57 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t57 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -453,7 +453,7 @@
       }
     }
   } =>#t57, block {
-    final core::Set<core::int> #t61 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t61 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -474,7 +474,7 @@
       }
     }
   } =>#t61, block {
-    final core::Set<core::int> #t65 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t65 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -508,7 +508,7 @@
       }
     }
   } =>#t69, block {
-    final core::Set<core::int> #t71 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t71 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t72 = a;
       if(!(#t72 == null)) {
@@ -523,7 +523,7 @@
       }
     }
   } =>#t71, block {
-    final core::Set<core::int> #t75 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t75 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t76 = b;
       if(!(#t76 == null)) {
@@ -538,7 +538,7 @@
       }
     }
   } =>#t75, block {
-    final core::Set<core::int> #t79 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t79 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t80 = c;
       if(!(#t80 == null)) {
@@ -579,12 +579,12 @@
         ^": null}, <core::int, core::int>{invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:54:19: Error: Unexpected type 'X' of a map spread entry.  Expected 'dynamic' or a Map.
     <int, int>{...x}, // Error.
                   ^": null}, block {
-    final core::Set<core::int> #t88 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t88 = new col::_InternalLinkedHashSet::•<core::int>();
     #t88.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:55:14: Error: Unexpected type 'W' of a spread.  Expected 'dynamic' or an Iterable.
     <int>{...w}, // Error.
              ^"){(core::int) → core::bool};
   } =>#t88, block {
-    final core::Set<core::int> #t89 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t89 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:56:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...x}, // Error.
@@ -598,7 +598,7 @@
       }
     }
   } =>#t89, block {
-    final core::Set<core::int> #t92 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t92 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:57:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...y}, // Error.
@@ -612,7 +612,7 @@
       }
     }
   } =>#t92, block {
-    final core::Set<core::int> #t95 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t95 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:58:24: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {if (condition) ...z}, // Error.
@@ -632,7 +632,7 @@
     {if (condition) ...w}, // Error.
                        ^", null){(core::int, core::int) → void};
   } =>#t98, block {
-    final core::Set<core::int> #t99 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t99 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -652,7 +652,7 @@
       }
     }
   } =>#t99, block {
-    final core::Set<core::int> #t102 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t102 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -672,7 +672,7 @@
       }
     }
   } =>#t102, block {
-    final core::Set<core::int> #t105 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t105 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -703,7 +703,7 @@
       }
     }
   } =>#t108, block {
-    final core::Set<core::int> #t109 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t109 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:64:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...x}, // Error.
@@ -717,7 +717,7 @@
       }
     }
   } =>#t109, block {
-    final core::Set<core::int> #t112 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t112 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:65:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...y}, // Error.
@@ -731,7 +731,7 @@
       }
     }
   } =>#t112, block {
-    final core::Set<core::int> #t115 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t115 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       core::Iterator<Never> :sync-for-iterator = invalid-expression "pkg/front_end/testcases/nnbd/issue43495.dart:66:38: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
     {for (int i = 0; i < 42; ++i) ...z}, // Error.
@@ -751,17 +751,17 @@
     {for (int i = 0; i < 42; ++i) ...w}, // Error.
                                      ^", null){(core::int, core::int) → void};
   } =>#t118, block {
-    final core::Set<core::int> #t119 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t119 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t120 = x;
     if(!(#t120 == null))
       #t119.{core::Set::addAll}{Invariant}(#t120{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t119, block {
-    final core::Set<core::int> #t121 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t121 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t122 = y;
     if(!(#t122 == null))
       #t121.{core::Set::addAll}{Invariant}(#t122{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t121, block {
-    final core::Set<core::int> #t123 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t123 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t124 = z;
     if(!(#t124 == null))
       #t123.{core::Set::addAll}{Invariant}(#t124{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
@@ -771,7 +771,7 @@
     if(!(#t126 == null))
       #t125.{core::Map::addAll}{Invariant}(#t126{core::Map<core::int, core::int>}){(core::Map<core::int, core::int>) → void};
   } =>#t125, block {
-    final core::Set<core::int> #t127 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t127 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t128 = x;
       if(!(#t128 == null)) {
@@ -786,7 +786,7 @@
       }
     }
   } =>#t127, block {
-    final core::Set<core::int> #t131 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t131 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t132 = y;
       if(!(#t132 == null)) {
@@ -801,7 +801,7 @@
       }
     }
   } =>#t131, block {
-    final core::Set<core::int> #t135 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t135 = new col::_InternalLinkedHashSet::•<core::int>();
     if(condition) {
       final core::Iterable<dynamic>? #t136 = z;
       if(!(#t136 == null)) {
@@ -823,7 +823,7 @@
         #t139.{core::Map::addAll}{Invariant}(#t140{core::Map<core::int, core::int>}){(core::Map<core::int, core::int>) → void};
     }
   } =>#t139, block {
-    final core::Set<core::int> #t141 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t141 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -844,7 +844,7 @@
       }
     }
   } =>#t141, block {
-    final core::Set<core::int> #t145 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t145 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -865,7 +865,7 @@
       }
     }
   } =>#t145, block {
-    final core::Set<core::int> #t149 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t149 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = iterable.{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -899,7 +899,7 @@
       }
     }
   } =>#t153, block {
-    final core::Set<core::int> #t155 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t155 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t156 = x;
       if(!(#t156 == null)) {
@@ -914,7 +914,7 @@
       }
     }
   } =>#t155, block {
-    final core::Set<core::int> #t159 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t159 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t160 = y;
       if(!(#t160 == null)) {
@@ -929,7 +929,7 @@
       }
     }
   } =>#t159, block {
-    final core::Set<core::int> #t163 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t163 = new col::_InternalLinkedHashSet::•<core::int>();
     for (core::int i = 0; i.{core::num::<}(42){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
       final core::Iterable<dynamic>? #t164 = z;
       if(!(#t164 == null)) {
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.strong.expect
index 8429111..922b391 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.strong.expect
@@ -5,7 +5,7 @@
 import "dart:async";
 
 typedef Exactly<invariant T extends core::Object? = dynamic> = (T%) → T%;
-extension _extension#0<T extends core::Object? = dynamic> on T% {
+extension /* unnamed */ _extension#0<T extends core::Object? = dynamic> on T% {
   method checkStaticType = self::_extension#0|checkStaticType;
   tearoff checkStaticType = self::_extension#0|get#checkStaticType;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.strong.transformed.expect
index 8429111..922b391 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.strong.transformed.expect
@@ -5,7 +5,7 @@
 import "dart:async";
 
 typedef Exactly<invariant T extends core::Object? = dynamic> = (T%) → T%;
-extension _extension#0<T extends core::Object? = dynamic> on T% {
+extension /* unnamed */ _extension#0<T extends core::Object? = dynamic> on T% {
   method checkStaticType = self::_extension#0|checkStaticType;
   tearoff checkStaticType = self::_extension#0|get#checkStaticType;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.expect
index 8429111..922b391 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.expect
@@ -5,7 +5,7 @@
 import "dart:async";
 
 typedef Exactly<invariant T extends core::Object? = dynamic> = (T%) → T%;
-extension _extension#0<T extends core::Object? = dynamic> on T% {
+extension /* unnamed */ _extension#0<T extends core::Object? = dynamic> on T% {
   method checkStaticType = self::_extension#0|checkStaticType;
   tearoff checkStaticType = self::_extension#0|get#checkStaticType;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.modular.expect
index 8429111..922b391 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.modular.expect
@@ -5,7 +5,7 @@
 import "dart:async";
 
 typedef Exactly<invariant T extends core::Object? = dynamic> = (T%) → T%;
-extension _extension#0<T extends core::Object? = dynamic> on T% {
+extension /* unnamed */ _extension#0<T extends core::Object? = dynamic> on T% {
   method checkStaticType = self::_extension#0|checkStaticType;
   tearoff checkStaticType = self::_extension#0|get#checkStaticType;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.outline.expect
index d770a61..4d4c256 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.outline.expect
@@ -5,7 +5,7 @@
 import "dart:async";
 
 typedef Exactly<invariant T extends core::Object? = dynamic> = (T%) → T%;
-extension _extension#0<T extends core::Object? = dynamic> on T% {
+extension /* unnamed */ _extension#0<T extends core::Object? = dynamic> on T% {
   method checkStaticType = self::_extension#0|checkStaticType;
   tearoff checkStaticType = self::_extension#0|get#checkStaticType;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.transformed.expect
index 8429111..922b391 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.transformed.expect
@@ -5,7 +5,7 @@
 import "dart:async";
 
 typedef Exactly<invariant T extends core::Object? = dynamic> = (T%) → T%;
-extension _extension#0<T extends core::Object? = dynamic> on T% {
+extension /* unnamed */ _extension#0<T extends core::Object? = dynamic> on T% {
   method checkStaticType = self::_extension#0|checkStaticType;
   tearoff checkStaticType = self::_extension#0|get#checkStaticType;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.expect
index a2ff9df..62b69c3 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.expect
@@ -8,7 +8,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::A? {
+extension /* unnamed */ _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
 static method _extension#0|get#text(lowered final self::A? #this) → core::String
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.transformed.expect
index a2ff9df..62b69c3 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::A? {
+extension /* unnamed */ _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
 static method _extension#0|get#text(lowered final self::A? #this) → core::String
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.expect
index a2ff9df..62b69c3 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.expect
@@ -8,7 +8,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::A? {
+extension /* unnamed */ _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
 static method _extension#0|get#text(lowered final self::A? #this) → core::String
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.modular.expect
index a2ff9df..62b69c3 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.modular.expect
@@ -8,7 +8,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::A? {
+extension /* unnamed */ _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
 static method _extension#0|get#text(lowered final self::A? #this) → core::String
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.outline.expect
index 79d4bd9..fec97de 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.outline.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → self::A
     ;
 }
-extension _extension#0 on self::A? {
+extension /* unnamed */ _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
 static method _extension#0|get#text(lowered final self::A? #this) → core::String
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.transformed.expect
index a2ff9df..62b69c3 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on self::A? {
+extension /* unnamed */ _extension#0 on self::A? {
   get text = self::_extension#0|get#text;
 }
 static method _extension#0|get#text(lowered final self::A? #this) → core::String
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.expect
index 297e474..63e8f0d 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.expect
@@ -10,7 +10,7 @@
   set setter(core::String v) → void {}
   operator []=(core::int index, core::String value) → void {}
 }
-extension _extension#0 on self::C? {
+extension /* unnamed */ _extension#0 on self::C? {
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.transformed.expect
index 321c92b..9e75dfb 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.transformed.expect
@@ -10,7 +10,7 @@
   set setter(core::String v) → void {}
   operator []=(core::int index, core::String value) → void {}
 }
-extension _extension#0 on self::C? {
+extension /* unnamed */ _extension#0 on self::C? {
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.expect
index 297e474..63e8f0d 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.expect
@@ -10,7 +10,7 @@
   set setter(core::String v) → void {}
   operator []=(core::int index, core::String value) → void {}
 }
-extension _extension#0 on self::C? {
+extension /* unnamed */ _extension#0 on self::C? {
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.modular.expect
index 297e474..63e8f0d 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.modular.expect
@@ -10,7 +10,7 @@
   set setter(core::String v) → void {}
   operator []=(core::int index, core::String value) → void {}
 }
-extension _extension#0 on self::C? {
+extension /* unnamed */ _extension#0 on self::C? {
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.outline.expect
index 57f6140..1f954c6 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.outline.expect
@@ -11,7 +11,7 @@
   operator []=(core::int index, core::String value) → void
     ;
 }
-extension _extension#0 on self::C? {
+extension /* unnamed */ _extension#0 on self::C? {
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.transformed.expect
index 321c92b..9e75dfb 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.transformed.expect
@@ -10,7 +10,7 @@
   set setter(core::String v) → void {}
   operator []=(core::int index, core::String value) → void {}
 }
-extension _extension#0 on self::C? {
+extension /* unnamed */ _extension#0 on self::C? {
   operator []= = self::_extension#0|[]=;
   set setter = self::_extension#0|set#setter;
 }
diff --git a/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.transformed.expect
index c819d5f..25f4587 100644
--- a/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/spread_if_null.dart.strong.transformed.expect
@@ -47,7 +47,7 @@
   } =>#t11;
   has-declared-initializer core::Set<core::int>? set = null;
   core::print( block {
-    final core::Set<core::int> #t13 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t13 = new col::_InternalLinkedHashSet::•<core::int>();
     #t13.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t13.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
     final core::Iterable<core::int>? #t14 = set;
@@ -56,7 +56,7 @@
     #t13.{core::Set::add}{Invariant}(3){(core::int) → core::bool};
   } =>#t13);
   core::print( block {
-    final core::Set<core::int> #t15 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t15 = new col::_InternalLinkedHashSet::•<core::int>();
     #t15.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t15.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
     final has-declared-initializer core::Iterable<core::int>? #t16 = null;
@@ -65,13 +65,13 @@
     #t15.{core::Set::add}{Invariant}(3){(core::int) → core::bool};
   } =>#t15);
   core::Set<core::int> set1 = block {
-    final core::Set<core::int> #t17 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t17 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t18 = set;
     if(!(#t18 == null))
       #t17.{core::Set::addAll}{Invariant}(#t18{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t17;
   core::Set<core::int> set3 = block {
-    final core::Set<core::int> #t19 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t19 = new col::_InternalLinkedHashSet::•<core::int>();
     #t19.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t19.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
     final core::Iterable<core::int>? #t20 = set;
@@ -80,7 +80,7 @@
     #t19.{core::Set::add}{Invariant}(3){(core::int) → core::bool};
   } =>#t19;
   core::Set<core::int> set4 = block {
-    final core::Set<core::int> #t21 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t21 = new col::_InternalLinkedHashSet::•<core::int>();
     #t21.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t21.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
     final has-declared-initializer core::Iterable<core::int>? #t22 = null;
diff --git a/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.transformed.expect
index c819d5f..25f4587 100644
--- a/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/spread_if_null.dart.weak.transformed.expect
@@ -47,7 +47,7 @@
   } =>#t11;
   has-declared-initializer core::Set<core::int>? set = null;
   core::print( block {
-    final core::Set<core::int> #t13 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t13 = new col::_InternalLinkedHashSet::•<core::int>();
     #t13.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t13.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
     final core::Iterable<core::int>? #t14 = set;
@@ -56,7 +56,7 @@
     #t13.{core::Set::add}{Invariant}(3){(core::int) → core::bool};
   } =>#t13);
   core::print( block {
-    final core::Set<core::int> #t15 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t15 = new col::_InternalLinkedHashSet::•<core::int>();
     #t15.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t15.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
     final has-declared-initializer core::Iterable<core::int>? #t16 = null;
@@ -65,13 +65,13 @@
     #t15.{core::Set::add}{Invariant}(3){(core::int) → core::bool};
   } =>#t15);
   core::Set<core::int> set1 = block {
-    final core::Set<core::int> #t17 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t17 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t18 = set;
     if(!(#t18 == null))
       #t17.{core::Set::addAll}{Invariant}(#t18{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
   } =>#t17;
   core::Set<core::int> set3 = block {
-    final core::Set<core::int> #t19 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t19 = new col::_InternalLinkedHashSet::•<core::int>();
     #t19.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t19.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
     final core::Iterable<core::int>? #t20 = set;
@@ -80,7 +80,7 @@
     #t19.{core::Set::add}{Invariant}(3){(core::int) → core::bool};
   } =>#t19;
   core::Set<core::int> set4 = block {
-    final core::Set<core::int> #t21 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t21 = new col::_InternalLinkedHashSet::•<core::int>();
     #t21.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t21.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
     final has-declared-initializer core::Iterable<core::int>? #t22 = null;
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
index 4b5b46a..b641bbf 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
@@ -144,13 +144,13 @@
       #t5.{core::List::addAll}{Invariant}(#t6{core::Iterable<core::String>}){(core::Iterable<core::String>) → void};
   } =>#t5;
   core::Set<core::String> a = block {
-    final core::Set<core::String> #t7 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Set<core::String> #t7 = new col::_InternalLinkedHashSet::•<core::String>();
     final core::Iterable<core::String>? #t8 = l;
     if(!(#t8 == null))
       #t7.{core::Set::addAll}{Invariant}(#t8{core::Iterable<core::String>}){(core::Iterable<core::String>) → void};
   } =>#t7;
   block {
-    final core::Set<core::String> #t9 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Set<core::String> #t9 = new col::_InternalLinkedHashSet::•<core::String>();
     final core::Iterable<core::String>? #t10 = l;
     if(!(#t10 == null))
       #t9.{core::Set::addAll}{Invariant}(#t10{core::Iterable<core::String>}){(core::Iterable<core::String>) → void};
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
index 4b5b46a..b641bbf 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
@@ -144,13 +144,13 @@
       #t5.{core::List::addAll}{Invariant}(#t6{core::Iterable<core::String>}){(core::Iterable<core::String>) → void};
   } =>#t5;
   core::Set<core::String> a = block {
-    final core::Set<core::String> #t7 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Set<core::String> #t7 = new col::_InternalLinkedHashSet::•<core::String>();
     final core::Iterable<core::String>? #t8 = l;
     if(!(#t8 == null))
       #t7.{core::Set::addAll}{Invariant}(#t8{core::Iterable<core::String>}){(core::Iterable<core::String>) → void};
   } =>#t7;
   block {
-    final core::Set<core::String> #t9 = new col::_CompactLinkedHashSet::•<core::String>();
+    final core::Set<core::String> #t9 = new col::_InternalLinkedHashSet::•<core::String>();
     final core::Iterable<core::String>? #t10 = l;
     if(!(#t10 == null))
       #t9.{core::Set::addAll}{Invariant}(#t10{core::Iterable<core::String>}){(core::Iterable<core::String>) → void};
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/inherited_implements.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/inherited_implements.dart.weak.outline.expect
index 645b335..06d61c1 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/inherited_implements.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/inherited_implements.dart.weak.outline.expect
@@ -245,14 +245,14 @@
 Extra constant evaluation status:
 Evaluated: StaticGet @ org-dartlang-testcase:///inherited_implements.dart:28:4 -> InstanceConstant(const _Override{})
 Evaluated: StaticGet @ org-dartlang-testcase:///inherited_implements.dart:37:4 -> InstanceConstant(const _Override{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///inherited_implements.dart:20:7 -> SymbolConstant(#mixedInMethod)
-Evaluated: ListLiteral @ org-dartlang-testcase:///inherited_implements.dart:20:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///inherited_implements.dart:20:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///inherited_implements.dart:20:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///inherited_implements.dart:19:7 -> SymbolConstant(#extendedMethod)
-Evaluated: ListLiteral @ org-dartlang-testcase:///inherited_implements.dart:19:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///inherited_implements.dart:19:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///inherited_implements.dart:19:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///inherited_implements.dart:36:7 -> SymbolConstant(#mixedInMethod)
+Evaluated: ListLiteral @ org-dartlang-testcase:///inherited_implements.dart:36:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///inherited_implements.dart:36:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///inherited_implements.dart:36:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///inherited_implements.dart:36:7 -> SymbolConstant(#extendedMethod)
+Evaluated: ListLiteral @ org-dartlang-testcase:///inherited_implements.dart:36:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///inherited_implements.dart:36:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///inherited_implements.dart:36:7 -> MapConstant(const <Symbol*, dynamic>{})
 Evaluated: StaticGet @ org-dartlang-testcase:///inherited_implements.dart:49:4 -> InstanceConstant(const _Override{})
 Evaluated: StaticGet @ org-dartlang-testcase:///inherited_implements.dart:59:4 -> InstanceConstant(const _Override{})
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///inherited_implements.dart:64:7 -> SymbolConstant(#extendedMethod)
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.expect
index 980d6fe..8b2c4aa 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.expect
@@ -70,19 +70,27 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:32:8: Error: 'NoMethodForPrivateNameError' isn't a type.
+//   } on NoMethodForPrivateNameError (e) {
+//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
 // pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:32:8: Error: A catch clause must have a body, even if it is empty.
 // Try adding an empty body.
-//   } on NoSuchMethodError (e) {
-//        ^^^^^^^^^^^^^^^^^
+//   } on NoMethodForPrivateNameError (e) {
+//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 //
 // pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:34:3: Error: Expected ';' after this.
 //   }
 //   ^
 //
+// pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:38:8: Error: 'NoMethodForPrivateNameError' isn't a type.
+//   } on NoMethodForPrivateNameError (e) {
+//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
 // pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:38:8: Error: A catch clause must have a body, even if it is empty.
 // Try adding an empty body.
-//   } on NoSuchMethodError (e) {
-//        ^^^^^^^^^^^^^^^^^
+//   } on NoMethodForPrivateNameError (e) {
+//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 //
 // pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:40:3: Error: Expected ';' after this.
 //   }
@@ -133,18 +141,18 @@
 static method testInterface2(opt::Interface2 c) → dynamic {
   try {
     c.{opt::Interface2::_privateGetter}{opt::A};
-    throw "Expected NoSuchMethodError";
+    throw "Expected NoMethodForPrivateNameError";
   }
-  on core::NoSuchMethodError catch(no-exception-var) {
+  on invalid-type catch(no-exception-var) {
   }
   (dynamic e) → Null {
     core::print(e);
   };
   try {
     c.{opt::Interface2::_privateSetter} = new opt::C::•();
-    throw "Expected NoSuchMethodError";
+    throw "Expected NoMethodForPrivateNameError";
   }
-  on core::NoSuchMethodError catch(no-exception-var) {
+  on invalid-type catch(no-exception-var) {
   }
   (dynamic e) → Null {
     core::print(e);
@@ -162,10 +170,10 @@
   synthetic constructor •() → opt3::Mixin2
     : super core::Object::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///opt_in_lib1.dart */ _privateGetter() → opt::A
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} opt::A;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///opt_in_lib1.dart */ _privateSetter(opt::C c) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(c)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _privateGetter() → opt::A
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _privateSetter(opt::C c) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(c)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 
 library;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.outline.expect
index e5c1602..6cffbf8 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.outline.expect
@@ -111,10 +111,10 @@
 class Mixin2 extends core::Object implements opt::Interface2 {
   synthetic constructor •() → opt3::Mixin2
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///opt_in_lib1.dart */ _privateGetter() → opt::A
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} opt::A;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///opt_in_lib1.dart */ _privateSetter(opt::C c) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(c)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _privateGetter() → opt::A
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _privateSetter(opt::C c) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(c)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 
 library;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.transformed.expect
index be4c652..1e9bffc 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/main.dart.weak.transformed.expect
@@ -70,19 +70,27 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:32:8: Error: 'NoMethodForPrivateNameError' isn't a type.
+//   } on NoMethodForPrivateNameError (e) {
+//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
 // pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:32:8: Error: A catch clause must have a body, even if it is empty.
 // Try adding an empty body.
-//   } on NoSuchMethodError (e) {
-//        ^^^^^^^^^^^^^^^^^
+//   } on NoMethodForPrivateNameError (e) {
+//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 //
 // pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:34:3: Error: Expected ';' after this.
 //   }
 //   ^
 //
+// pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:38:8: Error: 'NoMethodForPrivateNameError' isn't a type.
+//   } on NoMethodForPrivateNameError (e) {
+//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
 // pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:38:8: Error: A catch clause must have a body, even if it is empty.
 // Try adding an empty body.
-//   } on NoSuchMethodError (e) {
-//        ^^^^^^^^^^^^^^^^^
+//   } on NoMethodForPrivateNameError (e) {
+//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 //
 // pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart:40:3: Error: Expected ';' after this.
 //   }
@@ -133,18 +141,18 @@
 static method testInterface2(opt::Interface2 c) → dynamic {
   try {
     c.{opt::Interface2::_privateGetter}{opt::A};
-    throw "Expected NoSuchMethodError";
+    throw "Expected NoMethodForPrivateNameError";
   }
-  on core::NoSuchMethodError catch(no-exception-var) {
+  on invalid-type catch(no-exception-var) {
   }
   (dynamic e) → Null {
     core::print(e);
   };
   try {
     c.{opt::Interface2::_privateSetter} = new opt::C::•();
-    throw "Expected NoSuchMethodError";
+    throw "Expected NoMethodForPrivateNameError";
   }
-  on core::NoSuchMethodError catch(no-exception-var) {
+  on invalid-type catch(no-exception-var) {
   }
   (dynamic e) → Null {
     core::print(e);
@@ -162,10 +170,10 @@
   synthetic constructor •() → opt3::Mixin2
     : super core::Object::•()
     ;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///opt_in_lib1.dart */ _privateGetter() → opt::A
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} opt::A;
-  no-such-method-forwarder set /* from org-dartlang-testcase:///opt_in_lib1.dart */ _privateSetter(opt::C c) → void
-    return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(c)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation) → dynamic};
+  no-such-method-forwarder get _privateGetter() → opt::A
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
+  no-such-method-forwarder set _privateSetter(opt::C c) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(c)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 
 library;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart b/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart
index 0019ab0..28cc070 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/mixin_from_dill/opt_in_lib1.dart
@@ -28,14 +28,14 @@
 testInterface2(Interface2 c) {
   try {
     c._privateGetter;
-    throw 'Expected NoSuchMethodError';
-  } on NoSuchMethodError (e) {
+    throw 'Expected NoMethodForPrivateNameError';
+  } on NoMethodForPrivateNameError (e) {
     print(e);
   }
   try {
     c._privateSetter = new C();
-    throw 'Expected NoSuchMethodError';
-  } on NoSuchMethodError (e) {
+    throw 'Expected NoMethodForPrivateNameError';
+  } on NoMethodForPrivateNameError (e) {
     print(e);
   }
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/no_such_method.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/no_such_method.dart.weak.outline.expect
index bb3b265..2b7da3f 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/no_such_method.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/no_such_method.dart.weak.outline.expect
@@ -330,117 +330,117 @@
 
 Extra constant evaluation status:
 Evaluated: StaticGet @ org-dartlang-testcase:///no_such_method.dart:20:4 -> InstanceConstant(const _Override{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> SymbolConstant(#getter)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> SymbolConstant(#field)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> SymbolConstant(#method)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> SymbolConstant(#finalField)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> SymbolConstant(#setter=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> SymbolConstant(#field=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> SymbolConstant(#getter)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> SymbolConstant(#field)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> SymbolConstant(#method)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> SymbolConstant(#finalField)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> SymbolConstant(#setter=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> SymbolConstant(#field=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> SymbolConstant(#getter)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> SymbolConstant(#field)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> SymbolConstant(#method)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> SymbolConstant(#finalField)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> SymbolConstant(#setter=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> SymbolConstant(#field=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:26:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> SymbolConstant(#getter)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> SymbolConstant(#field)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> SymbolConstant(#method)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> SymbolConstant(#finalField)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> SymbolConstant(#setter=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> SymbolConstant(#field=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:28:7 -> MapConstant(const <Symbol*, dynamic>{})
 Evaluated: StaticGet @ org-dartlang-testcase:///no_such_method.dart:38:4 -> InstanceConstant(const _Override{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> SymbolConstant(#getter)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> SymbolConstant(#field)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> SymbolConstant(#method)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> SymbolConstant(#finalField)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> SymbolConstant(#setter=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> SymbolConstant(#field=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> SymbolConstant(#getter)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> SymbolConstant(#field)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> SymbolConstant(#method)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> SymbolConstant(#finalField)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> SymbolConstant(#setter=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> SymbolConstant(#field=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> SymbolConstant(#getter)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> SymbolConstant(#field)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> SymbolConstant(#method)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> SymbolConstant(#finalField)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> SymbolConstant(#setter=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> SymbolConstant(#field=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:44:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> SymbolConstant(#getter)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> SymbolConstant(#field)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> SymbolConstant(#method)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> SymbolConstant(#finalField)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> SymbolConstant(#setter=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> SymbolConstant(#field=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:46:7 -> MapConstant(const <Symbol*, dynamic>{})
 Evaluated: StaticGet @ org-dartlang-testcase:///no_such_method.dart:57:4 -> InstanceConstant(const _Override{})
 Evaluated: StaticGet @ org-dartlang-testcase:///no_such_method.dart:70:4 -> InstanceConstant(const _Override{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> SymbolConstant(#getter)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:7:11 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> SymbolConstant(#field)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> SymbolConstant(#method)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:6:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> SymbolConstant(#finalField)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:10:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> SymbolConstant(#setter=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:8:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> SymbolConstant(#field=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:9:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> SymbolConstant(#getter)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> SymbolConstant(#field)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> SymbolConstant(#method)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> SymbolConstant(#finalField)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> SymbolConstant(#setter=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> SymbolConstant(#field=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_such_method.dart:69:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 283, effectively constant: 114
diff --git a/pkg/front_end/testcases/nnbd_mixed/infer_constraints_from_opt_in.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/infer_constraints_from_opt_in.dart.weak.transformed.expect
index 865f8c3..3916537 100644
--- a/pkg/front_end/testcases/nnbd_mixed/infer_constraints_from_opt_in.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/infer_constraints_from_opt_in.dart.weak.transformed.expect
@@ -36,82 +36,82 @@
   core::List<core::int*>* local1h = core::_GrowableList::_literal1<core::int*>(inf::field8);
   core::List<Null>* local1i = core::_GrowableList::_literal1<Null>(null);
   core::Set<inf::C<dynamic>*>* local2a = block {
-    final core::Set<inf::C<dynamic>*>* #t1 = new col::_CompactLinkedHashSet::•<inf::C<dynamic>*>();
+    final core::Set<inf::C<dynamic>*>* #t1 = new col::_InternalLinkedHashSet::•<inf::C<dynamic>*>();
     #t1.{core::Set::add}{Invariant}(inf::field1){(inf::C<dynamic>*) →* core::bool*};
     #t1.{core::Set::add}{Invariant}(null){(inf::C<dynamic>*) →* core::bool*};
   } =>#t1;
   core::Set<inf::C<dynamic>*>* local2b = block {
-    final core::Set<inf::C<dynamic>*>* #t2 = new col::_CompactLinkedHashSet::•<inf::C<dynamic>*>();
+    final core::Set<inf::C<dynamic>*>* #t2 = new col::_InternalLinkedHashSet::•<inf::C<dynamic>*>();
     #t2.{core::Set::add}{Invariant}(inf::field2){(inf::C<dynamic>*) →* core::bool*};
     #t2.{core::Set::add}{Invariant}(null){(inf::C<dynamic>*) →* core::bool*};
   } =>#t2;
   core::Set<inf::C<core::int*>*>* local2c = block {
-    final core::Set<inf::C<core::int*>*>* #t3 = new col::_CompactLinkedHashSet::•<inf::C<core::int*>*>();
+    final core::Set<inf::C<core::int*>*>* #t3 = new col::_InternalLinkedHashSet::•<inf::C<core::int*>*>();
     #t3.{core::Set::add}{Invariant}(inf::field3){(inf::C<core::int*>*) →* core::bool*};
     #t3.{core::Set::add}{Invariant}(null){(inf::C<core::int*>*) →* core::bool*};
   } =>#t3;
   core::Set<inf::C<core::int*>*>* local2d = block {
-    final core::Set<inf::C<core::int*>*>* #t4 = new col::_CompactLinkedHashSet::•<inf::C<core::int*>*>();
+    final core::Set<inf::C<core::int*>*>* #t4 = new col::_InternalLinkedHashSet::•<inf::C<core::int*>*>();
     #t4.{core::Set::add}{Invariant}(inf::field4){(inf::C<core::int*>*) →* core::bool*};
     #t4.{core::Set::add}{Invariant}(null){(inf::C<core::int*>*) →* core::bool*};
   } =>#t4;
   core::Set<inf::C<core::int*>*>* local2e = block {
-    final core::Set<inf::C<core::int*>*>* #t5 = new col::_CompactLinkedHashSet::•<inf::C<core::int*>*>();
+    final core::Set<inf::C<core::int*>*>* #t5 = new col::_InternalLinkedHashSet::•<inf::C<core::int*>*>();
     #t5.{core::Set::add}{Invariant}(inf::field5){(inf::C<core::int*>*) →* core::bool*};
     #t5.{core::Set::add}{Invariant}(null){(inf::C<core::int*>*) →* core::bool*};
   } =>#t5;
   core::Set<inf::C<core::int*>*>* local2f = block {
-    final core::Set<inf::C<core::int*>*>* #t6 = new col::_CompactLinkedHashSet::•<inf::C<core::int*>*>();
+    final core::Set<inf::C<core::int*>*>* #t6 = new col::_InternalLinkedHashSet::•<inf::C<core::int*>*>();
     #t6.{core::Set::add}{Invariant}(inf::field6){(inf::C<core::int*>*) →* core::bool*};
     #t6.{core::Set::add}{Invariant}(null){(inf::C<core::int*>*) →* core::bool*};
   } =>#t6;
   core::Set<core::int*>* local2g = block {
-    final core::Set<core::int*>* #t7 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t7 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t7.{core::Set::add}{Invariant}(inf::field7){(core::int*) →* core::bool*};
     #t7.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
   } =>#t7;
   core::Set<core::int*>* local2h = block {
-    final core::Set<core::int*>* #t8 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t8 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t8.{core::Set::add}{Invariant}(inf::field8){(core::int*) →* core::bool*};
     #t8.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
   } =>#t8;
   core::Set<inf::C<dynamic>*>* local3a = block {
-    final core::Set<inf::C<dynamic>*>* #t9 = new col::_CompactLinkedHashSet::•<inf::C<dynamic>*>();
+    final core::Set<inf::C<dynamic>*>* #t9 = new col::_InternalLinkedHashSet::•<inf::C<dynamic>*>();
     #t9.{core::Set::add}{Invariant}(null){(inf::C<dynamic>*) →* core::bool*};
     #t9.{core::Set::add}{Invariant}(inf::field1){(inf::C<dynamic>*) →* core::bool*};
   } =>#t9;
   core::Set<inf::C<dynamic>*>* local3b = block {
-    final core::Set<inf::C<dynamic>*>* #t10 = new col::_CompactLinkedHashSet::•<inf::C<dynamic>*>();
+    final core::Set<inf::C<dynamic>*>* #t10 = new col::_InternalLinkedHashSet::•<inf::C<dynamic>*>();
     #t10.{core::Set::add}{Invariant}(null){(inf::C<dynamic>*) →* core::bool*};
     #t10.{core::Set::add}{Invariant}(inf::field2){(inf::C<dynamic>*) →* core::bool*};
   } =>#t10;
   core::Set<inf::C<core::int*>*>* local3c = block {
-    final core::Set<inf::C<core::int*>*>* #t11 = new col::_CompactLinkedHashSet::•<inf::C<core::int*>*>();
+    final core::Set<inf::C<core::int*>*>* #t11 = new col::_InternalLinkedHashSet::•<inf::C<core::int*>*>();
     #t11.{core::Set::add}{Invariant}(null){(inf::C<core::int*>*) →* core::bool*};
     #t11.{core::Set::add}{Invariant}(inf::field3){(inf::C<core::int*>*) →* core::bool*};
   } =>#t11;
   core::Set<inf::C<core::int*>*>* local3d = block {
-    final core::Set<inf::C<core::int*>*>* #t12 = new col::_CompactLinkedHashSet::•<inf::C<core::int*>*>();
+    final core::Set<inf::C<core::int*>*>* #t12 = new col::_InternalLinkedHashSet::•<inf::C<core::int*>*>();
     #t12.{core::Set::add}{Invariant}(null){(inf::C<core::int*>*) →* core::bool*};
     #t12.{core::Set::add}{Invariant}(inf::field4){(inf::C<core::int*>*) →* core::bool*};
   } =>#t12;
   core::Set<inf::C<core::int*>*>* local3e = block {
-    final core::Set<inf::C<core::int*>*>* #t13 = new col::_CompactLinkedHashSet::•<inf::C<core::int*>*>();
+    final core::Set<inf::C<core::int*>*>* #t13 = new col::_InternalLinkedHashSet::•<inf::C<core::int*>*>();
     #t13.{core::Set::add}{Invariant}(null){(inf::C<core::int*>*) →* core::bool*};
     #t13.{core::Set::add}{Invariant}(inf::field5){(inf::C<core::int*>*) →* core::bool*};
   } =>#t13;
   core::Set<inf::C<core::int*>*>* local3f = block {
-    final core::Set<inf::C<core::int*>*>* #t14 = new col::_CompactLinkedHashSet::•<inf::C<core::int*>*>();
+    final core::Set<inf::C<core::int*>*>* #t14 = new col::_InternalLinkedHashSet::•<inf::C<core::int*>*>();
     #t14.{core::Set::add}{Invariant}(null){(inf::C<core::int*>*) →* core::bool*};
     #t14.{core::Set::add}{Invariant}(inf::field6){(inf::C<core::int*>*) →* core::bool*};
   } =>#t14;
   core::Set<core::int*>* local3g = block {
-    final core::Set<core::int*>* #t15 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t15 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t15.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
     #t15.{core::Set::add}{Invariant}(inf::field7){(core::int*) →* core::bool*};
   } =>#t15;
   core::Set<core::int*>* local3h = block {
-    final core::Set<core::int*>* #t16 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t16 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t16.{core::Set::add}{Invariant}(null){(core::int*) →* core::bool*};
     #t16.{core::Set::add}{Invariant}(inf::field8){(core::int*) →* core::bool*};
   } =>#t16;
@@ -166,82 +166,82 @@
   core::List<core::int?> local1h = core::_GrowableList::_literal1<core::int?>(inf::field8);
   core::List<Null> local1i = core::_GrowableList::_literal1<Null>(null);
   core::Set<inf::C<dynamic>?> local2a = block {
-    final core::Set<inf::C<dynamic>?> #t17 = new col::_CompactLinkedHashSet::•<inf::C<dynamic>?>();
+    final core::Set<inf::C<dynamic>?> #t17 = new col::_InternalLinkedHashSet::•<inf::C<dynamic>?>();
     #t17.{core::Set::add}{Invariant}(inf::field1){(inf::C<dynamic>?) → core::bool};
     #t17.{core::Set::add}{Invariant}(null){(inf::C<dynamic>?) → core::bool};
   } =>#t17;
   core::Set<inf::C<dynamic>?> local2b = block {
-    final core::Set<inf::C<dynamic>?> #t18 = new col::_CompactLinkedHashSet::•<inf::C<dynamic>?>();
+    final core::Set<inf::C<dynamic>?> #t18 = new col::_InternalLinkedHashSet::•<inf::C<dynamic>?>();
     #t18.{core::Set::add}{Invariant}(inf::field2){(inf::C<dynamic>?) → core::bool};
     #t18.{core::Set::add}{Invariant}(null){(inf::C<dynamic>?) → core::bool};
   } =>#t18;
   core::Set<inf::C<core::int>?> local2c = block {
-    final core::Set<inf::C<core::int>?> #t19 = new col::_CompactLinkedHashSet::•<inf::C<core::int>?>();
+    final core::Set<inf::C<core::int>?> #t19 = new col::_InternalLinkedHashSet::•<inf::C<core::int>?>();
     #t19.{core::Set::add}{Invariant}(inf::field3){(inf::C<core::int>?) → core::bool};
     #t19.{core::Set::add}{Invariant}(null){(inf::C<core::int>?) → core::bool};
   } =>#t19;
   core::Set<inf::C<core::int>?> local2d = block {
-    final core::Set<inf::C<core::int>?> #t20 = new col::_CompactLinkedHashSet::•<inf::C<core::int>?>();
+    final core::Set<inf::C<core::int>?> #t20 = new col::_InternalLinkedHashSet::•<inf::C<core::int>?>();
     #t20.{core::Set::add}{Invariant}(inf::field4){(inf::C<core::int>?) → core::bool};
     #t20.{core::Set::add}{Invariant}(null){(inf::C<core::int>?) → core::bool};
   } =>#t20;
   core::Set<inf::C<core::int?>?> local2e = block {
-    final core::Set<inf::C<core::int?>?> #t21 = new col::_CompactLinkedHashSet::•<inf::C<core::int?>?>();
+    final core::Set<inf::C<core::int?>?> #t21 = new col::_InternalLinkedHashSet::•<inf::C<core::int?>?>();
     #t21.{core::Set::add}{Invariant}(inf::field5){(inf::C<core::int?>?) → core::bool};
     #t21.{core::Set::add}{Invariant}(null){(inf::C<core::int?>?) → core::bool};
   } =>#t21;
   core::Set<inf::C<core::int?>?> local2f = block {
-    final core::Set<inf::C<core::int?>?> #t22 = new col::_CompactLinkedHashSet::•<inf::C<core::int?>?>();
+    final core::Set<inf::C<core::int?>?> #t22 = new col::_InternalLinkedHashSet::•<inf::C<core::int?>?>();
     #t22.{core::Set::add}{Invariant}(inf::field6){(inf::C<core::int?>?) → core::bool};
     #t22.{core::Set::add}{Invariant}(null){(inf::C<core::int?>?) → core::bool};
   } =>#t22;
   core::Set<core::int?> local2g = block {
-    final core::Set<core::int?> #t23 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t23 = new col::_InternalLinkedHashSet::•<core::int?>();
     #t23.{core::Set::add}{Invariant}(inf::field7){(core::int?) → core::bool};
     #t23.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
   } =>#t23;
   core::Set<core::int?> local2h = block {
-    final core::Set<core::int?> #t24 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t24 = new col::_InternalLinkedHashSet::•<core::int?>();
     #t24.{core::Set::add}{Invariant}(inf::field8){(core::int?) → core::bool};
     #t24.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
   } =>#t24;
   core::Set<inf::C<dynamic>?> local3a = block {
-    final core::Set<inf::C<dynamic>?> #t25 = new col::_CompactLinkedHashSet::•<inf::C<dynamic>?>();
+    final core::Set<inf::C<dynamic>?> #t25 = new col::_InternalLinkedHashSet::•<inf::C<dynamic>?>();
     #t25.{core::Set::add}{Invariant}(null){(inf::C<dynamic>?) → core::bool};
     #t25.{core::Set::add}{Invariant}(inf::field1){(inf::C<dynamic>?) → core::bool};
   } =>#t25;
   core::Set<inf::C<dynamic>?> local3b = block {
-    final core::Set<inf::C<dynamic>?> #t26 = new col::_CompactLinkedHashSet::•<inf::C<dynamic>?>();
+    final core::Set<inf::C<dynamic>?> #t26 = new col::_InternalLinkedHashSet::•<inf::C<dynamic>?>();
     #t26.{core::Set::add}{Invariant}(null){(inf::C<dynamic>?) → core::bool};
     #t26.{core::Set::add}{Invariant}(inf::field2){(inf::C<dynamic>?) → core::bool};
   } =>#t26;
   core::Set<inf::C<core::int>?> local3c = block {
-    final core::Set<inf::C<core::int>?> #t27 = new col::_CompactLinkedHashSet::•<inf::C<core::int>?>();
+    final core::Set<inf::C<core::int>?> #t27 = new col::_InternalLinkedHashSet::•<inf::C<core::int>?>();
     #t27.{core::Set::add}{Invariant}(null){(inf::C<core::int>?) → core::bool};
     #t27.{core::Set::add}{Invariant}(inf::field3){(inf::C<core::int>?) → core::bool};
   } =>#t27;
   core::Set<inf::C<core::int>?> local3d = block {
-    final core::Set<inf::C<core::int>?> #t28 = new col::_CompactLinkedHashSet::•<inf::C<core::int>?>();
+    final core::Set<inf::C<core::int>?> #t28 = new col::_InternalLinkedHashSet::•<inf::C<core::int>?>();
     #t28.{core::Set::add}{Invariant}(null){(inf::C<core::int>?) → core::bool};
     #t28.{core::Set::add}{Invariant}(inf::field4){(inf::C<core::int>?) → core::bool};
   } =>#t28;
   core::Set<inf::C<core::int?>?> local3e = block {
-    final core::Set<inf::C<core::int?>?> #t29 = new col::_CompactLinkedHashSet::•<inf::C<core::int?>?>();
+    final core::Set<inf::C<core::int?>?> #t29 = new col::_InternalLinkedHashSet::•<inf::C<core::int?>?>();
     #t29.{core::Set::add}{Invariant}(null){(inf::C<core::int?>?) → core::bool};
     #t29.{core::Set::add}{Invariant}(inf::field5){(inf::C<core::int?>?) → core::bool};
   } =>#t29;
   core::Set<inf::C<core::int?>?> local3f = block {
-    final core::Set<inf::C<core::int?>?> #t30 = new col::_CompactLinkedHashSet::•<inf::C<core::int?>?>();
+    final core::Set<inf::C<core::int?>?> #t30 = new col::_InternalLinkedHashSet::•<inf::C<core::int?>?>();
     #t30.{core::Set::add}{Invariant}(null){(inf::C<core::int?>?) → core::bool};
     #t30.{core::Set::add}{Invariant}(inf::field6){(inf::C<core::int?>?) → core::bool};
   } =>#t30;
   core::Set<core::int?> local3g = block {
-    final core::Set<core::int?> #t31 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t31 = new col::_InternalLinkedHashSet::•<core::int?>();
     #t31.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
     #t31.{core::Set::add}{Invariant}(inf::field7){(core::int?) → core::bool};
   } =>#t31;
   core::Set<core::int?> local3h = block {
-    final core::Set<core::int?> #t32 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t32 = new col::_InternalLinkedHashSet::•<core::int?>();
     #t32.{core::Set::add}{Invariant}(null){(core::int?) → core::bool};
     #t32.{core::Set::add}{Invariant}(inf::field8){(core::int?) → core::bool};
   } =>#t32;
diff --git a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.expect
index 740dfc6..d72ca93 100644
--- a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.expect
@@ -77,7 +77,7 @@
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#C30, 0, #C2, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
   no-such-method-forwarder method noFolding(core::String* name) → void
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#C31, 0, #C2, core::List::unmodifiable<dynamic>(<dynamic>[name]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/_http/http.dart */ clear() → void
+  no-such-method-forwarder method clear() → void
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#C32, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.modular.expect
index 740dfc6..d72ca93 100644
--- a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.modular.expect
@@ -77,7 +77,7 @@
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#C30, 0, #C2, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
   no-such-method-forwarder method noFolding(core::String* name) → void
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#C31, 0, #C2, core::List::unmodifiable<dynamic>(<dynamic>[name]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/_http/http.dart */ clear() → void
+  no-such-method-forwarder method clear() → void
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#C32, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
index 0524cac..c657f94 100644
--- a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
@@ -75,7 +75,7 @@
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#forEach, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation*) →* dynamic};
   no-such-method-forwarder method noFolding(core::String* name) → void
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#noFolding, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[name]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/_http/http.dart */ clear() → void
+  no-such-method-forwarder method clear() → void
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#clear, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation*) →* dynamic};
 }
 static method main() → dynamic
@@ -170,8 +170,8 @@
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> SymbolConstant(#noFolding)
 Evaluated: ListLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> ListConstant(const <Type*>[])
 Evaluated: MapLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> SymbolConstant(#clear)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> SymbolConstant(#clear)
+Evaluated: ListLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 268, effectively constant: 91
diff --git a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.transformed.expect
index e753783..686a1f0 100644
--- a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.transformed.expect
@@ -77,7 +77,7 @@
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#C30, 0, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
   no-such-method-forwarder method noFolding(core::String* name) → void
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#C31, 0, #C2, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(name)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/_http/http.dart */ clear() → void
+  no-such-method-forwarder method clear() → void
     return this.{self::Mock::noSuchMethod}(new core::_InvocationMirror::_withType(#C32, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.expect
index b0dc0b4..a6c9e0c 100644
--- a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.expect
@@ -5,7 +5,7 @@
 
 import "org-dartlang-testcase:///nullable_extension_on_opt_out_lib.dart";
 
-extension _extension#0 on nul::A? {
+extension /* unnamed */ _extension#0 on nul::A? {
   get text = self::_extension#0|get#text;
 }
 static method _extension#0|get#text(lowered final nul::A? #this) → core::String
diff --git a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.modular.expect
index b0dc0b4..a6c9e0c 100644
--- a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.modular.expect
@@ -5,7 +5,7 @@
 
 import "org-dartlang-testcase:///nullable_extension_on_opt_out_lib.dart";
 
-extension _extension#0 on nul::A? {
+extension /* unnamed */ _extension#0 on nul::A? {
   get text = self::_extension#0|get#text;
 }
 static method _extension#0|get#text(lowered final nul::A? #this) → core::String
diff --git a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.outline.expect
index 532bcce..92abd93 100644
--- a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.outline.expect
@@ -5,7 +5,7 @@
 
 import "org-dartlang-testcase:///nullable_extension_on_opt_out_lib.dart";
 
-extension _extension#0 on nul::A? {
+extension /* unnamed */ _extension#0 on nul::A? {
   get text = self::_extension#0|get#text;
 }
 static method _extension#0|get#text(lowered final nul::A? #this) → core::String
diff --git a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.transformed.expect
index b0dc0b4..a6c9e0c 100644
--- a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.weak.transformed.expect
@@ -5,7 +5,7 @@
 
 import "org-dartlang-testcase:///nullable_extension_on_opt_out_lib.dart";
 
-extension _extension#0 on nul::A? {
+extension /* unnamed */ _extension#0 on nul::A? {
   get text = self::_extension#0|get#text;
 }
 static method _extension#0|get#text(lowered final nul::A? #this) → core::String
diff --git a/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.transformed.expect
index 3720023..eebc12c 100644
--- a/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/regress_null_aware.dart.weak.transformed.expect
@@ -29,6 +29,6 @@
 static method main(dynamic args) → dynamic {
   if(false)
     new self::Class::•().{self::Class::method}("", block {
-      final core::Set<core::String*>* #t5 = new col::_CompactLinkedHashSet::•<core::String*>();
+      final core::Set<core::String*>* #t5 = new col::_InternalLinkedHashSet::•<core::String*>();
     } =>#t5){(core::String*, core::Set<core::String*>*) →* core::List<core::String*>*};
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.weak.outline.expect
index 155b834..951d8ed 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.weak.outline.expect
@@ -47,11 +47,11 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:18:7 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:18:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:18:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:18:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:18:7 -> SymbolConstant(#foo=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:18:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:18:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:21:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:21:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:21:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:21:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:21:7 -> SymbolConstant(#foo=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:21:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field.dart:21:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 19, effectively constant: 7
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.weak.outline.expect
index 7bead7e..52e96e7 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.weak.outline.expect
@@ -66,11 +66,11 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:12:7 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:12:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:12:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:12:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:12:7 -> SymbolConstant(#foo=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:12:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:12:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:15:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:15:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:15:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:15:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:15:7 -> SymbolConstant(#foo=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:15:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_arent_mixed_in.dart:15:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 21, effectively constant: 7
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.weak.outline.expect
index 90f26d3..5432735 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.weak.outline.expect
@@ -70,11 +70,11 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:17:7 -> SymbolConstant(#foo=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:17:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:17:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:17:7 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:17:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:17:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:17:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:26:7 -> SymbolConstant(#foo=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:26:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:26:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:37:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:37:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:37:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_one_defined.dart:37:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 19, effectively constant: 7
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.weak.outline.expect
index 630a250..f5bbc22 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.weak.outline.expect
@@ -43,11 +43,11 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:18:11 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:18:11 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:18:11 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:18:11 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:18:11 -> SymbolConstant(#foo=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:18:11 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:18:11 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:21:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:21:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:21:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:21:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:21:7 -> SymbolConstant(#foo=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:21:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_accessors_from_field_with_substitution.dart:21:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 19, effectively constant: 7
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.weak.outline.expect
index d735754..9a14b03 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.weak.outline.expect
@@ -43,8 +43,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_interface_nsm_inherited.dart:16:8 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_interface_nsm_inherited.dart:16:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_interface_nsm_inherited.dart:16:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_interface_nsm_inherited.dart:16:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_interface_nsm_inherited.dart:19:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_interface_nsm_inherited.dart:19:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_interface_nsm_inherited.dart:19:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_interface_nsm_inherited.dart:19:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 8, effectively constant: 4
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.weak.outline.expect
index 344c08e..5dc5fb8 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.weak.outline.expect
@@ -72,9 +72,9 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_override_with_different_signature.dart:8:8 -> SymbolConstant(#eatFood)
-Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_override_with_different_signature.dart:8:8 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_override_with_different_signature.dart:8:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_override_with_different_signature.dart:11:7 -> SymbolConstant(#eatFood)
+Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_override_with_different_signature.dart:11:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///abstract_override_with_different_signature.dart:11:7 -> MapConstant(const <Symbol*, dynamic>{})
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_override_with_different_signature.dart:23:8 -> SymbolConstant(#eatFood)
 Evaluated: ListLiteral @ org-dartlang-testcase:///abstract_override_with_different_signature.dart:23:8 -> ListConstant(const <Type*>[])
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///abstract_override_with_different_signature.dart:23:8 -> SymbolConstant(#amount)
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.weak.outline.expect
index ada8b9c..d0c32f8 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.weak.outline.expect
@@ -66,8 +66,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///concrete_method_over_forwarder_in_mixin_application.dart:10:3 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///concrete_method_over_forwarder_in_mixin_application.dart:10:3 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///concrete_method_over_forwarder_in_mixin_application.dart:10:3 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///concrete_method_over_forwarder_in_mixin_application.dart:10:3 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///concrete_method_over_forwarder_in_mixin_application.dart:17:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///concrete_method_over_forwarder_in_mixin_application.dart:17:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///concrete_method_over_forwarder_in_mixin_application.dart:17:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///concrete_method_over_forwarder_in_mixin_application.dart:17:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 11, effectively constant: 4
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.weak.outline.expect
index 846c39a..78f996e 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.weak.outline.expect
@@ -32,11 +32,11 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///default_argument_values.dart:21:10 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///default_argument_values.dart:21:10 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///default_argument_values.dart:21:10 -> ListConstant(const <dynamic>[])
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///default_argument_values.dart:21:10 -> SymbolConstant(#bar)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///default_argument_values.dart:22:7 -> SymbolConstant(#hest)
-Evaluated: ListLiteral @ org-dartlang-testcase:///default_argument_values.dart:22:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///default_argument_values.dart:22:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///default_argument_values.dart:25:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///default_argument_values.dart:25:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///default_argument_values.dart:25:7 -> ListConstant(const <dynamic>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///default_argument_values.dart:25:7 -> SymbolConstant(#bar)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///default_argument_values.dart:25:7 -> SymbolConstant(#hest)
+Evaluated: ListLiteral @ org-dartlang-testcase:///default_argument_values.dart:25:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///default_argument_values.dart:25:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 22, effectively constant: 7
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.weak.outline.expect
index 6ceff7c..2c8f4d8 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.weak.outline.expect
@@ -54,8 +54,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///duplicated_abstract_method.dart:10:8 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///duplicated_abstract_method.dart:10:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///duplicated_abstract_method.dart:10:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///duplicated_abstract_method.dart:10:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///duplicated_abstract_method.dart:17:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///duplicated_abstract_method.dart:17:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///duplicated_abstract_method.dart:17:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///duplicated_abstract_method.dart:17:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 8, effectively constant: 4
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.expect
index 9966f87..b079e10 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.expect
@@ -63,16 +63,16 @@
   abstract member-signature method toString() → core::String*; -> core::Object::toString
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
-  no-such-method-forwarder get /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateGetter() → core::int*
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C10, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} core::int*;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateField() → core::int*
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} core::int*;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateMethod() → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateSetter(core::int* value) → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C13, 2, #C3, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateField(core::int* value) → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C14, 2, #C3, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder get _privateGetter() → core::int*
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C10, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder get _privateField() → core::int*
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C11, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder method _privateMethod() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C12, 0, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder set _privateSetter(core::int* value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C13, 2, #C3, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder set _privateField(core::int* value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C14, 2, #C3, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
 }
 class F extends self::E {
   synthetic constructor •() → self::F*
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.modular.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.modular.expect
index 9966f87..b079e10 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.modular.expect
@@ -63,16 +63,16 @@
   abstract member-signature method toString() → core::String*; -> core::Object::toString
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
-  no-such-method-forwarder get /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateGetter() → core::int*
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C10, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} core::int*;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateField() → core::int*
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} core::int*;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateMethod() → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateSetter(core::int* value) → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C13, 2, #C3, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateField(core::int* value) → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C14, 2, #C3, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder get _privateGetter() → core::int*
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C10, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder get _privateField() → core::int*
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C11, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder method _privateMethod() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C12, 0, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder set _privateSetter(core::int* value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C13, 2, #C3, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder set _privateField(core::int* value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C14, 2, #C3, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
 }
 class F extends self::E {
   synthetic constructor •() → self::F*
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.outline.expect
index 8be6aa2..8e67c61 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.outline.expect
@@ -60,16 +60,16 @@
   abstract member-signature method toString() → core::String*; -> core::Object::toString
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
-  no-such-method-forwarder get /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateGetter() → core::int*
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_privateGetter, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} core::int*;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateField() → core::int*
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_privateField, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} core::int*;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateMethod() → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_privateMethod, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateSetter(core::int* value) → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_privateSetter=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateField(core::int* value) → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_privateField=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder get _privateGetter() → core::int*
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_privateGetter, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
+  no-such-method-forwarder get _privateField() → core::int*
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_privateField, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
+  no-such-method-forwarder method _privateMethod() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_privateMethod, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
+  no-such-method-forwarder set _privateSetter(core::int* value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_privateSetter=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
+  no-such-method-forwarder set _privateField(core::int* value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_privateField=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 class F extends self::E {
   synthetic constructor •() → self::F*
@@ -103,33 +103,33 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:12:11 -> SymbolConstant(#bar)
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:12:11 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:12:11 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:12:11 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:13:8 -> SymbolConstant(#baz)
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:13:8 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:13:8 -> SymbolConstant(#y)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:13:8 -> SymbolConstant(#z)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:11:12 -> SymbolConstant(#foo=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:11:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:11:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:7:11 -> SymbolConstant(#_privateGetter)
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:7:11 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:7:11 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:7:11 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:6:7 -> SymbolConstant(#_privateField)
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:6:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:6:7 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:6:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:9:8 -> SymbolConstant(#_privateMethod)
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:9:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:9:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:9:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:8:12 -> SymbolConstant(#_privateSetter=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:8:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:8:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:6:7 -> SymbolConstant(#_privateField=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:6:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation_lib.dart:6:7 -> MapConstant(const <Symbol*, dynamic>{})
-Extra constant evaluation: evaluated: 79, effectively constant: 29
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> SymbolConstant(#bar)
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> SymbolConstant(#baz)
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> SymbolConstant(#y)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> SymbolConstant(#z)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> SymbolConstant(#foo=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:16:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> SymbolConstant(#_privateGetter)
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> SymbolConstant(#_privateField)
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> SymbolConstant(#_privateMethod)
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> SymbolConstant(#_privateSetter=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> SymbolConstant(#_privateField=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///forwarder_propagation.dart:22:7 -> MapConstant(const <Symbol*, dynamic>{})
+Extra constant evaluation: evaluated: 82, effectively constant: 29
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.transformed.expect
index 184900a..014731b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.weak.transformed.expect
@@ -63,16 +63,16 @@
   abstract member-signature method toString() → core::String*; -> core::Object::toString
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
-  no-such-method-forwarder get /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateGetter() → core::int*
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C10, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} core::int*;
-  no-such-method-forwarder get /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateField() → core::int*
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} core::int*;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateMethod() → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateSetter(core::int* value) → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C13, 2, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic};
-  no-such-method-forwarder set /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateField(core::int* value) → void
-    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C14, 2, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder get _privateGetter() → core::int*
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C10, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder get _privateField() → core::int*
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C11, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder method _privateMethod() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C12, 0, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder set _privateSetter(core::int* value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C13, 2, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
+  no-such-method-forwarder set _privateField(core::int* value) → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C14, 2, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
 }
 class F extends self::E {
   synthetic constructor •() → self::F*
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.weak.outline.expect
index 59617d9..f288865 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.weak.outline.expect
@@ -61,12 +61,12 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:10:8 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:10:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:10:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:10:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:10:8 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:10:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:10:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:10:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:13:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:13:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:13:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:13:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:17:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:17:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:17:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///forwarders_not_assumed_from_mixin.dart:17:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 18, effectively constant: 8
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.weak.outline.expect
index ee28386..6745a53 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.weak.outline.expect
@@ -44,8 +44,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///interface_with_concrete.dart:16:8 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_concrete.dart:16:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_concrete.dart:16:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///interface_with_concrete.dart:16:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///interface_with_concrete.dart:19:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_concrete.dart:19:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_concrete.dart:19:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///interface_with_concrete.dart:19:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 8, effectively constant: 4
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.weak.outline.expect
index a3f5875..64325c9 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.weak.outline.expect
@@ -87,12 +87,12 @@
 Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> ListConstant(const <Type*>[])
 Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> ListConstant(const <dynamic>[])
 Evaluated: MapLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:15:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:22:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:22:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:22:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:22:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:24:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:24:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:24:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///interface_with_nsm.dart:24:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 28, effectively constant: 12
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.weak.outline.expect
index 18495ea..cc7c786 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.weak.outline.expect
@@ -80,11 +80,11 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:17:12 -> SymbolConstant(#bar)
-Evaluated: ListLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:17:12 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:17:12 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:17:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:16:12 -> SymbolConstant(#foo=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:16:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:16:12 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:20:7 -> SymbolConstant(#bar)
+Evaluated: ListLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:20:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:20:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:20:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:20:7 -> SymbolConstant(#foo=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:20:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///multiple_abstract_setters.dart:20:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 19, effectively constant: 7
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.weak.outline.expect
index 3a87a23..557b2d3 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.weak.outline.expect
@@ -29,8 +29,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes.dart:13:8 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes.dart:13:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes.dart:13:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes.dart:13:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes.dart:16:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes.dart:16:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes.dart:16:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes.dart:16:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 8, effectively constant: 4
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.weak.outline.expect
index d402380..7d46c29 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.weak.outline.expect
@@ -37,8 +37,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes_chain.dart:14:8 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes_chain.dart:14:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes_chain.dart:14:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes_chain.dart:14:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes_chain.dart:21:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes_chain.dart:21:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes_chain.dart:21:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///no_forwarders_for_abstract_classes_chain.dart:21:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 8, effectively constant: 4
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.expect
index 00429c3..a29712d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.expect
@@ -25,8 +25,8 @@
   synthetic constructor •() → self::Bar*
     : super self::Foo::•()
     ;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
-    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder method _hest() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class Baz extends self::Foo implements pri::Fisk {
   synthetic constructor •() → self::Baz*
@@ -34,8 +34,8 @@
     ;
   method _hest() → dynamic
     return null;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
-    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder method _hest() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.modular.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.modular.expect
index 00429c3..a29712d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.modular.expect
@@ -25,8 +25,8 @@
   synthetic constructor •() → self::Bar*
     : super self::Foo::•()
     ;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
-    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder method _hest() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class Baz extends self::Foo implements pri::Fisk {
   synthetic constructor •() → self::Baz*
@@ -34,8 +34,8 @@
     ;
   method _hest() → dynamic
     return null;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
-    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder method _hest() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.outline.expect
index f92373e..c0f5446 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.outline.expect
@@ -23,16 +23,16 @@
 class Bar extends self::Foo implements pri::Fisk {
   synthetic constructor •() → self::Bar*
     ;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
-    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#_hest, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder method _hest() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_hest, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 class Baz extends self::Foo implements pri::Fisk {
   synthetic constructor •() → self::Baz*
     ;
   method _hest() → dynamic
     ;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
-    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#_hest, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder method _hest() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_hest, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 static method main() → dynamic
   ;
@@ -61,12 +61,12 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///private_module.dart:11:8 -> SymbolConstant(#_hest)
-Evaluated: ListLiteral @ org-dartlang-testcase:///private_module.dart:11:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///private_module.dart:11:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///private_module.dart:11:8 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///private_module.dart:11:8 -> SymbolConstant(#_hest)
-Evaluated: ListLiteral @ org-dartlang-testcase:///private_module.dart:11:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///private_module.dart:11:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///private_module.dart:11:8 -> MapConstant(const <Symbol*, dynamic>{})
-Extra constant evaluation: evaluated: 16, effectively constant: 8
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///private.dart:16:7 -> SymbolConstant(#_hest)
+Evaluated: ListLiteral @ org-dartlang-testcase:///private.dart:16:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///private.dart:16:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///private.dart:16:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///private.dart:18:7 -> SymbolConstant(#_hest)
+Evaluated: ListLiteral @ org-dartlang-testcase:///private.dart:18:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///private.dart:18:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///private.dart:18:7 -> MapConstant(const <Symbol*, dynamic>{})
+Extra constant evaluation: evaluated: 18, effectively constant: 8
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.transformed.expect
index 00429c3..a29712d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.weak.transformed.expect
@@ -25,8 +25,8 @@
   synthetic constructor •() → self::Bar*
     : super self::Foo::•()
     ;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
-    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder method _hest() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 class Baz extends self::Foo implements pri::Fisk {
   synthetic constructor •() → self::Baz*
@@ -34,8 +34,8 @@
     ;
   method _hest() → dynamic
     return null;
-  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
-    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))){(core::Invocation*) →* dynamic};
+  no-such-method-forwarder method _hest() → void
+    return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.weak.outline.expect
index 29e4137..da31070 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.weak.outline.expect
@@ -30,8 +30,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///private_same.dart:10:8 -> SymbolConstant(#_foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///private_same.dart:10:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///private_same.dart:10:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///private_same.dart:10:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///private_same.dart:13:7 -> SymbolConstant(#_foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///private_same.dart:13:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///private_same.dart:13:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///private_same.dart:13:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 8, effectively constant: 4
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.weak.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.weak.outline.expect
index 037de6a..dacb974 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.weak.outline.expect
@@ -59,8 +59,8 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///subst_on_forwarder.dart:10:5 -> SymbolConstant(#foo)
-Evaluated: ListLiteral @ org-dartlang-testcase:///subst_on_forwarder.dart:10:5 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///subst_on_forwarder.dart:10:5 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///subst_on_forwarder.dart:10:5 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///subst_on_forwarder.dart:19:7 -> SymbolConstant(#foo)
+Evaluated: ListLiteral @ org-dartlang-testcase:///subst_on_forwarder.dart:19:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///subst_on_forwarder.dart:19:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///subst_on_forwarder.dart:19:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 11, effectively constant: 4
diff --git a/pkg/front_end/testcases/records/const_record_literal.dart b/pkg/front_end/testcases/records/const_record_literal.dart
new file mode 100644
index 0000000..eb8fb1b
--- /dev/null
+++ b/pkg/front_end/testcases/records/const_record_literal.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2022, 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.
+
+const dynamic a = (1, 2);
+const dynamic b1 = (a: 1, b: 2);
+const dynamic b2 = (b: 2, a: 1);
+const dynamic b3 = (b: 2, 1);
+const dynamic c1 = (a: a, b: b1);
+const dynamic c2 = (b: b2, a: a);
+const dynamic c3 = (b: b3, a);
+const dynamic d = (c1, (1, 2));
+
+dynamic e = const (1, 2);
+dynamic f1 = const (a: 1, b: 2);
+dynamic f2 = const (b: 2, a: 1);
+dynamic f3 = const (b: 2, 1);
+dynamic g1 = const (a: a, b: b1);
+dynamic g2 = const (b: b2, a: a);
+dynamic g3 = const (b: b3, a);
+dynamic h = const (c1, (1, 2));
diff --git a/pkg/front_end/testcases/records/const_record_literal.dart.strong.expect b/pkg/front_end/testcases/records/const_record_literal.dart.strong.expect
new file mode 100644
index 0000000..08cf8e3
--- /dev/null
+++ b/pkg/front_end/testcases/records/const_record_literal.dart.strong.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic a = #C3;
+static const field dynamic b1 = #C4;
+static const field dynamic b2 = #C4;
+static const field dynamic b3 = #C5;
+static const field dynamic c1 = #C6;
+static const field dynamic c2 = #C6;
+static const field dynamic c3 = #C7;
+static const field dynamic d = #C8;
+static field dynamic e = #C3;
+static field dynamic f1 = #C4;
+static field dynamic f2 = #C4;
+static field dynamic f3 = #C5;
+static field dynamic g1 = #C6;
+static field dynamic g2 = #C6;
+static field dynamic g3 = #C7;
+static field dynamic h = #C8;
+
+constants  {
+  #C1 = 1
+  #C2 = 2
+const (#C1, #C2)
+const ({a:#C1, b:#C2})
+const (#C1, {b:#C2})
+const ({a:#C3, b:#C4})
+const (#C3, {b:#C5})
+const (#C6, #C3)
+}
diff --git a/pkg/front_end/testcases/records/const_record_literal.dart.strong.transformed.expect b/pkg/front_end/testcases/records/const_record_literal.dart.strong.transformed.expect
new file mode 100644
index 0000000..08cf8e3
--- /dev/null
+++ b/pkg/front_end/testcases/records/const_record_literal.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic a = #C3;
+static const field dynamic b1 = #C4;
+static const field dynamic b2 = #C4;
+static const field dynamic b3 = #C5;
+static const field dynamic c1 = #C6;
+static const field dynamic c2 = #C6;
+static const field dynamic c3 = #C7;
+static const field dynamic d = #C8;
+static field dynamic e = #C3;
+static field dynamic f1 = #C4;
+static field dynamic f2 = #C4;
+static field dynamic f3 = #C5;
+static field dynamic g1 = #C6;
+static field dynamic g2 = #C6;
+static field dynamic g3 = #C7;
+static field dynamic h = #C8;
+
+constants  {
+  #C1 = 1
+  #C2 = 2
+const (#C1, #C2)
+const ({a:#C1, b:#C2})
+const (#C1, {b:#C2})
+const ({a:#C3, b:#C4})
+const (#C3, {b:#C5})
+const (#C6, #C3)
+}
diff --git a/pkg/front_end/testcases/records/const_record_literal.dart.textual_outline.expect b/pkg/front_end/testcases/records/const_record_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..769adb8
--- /dev/null
+++ b/pkg/front_end/testcases/records/const_record_literal.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+const dynamic a = (1, 2);
+const dynamic b1 = (a: 1, b: 2);
+const dynamic b2 = (b: 2, a: 1);
+const dynamic b3 = (b: 2, 1);
+const dynamic c1 = (a: a, b: b1);
+const dynamic c2 = (b: b2, a: a);
+const dynamic c3 = (b: b3, a);
+const dynamic d = (c1, (1, 2));
+dynamic e = const (1, 2);
+dynamic f1 = const (a: 1, b: 2);
+dynamic f2 = const (b: 2, a: 1);
+dynamic f3 = const (b: 2, 1);
+dynamic g1 = const (a: a, b: b1);
+dynamic g2 = const (b: b2, a: a);
+dynamic g3 = const (b: b3, a);
+dynamic h = const (c1, (1, 2));
diff --git a/pkg/front_end/testcases/records/const_record_literal.dart.weak.expect b/pkg/front_end/testcases/records/const_record_literal.dart.weak.expect
new file mode 100644
index 0000000..08cf8e3
--- /dev/null
+++ b/pkg/front_end/testcases/records/const_record_literal.dart.weak.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic a = #C3;
+static const field dynamic b1 = #C4;
+static const field dynamic b2 = #C4;
+static const field dynamic b3 = #C5;
+static const field dynamic c1 = #C6;
+static const field dynamic c2 = #C6;
+static const field dynamic c3 = #C7;
+static const field dynamic d = #C8;
+static field dynamic e = #C3;
+static field dynamic f1 = #C4;
+static field dynamic f2 = #C4;
+static field dynamic f3 = #C5;
+static field dynamic g1 = #C6;
+static field dynamic g2 = #C6;
+static field dynamic g3 = #C7;
+static field dynamic h = #C8;
+
+constants  {
+  #C1 = 1
+  #C2 = 2
+const (#C1, #C2)
+const ({a:#C1, b:#C2})
+const (#C1, {b:#C2})
+const ({a:#C3, b:#C4})
+const (#C3, {b:#C5})
+const (#C6, #C3)
+}
diff --git a/pkg/front_end/testcases/records/const_record_literal.dart.weak.modular.expect b/pkg/front_end/testcases/records/const_record_literal.dart.weak.modular.expect
new file mode 100644
index 0000000..08cf8e3
--- /dev/null
+++ b/pkg/front_end/testcases/records/const_record_literal.dart.weak.modular.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic a = #C3;
+static const field dynamic b1 = #C4;
+static const field dynamic b2 = #C4;
+static const field dynamic b3 = #C5;
+static const field dynamic c1 = #C6;
+static const field dynamic c2 = #C6;
+static const field dynamic c3 = #C7;
+static const field dynamic d = #C8;
+static field dynamic e = #C3;
+static field dynamic f1 = #C4;
+static field dynamic f2 = #C4;
+static field dynamic f3 = #C5;
+static field dynamic g1 = #C6;
+static field dynamic g2 = #C6;
+static field dynamic g3 = #C7;
+static field dynamic h = #C8;
+
+constants  {
+  #C1 = 1
+  #C2 = 2
+const (#C1, #C2)
+const ({a:#C1, b:#C2})
+const (#C1, {b:#C2})
+const ({a:#C3, b:#C4})
+const (#C3, {b:#C5})
+const (#C6, #C3)
+}
diff --git a/pkg/front_end/testcases/records/const_record_literal.dart.weak.outline.expect b/pkg/front_end/testcases/records/const_record_literal.dart.weak.outline.expect
new file mode 100644
index 0000000..6158563
--- /dev/null
+++ b/pkg/front_end/testcases/records/const_record_literal.dart.weak.outline.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic a = const (1, 2);
+static const field dynamic b1 = const ({a: 1, b: 2});
+static const field dynamic b2 = const ({a: 1, b: 2});
+static const field dynamic b3 = const (1, {b: 2});
+static const field dynamic c1 = const ({a: self::a, b: self::b1});
+static const field dynamic c2 = const ({a: self::a, b: self::b2});
+static const field dynamic c3 = const (self::a, {b: self::b3});
+static const field dynamic d = const (self::c1, const (1, 2));
+static field dynamic e;
+static field dynamic f1;
+static field dynamic f2;
+static field dynamic f3;
+static field dynamic g1;
+static field dynamic g2;
+static field dynamic g3;
+static field dynamic h;
+
+
+Extra constant evaluation status:
+Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:5:19 -> RecordConstant(const (1, 2))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:6:20 -> RecordConstant(const ({a: 1, b: 2}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:7:20 -> RecordConstant(const ({a: 1, b: 2}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:8:20 -> RecordConstant(const (1, {b: 2}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:9:20 -> RecordConstant(const ({a: const (1, 2), b: const ({a: 1, b: 2})}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:10:20 -> RecordConstant(const ({a: const (1, 2), b: const ({a: 1, b: 2})}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:11:20 -> RecordConstant(const (const (1, 2), {b: const (1, {b: 2})}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:12:19 -> RecordConstant(const (const ({a: const (1, 2), b: const ({a: 1, b: 2})}), const (1, 2)))
+Extra constant evaluation: evaluated: 8, effectively constant: 8
diff --git a/pkg/front_end/testcases/records/const_record_literal.dart.weak.transformed.expect b/pkg/front_end/testcases/records/const_record_literal.dart.weak.transformed.expect
new file mode 100644
index 0000000..08cf8e3
--- /dev/null
+++ b/pkg/front_end/testcases/records/const_record_literal.dart.weak.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic a = #C3;
+static const field dynamic b1 = #C4;
+static const field dynamic b2 = #C4;
+static const field dynamic b3 = #C5;
+static const field dynamic c1 = #C6;
+static const field dynamic c2 = #C6;
+static const field dynamic c3 = #C7;
+static const field dynamic d = #C8;
+static field dynamic e = #C3;
+static field dynamic f1 = #C4;
+static field dynamic f2 = #C4;
+static field dynamic f3 = #C5;
+static field dynamic g1 = #C6;
+static field dynamic g2 = #C6;
+static field dynamic g3 = #C7;
+static field dynamic h = #C8;
+
+constants  {
+  #C1 = 1
+  #C2 = 2
+const (#C1, #C2)
+const ({a:#C1, b:#C2})
+const (#C1, {b:#C2})
+const ({a:#C3, b:#C4})
+const (#C3, {b:#C5})
+const (#C6, #C3)
+}
diff --git a/pkg/front_end/testcases/records/issue50004.dart b/pkg/front_end/testcases/records/issue50004.dart
new file mode 100644
index 0000000..147a026
--- /dev/null
+++ b/pkg/front_end/testcases/records/issue50004.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2022, 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.
+
+main() {
+  var r1 = (1, const [42]);
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/records/issue50004.dart.strong.expect b/pkg/front_end/testcases/records/issue50004.dart.strong.expect
new file mode 100644
index 0000000..8fed911
--- /dev/null
+++ b/pkg/front_end/testcases/records/issue50004.dart.strong.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  (core::int, core::List<core::int>) r1 = (1, #C2);
+}
+
+constants  {
+  #C1 = 42
+  #C2 = <core::int>[#C1]
+}
diff --git a/pkg/front_end/testcases/records/issue50004.dart.strong.transformed.expect b/pkg/front_end/testcases/records/issue50004.dart.strong.transformed.expect
new file mode 100644
index 0000000..6e0cd0fe
--- /dev/null
+++ b/pkg/front_end/testcases/records/issue50004.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  (core::int, core::List<core::int>) r1 = (1, #C2);
+}
+
+constants  {
+  #C1 = 42
+  #C2 = <core::int>[#C1]
+}
+
+Extra constant evaluation status:
+Evaluated: RecordLiteral @ org-dartlang-testcase:///issue50004.dart:6:12 -> RecordConstant(const (1, const <int>[42]))
+Extra constant evaluation: evaluated: 1, effectively constant: 1
diff --git a/pkg/front_end/testcases/records/issue50004.dart.textual_outline.expect b/pkg/front_end/testcases/records/issue50004.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/records/issue50004.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/records/issue50004.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/records/issue50004.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/records/issue50004.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/records/issue50004.dart.weak.expect b/pkg/front_end/testcases/records/issue50004.dart.weak.expect
new file mode 100644
index 0000000..66c8120
--- /dev/null
+++ b/pkg/front_end/testcases/records/issue50004.dart.weak.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  (core::int, core::List<core::int>) r1 = (1, #C2);
+}
+
+constants  {
+  #C1 = 42
+  #C2 = <core::int*>[#C1]
+}
diff --git a/pkg/front_end/testcases/records/issue50004.dart.weak.modular.expect b/pkg/front_end/testcases/records/issue50004.dart.weak.modular.expect
new file mode 100644
index 0000000..66c8120
--- /dev/null
+++ b/pkg/front_end/testcases/records/issue50004.dart.weak.modular.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  (core::int, core::List<core::int>) r1 = (1, #C2);
+}
+
+constants  {
+  #C1 = 42
+  #C2 = <core::int*>[#C1]
+}
diff --git a/pkg/front_end/testcases/records/issue50004.dart.weak.outline.expect b/pkg/front_end/testcases/records/issue50004.dart.weak.outline.expect
new file mode 100644
index 0000000..e2cba6b
--- /dev/null
+++ b/pkg/front_end/testcases/records/issue50004.dart.weak.outline.expect
@@ -0,0 +1,5 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/records/issue50004.dart.weak.transformed.expect b/pkg/front_end/testcases/records/issue50004.dart.weak.transformed.expect
new file mode 100644
index 0000000..4e8f4df
--- /dev/null
+++ b/pkg/front_end/testcases/records/issue50004.dart.weak.transformed.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  (core::int, core::List<core::int>) r1 = (1, #C2);
+}
+
+constants  {
+  #C1 = 42
+  #C2 = <core::int*>[#C1]
+}
+
+Extra constant evaluation status:
+Evaluated: RecordLiteral @ org-dartlang-testcase:///issue50004.dart:6:12 -> RecordConstant(const (1, const <int*>[42]))
+Extra constant evaluation: evaluated: 1, effectively constant: 1
diff --git a/pkg/front_end/testcases/records/record_get.dart.strong.transformed.expect b/pkg/front_end/testcases/records/record_get.dart.strong.transformed.expect
index c8f6304..716a16f 100644
--- a/pkg/front_end/testcases/records/record_get.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/records/record_get.dart.strong.transformed.expect
@@ -9,3 +9,12 @@
   (0, {a: "", b: true}).a{core::String};
   (0, {a: "", b: true}).b{core::bool};
 }
+
+
+Extra constant evaluation status:
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:6:3 -> RecordConstant(const (0, ""))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:7:3 -> RecordConstant(const (0, ""))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:8:3 -> RecordConstant(const (0, {a: "", b: true}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:9:3 -> RecordConstant(const (0, {a: "", b: true}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:10:3 -> RecordConstant(const (0, {a: "", b: true}))
+Extra constant evaluation: evaluated: 10, effectively constant: 5
diff --git a/pkg/front_end/testcases/records/record_get.dart.weak.transformed.expect b/pkg/front_end/testcases/records/record_get.dart.weak.transformed.expect
index c8f6304..716a16f 100644
--- a/pkg/front_end/testcases/records/record_get.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/records/record_get.dart.weak.transformed.expect
@@ -9,3 +9,12 @@
   (0, {a: "", b: true}).a{core::String};
   (0, {a: "", b: true}).b{core::bool};
 }
+
+
+Extra constant evaluation status:
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:6:3 -> RecordConstant(const (0, ""))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:7:3 -> RecordConstant(const (0, ""))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:8:3 -> RecordConstant(const (0, {a: "", b: true}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:9:3 -> RecordConstant(const (0, {a: "", b: true}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:10:3 -> RecordConstant(const (0, {a: "", b: true}))
+Extra constant evaluation: evaluated: 10, effectively constant: 5
diff --git a/pkg/front_end/testcases/records/record_literal.dart.strong.expect b/pkg/front_end/testcases/records/record_literal.dart.strong.expect
index e6cfefc..316ff4e 100644
--- a/pkg/front_end/testcases/records/record_literal.dart.strong.expect
+++ b/pkg/front_end/testcases/records/record_literal.dart.strong.expect
@@ -26,7 +26,7 @@
   (0, {b: 1});
   ({a: 0, b: 1});
   let final core::int #t1 = 0 in (1, {a: #t1});
-  (core::int, core::String);
+  #C3;
 }
 static method sorting() → dynamic {
   ({a: 0, b: 1, c: 2, d: 3});
@@ -40,3 +40,9 @@
   let final core::int #t23 = 0 in let final core::int #t24 = 1 in let final core::int #t25 = 2 in (#t23, #t25, 3, {a: #t24, b: 4, c: 5});
   let final core::int #t26 = 0 in let final core::int #t27 = 1 in let final core::int #t28 = 2 in (#t27, #t28, 3, {a: #t26, b: 4, c: 5});
 }
+
+constants  {
+  #C1 = TypeLiteralConstant(core::int)
+  #C2 = TypeLiteralConstant(core::String)
+const (#C1, #C2)
+}
diff --git a/pkg/front_end/testcases/records/record_literal.dart.strong.transformed.expect b/pkg/front_end/testcases/records/record_literal.dart.strong.transformed.expect
index 2f10b09..ca178d4 100644
--- a/pkg/front_end/testcases/records/record_literal.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/records/record_literal.dart.strong.transformed.expect
@@ -26,7 +26,7 @@
   (0, {b: 1});
   ({a: 0, b: 1});
   let final core::int #t1 = 0 in (1, {a: #t1});
-  (core::int, core::String);
+  #C3;
 }
 static method sorting() → dynamic {
   ({a: 0, b: 1, c: 2, d: 3});
@@ -41,36 +41,25 @@
   let final core::int #t26 = 0 in let final core::int #t27 = 1 in let final core::int #t28 = 2 in (#t27, #t28, 3, {a: #t26, b: 4, c: 5});
 }
 
+constants  {
+  #C1 = TypeLiteralConstant(core::int)
+  #C2 = TypeLiteralConstant(core::String)
+const (#C1, #C2)
+}
 
 Extra constant evaluation status:
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:10:7 -> IntConstant(0)
-Evaluated: TypeLiteral @ org-dartlang-testcase:///record_literal.dart:11:4 -> TypeLiteralConstant(int)
-Evaluated: TypeLiteral @ org-dartlang-testcase:///record_literal.dart:11:9 -> TypeLiteralConstant(String)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:7 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:13 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:19 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:7 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:19 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:13 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:13 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:19 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:7 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:4 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:7 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:13 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:4 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:7 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:13 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:19 -> IntConstant(3)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:4 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:7 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:13 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:19 -> IntConstant(3)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:25 -> IntConstant(4)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:4 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:13 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:10 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:10 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:13 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:7 -> IntConstant(0)
-Extra constant evaluation: evaluated: 75, effectively constant: 30
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:7:3 -> RecordConstant(const (0, 1))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:8:3 -> RecordConstant(const (0, {b: 1}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:9:3 -> RecordConstant(const ({a: 0, b: 1}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:10:7 -> RecordConstant(const (1, {a: 0}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:15:3 -> RecordConstant(const ({a: 0, b: 1, c: 2, d: 3}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:16:7 -> RecordConstant(const ({a: 0, b: 1, c: 3, d: 2}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:17:7 -> RecordConstant(const ({a: 0, b: 2, c: 3, d: 1}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:18:7 -> RecordConstant(const ({a: 1, b: 2, c: 3, d: 0}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:19:3 -> RecordConstant(const (0, 1, 2, {a: 3, b: 4, c: 5}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:20:4 -> RecordConstant(const (0, 1, 3, {a: 2, b: 4, c: 5}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:21:4 -> RecordConstant(const (0, 1, 4, {a: 2, b: 3, c: 5}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:22:4 -> RecordConstant(const (0, 1, 5, {a: 2, b: 3, c: 4}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:23:4 -> RecordConstant(const (0, 2, 3, {a: 1, b: 4, c: 5}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:24:7 -> RecordConstant(const (1, 2, 3, {a: 0, b: 4, c: 5}))
+Extra constant evaluation: evaluated: 16, effectively constant: 14
diff --git a/pkg/front_end/testcases/records/record_literal.dart.weak.expect b/pkg/front_end/testcases/records/record_literal.dart.weak.expect
index e6cfefc..7e1bd55 100644
--- a/pkg/front_end/testcases/records/record_literal.dart.weak.expect
+++ b/pkg/front_end/testcases/records/record_literal.dart.weak.expect
@@ -26,7 +26,7 @@
   (0, {b: 1});
   ({a: 0, b: 1});
   let final core::int #t1 = 0 in (1, {a: #t1});
-  (core::int, core::String);
+  #C3;
 }
 static method sorting() → dynamic {
   ({a: 0, b: 1, c: 2, d: 3});
@@ -40,3 +40,9 @@
   let final core::int #t23 = 0 in let final core::int #t24 = 1 in let final core::int #t25 = 2 in (#t23, #t25, 3, {a: #t24, b: 4, c: 5});
   let final core::int #t26 = 0 in let final core::int #t27 = 1 in let final core::int #t28 = 2 in (#t27, #t28, 3, {a: #t26, b: 4, c: 5});
 }
+
+constants  {
+  #C1 = TypeLiteralConstant(core::int*)
+  #C2 = TypeLiteralConstant(core::String*)
+const (#C1, #C2)
+}
diff --git a/pkg/front_end/testcases/records/record_literal.dart.weak.modular.expect b/pkg/front_end/testcases/records/record_literal.dart.weak.modular.expect
index e6cfefc..7e1bd55 100644
--- a/pkg/front_end/testcases/records/record_literal.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/records/record_literal.dart.weak.modular.expect
@@ -26,7 +26,7 @@
   (0, {b: 1});
   ({a: 0, b: 1});
   let final core::int #t1 = 0 in (1, {a: #t1});
-  (core::int, core::String);
+  #C3;
 }
 static method sorting() → dynamic {
   ({a: 0, b: 1, c: 2, d: 3});
@@ -40,3 +40,9 @@
   let final core::int #t23 = 0 in let final core::int #t24 = 1 in let final core::int #t25 = 2 in (#t23, #t25, 3, {a: #t24, b: 4, c: 5});
   let final core::int #t26 = 0 in let final core::int #t27 = 1 in let final core::int #t28 = 2 in (#t27, #t28, 3, {a: #t26, b: 4, c: 5});
 }
+
+constants  {
+  #C1 = TypeLiteralConstant(core::int*)
+  #C2 = TypeLiteralConstant(core::String*)
+const (#C1, #C2)
+}
diff --git a/pkg/front_end/testcases/records/record_literal.dart.weak.transformed.expect b/pkg/front_end/testcases/records/record_literal.dart.weak.transformed.expect
index 63a54ad..c6dcc60 100644
--- a/pkg/front_end/testcases/records/record_literal.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/records/record_literal.dart.weak.transformed.expect
@@ -26,7 +26,7 @@
   (0, {b: 1});
   ({a: 0, b: 1});
   let final core::int #t1 = 0 in (1, {a: #t1});
-  (core::int, core::String);
+  #C3;
 }
 static method sorting() → dynamic {
   ({a: 0, b: 1, c: 2, d: 3});
@@ -41,36 +41,25 @@
   let final core::int #t26 = 0 in let final core::int #t27 = 1 in let final core::int #t28 = 2 in (#t27, #t28, 3, {a: #t26, b: 4, c: 5});
 }
 
+constants  {
+  #C1 = TypeLiteralConstant(core::int*)
+  #C2 = TypeLiteralConstant(core::String*)
+const (#C1, #C2)
+}
 
 Extra constant evaluation status:
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:10:7 -> IntConstant(0)
-Evaluated: TypeLiteral @ org-dartlang-testcase:///record_literal.dart:11:4 -> TypeLiteralConstant(int*)
-Evaluated: TypeLiteral @ org-dartlang-testcase:///record_literal.dart:11:9 -> TypeLiteralConstant(String*)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:7 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:13 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:19 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:7 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:19 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:13 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:13 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:19 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:7 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:4 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:7 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:13 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:4 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:7 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:13 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:19 -> IntConstant(3)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:4 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:7 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:13 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:19 -> IntConstant(3)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:25 -> IntConstant(4)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:4 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:13 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:10 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:10 -> IntConstant(1)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:13 -> IntConstant(2)
-Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:7 -> IntConstant(0)
-Extra constant evaluation: evaluated: 75, effectively constant: 30
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:7:3 -> RecordConstant(const (0, 1))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:8:3 -> RecordConstant(const (0, {b: 1}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:9:3 -> RecordConstant(const ({a: 0, b: 1}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:10:7 -> RecordConstant(const (1, {a: 0}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:15:3 -> RecordConstant(const ({a: 0, b: 1, c: 2, d: 3}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:16:7 -> RecordConstant(const ({a: 0, b: 1, c: 3, d: 2}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:17:7 -> RecordConstant(const ({a: 0, b: 2, c: 3, d: 1}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:18:7 -> RecordConstant(const ({a: 1, b: 2, c: 3, d: 0}))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:19:3 -> RecordConstant(const (0, 1, 2, {a: 3, b: 4, c: 5}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:20:4 -> RecordConstant(const (0, 1, 3, {a: 2, b: 4, c: 5}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:21:4 -> RecordConstant(const (0, 1, 4, {a: 2, b: 3, c: 5}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:22:4 -> RecordConstant(const (0, 1, 5, {a: 2, b: 3, c: 4}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:23:4 -> RecordConstant(const (0, 2, 3, {a: 1, b: 4, c: 5}))
+Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:24:7 -> RecordConstant(const (1, 2, 3, {a: 0, b: 4, c: 5}))
+Extra constant evaluation: evaluated: 16, effectively constant: 14
diff --git a/pkg/front_end/testcases/records/record_type_errors.dart.strong.expect b/pkg/front_end/testcases/records/record_type_errors.dart.strong.expect
index 71154db..67dfe7f 100644
--- a/pkg/front_end/testcases/records/record_type_errors.dart.strong.expect
+++ b/pkg/front_end/testcases/records/record_type_errors.dart.strong.expect
@@ -2,13 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:5:2: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-// () emptyType = throw '';
-//  ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (int) singleType = throw '';
 //     ^
 //
@@ -25,12 +20,12 @@
 // (var a, {var b}) missingType = throw '';
 //  ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (var a, {var b}) missingType = throw '';
 //                ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 // (int, {}) emptyNamedFields = throw '';
 //        ^
@@ -71,13 +66,8 @@
 // (var a, {var b}) missingType = throw '';
 //  ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:14:4: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-//   () emptyType = throw '';
-//    ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:15:7: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:15:7: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 //   (int) singleType = throw '';
 //       ^
 //
@@ -98,12 +88,12 @@
 //   (var a, {var b}) missingType = throw '';
 //    ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:17:18: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:17:18: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 //   (var a, {var b}) missingType = throw '';
 //                  ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:18:10: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:18:10: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 //   (int, {}) emptyNamedFields = throw '';
 //          ^
diff --git a/pkg/front_end/testcases/records/record_type_errors.dart.strong.transformed.expect b/pkg/front_end/testcases/records/record_type_errors.dart.strong.transformed.expect
index 71154db..67dfe7f 100644
--- a/pkg/front_end/testcases/records/record_type_errors.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/records/record_type_errors.dart.strong.transformed.expect
@@ -2,13 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:5:2: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-// () emptyType = throw '';
-//  ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (int) singleType = throw '';
 //     ^
 //
@@ -25,12 +20,12 @@
 // (var a, {var b}) missingType = throw '';
 //  ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (var a, {var b}) missingType = throw '';
 //                ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 // (int, {}) emptyNamedFields = throw '';
 //        ^
@@ -71,13 +66,8 @@
 // (var a, {var b}) missingType = throw '';
 //  ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:14:4: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-//   () emptyType = throw '';
-//    ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:15:7: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:15:7: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 //   (int) singleType = throw '';
 //       ^
 //
@@ -98,12 +88,12 @@
 //   (var a, {var b}) missingType = throw '';
 //    ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:17:18: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:17:18: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 //   (var a, {var b}) missingType = throw '';
 //                  ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:18:10: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:18:10: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 //   (int, {}) emptyNamedFields = throw '';
 //          ^
diff --git a/pkg/front_end/testcases/records/record_type_errors.dart.weak.expect b/pkg/front_end/testcases/records/record_type_errors.dart.weak.expect
index 71154db..67dfe7f 100644
--- a/pkg/front_end/testcases/records/record_type_errors.dart.weak.expect
+++ b/pkg/front_end/testcases/records/record_type_errors.dart.weak.expect
@@ -2,13 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:5:2: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-// () emptyType = throw '';
-//  ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (int) singleType = throw '';
 //     ^
 //
@@ -25,12 +20,12 @@
 // (var a, {var b}) missingType = throw '';
 //  ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (var a, {var b}) missingType = throw '';
 //                ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 // (int, {}) emptyNamedFields = throw '';
 //        ^
@@ -71,13 +66,8 @@
 // (var a, {var b}) missingType = throw '';
 //  ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:14:4: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-//   () emptyType = throw '';
-//    ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:15:7: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:15:7: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 //   (int) singleType = throw '';
 //       ^
 //
@@ -98,12 +88,12 @@
 //   (var a, {var b}) missingType = throw '';
 //    ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:17:18: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:17:18: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 //   (var a, {var b}) missingType = throw '';
 //                  ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:18:10: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:18:10: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 //   (int, {}) emptyNamedFields = throw '';
 //          ^
diff --git a/pkg/front_end/testcases/records/record_type_errors.dart.weak.modular.expect b/pkg/front_end/testcases/records/record_type_errors.dart.weak.modular.expect
index 71154db..67dfe7f 100644
--- a/pkg/front_end/testcases/records/record_type_errors.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/records/record_type_errors.dart.weak.modular.expect
@@ -2,13 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:5:2: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-// () emptyType = throw '';
-//  ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (int) singleType = throw '';
 //     ^
 //
@@ -25,12 +20,12 @@
 // (var a, {var b}) missingType = throw '';
 //  ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (var a, {var b}) missingType = throw '';
 //                ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 // (int, {}) emptyNamedFields = throw '';
 //        ^
@@ -71,13 +66,8 @@
 // (var a, {var b}) missingType = throw '';
 //  ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:14:4: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-//   () emptyType = throw '';
-//    ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:15:7: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:15:7: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 //   (int) singleType = throw '';
 //       ^
 //
@@ -98,12 +88,12 @@
 //   (var a, {var b}) missingType = throw '';
 //    ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:17:18: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:17:18: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 //   (var a, {var b}) missingType = throw '';
 //                  ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:18:10: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:18:10: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 //   (int, {}) emptyNamedFields = throw '';
 //          ^
diff --git a/pkg/front_end/testcases/records/record_type_errors.dart.weak.outline.expect b/pkg/front_end/testcases/records/record_type_errors.dart.weak.outline.expect
index a917911..7f4a4e9 100644
--- a/pkg/front_end/testcases/records/record_type_errors.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/records/record_type_errors.dart.weak.outline.expect
@@ -2,13 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:5:2: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-// () emptyType = throw '';
-//  ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (int) singleType = throw '';
 //     ^
 //
@@ -25,12 +20,12 @@
 // (var a, {var b}) missingType = throw '';
 //  ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (var a, {var b}) missingType = throw '';
 //                ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 // (int, {}) emptyNamedFields = throw '';
 //        ^
diff --git a/pkg/front_end/testcases/records/record_type_errors.dart.weak.transformed.expect b/pkg/front_end/testcases/records/record_type_errors.dart.weak.transformed.expect
index 71154db..67dfe7f 100644
--- a/pkg/front_end/testcases/records/record_type_errors.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/records/record_type_errors.dart.weak.transformed.expect
@@ -2,13 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:5:2: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-// () emptyType = throw '';
-//  ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:6:5: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (int) singleType = throw '';
 //     ^
 //
@@ -25,12 +20,12 @@
 // (var a, {var b}) missingType = throw '';
 //  ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:8:16: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 // (var a, {var b}) missingType = throw '';
 //                ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:9:8: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 // (int, {}) emptyNamedFields = throw '';
 //        ^
@@ -71,13 +66,8 @@
 // (var a, {var b}) missingType = throw '';
 //  ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:14:4: Error: Record type fields list cannot be empty.
-// Try adding a record type field to the list.
-//   () emptyType = throw '';
-//    ^
-//
-// pkg/front_end/testcases/records/record_type_errors.dart:15:7: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:15:7: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 //   (int) singleType = throw '';
 //       ^
 //
@@ -98,12 +88,12 @@
 //   (var a, {var b}) missingType = throw '';
 //    ^^^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:17:18: Error: Record type fields list cannot contain only one element without a named field.
-// Try adding another record type field to the list or add a named field.
+// pkg/front_end/testcases/records/record_type_errors.dart:17:18: Error: Record type with one entry requires a trailing comma.
+// Try adding a trailing comma.
 //   (var a, {var b}) missingType = throw '';
 //                  ^
 //
-// pkg/front_end/testcases/records/record_type_errors.dart:18:10: Error: Record type named fields list cannot be empty.
+// pkg/front_end/testcases/records/record_type_errors.dart:18:10: Error: Record type named fields list can't be empty.
 // Try adding a record type named field to the list.
 //   (int, {}) emptyNamedFields = throw '';
 //          ^
diff --git a/pkg/front_end/testcases/records/simple_inference.dart b/pkg/front_end/testcases/records/simple_inference.dart
new file mode 100644
index 0000000..da9d76a
--- /dev/null
+++ b/pkg/front_end/testcases/records/simple_inference.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2022, 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.
+
+foo1((int, String?) r) {
+  var r2 = r;
+}
+
+foo2((int, String?) r, X Function<X>() f) {
+  r = (0, f());
+}
+
+foo3() {
+  (num, num) r = (3, 3.5)..$0.isEven;
+}
+
+foo4() {
+  (num, num) r = (3 as dynamic, 3.5); // Error.
+}
+
+foo5((int, String?) r, (int, X) Function<X>() f) {
+  r = f();
+}
+
+foo6((X, Y) Function<X, Y>(X x, Y y) f, int x, String y) {
+  var r = f(x, y);
+}
+
+foo7((X, (Y, Z)) Function<X, Y, Z>(X x, Y y, Z z) f, int x, String y, bool? z) {
+  var r = f(x, y, z);
+}
+
+class A8<X extends (X, Y), Y extends num> {}
+
+foo8(A8 a) {}
+
+class A9<X extends (Y, Z), Y extends num, Z extends String?> {}
+
+foo9(A9 a) {}
+
+main() {}
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.strong.expect b/pkg/front_end/testcases/records/simple_inference.dart.strong.expect
new file mode 100644
index 0000000..51b70be
--- /dev/null
+++ b/pkg/front_end/testcases/records/simple_inference.dart.strong.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
+//   (num, num) r = (3 as dynamic, 3.5); // Error.
+//                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A8<X extends (self::A8::X, self::A8::Y) = (dynamic, core::num), Y extends core::num> extends core::Object {
+  synthetic constructor •() → self::A8<self::A8::X, self::A8::Y>
+    : super core::Object::•()
+    ;
+}
+class A9<X extends (self::A9::Y, self::A9::Z%) = (core::num, core::String?), Y extends core::num, Z extends core::String?> extends core::Object {
+  synthetic constructor •() → self::A9<self::A9::X, self::A9::Y, self::A9::Z%>
+    : super core::Object::•()
+    ;
+}
+static method foo1((core::int, core::String?) r) → dynamic {
+  (core::int, core::String?) r2 = r;
+}
+static method foo2((core::int, core::String?) r, <X extends core::Object? = dynamic>() → X% f) → dynamic {
+  r = (0, f<core::String?>(){() → core::String?});
+}
+static method foo3() → dynamic {
+  (core::num, core::num) r = let final(core::int, core::double) #t1 = (3, 3.5) in block {
+    #t1.$0{core::int}.{core::int::isEven}{core::bool};
+  } =>#t1;
+}
+static method foo4() → dynamic {
+  (core::num, core::num) r = invalid-expression "pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
+  (num, num) r = (3 as dynamic, 3.5); // Error.
+                 ^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
+}
+static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
+  r = f<core::String?>(){() → (core::int, core::String?)};
+}
+static method foo6(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(X%, Y%) → (X%, Y%) f, core::int x, core::String y) → dynamic {
+  (core::int, core::String) r = f<core::int, core::String>(x, y){(core::int, core::String) → (core::int, core::String)};
+}
+static method foo7(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>(X%, Y%, Z%) → (X%, (Y%, Z%)) f, core::int x, core::String y, core::bool? z) → dynamic {
+  (core::int, (core::String, core::bool?)) r = f<core::int, core::String, core::bool?>(x, y, z){(core::int, core::String, core::bool?) → (core::int, (core::String, core::bool?))};
+}
+static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic {}
+static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/records/simple_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..f44bae4
--- /dev/null
+++ b/pkg/front_end/testcases/records/simple_inference.dart.strong.transformed.expect
@@ -0,0 +1,56 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
+//   (num, num) r = (3 as dynamic, 3.5); // Error.
+//                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A8<X extends (self::A8::X, self::A8::Y) = (dynamic, core::num), Y extends core::num> extends core::Object {
+  synthetic constructor •() → self::A8<self::A8::X, self::A8::Y>
+    : super core::Object::•()
+    ;
+}
+class A9<X extends (self::A9::Y, self::A9::Z%) = (core::num, core::String?), Y extends core::num, Z extends core::String?> extends core::Object {
+  synthetic constructor •() → self::A9<self::A9::X, self::A9::Y, self::A9::Z%>
+    : super core::Object::•()
+    ;
+}
+static method foo1((core::int, core::String?) r) → dynamic {
+  (core::int, core::String?) r2 = r;
+}
+static method foo2((core::int, core::String?) r, <X extends core::Object? = dynamic>() → X% f) → dynamic {
+  r = (0, f<core::String?>(){() → core::String?});
+}
+static method foo3() → dynamic {
+  (core::num, core::num) r = let final(core::int, core::double) #t1 = (3, 3.5) in block {
+    #t1.$0{core::int}.{core::int::isEven}{core::bool};
+  } =>#t1;
+}
+static method foo4() → dynamic {
+  (core::num, core::num) r = invalid-expression "pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
+  (num, num) r = (3 as dynamic, 3.5); // Error.
+                 ^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
+}
+static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
+  r = f<core::String?>(){() → (core::int, core::String?)};
+}
+static method foo6(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(X%, Y%) → (X%, Y%) f, core::int x, core::String y) → dynamic {
+  (core::int, core::String) r = f<core::int, core::String>(x, y){(core::int, core::String) → (core::int, core::String)};
+}
+static method foo7(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>(X%, Y%, Z%) → (X%, (Y%, Z%)) f, core::int x, core::String y, core::bool? z) → dynamic {
+  (core::int, (core::String, core::bool?)) r = f<core::int, core::String, core::bool?>(x, y, z){(core::int, core::String, core::bool?) → (core::int, (core::String, core::bool?))};
+}
+static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic {}
+static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic {}
+static method main() → dynamic {}
+
+
+Extra constant evaluation status:
+Evaluated: RecordLiteral @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
+Evaluated: VariableGetImpl @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
+Evaluated: VariableGet @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
+Extra constant evaluation: evaluated: 24, effectively constant: 3
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.textual_outline.expect b/pkg/front_end/testcases/records/simple_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..167158a
--- /dev/null
+++ b/pkg/front_end/testcases/records/simple_inference.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+foo1((int, String?) r) {}
+foo2((int, String?) r, X Function<X>() f) {}
+foo3() {}
+foo4() {}
+foo5((int, String?) r, (int, X) Function<X>() f) {}
+foo6((X, Y) Function<X, Y>(X x, Y y) f, int x, String y) {}
+foo7((X, (Y, Z)) Function<X, Y, Z>(X x, Y y, Z z) f, int x, String y, bool? z) {}
+class A8<X extends (X, Y), Y extends num> {}
+foo8(A8 a) {}
+class A9<X extends (Y, Z), Y extends num, Z extends String?> {}
+foo9(A9 a) {}
+main() {}
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.weak.expect b/pkg/front_end/testcases/records/simple_inference.dart.weak.expect
new file mode 100644
index 0000000..51b70be
--- /dev/null
+++ b/pkg/front_end/testcases/records/simple_inference.dart.weak.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
+//   (num, num) r = (3 as dynamic, 3.5); // Error.
+//                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A8<X extends (self::A8::X, self::A8::Y) = (dynamic, core::num), Y extends core::num> extends core::Object {
+  synthetic constructor •() → self::A8<self::A8::X, self::A8::Y>
+    : super core::Object::•()
+    ;
+}
+class A9<X extends (self::A9::Y, self::A9::Z%) = (core::num, core::String?), Y extends core::num, Z extends core::String?> extends core::Object {
+  synthetic constructor •() → self::A9<self::A9::X, self::A9::Y, self::A9::Z%>
+    : super core::Object::•()
+    ;
+}
+static method foo1((core::int, core::String?) r) → dynamic {
+  (core::int, core::String?) r2 = r;
+}
+static method foo2((core::int, core::String?) r, <X extends core::Object? = dynamic>() → X% f) → dynamic {
+  r = (0, f<core::String?>(){() → core::String?});
+}
+static method foo3() → dynamic {
+  (core::num, core::num) r = let final(core::int, core::double) #t1 = (3, 3.5) in block {
+    #t1.$0{core::int}.{core::int::isEven}{core::bool};
+  } =>#t1;
+}
+static method foo4() → dynamic {
+  (core::num, core::num) r = invalid-expression "pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
+  (num, num) r = (3 as dynamic, 3.5); // Error.
+                 ^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
+}
+static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
+  r = f<core::String?>(){() → (core::int, core::String?)};
+}
+static method foo6(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(X%, Y%) → (X%, Y%) f, core::int x, core::String y) → dynamic {
+  (core::int, core::String) r = f<core::int, core::String>(x, y){(core::int, core::String) → (core::int, core::String)};
+}
+static method foo7(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>(X%, Y%, Z%) → (X%, (Y%, Z%)) f, core::int x, core::String y, core::bool? z) → dynamic {
+  (core::int, (core::String, core::bool?)) r = f<core::int, core::String, core::bool?>(x, y, z){(core::int, core::String, core::bool?) → (core::int, (core::String, core::bool?))};
+}
+static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic {}
+static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.weak.modular.expect b/pkg/front_end/testcases/records/simple_inference.dart.weak.modular.expect
new file mode 100644
index 0000000..51b70be
--- /dev/null
+++ b/pkg/front_end/testcases/records/simple_inference.dart.weak.modular.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
+//   (num, num) r = (3 as dynamic, 3.5); // Error.
+//                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A8<X extends (self::A8::X, self::A8::Y) = (dynamic, core::num), Y extends core::num> extends core::Object {
+  synthetic constructor •() → self::A8<self::A8::X, self::A8::Y>
+    : super core::Object::•()
+    ;
+}
+class A9<X extends (self::A9::Y, self::A9::Z%) = (core::num, core::String?), Y extends core::num, Z extends core::String?> extends core::Object {
+  synthetic constructor •() → self::A9<self::A9::X, self::A9::Y, self::A9::Z%>
+    : super core::Object::•()
+    ;
+}
+static method foo1((core::int, core::String?) r) → dynamic {
+  (core::int, core::String?) r2 = r;
+}
+static method foo2((core::int, core::String?) r, <X extends core::Object? = dynamic>() → X% f) → dynamic {
+  r = (0, f<core::String?>(){() → core::String?});
+}
+static method foo3() → dynamic {
+  (core::num, core::num) r = let final(core::int, core::double) #t1 = (3, 3.5) in block {
+    #t1.$0{core::int}.{core::int::isEven}{core::bool};
+  } =>#t1;
+}
+static method foo4() → dynamic {
+  (core::num, core::num) r = invalid-expression "pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
+  (num, num) r = (3 as dynamic, 3.5); // Error.
+                 ^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
+}
+static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
+  r = f<core::String?>(){() → (core::int, core::String?)};
+}
+static method foo6(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(X%, Y%) → (X%, Y%) f, core::int x, core::String y) → dynamic {
+  (core::int, core::String) r = f<core::int, core::String>(x, y){(core::int, core::String) → (core::int, core::String)};
+}
+static method foo7(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>(X%, Y%, Z%) → (X%, (Y%, Z%)) f, core::int x, core::String y, core::bool? z) → dynamic {
+  (core::int, (core::String, core::bool?)) r = f<core::int, core::String, core::bool?>(x, y, z){(core::int, core::String, core::bool?) → (core::int, (core::String, core::bool?))};
+}
+static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic {}
+static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.weak.outline.expect b/pkg/front_end/testcases/records/simple_inference.dart.weak.outline.expect
new file mode 100644
index 0000000..2630b16
--- /dev/null
+++ b/pkg/front_end/testcases/records/simple_inference.dart.weak.outline.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A8<X extends (self::A8::X, self::A8::Y) = (dynamic, core::num), Y extends core::num> extends core::Object {
+  synthetic constructor •() → self::A8<self::A8::X, self::A8::Y>
+    ;
+}
+class A9<X extends (self::A9::Y, self::A9::Z%) = (core::num, core::String?), Y extends core::num, Z extends core::String?> extends core::Object {
+  synthetic constructor •() → self::A9<self::A9::X, self::A9::Y, self::A9::Z%>
+    ;
+}
+static method foo1((core::int, core::String?) r) → dynamic
+  ;
+static method foo2((core::int, core::String?) r, <X extends core::Object? = dynamic>() → X% f) → dynamic
+  ;
+static method foo3() → dynamic
+  ;
+static method foo4() → dynamic
+  ;
+static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic
+  ;
+static method foo6(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(X%, Y%) → (X%, Y%) f, core::int x, core::String y) → dynamic
+  ;
+static method foo7(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>(X%, Y%, Z%) → (X%, (Y%, Z%)) f, core::int x, core::String y, core::bool? z) → dynamic
+  ;
+static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic
+  ;
+static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/records/simple_inference.dart.weak.transformed.expect
new file mode 100644
index 0000000..f44bae4
--- /dev/null
+++ b/pkg/front_end/testcases/records/simple_inference.dart.weak.transformed.expect
@@ -0,0 +1,56 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
+//   (num, num) r = (3 as dynamic, 3.5); // Error.
+//                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A8<X extends (self::A8::X, self::A8::Y) = (dynamic, core::num), Y extends core::num> extends core::Object {
+  synthetic constructor •() → self::A8<self::A8::X, self::A8::Y>
+    : super core::Object::•()
+    ;
+}
+class A9<X extends (self::A9::Y, self::A9::Z%) = (core::num, core::String?), Y extends core::num, Z extends core::String?> extends core::Object {
+  synthetic constructor •() → self::A9<self::A9::X, self::A9::Y, self::A9::Z%>
+    : super core::Object::•()
+    ;
+}
+static method foo1((core::int, core::String?) r) → dynamic {
+  (core::int, core::String?) r2 = r;
+}
+static method foo2((core::int, core::String?) r, <X extends core::Object? = dynamic>() → X% f) → dynamic {
+  r = (0, f<core::String?>(){() → core::String?});
+}
+static method foo3() → dynamic {
+  (core::num, core::num) r = let final(core::int, core::double) #t1 = (3, 3.5) in block {
+    #t1.$0{core::int}.{core::int::isEven}{core::bool};
+  } =>#t1;
+}
+static method foo4() → dynamic {
+  (core::num, core::num) r = invalid-expression "pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
+  (num, num) r = (3 as dynamic, 3.5); // Error.
+                 ^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
+}
+static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
+  r = f<core::String?>(){() → (core::int, core::String?)};
+}
+static method foo6(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(X%, Y%) → (X%, Y%) f, core::int x, core::String y) → dynamic {
+  (core::int, core::String) r = f<core::int, core::String>(x, y){(core::int, core::String) → (core::int, core::String)};
+}
+static method foo7(<X extends core::Object? = dynamic, Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>(X%, Y%, Z%) → (X%, (Y%, Z%)) f, core::int x, core::String y, core::bool? z) → dynamic {
+  (core::int, (core::String, core::bool?)) r = f<core::int, core::String, core::bool?>(x, y, z){(core::int, core::String, core::bool?) → (core::int, (core::String, core::bool?))};
+}
+static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic {}
+static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic {}
+static method main() → dynamic {}
+
+
+Extra constant evaluation status:
+Evaluated: RecordLiteral @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
+Evaluated: VariableGetImpl @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
+Evaluated: VariableGet @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
+Extra constant evaluation: evaluated: 24, effectively constant: 3
diff --git a/pkg/front_end/testcases/records/structurally_constant.dart b/pkg/front_end/testcases/records/structurally_constant.dart
new file mode 100644
index 0000000..f5f37d6
--- /dev/null
+++ b/pkg/front_end/testcases/records/structurally_constant.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, 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.
+
+void method1([a = (0, 1), b = (const <String>[], c: 'foo')]) {
+  (0, 1); // Const
+  (const <String>[], c: 'foo'); // Const
+}
+
+void method2({a = (0, 1), b = (const <String>[], c: 'foo')}) {
+  (<String>[], c: 'foo'); // Non-const
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/records/structurally_constant.dart.strong.expect b/pkg/front_end/testcases/records/structurally_constant.dart.strong.expect
new file mode 100644
index 0000000..ea1be05
--- /dev/null
+++ b/pkg/front_end/testcases/records/structurally_constant.dart.strong.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method method1([dynamic a = #C3, dynamic b = #C6]) → void {
+  (0, 1);
+  (#C4, {c: "foo"});
+}
+static method method2({dynamic a = #C3, dynamic b = #C6}) → void {
+  (<core::String>[], {c: "foo"});
+}
+
+constants  {
+  #C1 = 0
+  #C2 = 1
+const (#C1, #C2)
+  #C4 = <core::String>[]
+  #C5 = "foo"
+const (#C4, {c:#C5})
+}
diff --git a/pkg/front_end/testcases/records/structurally_constant.dart.strong.transformed.expect b/pkg/front_end/testcases/records/structurally_constant.dart.strong.transformed.expect
new file mode 100644
index 0000000..9cea43a
--- /dev/null
+++ b/pkg/front_end/testcases/records/structurally_constant.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method method1([dynamic a = #C3, dynamic b = #C6]) → void {
+  (0, 1);
+  (#C4, {c: "foo"});
+}
+static method method2({dynamic a = #C3, dynamic b = #C6}) → void {
+  (core::_GrowableList::•<core::String>(0), {c: "foo"});
+}
+
+constants  {
+  #C1 = 0
+  #C2 = 1
+const (#C1, #C2)
+  #C4 = <core::String>[]
+  #C5 = "foo"
+const (#C4, {c:#C5})
+}
+
+Extra constant evaluation status:
+Evaluated: RecordLiteral @ org-dartlang-testcase:///structurally_constant.dart:6:3 -> RecordConstant(const (0, 1))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///structurally_constant.dart:7:3 -> RecordConstant(const (const <String>[], {c: "foo"}))
+Extra constant evaluation: evaluated: 4, effectively constant: 2
diff --git a/pkg/front_end/testcases/records/structurally_constant.dart.textual_outline.expect b/pkg/front_end/testcases/records/structurally_constant.dart.textual_outline.expect
new file mode 100644
index 0000000..567ec32
--- /dev/null
+++ b/pkg/front_end/testcases/records/structurally_constant.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void method1([a = (0, 1), b = (const <String>[], c: 'foo')]) {}
+void method2({a = (0, 1), b = (const <String>[], c: 'foo')}) {}
diff --git a/pkg/front_end/testcases/records/structurally_constant.dart.weak.expect b/pkg/front_end/testcases/records/structurally_constant.dart.weak.expect
new file mode 100644
index 0000000..334aace
--- /dev/null
+++ b/pkg/front_end/testcases/records/structurally_constant.dart.weak.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method method1([dynamic a = #C3, dynamic b = #C6]) → void {
+  (0, 1);
+  (#C4, {c: "foo"});
+}
+static method method2({dynamic a = #C3, dynamic b = #C6}) → void {
+  (<core::String>[], {c: "foo"});
+}
+
+constants  {
+  #C1 = 0
+  #C2 = 1
+const (#C1, #C2)
+  #C4 = <core::String*>[]
+  #C5 = "foo"
+const (#C4, {c:#C5})
+}
diff --git a/pkg/front_end/testcases/records/structurally_constant.dart.weak.modular.expect b/pkg/front_end/testcases/records/structurally_constant.dart.weak.modular.expect
new file mode 100644
index 0000000..334aace
--- /dev/null
+++ b/pkg/front_end/testcases/records/structurally_constant.dart.weak.modular.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method method1([dynamic a = #C3, dynamic b = #C6]) → void {
+  (0, 1);
+  (#C4, {c: "foo"});
+}
+static method method2({dynamic a = #C3, dynamic b = #C6}) → void {
+  (<core::String>[], {c: "foo"});
+}
+
+constants  {
+  #C1 = 0
+  #C2 = 1
+const (#C1, #C2)
+  #C4 = <core::String*>[]
+  #C5 = "foo"
+const (#C4, {c:#C5})
+}
diff --git a/pkg/front_end/testcases/records/structurally_constant.dart.weak.outline.expect b/pkg/front_end/testcases/records/structurally_constant.dart.weak.outline.expect
new file mode 100644
index 0000000..67f8ca4
--- /dev/null
+++ b/pkg/front_end/testcases/records/structurally_constant.dart.weak.outline.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method method1([has-declared-initializer dynamic a, has-declared-initializer dynamic b]) → void
+  ;
+static method method2({has-declared-initializer dynamic a, has-declared-initializer dynamic b}) → void
+  ;
diff --git a/pkg/front_end/testcases/records/structurally_constant.dart.weak.transformed.expect b/pkg/front_end/testcases/records/structurally_constant.dart.weak.transformed.expect
new file mode 100644
index 0000000..e705279
--- /dev/null
+++ b/pkg/front_end/testcases/records/structurally_constant.dart.weak.transformed.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method method1([dynamic a = #C3, dynamic b = #C6]) → void {
+  (0, 1);
+  (#C4, {c: "foo"});
+}
+static method method2({dynamic a = #C3, dynamic b = #C6}) → void {
+  (core::_GrowableList::•<core::String>(0), {c: "foo"});
+}
+
+constants  {
+  #C1 = 0
+  #C2 = 1
+const (#C1, #C2)
+  #C4 = <core::String*>[]
+  #C5 = "foo"
+const (#C4, {c:#C5})
+}
+
+Extra constant evaluation status:
+Evaluated: RecordLiteral @ org-dartlang-testcase:///structurally_constant.dart:6:3 -> RecordConstant(const (0, 1))
+Evaluated: RecordLiteral @ org-dartlang-testcase:///structurally_constant.dart:7:3 -> RecordConstant(const (const <String*>[], {c: "foo"}))
+Extra constant evaluation: evaluated: 4, effectively constant: 2
diff --git a/pkg/front_end/testcases/records/tear_off_with_record_type.dart b/pkg/front_end/testcases/records/tear_off_with_record_type.dart
new file mode 100644
index 0000000..6a881c3
--- /dev/null
+++ b/pkg/front_end/testcases/records/tear_off_with_record_type.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, 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.
+
+class C<T> {
+  void method() {
+    C<(num, {String name})>.new; // Const
+    C<(T, {String name})>.new; // Non-const
+    C<(num, {T name})>.new; // Non-const
+  }
+}
diff --git a/pkg/front_end/testcases/records/tear_off_with_record_type.dart.strong.expect b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.strong.expect
new file mode 100644
index 0000000..024d162
--- /dev/null
+++ b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.strong.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    : super core::Object::•()
+    ;
+  method method() → void {
+    #C2;
+    #C1<(self::C::T%, {required name: core::String})>;
+    #C1<(core::num, {required name: self::C::T%})>;
+  }
+}
+
+constants  {
+  #C1 = constructor-tearoff self::C::•
+  #C2 = instantiation #C1 <(core::num, {required name: core::String})>
+}
diff --git a/pkg/front_end/testcases/records/tear_off_with_record_type.dart.strong.transformed.expect b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..024d162
--- /dev/null
+++ b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    : super core::Object::•()
+    ;
+  method method() → void {
+    #C2;
+    #C1<(self::C::T%, {required name: core::String})>;
+    #C1<(core::num, {required name: self::C::T%})>;
+  }
+}
+
+constants  {
+  #C1 = constructor-tearoff self::C::•
+  #C2 = instantiation #C1 <(core::num, {required name: core::String})>
+}
diff --git a/pkg/front_end/testcases/records/tear_off_with_record_type.dart.textual_outline.expect b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.textual_outline.expect
new file mode 100644
index 0000000..263a133
--- /dev/null
+++ b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class C<T> {
+  void method() {}
+}
diff --git a/pkg/front_end/testcases/records/tear_off_with_record_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..263a133
--- /dev/null
+++ b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class C<T> {
+  void method() {}
+}
diff --git a/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.expect b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.expect
new file mode 100644
index 0000000..4d983ae
--- /dev/null
+++ b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    : super core::Object::•()
+    ;
+  method method() → void {
+    #C2;
+    #C1<(self::C::T%, {required name: core::String})>;
+    #C1<(core::num, {required name: self::C::T%})>;
+  }
+}
+
+constants  {
+  #C1 = constructor-tearoff self::C::•
+  #C2 = instantiation #C1 <(core::num*, {required name: core::String*})*>
+}
diff --git a/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.modular.expect b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.modular.expect
new file mode 100644
index 0000000..4d983ae
--- /dev/null
+++ b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.modular.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    : super core::Object::•()
+    ;
+  method method() → void {
+    #C2;
+    #C1<(self::C::T%, {required name: core::String})>;
+    #C1<(core::num, {required name: self::C::T%})>;
+  }
+}
+
+constants  {
+  #C1 = constructor-tearoff self::C::•
+  #C2 = instantiation #C1 <(core::num*, {required name: core::String*})*>
+}
diff --git a/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.outline.expect b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.outline.expect
new file mode 100644
index 0000000..b105acb
--- /dev/null
+++ b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.outline.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    ;
+  method method() → void
+    ;
+}
diff --git a/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.transformed.expect b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.transformed.expect
new file mode 100644
index 0000000..4d983ae
--- /dev/null
+++ b/pkg/front_end/testcases/records/tear_off_with_record_type.dart.weak.transformed.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::T%>
+    : super core::Object::•()
+    ;
+  method method() → void {
+    #C2;
+    #C1<(self::C::T%, {required name: core::String})>;
+    #C1<(core::num, {required name: self::C::T%})>;
+  }
+}
+
+constants  {
+  #C1 = constructor-tearoff self::C::•
+  #C2 = instantiation #C1 <(core::num*, {required name: core::String*})*>
+}
diff --git a/pkg/front_end/testcases/regress/issue_42423.dart.weak.transformed.expect b/pkg/front_end/testcases/regress/issue_42423.dart.weak.transformed.expect
index 2400154..60ba64c 100644
--- a/pkg/front_end/testcases/regress/issue_42423.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_42423.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
 
 static method test1(dynamic stringList) → dynamic {
   core::Set<core::int> intSet = block {
-    final core::Set<core::int> #t1 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t1 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<dynamic>? #t2 = stringList as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
     if(!(#t2 == null)) {
       core::Iterator<dynamic> :sync-for-iterator = #t2{core::Iterable<dynamic>}.{core::Iterable::iterator}{core::Iterator<dynamic>};
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.transformed.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.transformed.expect
index ae2ecfb..9642b09 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.transformed.expect
@@ -55,10 +55,10 @@
 static method main() → dynamic async /* futureValueType= dynamic */ {
   core::Map<core::int*, core::bool*>* m = <core::int*, core::bool*>{};
   core::Set<core::int*>* s = block {
-    final core::Set<core::int*>* #t1 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t1 = new col::_InternalLinkedHashSet::•<core::int*>();
   } =>#t1;
   core::Iterable<core::int*>* i = block {
-    final core::Set<core::int*>* #t2 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t2 = new col::_InternalLinkedHashSet::•<core::int*>();
   } =>#t2;
   col::LinkedHashSet<core::int*>* lhs = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:15:28: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
  - 'Set' is from 'dart:core'.
@@ -66,7 +66,7 @@
 Change the type of the set literal or the context in which it is used.
   LinkedHashSet<int> lhs = {};
                            ^" in block {
-    final core::Set<dynamic>* #t3 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t3 = new col::_InternalLinkedHashSet::•<dynamic>();
   } =>#t3;
   col::LinkedHashMap<core::int*, core::bool*>* lhm = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:16:34: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
  - 'Map' is from 'dart:core'.
@@ -89,11 +89,11 @@
   return <core::int*, core::bool*>{};
 static method setfun() → asy::Future<core::Set<core::int*>*>* async /* futureValueType= core::Set<core::int*>* */ 
   return block {
-    final core::Set<core::int*>* #t4 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t4 = new col::_InternalLinkedHashSet::•<core::int*>();
   } =>#t4;
 static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* async /* futureValueType= core::Iterable<core::int*>* */ 
   return block {
-    final core::Set<core::int*>* #t5 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t5 = new col::_InternalLinkedHashSet::•<core::int*>();
   } =>#t5;
 static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* async /* futureValueType= col::LinkedHashSet<core::int*>* */ 
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:34:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
@@ -103,7 +103,7 @@
 Change the type of the set literal or the context in which it is used.
 Future<LinkedHashSet<int>> lhsfun() async => {};
                                              ^" in block {
-    final core::Set<dynamic>* #t6 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t6 = new col::_InternalLinkedHashSet::•<dynamic>();
   } =>#t6;
 static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* async /* futureValueType= col::LinkedHashMap<core::int*, core::bool*>* */ 
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:35:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
@@ -117,11 +117,11 @@
   return <core::int*, core::bool*>{};
 static method setfun2() → FutureOr<core::Set<core::int*>*>*
   return block {
-    final core::Set<core::int*>* #t7 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t7 = new col::_InternalLinkedHashSet::•<core::int*>();
   } =>#t7;
 static method iterablefun2() → FutureOr<core::Iterable<core::int*>*>*
   return block {
-    final core::Set<core::int*>* #t8 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t8 = new col::_InternalLinkedHashSet::•<core::int*>();
   } =>#t8;
 static method lhsfun2() → FutureOr<col::LinkedHashSet<core::int*>*>*
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:40:43: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashSet<int>>'.
@@ -129,7 +129,7 @@
  - 'LinkedHashSet' is from 'dart:collection'.
 FutureOr<LinkedHashSet<int>> lhsfun2() => {};
                                           ^" in ( block {
-    final core::Set<dynamic>* #t9 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t9 = new col::_InternalLinkedHashSet::•<dynamic>();
   } =>#t9) as{TypeError} FutureOr<col::LinkedHashSet<core::int*>*>*;
 static method lhmfun2() → FutureOr<col::LinkedHashMap<core::int*, core::bool*>*>*
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:41:49: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashMap<int, bool>>'.
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule2.dart.weak.transformed.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule2.dart.weak.transformed.expect
index 2fa022c..1cc8211 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule2.dart.weak.transformed.expect
@@ -51,17 +51,17 @@
 static method main() → dynamic async /* futureValueType= dynamic */ {
   core::Map<core::int, core::bool> m = <core::int, core::bool>{};
   core::Set<core::int> s = block {
-    final core::Set<core::int> #t1 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t1 = new col::_InternalLinkedHashSet::•<core::int>();
   } =>#t1;
   core::Iterable<core::int> i = block {
-    final core::Set<core::int> #t2 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t2 = new col::_InternalLinkedHashSet::•<core::int>();
   } =>#t2;
   col::LinkedHashSet<core::int> lhs = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule2.dart:13:28: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'LinkedHashSet<int>'.
  - 'Set' is from 'dart:core'.
  - 'LinkedHashSet' is from 'dart:collection'.
   LinkedHashSet<int> lhs = {};
                            ^" in ( block {
-    final core::Set<dynamic> #t3 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t3 = new col::_InternalLinkedHashSet::•<dynamic>();
   } =>#t3) as{TypeError,ForNonNullableByDefault} col::LinkedHashSet<core::int>;
   col::LinkedHashMap<core::int, core::bool> lhm = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule2.dart:14:34: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'LinkedHashMap<int, bool>'.
  - 'Map' is from 'dart:core'.
@@ -83,11 +83,11 @@
   return <core::int, core::bool>{};
 static method setfun() → asy::Future<core::Set<core::int>> async /* futureValueType= core::Set<core::int> */ 
   return block {
-    final core::Set<core::int> #t4 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t4 = new col::_InternalLinkedHashSet::•<core::int>();
   } =>#t4;
 static method iterablefun() → asy::Future<core::Iterable<core::int>> async /* futureValueType= core::Iterable<core::int> */ 
   return block {
-    final core::Set<core::int> #t5 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t5 = new col::_InternalLinkedHashSet::•<core::int>();
   } =>#t5;
 static method lhsfun() → asy::Future<col::LinkedHashSet<core::int>> async /* futureValueType= col::LinkedHashSet<core::int> */ 
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule2.dart:32:46: Error: A value of type 'Set<dynamic>' can't be returned from an async function with return type 'Future<LinkedHashSet<int>>'.
@@ -96,7 +96,7 @@
  - 'LinkedHashSet' is from 'dart:collection'.
 Future<LinkedHashSet<int>> lhsfun() async => {};
                                              ^" in ( block {
-    final core::Set<dynamic> #t6 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t6 = new col::_InternalLinkedHashSet::•<dynamic>();
   } =>#t6) as{TypeError,ForNonNullableByDefault} col::LinkedHashSet<core::int>;
 static method lhmfun() → asy::Future<col::LinkedHashMap<core::int, core::bool>> async /* futureValueType= col::LinkedHashMap<core::int, core::bool> */ 
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule2.dart:33:52: Error: A value of type 'Map<dynamic, dynamic>' can't be returned from an async function with return type 'Future<LinkedHashMap<int, bool>>'.
@@ -109,11 +109,11 @@
   return <core::int, core::bool>{};
 static method setfun2() → FutureOr<core::Set<core::int>>
   return block {
-    final core::Set<core::int> #t7 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t7 = new col::_InternalLinkedHashSet::•<core::int>();
   } =>#t7;
 static method iterablefun2() → FutureOr<core::Iterable<core::int>>
   return block {
-    final core::Set<core::int> #t8 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t8 = new col::_InternalLinkedHashSet::•<core::int>();
   } =>#t8;
 static method lhsfun2() → FutureOr<col::LinkedHashSet<core::int>>
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule2.dart:38:43: Error: A value of type 'Set<dynamic>' can't be returned from a function with return type 'FutureOr<LinkedHashSet<int>>'.
@@ -121,7 +121,7 @@
  - 'LinkedHashSet' is from 'dart:collection'.
 FutureOr<LinkedHashSet<int>> lhsfun2() => {};
                                           ^" in ( block {
-    final core::Set<dynamic> #t9 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t9 = new col::_InternalLinkedHashSet::•<dynamic>();
   } =>#t9) as{TypeError,ForNonNullableByDefault} FutureOr<col::LinkedHashSet<core::int>>;
 static method lhmfun2() → FutureOr<col::LinkedHashMap<core::int, core::bool>>
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule2.dart:39:49: Error: A value of type 'Map<dynamic, dynamic>' can't be returned from a function with return type 'FutureOr<LinkedHashMap<int, bool>>'.
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 09ae599..2bd8925 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -6,6 +6,8 @@
 # Kernel ASTs directly, that is, code in pkg/fasta/lib/src/kernel/ with
 # strong-mode enabled.
 
+macros/scope_access: SemiFuzzCrash
+
 dart2js/flutter_issue94561/main: SemiFuzzFailure
 dart2js/flutter_issue94561/main.no_link: SemiFuzzFailure
 dart2js/late_fields: SemiFuzzFailure
@@ -26,6 +28,7 @@
 late_lowering/private_members: SemiFuzzFailure # Reproduced in https://dart-review.googlesource.com/c/sdk/+/242285
 macros/multiple_imports: SemiFuzzFailure # probably augment imports that isn't split correctly.
 nnbd/constants: SemiFuzzFailure # Reproduced in https://dart-review.googlesource.com/c/sdk/+/242441
+macros/multiple_augment_class: SemiFuzzFailure # https://github.com/dart-lang/sdk/issues/49990
 
 # These tests have "privacy issues" and isn't compatiable with splitting files (fuzzing):
 dart2js/mixin_default_values/main: semiFuzzFailureOnForceRebuildBodies # private method
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 7516fa9..642a81e 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -8,6 +8,7 @@
 general/error_recovery/issue_38415.crash: EmptyOutput
 general/error_recovery/issue_39024.crash: EmptyOutput
 general/error_recovery/issue_39058.crash: EmptyOutput
+general/issue49357a: EmptyOutput
 rasta/bad_interpolation: EmptyOutput
 rasta/issue_000035: EmptyOutput
 rasta/issue_000035a: EmptyOutput
@@ -20,8 +21,8 @@
 regress/issue_39091_2: EmptyOutput
 regress/utf_16_le_content.crash: EmptyOutput
 
-const_functions/const_functions_const_ctor_error: FormatterCrash
 const_functions/const_functions_const_ctor: FormatterCrash
+const_functions/const_functions_const_ctor_error: FormatterCrash
 const_functions/const_functions_const_factory: FormatterCrash
 constructor_tearoffs/issue46133: FormatterCrash
 constructor_tearoffs/issue47075: FormatterCrash
@@ -37,8 +38,8 @@
 extension_types/simple_operator_resolution: FormatterCrash
 extension_types/simple_setter_resolution: FormatterCrash
 extension_types/simple_show_and_hide: FormatterCrash
-extension_types/simple_show_hide_conflicts: FormatterCrash
 extension_types/simple_show_hide: FormatterCrash
+extension_types/simple_show_hide_conflicts: FormatterCrash
 extension_types/type_variable_in_static_context: FormatterCrash
 extension_types/various_hide_elements: FormatterCrash
 extension_types/various_show_elements: FormatterCrash
@@ -51,13 +52,13 @@
 general/bad_setter_abstract: FormatterCrash
 general/bug31124: FormatterCrash
 general/clone_function_type: FormatterCrash
-general/constants/js_semantics/number_folds_opt_out: FormatterCrash
 general/constants/js_semantics/number_folds: FormatterCrash
+general/constants/js_semantics/number_folds_opt_out: FormatterCrash
 general/constants/non_const_constructor: FormatterCrash
-general/constants/number_folds_opt_out: FormatterCrash
 general/constants/number_folds: FormatterCrash
-general/constants/various: FormatterCrash
+general/constants/number_folds_opt_out: FormatterCrash
 general/constants/various2: FormatterCrash
+general/constants/various: FormatterCrash
 general/constructor_initializer_invalid: FormatterCrash
 general/duplicated_declarations: FormatterCrash
 general/enum_super_constructor: FormatterCrash
@@ -82,10 +83,10 @@
 general/extension_types_feature_not_enabled: FormatterCrash
 general/function_type_default_value: FormatterCrash
 general/incomplete_field_formal_parameter: FormatterCrash
-general/invalid_operator: FormatterCrash
 general/invalid_operator2: FormatterCrash
+general/invalid_operator: FormatterCrash
 general/invalid_super_initializer: FormatterCrash
-general/issue_46886: FormatterCrash
+general/issue28565: FormatterCrash
 general/issue41842: FormatterCrash
 general/issue42997: FormatterCrash
 general/issue43363: FormatterCrash
@@ -97,14 +98,17 @@
 general/issue48487: FormatterCrash
 general/issue48487b: FormatterCrash
 general/issue48919: FormatterCrash
+general/issue_46886: FormatterCrash
 general/macro_class: FormatterCrash
-general/many_errors: FormatterCrash
 general/many_errors2: FormatterCrash
+general/many_errors: FormatterCrash
 general/missing_prefix_name: FormatterCrash
 general/new_as_selector: FormatterCrash
 general/null_aware_super: FormatterCrash
-general/null_safety_invalid_experiment_and_language_version: FormatterCrash
 general/null_safety_invalid_experiment: FormatterCrash
+general/null_safety_invalid_experiment_and_language_version: FormatterCrash
+general/records: FormatterCrash
+general/records_opt_out: FormatterCrash
 general/type_parameters_on_void: FormatterCrash
 general/type_variable_in_static_context: FormatterCrash
 general/var_as_type_name: FormatterCrash
@@ -113,21 +117,23 @@
 macros/augment_concrete: FormatterCrash
 macros/augment_super: FormatterCrash
 macros/class_members: FormatterCrash
+macros/duplicate_augment: FormatterCrash
 macros/extend_augmented: FormatterCrash
 macros/inject_constructor: FormatterCrash
 macros/library_members: FormatterCrash
 macros/macro_class: FormatterCrash
+macros/multiple_augment_class: FormatterCrash
 macros/multiple_imports: FormatterCrash
 macros/scope_access: FormatterCrash
-nnbd_mixed/inheritance_from_opt_in: FormatterCrash
-nnbd_mixed/issue41597: FormatterCrash
-nnbd_mixed/null_safety_invalid_language_version: FormatterCrash
 nnbd/abstract_field_errors: FormatterCrash
 nnbd/duplicates_instance_extension: FormatterCrash
 nnbd/field_vs_setter: FormatterCrash
 nnbd/forbidden_supers: FormatterCrash
 nnbd/later: FormatterCrash
 nnbd/nonfield_vs_setter: FormatterCrash
+nnbd_mixed/inheritance_from_opt_in: FormatterCrash
+nnbd_mixed/issue41597: FormatterCrash
+nnbd_mixed/null_safety_invalid_language_version: FormatterCrash
 nonfunction_type_aliases/old_version: FormatterCrash
 rasta/bad_redirection: FormatterCrash
 rasta/issue_000032: FormatterCrash
@@ -138,10 +144,13 @@
 rasta/issue_000047: FormatterCrash
 rasta/malformed_const_constructor: FormatterCrash
 rasta/mandatory_parameter_initializer: FormatterCrash
+records/const_record_literal: FormatterCrash
 records/record_literal_errors: FormatterCrash
 records/record_type: FormatterCrash
 records/record_type_errors: FormatterCrash
 records/record_type_unsupported: FormatterCrash
+records/simple_inference: FormatterCrash
+records/structurally_constant: FormatterCrash
 regress/ambiguous_builder_01: FormatterCrash
 regress/issue_29942: FormatterCrash
 regress/issue_29944: FormatterCrash
diff --git a/pkg/front_end/testcases/unified_collections/fold_initial.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/fold_initial.dart.weak.transformed.expect
index 7ebbdd7..673b6f0 100644
--- a/pkg/front_end/testcases/unified_collections/fold_initial.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/unified_collections/fold_initial.dart.weak.transformed.expect
@@ -17,7 +17,7 @@
   } =>#t1;
   self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
   core::Set<core::int*>* set = block {
-    final core::Set<core::int*>* #t2 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t2 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t2.{core::Set::add}{Invariant}(element0 as{TypeError,ForDynamic} core::int*){(core::int*) →* core::bool*};
     #t2.{core::Set::add}{Invariant}(element1 as{TypeError} core::int*){(core::int*) →* core::bool*};
     #t2.{core::Set::add}{Invariant}(element2){(core::int*) →* core::bool*};
@@ -51,7 +51,7 @@
   } =>#t3;
   self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
   core::Set<core::int*>* set = block {
-    final core::Set<core::int*>* #t6 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t6 = new col::_InternalLinkedHashSet::•<core::int*>();
     {
       core::Iterator<dynamic>* :sync-for-iterator = (initial as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator}{core::Iterator<dynamic>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -92,7 +92,7 @@
   } =>#t9;
   self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
   core::Set<core::int*>* set = block {
-    final core::Set<core::int*>* #t12 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t12 = new col::_InternalLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::num*>* :sync-for-iterator = initial.{core::Iterable::iterator}{core::Iterator<core::num*>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -133,7 +133,7 @@
   } =>#t15;
   self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
   core::Set<core::int*>* set = block {
-    final core::Set<core::int*>* #t18 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t18 = new col::_InternalLinkedHashSet::•<core::int*>();
     {
       core::Iterator<core::num*>* :sync-for-iterator = initial.{core::Iterable::iterator}{core::Iterator<core::num*>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -209,7 +209,7 @@
   } =>#t25;
   self::expect(core::_GrowableList::generate<core::int*>(7, (core::int* i) → core::int* => i), list);
   core::Set<core::int*>* set = block {
-    final core::Set<core::int*>* #t27 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t27 = new col::_InternalLinkedHashSet::•<core::int*>();
     final core::Iterable<core::int*>* #t28 = initial;
     if(!(#t28 == null))
       #t27.{core::Set::addAll}{Invariant}(#t28){(core::Iterable<core::int*>*) →* void};
diff --git a/pkg/front_end/testcases/unified_collections/fold_initial2.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/fold_initial2.dart.weak.transformed.expect
index a52dccb..633fc0e 100644
--- a/pkg/front_end/testcases/unified_collections/fold_initial2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/unified_collections/fold_initial2.dart.weak.transformed.expect
@@ -17,7 +17,7 @@
   } =>#t1;
   self::expect(core::_GrowableList::generate<core::int?>(7, (core::int? i) → core::int? => i), list);
   core::Set<core::int?> set = block {
-    final core::Set<core::int?> #t2 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t2 = new col::_InternalLinkedHashSet::•<core::int?>();
     #t2.{core::Set::add}{Invariant}(element0 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?){(core::int?) → core::bool};
     #t2.{core::Set::add}{Invariant}(element1{core::int}){(core::int?) → core::bool};
     #t2.{core::Set::add}{Invariant}(element2){(core::int?) → core::bool};
@@ -51,7 +51,7 @@
   } =>#t3;
   self::expect(core::_GrowableList::generate<core::int>(7, (core::int i) → core::int => i), list);
   core::Set<core::int> set = block {
-    final core::Set<core::int> #t6 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t6 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = (initial as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -178,7 +178,7 @@
   } =>#t17;
   self::expect(core::_GrowableList::generate<core::int>(7, (core::int i) → core::int => i), list);
   core::Set<core::int> set = block {
-    final core::Set<core::int> #t19 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t19 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<core::int>? #t20 = initial;
     if(!(#t20 == null))
       #t19.{core::Set::addAll}{Invariant}(#t20{core::Iterable<core::int>}){(core::Iterable<core::int>) → void};
diff --git a/pkg/front_end/testcases/unified_collections/invariance.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/invariance.dart.weak.transformed.expect
index 103e813..bdc9157 100644
--- a/pkg/front_end/testcases/unified_collections/invariance.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/unified_collections/invariance.dart.weak.transformed.expect
@@ -34,19 +34,19 @@
       #t1.{core::List::add}{Invariant}(2){(core::int*) →* void};
   } =>#t1;
   core::Set<core::int*>* set1 = block {
-    final core::Set<core::int*>* #t6 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t6 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t6.{core::Set::add}{Invariant}(0){(core::int*) →* core::bool*};
   } =>#t6;
   core::Set<core::num*>* set2 = block {
-    final core::Set<core::num*>* #t7 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t7 = new col::_InternalLinkedHashSet::•<core::num*>();
     #t7.{core::Set::add}{Invariant}(0){(core::num*) →* core::bool*};
   } =>#t7;
   dynamic set3 = block {
-    final core::Set<core::int*>* #t8 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t8 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t8.{core::Set::add}{Invariant}(0){(core::int*) →* core::bool*};
   } =>#t8;
   core::Set<core::int*>* set = block {
-    final core::Set<core::int*>* #t9 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t9 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t9.{core::Set::add}{Invariant}(0){(core::int*) →* core::bool*};
     #t9.{core::Set::addAll}{Invariant}(set1){(core::Iterable<core::int*>*) →* void};
     {
diff --git a/pkg/front_end/testcases/unified_collections/invariance2.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/invariance2.dart.weak.transformed.expect
index 8daf324..3470bf4 100644
--- a/pkg/front_end/testcases/unified_collections/invariance2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/unified_collections/invariance2.dart.weak.transformed.expect
@@ -25,19 +25,19 @@
       #t1.{core::List::add}{Invariant}(2){(core::int?) → void};
   } =>#t1;
   core::Set<core::int> set1 = block {
-    final core::Set<core::int> #t4 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t4 = new col::_InternalLinkedHashSet::•<core::int>();
     #t4.{core::Set::add}{Invariant}(0){(core::int) → core::bool};
   } =>#t4;
   core::Set<core::int?> set2 = block {
-    final core::Set<core::int?> #t5 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t5 = new col::_InternalLinkedHashSet::•<core::int?>();
     #t5.{core::Set::add}{Invariant}(0){(core::int?) → core::bool};
   } =>#t5;
   dynamic set3 = block {
-    final core::Set<core::int> #t6 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t6 = new col::_InternalLinkedHashSet::•<core::int>();
     #t6.{core::Set::add}{Invariant}(0){(core::int) → core::bool};
   } =>#t6;
   core::Set<core::int?> set = block {
-    final core::Set<core::int?> #t7 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t7 = new col::_InternalLinkedHashSet::•<core::int?>();
     #t7.{core::Set::add}{Invariant}(0){(core::int?) → core::bool};
     #t7.{core::Set::addAll}{Invariant}(set1){(core::Iterable<core::int?>) → void};
     #t7.{core::Set::addAll}{Invariant}(set2){(core::Iterable<core::int?>) → void};
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/set_add_all.dart.weak.transformed.expect
index 3e729d4..eb20a9e 100644
--- a/pkg/front_end/testcases/unified_collections/set_add_all.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/unified_collections/set_add_all.dart.weak.transformed.expect
@@ -6,55 +6,55 @@
 
 static method useAddAll() → void {
   dynamic dynamicSet1 = block {
-    final core::Set<core::int*>* #t1 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t1 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t1.{core::Set::add}{Invariant}(0){(core::int*) →* core::bool*};
     #t1.{core::Set::add}{Invariant}(1){(core::int*) →* core::bool*};
     #t1.{core::Set::add}{Invariant}(2){(core::int*) →* core::bool*};
   } =>#t1;
   dynamic dynamicSet2 = block {
-    final core::Set<core::num*>* #t2 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t2 = new col::_InternalLinkedHashSet::•<core::num*>();
     #t2.{core::Set::add}{Invariant}(3){(core::num*) →* core::bool*};
     #t2.{core::Set::add}{Invariant}(4){(core::num*) →* core::bool*};
     #t2.{core::Set::add}{Invariant}(5){(core::num*) →* core::bool*};
   } =>#t2;
   core::Iterable<core::int*>* iterableIntSet = block {
-    final core::Set<core::int*>* #t3 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t3 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t3.{core::Set::add}{Invariant}(6){(core::int*) →* core::bool*};
     #t3.{core::Set::add}{Invariant}(7){(core::int*) →* core::bool*};
     #t3.{core::Set::add}{Invariant}(8){(core::int*) →* core::bool*};
   } =>#t3;
   core::Iterable<core::num*>* iterableNumSet1 = block {
-    final core::Set<core::int*>* #t4 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t4 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t4.{core::Set::add}{Invariant}(9){(core::int*) →* core::bool*};
     #t4.{core::Set::add}{Invariant}(10){(core::int*) →* core::bool*};
     #t4.{core::Set::add}{Invariant}(11){(core::int*) →* core::bool*};
   } =>#t4;
   core::Iterable<core::num*>* iterableNumSet2 = block {
-    final core::Set<core::num*>* #t5 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t5 = new col::_InternalLinkedHashSet::•<core::num*>();
     #t5.{core::Set::add}{Invariant}(12){(core::num*) →* core::bool*};
     #t5.{core::Set::add}{Invariant}(13){(core::num*) →* core::bool*};
     #t5.{core::Set::add}{Invariant}(14){(core::num*) →* core::bool*};
   } =>#t5;
   core::Set<core::int*>* intSet = block {
-    final core::Set<core::int*>* #t6 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t6 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t6.{core::Set::add}{Invariant}(15){(core::int*) →* core::bool*};
     #t6.{core::Set::add}{Invariant}(16){(core::int*) →* core::bool*};
     #t6.{core::Set::add}{Invariant}(17){(core::int*) →* core::bool*};
   } =>#t6;
   core::Set<core::num*>* numSet1 = block {
-    final core::Set<core::int*>* #t7 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t7 = new col::_InternalLinkedHashSet::•<core::int*>();
     #t7.{core::Set::add}{Invariant}(18){(core::int*) →* core::bool*};
     #t7.{core::Set::add}{Invariant}(19){(core::int*) →* core::bool*};
     #t7.{core::Set::add}{Invariant}(20){(core::int*) →* core::bool*};
   } =>#t7;
   core::Set<core::num*>* numSet2 = block {
-    final core::Set<core::num*>* #t8 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t8 = new col::_InternalLinkedHashSet::•<core::num*>();
     #t8.{core::Set::add}{Invariant}(21){(core::num*) →* core::bool*};
     #t8.{core::Set::add}{Invariant}(22){(core::num*) →* core::bool*};
     #t8.{core::Set::add}{Invariant}(23){(core::num*) →* core::bool*};
   } =>#t8;
   core::Set<core::int*>* set1 = block {
-    final core::Set<core::int*>* #t9 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t9 = new col::_InternalLinkedHashSet::•<core::int*>();
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator}{core::Iterator<dynamic>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -120,7 +120,7 @@
   } =>#t9;
   self::expect(core::_GrowableList::generate<core::int*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(){() →* core::Set<core::int*>*}, set1);
   core::Set<core::num*>* set2 = block {
-    final core::Set<core::num*>* #t22 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t22 = new col::_InternalLinkedHashSet::•<core::num*>();
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator}{core::Iterator<dynamic>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -150,7 +150,7 @@
   } =>#t22;
   self::expect(core::_GrowableList::generate<core::num*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(){() →* core::Set<core::num*>*}, set2);
   core::Set<core::int*>* set3 = block {
-    final core::Set<core::int*>* #t27 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t27 = new col::_InternalLinkedHashSet::•<core::int*>();
     final core::Iterable<dynamic>* #t28 = dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
     if(!(#t28 == null)) {
       core::Iterator<dynamic>* :sync-for-iterator = #t28.{core::Iterable::iterator}{core::Iterator<dynamic>*};
@@ -226,7 +226,7 @@
   } =>#t27;
   self::expect(core::_GrowableList::generate<core::int*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(){() →* core::Set<core::int*>*}, set3);
   core::Set<core::num*>* set4 = block {
-    final core::Set<core::num*>* #t48 = new col::_CompactLinkedHashSet::•<core::num*>();
+    final core::Set<core::num*>* #t48 = new col::_InternalLinkedHashSet::•<core::num*>();
     final core::Iterable<dynamic>* #t49 = dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
     if(!(#t49 == null)) {
       core::Iterator<dynamic>* :sync-for-iterator = #t49.{core::Iterable::iterator}{core::Iterator<dynamic>*};
@@ -270,7 +270,7 @@
   } =>#t48;
   self::expect(core::_GrowableList::generate<core::num*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(){() →* core::Set<core::num*>*}, set4);
   core::Set<core::int*>* set5 = block {
-    final core::Set<core::int*>* #t61 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t61 = new col::_InternalLinkedHashSet::•<core::int*>();
     {
       core::Iterator<dynamic>* :sync-for-iterator = (dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*).{core::Iterable::iterator}{core::Iterator<dynamic>*};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -347,7 +347,7 @@
   } =>#t74;
   self::expect(core::_GrowableList::generate<dynamic>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(){() →* core::Set<dynamic>*}, set6);
   core::Set<core::int*>* set7 = block {
-    final core::Set<core::int*>* #t75 = new col::_CompactLinkedHashSet::•<core::int*>();
+    final core::Set<core::int*>* #t75 = new col::_InternalLinkedHashSet::•<core::int*>();
     final core::Iterable<dynamic>* #t76 = dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
     if(!(#t76 == null)) {
       core::Iterator<dynamic>* :sync-for-iterator = #t76.{core::Iterable::iterator}{core::Iterator<dynamic>*};
@@ -423,7 +423,7 @@
   } =>#t75;
   self::expect(core::_GrowableList::generate<core::int*>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(){() →* core::Set<core::int*>*}, set7);
   core::Set<dynamic>* set8 = block {
-    final core::Set<dynamic>* #t96 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic>* #t96 = new col::_InternalLinkedHashSet::•<dynamic>();
     final core::Iterable<dynamic>* #t97 = dynamicSet1 as{TypeError,ForDynamic} core::Iterable<dynamic>*;
     if(!(#t97 == null))
       #t96.{core::Set::addAll}{Invariant}(#t97){(core::Iterable<dynamic>*) →* void};
@@ -452,13 +452,13 @@
   self::expect(core::_GrowableList::generate<dynamic>(24, (core::int* i) → core::int* => i).{core::Iterable::toSet}(){() →* core::Set<dynamic>*}, set8);
   {
     core::Set<core::int*>* intSet1 = block {
-      final core::Set<core::int*>* #t105 = new col::_CompactLinkedHashSet::•<core::int*>();
+      final core::Set<core::int*>* #t105 = new col::_InternalLinkedHashSet::•<core::int*>();
       #t105.{core::Set::add}{Invariant}(0){(core::int*) →* core::bool*};
       #t105.{core::Set::add}{Invariant}(1){(core::int*) →* core::bool*};
       #t105.{core::Set::add}{Invariant}(2){(core::int*) →* core::bool*};
     } =>#t105;
     core::Set<core::int*>* intSet2 = block {
-      final core::Set<core::int*>* #t106 = new col::_CompactLinkedHashSet::•<core::int*>();
+      final core::Set<core::int*>* #t106 = new col::_InternalLinkedHashSet::•<core::int*>();
       #t106.{core::Set::add}{Invariant}(3){(core::int*) →* core::bool*};
       #t106.{core::Set::add}{Invariant}(4){(core::int*) →* core::bool*};
       #t106.{core::Set::add}{Invariant}(5){(core::int*) →* core::bool*};
diff --git a/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.weak.transformed.expect b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.weak.transformed.expect
index 553756f..a4ab110 100644
--- a/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/unified_collections/set_add_all_nnbd.dart.weak.transformed.expect
@@ -6,37 +6,37 @@
 
 static method useAddAll() → void {
   dynamic dynamicSet1 = block {
-    final core::Set<core::int> #t1 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t1 = new col::_InternalLinkedHashSet::•<core::int>();
     #t1.{core::Set::add}{Invariant}(0){(core::int) → core::bool};
     #t1.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t1.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
   } =>#t1;
   dynamic dynamicSet2 = block {
-    final core::Set<core::num> #t2 = new col::_CompactLinkedHashSet::•<core::num>();
+    final core::Set<core::num> #t2 = new col::_InternalLinkedHashSet::•<core::num>();
     #t2.{core::Set::add}{Invariant}(3){(core::num) → core::bool};
     #t2.{core::Set::add}{Invariant}(4){(core::num) → core::bool};
     #t2.{core::Set::add}{Invariant}(5){(core::num) → core::bool};
   } =>#t2;
   dynamic dynamicSet3 = block {
-    final core::Set<core::int?> #t3 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t3 = new col::_InternalLinkedHashSet::•<core::int?>();
     #t3.{core::Set::add}{Invariant}(6){(core::int?) → core::bool};
     #t3.{core::Set::add}{Invariant}(7){(core::int?) → core::bool};
     #t3.{core::Set::add}{Invariant}(8){(core::int?) → core::bool};
   } =>#t3;
   core::Iterable<core::int> iterableIntSet = block {
-    final core::Set<core::int> #t4 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t4 = new col::_InternalLinkedHashSet::•<core::int>();
     #t4.{core::Set::add}{Invariant}(9){(core::int) → core::bool};
     #t4.{core::Set::add}{Invariant}(10){(core::int) → core::bool};
     #t4.{core::Set::add}{Invariant}(11){(core::int) → core::bool};
   } =>#t4;
   core::Set<core::int> intSet = block {
-    final core::Set<core::int> #t5 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t5 = new col::_InternalLinkedHashSet::•<core::int>();
     #t5.{core::Set::add}{Invariant}(12){(core::int) → core::bool};
     #t5.{core::Set::add}{Invariant}(13){(core::int) → core::bool};
     #t5.{core::Set::add}{Invariant}(14){(core::int) → core::bool};
   } =>#t5;
   core::Set<core::int> set1 = block {
-    final core::Set<core::int> #t6 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t6 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = (dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -72,7 +72,7 @@
   } =>#t6;
   self::expect(core::_GrowableList::generate<core::int>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(){() → core::Set<core::int>}, set1);
   core::Set<core::num> set2 = block {
-    final core::Set<core::num> #t13 = new col::_CompactLinkedHashSet::•<core::num>();
+    final core::Set<core::num> #t13 = new col::_InternalLinkedHashSet::•<core::num>();
     {
       core::Iterator<dynamic> :sync-for-iterator = (dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -108,7 +108,7 @@
   } =>#t13;
   self::expect(core::_GrowableList::generate<core::num>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(){() → core::Set<core::num>}, set2);
   core::Set<core::int> set3 = block {
-    final core::Set<core::int> #t20 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t20 = new col::_InternalLinkedHashSet::•<core::int>();
     {
       core::Iterator<dynamic> :sync-for-iterator = (dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator}{core::Iterator<dynamic>};
       for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
@@ -153,13 +153,13 @@
   self::expect(core::_GrowableList::generate<dynamic>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(){() → core::Set<dynamic>}, set4);
   {
     core::Set<core::int> intSet1 = block {
-      final core::Set<core::int> #t28 = new col::_CompactLinkedHashSet::•<core::int>();
+      final core::Set<core::int> #t28 = new col::_InternalLinkedHashSet::•<core::int>();
       #t28.{core::Set::add}{Invariant}(0){(core::int) → core::bool};
       #t28.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
       #t28.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
     } =>#t28;
     core::Set<core::int> intSet2 = block {
-      final core::Set<core::int> #t29 = new col::_CompactLinkedHashSet::•<core::int>();
+      final core::Set<core::int> #t29 = new col::_InternalLinkedHashSet::•<core::int>();
       #t29.{core::Set::add}{Invariant}(3){(core::int) → core::bool};
       #t29.{core::Set::add}{Invariant}(4){(core::int) → core::bool};
       #t29.{core::Set::add}{Invariant}(5){(core::int) → core::bool};
@@ -173,37 +173,37 @@
 }
 static method useAddAllNullable() → void {
   dynamic dynamicSet1 = block {
-    final core::Set<core::int> #t31 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t31 = new col::_InternalLinkedHashSet::•<core::int>();
     #t31.{core::Set::add}{Invariant}(0){(core::int) → core::bool};
     #t31.{core::Set::add}{Invariant}(1){(core::int) → core::bool};
     #t31.{core::Set::add}{Invariant}(2){(core::int) → core::bool};
   } =>#t31;
   dynamic dynamicSet2 = block {
-    final core::Set<core::num> #t32 = new col::_CompactLinkedHashSet::•<core::num>();
+    final core::Set<core::num> #t32 = new col::_InternalLinkedHashSet::•<core::num>();
     #t32.{core::Set::add}{Invariant}(3){(core::num) → core::bool};
     #t32.{core::Set::add}{Invariant}(4){(core::num) → core::bool};
     #t32.{core::Set::add}{Invariant}(5){(core::num) → core::bool};
   } =>#t32;
   dynamic dynamicSet3 = block {
-    final core::Set<core::int?> #t33 = new col::_CompactLinkedHashSet::•<core::int?>();
+    final core::Set<core::int?> #t33 = new col::_InternalLinkedHashSet::•<core::int?>();
     #t33.{core::Set::add}{Invariant}(6){(core::int?) → core::bool};
     #t33.{core::Set::add}{Invariant}(7){(core::int?) → core::bool};
     #t33.{core::Set::add}{Invariant}(8){(core::int?) → core::bool};
   } =>#t33;
   core::Iterable<core::int>? iterableIntSet = true ?{core::Set<core::int>?} block {
-    final core::Set<core::int> #t34 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t34 = new col::_InternalLinkedHashSet::•<core::int>();
     #t34.{core::Set::add}{Invariant}(9){(core::int) → core::bool};
     #t34.{core::Set::add}{Invariant}(10){(core::int) → core::bool};
     #t34.{core::Set::add}{Invariant}(11){(core::int) → core::bool};
   } =>#t34 : null;
   core::Set<core::int>? intSet = true ?{core::Set<core::int>?} block {
-    final core::Set<core::int> #t35 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t35 = new col::_InternalLinkedHashSet::•<core::int>();
     #t35.{core::Set::add}{Invariant}(12){(core::int) → core::bool};
     #t35.{core::Set::add}{Invariant}(13){(core::int) → core::bool};
     #t35.{core::Set::add}{Invariant}(14){(core::int) → core::bool};
   } =>#t35 : null;
   core::Set<core::int> set1 = block {
-    final core::Set<core::int> #t36 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t36 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<dynamic>? #t37 = dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
     if(!(#t37 == null)) {
       core::Iterator<dynamic> :sync-for-iterator = #t37{core::Iterable<dynamic>}.{core::Iterable::iterator}{core::Iterator<dynamic>};
@@ -246,7 +246,7 @@
   } =>#t36;
   self::expect(core::_GrowableList::generate<core::int>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(){() → core::Set<core::int>}, set1);
   core::Set<core::num> set2 = block {
-    final core::Set<core::num> #t48 = new col::_CompactLinkedHashSet::•<core::num>();
+    final core::Set<core::num> #t48 = new col::_InternalLinkedHashSet::•<core::num>();
     final core::Iterable<dynamic>? #t49 = dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
     if(!(#t49 == null)) {
       core::Iterator<dynamic> :sync-for-iterator = #t49{core::Iterable<dynamic>}.{core::Iterable::iterator}{core::Iterator<dynamic>};
@@ -289,7 +289,7 @@
   } =>#t48;
   self::expect(core::_GrowableList::generate<core::num>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(){() → core::Set<core::num>}, set2);
   core::Set<core::int> set3 = block {
-    final core::Set<core::int> #t60 = new col::_CompactLinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t60 = new col::_InternalLinkedHashSet::•<core::int>();
     final core::Iterable<dynamic>? #t61 = dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
     if(!(#t61 == null)) {
       core::Iterator<dynamic> :sync-for-iterator = #t61{core::Iterable<dynamic>}.{core::Iterable::iterator}{core::Iterator<dynamic>};
@@ -332,7 +332,7 @@
   } =>#t60;
   self::expect(core::_GrowableList::generate<core::int>(15, (core::int i) → core::int => i).{core::Iterable::toSet}(){() → core::Set<core::int>}, set3);
   core::Set<dynamic> set4 = block {
-    final core::Set<dynamic> #t72 = new col::_CompactLinkedHashSet::•<dynamic>();
+    final core::Set<dynamic> #t72 = new col::_InternalLinkedHashSet::•<dynamic>();
     final core::Iterable<dynamic>? #t73 = dynamicSet1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>?;
     if(!(#t73 == null))
       #t72.{core::Set::addAll}{Invariant}(#t73{core::Iterable<dynamic>}){(core::Iterable<dynamic>) → void};
diff --git a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.outline.expect b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.outline.expect
index ce7effd..1467965 100644
--- a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.outline.expect
@@ -88,17 +88,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> SymbolConstant(#x)
-Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:23:5 -> SymbolConstant(#method)
-Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:23:5 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:23:5 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:24:12 -> SymbolConstant(#y=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:24:12 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:24:12 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> SymbolConstant(#x=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> SymbolConstant(#x)
+Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> SymbolConstant(#method)
+Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> SymbolConstant(#y=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> SymbolConstant(#x=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:50:7 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 42, effectively constant: 13
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 910bd78..592f18e 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -4,6 +4,8 @@
 
 # Status file for the weak_suite.dart test suite.
 
+macros/scope_access: SemiFuzzCrash
+
 const_functions/const_functions_list: SemiFuzzCrash
 generic_metadata/typedef_generic_types_in_arguments_and_bounds: SemiFuzzCrash
 nnbd_mixed/mixed_mixin: SemiFuzzFailure
@@ -14,7 +16,10 @@
 dart2js/late_fields_with_annotation: SemiFuzzFailure # https://github.com/dart-lang/sdk/issues/49415
 macros/augment_concrete: SemiFuzzFailure # https://github.com/dart-lang/sdk/issues/49414
 macros/extend_augmented: SemiFuzzFailure # Similar to https://github.com/dart-lang/sdk/issues/49414
+macros/multiple_augment_class: SemiFuzzFailure # https://github.com/dart-lang/sdk/issues/49990
 
+general/issue48765: semiFuzzFailureOnForceRebuildBodies # private class
+general/mixin_from_patch/main: semiFuzzFailureOnForceRebuildBodies # needs custom libraries.json (and platform?) not setup here
 dart2js/tear_off_patch/main: semiFuzzFailureOnForceRebuildBodies # needs custom libraries.json (and platform?) not setup here
 general/constants/with_unevaluated_agnostic/various_2: SemiFuzzFailure # Looks similar to https://dart-review.googlesource.com/c/sdk/+/242441
 general/no_such_method_forwarder: SemiFuzzFailure # https://dart-review.googlesource.com/c/sdk/+/242444
@@ -159,6 +164,7 @@
 general/mixin_application_override: TypeCheckError
 general/mixin_constructors_with_default_values: RuntimeError # Expected
 general/mixin_covariant2: RuntimeError
+general/multiple_class_patches/main: RuntimeError
 general/operator_method_not_found: RuntimeError # Expected
 general/optional: RuntimeError
 general/override_check_accessor_after_inference: TypeCheckError # Issue #31620
diff --git a/pkg/front_end/tool/duplicate_code_finder_experiment.dart b/pkg/front_end/tool/duplicate_code_finder_experiment.dart
new file mode 100644
index 0000000..6780206
--- /dev/null
+++ b/pkg/front_end/tool/duplicate_code_finder_experiment.dart
@@ -0,0 +1,363 @@
+// Copyright (c) 2022, 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:io';
+
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
+    show ErrorToken, ScannerConfiguration, StringScanner;
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart'
+    show BeginToken, SimpleToken, Token, TokenType;
+
+class Duplicate {
+  final List<FromToUri> where;
+  final String example;
+
+  Duplicate(this.where, this.example);
+
+  @override
+  String toString() => "Duplicate[$example]";
+}
+
+class FromToUri {
+  final Uri uri;
+  final int startOffset;
+  final int endOffset;
+
+  FromToUri(this.uri, this.startOffset, this.endOffset);
+}
+
+class Line {
+  String content;
+  Uri uri;
+  int startOffset;
+  int endOffset;
+  Line? previous;
+  Line? next;
+
+  Line(
+      this.content, this.uri, this.startOffset, this.endOffset, this.previous) {
+    if (previous != null) {
+      previous!.next = this;
+    }
+  }
+}
+
+class ExtendedLines {
+  List<Line> startLines;
+  int lineCount;
+
+  ExtendedLines(this.startLines, this.lineCount);
+}
+
+class MultiMap<K, V> {
+  Map<K, List<V>> data = {};
+
+  void operator []=(K key, V value) {
+    List<V>? lookup = data[key];
+    if (lookup != null) {
+      lookup.add(value);
+    } else {
+      data[key] = [value];
+    }
+  }
+}
+
+void _indexLines(MultiMap<String, Line> mapped, Set<String> denyListed,
+    String data, Uri uri) {
+  // TODO(jensj): Work directly on scanned tokens, or use parser as well?
+  // * Should probably only operate on body content, and then not cross bracket
+  //   boundaries in that it should suggest that "foo; } } bar;" is a duplicate
+  //   -- while it might be duplicate, we can't replace that with a function
+  //   call (to get rid of duplicate code).
+  // * If something is a string we could perhaps ignore the content so that
+/*
+    assert(declaration.parent == _libraryTypeParameterScopeBuilder);
+    Map<String, Builder> members = declaration.members!;
+    Map<String, MemberBuilder> constructors = declaration.constructors!;
+    Map<String, MemberBuilder> setters = declaration.setters!;
+
+    Scope classScope = new Scope(
+        local: members,
+        setters: setters,
+        parent: scope.withTypeVariables(typeVariables),
+        debugName: "class $className",
+        isModifiable: false);
+*/
+  //   and
+/*
+    assert(declaration.parent == _libraryTypeParameterScopeBuilder);
+    Map<String, Builder> members = declaration.members!;
+    Map<String, MemberBuilder> constructors = declaration.constructors!;
+    Map<String, MemberBuilder> setters = declaration.setters!;
+
+    Scope classScope = new Scope(
+        local: members,
+        setters: setters,
+        parent: scope.withTypeVariables(typeVariables),
+        debugName: "extension $extensionName",
+        isModifiable: false);
+*/
+  //   could match.
+  Token scannedToken = _scan(data);
+  if (scannedToken is ErrorToken) throw "Can't operate on erroneous data";
+  Token token = scannedToken;
+  StringBuffer sb = new StringBuffer();
+  String space = "";
+  int? startOffset;
+
+  List<Token> endGroups = [];
+  Line? previousLine;
+
+  void endLine(Token lastToken) {
+    String s = sb.toString();
+    int lineStart = startOffset!;
+    sb.clear();
+    space = "";
+    startOffset = null;
+
+    Line line = new Line(s, uri, lineStart, lastToken.charEnd, previousLine);
+    previousLine = line;
+    if (!denyListed.contains(s)) mapped[s] = line;
+  }
+
+  while (true) {
+    sb.write(space);
+    sb.write(token.lexeme);
+    space = " ";
+    startOffset ??= token.charOffset;
+
+    if (endGroups.isNotEmpty && endGroups.last == token) {
+      endLine(token);
+      endGroups.removeLast();
+    } else if (token is BeginToken &&
+        token.type == TokenType.OPEN_CURLY_BRACKET &&
+        token.endGroup != null) {
+      // End line on a "{".
+      endLine(token);
+      endGroups.add(token.endGroup!);
+    } else if (token is SimpleToken && token.type == TokenType.SEMICOLON) {
+      // End line on a ";".
+      endLine(token);
+    } else if (token.next!.isEof) {
+      endLine(token);
+      break;
+    }
+
+    token = token.next!;
+  }
+}
+
+void _extendIndexedLines(List<Line> lines, Set<Line> alreadyIncluded,
+    List<Duplicate> foundDuplicates, Set<String> denyListed) {
+  int length = lines.length;
+
+  if (length == 1) {
+    // The indexed line was only seen once. That's not a duplicate!
+    return;
+  }
+
+  // We move forward in the data, and if having found a -> b -> c
+  // after having processed 'a' we shouldn't process from 'b' too. We thus
+  // remove already included lines here.
+  for (Line line in lines) {
+    if (alreadyIncluded.contains(line)) {
+      length--;
+    }
+  }
+  if (length <= 1) {
+    // We've seen this line before, but all duplicates was included in another
+    // actual duplicate find. Don't process and report again!
+    return;
+  }
+
+  // Can this potential duplicate be extended?
+  List<ExtendedLines>? extended = _extend(lines,
+      existingMatchCount: 1, leastMatches: 3, denyListed: denyListed);
+  if (extended == null || extended.isEmpty) return;
+  for (ExtendedLines extendedLine in extended) {
+    for (Line line in extendedLine.startLines) {
+      int left = extendedLine.lineCount - 1;
+      Line l = line;
+      while (left > 0) {
+        alreadyIncluded.add(l);
+        left--;
+        l = l.next!;
+      }
+    }
+    List<FromToUri> where = [];
+    StringBuffer sb = new StringBuffer();
+    String? example;
+    for (Line firstLine in extendedLine.startLines) {
+      int left = extendedLine.lineCount - 1;
+      Line lastLine = firstLine;
+      if (example == null) sb.writeln(lastLine.content);
+      while (left > 0) {
+        left--;
+        lastLine = lastLine.next!;
+        if (example == null) sb.writeln(lastLine.content);
+      }
+      where.add(new FromToUri(
+          firstLine.uri, firstLine.startOffset, lastLine.endOffset));
+      example ??= sb.toString();
+    }
+    foundDuplicates.add(new Duplicate(where, example!));
+  }
+}
+
+List<Duplicate> findDuplicates(Map<Uri, String> data, {bool verbose = false}) {
+  MultiMap<String, Line> indexedLines = new MultiMap();
+  const Set<String> denyListed = const {"}", "return ;", ";", ") ;", "else {"};
+
+  for (MapEntry<Uri, String> entry in data.entries) {
+    _indexLines(indexedLines, denyListed, entry.value, entry.key);
+  }
+
+  // TODO(jensj): The already included approach is too simple. E.g.
+  /*
+match1;
+nomatch;
+
+match0;
+match1;
+match2;
+match3;
+
+vs
+
+match1;
+nomatchX;
+
+match0;
+match1;
+match2;
+match3;
+
+would first find match1 match2 match3 --- then match0 match1 match2 match3.
+*/
+
+  Set<Line> alreadyIncluded = {};
+  List<Duplicate> result = [];
+  for (MapEntry<String, List<Line>> entry in indexedLines.data.entries) {
+    _extendIndexedLines(entry.value, alreadyIncluded, result, denyListed);
+  }
+
+  if (verbose) {
+    if (result.length == 0) {
+      print("Didn't find any duplicates.");
+    } else if (result.length == 1) {
+      print("Found 1 duplicate:");
+    } else {
+      print("Found ${result.length} duplicates:");
+    }
+    for (Duplicate duplicate in result) {
+      print("Found '${duplicate.example}' at:");
+      for (FromToUri where in duplicate.where) {
+        print("${where.uri}: ${where.startOffset} -> ${where.endOffset}");
+      }
+      print("----\n\n");
+    }
+  }
+
+  return result;
+}
+
+/// Given a list of lines that match, find duplicates that match on more lines,
+/// thereby extending and possibly splitting the match.
+List<ExtendedLines>? _extend(List<Line> lines,
+    {required int existingMatchCount,
+    required int leastMatches,
+    required Set<String> denyListed}) {
+  MultiMap<String, Line> mapped = new MultiMap();
+
+  // E.g. for this input
+  // a -> b1 -> c1 -> d1
+  // a -> b1 -> c1 -> d2
+  // a -> b2 -> c2 -> d1
+  // a -> b2 -> c2 -> d2
+  // a -> b3 -> c2 -> d1
+  // we'd like it to be split into
+  // [a, b1, c1] and [a, b2, c2]
+
+  for (Line line in lines) {
+    Line? next = line.next;
+    if (next != null) {
+      mapped[next.content] = next;
+    }
+  }
+
+  List<ExtendedLines>? result;
+
+  for (MapEntry<String, List<Line>> entry in mapped.data.entries) {
+    if (entry.value.length == 1) {
+      continue;
+    }
+
+    int newMatchCount = existingMatchCount + 1;
+    // Don't count e.g. '}' as an actual match -> require one additional match.
+    // Notice that we can't just not count it as that would destroy the count
+    // which we use to go back and forth between first and last matched line.
+    if (denyListed.contains(entry.key)) {
+      leastMatches++;
+    }
+
+    List<ExtendedLines>? extended = _extend(entry.value,
+        existingMatchCount: newMatchCount,
+        leastMatches: leastMatches,
+        denyListed: denyListed);
+    if (extended != null) {
+      // Was extended further.
+      (result ??= []).addAll(extended);
+    } else if (newMatchCount >= leastMatches) {
+      // Couldn't be extended further, but this was far enough.
+      (result ??= []).add(new ExtendedLines(
+          entry.value.map((Line endLine) {
+            Line line = endLine;
+            int back = existingMatchCount;
+            while (back > 0) {
+              line = line.previous!;
+              back--;
+            }
+            return line;
+          }).toList(),
+          newMatchCount));
+    }
+  }
+
+  return result;
+}
+
+Token _scan(String data) {
+  ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
+      enableTripleShift: true,
+      enableExtensionMethods: true,
+      enableNonNullable: true,
+      forAugmentationLibrary: false);
+
+  StringScanner scanner =
+      new StringScanner(data, configuration: scannerConfiguration);
+  Token firstToken = scanner.tokenize();
+  return firstToken;
+}
+
+void main(List<String> args) {
+  if (args.isEmpty) {
+    args = [
+      Platform.script
+          .resolve("../lib/src/fasta/source/source_library_builder.dart")
+          .toFilePath()
+    ];
+  }
+  bool printed = false;
+  for (String s in args) {
+    File f = new File(s);
+    if (!f.existsSync()) continue;
+    String data = f.readAsStringSync();
+
+    if (printed) print("\n\n=============\n\n");
+    print("Output on $s:");
+    findDuplicates({Uri.parse(s): data}, verbose: true);
+    printed = true;
+  }
+}
diff --git a/pkg/front_end/tool/duplicate_code_finder_test.dart b/pkg/front_end/tool/duplicate_code_finder_test.dart
new file mode 100644
index 0000000..a797a7f
--- /dev/null
+++ b/pkg/front_end/tool/duplicate_code_finder_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2022, 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 'duplicate_code_finder_experiment.dart';
+
+void main() {
+  exactlySameLine();
+  sameLineDifferentIndentation();
+}
+
+Uri testUri = Uri.parse("test://uri.dart");
+
+void exactlySameLine() {
+  // Can find exactly the same lines.
+  List<Duplicate> result = findDuplicates({
+    testUri: """
+if (whatever()) {
+  Foo f = new Foo();
+  f.partA();
+  f.partB();
+  f.partC();
+} else {
+  print("Else case");
+  Foo f = new Foo();
+  f.partA();
+  f.partB();
+  f.partC();
+}
+""",
+  });
+  if (result.length != 1) throw "Didn't find exactly 1 result; got $result";
+  String s = result.single.toString();
+  if (!s.contains("Foo f = new Foo ( ) ;") ||
+      !s.contains("f . partA ( ) ;") ||
+      !s.contains("f . partB ( ) ;") ||
+      !s.contains("f . partC ( ) ;")) {
+    throw "Didn't contain expected, was $s";
+  }
+}
+
+void sameLineDifferentIndentation() {
+  // Can find exactly the same lines.
+  List<Duplicate> result = findDuplicates({
+    testUri: """
+if (whatever()) {
+  Foo f = new Foo();
+  f.partA();
+  f.partB();
+  f.partC();
+} else {
+  if (something()) {
+    print("Else case with something");
+  } else {
+    Foo f = new Foo();
+    f.partA();
+    f.partB();
+    f.partC();
+  }
+}
+""",
+  });
+  if (result.length != 1) throw "Didn't find exactly 1 result; got $result";
+  String s = result.single.toString();
+  if (!s.contains("Foo f = new Foo ( ) ;") ||
+      !s.contains("f . partA ( ) ;") ||
+      !s.contains("f . partB ( ) ;") ||
+      !s.contains("f . partC ( ) ;")) {
+    throw "Didn't contain expected, was $s";
+  }
+}
diff --git a/pkg/frontend_server/bin/frontend_server_starter.dart b/pkg/frontend_server/bin/frontend_server_starter.dart
index 487f980..95328ae 100644
--- a/pkg/frontend_server/bin/frontend_server_starter.dart
+++ b/pkg/frontend_server/bin/frontend_server_starter.dart
@@ -1,4 +1,7 @@
-// @dart = 2.9
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 library frontend_server;
 
 import 'dart:async';
diff --git a/pkg/frontend_server/lib/compute_kernel.dart b/pkg/frontend_server/lib/compute_kernel.dart
index 611ff26..d50f134 100644
--- a/pkg/frontend_server/lib/compute_kernel.dart
+++ b/pkg/frontend_server/lib/compute_kernel.dart
@@ -237,12 +237,21 @@
   List<Uri> summaryInputs =
       (parsedArgs['input-summary'] as List<String>).map(toUri).toList();
 
+  fe.InitializedCompilerState state;
+  bool usingIncrementalCompiler = false;
+  bool recordUsedInputs = parsedArgs["used-inputs"] != null;
+  var environmentDefines = _parseEnvironmentDefines(parsedArgs['define']);
+  var verbose = parsedArgs['verbose'] as bool;
+  var verbosity = fe.Verbosity.parseArgument(parsedArgs['verbosity']);
+  Uri? sdkSummaryUri = toUriNullable(parsedArgs['dart-sdk-summary']);
+
   Map<Uri, Uri> redirectsToFrom = {};
   for (String redirect in parsedArgs['redirect']) {
     List<String> split = redirect.split("|");
     if (split.length != 2) throw "Invalid redirect input: '$redirect'";
     redirectsToFrom[toUri(split[1])] = toUri(split[0]);
   }
+
   if (redirectsToFrom.isNotEmpty) {
     // If redirecting from a->b and we were asked to compile b, we want
     // the output to look like we compiled a.
@@ -260,15 +269,15 @@
     // actually return data from b. If asked to read b throw.
     fe.InitializedCompilerState helper = fe.initializeCompiler(
         null,
-        toUri(parsedArgs['dart-sdk-summary']),
-        toUri(parsedArgs['libraries-file']),
-        toUri(parsedArgs['packages-file']),
+        sdkSummaryUri,
+        toUriNullable(parsedArgs['libraries-file']),
+        toUriNullable(parsedArgs['packages-file']),
         [...summaryInputs, ...linkedInputs],
         target,
         fileSystem,
         parsedArgs['enable-experiment'] as List<String>,
-        {},
-        verbose: false,
+        environmentDefines,
+        verbose: verbose,
         nnbdMode: nnbdMode);
     var uriTranslator = await helper.processedOpts.getUriTranslator();
     _FakeFileSystem ffs = fileSystem = new _FakeFileSystem(fileSystem);
@@ -279,14 +288,6 @@
     }
   }
 
-  fe.InitializedCompilerState state;
-  bool usingIncrementalCompiler = false;
-  bool recordUsedInputs = parsedArgs["used-inputs"] != null;
-  var environmentDefines = _parseEnvironmentDefines(parsedArgs['define']);
-  var verbose = parsedArgs['verbose'] as bool;
-  var verbosity = fe.Verbosity.parseArgument(parsedArgs['verbosity']);
-  Uri? sdkSummaryUri = toUriNullable(parsedArgs['dart-sdk-summary']);
-
   if (parsedArgs['use-incremental-compiler']) {
     usingIncrementalCompiler = true;
 
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 82b61c64..47c365f 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// @dart = 2.9
 library frontend_server;
 
 import 'dart:async';
@@ -24,6 +23,8 @@
 // an effort to discourage further use.
 // ignore_for_file: implementation_imports
 import 'package:front_end/src/api_unstable/vm.dart';
+import 'package:front_end/src/api_unstable/ddc.dart' as ddc
+    show IncrementalCompiler;
 import 'package:front_end/widget_cache.dart';
 import 'package:kernel/ast.dart' show Library, Procedure, LibraryDependency;
 import 'package:kernel/binary/ast_to_binary.dart';
@@ -187,7 +188,7 @@
   ..addOption('libraries-spec',
       help: 'A path or uri to the libraries specification JSON file')
   ..addFlag('debugger-module-names',
-      help: 'Use debugger-friendly modules names', defaultsTo: true)
+      help: 'Use debugger-friendly modules names', defaultsTo: false)
   ..addFlag('experimental-emit-debug-metadata',
       help: 'Emit module and library metadata for the debugger',
       defaultsTo: false)
@@ -270,12 +271,12 @@
   Future<bool> compile(
     String entryPoint,
     ArgResults options, {
-    IncrementalCompiler generator,
+    IncrementalCompiler? generator,
   });
 
   /// Assuming some Dart program was previously compiled, recompile it again
   /// taking into account some changed(invalidated) sources.
-  Future<Null> recompileDelta({String entryPoint});
+  Future<Null> recompileDelta({String? entryPoint});
 
   /// Accept results of previous compilation so that next recompilation cycle
   /// won't recompile sources that were previously reported as changed.
@@ -285,7 +286,7 @@
   /// accepted state.
   Future<void> rejectLastDelta();
 
-  /// This let's compiler know that source file identifed by `uri` was changed.
+  /// This let's compiler know that source file identified by `uri` was changed.
   void invalidate(Uri uri);
 
   /// Resets incremental compiler accept/reject status so that next time
@@ -309,8 +310,8 @@
       List<String> typeBounds,
       List<String> typeDefaults,
       String libraryUri,
-      String klass,
-      String method,
+      String? klass,
+      String? method,
       bool isStatic);
 
   /// Compiles [expression] in [libraryUri] at [line]:[column] to JavaScript
@@ -357,50 +358,51 @@
 }
 
 class FrontendCompiler implements CompilerInterface {
-  FrontendCompiler(this._outputStream,
-      {this.printerFactory,
+  FrontendCompiler(StringSink? outputStream,
+      {BinaryPrinterFactory? printerFactory,
       this.transformer,
       this.unsafePackageSerialization,
       this.incrementalSerialization = true,
       this.useDebuggerModuleNames = false,
       this.emitDebugMetadata = false,
-      this.emitDebugSymbols = false}) {
-    _outputStream ??= stdout;
-    printerFactory ??= new BinaryPrinterFactory();
-  }
+      this.emitDebugSymbols = false})
+      : _outputStream = outputStream ?? stdout,
+        printerFactory = printerFactory ?? new BinaryPrinterFactory();
 
-  StringSink _outputStream;
-  BinaryPrinterFactory printerFactory;
-  bool unsafePackageSerialization;
-  bool incrementalSerialization;
-  bool useDebuggerModuleNames;
-  bool emitDebugMetadata;
-  bool emitDebugSymbols;
-  bool _printIncrementalDependencies;
-
-  CompilerOptions _compilerOptions;
-  ProcessedOptions _processedOptions;
-  FileSystem _fileSystem;
-  Uri _mainSource;
-  List<Uri> _additionalSources;
-  ArgResults _options;
-
-  IncrementalCompiler _generator;
-  IncrementalJavaScriptBundler _bundler;
-
-  WidgetCache _widgetCache;
-
-  String _kernelBinaryFilename;
-  String _kernelBinaryFilenameIncremental;
-  String _kernelBinaryFilenameFull;
-  String _initializeFromDill;
-  bool _assumeInitializeFromDillUpToDate;
-
+  /// Fields with initializers
+  final List<String> errors = <String>[];
   Set<Uri> previouslyReportedDependencies = Set<Uri>();
 
-  final ProgramTransformer transformer;
+  /// Initialized in the constructor
+  bool emitDebugMetadata;
+  bool emitDebugSymbols;
+  bool incrementalSerialization;
+  StringSink _outputStream;
+  BinaryPrinterFactory printerFactory;
+  bool useDebuggerModuleNames;
 
-  final List<String> errors = <String>[];
+  /// Initialized in [compile].
+  late List<Uri> _additionalSources;
+  late bool _assumeInitializeFromDillUpToDate;
+  late CompilerOptions _compilerOptions;
+  late FileSystem _fileSystem;
+  late IncrementalCompiler _generator;
+  late String _initializeFromDill;
+  late String _kernelBinaryFilename;
+  late String _kernelBinaryFilenameIncremental;
+  late String _kernelBinaryFilenameFull;
+  late Uri _mainSource;
+  late ArgResults _options;
+  late bool _printIncrementalDependencies;
+  late ProcessedOptions _processedOptions;
+
+  /// Initialized in [writeJavascriptBundle]
+  IncrementalJavaScriptBundler? _bundler;
+
+  /// Nullable fields
+  final ProgramTransformer? transformer;
+  bool? unsafePackageSerialization;
+  WidgetCache? _widgetCache;
 
   _onDiagnostic(DiagnosticMessage message) {
     switch (message.severity) {
@@ -428,7 +430,7 @@
   Future<bool> compile(
     String entryPoint,
     ArgResults options, {
-    IncrementalCompiler generator,
+    IncrementalCompiler? generator,
   }) async {
     _options = options;
     _fileSystem = createFrontEndFileSystem(
@@ -453,8 +455,8 @@
     final Uri sdkRoot = _ensureFolderPath(options['sdk-root']);
     final String platformKernelDill =
         options['platform'] ?? 'platform_strong.dill';
-    final String packagesOption = _options['packages'];
-    final bool nullSafety = _options['sound-null-safety'];
+    final String? packagesOption = _options['packages'];
+    final bool? nullSafety = _options['sound-null-safety'];
     final CompilerOptions compilerOptions = CompilerOptions()
       ..sdkRoot = sdkRoot
       ..fileSystem = _fileSystem
@@ -550,7 +552,7 @@
       return false;
     }
 
-    final String importDill = options['import-dill'];
+    final String? importDill = options['import-dill'];
     if (importDill != null) {
       compilerOptions.additionalDills = <Uri>[
         Uri.base.resolveUri(Uri.file(importDill))
@@ -559,11 +561,11 @@
 
     _processedOptions = ProcessedOptions(options: compilerOptions);
 
-    KernelCompilationResults results;
-    IncrementalSerializer incrementalSerializer;
+    KernelCompilationResults? results;
+    IncrementalSerializer? incrementalSerializer;
     if (options['incremental']) {
       _compilerOptions.environmentDefines =
-          _compilerOptions.target.updateEnvironmentDefines(environmentDefines);
+          _compilerOptions.target!.updateEnvironmentDefines(environmentDefines);
 
       _compilerOptions.omitPlatform = false;
       _generator = generator ?? _createGenerator(Uri.file(_initializeFromDill));
@@ -605,10 +607,10 @@
           treeShakeWriteOnlyFields: options['tree-shake-write-only-fields'],
           fromDillFile: options['from-dill']));
     }
-    if (results.component != null) {
-      transformer?.transform(results.component);
+    if (results!.component != null) {
+      transformer?.transform(results.component!);
 
-      if (_compilerOptions.target.name == 'dartdevc') {
+      if (_compilerOptions.target!.name == 'dartdevc') {
         await writeJavascriptBundle(results, _kernelBinaryFilename,
             options['filesystem-scheme'], options['dartdevc-module-format'],
             fullComponent: true);
@@ -618,12 +620,13 @@
           incrementalSerializer: incrementalSerializer);
 
       _outputStream.writeln(boundaryKey);
-      await _outputDependenciesDelta(results.compiledSources);
+      final compiledSources = results.compiledSources!;
+      await _outputDependenciesDelta(compiledSources);
       _outputStream
           .writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
-      final String depfile = options['depfile'];
+      final String? depfile = options['depfile'];
       if (depfile != null) {
-        await writeDepfile(compilerOptions.fileSystem, results.compiledSources,
+        await writeDepfile(compilerOptions.fileSystem, compiledSources,
             _kernelBinaryFilename, depfile);
       }
 
@@ -639,10 +642,10 @@
     if (!_printIncrementalDependencies) {
       return;
     }
-    Set<Uri> uris = Set<Uri>();
+    Set<Uri> uris = {};
     for (Uri uri in compiledSources) {
       // Skip empty or corelib dependencies.
-      if (uri == null || uri.isScheme('org-dartlang-sdk')) continue;
+      if (uri.isScheme('org-dartlang-sdk')) continue;
       uris.add(uri);
     }
     for (Uri uri in uris) {
@@ -668,18 +671,19 @@
     previouslyReportedDependencies = uris;
   }
 
-  /// Write a JavaScript bundle containg the provided component.
+  /// Write a JavaScript bundle containing the provided component.
   Future<void> writeJavascriptBundle(KernelCompilationResults results,
       String filename, String fileSystemScheme, String moduleFormat,
-      {bool fullComponent}) async {
+      {required bool fullComponent}) async {
+    // ignore: unnecessary_null_comparison
     assert(fullComponent != null);
     var packageConfig = await loadPackageConfigUri(
         _compilerOptions.packagesFileUri ??
             File('.dart_tool/package_config.json').absolute.uri);
     var soundNullSafety = _compilerOptions.nnbdMode == NnbdMode.Strong;
-    final Component component = results.component;
+    final Component component = results.component!;
 
-    _bundler ??= IncrementalJavaScriptBundler(
+    final bundler = _bundler ??= IncrementalJavaScriptBundler(
       _compilerOptions.fileSystem,
       results.loadedLibraries,
       fileSystemScheme,
@@ -689,10 +693,13 @@
       soundNullSafety: soundNullSafety,
     );
     if (fullComponent) {
-      await _bundler.initialize(component, _mainSource);
+      await bundler.initialize(component, _mainSource, packageConfig);
     } else {
-      await _bundler.invalidate(
-          component, _generator.lastKnownGoodResult?.component, _mainSource);
+      await bundler.invalidate(
+          component,
+          _generator.lastKnownGoodResult!.component,
+          _mainSource,
+          packageConfig);
     }
 
     // Create JavaScript bundler.
@@ -711,9 +718,9 @@
     final metadataFileSink =
         emitDebugMetadata ? metadataFile.openWrite() : null;
     final symbolsFileSink = emitDebugSymbols ? symbolsFile.openWrite() : null;
-    final kernel2JsCompilers = await _bundler.compile(
-        results.classHierarchy,
-        results.coreTypes,
+    final kernel2JsCompilers = await bundler.compile(
+        results.classHierarchy!,
+        results.coreTypes!,
         packageConfig,
         sourceFileSink,
         manifestFileSink,
@@ -732,8 +739,8 @@
 
   writeDillFile(KernelCompilationResults results, String filename,
       {bool filterExternal = false,
-      IncrementalSerializer incrementalSerializer}) async {
-    final Component component = results.component;
+      IncrementalSerializer? incrementalSerializer}) async {
+    final Component component = results.component!;
     final IOSink sink = File(filename).openWrite();
     final Set<Library> loadedLibraries = results.loadedLibraries;
     final BinaryPrinter printer = filterExternal
@@ -759,10 +766,10 @@
           _mainSource, _compilerOptions, results, filename);
     }
 
-    final String manifestFilename = _options['far-manifest'];
+    final String? manifestFilename = _options['far-manifest'];
     if (manifestFilename != null) {
       final String output = _options['output-dill'];
-      final String dataDir = _options.options.contains('component-name')
+      final String? dataDir = _options.options.contains('component-name')
           ? _options['component-name']
           : _options['data-dir'];
       await createFarManifest(output, dataDir, manifestFilename);
@@ -791,9 +798,9 @@
 
     nextUri:
     for (Uri uri in component.uriToSource.keys) {
-      if (uri == null || '$uri' == '') continue nextUri;
+      if ('$uri' == '') continue nextUri;
 
-      final List<int> oldBytes = component.uriToSource[uri].source;
+      final List<int> oldBytes = component.uriToSource[uri]!.source;
       FileSystemEntity entity;
       try {
         entity = _compilerOptions.fileSystem.entityForUri(uri);
@@ -828,7 +835,7 @@
   }
 
   @override
-  Future<Null> recompileDelta({String entryPoint}) async {
+  Future<Null> recompileDelta({String? entryPoint}) async {
     final String boundaryKey = Uuid().generateV4();
     _outputStream.writeln('result $boundaryKey');
     await invalidateIfInitializingFromDill();
@@ -840,9 +847,7 @@
     IncrementalCompilerResult deltaProgramResult = await _generator
         .compile(entryPoints: [_mainSource, ..._additionalSources]);
     Component deltaProgram = deltaProgramResult.component;
-    if (deltaProgram != null && transformer != null) {
-      transformer.transform(deltaProgram);
-    }
+    transformer?.transform(deltaProgram);
 
     KernelCompilationResults results = KernelCompilationResults(
         deltaProgram,
@@ -851,7 +856,7 @@
         deltaProgramResult.coreTypes,
         deltaProgram.uriToSource.keys);
 
-    if (_compilerOptions.target.name == 'dartdevc') {
+    if (_compilerOptions.target!.name == 'dartdevc') {
       await writeJavascriptBundle(results, _kernelBinaryFilename,
           _options['filesystem-scheme'], _options['dartdevc-module-format'],
           fullComponent: false);
@@ -862,7 +867,7 @@
     _updateWidgetCache(deltaProgram);
 
     _outputStream.writeln(boundaryKey);
-    await _outputDependenciesDelta(results.compiledSources);
+    await _outputDependenciesDelta(results.compiledSources!);
     _outputStream
         .writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
     _kernelBinaryFilename = _kernelBinaryFilenameIncremental;
@@ -877,12 +882,12 @@
       List<String> typeBounds,
       List<String> typeDefaults,
       String libraryUri,
-      String klass,
-      String method,
+      String? klass,
+      String? method,
       bool isStatic) async {
     final String boundaryKey = Uuid().generateV4();
     _outputStream.writeln('result $boundaryKey');
-    Procedure procedure = await _generator.compileExpression(
+    Procedure? procedure = await _generator.compileExpression(
         expression,
         definitions,
         definitionTypes,
@@ -908,7 +913,7 @@
 
   /// Program compilers per module.
   ///
-  /// Produced suring initial compilation of the module to JavaScript,
+  /// Produced during initial compilation of the module to JavaScript,
   /// cached to be used for expression compilation in [compileExpressionToJs].
   final Map<String, ProgramCompiler> cachedProgramCompilers = {};
 
@@ -939,8 +944,8 @@
     _processedOptions.ticker
         .logMs('Compiling expression to JavaScript in $moduleName');
 
-    final kernel2jsCompiler = cachedProgramCompilers[moduleName];
-    IncrementalCompilerResult compilerResult = _generator.lastKnownGoodResult;
+    final kernel2jsCompiler = cachedProgramCompilers[moduleName]!;
+    IncrementalCompilerResult compilerResult = _generator.lastKnownGoodResult!;
     Component component = compilerResult.component;
     component.computeCanonicalNames();
 
@@ -950,7 +955,7 @@
       _compilerOptions,
       parseModuleFormat(_options['dartdevc-module-format'] as String),
       errors,
-      _generator.generator,
+      _generator.generator as ddc.IncrementalCompiler,
       kernel2jsCompiler,
       component,
     );
@@ -958,7 +963,7 @@
     final procedure = await expressionCompiler.compileExpressionToJs(
         libraryUri, line, column, jsFrameValues, expression);
 
-    final result = errors.isNotEmpty ? errors[0] : procedure;
+    final result = errors.isNotEmpty ? errors[0] : procedure!;
 
     // TODO(annagrin): kernelBinaryFilename is too specific
     // rename to _outputFileName?
@@ -1000,8 +1005,6 @@
 
   writePackagesToSinkAndTrimComponent(
       Component deltaProgram, Sink<List<int>> ioSink) {
-    if (deltaProgram == null) return;
-
     List<Library> packageLibraries = <Library>[];
     List<Library> libraries = <Library>[];
     deltaProgram.computeCanonicalNames();
@@ -1025,25 +1028,24 @@
       if (alreadyAdded.add(data)) {
         ioSink.add(data);
         // Now also add all dependencies.
-        for (Uri dep in cachedPackageDependencies[uri]) {
-          addDataAndDependentData(cachedPackageLibraries[dep], dep);
+        for (Uri dep in cachedPackageDependencies[uri]!) {
+          addDataAndDependentData(cachedPackageLibraries[dep]!, dep);
         }
       }
     }
 
     for (Library lib in packageLibraries) {
-      List<int> data = cachedPackageLibraries[lib.fileUri];
+      List<int>? data = cachedPackageLibraries[lib.fileUri];
       if (data != null) {
         addDataAndDependentData(data, lib.fileUri);
       } else {
         String package = lib.importUri.pathSegments.first;
-        newPackages[package] ??= <Library>[];
-        newPackages[package].add(lib);
+        (newPackages[package] ??= <Library>[]).add(lib);
       }
     }
 
     for (String package in newPackages.keys) {
-      List<Library> libraries = newPackages[package];
+      List<Library> libraries = newPackages[package]!;
       Component singleLibrary = Component(
           libraries: libraries,
           uriToSource: deltaProgram.uriToSource,
@@ -1106,7 +1108,7 @@
     _kernelBinaryFilename = _kernelBinaryFilenameFull;
   }
 
-  IncrementalCompiler _createGenerator(Uri initializeFromDillUri) {
+  IncrementalCompiler _createGenerator(Uri? initializeFromDillUri) {
     return IncrementalCompiler(
         _compilerOptions, [_mainSource, ..._additionalSources],
         initializeFromDillUri: initializeFromDillUri,
@@ -1124,8 +1126,8 @@
     if (_widgetCache == null || _generator.fullComponent) {
       return;
     }
-    final String singleModifiedClassName =
-        _widgetCache.checkSingleWidgetTypeModified(
+    final String? singleModifiedClassName =
+        _widgetCache!.checkSingleWidgetTypeModified(
       _generator.lastKnownGoodResult?.component,
       partialComponent,
       _generator.lastKnownGoodResult?.classHierarchy,
@@ -1168,7 +1170,7 @@
 }
 
 class _CompileExpressionRequest {
-  String expression;
+  late String expression;
   // Note that FE will reject a compileExpression command by returning a null
   // procedure when defs or typeDefs include an illegal identifier.
   List<String> defs = <String>[];
@@ -1176,32 +1178,32 @@
   List<String> typeDefs = <String>[];
   List<String> typeBounds = <String>[];
   List<String> typeDefaults = <String>[];
-  String library;
-  String klass;
-  String method;
-  bool isStatic;
+  late String library;
+  String? klass;
+  String? method;
+  late bool isStatic;
 }
 
 class _CompileExpressionToJsRequest {
-  String libraryUri;
-  int line;
-  int column;
+  late String libraryUri;
+  late int line;
+  late int column;
   Map<String, String> jsModules = <String, String>{};
   Map<String, String> jsFrameValues = <String, String>{};
-  String moduleName;
-  String expression;
+  late String moduleName;
+  late String expression;
 }
 
 /// Listens for the compilation commands on [input] stream.
 /// This supports "interactive" recompilation mode of execution.
 StreamSubscription<String> listenAndCompile(CompilerInterface compiler,
     Stream<List<int>> input, ArgResults options, Completer<int> completer,
-    {IncrementalCompiler generator}) {
+    {IncrementalCompiler? generator}) {
   _State state = _State.READY_FOR_INSTRUCTION;
-  _CompileExpressionRequest compileExpressionRequest;
-  _CompileExpressionToJsRequest compileExpressionToJsRequest;
-  String boundaryKey;
-  String recompileEntryPoint;
+  late _CompileExpressionRequest compileExpressionRequest;
+  late _CompileExpressionToJsRequest compileExpressionToJsRequest;
+  late String boundaryKey;
+  String? recompileEntryPoint;
   return input
       .transform(utf8.decoder)
       .transform(const LineSplitter())
diff --git a/pkg/frontend_server/lib/src/javascript_bundle.dart b/pkg/frontend_server/lib/src/javascript_bundle.dart
index 19a702e..e265560 100644
--- a/pkg/frontend_server/lib/src/javascript_bundle.dart
+++ b/pkg/frontend_server/lib/src/javascript_bundle.dart
@@ -2,7 +2,6 @@
 // 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:convert';
 import 'dart:io';
 
@@ -33,7 +32,7 @@
     this.emitDebugMetadata = false,
     this.emitDebugSymbols = false,
     this.soundNullSafety = false,
-    String moduleFormat,
+    String? moduleFormat,
   }) : _moduleFormat = parseModuleFormat(moduleFormat ?? 'amd');
 
   final bool useDebuggerModuleNames;
@@ -41,7 +40,7 @@
   final bool emitDebugSymbols;
   final ModuleFormat _moduleFormat;
   final bool soundNullSafety;
-  final FileSystem _fileSystem;
+  final FileSystem? _fileSystem;
   final Set<Library> _loadedLibraries;
   final Map<Uri, Component> _uriToComponent = <Uri, Component>{};
   final _importToSummary = Map<Library, Component>.identity();
@@ -50,12 +49,13 @@
   final Map<Uri, String> _moduleImportNameForSummary = <Uri, String>{};
   final String _fileSystemScheme;
 
-  Component _lastFullComponent;
-  Component _currentComponent;
-  StrongComponents _strongComponents;
+  late Component _lastFullComponent;
+  late Component _currentComponent;
+  late StrongComponents _strongComponents;
 
   /// Initialize the incremental bundler from a full component.
-  Future<void> initialize(Component fullComponent, Uri mainUri) async {
+  Future<void> initialize(
+      Component fullComponent, Uri mainUri, PackageConfig packageConfig) async {
     _lastFullComponent = fullComponent;
     _currentComponent = fullComponent;
     _strongComponents = StrongComponents(
@@ -65,13 +65,16 @@
       _fileSystem,
     );
     await _strongComponents.computeModules();
-    _updateSummaries(_strongComponents.modules.keys);
+    _updateSummaries(_strongComponents.modules.keys, packageConfig);
   }
 
   /// Update the incremental bundler from a partial component and the last full
   /// component.
-  Future<void> invalidate(Component partialComponent,
-      Component lastFullComponent, Uri mainUri) async {
+  Future<void> invalidate(
+      Component partialComponent,
+      Component lastFullComponent,
+      Uri mainUri,
+      PackageConfig packageConfig) async {
     _currentComponent = partialComponent;
     _updateFullComponent(lastFullComponent, partialComponent);
     _strongComponents = StrongComponents(
@@ -87,9 +90,9 @@
     });
     var invalidated = <Uri>{
       for (Library library in partialComponent.libraries)
-        _strongComponents.moduleAssignment[library.importUri],
+        _strongComponents.moduleAssignment[library.importUri]!,
     };
-    _updateSummaries(invalidated);
+    _updateSummaries(invalidated, packageConfig);
   }
 
   void _updateFullComponent(Component lastKnownGood, Component candidate) {
@@ -115,9 +118,9 @@
   }
 
   /// Update the summaries [moduleKeys].
-  void _updateSummaries(Iterable<Uri> moduleKeys) {
+  void _updateSummaries(Iterable<Uri> moduleKeys, PackageConfig packageConfig) {
     for (Uri uri in moduleKeys) {
-      final List<Library> libraries = _strongComponents.modules[uri].toList();
+      final List<Library> libraries = _strongComponents.modules[uri]!.toList();
       final Component summaryComponent = Component(
         libraries: libraries,
         nameRoot: _lastFullComponent.root,
@@ -126,17 +129,13 @@
       summaryComponent.setMainMethodAndMode(
           null, false, _currentComponent.mode);
 
-      var baseName = urlForComponentUri(uri);
+      var baseName = urlForComponentUri(uri, packageConfig);
       _moduleImportForSummary[uri] = '$baseName.lib.js';
-      if (useDebuggerModuleNames) {
-        _moduleImportNameForSummary[uri] = makeDebuggerModuleName(baseName);
-      }
+      _moduleImportNameForSummary[uri] = makeModuleName(baseName);
 
       _uriToComponent[uri] = summaryComponent;
-      // debugger loads modules by modules names, not paths
-      var moduleImport = useDebuggerModuleNames
-          ? _moduleImportNameForSummary[uri]
-          : _moduleImportForSummary[uri];
+      // module loaders loads modules by modules names, not paths
+      var moduleImport = _moduleImportNameForSummary[uri]!;
 
       var oldSummaries = <Component>[];
       for (Component summary in _summaryToModule.keys) {
@@ -166,8 +165,8 @@
     IOSink codeSink,
     IOSink manifestSink,
     IOSink sourceMapsSink,
-    IOSink metadataSink,
-    IOSink symbolsSink,
+    IOSink? metadataSink,
+    IOSink? symbolsSink,
   ) async {
     var codeOffset = 0;
     var sourceMapOffset = 0;
@@ -183,24 +182,18 @@
         continue;
       }
       final Uri moduleUri =
-          _strongComponents.moduleAssignment[library.importUri];
+          _strongComponents.moduleAssignment[library.importUri]!;
       if (visited.contains(moduleUri)) {
         continue;
       }
       visited.add(moduleUri);
 
-      final summaryComponent = _uriToComponent[moduleUri];
+      final summaryComponent = _uriToComponent[moduleUri]!;
 
       // module name to use in trackLibraries
       // use full path for tracking if module uri is not a package uri.
-      String moduleName = urlForComponentUri(moduleUri);
-      if (useDebuggerModuleNames) {
-        // Skip the leading '/' as module names are used to require
-        // modules using module paths mape in RequireJS, which treats
-        // names with leading '/' or '.js' extensions specially
-        // and tries to load them without mapping.
-        moduleName = makeDebuggerModuleName(moduleName);
-      }
+      final moduleUrl = urlForComponentUri(moduleUri, packageConfig);
+      final moduleName = makeModuleName(moduleUrl);
 
       var compiler = ProgramCompiler(
         _currentComponent,
@@ -223,13 +216,12 @@
       // Save program compiler to reuse for expression evaluation.
       kernel2JsCompilers[moduleName] = compiler;
 
-      final moduleUrl = urlForComponentUri(moduleUri);
-      String sourceMapBase;
+      String? sourceMapBase;
       if (moduleUri.isScheme('package')) {
         // Source locations come through as absolute file uris. In order to
         // make relative paths in the source map we get the absolute uri for
         // the module and make them relative to that.
-        sourceMapBase = p.dirname((packageConfig.resolve(moduleUri)).path);
+        sourceMapBase = p.dirname((packageConfig.resolve(moduleUri))!.path);
       }
 
       final code = jsProgramToCode(
@@ -256,12 +248,12 @@
       codeSink.add(codeBytes);
       sourceMapsSink.add(sourceMapBytes);
       if (emitDebugMetadata) {
-        metadataSink.add(metadataBytes);
+        metadataSink!.add(metadataBytes!);
       }
       if (emitDebugSymbols) {
-        symbolsSink.add(symbolsBytes);
+        symbolsSink!.add(symbolsBytes!);
       }
-      final String moduleKey = _moduleImportForSummary[moduleUri];
+      final String moduleKey = _moduleImportForSummary[moduleUri]!;
       manifest[moduleKey] = {
         'code': <int>[codeOffset, codeOffset += codeBytes.length],
         'sourcemap': <int>[
@@ -271,12 +263,12 @@
         if (emitDebugMetadata)
           'metadata': <int>[
             metadataOffset,
-            metadataOffset += metadataBytes.length
+            metadataOffset += metadataBytes!.length
           ],
         if (emitDebugSymbols)
           'symbols': <int>[
             symbolsOffset,
-            symbolsOffset += symbolsBytes.length,
+            symbolsOffset += symbolsBytes!.length,
           ],
       };
     }
@@ -284,12 +276,42 @@
 
     return kernel2JsCompilers;
   }
-}
 
-String urlForComponentUri(Uri componentUri) => componentUri.isScheme('package')
-    ? '/packages/${componentUri.path}'
-    : componentUri.path;
+  /// Module name used in the browser to load modules.
+  ///
+  /// Module names are used to load modules using module
+  /// paths maps in RequireJS, which treats names with
+  /// leading '/' or '.js' extensions specially, and tries
+  /// to load them without mapping.
+  /// Skip the leading '/' to always load modules via module
+  /// path maps.
+  String makeModuleName(String name) {
+    return name.startsWith('/') ? name.substring(1) : name;
+  }
 
-String makeDebuggerModuleName(String name) {
-  return name.startsWith('/') ? name.substring(1) : name;
+  /// Create component url.
+  ///
+  /// Used as a server path in the browser for the module created
+  /// from the component.
+  String urlForComponentUri(Uri componentUri, PackageConfig packageConfig) {
+    if (!componentUri.isScheme('package')) {
+      return componentUri.path;
+    }
+    if (!useDebuggerModuleNames) {
+      return '/packages/${componentUri.path}';
+    }
+    // Match relative directory structure of server paths to the
+    // actual directory structure, so the sourcemaps relative paths
+    // can be resolved by the browser.
+    final resolvedUri = packageConfig.resolve(componentUri)!;
+    final package = packageConfig.packageOf(resolvedUri)!;
+    final root = package.root;
+    final relativeRoot = root.pathSegments
+        .lastWhere((segment) => segment.isNotEmpty, orElse: null);
+    final relativeUrl = resolvedUri.toString().replaceFirst('$root', '');
+
+    // Relative component url (used as server path in the browser):
+    // `packages/<package directory>/<path to file.dart>`
+    return 'packages/$relativeRoot/$relativeUrl';
+  }
 }
diff --git a/pkg/frontend_server/lib/src/resident_frontend_server.dart b/pkg/frontend_server/lib/src/resident_frontend_server.dart
index c2eb765..7488ef3 100644
--- a/pkg/frontend_server/lib/src/resident_frontend_server.dart
+++ b/pkg/frontend_server/lib/src/resident_frontend_server.dart
@@ -2,17 +2,10 @@
 // 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:async';
 import 'dart:convert';
 import 'dart:io'
-    show
-        exit,
-        File,
-        InternetAddress,
-        ProcessSignal,
-        ServerSocket,
-        Socket;
+    show exit, File, InternetAddress, ProcessSignal, ServerSocket, Socket;
 import 'dart:typed_data' show Uint8List;
 
 import 'package:args/args.dart';
@@ -34,7 +27,7 @@
 
 /// Ensures the info file is removed if Ctrl-C is sent to the server.
 /// Mostly used when debugging.
-StreamSubscription<ProcessSignal> _cleanupHandler;
+StreamSubscription<ProcessSignal>? _cleanupHandler;
 
 extension on DateTime {
   /// Truncates by [amount].
@@ -74,9 +67,9 @@
 class ResidentCompiler {
   File _entryPoint;
   File _outputDill;
-  File _currentPackage;
+  File? _currentPackage;
   ArgResults _compileOptions;
-  FrontendCompiler _compiler;
+  late FrontendCompiler _compiler;
   DateTime _lastCompileStartTime = DateTime.now().floorTime();
   _ResidentState _state = _ResidentState.WAITING_FOR_FIRST_COMPILE;
   final StringBuffer _compilerOutput = StringBuffer();
@@ -115,7 +108,7 @@
     }
     return _currentPackage != null &&
         !_lastCompileStartTime
-            .isAfter(_currentPackage.statSync().modified.floorTime());
+            .isAfter(_currentPackage!.statSync().modified.floorTime());
   }
 
   /// Compiles the entry point that this ResidentCompiler is hooked to.
@@ -359,20 +352,20 @@
   /// Returns a JSON string that the resident compiler will be able to
   /// interpret.
   static String createCompileJSON(
-      {String executable,
-      String packages,
-      String outputDill,
-      bool supportMirrors,
-      bool enableAsserts,
-      bool soundNullSafety,
-      String verbosity,
-      bool aot,
-      bool tfa,
-      bool rta,
-      bool treeShakeWriteOnlyFields,
-      bool protobufTreeShakerV2,
-      List<String> define,
-      List<String> enableExperiement,
+      {required String executable,
+      String? packages,
+      required String outputDill,
+      bool? supportMirrors,
+      bool? enableAsserts,
+      bool? soundNullSafety,
+      String? verbosity,
+      bool? aot,
+      bool? tfa,
+      bool? rta,
+      bool? treeShakeWriteOnlyFields,
+      bool? protobufTreeShakerV2,
+      List<String>? define,
+      List<String>? enableExperiement,
       bool verbose = false}) {
     return jsonEncode(<String, Object>{
       "command": "compile",
@@ -403,7 +396,7 @@
 /// ResidentFrontendServer instance.
 Future<Map<String, dynamic>> sendAndReceiveResponse(
     InternetAddress address, int port, String request) async {
-  Socket client;
+  Socket? client;
   Map<String, dynamic> jsonResponse;
   try {
     client = await Socket.connect(address, port);
@@ -428,7 +421,7 @@
     ServerSocket server, File serverInfoFile) async {
   try {
     if (_cleanupHandler != null) {
-      _cleanupHandler.cancel();
+      _cleanupHandler!.cancel();
     }
   } catch (_) {
   } finally {
@@ -455,7 +448,7 @@
 /// provided [address] and [port].
 /// If the last request exceeds the amount of time specified by
 /// [inactivityTimeout], the server will bring itself down
-Future<StreamSubscription<Socket>> residentListenAndCompile(
+Future<StreamSubscription<Socket>?> residentListenAndCompile(
     InternetAddress address, int port, File serverInfoFile,
     {Duration inactivityTimeout = const Duration(minutes: 30)}) async {
   ServerSocket server;
diff --git a/pkg/frontend_server/lib/starter.dart b/pkg/frontend_server/lib/starter.dart
index e88a7dd..33c17a6 100644
--- a/pkg/frontend_server/lib/starter.dart
+++ b/pkg/frontend_server/lib/starter.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.md file.
 
-// @dart = 2.9
 import 'dart:async';
 import 'dart:io' show Directory, File, InternetAddress, stdin;
 
@@ -21,11 +20,11 @@
 /// version for testing.
 Future<int> starter(
   List<String> args, {
-  CompilerInterface compiler,
-  Stream<List<int>> input,
-  StringSink output,
-  IncrementalCompiler generator,
-  BinaryPrinterFactory binaryPrinterFactory,
+  CompilerInterface? compiler,
+  Stream<List<int>>? input,
+  StringSink? output,
+  IncrementalCompiler? generator,
+  BinaryPrinterFactory? binaryPrinterFactory,
 }) async {
   ArgResults options;
   try {
@@ -50,7 +49,7 @@
 
     final String input = options.rest[0];
     final String sdkRoot = options['sdk-root'];
-    final String platform = options['platform'];
+    final String? platform = options['platform'];
     final Directory temp =
         Directory.systemTemp.createTempSync('train_frontend_server');
     try {
diff --git a/pkg/frontend_server/pubspec.yaml b/pkg/frontend_server/pubspec.yaml
index 5218bd1..b8e8c68 100644
--- a/pkg/frontend_server/pubspec.yaml
+++ b/pkg/frontend_server/pubspec.yaml
@@ -4,7 +4,7 @@
 publish_to: none
 
 environment:
-  sdk: "^2.15.0"
+  sdk: '>=2.15.0 <3.0.0'
 
 # Use 'any' constraints here; we get our versions from the DEPS file.
 dependencies:
@@ -23,5 +23,4 @@
 # Use 'any' constraints here; we get our versions from the DEPS file.
 dev_dependencies:
   lints: any
-  mockito: any
   test: any
diff --git a/pkg/frontend_server/test/frontend_server_flutter.dart b/pkg/frontend_server/test/frontend_server_flutter.dart
index 160b1fd..109567a 100644
--- a/pkg/frontend_server/test/frontend_server_flutter.dart
+++ b/pkg/frontend_server/test/frontend_server_flutter.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.md file.
 
-// @dart = 2.9
 import 'dart:async' show StreamController;
 import 'dart:convert' show utf8, LineSplitter;
 import 'dart:io' show Directory, File, FileSystemEntity, IOSink, exitCode;
@@ -20,8 +19,8 @@
 import 'package:frontend_server/starter.dart';
 
 main(List<String> args) async {
-  String flutterDir;
-  String flutterPlatformDir;
+  String? flutterDir;
+  String? flutterPlatformDir;
   for (String arg in args) {
     if (arg.startsWith("--flutterDir=")) {
       flutterDir = arg.substring(13);
@@ -47,8 +46,9 @@
   return NnbdMode.Strong;
 }
 
-Future compileTests(String flutterDir, String flutterPlatformDir, Logger logger,
-    {String filter, int shards = 1, int shard = 0}) async {
+Future compileTests(
+    String? flutterDir, String? flutterPlatformDir, Logger logger,
+    {String? filter, int shards = 1, int shard = 0}) async {
   if (flutterDir == null || !(new Directory(flutterDir).existsSync())) {
     throw "Didn't get a valid flutter directory to work with.";
   }
@@ -206,7 +206,7 @@
     Directory testDir,
     Directory flutterDirectory,
     Logger logger,
-    String filter,
+    String? filter,
     List<String> allCompilationErrors) async {
   Directory tempDir = systemTempDir.createTempSync('flutter_frontend_test');
   try {
@@ -237,7 +237,7 @@
     Directory testDir,
     Directory flutterDirectory,
     Logger logger,
-    String filter) async {
+    String? filter) async {
   if (testFiles.isEmpty) return [];
 
   File dillFile = new File('${tempDir.path}/dill.dill');
@@ -355,10 +355,10 @@
   bool expectSources = true;
 
   StreamController<Result> _receivedResults;
-  List<String> _receivedSources;
+  List<String>? _receivedSources;
 
-  String _boundaryKey;
-  bool _readingSources;
+  String? _boundaryKey;
+  bool _readingSources = false;
 
   List<String> allReceived = <String>[];
 
@@ -374,7 +374,7 @@
       return;
     }
 
-    if (s.startsWith(_boundaryKey)) {
+    if (s.startsWith(_boundaryKey!)) {
       // First boundaryKey separates compiler output from list of sources
       // (if we expect list of sources, which is indicated by receivedSources
       // being not null)
@@ -385,30 +385,27 @@
       // Second boundaryKey indicates end of frontend server response
       expectSources = true;
       _receivedResults.add(new Result(
-          s.length > _boundaryKey.length
-              ? s.substring(_boundaryKey.length + 1)
+          s.length > _boundaryKey!.length
+              ? s.substring(_boundaryKey!.length + 1)
               : null,
           _receivedSources));
       _boundaryKey = null;
     } else {
       if (_readingSources) {
-        if (_receivedSources == null) {
-          _receivedSources = <String>[];
-        }
-        _receivedSources.add(s);
+        (_receivedSources ??= <String>[]).add(s);
       }
     }
   }
 }
 
 class Result {
-  String status;
-  List<String> sources;
+  String? status;
+  List<String>? sources;
 
   Result(this.status, this.sources);
 
-  void expectNoErrors({String filename}) {
-    CompilationResult result = new CompilationResult.parse(status);
+  void expectNoErrors({String? filename}) {
+    CompilationResult result = new CompilationResult.parse(status!);
     if (result.errorsCount != 0) {
       throw "Got ${result.errorsCount} errors. Expected 0.";
     }
@@ -421,10 +418,10 @@
 }
 
 class CompilationResult {
-  String filename;
-  int errorsCount;
+  late String filename;
+  late int errorsCount;
 
-  CompilationResult.parse(String filenameAndErrorCount) {
+  CompilationResult.parse(String? filenameAndErrorCount) {
     if (filenameAndErrorCount == null) {
       return;
     }
diff --git a/pkg/frontend_server/test/frontend_server_flutter_suite.dart b/pkg/frontend_server/test/frontend_server_flutter_suite.dart
index 8473358..c574c15 100644
--- a/pkg/frontend_server/test/frontend_server_flutter_suite.dart
+++ b/pkg/frontend_server/test/frontend_server_flutter_suite.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.md file.
 
-// @dart = 2.9
 import 'dart:async' show StreamSubscription, Timer;
 import 'dart:convert' show jsonEncode;
 import 'dart:io' show File, exitCode;
@@ -19,7 +18,7 @@
   final bool verbose;
   final bool printFailureLog;
   final Uri outputDirectory;
-  final String testFilter;
+  final String? testFilter;
   final String flutterDir;
   final String flutterPlatformDir;
 
@@ -49,7 +48,7 @@
     var parsedArguments = parser.parse(args);
     String outputPath = parsedArguments["output-directory"] ?? ".";
     Uri outputDirectory = Uri.base.resolveUri(Uri.directory(outputPath));
-    String filter;
+    String? filter;
     if (parsedArguments.rest.length == 1) {
       filter = parsedArguments.rest.single;
       if (filter.startsWith("$suiteNamePrefix/")) {
@@ -82,7 +81,7 @@
       "configuration": suiteConfiguration.configurationName,
       "suite": suiteNamePrefix,
       "test_name": testName,
-      "time_ms": stopwatches[testName].elapsedMilliseconds,
+      "time_ms": stopwatches[testName]!.elapsedMilliseconds,
       "expected": "Pass",
       "result": matchedExpectations ? "Pass" : "Fail",
       "matches": matchedExpectations,
@@ -145,7 +144,7 @@
   final bool verbose;
   final bool printFailureLog;
   final String configurationName;
-  final String testFilter;
+  final String? testFilter;
 
   final int shard;
   final int shards;
@@ -194,7 +193,7 @@
     ..listen((resultEntry) => results.add(resultEntry));
   ReceivePort logsPort = new ReceivePort()
     ..listen((logEntry) => logs.add(logEntry));
-  String filter = options.testFilter;
+  String? filter = options.testFilter;
 
   const int shards = 4;
   List<Future<bool>> futures = [];
diff --git a/pkg/frontend_server/test/frontend_server_test.dart b/pkg/frontend_server/test/frontend_server_test.dart
index d60a8ec..a6c1eaf 100644
--- a/pkg/frontend_server/test/frontend_server_test.dart
+++ b/pkg/frontend_server/test/frontend_server_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.md file.
 
-// @dart = 2.9
 // ignore_for_file: empty_catches
 
 import 'dart:async';
@@ -11,6 +10,7 @@
 import 'dart:isolate';
 import 'dart:typed_data';
 
+import 'package:args/args.dart';
 import 'package:_fe_analyzer_shared/src/macros/compiler/request_channel.dart';
 import 'package:front_end/src/api_unstable/vm.dart';
 import 'package:frontend_server/frontend_server.dart';
@@ -19,14 +19,103 @@
 import 'package:kernel/binary/ast_to_binary.dart';
 import 'package:kernel/kernel.dart' show loadComponentFromBinary;
 import 'package:kernel/verifier.dart' show verifyComponent;
-import 'package:mockito/mockito.dart';
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:vm/incremental_compiler.dart';
 
+class _MockedBinaryPrinter implements BinaryPrinter {
+  @override
+  dynamic noSuchMethod(Invocation invocation) {}
+}
+
+class _MockedBinaryPrinterFactory implements BinaryPrinterFactory {
+  @override
+  BinaryPrinter newBinaryPrinter(Sink<List<int>> targetSink) {
+    return _MockedBinaryPrinter();
+  }
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) {}
+}
+
+typedef VerifyCompile = void Function(String entryPoint, ArgResults opts);
+typedef VerifyInvalidate = void Function(Uri uri);
+typedef VerifyRecompileDelta = void Function(String? entryPoint);
+typedef Verify = void Function();
+
+nopVerifyCompile(String entryPoint, ArgResults opts) {}
+nopVerifyInvalidate(Uri uri) {}
+nopVerifyRecompileDelta(String? entryPoint) {}
+nopVerify() {}
+
+class _MockedCompiler implements CompilerInterface {
+  _MockedCompiler(
+      {this.verifyCompile = nopVerifyCompile,
+      this.verifyRecompileDelta = nopVerifyRecompileDelta,
+      this.verifyInvalidate = nopVerifyInvalidate,
+      this.verifyAcceptLastDelta = nopVerify,
+      this.verifyResetIncrementalCompiler= nopVerify}) {}
+
+  @override
+  void acceptLastDelta() {
+    verifyAcceptLastDelta();
+  }
+
+  @override
+  Future<Null> recompileDelta({String? entryPoint}) async {
+    verifyRecompileDelta(entryPoint);
+  }
+
+  @override
+  void resetIncrementalCompiler() {
+    verifyResetIncrementalCompiler();
+  }
+
+  @override
+  void invalidate(Uri uri) {
+    verifyInvalidate(uri);
+  }
+
+  @override
+  Future<bool> compile(
+    String entryPoint,
+    ArgResults opts, {
+    IncrementalCompiler? generator,
+  }) async {
+    verifyCompile(entryPoint, opts);
+    return true;
+  }
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) {}
+
+  final VerifyCompile verifyCompile;
+  final VerifyRecompileDelta verifyRecompileDelta;
+  final VerifyInvalidate verifyInvalidate;
+  final Verify verifyAcceptLastDelta;
+  final Verify verifyResetIncrementalCompiler;
+}
+
+class _MockedIncrementalCompiler implements IncrementalCompiler {
+  @override
+  accept() {}
+
+  @override
+  bool get initialized => false;
+
+  @override
+  Future<IncrementalCompilerResult> compile({List<Uri>? entryPoints}) async {
+    return Future<IncrementalCompilerResult>.value(
+        IncrementalCompilerResult(Component()));
+  }
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) {}
+}
+
 void main() async {
   group('basic', () {
-    final CompilerInterface compiler = _MockedCompiler();
+    final compiler = _MockedCompiler();
 
     test('train with mocked compiler completes', () async {
       await starter(<String>['--train', 'foo.dart'], compiler: compiler);
@@ -34,26 +123,27 @@
   });
 
   group('batch compile with mocked compiler', () {
-    final CompilerInterface compiler = _MockedCompiler();
-    when(compiler.compile(any, any, generator: anyNamed('generator')))
-        .thenAnswer((_) => Future.value(true));
-
     test('compile from command line', () async {
+      final verify = (String entryPoint, ArgResults opts) {
+        expect(entryPoint, equals('server.dart'));
+        expect(opts['sdk-root'], equals('sdkroot'));
+      };
+      final compiler = _MockedCompiler(verifyCompile : verify);
       final List<String> args = <String>[
         'server.dart',
         '--sdk-root',
         'sdkroot',
       ];
       await starter(args, compiler: compiler);
-      final List<dynamic> capturedArgs = verify(compiler.compile(
-        argThat(equals('server.dart')),
-        captureAny,
-        generator: anyNamed('generator'),
-      )).captured;
-      expect(capturedArgs.single['sdk-root'], equals('sdkroot'));
     });
 
     test('compile from command line with link platform', () async {
+      final verify = (String entryPoint, ArgResults opts) {
+        expect(entryPoint, equals('server.dart'));
+        expect(opts['sdk-root'], equals('sdkroot'));
+        expect(opts['link-platform'], equals(true));
+      };
+      final compiler = _MockedCompiler(verifyCompile : verify);
       final List<String> args = <String>[
         'server.dart',
         '--sdk-root',
@@ -61,16 +151,16 @@
         '--link-platform',
       ];
       await starter(args, compiler: compiler);
-      final List<dynamic> capturedArgs = verify(compiler.compile(
-        argThat(equals('server.dart')),
-        captureAny,
-        generator: anyNamed('generator'),
-      )).captured;
-      expect(capturedArgs.single['sdk-root'], equals('sdkroot'));
-      expect(capturedArgs.single['link-platform'], equals(true));
     });
 
     test('compile from command line with widget cache', () async {
+      final verify = (String entryPoint, ArgResults opts) {
+        expect(entryPoint, equals('server.dart'));
+        expect(opts['sdk-root'], equals('sdkroot'));
+        expect(opts['link-platform'], equals(true));
+        expect(opts['flutter-widget-cache'], equals(true));
+      };
+      final compiler = _MockedCompiler(verifyCompile : verify);
       final List<String> args = <String>[
         'server.dart',
         '--sdk-root',
@@ -78,38 +168,25 @@
         '--flutter-widget-cache',
       ];
       await starter(args, compiler: compiler);
-      final List<dynamic> capturedArgs = verify(compiler.compile(
-        argThat(equals('server.dart')),
-        captureAny,
-        generator: anyNamed('generator'),
-      )).captured;
-      expect(capturedArgs.single['sdk-root'], equals('sdkroot'));
-      expect(capturedArgs.single['link-platform'], equals(true));
-      expect(capturedArgs.single['flutter-widget-cache'], equals(true));
     });
   });
 
   group('interactive compile with mocked compiler', () {
-    final CompilerInterface compiler = _MockedCompiler();
-
     final List<String> args = <String>[
       '--sdk-root',
       'sdkroot',
     ];
 
     test('compile one file', () async {
+      final compileCalled = ReceivePort();
+      final verify = (String entryPoint, ArgResults opts) {
+        expect(entryPoint, equals('server.dart'));
+        expect(opts['sdk-root'], equals('sdkroot'));
+        compileCalled.sendPort.send(true);
+      };
+      final compiler = _MockedCompiler(verifyCompile : verify);
       final StreamController<List<int>> inputStreamController =
           StreamController<List<int>>();
-      final ReceivePort compileCalled = ReceivePort();
-      when(compiler.compile(any, any, generator: anyNamed('generator')))
-          .thenAnswer((Invocation invocation) async {
-        expect(invocation.positionalArguments[0], equals('server.dart'));
-        expect(
-            invocation.positionalArguments[1]['sdk-root'], equals('sdkroot'));
-        compileCalled.sendPort.send(true);
-        return true;
-      });
-
       Future<int> result = starter(
         args,
         compiler: compiler,
@@ -123,17 +200,15 @@
     });
 
     test('compile one file to JavaScript', () async {
+      final compileCalled = ReceivePort();
+      final verify = (String entryPoint, ArgResults opts) {
+        expect(entryPoint, equals('server.dart'));
+        expect(opts['sdk-root'], equals('sdkroot'));
+        compileCalled.sendPort.send(true);
+      };
+      final compiler = _MockedCompiler(verifyCompile : verify);
       final StreamController<List<int>> inputStreamController =
           StreamController<List<int>>();
-      final ReceivePort compileCalled = ReceivePort();
-      when(compiler.compile(any, any, generator: anyNamed('generator')))
-          .thenAnswer((Invocation invocation) async {
-        expect(invocation.positionalArguments[0], equals('server.dart'));
-        expect(
-            invocation.positionalArguments[1]['sdk-root'], equals('sdkroot'));
-        compileCalled.sendPort.send(true);
-        return true;
-      });
 
       Future<int> result = starter(
         ['--target=dartdevc', ...args],
@@ -149,26 +224,21 @@
   });
 
   group('interactive compile with mocked compiler', () {
-    final CompilerInterface compiler = _MockedCompiler();
-
     final List<String> args = <String>[
       '--sdk-root',
       'sdkroot',
     ];
 
     test('compile one file', () async {
+      final compileCalled = ReceivePort();
+      final verify = (String entryPoint, ArgResults opts) {
+        expect(entryPoint, equals('server.dart'));
+        expect(opts['sdk-root'], equals('sdkroot'));
+        compileCalled.sendPort.send(true);
+      };
+      final compiler = _MockedCompiler(verifyCompile : verify);
       final StreamController<List<int>> inputStreamController =
           StreamController<List<int>>();
-      final ReceivePort compileCalled = ReceivePort();
-      when(compiler.compile(any, any, generator: anyNamed('generator')))
-          .thenAnswer((Invocation invocation) async {
-        expect(invocation.positionalArguments[0], equals('server.dart'));
-        expect(
-            invocation.positionalArguments[1]['sdk-root'], equals('sdkroot'));
-        compileCalled.sendPort.send(true);
-        return true;
-      });
-
       Future<int> result = starter(
         args,
         compiler: compiler,
@@ -182,20 +252,16 @@
     });
 
     test('compile few files', () async {
+      final compileCalled = ReceivePort();
+      int counter = 1;
+      final verify = (String entryPoint, ArgResults opts) {
+        expect(entryPoint, equals('server${counter++}.dart'));
+        expect(opts['sdk-root'], equals('sdkroot'));
+        compileCalled.sendPort.send(true);
+      };
+      final compiler = _MockedCompiler(verifyCompile : verify);
       final StreamController<List<int>> inputStreamController =
           StreamController<List<int>>();
-      final ReceivePort compileCalled = ReceivePort();
-      int counter = 1;
-      when(compiler.compile(any, any, generator: anyNamed('generator')))
-          .thenAnswer((Invocation invocation) async {
-        expect(invocation.positionalArguments[0],
-            equals('server${counter++}.dart'));
-        expect(
-            invocation.positionalArguments[1]['sdk-root'], equals('sdkroot'));
-        compileCalled.sendPort.send(true);
-        return true;
-      });
-
       Future<int> result = starter(
         args,
         compiler: compiler,
@@ -211,10 +277,6 @@
   });
 
   group('interactive incremental compile with mocked compiler', () {
-    final CompilerInterface compiler = _MockedCompiler();
-    when(compiler.compile(any, any, generator: anyNamed('generator')))
-        .thenAnswer((_) => Future.value(true));
-
     final List<String> args = <String>[
       '--sdk-root',
       'sdkroot',
@@ -222,14 +284,23 @@
     ];
 
     test('recompile few files', () async {
+      final recompileDeltaCalled = ReceivePort();
+      int invalidated = 0;
+      int counter = 1;
+      final verifyI = (Uri uri) {
+        expect(uri.path, contains('file${counter++}.dart'));
+        invalidated += 1;
+      };
+      final verifyR = (String? entryPoint) {
+        expect(invalidated, equals(2));
+        expect(entryPoint, equals(null));
+        recompileDeltaCalled.sendPort.send(true);
+      };
+      final compiler = _MockedCompiler(
+        verifyInvalidate : verifyI, verifyRecompileDelta : verifyR);
       final StreamController<List<int>> inputStreamController =
           StreamController<List<int>>();
-      final ReceivePort recompileCalled = ReceivePort();
 
-      when(compiler.recompileDelta(entryPoint: null))
-          .thenAnswer((Invocation invocation) async {
-        recompileCalled.sendPort.send(true);
-      });
       Future<int> result = starter(
         args,
         compiler: compiler,
@@ -237,55 +308,62 @@
       );
       inputStreamController
           .add('recompile abc\nfile1.dart\nfile2.dart\nabc\n'.codeUnits);
-      await recompileCalled.first;
+      await recompileDeltaCalled.first;
 
-      verifyInOrder(<void>[
-        compiler.invalidate(Uri.base.resolve('file1.dart')),
-        compiler.invalidate(Uri.base.resolve('file2.dart')),
-        await compiler.recompileDelta(entryPoint: null),
-      ]);
       inputStreamController.add('quit\n'.codeUnits);
       expect(await result, 0);
       inputStreamController.close();
     });
 
     test('recompile one file with widget cache does not fail', () async {
+      final recompileDeltaCalled = ReceivePort();
+      bool invalidated = false;
+      final verifyR = (String? entryPoint) {
+        expect(invalidated, equals(true));
+        expect(entryPoint, equals(null));
+        recompileDeltaCalled.sendPort.send(true);
+      };
+      final verifyI = (Uri uri) {
+        invalidated = true;
+        expect(uri.path, contains('file1.dart'));
+      };
       // The component will not contain the flutter framework sources so
       // this should no-op.
+      final compiler = _MockedCompiler(
+        verifyRecompileDelta : verifyR, verifyInvalidate : verifyI);
       final StreamController<List<int>> inputStreamController =
           StreamController<List<int>>();
-      final ReceivePort recompileCalled = ReceivePort();
 
-      when(compiler.recompileDelta(entryPoint: null))
-          .thenAnswer((Invocation invocation) async {
-        recompileCalled.sendPort.send(true);
-      });
       Future<int> result = starter(
         <String>[...args, '--flutter-widget-cache'],
         compiler: compiler,
         input: inputStreamController.stream,
       );
       inputStreamController.add('recompile abc\nfile1.dart\nabc\n'.codeUnits);
-      await recompileCalled.first;
-
-      verifyInOrder(<void>[
-        compiler.invalidate(Uri.base.resolve('file1.dart')),
-        await compiler.recompileDelta(entryPoint: null),
-      ]);
+      await recompileDeltaCalled.first;
       inputStreamController.add('quit\n'.codeUnits);
       expect(await result, 0);
       inputStreamController.close();
     });
 
     test('recompile few files with new entrypoint', () async {
+      int invalidated = 0;
+      final recompileDeltaCalled = ReceivePort();
+      int counter = 1;
+      final verifyI = (Uri uri) {
+        expect(uri.path, contains('file${counter++}.dart'));
+        invalidated += 1;
+      };
+      final verifyR = (String? entryPoint) {
+        expect(invalidated, equals(2));
+        expect(entryPoint, equals('file2.dart'));
+        recompileDeltaCalled.sendPort.send(true);
+      };
+      final compiler = _MockedCompiler(
+        verifyRecompileDelta : verifyR, verifyInvalidate : verifyI);
       final StreamController<List<int>> inputStreamController =
           StreamController<List<int>>();
-      final ReceivePort recompileCalled = ReceivePort();
 
-      when(compiler.recompileDelta(entryPoint: 'file2.dart'))
-          .thenAnswer((Invocation invocation) async {
-        recompileCalled.sendPort.send(true);
-      });
       Future<int> result = starter(
         args,
         compiler: compiler,
@@ -293,25 +371,20 @@
       );
       inputStreamController.add(
           'recompile file2.dart abc\nfile1.dart\nfile2.dart\nabc\n'.codeUnits);
-      await recompileCalled.first;
-
-      verifyInOrder(<void>[
-        compiler.invalidate(Uri.base.resolve('file1.dart')),
-        compiler.invalidate(Uri.base.resolve('file2.dart')),
-        await compiler.recompileDelta(entryPoint: 'file2.dart'),
-      ]);
+      await recompileDeltaCalled.first;
       inputStreamController.add('quit\n'.codeUnits);
       expect(await result, 0);
       inputStreamController.close();
     });
 
     test('accept', () async {
+      final acceptCalled = ReceivePort();
+      final verify = () {
+        acceptCalled.sendPort.send(true);
+      };
+      final compiler = _MockedCompiler(verifyAcceptLastDelta : verify);
       final StreamController<List<int>> inputStreamController =
           StreamController<List<int>>();
-      final ReceivePort acceptCalled = ReceivePort();
-      when(compiler.acceptLastDelta()).thenAnswer((Invocation invocation) {
-        acceptCalled.sendPort.send(true);
-      });
       Future<int> result = starter(
         args,
         compiler: compiler,
@@ -325,13 +398,13 @@
     });
 
     test('reset', () async {
+      final resetCalled = ReceivePort();
+      final verify = () {
+        resetCalled.sendPort.send(true);
+      };
+      final compiler = _MockedCompiler(verifyResetIncrementalCompiler : verify);
       final StreamController<List<int>> inputStreamController =
           StreamController<List<int>>();
-      final ReceivePort resetCalled = ReceivePort();
-      when(compiler.resetIncrementalCompiler())
-          .thenAnswer((Invocation invocation) {
-        resetCalled.sendPort.send(true);
-      });
       Future<int> result = starter(
         args,
         compiler: compiler,
@@ -345,14 +418,38 @@
     });
 
     test('compile then recompile', () async {
+      final recompileDeltaCalled = ReceivePort();
+      bool compile = false;
+      int invalidate = 0;
+      bool acceptDelta = false;
+      final verifyC = (String entryPoint, ArgResults opts) {
+        compile = true;
+        expect(entryPoint, equals('file1.dart'));
+      };
+      final verifyA = () {
+        expect(compile, equals(true));
+        acceptDelta = true;
+      };
+      int counter = 2;
+      final verifyI = (Uri uri) {
+        expect(compile, equals(true));
+        expect(acceptDelta, equals(true));
+        expect(uri.path, contains('file${counter++}.dart'));
+        invalidate += 1;
+      };
+      final verifyR = (String? entryPoint) {
+        expect(compile, equals(true));
+        expect(invalidate, equals(2));
+        expect(acceptDelta, equals(true));
+        expect(entryPoint, equals(null));
+        recompileDeltaCalled.sendPort.send(true);
+      };
+      final compiler = _MockedCompiler(verifyCompile : verifyC,
+        verifyRecompileDelta : verifyR, verifyInvalidate : verifyI,
+        verifyAcceptLastDelta : verifyA);
       final StreamController<List<int>> inputStreamController =
           StreamController<List<int>>();
-      final ReceivePort recompileCalled = ReceivePort();
 
-      when(compiler.recompileDelta(entryPoint: null))
-          .thenAnswer((Invocation invocation) async {
-        recompileCalled.sendPort.send(true);
-      });
       Future<int> result = starter(
         args,
         compiler: compiler,
@@ -362,16 +459,7 @@
       inputStreamController.add('accept\n'.codeUnits);
       inputStreamController
           .add('recompile def\nfile2.dart\nfile3.dart\ndef\n'.codeUnits);
-      await recompileCalled.first;
-
-      verifyInOrder(<void>[
-        await compiler.compile('file1.dart', any,
-            generator: anyNamed('generator')),
-        compiler.acceptLastDelta(),
-        compiler.invalidate(Uri.base.resolve('file2.dart')),
-        compiler.invalidate(Uri.base.resolve('file3.dart')),
-        await compiler.recompileDelta(entryPoint: null),
-      ]);
+      await recompileDeltaCalled.first;
       inputStreamController.add('quit\n'.codeUnits);
       expect(await result, 0);
       inputStreamController.close();
@@ -385,7 +473,7 @@
       '--incremental',
     ];
 
-    Directory tempDir;
+    late Directory tempDir;
     setUp(() {
       tempDir = Directory.systemTemp.createTempSync();
     });
@@ -401,7 +489,7 @@
       final IOSink ioSink = IOSink(stdoutStreamController.sink);
       ReceivePort receivedResult = ReceivePort();
 
-      String boundaryKey;
+      String? boundaryKey;
       stdoutStreamController.stream
           .transform(utf8.decoder)
           .transform(const LineSplitter())
@@ -412,7 +500,7 @@
             boundaryKey = s.substring(RESULT_OUTPUT_SPACE.length);
           }
         } else {
-          if (s.startsWith(boundaryKey)) {
+          if (s.startsWith(boundaryKey!)) {
             boundaryKey = null;
             receivedResult.sendPort.send(true);
           }
@@ -420,17 +508,8 @@
       });
 
       final _MockedIncrementalCompiler generator = _MockedIncrementalCompiler();
-      when(generator.initialized).thenAnswer((_) => false);
-      when(generator.compile()).thenAnswer((_) =>
-          Future<IncrementalCompilerResult>.value(
-              IncrementalCompilerResult(Component())));
-      when(generator.compile(entryPoints: anyNamed("entryPoints"))).thenAnswer(
-          (_) => Future<IncrementalCompilerResult>.value(
-              IncrementalCompilerResult(Component())));
       final _MockedBinaryPrinterFactory printerFactory =
           _MockedBinaryPrinterFactory();
-      when(printerFactory.newBinaryPrinter(any))
-          .thenReturn(_MockedBinaryPrinter());
       Future<int> result = starter(
         args,
         compiler: null,
@@ -455,10 +534,10 @@
     });
 
     group('compile with output path', () {
-      final CompilerInterface compiler = _MockedCompiler();
-      when(compiler.compile(any, any, generator: anyNamed('generator')))
-          .thenAnswer((_) => Future.value(true));
-
+      final verify = (String entryPoint, ArgResults opts) {
+        expect(opts['sdk-root'], equals('sdkroot'));
+      };
+      final compiler = _MockedCompiler(verifyCompile : verify);
       test('compile from command line', () async {
         final List<String> args = <String>[
           'server.dart',
@@ -470,12 +549,6 @@
           '/foo/bar/server.incremental.dart.dill',
         ];
         expect(await starter(args, compiler: compiler), 0);
-        final List<dynamic> capturedArgs = verify(compiler.compile(
-          argThat(equals('server.dart')),
-          captureAny,
-          generator: anyNamed('generator'),
-        )).captured;
-        expect(capturedArgs.single['sdk-root'], equals('sdkroot'));
       });
     });
   });
@@ -489,7 +562,7 @@
         computePlatformBinariesLocation().resolve('ddc_sdk.dill');
     final sdkRoot = computePlatformBinariesLocation();
 
-    Directory tempDir;
+    late Directory tempDir;
     setUp(() {
       var systemTempDir = Directory.systemTemp;
       tempDir = systemTempDir.createTempSync('frontendServerTest');
@@ -545,7 +618,7 @@
           frontendServer.compileExpression('2+2', file.uri, isStatic: null);
           count += 1;
         } else if (count == 1) {
-          expect(result.errorsCount, isNull);
+          expect(result.errorsCount, equals(0));
           // Previous request should have failed because isStatic was blank
           expect(compiledResult.status, isNull);
 
@@ -619,7 +692,7 @@
         } else if (count == 2) {
           // Third request is to 'compile-expression-to-js' that fails
           // due to non-web target
-          expect(result.errorsCount, isNull);
+          expect(result.errorsCount, equals(0));
           expect(compiledResult.status, isNull);
 
           frontendServer.compileExpression('2+2', file.uri, isStatic: false);
@@ -1478,9 +1551,9 @@
 
     group('http uris', () {
       var host = 'localhost';
-      File dillFile;
-      int port;
-      HttpServer server;
+      late File dillFile;
+      late int port;
+      late HttpServer server;
 
       setUp(() async {
         dillFile = File('${tempDir.path}/app.dill');
@@ -1652,7 +1725,7 @@
 
         test('OK', () async {
           await runWithServer((requestChannel) async {
-            await requestChannel.sendRequest<Uint8List>('dill.put', {
+            await requestChannel.sendRequest<Uint8List?>('dill.put', {
               'uri': 'vm:dill',
               'bytes': Uint8List(256),
             });
@@ -1681,7 +1754,7 @@
 
         test('OK', () async {
           await runWithServer((requestChannel) async {
-            await requestChannel.sendRequest<Uint8List>('dill.remove', {
+            await requestChannel.sendRequest<Uint8List?>('dill.remove', {
               'uri': 'vm:dill',
             });
           });
@@ -1833,7 +1906,7 @@
 
     test('compile to JavaScript weak null safety', () async {
       var file = File('${tempDir.path}/foo.dart')..createSync();
-      file.writeAsStringSync("// @dart = 2.9\nmain() {\n}\n");
+      file.writeAsStringSync("main() {\n}\n");
       var packages = File('${tempDir.path}/.dart_tool/package_config.json')
         ..createSync()
         ..writeAsStringSync(jsonEncode({
@@ -1865,7 +1938,7 @@
     test('compile to JavaScript weak null safety then non-existent file',
         () async {
       var file = File('${tempDir.path}/foo.dart')..createSync();
-      file.writeAsStringSync("// @dart = 2.9\nmain() {\n}\n");
+      file.writeAsStringSync("main() {\n}\n");
       var packages = File('${tempDir.path}/.dart_tool/package_config.json')
         ..createSync()
         ..writeAsStringSync(jsonEncode({
@@ -2896,7 +2969,7 @@
     }, timeout: Timeout.factor(8));
 
     test('compile with(out) warning', () async {
-      Future runTest({bool hideWarnings}) async {
+      Future runTest({bool hideWarnings = true}) async {
         var file = File('${tempDir.path}/foo.dart')..createSync();
         file.writeAsStringSync("""
 main() {}
@@ -2971,10 +3044,10 @@
 }
 
 class CompilationResult {
-  String filename;
-  int errorsCount;
+  late String filename;
+  int errorsCount = 0;
 
-  CompilationResult.parse(String filenameAndErrorCount) {
+  CompilationResult.parse(String? filenameAndErrorCount) {
     if (filenameAndErrorCount == null) {
       return;
     }
@@ -2989,10 +3062,10 @@
   bool expectSources = true;
   StreamController<Result> _receivedResults;
 
-  List<String> _receivedSources;
-  String _boundaryKey;
+  List<String>? _receivedSources;
+  String? _boundaryKey;
 
-  bool _readingSources;
+  bool _readingSources = false;
   OutputParser(this._receivedResults);
 
   void listener(String s) {
@@ -3006,7 +3079,8 @@
       return;
     }
 
-    if (s.startsWith(_boundaryKey)) {
+    var bKey = _boundaryKey!;
+    if (s.startsWith(bKey)) {
       // First boundaryKey separates compiler output from list of sources
       // (if we expect list of sources, which is indicated by receivedSources
       // being not null)
@@ -3017,29 +3091,29 @@
       // Second boundaryKey indicates end of frontend server response
       expectSources = true;
       _receivedResults.add(Result(
-          s.length > _boundaryKey.length
-              ? s.substring(_boundaryKey.length + 1)
+          s.length > bKey.length
+              ? s.substring(bKey.length + 1)
               : null,
-          _receivedSources));
+          _receivedSources!));
       _boundaryKey = null;
     } else {
       if (_readingSources) {
         if (_receivedSources == null) {
           _receivedSources = <String>[];
         }
-        _receivedSources.add(s);
+        _receivedSources!.add(s);
       }
     }
   }
 }
 
 class Result {
-  String status;
+  String? status;
   List<String> sources;
 
   Result(this.status, this.sources);
 
-  void expectNoErrors({String filename}) {
+  void expectNoErrors({String? filename}) {
     var result = CompilationResult.parse(status);
     expect(result.errorsCount, equals(0));
     if (filename != null) {
@@ -3048,15 +3122,6 @@
   }
 }
 
-class _MockedBinaryPrinter extends Mock implements BinaryPrinter {}
-
-class _MockedBinaryPrinterFactory extends Mock
-    implements BinaryPrinterFactory {}
-
-class _MockedCompiler extends Mock implements CompilerInterface {}
-
-class _MockedIncrementalCompiler extends Mock implements IncrementalCompiler {}
-
 /// Creates a matcher for the negation of [matcher].
 Matcher not(Matcher matcher) => NotMatcher(matcher);
 
@@ -3160,10 +3225,10 @@
   /// [boundaryKey] is used as the boundary-key in the communication with the
   /// frontend server.
   // TODO(johnniwinther): Use (required) named arguments.
-  void recompile(Uri invalidatedUri,
+  void recompile(Uri? invalidatedUri,
       {String boundaryKey = 'abc',
-      List<Uri> invalidatedUris,
-      String entryPoint}) {
+      List<Uri>? invalidatedUris,
+      String? entryPoint}) {
     invalidatedUris ??= [if (invalidatedUri != null) invalidatedUri];
     outputParser.expectSources = true;
     inputStreamController.add('recompile '
@@ -3186,7 +3251,7 @@
   /// frontend server.
   // TODO(johnniwinther): Use (required) named arguments.
   void compileExpression(String expression, Uri library,
-      {String boundaryKey = 'abc', String className = '', bool isStatic}) {
+      {String boundaryKey = 'abc', String className = '', bool? isStatic}) {
     // 'compile-expression <boundarykey>
     // expression
     // definitions (one per line)
diff --git a/pkg/frontend_server/test/src/javascript_bundle_test.dart b/pkg/frontend_server/test/src/javascript_bundle_test.dart
index 77afeab..21fa080 100644
--- a/pkg/frontend_server/test/src/javascript_bundle_test.dart
+++ b/pkg/frontend_server/test/src/javascript_bundle_test.dart
@@ -2,7 +2,6 @@
 // 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:convert';
 import 'dart:io';
 
@@ -83,179 +82,233 @@
       {
         'name': 'a',
         'rootUri': 'file:///pkg/a',
-        'packagesUri': '',
+        'packageUri': 'lib/',
       }
     ],
   }, Uri.base);
   final multiRootScheme = 'org-dartlang-app';
 
-  test('compiles JavaScript code', () async {
-    final uri = Uri.file('/c.dart');
-    final library = Library(
-      uri,
-      fileUri: uri,
-      procedures: [
-        Procedure(Name('ArbitrarilyChosen'), ProcedureKind.Method,
-            FunctionNode(Block([])),
-            fileUri: uri)
-      ],
-    );
-    final testComponent = Component(libraries: [library, ...testCoreLibraries]);
-    final javaScriptBundler = IncrementalJavaScriptBundler(
-      null,
-      {},
-      multiRootScheme,
-    );
+  for (final debuggerNames in [true, false]) {
+    group('Debugger module names: $debuggerNames |', () {
+      test('Creates module uris for file paths', () async {
+        final fileUri = Uri.file('/c.dart');
 
-    await javaScriptBundler.initialize(testComponent, uri);
+        final javaScriptBundler = IncrementalJavaScriptBundler(
+          null,
+          {},
+          multiRootScheme,
+          useDebuggerModuleNames: debuggerNames,
+        );
 
-    final manifestSink = _MemorySink();
-    final codeSink = _MemorySink();
-    final sourcemapSink = _MemorySink();
-    final metadataSink = _MemorySink();
-    final symbolsSink = _MemorySink();
-    final coreTypes = CoreTypes(testComponent);
+        final moduleUrl =
+            javaScriptBundler.urlForComponentUri(fileUri, packageConfig);
+        final moduleName = javaScriptBundler.makeModuleName(moduleUrl);
+        expect(moduleUrl, '/c.dart');
+        expect(moduleName, 'c.dart');
+      });
 
-    final compilers = await javaScriptBundler.compile(
-      ClassHierarchy(testComponent, coreTypes),
-      coreTypes,
-      packageConfig,
-      codeSink,
-      manifestSink,
-      sourcemapSink,
-      metadataSink,
-      symbolsSink,
-    );
+      test('Creates module uris for package paths', () async {
+        final packageUri = Uri.parse('package:a/a.dart');
 
-    final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
-    final String code = utf8.decode(codeSink.buffer);
+        final javaScriptBundler = IncrementalJavaScriptBundler(
+          null,
+          {},
+          multiRootScheme,
+          useDebuggerModuleNames: debuggerNames,
+        );
 
-    expect(manifest, {
-      '/c.dart.lib.js': {
-        'code': [0, codeSink.buffer.length],
-        'sourcemap': [0, sourcemapSink.buffer.length],
-      },
+        final moduleUrl =
+            javaScriptBundler.urlForComponentUri(packageUri, packageConfig);
+        final moduleName = javaScriptBundler.makeModuleName(moduleUrl);
+        expect(moduleUrl,
+            debuggerNames ? 'packages/a/lib/a.dart' : '/packages/a/a.dart');
+        expect(moduleName,
+            debuggerNames ? 'packages/a/lib/a.dart' : 'packages/a/a.dart');
+      });
+
+      test('compiles JavaScript code', () async {
+        final uri = Uri.file('/c.dart');
+        final library = Library(
+          uri,
+          fileUri: uri,
+          procedures: [
+            Procedure(Name('ArbitrarilyChosen'), ProcedureKind.Method,
+                FunctionNode(Block([])),
+                fileUri: uri)
+          ],
+        );
+        final testComponent =
+            Component(libraries: [library, ...testCoreLibraries]);
+        final javaScriptBundler = IncrementalJavaScriptBundler(
+          null,
+          {},
+          multiRootScheme,
+          useDebuggerModuleNames: debuggerNames,
+        );
+
+        await javaScriptBundler.initialize(testComponent, uri, packageConfig);
+
+        final manifestSink = _MemorySink();
+        final codeSink = _MemorySink();
+        final sourcemapSink = _MemorySink();
+        final metadataSink = _MemorySink();
+        final symbolsSink = _MemorySink();
+        final coreTypes = CoreTypes(testComponent);
+
+        final compilers = await javaScriptBundler.compile(
+          ClassHierarchy(testComponent, coreTypes),
+          coreTypes,
+          packageConfig,
+          codeSink,
+          manifestSink,
+          sourcemapSink,
+          metadataSink,
+          symbolsSink,
+        );
+
+        final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
+        final String code = utf8.decode(codeSink.buffer);
+
+        expect(manifest, {
+          '/c.dart.lib.js': {
+            'code': [0, codeSink.buffer.length],
+            'sourcemap': [0, sourcemapSink.buffer.length],
+          },
+        });
+        expect(code, contains('ArbitrarilyChosen'));
+
+        // Verify source map url is correct.
+        expect(code, contains('sourceMappingURL=c.dart.lib.js.map'));
+
+        // Verify program compilers are created.
+        final moduleUrl = javaScriptBundler.urlForComponentUri(
+            library.importUri, packageConfig);
+        final moduleName = javaScriptBundler.makeModuleName(moduleUrl);
+        expect(compilers.keys, equals([moduleName]));
+      });
+
+      test('converts package: uris into /packages/ uris', () async {
+        var importUri = Uri.parse('package:a/a.dart');
+        var fileUri = packageConfig.resolve(importUri)!;
+        final library = Library(
+          importUri,
+          fileUri: fileUri,
+          procedures: [
+            Procedure(Name('ArbitrarilyChosen'), ProcedureKind.Method,
+                FunctionNode(Block([])),
+                fileUri: fileUri)
+          ],
+        );
+
+        final testComponent =
+            Component(libraries: [library, ...testCoreLibraries]);
+
+        final javaScriptBundler = IncrementalJavaScriptBundler(
+          null,
+          {},
+          multiRootScheme,
+          useDebuggerModuleNames: debuggerNames,
+        );
+
+        await javaScriptBundler.initialize(
+            testComponent, importUri, packageConfig);
+
+        final manifestSink = _MemorySink();
+        final codeSink = _MemorySink();
+        final sourcemapSink = _MemorySink();
+        final metadataSink = _MemorySink();
+        final symbolsSink = _MemorySink();
+        final coreTypes = CoreTypes(testComponent);
+
+        await javaScriptBundler.compile(
+          ClassHierarchy(testComponent, coreTypes),
+          coreTypes,
+          packageConfig,
+          codeSink,
+          manifestSink,
+          sourcemapSink,
+          metadataSink,
+          symbolsSink,
+        );
+
+        final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
+        final String code = utf8.decode(codeSink.buffer);
+
+        final moduleUrl = javaScriptBundler.urlForComponentUri(
+            library.importUri, packageConfig);
+
+        expect(manifest, {
+          '$moduleUrl.lib.js': {
+            'code': [0, codeSink.buffer.length],
+            'sourcemap': [0, sourcemapSink.buffer.length],
+          },
+        });
+        expect(code, contains('ArbitrarilyChosen'));
+
+        // Verify source map url is correct.
+        expect(code, contains('sourceMappingURL=a.dart.lib.js.map'));
+      });
+
+      test('multi-root uris create modules relative to the root', () async {
+        var importUri = Uri.parse('$multiRootScheme:/web/main.dart');
+        var fileUri = importUri;
+        final library = Library(
+          importUri,
+          fileUri: fileUri,
+          procedures: [
+            Procedure(Name('ArbitrarilyChosen'), ProcedureKind.Method,
+                FunctionNode(Block([])),
+                fileUri: fileUri)
+          ],
+        );
+
+        final testComponent =
+            Component(libraries: [library, ...testCoreLibraries]);
+
+        final javaScriptBundler = IncrementalJavaScriptBundler(
+          null,
+          {},
+          multiRootScheme,
+          useDebuggerModuleNames: debuggerNames,
+        );
+
+        await javaScriptBundler.initialize(
+            testComponent, importUri, packageConfig);
+
+        final manifestSink = _MemorySink();
+        final codeSink = _MemorySink();
+        final sourcemapSink = _MemorySink();
+        final metadataSink = _MemorySink();
+        final symbolsSink = _MemorySink();
+        final coreTypes = CoreTypes(testComponent);
+
+        await javaScriptBundler.compile(
+          ClassHierarchy(testComponent, coreTypes),
+          coreTypes,
+          packageConfig,
+          codeSink,
+          manifestSink,
+          sourcemapSink,
+          metadataSink,
+          symbolsSink,
+        );
+
+        final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
+        final String code = utf8.decode(codeSink.buffer);
+
+        expect(manifest, {
+          '${importUri.path}.lib.js': {
+            'code': [0, codeSink.buffer.length],
+            'sourcemap': [0, sourcemapSink.buffer.length],
+          },
+        });
+        expect(code, contains('ArbitrarilyChosen'));
+
+        // Verify source map url is correct.
+        expect(code, contains('sourceMappingURL=main.dart.lib.js.map'));
+      });
     });
-    expect(code, contains('ArbitrarilyChosen'));
-
-    // verify source map url is correct.
-    expect(code, contains('sourceMappingURL=c.dart.lib.js.map'));
-
-    // verify program compilers are created.
-    expect(compilers.keys, equals([urlForComponentUri(library.importUri)]));
-  });
-
-  test('converts package: uris into /packages/ uris', () async {
-    var importUri = Uri.parse('package:a/a.dart');
-    var fileUri = packageConfig.resolve(importUri);
-    final library = Library(
-      importUri,
-      fileUri: fileUri,
-      procedures: [
-        Procedure(Name('ArbitrarilyChosen'), ProcedureKind.Method,
-            FunctionNode(Block([])),
-            fileUri: fileUri)
-      ],
-    );
-
-    final testComponent = Component(libraries: [library, ...testCoreLibraries]);
-
-    final javaScriptBundler = IncrementalJavaScriptBundler(
-      null,
-      {},
-      multiRootScheme,
-    );
-
-    await javaScriptBundler.initialize(testComponent, importUri);
-
-    final manifestSink = _MemorySink();
-    final codeSink = _MemorySink();
-    final sourcemapSink = _MemorySink();
-    final metadataSink = _MemorySink();
-    final symbolsSink = _MemorySink();
-    final coreTypes = CoreTypes(testComponent);
-
-    await javaScriptBundler.compile(
-      ClassHierarchy(testComponent, coreTypes),
-      coreTypes,
-      packageConfig,
-      codeSink,
-      manifestSink,
-      sourcemapSink,
-      metadataSink,
-      symbolsSink,
-    );
-
-    final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
-    final String code = utf8.decode(codeSink.buffer);
-
-    expect(manifest, {
-      '/packages/a/a.dart.lib.js': {
-        'code': [0, codeSink.buffer.length],
-        'sourcemap': [0, sourcemapSink.buffer.length],
-      },
-    });
-    expect(code, contains('ArbitrarilyChosen'));
-
-    // verify source map url is correct.
-    expect(code, contains('sourceMappingURL=a.dart.lib.js.map'));
-  });
-
-  test('multi-root uris create modules relative to the root', () async {
-    var importUri = Uri.parse('$multiRootScheme:/web/main.dart');
-    var fileUri = importUri;
-    final library = Library(
-      importUri,
-      fileUri: fileUri,
-      procedures: [
-        Procedure(Name('ArbitrarilyChosen'), ProcedureKind.Method,
-            FunctionNode(Block([])),
-            fileUri: fileUri)
-      ],
-    );
-
-    final testComponent = Component(libraries: [library, ...testCoreLibraries]);
-
-    final javaScriptBundler = IncrementalJavaScriptBundler(
-      null,
-      {},
-      multiRootScheme,
-    );
-
-    await javaScriptBundler.initialize(testComponent, importUri);
-
-    final manifestSink = _MemorySink();
-    final codeSink = _MemorySink();
-    final sourcemapSink = _MemorySink();
-    final metadataSink = _MemorySink();
-    final symbolsSink = _MemorySink();
-    final coreTypes = CoreTypes(testComponent);
-
-    await javaScriptBundler.compile(
-      ClassHierarchy(testComponent, coreTypes),
-      coreTypes,
-      packageConfig,
-      codeSink,
-      manifestSink,
-      sourcemapSink,
-      metadataSink,
-      symbolsSink,
-    );
-
-    final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
-    final String code = utf8.decode(codeSink.buffer);
-
-    expect(manifest, {
-      '${importUri.path}.lib.js': {
-        'code': [0, codeSink.buffer.length],
-        'sourcemap': [0, sourcemapSink.buffer.length],
-      },
-    });
-    expect(code, contains('ArbitrarilyChosen'));
-
-    // verify source map url is correct.
-    expect(code, contains('sourceMappingURL=main.dart.lib.js.map'));
-  });
+  }
 
   test('can combine strongly connected components', () async {
     // Create three libraries A, B, C where A is the entrypoint and B & C
@@ -286,7 +339,7 @@
       multiRootScheme,
     );
 
-    await javaScriptBundler.initialize(testComponent, uriA);
+    await javaScriptBundler.initialize(testComponent, uriA, packageConfig);
 
     final manifestSink = _MemorySink();
     final codeSink = _MemorySink();
@@ -321,14 +374,14 @@
         r"define(['dart_sdk'], (function load__c_dart(dart_sdk) {";
     expect(code, contains(cModuleHeader));
 
-    // verify source map url is correct.
+    // Verify source map url is correct.
     expect(code, contains('sourceMappingURL=a.dart.lib.js.map'));
 
     final offsets = manifest['/a.dart.lib.js']['sourcemap'];
     final sourcemapModuleA = json.decode(
         utf8.decode(sourcemapSink.buffer.sublist(offsets.first, offsets.last)));
 
-    // verify source maps are pointing at correct source files.
+    // Verify source maps are pointing at correct source files.
     expect(sourcemapModuleA['file'], 'a.dart.lib.js');
   });
 
@@ -364,7 +417,7 @@
       multiRootScheme,
     );
 
-    await javaScriptBundler.initialize(testComponent, uriA);
+    await javaScriptBundler.initialize(testComponent, uriA, packageConfig);
 
     // Now change A and B so that they no longer import each other.
     final libraryC2 = Library(uriC, fileUri: uriC);
@@ -385,7 +438,8 @@
     final partialComponent =
         Component(libraries: [libraryA2, libraryB2, libraryC2]);
 
-    await javaScriptBundler.invalidate(partialComponent, testComponent, uriA);
+    await javaScriptBundler.invalidate(
+        partialComponent, testComponent, uriA, packageConfig);
 
     final manifestSink = _MemorySink();
     final codeSink = _MemorySink();
@@ -422,14 +476,14 @@
     final cModuleHeader =
         r"define(['dart_sdk'], (function load__c_dart(dart_sdk) {";
     expect(code, contains(cModuleHeader));
-    // verify source map url is correct.
+    // Verify source map url is correct.
     expect(code, contains('sourceMappingURL=a.dart.lib.js.map'));
 
     final offsets = manifest['/a.dart.lib.js']['sourcemap'];
     final sourcemapModuleA = json.decode(
         utf8.decode(sourcemapSink.buffer.sublist(offsets.first, offsets.last)));
 
-    // verify source maps are pointing at correct source files.
+    // Verify source maps are pointing at correct source files.
     expect(sourcemapModuleA['file'], 'a.dart.lib.js');
   });
 
@@ -470,7 +524,7 @@
       multiRootScheme,
     );
 
-    await javaScriptBundler.initialize(testComponent, uriA);
+    await javaScriptBundler.initialize(testComponent, uriA, packageConfig);
 
     // Create a new component that only contains C.
     final libraryC2 = Library(
@@ -485,7 +539,8 @@
 
     final partialComponent = Component(libraries: [libraryC2]);
 
-    await javaScriptBundler.invalidate(partialComponent, testComponent, uriA);
+    await javaScriptBundler.invalidate(
+        partialComponent, testComponent, uriA, packageConfig);
 
     final manifestSink = _MemorySink();
     final codeSink = _MemorySink();
@@ -539,8 +594,7 @@
 ) {
   final result = Map<String, List<String>>.from(left);
   for (String key in right.keys) {
-    result[key] ??= [];
-    result[key].addAll(right[key]);
+    (result[key] ??= []).addAll(right[key]!);
   }
   return result;
 }
diff --git a/pkg/frontend_server/test/src/resident_frontend_server_test.dart b/pkg/frontend_server/test/src/resident_frontend_server_test.dart
index b2cbe8a..1145ac5 100644
--- a/pkg/frontend_server/test/src/resident_frontend_server_test.dart
+++ b/pkg/frontend_server/test/src/resident_frontend_server_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.md file.
 
-// @dart = 2.9
 import 'dart:convert';
 import 'dart:io';
 
@@ -66,8 +65,8 @@
   });
 
   group('Resident Frontend Server: compile tests: ', () {
-    Directory d;
-    File executable, package, cachedDill;
+    late Directory d;
+    late File executable, package, cachedDill;
 
     setUp(() async {
       d = Directory.systemTemp.createTempSync();
@@ -188,11 +187,11 @@
       expect(compileResults2['incremental'], true);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.first,
+              .compilers[executable.path]!.trackedSources.first,
           equals(Uri.file(executable.path)));
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.length,
+              .compilers[executable.path]!.trackedSources.length,
           1);
     });
 
@@ -243,19 +242,19 @@
           allOf(true, equals(compileResults2['success'])));
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.length,
+              .compilers[executable.path]!.trackedSources.length,
           1);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.first,
+              .compilers[executable.path]!.trackedSources.first,
           equals(Uri.file(executable.path)));
       expect(
           ResidentFrontendServer
-              .compilers[executable2.path].trackedSources.length,
+              .compilers[executable2.path]!.trackedSources.length,
           1);
       expect(
           ResidentFrontendServer
-              .compilers[executable2.path].trackedSources.first,
+              .compilers[executable2.path]!.trackedSources.first,
           equals(Uri.file(executable2.path)));
       expect(ResidentFrontendServer.compilers.length, 2);
     });
@@ -322,11 +321,11 @@
       expect(compileResult1['incremental'], null);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.length,
+              .compilers[executable.path]!.trackedSources.length,
           1);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.first,
+              .compilers[executable.path]!.trackedSources.first,
           equals(Uri.file(executable.path)));
 
       // switching entrypoints, packages, and modifying packages
@@ -355,10 +354,10 @@
       expect(compileResult2['returnedStoredKernel'], null);
       expect(
           ResidentFrontendServer
-              .compilers[executable2.path].trackedSources.length,
+              .compilers[executable2.path]!.trackedSources.length,
           greaterThanOrEqualTo(2));
       expect(
-          ResidentFrontendServer.compilers[executable2.path].trackedSources,
+          ResidentFrontendServer.compilers[executable2.path]!.trackedSources,
           containsAll(
               <Uri>{Uri.file(executable2.path), Uri.file(executable3.path)}));
 
@@ -374,9 +373,9 @@
       expect(compileResult3['incremental'], true);
       expect(
           ResidentFrontendServer
-              .compilers[executable2.path].trackedSources.length,
+              .compilers[executable2.path]!.trackedSources.length,
           greaterThanOrEqualTo(1));
-      expect(ResidentFrontendServer.compilers[executable2.path].trackedSources,
+      expect(ResidentFrontendServer.compilers[executable2.path]!.trackedSources,
           containsAll(<Uri>{Uri.file(executable2.path)}));
     });
 
@@ -408,11 +407,11 @@
       expect(compileResults2['incremental'], true);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.length,
+              .compilers[executable.path]!.trackedSources.length,
           1);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.first,
+              .compilers[executable.path]!.trackedSources.first,
           equals(Uri.file(executable.path)));
     });
 
@@ -507,8 +506,8 @@
   });
 
   group('Resident Frontend Server: socket tests: ', () {
-    Directory d;
-    File serverInfo;
+    late Directory d;
+    late File serverInfo;
 
     setUp(() {
       d = Directory.systemTemp.createTempSync();
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index f646a84..6263940 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -340,7 +340,7 @@
   List<Expression> annotations;
   UriReference fileUri;
   FileOffset fileOffset;
-  Byte flags (isExtensionTypeDeclaration);
+  Byte flags (isExtensionTypeDeclaration, isUnnamedExtension);
   List<TypeParameter> typeParameters;
   DartType onType;
   Option<ExtensionTypeShowHideClause> showHideClause;
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index bde22eb..a9980bc 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1543,6 +1543,7 @@
 
   // Must match serialized bit positions.
   static const int FlagExtensionTypeDeclaration = 1 << 0;
+  static const int FlagUnnamedExtension = 1 << 1;
 
   int flags = 0;
 
@@ -1592,6 +1593,16 @@
         : (flags & ~FlagExtensionTypeDeclaration);
   }
 
+  bool get isUnnamedExtension {
+    return flags & FlagUnnamedExtension != 0;
+  }
+
+  void set isUnnamedExtension(bool value) {
+    flags = value
+        ? (flags | FlagUnnamedExtension)
+        : (flags & ~FlagUnnamedExtension);
+  }
+
   @override
   R accept<R>(TreeVisitor<R> v) => v.visitExtension(this);
 
@@ -3824,93 +3835,6 @@
             .applyToFunctionType(computeThisFunctionType(nullability));
   }
 
-  /// Return function type of node returning [typedefType] reuse type parameters
-  ///
-  /// When this getter is invoked, the parent must be a [Constructor].
-  /// This getter works similarly to [computeThisFunctionType], but uses
-  /// [typedef] to compute the return type of the returned function type. It
-  /// is useful in some contexts, especially during inference of aliased
-  /// constructor invocations.
-  FunctionType computeAliasedConstructorFunctionType(
-      Typedef typedef, Library library) {
-    assert(parent is Constructor, "Only run this method on constructors");
-    Constructor parentConstructor = parent as Constructor;
-    // We need create a copy of the list of type parameters, otherwise
-    // transformations like erasure don't work.
-    List<TypeParameter> classTypeParametersCopy =
-        List.of(parentConstructor.enclosingClass.typeParameters);
-    List<TypeParameter> typedefTypeParametersCopy =
-        List.of(typedef.typeParameters);
-    List<DartType> asTypeArguments =
-        getAsTypeArguments(typedefTypeParametersCopy, library);
-    TypedefType typedefType =
-        TypedefType(typedef, library.nonNullable, asTypeArguments);
-    DartType unaliasedTypedef = typedefType.unalias;
-    assert(unaliasedTypedef is InterfaceType,
-        "[typedef] is assumed to resolve to an interface type");
-    InterfaceType targetType = unaliasedTypedef as InterfaceType;
-    Substitution substitution = Substitution.fromPairs(
-        classTypeParametersCopy, targetType.typeArguments);
-    List<DartType> positional = positionalParameters
-        .map((VariableDeclaration decl) =>
-            substitution.substituteType(decl.type))
-        .toList(growable: false);
-    List<NamedType> named = namedParameters
-        .map((VariableDeclaration decl) => NamedType(
-            decl.name!, substitution.substituteType(decl.type),
-            isRequired: decl.isRequired))
-        .toList(growable: false);
-    named.sort();
-    return FunctionType(positional, typedefType.unalias, library.nonNullable,
-        namedParameters: named,
-        typeParameters: typedefTypeParametersCopy,
-        requiredParameterCount: requiredParameterCount);
-  }
-
-  /// Return function type of node returning [typedefType] reuse type parameters
-  ///
-  /// When this getter is invoked, the parent must be a [Procedure] which is a
-  /// redirecting factory constructor. This getter works similarly to
-  /// [computeThisFunctionType], but uses [typedef] to compute the return type
-  /// of the returned function type. It is useful in some contexts, especially
-  /// during inference of aliased factory invocations.
-  FunctionType computeAliasedFactoryFunctionType(
-      Typedef typedef, Library library) {
-    assert(
-        parent is Procedure &&
-            (parent as Procedure).kind == ProcedureKind.Factory,
-        "Only run this method on a factory");
-    // We need create a copy of the list of type parameters, otherwise
-    // transformations like erasure don't work.
-    List<TypeParameter> classTypeParametersCopy = List.of(typeParameters);
-    List<TypeParameter> typedefTypeParametersCopy =
-        List.of(typedef.typeParameters);
-    List<DartType> asTypeArguments =
-        getAsTypeArguments(typedefTypeParametersCopy, library);
-    TypedefType typedefType =
-        TypedefType(typedef, library.nonNullable, asTypeArguments);
-    DartType unaliasedTypedef = typedefType.unalias;
-    assert(unaliasedTypedef is InterfaceType,
-        "[typedef] is assumed to resolve to an interface type");
-    InterfaceType targetType = unaliasedTypedef as InterfaceType;
-    Substitution substitution = Substitution.fromPairs(
-        classTypeParametersCopy, targetType.typeArguments);
-    List<DartType> positional = positionalParameters
-        .map((VariableDeclaration decl) =>
-            substitution.substituteType(decl.type))
-        .toList(growable: false);
-    List<NamedType> named = namedParameters
-        .map((VariableDeclaration decl) => NamedType(
-            decl.name!, substitution.substituteType(decl.type),
-            isRequired: decl.isRequired))
-        .toList(growable: false);
-    named.sort();
-    return FunctionType(positional, typedefType.unalias, library.nonNullable,
-        namedParameters: named,
-        typeParameters: typedefTypeParametersCopy,
-        requiredParameterCount: requiredParameterCount);
-  }
-
   @override
   R accept<R>(TreeVisitor<R> v) => v.visitFunctionNode(this);
 
@@ -8717,7 +8641,12 @@
   }
 
   @override
-  void transformOrRemoveChildren(RemovingTransformer v) {}
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    v.transformExpressionList(positional, this);
+    v.transformNamedExpressionList(named, this);
+    recordType =
+        v.visitDartType(recordType, cannotRemoveSentinel) as RecordType;
+  }
 
   @override
   String toString() {
@@ -10802,11 +10731,10 @@
   @override
   List<Expression> annotations = const <Expression>[];
 
-  /// For named parameters, this is the name of the parameter. No two named
-  /// parameters (in the same parameter list) can have the same name.
+  /// The name of the variable or parameter as provided in the source code.
   ///
-  /// In all other cases, the name is cosmetic, may be empty or null,
-  /// and is not necessarily unique.
+  /// If this variable is synthesized, for instance the variable of a [Let]
+  /// expression, the name is in most cases `null`.
   String? name;
   int flags = 0;
   DartType type; // Not null, defaults to dynamic.
@@ -13731,7 +13659,7 @@
 
 class RecordConstant extends Constant {
   final List<Constant> positional;
-  final List<ConstantRecordNamedField> named;
+  final Map<String, Constant> named;
   final RecordType recordType;
 
   RecordConstant(this.positional, this.named, this.recordType);
@@ -13742,8 +13670,8 @@
     for (final Constant entry in positional) {
       entry.acceptReference(v);
     }
-    for (final ConstantRecordNamedField entry in named) {
-      entry.value.acceptReference(v);
+    for (final Constant entry in named.values) {
+      entry.acceptReference(v);
     }
   }
 
@@ -13764,22 +13692,22 @@
   @override
   void toTextInternal(AstPrinter printer) {
     printer.write("const (");
-    for (int i = 0; i < positional.length; i++) {
-      if (i > 0) {
-        printer.write(", ");
-      }
-      printer.writeConstant(positional[i]);
+    String comma = '';
+    for (Constant entry in positional) {
+      printer.write(comma);
+      printer.writeConstant(entry);
+      comma = ', ';
     }
     if (named.isNotEmpty) {
-      if (positional.isNotEmpty) {
-        printer.write(", ");
-      }
+      printer.write(comma);
+      comma = '';
       printer.write("{");
-      for (int i = 0; i < named.length; i++) {
-        if (i > 0) {
-          printer.write(", ");
-        }
-        printer.writeConstantRecordNamedField(named[i]);
+      for (MapEntry<String, Constant> entry in named.entries) {
+        printer.write(comma);
+        printer.write(entry.key);
+        printer.write(": ");
+        printer.writeConstant(entry.value);
+        comma = ', ';
       }
       printer.write("}");
     }
@@ -13791,7 +13719,7 @@
 
   @override
   late final int hashCode = _Hash.combineFinish(recordType.hashCode,
-      _Hash.combineListHash(named, _Hash.combineListHash(positional)));
+      _Hash.combineMapHashUnordered(named, _Hash.combineListHash(positional)));
 
   @override
   bool operator ==(Object other) =>
@@ -13799,46 +13727,12 @@
       (other is RecordConstant &&
           other.recordType == recordType &&
           listEquals(other.positional, positional) &&
-          listEquals(other.named, named));
+          mapEquals(other.named, named));
 
   @override
   DartType getType(StaticTypeContext context) => recordType;
 }
 
-class ConstantRecordNamedField {
-  final String name;
-  final Constant value;
-
-  ConstantRecordNamedField(this.name, this.value);
-
-  @override
-  String toString() => "ConstantRecordNamedField(${toStringInternal()})";
-
-  @override
-  int get hashCode => _Hash.hash2(name, value);
-
-  @override
-  bool operator ==(Object other) {
-    return other is ConstantRecordNamedField &&
-        other.name == name &&
-        other.value == value;
-  }
-
-  String toStringInternal() => toText(defaultAstTextStrategy);
-
-  String toText(AstTextStrategy strategy) {
-    AstPrinter printer = new AstPrinter(strategy);
-    printer.writeConstantRecordNamedField(this);
-    return printer.getText();
-  }
-
-  void toTextInternal(AstPrinter printer) {
-    printer.write(name);
-    printer.write(": ");
-    printer.writeConstant(value);
-  }
-}
-
 class InstanceConstant extends Constant {
   final Reference classReference;
   final List<DartType> typeArguments;
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index ce5eb5a..c2b94a8 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -443,14 +443,15 @@
   Constant _readRecordConstant() {
     List<Constant> positional = _readConstantReferenceList();
     final int namedLength = readUInt30();
-    final List<ConstantRecordNamedField> named =
-        new List<ConstantRecordNamedField>.generate(namedLength, (_) {
-      final String name = readString();
+    final List<MapEntry<String, Constant>> named =
+        new List<MapEntry<String, Constant>>.generate(namedLength, (_) {
+      final String name = readStringReference();
       final Constant value = readConstantReference();
-      return new ConstantRecordNamedField(name, value);
+      return new MapEntry<String, Constant>(name, value);
     }, growable: useGrowableLists);
     final RecordType recordType = readDartType() as RecordType;
-    return new RecordConstant(positional, named, recordType);
+    return new RecordConstant(
+        positional, new Map<String, Constant>.fromEntries(named), recordType);
   }
 
   Constant _readInstanceConstant() {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 1b2a919..eba37ec 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -300,9 +300,9 @@
       writeUInt30(constant.positional.length);
       constant.positional.forEach(writeConstantReference);
       writeUInt30(constant.named.length);
-      for (final ConstantRecordNamedField namedField in constant.named) {
-        writeStringReference(namedField.name);
-        writeConstantReference(namedField.value);
+      for (final MapEntry<String, Constant> entry in constant.named.entries) {
+        writeStringReference(entry.key);
+        writeConstantReference(entry.value);
       }
       writeDartType(constant.recordType);
     } else {
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index ec38516..435684c 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -85,6 +85,9 @@
   InterfaceType? _functionLegacyRawType;
   InterfaceType? _functionNullableRawType;
   InterfaceType? _functionNonNullableRawType;
+  InterfaceType? _recordLegacyRawType;
+  InterfaceType? _recordNullableRawType;
+  InterfaceType? _recordNonNullableRawType;
   InterfaceType? _invocationLegacyRawType;
   InterfaceType? _invocationNullableRawType;
   InterfaceType? _invocationNonNullableRawType;
@@ -134,6 +137,8 @@
 
   late final Class functionClass = index.getClass('dart:core', 'Function');
 
+  late final Class recordClass = index.getClass('dart:core', 'Record');
+
   late final Class futureClass = index.getClass('dart:core', 'Future');
 
   late final Procedure futureSyncFactory =
@@ -196,9 +201,9 @@
   /// The `dart:mirrors` library, or `null` if the component does not use it.
   late final Library? mirrorsLibrary = index.tryGetLibrary('dart:mirrors');
 
-  late final Constructor noSuchMethodErrorDefaultConstructor =
+  late final Procedure noSuchMethodErrorDefaultConstructor =
       // TODO(regis): Replace 'withInvocation' with '' after dart2js is fixed.
-      index.getConstructor('dart:core', 'NoSuchMethodError', 'withInvocation');
+      index.getProcedure('dart:core', 'NoSuchMethodError', 'withInvocation');
 
   late final Class deprecatedNullClass = index.getClass('dart:core', 'Null');
 
@@ -792,6 +797,38 @@
     }
   }
 
+  InterfaceType get recordLegacyRawType {
+    return _recordLegacyRawType ??= _legacyRawTypes[recordClass] ??=
+        new InterfaceType(recordClass, Nullability.legacy, const <DartType>[]);
+  }
+
+  InterfaceType get recordNullableRawType {
+    return _recordNullableRawType ??= _nullableRawTypes[recordClass] ??=
+        new InterfaceType(
+            recordClass, Nullability.nullable, const <DartType>[]);
+  }
+
+  InterfaceType get recordNonNullableRawType {
+    return _recordNonNullableRawType ??= _nonNullableRawTypes[recordClass] ??=
+        new InterfaceType(
+            recordClass, Nullability.nonNullable, const <DartType>[]);
+  }
+
+  InterfaceType recordRawType(Nullability nullability) {
+    switch (nullability) {
+      case Nullability.legacy:
+        return recordLegacyRawType;
+      case Nullability.nullable:
+        return recordNullableRawType;
+      case Nullability.nonNullable:
+        return recordNonNullableRawType;
+      case Nullability.undetermined:
+      default:
+        throw new StateError(
+            "Unsupported nullability $nullability on an InterfaceType.");
+    }
+  }
+
   InterfaceType get invocationLegacyRawType {
     return _invocationLegacyRawType ??= _legacyRawTypes[invocationClass] ??=
         new InterfaceType(
diff --git a/pkg/kernel/lib/reference_from_index.dart b/pkg/kernel/lib/reference_from_index.dart
index 47c7260..40e9ef6 100644
--- a/pkg/kernel/lib/reference_from_index.dart
+++ b/pkg/kernel/lib/reference_from_index.dart
@@ -7,8 +7,10 @@
         Class,
         Constructor,
         Extension,
+        ExtensionMemberDescriptor,
         Field,
         Library,
+        Member,
         Name,
         Procedure,
         ProcedureKind,
@@ -98,13 +100,37 @@
       assert(_indexedClasses[c.name] == null);
       _indexedClasses[c.name] = new IndexedClass._(c, library);
     }
+    List<Extension> unnamedExtensions = [];
     for (int i = 0; i < library.extensions.length; i++) {
       Extension extension = library.extensions[i];
-      assert(_extensions[extension.name] == null);
-      _extensions[extension.name] = extension;
+      if (extension.isUnnamedExtension) {
+        unnamedExtensions.add(extension);
+      } else {
+        assert(_extensions[extension.name] == null);
+        _extensions[extension.name] = extension;
+      }
     }
     _addProcedures(library.procedures);
     _addFields(library.fields);
+
+    // Unnamed extensions and their members cannot be looked up and reused and
+    // their references should not therefore not be bound to the canonical names
+    // as it would otherwise prevent (new) unnamed extensions and member from
+    // repurposing these canonical names.
+    for (Extension extension in unnamedExtensions) {
+      extension.reference.canonicalName?.unbind();
+      for (ExtensionMemberDescriptor descriptor in extension.members) {
+        Reference reference = descriptor.member;
+        Member member = reference.asMember;
+        if (member is Field) {
+          member.fieldReference.canonicalName?.unbind();
+          member.getterReference.canonicalName?.unbind();
+          member.setterReference?.canonicalName?.unbind();
+        } else {
+          member.reference.canonicalName?.unbind();
+        }
+      }
+    }
   }
 
   Typedef? lookupTypedef(String name) => _typedefs[name];
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index 8ce437e..c470556 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -57,7 +57,7 @@
   }
 }
 
-class OccurrenceCollectorVisitor extends DartTypeVisitor<void> {
+class OccurrenceCollectorVisitor implements DartTypeVisitor<void> {
   final Set<TypeParameter> typeParameters;
   Set<TypeParameter> occurred = new Set<TypeParameter>();
 
@@ -70,11 +70,37 @@
   }
 
   @override
-  void visitInvalidType(InvalidType node);
+  void visitInvalidType(InvalidType node) {}
+
   @override
-  void visitDynamicType(DynamicType node);
+  void visitDynamicType(DynamicType node) {}
+
   @override
-  void visitVoidType(VoidType node);
+  void visitVoidType(VoidType node) {}
+
+  @override
+  void visitExtensionType(ExtensionType node) {
+    for (DartType argument in node.typeArguments) {
+      argument.accept(this);
+    }
+  }
+
+  @override
+  void visitFutureOrType(FutureOrType node) {
+    node.typeArgument.accept(this);
+  }
+
+  @override
+  void visitIntersectionType(IntersectionType node) {
+    node.left.accept(this);
+    node.right.accept(this);
+  }
+
+  @override
+  void visitNeverType(NeverType node) {}
+
+  @override
+  void visitNullType(NullType node) {}
 
   @override
   void visitInterfaceType(InterfaceType node) {
@@ -84,6 +110,16 @@
   }
 
   @override
+  void visitRecordType(RecordType node) {
+    for (DartType positional in node.positional) {
+      positional.accept(this);
+    }
+    for (NamedType named in node.named) {
+      named.type.accept(this);
+    }
+  }
+
+  @override
   void visitTypedefType(TypedefType node) {
     for (DartType argument in node.typeArguments) {
       argument.accept(this);
@@ -602,6 +638,12 @@
   }
 
   @override
+  DartType? visitRecordType(RecordType node, int variance) {
+    isOutermost = false;
+    return super.visitRecordType(node, variance);
+  }
+
+  @override
   DartType? visitFutureOrType(FutureOrType node, int variance) {
     isOutermost = false;
     // Check FutureOr-based top types.
diff --git a/pkg/kernel/lib/src/constant_replacer.dart b/pkg/kernel/lib/src/constant_replacer.dart
index 80be380..225f650 100644
--- a/pkg/kernel/lib/src/constant_replacer.dart
+++ b/pkg/kernel/lib/src/constant_replacer.dart
@@ -181,13 +181,11 @@
         (positional ??= List.of(node.positional))[i] = entry;
       }
     }
-    List<ConstantRecordNamedField>? named;
-    for (int i = 0; i < node.named.length; i++) {
-      ConstantRecordNamedField namedField = node.named[i];
-      Constant? value = visitConstant(namedField.value);
+    Map<String, Constant>? named;
+    for (MapEntry<String, Constant> entry in node.named.entries) {
+      Constant? value = visitConstant(entry.value);
       if (value != null) {
-        (named ??= List.of(node.named))[i] =
-            ConstantRecordNamedField(namedField.name, value);
+        (named ??= Map.of(node.named))[entry.key] = value;
       }
     }
     if (recordType == null && positional == null && named == null) {
diff --git a/pkg/kernel/lib/src/dart_type_equivalence.dart b/pkg/kernel/lib/src/dart_type_equivalence.dart
index 97a278d..543dde6 100644
--- a/pkg/kernel/lib/src/dart_type_equivalence.dart
+++ b/pkg/kernel/lib/src/dart_type_equivalence.dart
@@ -88,8 +88,13 @@
         if (!nodeNamedParameters.containsKey(otherName) ||
             !nodeNamedParameters[otherName]!.accept1(this, otherType)) {
           result = false;
+        } else {
+          nodeNamedParameters.remove(otherName);
         }
       }
+      if (nodeNamedParameters.isNotEmpty) {
+        result = false;
+      }
       if (!node.returnType.accept1(this, other.returnType)) {
         result = false;
       }
@@ -131,20 +136,10 @@
       while (result && nodeIndex < node.named.length) {
         NamedType nodeNamedType = node.named[nodeIndex];
         NamedType otherNamedType = other.named[otherIndex];
-        int comparisonResult =
-            nodeNamedType.name.compareTo(otherNamedType.name);
-        if (comparisonResult == 0) {
-          // nodeNamedType.name == otherNamedType.name
-          result = nodeNamedType.type.accept1(this, otherNamedType.type);
-          otherIndex++;
-          nodeIndex++;
-        } else if (comparisonResult < 0) {
-          // nodeNamedType.name < otherNamedType.name
-          nodeIndex++;
-        } else {
-          // nodeNamedType.name > otherNamedType.name
-          // 'otherNamedType.name' is not found in 'node.named'.
+        if (nodeNamedType.name != otherNamedType.name) {
           result = false;
+        } else {
+          result = nodeNamedType.type.accept1(this, otherNamedType.type);
         }
       }
 
diff --git a/pkg/kernel/lib/src/equivalence.dart b/pkg/kernel/lib/src/equivalence.dart
index 07cd0fe..284d2e6 100644
--- a/pkg/kernel/lib/src/equivalence.dart
+++ b/pkg/kernel/lib/src/equivalence.dart
@@ -4599,21 +4599,6 @@
     return result;
   }
 
-  bool checkConstantRecordNamedField(EquivalenceVisitor visitor,
-      ConstantRecordNamedField? node, Object? other) {
-    if (identical(node, other)) return true;
-    if (node is! ConstantRecordNamedField) return false;
-    if (other is! ConstantRecordNamedField) return false;
-    bool result = true;
-    if (!checkConstantRecordNamedField_name(visitor, node, other)) {
-      result = visitor.resultOnInequivalence;
-    }
-    if (!checkConstantRecordNamedField_value(visitor, node, other)) {
-      result = visitor.resultOnInequivalence;
-    }
-    return result;
-  }
-
   bool checkRecordConstant(
       EquivalenceVisitor visitor, RecordConstant? node, Object? other) {
     if (identical(node, other)) return true;
@@ -7764,24 +7749,10 @@
         node.positional, other.positional, visitor.checkNodes, 'positional');
   }
 
-  bool checkConstantRecordNamedField_name(EquivalenceVisitor visitor,
-      ConstantRecordNamedField node, ConstantRecordNamedField other) {
-    return visitor.checkValues(node.name, other.name, 'name');
-  }
-
-  bool checkConstantRecordNamedField_value(EquivalenceVisitor visitor,
-      ConstantRecordNamedField node, ConstantRecordNamedField other) {
-    return visitor.checkNodes(node.value, other.value, 'value');
-  }
-
   bool checkRecordConstant_named(
       EquivalenceVisitor visitor, RecordConstant node, RecordConstant other) {
-    return visitor.checkLists(node.named, other.named, (a, b, _) {
-      if (identical(a, b)) return true;
-      if (a is! ConstantRecordNamedField) return false;
-      if (b is! ConstantRecordNamedField) return false;
-      return checkConstantRecordNamedField(visitor, a, b);
-    }, 'named');
+    return visitor.checkMaps(node.named, other.named, visitor.matchValues,
+        visitor.checkValues, visitor.checkNodes, 'named');
   }
 
   bool checkRecordConstant_recordType(
diff --git a/pkg/kernel/lib/src/node_creator.dart b/pkg/kernel/lib/src/node_creator.dart
index bc1b8e9..a3652be 100644
--- a/pkg/kernel/lib/src/node_creator.dart
+++ b/pkg/kernel/lib/src/node_creator.dart
@@ -1266,25 +1266,25 @@
       case ConstantKind.RecordConstant:
         return _createOneOf(_pendingConstants, kind, index, [
           () => RecordConstant(
-              [], [], RecordType([], [], Nullability.nonNullable)),
+              [], {}, RecordType([], [], Nullability.nonNullable)),
           () => RecordConstant(
               [_createConstant(), _createConstant()],
-              [],
+              {},
               RecordType([_createDartType(), _createDartType()], [],
                   Nullability.nonNullable)),
           () => RecordConstant(
                   [],
-                  [
-                    ConstantRecordNamedField('a', _createConstant()),
-                    ConstantRecordNamedField('b', _createConstant())
-                  ],
+                  {
+                    'a': _createConstant(),
+                    'b': _createConstant(),
+                  },
                   RecordType([], [
                     NamedType('a', _createDartType()),
                     NamedType('b', _createDartType())
                   ], Nullability.nonNullable)),
           () => RecordConstant(
               [_createConstant()],
-              [ConstantRecordNamedField('a', _createConstant())],
+              {'a': _createConstant()},
               RecordType(
                   [_createDartType()],
                   [NamedType('a', _createDartType())],
diff --git a/pkg/kernel/lib/src/printer.dart b/pkg/kernel/lib/src/printer.dart
index 30d721b..17dd31f 100644
--- a/pkg/kernel/lib/src/printer.dart
+++ b/pkg/kernel/lib/src/printer.dart
@@ -471,10 +471,6 @@
     node.toTextInternal(this);
   }
 
-  void writeConstantRecordNamedField(ConstantRecordNamedField node) {
-    node.toTextInternal(this);
-  }
-
   /// Returns the text written to this printer.
   String getText() => _sb.toString();
 }
diff --git a/pkg/kernel/lib/src/replacement_visitor.dart b/pkg/kernel/lib/src/replacement_visitor.dart
index b1393e2..ed12e45 100644
--- a/pkg/kernel/lib/src/replacement_visitor.dart
+++ b/pkg/kernel/lib/src/replacement_visitor.dart
@@ -98,8 +98,7 @@
 
     List<DartType>? newPositional = null;
     for (int i = 0; i < node.positional.length; i++) {
-      DartType? newType = visitType(node.positional[i],
-          Variance.combine(variance, Variance.contravariant));
+      DartType? newType = visitType(node.positional[i], variance);
       if (newType != null) {
         newPositional ??= node.positional.toList(growable: false);
         newPositional[i] = newType;
@@ -107,8 +106,7 @@
     }
     List<NamedType>? newNamed = null;
     for (int i = 0; i < node.named.length; i++) {
-      DartType? newType = visitType(node.named[i].type,
-          Variance.combine(variance, Variance.contravariant));
+      DartType? newType = visitType(node.named[i].type, variance);
       NamedType? newNamedType = createNamedType(node.named[i], newType);
       if (newNamedType != null) {
         newNamed ??= node.named.toList(growable: false);
diff --git a/pkg/kernel/lib/src/standard_bounds.dart b/pkg/kernel/lib/src/standard_bounds.dart
index 9e3b8a7..3883330 100644
--- a/pkg/kernel/lib/src/standard_bounds.dart
+++ b/pkg/kernel/lib/src/standard_bounds.dart
@@ -411,6 +411,11 @@
           type1, type2, clientLibrary);
     }
 
+    if (type1 is RecordType && type2 is RecordType) {
+      return _getNullabilityAwareRecordStandardLowerBound(
+          type1, type2, clientLibrary);
+    }
+
     // DOWN(T1, T2) = T1 if T1 <: T2.
     // DOWN(T1, T2) = T2 if T2 <: T1.
 
@@ -780,6 +785,33 @@
           type1, coreTypes.objectNonNullableRawType, clientLibrary);
     }
 
+    if (type1 is RecordType) {
+      if (type2 is RecordType) {
+        return _getNullabilityAwareRecordStandardUpperBound(
+            type1, type2, clientLibrary);
+      }
+
+      if (type2 is InterfaceType && type2.classNode == coreTypes.recordClass) {
+        // UP(Record(...), Record) = Record
+        return coreTypes.recordRawType(uniteNullabilities(
+            type1.declaredNullability, type2.declaredNullability));
+      }
+
+      // UP(Record(...), T2) = UP(Object, T2)
+      return _getNullabilityAwareStandardUpperBound(
+          coreTypes.objectNonNullableRawType, type2, clientLibrary);
+    } else if (type2 is RecordType) {
+      if (type1 is InterfaceType && type1.classNode == coreTypes.recordClass) {
+        // UP(Record, Record(...)) = Record
+        return coreTypes.recordRawType(uniteNullabilities(
+            type1.declaredNullability, type2.declaredNullability));
+      }
+
+      // UP(T1, Record(...)) = UP(T1, Object)
+      return _getNullabilityAwareStandardUpperBound(
+          type1, coreTypes.objectNonNullableRawType, clientLibrary);
+    }
+
     // UP(FutureOr<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
     // UP(Future<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
     // UP(FutureOr<T1>, Future<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
@@ -1051,6 +1083,60 @@
             math.min(f.requiredParameterCount, g.requiredParameterCount));
   }
 
+  /// Computes the nullability-aware lower bound of two record types.
+  ///
+  /// The algorithm is defined as follows:
+  /// DOWN((P00, ..., P0k, Named0), (P10, ..., P1k, Named1)) =
+  ///   (P20, ..., P2k, Named2)
+  /// if:
+  ///   P2i is DOWN(P0i, P1i),
+  ///   Named0 contains R0i xi
+  ///       if Named1 contains R1i xi
+  ///   Named1 contains R1i xi
+  ///       if Named0 contains R0i xi
+  ///   Named2 contains exactly R2i xi
+  ///       for each xi in both Named0 and Named1
+  ///     where R0i xi is in Named0
+  ///     where R1i xi is in Named1
+  ///     and R2i is UP(R0i, R1i)
+  /// DOWN(Record(...), Record(...)) = Never otherwise.
+  DartType _getNullabilityAwareRecordStandardLowerBound(
+      RecordType r1, RecordType r2, Library clientLibrary) {
+    // The fallback result for whenever the following rule applies:
+    //     DOWN(Record(...), Record(...)) = Never otherwise.
+    late final DartType fallbackResult = NeverType.fromNullability(
+        intersectNullabilities(r1.declaredNullability, r2.declaredNullability));
+
+    if (r1.positional.length != r2.positional.length ||
+        r1.named.length != r2.named.length) {
+      return fallbackResult;
+    }
+
+    int positionalLength = r1.positional.length;
+    int namedLength = r1.named.length;
+
+    for (int i = 0; i < namedLength; i++) {
+      if (r1.named[i].name != r2.named[i].name) {
+        return fallbackResult;
+      }
+    }
+
+    List<DartType> positional = new List<DartType>.generate(
+        positionalLength,
+        (i) => _getNullabilityAwareStandardLowerBound(
+            r1.positional[i], r2.positional[i], clientLibrary));
+
+    List<NamedType> named = new List<NamedType>.generate(
+        namedLength,
+        (i) => new NamedType(
+            r1.named[i].name,
+            _getNullabilityAwareStandardLowerBound(
+                r1.named[i].type, r2.named[i].type, clientLibrary)));
+
+    return new RecordType(positional, named,
+        intersectNullabilities(r1.declaredNullability, r2.declaredNullability));
+  }
+
   /// Computes the nullability-aware lower bound of two function types.
   ///
   /// UP(
@@ -1219,6 +1305,63 @@
         requiredParameterCount: f.requiredParameterCount);
   }
 
+  /// Computes the nullability-aware lower bound of two record types.
+  ///
+  /// UP((P00, ... P0k, Named0), (P10, ... P1k, Named1)) =
+  ///   (P20, ..., P2k, Named2)
+  /// if:
+  ///   P2i is UP(P0i, P1i)
+  ///   Named0 contains R0i xi
+  ///       if Named1 contains R1i xi
+  ///   Named1 contains R1i xi
+  ///       if Named0 contains R0i xi
+  ///   Named2 contains exactly R2i xi
+  ///       for each xi in both Named0 and Named1
+  ///     where R0i xi is in Named0
+  ///     where R1i xi is in Named1
+  ///     and R2i is UP(R0i, R1i)
+  /// UP(Record(...), Record(...)) = Record otherwise
+  DartType _getNullabilityAwareRecordStandardUpperBound(
+      RecordType r1, RecordType r2, Library clientLibrary) {
+    // The return value for whenever the following applies:
+    //     UP(Record(...), Record(...)) = Record otherwise
+    late final DartType fallbackResult = coreTypes.recordRawType(
+        uniteNullabilities(r1.declaredNullability, r2.declaredNullability));
+
+    // Here we perform a quick check on the function types to figure out if we
+    // can compute a non-trivial upper bound for them.
+    if (r1.positional.length != r2.positional.length ||
+        r1.named.length != r2.named.length) {
+      return fallbackResult;
+    }
+
+    int positionalLength = r1.positional.length;
+    int namedLength = r1.named.length;
+
+    for (int i = 0; i < namedLength; i++) {
+      // The named parameters of record types are assumed to be sorted
+      // lexicographically.
+      if (r1.named[i].name != r2.named[i].name) {
+        return fallbackResult;
+      }
+    }
+
+    List<DartType> positional = new List<DartType>.generate(
+        positionalLength,
+        (i) => _getNullabilityAwareStandardUpperBound(
+            r1.positional[i], r2.positional[i], clientLibrary));
+
+    List<NamedType> named = new List<NamedType>.generate(
+        namedLength,
+        (i) => new NamedType(
+            r1.named[i].name,
+            _getNullabilityAwareStandardUpperBound(
+                r1.named[i].type, r2.named[i].type, clientLibrary)));
+
+    return new RecordType(positional, named,
+        uniteNullabilities(r1.declaredNullability, r2.declaredNullability));
+  }
+
   DartType _getNullabilityAwareTypeParameterStandardUpperBound(
       TypeParameterType type1, DartType type2, Library clientLibrary) {
     // UP(X1 extends B1, T2) =
@@ -1276,10 +1419,20 @@
             topType: coreTypes.objectNullableRawType,
             topFunctionType: coreTypes.functionNonNullableRawType,
             unhandledTypeHandler: (type, recursor) => false);
+    Nullability resultingNullability =
+        uniteNullabilities(type1.right.declaredNullability, type2.nullability);
+
+    // If the resulting nullability is [Nullability.undetermined], one of the
+    // types can be nullable at run time. The upper bound is supposed to be a
+    // supertype to both of the types under all conditions, so we interpret the
+    // undetermined case as [Nullability.nullable].
+    resultingNullability = resultingNullability == Nullability.undetermined
+        ? Nullability.nullable
+        : resultingNullability;
+
     return _getNullabilityAwareStandardUpperBound(
             eliminator.eliminateToGreatest(type1.right), type2, clientLibrary)
-        .withDeclaredNullability(uniteNullabilities(
-            type1.right.declaredNullability, type2.nullability));
+        .withDeclaredNullability(resultingNullability);
   }
 
   DartType _getNullabilityObliviousStandardUpperBound(
diff --git a/pkg/kernel/lib/src/types.dart b/pkg/kernel/lib/src/types.dart
index ba77a54..e79d5ce 100644
--- a/pkg/kernel/lib/src/types.dart
+++ b/pkg/kernel/lib/src/types.dart
@@ -115,6 +115,8 @@
         return relation.isFutureOrRelated(s, t, this);
       } else if (s is ExtensionType) {
         return relation.isExtensionRelated(s, t, this);
+      } else if (s is RecordType) {
+        return relation.isRecordRelated(s, t, this);
       }
     } else if (t is FunctionType) {
       const IsFunctionSubtypeOf relation = const IsFunctionSubtypeOf();
@@ -136,6 +138,8 @@
         return relation.isFutureOrRelated(s, t, this);
       } else if (s is ExtensionType) {
         return relation.isExtensionRelated(s, t, this);
+      } else if (s is RecordType) {
+        return relation.isRecordRelated(s, t, this);
       }
     } else if (t is TypeParameterType) {
       const IsTypeParameterSubtypeOf relation =
@@ -158,6 +162,8 @@
         return relation.isFutureOrRelated(s, t, this);
       } else if (s is ExtensionType) {
         return relation.isExtensionRelated(s, t, this);
+      } else if (s is RecordType) {
+        return relation.isRecordRelated(s, t, this);
       }
     } else if (t is IntersectionType) {
       const IsIntersectionSubtypeOf relation = const IsIntersectionSubtypeOf();
@@ -179,6 +185,8 @@
         return relation.isFutureOrRelated(s, t, this);
       } else if (s is ExtensionType) {
         return relation.isExtensionRelated(s, t, this);
+      } else if (s is RecordType) {
+        return relation.isRecordRelated(s, t, this);
       }
     } else if (t is TypedefType) {
       const IsTypedefSubtypeOf relation = const IsTypedefSubtypeOf();
@@ -200,6 +208,8 @@
         return relation.isFutureOrRelated(s, t, this);
       } else if (s is ExtensionType) {
         return relation.isExtensionRelated(s, t, this);
+      } else if (s is RecordType) {
+        return relation.isRecordRelated(s, t, this);
       }
     } else if (t is FutureOrType) {
       const IsFutureOrSubtypeOf relation = const IsFutureOrSubtypeOf();
@@ -221,6 +231,8 @@
         return relation.isFutureOrRelated(s, t, this);
       } else if (s is ExtensionType) {
         return relation.isExtensionRelated(s, t, this);
+      } else if (s is RecordType) {
+        return relation.isRecordRelated(s, t, this);
       }
     } else if (t is NullType) {
       const IsNullTypeSubtypeOf relation = const IsNullTypeSubtypeOf();
@@ -242,6 +254,8 @@
         return relation.isFutureOrRelated(s, t, this);
       } else if (s is ExtensionType) {
         return relation.isExtensionRelated(s, t, this);
+      } else if (s is RecordType) {
+        return relation.isRecordRelated(s, t, this);
       }
     } else if (t is NeverType) {
       const IsNeverTypeSubtypeOf relation = const IsNeverTypeSubtypeOf();
@@ -263,6 +277,32 @@
         return relation.isFutureOrRelated(s, t, this);
       } else if (s is ExtensionType) {
         return relation.isExtensionRelated(s, t, this);
+      } else if (s is RecordType) {
+        return relation.isRecordRelated(s, t, this);
+      }
+    } else if (t is RecordType) {
+      const IsRecordSubtypeOf relation = const IsRecordSubtypeOf();
+      if (s is DynamicType) {
+        return relation.isDynamicRelated(s, t, this);
+      } else if (s is VoidType) {
+        return relation.isVoidRelated(s, t, this);
+      } else if (s is InterfaceType) {
+        return relation.isInterfaceRelated(s, t, this);
+      } else if (s is FunctionType) {
+        return relation.isFunctionRelated(s, t, this);
+      } else if (s is TypeParameterType) {
+        return relation.isTypeParameterRelated(s, t, this);
+      } else if (s is IntersectionType) {
+        return relation.isIntersectionRelated(s, t, this);
+      } else if (s is IntersectionType) {
+      } else if (s is TypedefType) {
+        return relation.isTypedefRelated(s, t, this);
+      } else if (s is FutureOrType) {
+        return relation.isFutureOrRelated(s, t, this);
+      } else if (s is ExtensionType) {
+        return relation.isExtensionRelated(s, t, this);
+      } else if (s is RecordType) {
+        return relation.isRecordRelated(s, t, this);
       }
     } else if (t is ExtensionType) {
       const IsExtensionTypeSubtypeOf relation =
@@ -286,6 +326,8 @@
         return relation.isFutureOrRelated(s, t, this);
       } else if (s is ExtensionType) {
         return relation.isExtensionRelated(s, t, this);
+      } else if (s is RecordType) {
+        return relation.isRecordRelated(s, t, this);
       }
     } else {
       throw "Unhandled type: ${t.runtimeType}";
@@ -371,6 +413,8 @@
   IsSubtypeOf isTypedefRelated(TypedefType s, T t, Types types);
 
   IsSubtypeOf isExtensionRelated(ExtensionType s, T t, Types types);
+
+  IsSubtypeOf isRecordRelated(RecordType s, T t, Types types);
 }
 
 class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
@@ -447,6 +491,14 @@
       ExtensionType s, InterfaceType t, Types types) {
     return const IsSubtypeOf.never();
   }
+
+  @override
+  IsSubtypeOf isRecordRelated(RecordType s, InterfaceType t, Types types) {
+    // 'Object' is handled separately.
+    return t.classNode == types.hierarchy.coreTypes.recordClass
+        ? new IsSubtypeOf.basedSolelyOnNullabilities(s, t)
+        : const IsSubtypeOf.never();
+  }
 }
 
 class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
@@ -626,6 +678,97 @@
   IsSubtypeOf isExtensionRelated(ExtensionType s, FunctionType t, Types types) {
     return const IsSubtypeOf.never();
   }
+
+  @override
+  IsSubtypeOf isRecordRelated(RecordType s, FunctionType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+}
+
+class IsRecordSubtypeOf extends TypeRelation<RecordType> {
+  const IsRecordSubtypeOf();
+
+  @override
+  IsSubtypeOf isFunctionRelated(FunctionType s, RecordType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isInterfaceRelated(InterfaceType s, RecordType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isDynamicRelated(DynamicType s, RecordType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isFutureOrRelated(FutureOrType s, RecordType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isIntersectionRelated(
+      IntersectionType intersection, RecordType t, Types types) {
+    // Rule 12.
+    return types.performNullabilityAwareSubtypeCheck(intersection.right, t);
+  }
+
+  @override
+  IsSubtypeOf isTypeParameterRelated(
+      TypeParameterType s, RecordType t, Types types) {
+    // Rule 13.
+    return types
+        .performNullabilityAwareSubtypeCheck(s.parameter.bound, t)
+        .and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
+  }
+
+  @override
+  IsSubtypeOf isTypedefRelated(TypedefType s, RecordType t, Types types) {
+    // Rule 5.
+    return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
+  }
+
+  @override
+  IsSubtypeOf isVoidRelated(VoidType s, RecordType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isExtensionRelated(ExtensionType s, RecordType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
+
+  @override
+  IsSubtypeOf isRecordRelated(RecordType s, RecordType t, Types types) {
+    if (s.positional.length != t.positional.length ||
+        s.named.length != t.named.length) {
+      return const IsSubtypeOf.never();
+    }
+    for (int i = 0; i < s.named.length; i++) {
+      if (s.named[i].name != t.named[i].name) {
+        return const IsSubtypeOf.never();
+      }
+    }
+
+    IsSubtypeOf result = IsSubtypeOf.always();
+    for (int i = 0; i < s.positional.length; i++) {
+      result = result.and(types.performNullabilityAwareSubtypeCheck(
+          s.positional[i], t.positional[i]));
+      if (!result.isSubtypeWhenIgnoringNullabilities()) {
+        return const IsSubtypeOf.never();
+      }
+    }
+    for (int i = 0; i < s.named.length; i++) {
+      result = result.and(types.performNullabilityAwareSubtypeCheck(
+          s.named[i].type, t.named[i].type));
+      if (!result.isSubtypeWhenIgnoringNullabilities()) {
+        return const IsSubtypeOf.never();
+      }
+    }
+    return result.and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
+  }
 }
 
 class IsTypeParameterSubtypeOf extends TypeRelation<TypeParameterType> {
@@ -712,6 +855,11 @@
       ExtensionType s, TypeParameterType t, Types types) {
     return const IsSubtypeOf.never();
   }
+
+  @override
+  IsSubtypeOf isRecordRelated(RecordType s, TypeParameterType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
 }
 
 class IsTypedefSubtypeOf extends TypeRelation<TypedefType> {
@@ -763,6 +911,11 @@
   IsSubtypeOf isExtensionRelated(ExtensionType s, TypedefType t, Types types) {
     return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
   }
+
+  @override
+  IsSubtypeOf isRecordRelated(RecordType s, TypedefType t, Types types) {
+    return types.performNullabilityAwareMutualSubtypesCheck(s, t.unalias);
+  }
 }
 
 class IsFutureOrSubtypeOf extends TypeRelation<FutureOrType> {
@@ -897,6 +1050,13 @@
     return types.performNullabilityAwareSubtypeCheck(
         s, t.typeArgument.withDeclaredNullability(t.nullability));
   }
+
+  @override
+  IsSubtypeOf isRecordRelated(RecordType s, FutureOrType t, Types types) {
+    // Rule 11.
+    return types.performNullabilityAwareMutualSubtypesCheck(
+        s, t.typeArgument.withDeclaredNullability(t.nullability));
+  }
 }
 
 class IsIntersectionSubtypeOf extends TypeRelation<IntersectionType> {
@@ -962,6 +1122,11 @@
       ExtensionType s, IntersectionType t, Types types) {
     return const IsSubtypeOf.never();
   }
+
+  @override
+  IsSubtypeOf isRecordRelated(RecordType s, IntersectionType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
 }
 
 class IsNullTypeSubtypeOf implements TypeRelation<NullType> {
@@ -1017,6 +1182,11 @@
   IsSubtypeOf isExtensionRelated(ExtensionType s, NullType t, Types types) {
     return const IsSubtypeOf.never();
   }
+
+  @override
+  IsSubtypeOf isRecordRelated(RecordType s, NullType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
 }
 
 class IsNeverTypeSubtypeOf implements TypeRelation<NeverType> {
@@ -1070,6 +1240,11 @@
   IsSubtypeOf isExtensionRelated(ExtensionType s, NeverType t, Types types) {
     return const IsSubtypeOf.never();
   }
+
+  @override
+  IsSubtypeOf isRecordRelated(RecordType s, NeverType t, Types types) {
+    return const IsSubtypeOf.never();
+  }
 }
 
 class IsExtensionTypeSubtypeOf implements TypeRelation<ExtensionType> {
@@ -1131,4 +1306,9 @@
             s.typeArguments, t.typeArguments, t.extension.typeParameters)
         .and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
   }
+
+  @override
+  IsSubtypeOf isRecordRelated(RecordType s, ExtensionType t, Types types) {
+    return types.performNullabilityAwareSubtypeCheck(s, t.onType);
+  }
 }
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 5b8eca8..e8eeff0 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -542,6 +542,8 @@
   Class? concreteConstMapLiteralClass(CoreTypes coreTypes) => null;
   Class? concreteSetLiteralClass(CoreTypes coreTypes) => null;
   Class? concreteConstSetLiteralClass(CoreTypes coreTypes) => null;
+  Class? concreteRecordLiteralClass(CoreTypes coreTypes) => null;
+  Class? concreteConstRecordLiteralClass(CoreTypes coreTypes) => null;
 
   Class? concreteIntLiteralClass(CoreTypes coreTypes, int value) => null;
   Class? concreteDoubleLiteralClass(CoreTypes coreTypes, double value) => null;
diff --git a/pkg/kernel/lib/testing/mock_sdk.dart b/pkg/kernel/lib/testing/mock_sdk.dart
index d4a937b..8f0ea6d 100644
--- a/pkg/kernel/lib/testing/mock_sdk.dart
+++ b/pkg/kernel/lib/testing/mock_sdk.dart
@@ -16,4 +16,5 @@
 class Function;
 class String;
 class bool;
+class Record;
 """;
diff --git a/pkg/kernel/lib/testing/type_parser.dart b/pkg/kernel/lib/testing/type_parser.dart
index be334a5..f1e1073 100644
--- a/pkg/kernel/lib/testing/type_parser.dart
+++ b/pkg/kernel/lib/testing/type_parser.dart
@@ -211,6 +211,40 @@
   }
 }
 
+class ParsedRecordType extends ParsedType {
+  final List<ParsedType> positional;
+  final List<ParsedNamedArgument> named;
+  final ParsedNullability parsedNullability;
+
+  ParsedRecordType(this.positional, this.named, this.parsedNullability);
+
+  @override
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write("(");
+    for (int i = 0; i < positional.length; i++) {
+      if (i != 0) sb.write(", ");
+      sb.write(positional[i]);
+    }
+    if (named.isNotEmpty) {
+      if (positional.isNotEmpty) sb.write(", ");
+      sb.write("{");
+      for (int i = 0; i < named.length; i++) {
+        if (i != 0) sb.write(", ");
+        sb.write(named[i]);
+      }
+      sb.write("}");
+    }
+    sb.write(")");
+    return "$sb";
+  }
+
+  @override
+  R accept<R, A>(Visitor<R, A> visitor, A a) {
+    return visitor.visitRecordType(this, a);
+  }
+}
+
 class ParsedVoidType extends ParsedType {
   @override
   String toString() => "void";
@@ -390,7 +424,7 @@
     do {
       ParsedType type;
       if (optional("(") || optional("<")) {
-        type = parseFunctionType();
+        type = parseFunctionOrRecordType();
       } else if (optionalAdvance("void")) {
         type = new ParsedInterfaceType(
             "void", <ParsedType>[], ParsedNullability.nullable);
@@ -432,15 +466,30 @@
     return parseType();
   }
 
-  ParsedFunctionType parseFunctionType() {
+  ParsedType /* ParsedFunctionType|ParsedRecordType */
+      parseFunctionOrRecordType() {
     List<ParsedTypeVariable> typeVariables = parseTypeVariablesOpt();
     ParsedArguments arguments = parseArguments();
-    expect("-");
-    expect(">");
-    ParsedNullability parsedNullability = parseNullability();
-    ParsedType returnType = parseReturnType();
-    return new ParsedFunctionType(
-        typeVariables, returnType, arguments, parsedNullability);
+    if (optional("-")) {
+      // FunctionType.
+      expect("-");
+      expect(">");
+      ParsedNullability parsedNullability = parseNullability();
+      ParsedType returnType = parseReturnType();
+      return new ParsedFunctionType(
+          typeVariables, returnType, arguments, parsedNullability);
+    } else {
+      // RecordType.
+      if (typeVariables.isNotEmpty) {
+        throw "Type variables are detected on a record type.";
+      }
+      if (arguments.positional.isNotEmpty) {
+        throw "Records can't have optional positional fields.";
+      }
+      ParsedNullability parsedNullability = parseNullability();
+      return new ParsedRecordType(
+          arguments.required, arguments.named, parsedNullability);
+    }
   }
 
   String parseName() {
@@ -524,7 +573,7 @@
     }
     ParsedFunctionType? callableType;
     if (optionalAdvance("{")) {
-      callableType = parseFunctionType();
+      callableType = parseFunctionOrRecordType() as ParsedFunctionType?;
       expect("}");
     } else {
       expect(";");
@@ -666,6 +715,8 @@
 
   R visitFunctionType(ParsedFunctionType node, A a);
 
+  R visitRecordType(ParsedRecordType node, A a);
+
   R visitVoidType(ParsedVoidType node, A a);
 
   R visitTypeVariable(ParsedTypeVariable node, A a);
diff --git a/pkg/kernel/lib/testing/type_parser_environment.dart b/pkg/kernel/lib/testing/type_parser_environment.dart
index 9e33bfe..94698cf 100644
--- a/pkg/kernel/lib/testing/type_parser_environment.dart
+++ b/pkg/kernel/lib/testing/type_parser_environment.dart
@@ -452,6 +452,25 @@
   }
 
   @override
+  RecordType visitRecordType(
+      ParsedRecordType node, TypeParserEnvironment environment) {
+    List<DartType> positional = <DartType>[];
+    List<NamedType> named = <NamedType>[];
+    {
+      for (ParsedType positionalField in node.positional) {
+        positional.add(_parseType(positionalField, environment));
+      }
+      for (ParsedNamedArgument namedField in node.named) {
+        named.add(new NamedType(
+            namedField.name, _parseType(namedField.type, environment)));
+      }
+    }
+    named.sort();
+    return new RecordType(
+        positional, named, interpretParsedNullability(node.parsedNullability));
+  }
+
+  @override
   VoidType visitVoidType(
       ParsedVoidType node, TypeParserEnvironment environment) {
     return const VoidType();
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index aebbf73..bfb401d 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1335,6 +1335,9 @@
     if (node.isExtensionTypeDeclaration) {
       writeWord('type');
     }
+    if (node.isUnnamedExtension) {
+      writeWord('/* unnamed */');
+    }
     writeWord(getExtensionName(node));
     writeTypeParameterList(node.typeParameters);
     writeSpaced('on');
@@ -2896,6 +2899,26 @@
   }
 
   @override
+  void visitRecordConstant(RecordConstant node) {
+    writeWord('const');
+    writeSpace();
+    writeSymbol('(');
+    writeList(node.positional, writeConstantReference);
+    if (node.named.isNotEmpty) {
+      if (node.positional.isNotEmpty) writeComma();
+      writeSymbol('{');
+      writeList(node.named.entries, (MapEntry<String, Constant> entry) {
+        writeWord(entry.key);
+        writeSymbol(':');
+        writeConstantReference(entry.value);
+      });
+      writeSymbol('}');
+    }
+    writeSymbol(')');
+    endLine();
+  }
+
+  @override
   void visitInstantiationConstant(InstantiationConstant node) {
     writeIndentation();
     writeConstantReference(node);
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index d1f8dc4..08d47c0 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -312,7 +312,7 @@
 
   @override
   bool defaultDartType(DartType node) {
-    throw new UnsupportedError("Unsupported type $node (${node.runtimeType}.");
+    throw new UnsupportedError("Unsupported type $node (${node.runtimeType}).");
   }
 
   @override
@@ -651,7 +651,7 @@
   return a;
 }
 
-abstract class _TypeSubstitutor extends DartTypeVisitor<DartType> {
+abstract class _TypeSubstitutor implements DartTypeVisitor<DartType> {
   final _TypeSubstitutor? outer;
   bool covariantContext = true;
 
@@ -716,6 +716,24 @@
   }
 
   @override
+  DartType visitExtensionType(ExtensionType node) {
+    if (node.typeArguments.isEmpty) return node;
+    int before = useCounter;
+    List<DartType> typeArguments = node.typeArguments.map(visit).toList();
+    if (useCounter == before) return node;
+    return new ExtensionType(node.extension, node.nullability, typeArguments);
+  }
+
+  @override
+  DartType visitRecordType(RecordType node) {
+    int before = useCounter;
+    List<DartType> positional = node.positional.map(visit).toList();
+    List<NamedType> named = node.named.map(visitNamedType).toList();
+    if (useCounter == before) return node;
+    return new RecordType(positional, named, node.nullability);
+  }
+
+  @override
   DartType visitFutureOrType(FutureOrType node) {
     int before = useCounter;
     DartType typeArgument = node.typeArgument.accept(this);
diff --git a/pkg/kernel/test/norm_test.dart b/pkg/kernel/test/norm_test.dart
index f6cef2d..d6bde05 100644
--- a/pkg/kernel/test/norm_test.dart
+++ b/pkg/kernel/test/norm_test.dart
@@ -140,6 +140,20 @@
   check('FutureOr<FutureOr<int>?>', 'FutureOr<FutureOr<int>?>?');
   check('FutureOr<FutureOr<FutureOr<int>>?>',
       'FutureOr<FutureOr<FutureOr<int>>?>?');
+
+  check('(T, S & Never, {R foo})', '(Never, Never, {Never foo})',
+      'T extends Never, S extends Object?, R extends T');
+  check('(T, bool?, {FutureOr<Null> foo, FutureOr<dynamic> bar})',
+      '(Never, bool?, {Future<Null>? foo, dynamic bar})', 'T extends Never');
+  check('() -> List<({FutureOr<dynamic> foo})>', '() -> List<({dynamic foo})>');
+  check('<T extends Never>((T, T)) -> void',
+      '<T extends Never>((Never, Never)) -> void');
+
+  checkNormToSame('(int, {String? foo})');
+  checkNormToSame('(int, String?, {List<int> foo, T bar})', 'T extends num');
+  checkNormToSame('()');
+  checkNormToSame('(int?)');
+  checkNormToSame('List<(int, {String foo})>');
 }
 
 void check(String input, String output, [String typeParameters = '']) {
diff --git a/pkg/native_stack_traces/CHANGELOG.md b/pkg/native_stack_traces/CHANGELOG.md
index fade380..38b806b 100644
--- a/pkg/native_stack_traces/CHANGELOG.md
+++ b/pkg/native_stack_traces/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.5.3
+
+- Exported more ELF utilities for use in Dart tests.
+
 ## 0.5.2
 
 - Adjusted logic for finding the DWARF MachO file in a dSYM.
diff --git a/pkg/native_stack_traces/lib/elf.dart b/pkg/native_stack_traces/lib/elf.dart
index 31272b1..7c6e4bb 100644
--- a/pkg/native_stack_traces/lib/elf.dart
+++ b/pkg/native_stack_traces/lib/elf.dart
@@ -8,4 +8,12 @@
         isolateSymbolName,
         vmDataSymbolName,
         vmSymbolName;
-export 'src/elf.dart' show DynamicTable, DynamicTableTag, Elf, Section, Symbol;
+export 'src/elf.dart'
+    show
+        DynamicTable,
+        DynamicTableTag,
+        Elf,
+        Section,
+        Symbol,
+        SymbolBinding,
+        SymbolType;
diff --git a/pkg/native_stack_traces/lib/src/elf.dart b/pkg/native_stack_traces/lib/src/elf.dart
index 2e476fe..6e50138 100644
--- a/pkg/native_stack_traces/lib/src/elf.dart
+++ b/pkg/native_stack_traces/lib/src/elf.dart
@@ -777,23 +777,74 @@
   }
 }
 
+/// An enumeration of recognized symbol binding values used by the ELF format.
 enum SymbolBinding {
-  STB_LOCAL,
-  STB_GLOBAL,
-  STB_WEAK,
+  // We only list the standard types here, not OS-specific ones.
+  STB_LOCAL(0, 'local'),
+  STB_GLOBAL(1, 'global'),
+  STB_WEAK(2, 'weak');
+
+  final int code;
+  final String description;
+
+  const SymbolBinding(this.code, this.description);
+
+  static SymbolBinding? fromCode(int code) {
+    for (final value in values) {
+      if (value.code == code) {
+        return value;
+      }
+    }
+    return null;
+  }
 }
 
+/// An enumeration of recognized symbol types used by the ELF format.
 enum SymbolType {
-  STT_NOTYPE,
-  STT_OBJECT,
-  STT_FUNC,
+  // We only list the standard types here, not OS-specific ones.
+  STT_NOTYPE(0, 'notype'),
+  STT_OBJECT(1, 'object'),
+  STT_FUNC(2, 'function'),
+  STT_SECTION(3, 'section'),
+  STT_FILE(4, 'file'),
+  STT_COMMON(5, 'common'),
+  STT_TLS(6, 'thread-local');
+
+  final int code;
+  final String description;
+
+  const SymbolType(this.code, this.description);
+
+  static SymbolType? fromCode(int code) {
+    for (final value in values) {
+      if (value.code == code) {
+        return value;
+      }
+    }
+    return null;
+  }
 }
 
 enum SymbolVisibility {
-  STV_DEFAULT,
-  STV_INTERNAL,
-  STV_HIDDEN,
-  STV_PROTECTED,
+  // We only list the standard values here.
+  STV_DEFAULT(0, 'public'),
+  STV_INTERNAL(1, 'internal'),
+  STV_HIDDEN(2, 'hidden'),
+  STV_PROTECTED(3, 'protected');
+
+  final int code;
+  final String description;
+
+  const SymbolVisibility(this.code, this.description);
+
+  static SymbolVisibility? fromCode(int code) {
+    for (final value in values) {
+      if (value.code == code) {
+        return value;
+      }
+    }
+    return null;
+  }
 }
 
 /// A symbol in an ELF file, which names a portion of the virtual address space.
@@ -834,40 +885,20 @@
         nameIndex, info, other, sectionIndex, value, size, wordSize);
   }
 
-  SymbolBinding get bind => SymbolBinding.values[info >> 4];
-  SymbolType get type => SymbolType.values[info & 0x0f];
-  SymbolVisibility get visibility => SymbolVisibility.values[other & 0x03];
+  SymbolBinding? get bind => SymbolBinding.fromCode(info >> 4);
+  SymbolType? get type => SymbolType.fromCode(info & 0x0f);
+  SymbolVisibility? get visibility => SymbolVisibility.fromCode(other & 0x03);
 
   void writeToStringBuffer(StringBuffer buffer) {
     buffer
       ..write('"')
       ..write(name)
-      ..write('" =>');
-    switch (bind) {
-      case SymbolBinding.STB_GLOBAL:
-        buffer.write(' a global');
-        break;
-      case SymbolBinding.STB_LOCAL:
-        buffer.write(' a local');
-        break;
-      case SymbolBinding.STB_WEAK:
-        buffer.write(' a weak');
-        break;
-    }
-    switch (visibility) {
-      case SymbolVisibility.STV_DEFAULT:
-        break;
-      case SymbolVisibility.STV_HIDDEN:
-        buffer.write(' hidden');
-        break;
-      case SymbolVisibility.STV_INTERNAL:
-        buffer.write(' internal');
-        break;
-      case SymbolVisibility.STV_PROTECTED:
-        buffer.write(' protected');
-        break;
-    }
-    buffer
+      ..write('" => a ')
+      ..write(bind?.description ?? '<binding unrecognized>')
+      ..write(' ')
+      ..write(type?.description ?? '<type unrecognized>')
+      ..write(' ')
+      ..write(visibility?.description ?? '<visibility unrecognized>')
       ..write(' symbol that points to ')
       ..write(size)
       ..write(' bytes at location 0x')
@@ -1087,6 +1118,17 @@
     return null;
   }
 
+  /// Returns an iterable of the symbols in the dynamic symbol table(s).
+  /// The ordering of the symbols is not guaranteed.
+  Iterable<Symbol> get dynamicSymbols sync* {
+    for (final section in namedSections('.dynsym')) {
+      final dynsym = section as SymbolTable;
+      for (final symbol in dynsym.values) {
+        yield symbol;
+      }
+    }
+  }
+
   /// Reverse lookup of the static symbol that contains the given virtual
   /// address. Returns null if no static symbol matching the address is found.
   @override
@@ -1109,6 +1151,17 @@
     return bestSym;
   }
 
+  /// Returns an iterable of the symbols in the static symbol table(s).
+  /// The ordering of the symbols is not guaranteed.
+  Iterable<Symbol> get staticSymbols sync* {
+    for (final section in namedSections('.symtab')) {
+      final symtab = section as SymbolTable;
+      for (final symbol in symtab.values) {
+        yield symbol;
+      }
+    }
+  }
+
   /// Creates an [Elf] from the data pointed to by [reader].
   ///
   /// After succesful completion, the [endian] and [wordSize] fields of the
diff --git a/pkg/native_stack_traces/pubspec.yaml b/pkg/native_stack_traces/pubspec.yaml
index 0f6a22b..39174a6 100644
--- a/pkg/native_stack_traces/pubspec.yaml
+++ b/pkg/native_stack_traces/pubspec.yaml
@@ -1,5 +1,5 @@
 name: native_stack_traces
-version: 0.5.2
+version: 0.5.3
 description: Utilities for working with non-symbolic stack traces.
 repository: https://github.com/dart-lang/sdk/tree/main/pkg/native_stack_traces
 
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index 7a295e2..270028e 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -37,7 +37,7 @@
   factory CodeReference.fromElement(Element element) {
     var unitElement = element.thisOrAncestorOfType<CompilationUnitElement>();
     if (unitElement == null) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement is LibraryElement) {
         unitElement = enclosingElement.definingCompilationUnit;
       } else {
@@ -76,7 +76,7 @@
       if (elementName != null) {
         parts.add(elementName);
       }
-      element = element.enclosingElement3;
+      element = element.enclosingElement;
     }
     if (parts.isEmpty) return null;
     return parts.reversed.join('.');
@@ -96,7 +96,7 @@
       if (nodeName != null) {
         parts.add(nodeName);
       } else if (parts.isEmpty && node is VariableDeclarationList) {
-        parts.add(node.variables.first.declaredElement2!.name);
+        parts.add(node.variables.first.declaredElement!.name);
       }
       node = node.parent;
     }
@@ -106,9 +106,9 @@
 
   static String? _computeNodeDeclarationName(AstNode node) {
     if (node is ExtensionDeclaration) {
-      return node.declaredElement2?.name ?? '<unnamed extension>';
+      return node.declaredElement?.name ?? '<unnamed extension>';
     } else if (node is Declaration) {
-      var name = node.declaredElement2?.name;
+      var name = node.declaredElement?.name;
       return name == '' ? '<unnamed>' : name;
     } else {
       return null;
diff --git a/pkg/nnbd_migration/lib/src/decorated_type.dart b/pkg/nnbd_migration/lib/src/decorated_type.dart
index 8700003..a4c032a 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type.dart
@@ -173,7 +173,7 @@
   /// during comparison of generic function types.
   DecoratedType._forTypeParameterSubstitution(TypeParameterElement parameter)
       : type = TypeParameterTypeImpl(
-          element: parameter,
+          element2: parameter,
           nullabilitySuffix: NullabilitySuffix.star,
         ),
         node = null,
@@ -184,8 +184,8 @@
     // We'll be storing the type parameter bounds in
     // [_decoratedTypeParameterBounds] so the type parameter needs to have an
     // enclosing element of `null`.
-    assert(parameter.enclosingElement3 == null,
-        '$parameter should not have parent ${parameter.enclosingElement3}');
+    assert(parameter.enclosingElement == null,
+        '$parameter should not have parent ${parameter.enclosingElement}');
   }
 
   /// If `this` represents an interface type, returns the substitution necessary
@@ -414,7 +414,7 @@
             Map<TypeParameterElement, DecoratedType>.from(substitution);
         for (int i = 0; i < typeFormals.length; i++) {
           // Check if it's a fresh type variable.
-          if (undecoratedResult.typeFormals[i].enclosingElement3 == null) {
+          if (undecoratedResult.typeFormals[i].enclosingElement == null) {
             substitution[typeFormals[i]] =
                 DecoratedType._forTypeParameterSubstitution(
                     undecoratedResult.typeFormals[i]);
@@ -541,7 +541,7 @@
   final _parentedBounds = <TypeParameterElement, DecoratedType?>{};
 
   DecoratedType? get(TypeParameterElement element) {
-    if (element.enclosingElement3 == null) {
+    if (element.enclosingElement == null) {
       return _orphanBounds[element];
     } else {
       return _parentedBounds[element];
@@ -549,7 +549,7 @@
   }
 
   void put(TypeParameterElement element, DecoratedType? bounds) {
-    if (element.enclosingElement3 == null) {
+    if (element.enclosingElement == null) {
       _orphanBounds[element] = bounds;
     } else {
       _parentedBounds[element] = bounds;
diff --git a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
index ed1af08..aaaaa04 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
@@ -67,6 +67,13 @@
   }
 
   @override
+  bool isPropertyPromotable(Object property) {
+    // TODO(paulberry): research whether we would get higher quality migrations
+    // if we returned `true` instead.
+    return false;
+  }
+
+  @override
   bool isSameType(DecoratedType type1, DecoratedType type2) {
     return type1 == type2;
   }
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 8026a01..31fe047 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -161,9 +161,9 @@
 
   FunctionExpression? _currentFunctionExpression;
 
-  /// The [ClassElement] or [ExtensionElement] of the current class or extension
-  /// being visited, or null.
-  Element? _currentClassOrExtension;
+  /// The [InterfaceElement] or [ExtensionElement] of the current interface
+  /// or extension being visited, or null.
+  Element? _currentInterfaceOrExtension;
 
   /// If an extension declaration is being visited, the decorated type of the
   /// type appearing in the `on` clause (this is the type of `this` inside the
@@ -285,8 +285,8 @@
     Map<TypeParameterElement, DecoratedType?>? substitution;
     Element? baseElement = element.declaration;
     if (targetType != null) {
-      var enclosingElement = baseElement!.enclosingElement3;
-      if (enclosingElement is ClassElement) {
+      var enclosingElement = baseElement!.enclosingElement;
+      if (enclosingElement is InterfaceElement) {
         if (targetType.type.explicitBound is InterfaceType &&
             enclosingElement.typeParameters.isNotEmpty) {
           substitution = _decoratedClassHierarchy!
@@ -479,8 +479,8 @@
       var assignee =
           getWriteOrReadElement(node.leftHandSide as SimpleIdentifier)!;
       var enclosingElementOfCurrentFunction =
-          _currentFunctionExpression!.declaredElement!.enclosingElement3;
-      if (enclosingElementOfCurrentFunction == assignee.enclosingElement3) {
+          _currentFunctionExpression!.declaredElement!.enclosingElement;
+      if (enclosingElementOfCurrentFunction == assignee.enclosingElement) {
         // [node]'s enclosing function is a function expression passed directly
         // to a call to the test package's `setUp` function, and [node] is an
         // assignment to a variable declared in the same scope as the call to
@@ -674,7 +674,7 @@
         node is ExtensionDeclaration ||
         node is MixinDeclaration);
     try {
-      _currentClassOrExtension = node.declaredElement2;
+      _currentInterfaceOrExtension = node.declaredElement;
 
       List<ClassMember> members;
       if (node is ClassDeclaration) {
@@ -690,12 +690,11 @@
           if (member is FieldDeclaration &&
               _variables.getLateHint(source, member.fields) == null)
             for (var field in member.fields.variables)
-              if (!field.declaredElement2!.isStatic &&
-                  field.initializer == null)
-                (field.declaredElement2 as FieldElement?)
+              if (!field.declaredElement!.isStatic && field.initializer == null)
+                (field.declaredElement as FieldElement?)
       };
-      if (_currentClassOrExtension is ClassElement &&
-          (_currentClassOrExtension as ClassElement)
+      if (_currentInterfaceOrExtension is ClassElement &&
+          (_currentInterfaceOrExtension as ClassElement)
                   .unnamedConstructor
                   ?.isSynthetic ==
               true) {
@@ -705,7 +704,7 @@
       _dispatchList(members);
       _fieldsNotInitializedAtDeclaration = null;
     } finally {
-      _currentClassOrExtension = null;
+      _currentInterfaceOrExtension = null;
     }
     return null;
   }
@@ -715,7 +714,7 @@
     _dispatch(node.superclass);
     _dispatch(node.implementsClause);
     _dispatch(node.withClause);
-    var classElement = node.declaredElement2!;
+    var classElement = node.declaredElement!;
     var supertype = classElement.supertype!;
     var superElement = supertype.element2;
     for (var constructorElement in classElement.constructors) {
@@ -809,7 +808,7 @@
     _dispatch(node.redirectedConstructor?.type.typeArguments);
     _handleExecutableDeclaration(
         node,
-        node.declaredElement2!,
+        node.declaredElement!,
         node.metadata,
         null,
         node.parameters,
@@ -855,7 +854,7 @@
         // Nothing to do; assume the implicit default value of `null` will never
         // be reached.
       } else {
-        var enclosingElement = declaredElement.enclosingElement3;
+        var enclosingElement = declaredElement.enclosingElement;
         if (enclosingElement is ConstructorElement &&
             enclosingElement.isFactory &&
             enclosingElement.redirectedConstructor != null) {
@@ -1000,7 +999,7 @@
         _flowAnalysis = null;
         _assignedVariables = null;
       }
-      var declaredElement = node.declaredElement2;
+      var declaredElement = node.declaredElement;
       if (declaredElement is PropertyAccessorElement) {
         if (declaredElement.isGetter) {
           var setter = declaredElement.correspondingSetter;
@@ -1224,7 +1223,7 @@
   DecoratedType visitInstanceCreationExpression(
       InstanceCreationExpression node) {
     var callee = node.constructorName.staticElement!;
-    var typeParameters = callee.enclosingElement3.typeParameters;
+    var typeParameters = callee.enclosingElement.typeParameters;
     Iterable<DartType?> typeArgumentTypes;
     List<DecoratedType> decoratedTypeArguments;
     var typeArguments = node.constructorName.type.typeArguments;
@@ -1373,12 +1372,12 @@
     if (BuiltValueTransformer.findNullableAnnotation(node) != null) {
       _graph.makeNullable(
           _variables
-              .decoratedElementType(node.declaredElement2!.declaration)
+              .decoratedElementType(node.declaredElement!.declaration)
               .returnType!
               .node!,
           BuiltValueNullableOrigin(source, node));
     }
-    _handleExecutableDeclaration(node, node.declaredElement2!, node.metadata,
+    _handleExecutableDeclaration(node, node.declaredElement!, node.metadata,
         node.returnType, node.parameters, null, node.body, null);
     _dispatch(node.typeParameters);
     return null;
@@ -1405,7 +1404,7 @@
       } else {
         targetType = _handleTarget(target, node.methodName.name, callee);
       }
-    } else if (target == null && callee!.enclosingElement3 is ClassElement) {
+    } else if (target == null && callee!.enclosingElement is ClassElement) {
       targetType = _thisOrSuper(node);
       _checkThisNotNull(targetType, node);
     }
@@ -1812,13 +1811,13 @@
     } else if (staticElement is FunctionElement ||
         staticElement is MethodElement ||
         staticElement is ConstructorElement) {
-      if (staticElement!.enclosingElement3 is ClassElement) {
+      if (staticElement!.enclosingElement is ClassElement) {
         targetType = _thisOrSuper(node);
       }
       result =
           getOrComputeElementType(node, staticElement, targetType: targetType);
     } else if (staticElement is PropertyAccessorElement) {
-      if (staticElement.enclosingElement3 is ClassElement) {
+      if (staticElement.enclosingElement is ClassElement) {
         targetType = _thisOrSuper(node);
       }
       var elementType =
@@ -1833,8 +1832,8 @@
     } else if (staticElement == null) {
       assert(node.toString() == 'void', "${node.toString()} != 'void'");
       result = _makeNullableVoidType(node);
-    } else if (staticElement.enclosingElement3 is ClassElement &&
-        staticElement.enclosingElement3 is EnumElement) {
+    } else if (staticElement.enclosingElement is ClassElement &&
+        staticElement.enclosingElement is EnumElement) {
       result = getOrComputeElementType(node, staticElement);
     } else {
       // TODO(paulberry)
@@ -1900,7 +1899,7 @@
     var nullabilityNode = NullabilityNode.forInferredType(target);
     var class_ = node.thisOrAncestorOfType<ClassDeclaration>()!;
     var decoratedSupertype = _decoratedClassHierarchy!.getDecoratedSupertype(
-        class_.declaredElement2!, callee.enclosingElement3);
+        class_.declaredElement!, callee.enclosingElement);
     var typeArguments = decoratedSupertype.typeArguments;
     Iterable<DartType?> typeArgumentTypes;
     typeArgumentTypes = typeArguments.map((t) => t!.type);
@@ -1908,7 +1907,7 @@
         typeArguments: typeArguments);
     var calleeType =
         getOrComputeElementType(node, callee, targetType: createdType);
-    var constructorTypeParameters = callee.enclosingElement3.typeParameters;
+    var constructorTypeParameters = callee.enclosingElement.typeParameters;
 
     _handleInvocationArguments(
         node,
@@ -1933,7 +1932,11 @@
     for (var member in node.members) {
       _postDominatedLocals.doScoped(action: () {
         var hasLabel = member.labels.isNotEmpty;
-        _flowAnalysis!.switchStatement_beginCase(hasLabel, node);
+        _flowAnalysis!.switchStatement_beginCase();
+        _flowAnalysis!.switchStatement_beginAlternatives();
+        _flowAnalysis!.switchStatement_endAlternative();
+        _flowAnalysis!
+            .switchStatement_endAlternatives(node, hasLabels: hasLabel);
         if (member is SwitchCase) {
           _dispatch(member.expression);
         } else {
@@ -2004,7 +2007,7 @@
     for (var variable in node.variables) {
       _dispatchList(variable.metadata);
       var initializer = variable.initializer;
-      var declaredElement = variable.declaredElement2!;
+      var declaredElement = variable.declaredElement!;
       if (isTopLevel) {
         assert(_flowAnalysis == null);
         _createFlowAnalysis(variable, null);
@@ -2016,7 +2019,7 @@
         }
       }
       var type = _variables.decoratedElementType(declaredElement);
-      var enclosingElement = declaredElement.enclosingElement3;
+      var enclosingElement = declaredElement.enclosingElement;
       if (!declaredElement.isStatic && enclosingElement is ClassElement) {
         var overriddenElements = _inheritanceManager.getOverridden2(
             enclosingElement,
@@ -2076,7 +2079,7 @@
     //
     // We cannot make a hard edge from y to never in this case.
     if (node.variables.length == 1) {
-      _postDominatedLocals.add(node.variables.single.declaredElement2!);
+      _postDominatedLocals.add(node.variables.single.declaredElement!);
     }
 
     return null;
@@ -2580,7 +2583,7 @@
   void _handleConstructorRedirection(
       FormalParameterList parameters, ConstructorName redirectedConstructor) {
     var callee = redirectedConstructor.staticElement!.declaration;
-    var redirectedClass = callee.enclosingElement3;
+    var redirectedClass = callee.enclosingElement;
     var calleeType = _variables.decoratedElementType(callee);
     var typeArguments = redirectedConstructor.type.typeArguments;
     var typeArgumentTypes =
@@ -2599,7 +2602,7 @@
     if (node.argumentList.arguments.isNotEmpty &&
         callee is ExecutableElement &&
         callee.isStatic) {
-      var enclosingElement = callee.enclosingElement3;
+      var enclosingElement = callee.enclosingElement;
       if (enclosingElement is ClassElement) {
         if (callee.name == 'checkNotNull' &&
                 enclosingElement.name == 'ArgumentError' &&
@@ -2644,7 +2647,7 @@
     _addParametersToFlowAnalysis(parameters);
     // Push a scope of post-dominated declarations on the stack.
     _postDominatedLocals.pushScope(elements: declaredElement.parameters);
-    if (declaredElement.enclosingElement3 is ExtensionElement) {
+    if (declaredElement.enclosingElement is ExtensionElement) {
       _postDominatedLocals.add(_extensionThis);
     }
     try {
@@ -2659,7 +2662,7 @@
         _handleConstructorRedirection(parameters!, redirectedConstructor);
       }
       if (declaredElement is! ConstructorElement) {
-        var enclosingElement = declaredElement.enclosingElement3;
+        var enclosingElement = declaredElement.enclosingElement;
         if (enclosingElement is ClassElement) {
           var overriddenElements = _inheritanceManager.getOverridden2(
               enclosingElement,
@@ -2746,7 +2749,7 @@
       ClassElement classElement,
       Element overriddenElement) {
     overriddenElement = overriddenElement.declaration!;
-    var overriddenClass = overriddenElement.enclosingElement3 as ClassElement;
+    var overriddenClass = overriddenElement.enclosingElement as ClassElement;
     var decoratedSupertype = _decoratedClassHierarchy!
         .getDecoratedSupertype(classElement, overriddenClass);
     var substitution = decoratedSupertype.asSubstitution;
@@ -2847,7 +2850,8 @@
       ClassElement classElement,
       Element overriddenElement) {
     overriddenElement = overriddenElement.declaration!;
-    var overriddenClass = overriddenElement.enclosingElement3 as ClassElement;
+    var overriddenClass =
+        overriddenElement.enclosingElement as InterfaceElement;
     var decoratedSupertype = _decoratedClassHierarchy!
         .getDecoratedSupertype(classElement, overriddenClass);
     var substitution = decoratedSupertype.asSubstitution;
@@ -2905,7 +2909,7 @@
       Element? lhsElement;
       DecoratedType? lhsType;
       if (parts is ForEachPartsWithDeclaration) {
-        var variableElement = parts.loopVariable.declaredElement2!;
+        var variableElement = parts.loopVariable.declaredElement!;
         _flowAnalysis!.declare(variableElement, true);
         lhsElement = variableElement;
         _dispatch(parts.loopVariable.type);
@@ -2978,13 +2982,13 @@
     Map<TypeParameterElement, DecoratedType?> getterSubstitution = const {};
     Map<TypeParameterElement, DecoratedType?> setterSubstitution = const {};
     if (class_ != null) {
-      var getterClass = getter.enclosingElement3 as ClassElement;
+      var getterClass = getter.enclosingElement as ClassElement;
       if (!identical(class_, getterClass)) {
         getterSubstitution = _decoratedClassHierarchy!
             .getDecoratedSupertype(class_, getterClass)
             .asSubstitution;
       }
-      var setterClass = setter.enclosingElement3 as ClassElement;
+      var setterClass = setter.enclosingElement as ClassElement;
       if (!identical(class_, setterClass)) {
         setterSubstitution = _decoratedClassHierarchy!
             .getDecoratedSupertype(class_, setterClass)
@@ -3120,7 +3124,7 @@
     if (target is SimpleIdentifier) {
       var targetElement = target.staticElement;
       if (targetElement is ParameterElement &&
-          targetElement.enclosingElement3 == _currentExecutable &&
+          targetElement.enclosingElement == _currentExecutable &&
           !_currentExecutable!.name.startsWith('_')) {
         _graph.makeNullable(
             _variables.decoratedElementType(targetElement).node!,
@@ -3254,7 +3258,7 @@
     if (isDeclaredOnObject(name)) {
       return _dispatch(target);
     } else if ((callee is MethodElement || callee is PropertyAccessorElement) &&
-        callee!.enclosingElement3 is ExtensionElement) {
+        callee!.enclosingElement is ExtensionElement) {
       // Extension methods can be called on a `null` target, when the `on` type
       // of the extension is nullable.  Note: we don't need to check whether the
       // target type is assignable to the extended type; that is done in
@@ -3459,7 +3463,7 @@
   }
 
   DecoratedType? _thisOrSuper(Expression node) {
-    if (_currentClassOrExtension == null) {
+    if (_currentInterfaceOrExtension == null) {
       return null;
     }
 
@@ -3473,8 +3477,8 @@
     var token = node.beginToken.lexeme;
     var target =
         NullabilityNodeTarget.text('$token expression').withCodeRef(node);
-    if (_currentClassOrExtension is ClassElement) {
-      final type = (_currentClassOrExtension as ClassElement).thisType;
+    if (_currentInterfaceOrExtension is InterfaceElement) {
+      final type = (_currentInterfaceOrExtension as InterfaceElement).thisType;
 
       // Instantiate the type, and any type arguments, with non-nullable types,
       // because the type of `this` is always `ClassName<Param, Param, ...>`
@@ -3488,7 +3492,7 @@
                   t, makeNonNullableNode(target.typeArgument(index++))))
               .toList());
     } else {
-      assert(_currentClassOrExtension is ExtensionElement);
+      assert(_currentInterfaceOrExtension is ExtensionElement);
       assert(_currentExtendedType != null);
       return _currentExtendedType;
     }
diff --git a/pkg/nnbd_migration/lib/src/fix_aggregator.dart b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
index 356da031..4014018 100644
--- a/pkg/nnbd_migration/lib/src/fix_aggregator.dart
+++ b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
@@ -1013,23 +1013,29 @@
 /// Common infrastructure used by [NodeChange] objects that operate on AST nodes
 /// with that can be null-aware (method invocations and propety accesses).
 mixin NodeChangeForNullAware<N extends Expression> on NodeChange<N> {
-  /// Indicates whether null-awareness should be removed.
-  bool removeNullAwareness = false;
+  /// Indicates how null-awareness should be handled.
+  NullAwarenessRemovalType nullAwarenessRemoval = NullAwarenessRemovalType.none;
 
   @override
-  Iterable<String> get _toStringParts =>
-      [...super._toStringParts, if (removeNullAwareness) 'removeNullAwareness'];
+  Iterable<String> get _toStringParts => [
+        ...super._toStringParts,
+        if (nullAwarenessRemoval == NullAwarenessRemovalType.strong)
+          'removeNullAwareness (strong)'
+        else if (nullAwarenessRemoval == NullAwarenessRemovalType.weak)
+          'removeNullAwareness (weak)'
+      ];
 
   /// Returns an [EditPlan] that removes null awareness, if appropriate.
   /// Otherwise returns `null`.
   EditPlan? _applyNullAware(N node, FixAggregator aggregator) {
-    if (!removeNullAwareness) return null;
-    var description = aggregator._warnOnWeakCode
+    if (nullAwarenessRemoval == NullAwarenessRemovalType.none) return null;
+    var weak = aggregator._warnOnWeakCode &&
+        nullAwarenessRemoval == NullAwarenessRemovalType.weak;
+    var description = weak
         ? NullabilityFixDescription.nullAwarenessUnnecessaryInStrongMode
         : NullabilityFixDescription.removeNullAwareness;
     return aggregator.planner.removeNullAwareness(node,
-        info: AtomicEditInfo(description, const {}),
-        isInformative: aggregator._warnOnWeakCode);
+        info: AtomicEditInfo(description, const {}), isInformative: weak);
   }
 }
 
@@ -1366,6 +1372,19 @@
   String describe() => 'NoValidMigrationChange';
 }
 
+/// Enum used by [NodeChangeForNullAware] to indicate how null awareness should
+/// be handled.
+enum NullAwarenessRemovalType {
+  /// Do not remove null awareness.
+  none,
+
+  /// If warning on weak code, issue a warning; otherwise remove null awareness.
+  weak,
+
+  /// Remove null awareness unconditionally.
+  strong,
+}
+
 /// [ExpressionChange] describing the addition of an `!` after an expression.
 class NullCheckChange extends ExpressionChange {
   /// The hint that is causing this `!` to be added, if any.
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index ae11d8e..0cfe32c 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -266,6 +266,20 @@
     }
   }
 
+  /// If [node] is a property access or method invocation, returns the element
+  /// it invokes.  Otherwise returns `null`.
+  Element? _findPropertyOrMethodElement(Expression node) {
+    if (node is PrefixedIdentifier) {
+      return node.identifier.staticElement;
+    } else if (node is PropertyAccess) {
+      return node.propertyName.staticElement;
+    } else if (node is MethodInvocation) {
+      return node.methodName.staticElement;
+    } else {
+      return null;
+    }
+  }
+
   /// Returns the [NodeChange] object accumulating changes for the given [node],
   /// creating it if necessary.
   NodeChange _getChange(AstNode node) =>
@@ -284,7 +298,18 @@
       throw StateError('Unexpected expression type: ${node.runtimeType}');
     }
     if (!_typeSystem.isPotentiallyNullable(target!.staticType!)) {
-      (_getChange(node) as NodeChangeForNullAware).removeNullAwareness = true;
+      var element = _findPropertyOrMethodElement(target);
+      if (element != null) {
+        var library = element.library;
+        if (library!.isNonNullableByDefault &&
+            !_graph.isBeingMigrated(library.source)) {
+          (_getChange(node) as NodeChangeForNullAware).nullAwarenessRemoval =
+              NullAwarenessRemovalType.strong;
+          return false;
+        }
+      }
+      (_getChange(node) as NodeChangeForNullAware).nullAwarenessRemoval =
+          NullAwarenessRemovalType.weak;
       return false;
     }
     return true;
@@ -467,7 +492,7 @@
           return variable.typeInternal;
         }
         if (variable is ParameterElement) {
-          var enclosingElement = variable.enclosingElement3;
+          var enclosingElement = variable.enclosingElement;
           if (enclosingElement is PropertyAccessorElement &&
               enclosingElement.isSynthetic) {
             // This is the parameter of a synthetic getter, so it has the same
@@ -502,7 +527,7 @@
   /// on a nullable type without introducing a null check).
   bool isNullableExtensionMember(Element? element) {
     if (element != null) {
-      var enclosingElement = element.enclosingElement3;
+      var enclosingElement = element.enclosingElement;
       if (enclosingElement is ExtensionElement) {
         return _fixBuilder._typeSystem
             .isPotentiallyNullable(enclosingElement.extendedType);
@@ -701,7 +726,7 @@
   }
 
   InterfaceType _getClassInterface(
-      ClassElement class_, InterfaceElement superclass) {
+      InterfaceElement class_, InterfaceElement superclass) {
     var decoratedSupertype = _fixBuilder._decoratedClassHierarchy!
         .getDecoratedSupertype(class_, superclass);
     var finalType = _fixBuilder._variables!.toFinalType(decoratedSupertype);
@@ -1139,7 +1164,7 @@
       bool explicitTypeNeeded = false;
       for (var variableDeclaration in node.variables) {
         var neededType = _fixBuilder
-            ._computeMigratedType(variableDeclaration.declaredElement2!);
+            ._computeMigratedType(variableDeclaration.declaredElement!);
         neededTypes.add(neededType);
         var inferredType = variableDeclaration.initializer?.staticType ??
             _fixBuilder.typeProvider.dynamicType;
@@ -1177,7 +1202,7 @@
     // Check if the nullability node for a single variable declaration has been
     // declared to be late.
     if (node.variables.length == 1) {
-      var variableElement = node.variables.single.declaredElement2!;
+      var variableElement = node.variables.single.declaredElement!;
       var lateCondition = _fixBuilder._variables!
           .decoratedElementType(variableElement)
           .node!
@@ -1253,7 +1278,7 @@
       var nullabilityNode =
           _fixBuilder._variables!.decoratedElementType(element!).node!;
       if (!nullabilityNode.isNullable) {
-        var enclosingElement = element.enclosingElement3;
+        var enclosingElement = element.enclosingElement;
         if (enclosingElement is ConstructorElement &&
             enclosingElement.isFactory &&
             enclosingElement.redirectedConstructor != null &&
@@ -1366,8 +1391,8 @@
     // Change an existing `@required` annotation into a `required` keyword if
     // possible.
     final element = parameter.declaredElement!;
-    final method = element.enclosingElement3!;
-    final cls = method.enclosingElement3!;
+    final method = element.enclosingElement!;
+    final cls = method.enclosingElement!;
     var info = AtomicEditInfo(
         NullabilityFixDescription.addRequired(
             cls.name, method.name, element.name),
diff --git a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
index 6e5e0e1..beb0e96 100644
--- a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
@@ -560,7 +560,7 @@
         enclosingNode != null;
         enclosingNode = enclosingNode.parent) {
       if (enclosingNode is ConstructorDeclaration) {
-        if (enclosingNode.name2 == null) {
+        if (enclosingNode.name == null) {
           return _describeClassOrExtensionMember(
               enclosingNode.parent as CompilationUnitMember?,
               'the default constructor of',
@@ -569,10 +569,10 @@
           return _describeClassOrExtensionMember(
               enclosingNode.parent as CompilationUnitMember?,
               'the constructor',
-              enclosingNode.name2!.lexeme);
+              enclosingNode.name!.lexeme);
         }
       } else if (enclosingNode is MethodDeclaration) {
-        var functionName = enclosingNode.name2.lexeme;
+        var functionName = enclosingNode.name.lexeme;
         String baseDescription;
         if (enclosingNode.isGetter) {
           baseDescription = 'the getter';
@@ -590,7 +590,7 @@
             functionName);
       } else if (enclosingNode is FunctionDeclaration &&
           enclosingNode.parent is CompilationUnit) {
-        var functionName = enclosingNode.name2.lexeme;
+        var functionName = enclosingNode.name.lexeme;
         String baseDescription;
         if (enclosingNode.isGetter) {
           baseDescription = 'the getter';
@@ -617,20 +617,20 @@
   static String _describeClassOrExtensionMember(CompilationUnitMember? parent,
       String baseDescription, String functionName) {
     if (parent is NamedCompilationUnitMember) {
-      var parentName = parent.name2.lexeme;
+      var parentName = parent.name.lexeme;
       if (functionName.isEmpty) {
         return "$baseDescription '$parentName'";
       } else {
         return "$baseDescription '$parentName.$functionName'";
       }
     } else if (parent is ExtensionDeclaration) {
-      if (parent.name2 == null) {
+      if (parent.name == null) {
         var extendedTypeString = parent.extendedType.type!.getDisplayString(
           withNullability: false,
         );
         return "$baseDescription '$functionName' in unnamed extension on $extendedTypeString";
       } else {
-        return "$baseDescription '${parent.name2!.lexeme}.$functionName'";
+        return "$baseDescription '${parent.name!.lexeme}.$functionName'";
       }
     } else {
       throw ArgumentError(
@@ -639,7 +639,7 @@
   }
 
   static String? _describeVariableDeclaration(VariableDeclaration node) {
-    var variableName = node.name2.lexeme;
+    var variableName = node.name.lexeme;
     var parent = node.parent!;
     var grandParent = parent.parent;
     if (grandParent is FieldDeclaration) {
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index bff3f1c..48550f6 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -131,7 +131,7 @@
     node.typeParameters?.accept(this);
     node.nativeClause?.accept(this);
     node.members.accept(this);
-    var classElement = node.declaredElement2!;
+    var classElement = node.declaredElement!;
     _handleSupertypeClauses(node, classElement, node.extendsClause?.superclass,
         node.withClause, node.implementsClause, null);
     var constructors = classElement.constructors;
@@ -156,7 +156,7 @@
   DecoratedType? visitClassTypeAlias(ClassTypeAlias node) {
     node.metadata.accept(this);
     node.typeParameters?.accept(this);
-    var classElement = node.declaredElement2!;
+    var classElement = node.declaredElement!;
     _handleSupertypeClauses(node, classElement, node.superclass,
         node.withClause, node.implementsClause, null);
     for (var constructorElement in classElement.constructors) {
@@ -188,7 +188,7 @@
   DecoratedType? visitConstructorDeclaration(ConstructorDeclaration node) {
     _handleExecutableDeclaration(
         node,
-        node.declaredElement2!,
+        node.declaredElement!,
         node.metadata,
         null,
         null,
@@ -211,7 +211,7 @@
   @override
   DecoratedType? visitDeclaredIdentifier(DeclaredIdentifier node) {
     node.metadata.accept(this);
-    var declaredElement = node.declaredElement2!;
+    var declaredElement = node.declaredElement!;
     var target = NullabilityNodeTarget.element(declaredElement);
     DecoratedType? type =
         _pushNullabilityNodeTarget(target, () => node.type?.accept(this));
@@ -220,7 +220,7 @@
           _typeProvider, declaredElement.type, _graph, target);
       instrumentation?.implicitType(source, node, type);
     }
-    _variables!.recordDecoratedElementType(node.declaredElement2, type);
+    _variables!.recordDecoratedElementType(node.declaredElement, type);
     return type;
   }
 
@@ -248,7 +248,7 @@
   @override
   DecoratedType? visitEnumDeclaration(EnumDeclaration node) {
     node.metadata.accept(this);
-    var classElement = node.declaredElement2!;
+    var classElement = node.declaredElement!;
     _variables!.recordDecoratedElementType(
         classElement, DecoratedType(classElement.thisType, _graph.never));
 
@@ -260,7 +260,7 @@
     }
 
     for (var item in node.constants) {
-      var declaredElement = item.declaredElement2!;
+      var declaredElement = item.declaredElement!;
       var target = NullabilityNodeTarget.element(declaredElement);
       _variables!.recordDecoratedElementType(declaredElement,
           DecoratedType(classElement.thisType, makeNonNullNode(target, item)));
@@ -286,7 +286,7 @@
     var type = _pushNullabilityNodeTarget(
         NullabilityNodeTarget.text('extended type'),
         () => node.extendedType.accept(this));
-    _variables!.recordDecoratedElementType(node.declaredElement2, type);
+    _variables!.recordDecoratedElementType(node.declaredElement, type);
     node.members.accept(this);
     return null;
   }
@@ -317,7 +317,7 @@
   DecoratedType? visitFunctionDeclaration(FunctionDeclaration node) {
     _handleExecutableDeclaration(
         node,
-        node.declaredElement2!,
+        node.declaredElement!,
         node.metadata,
         node.returnType,
         node.functionExpression.typeParameters,
@@ -350,7 +350,7 @@
   @override
   DecoratedType? visitFunctionTypeAlias(FunctionTypeAlias node) {
     node.metadata.accept(this);
-    var declaredElement = node.declaredElement2!;
+    var declaredElement = node.declaredElement!;
     var functionElement =
         declaredElement.aliasedElement as GenericFunctionTypeElement;
     var functionType = functionElement.type;
@@ -403,12 +403,12 @@
     node.metadata.accept(this);
     DecoratedType? decoratedFunctionType;
     node.typeParameters?.accept(this);
-    var target = NullabilityNodeTarget.element(node.declaredElement2!);
+    var target = NullabilityNodeTarget.element(node.declaredElement!);
     _pushNullabilityNodeTarget(target, () {
       decoratedFunctionType = node.functionType!.accept(this);
     });
     _variables!.recordDecoratedElementType(
-        (node.declaredElement2 as TypeAliasElement).aliasedElement,
+        (node.declaredElement as TypeAliasElement).aliasedElement,
         decoratedFunctionType);
     return null;
   }
@@ -431,7 +431,7 @@
 
   @override
   DecoratedType? visitMethodDeclaration(MethodDeclaration node) {
-    var declaredElement = node.declaredElement2;
+    var declaredElement = node.declaredElement;
     var decoratedType = _handleExecutableDeclaration(
         node,
         declaredElement!,
@@ -478,7 +478,7 @@
     node.metadata.accept(this);
     node.typeParameters?.accept(this);
     node.members.accept(this);
-    _handleSupertypeClauses(node, node.declaredElement2!, null, null,
+    _handleSupertypeClauses(node, node.declaredElement!, null, null,
         node.implementsClause, node.onClause);
     return null;
   }
@@ -616,7 +616,7 @@
 
   @override
   DecoratedType? visitTypeParameter(TypeParameter node) {
-    var element = node.declaredElement2!;
+    var element = node.declaredElement!;
     var bound = node.bound;
     DecoratedType? decoratedBound;
     var target = NullabilityNodeTarget.typeParameterBound(element);
@@ -638,7 +638,7 @@
     node.metadata.accept(this);
     var typeAnnotation = node.type;
     var declaredType = _pushNullabilityNodeTarget(
-        NullabilityNodeTarget.element(node.variables.first.declaredElement2!),
+        NullabilityNodeTarget.element(node.variables.first.declaredElement!),
         () => typeAnnotation?.accept(this));
     var hint = getPrefixHint(node.firstTokenAfterCommentAndMetadata);
     if (hint != null && hint.kind == HintCommentKind.late_) {
@@ -650,7 +650,7 @@
     var parent = node.parent;
     for (var variable in node.variables) {
       variable.metadata.accept(this);
-      var declaredElement = variable.declaredElement2;
+      var declaredElement = variable.declaredElement;
       var type = declaredType;
       if (type == null) {
         var target = NullabilityNodeTarget.element(declaredElement!);
@@ -703,7 +703,7 @@
     for (var annotation in metadata) {
       var element = annotation.element;
       if (element is ConstructorElement) {
-        var name = element.enclosingElement3.name;
+        var name = element.enclosingElement.name;
         if (_isAngularUri(element.librarySource.uri)) {
           if (name == 'ViewChild' || name == 'ContentChild') {
             return _AngularAnnotation.child;
@@ -745,7 +745,7 @@
         // Constructors have no explicit return type annotation, so use the
         // implicit return type.
         decoratedReturnType = _createDecoratedTypeForClass(
-            declaredElement.enclosingElement3, parameters!.parent);
+            declaredElement.enclosingElement, parameters!.parent);
         instrumentation?.implicitReturnType(source, node, decoratedReturnType);
       } else {
         // Inferred return type.
@@ -846,7 +846,7 @@
     for (var annotation in node.metadata) {
       var element = annotation.element;
       if (element is ConstructorElement &&
-          element.enclosingElement3.name == 'Optional' &&
+          element.enclosingElement.name == 'Optional' &&
           _isAngularUri(element.librarySource.uri)) {
         _graph.makeNullable(
             decoratedType!.node!, AngularAnnotationOrigin(source, node));
diff --git a/pkg/nnbd_migration/lib/src/nullability_node_target.dart b/pkg/nnbd_migration/lib/src/nullability_node_target.dart
index 4566ca2..8319936 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node_target.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node_target.dart
@@ -15,7 +15,7 @@
     } else {
       parts.add(name);
     }
-    element = element.enclosingElement3;
+    element = element.enclosingElement;
   }
   if (parts.isEmpty) {
     assert(false, 'Could not compute a name for $element');
diff --git a/pkg/nnbd_migration/lib/src/utilities/built_value_transformer.dart b/pkg/nnbd_migration/lib/src/utilities/built_value_transformer.dart
index 892c0b5..c4ed06f 100644
--- a/pkg/nnbd_migration/lib/src/utilities/built_value_transformer.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/built_value_transformer.dart
@@ -13,7 +13,7 @@
           var element = annotation.element;
           if (element is PropertyAccessorElement &&
               element.name == 'nullable') {
-            if (element.enclosingElement3 is CompilationUnitElement) {
+            if (element.enclosingElement is CompilationUnitElement) {
               if (element.library.source.uri.toString() ==
                   'package:built_value/built_value.dart') {
                 return annotation;
diff --git a/pkg/nnbd_migration/lib/src/utilities/where_not_null_transformer.dart b/pkg/nnbd_migration/lib/src/utilities/where_not_null_transformer.dart
index 35d3588..17e7526 100644
--- a/pkg/nnbd_migration/lib/src/utilities/where_not_null_transformer.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/where_not_null_transformer.dart
@@ -139,7 +139,7 @@
     if (element is MethodElement) {
       if (element.isStatic) return false;
       if (element.name != 'where') return false;
-      var enclosingElement = element.declaration.enclosingElement3;
+      var enclosingElement = element.declaration.enclosingElement;
       if (enclosingElement is ClassElement) {
         // If the class is `Iterable` or a subtype of it, we consider the user
         // to be calling a transformable method.
diff --git a/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart b/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart
index 162d544..d276ad5 100644
--- a/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart
@@ -104,7 +104,7 @@
       if (element.isStatic) return null;
       var replacementName = _replacementNames[element.name];
       if (replacementName == null) return null;
-      var enclosingElement = element.declaration.enclosingElement3;
+      var enclosingElement = element.declaration.enclosingElement;
       if (enclosingElement is ClassElement) {
         // If the class is `Iterable` or a subtype of it, we consider the user
         // to be calling a transformable method.
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index a41bab4..573ce93 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -125,7 +125,7 @@
   /// nullabilities.
   DecoratedType? decoratedTypeParameterBound(TypeParameterElement typeParameter,
       {bool allowNullUnparentedBounds = false}) {
-    var enclosingElement = typeParameter.enclosingElement3;
+    var enclosingElement = typeParameter.enclosingElement;
     var decoratedType =
         DecoratedTypeParameterBounds.current!.get(typeParameter);
     if (enclosingElement == null) {
@@ -349,7 +349,7 @@
       );
     } else if (type is TypeParameterType) {
       return TypeParameterTypeImpl(
-        element: type.element2,
+        element2: type.element2,
         nullabilitySuffix: nullabilitySuffix,
       );
     } else {
@@ -431,7 +431,7 @@
   bool _isLoadLibraryElement(Element element) =>
       element.isSynthetic &&
       element is FunctionElement &&
-      element.enclosingElement3 is LibraryElement &&
+      element.enclosingElement is LibraryElement &&
       element.name == 'loadLibrary';
 
   /// Inverts the logic of [uniqueIdentifierForSpan], producing an (offset, end)
diff --git a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
index 0926da6..c7b390f 100644
--- a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
+++ b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
@@ -69,7 +69,7 @@
         typeFormals: [typeFormal],
         parameters: const [],
         returnType: TypeParameterTypeImpl(
-          element: typeFormal,
+          element2: typeFormal,
           nullabilitySuffix: NullabilitySuffix.star,
         ),
         nullabilitySuffix: suffix,
@@ -98,7 +98,7 @@
         typeFormals: [typeFormal],
         parameters: const [],
         returnType: TypeParameterTypeImpl(
-          element: typeFormal,
+          element2: typeFormal,
           nullabilitySuffix: NullabilitySuffix.star,
         ),
         nullabilitySuffix: suffix,
@@ -311,7 +311,7 @@
 
     withElement.checkTypeParameter(
         withElement.decorate(TypeParameterTypeImpl(
-            element: element, nullabilitySuffix: NullabilitySuffix.question)),
+            element2: element, nullabilitySuffix: NullabilitySuffix.question)),
         withElement.checkExplicitlyNullable,
         element,
         'test type');
@@ -325,8 +325,8 @@
     var withElement = withUnit.withElement(element);
 
     withElement.checkTypeParameter(
-        withElement.decorate(
-            TypeParameterTypeImpl(element: element, nullabilitySuffix: suffix)),
+        withElement.decorate(TypeParameterTypeImpl(
+            element2: element, nullabilitySuffix: suffix)),
         withElement.checkExplicitlyNonNullable,
         element,
         'test type');
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 83b4755..0044fc9 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -3857,7 +3857,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_field_final_uninitalized_used() async {
+  Future<void> test_field_final_uninitialized_used() async {
     var content = '''
 class C {
   final String s;
@@ -4194,6 +4194,28 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_field_overrides_field_in_mixin() async {
+    var content = '''
+class C extends Object with M {
+  int x;
+}
+
+mixin M {
+  int x;
+}
+''';
+    var expected = '''
+class C extends Object with M {
+  int? x;
+}
+
+mixin M {
+  int? x;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_field_overrides_getter() async {
     var content = '''
 abstract class C {
@@ -4244,7 +4266,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_field_uninitalized_used() async {
+  Future<void> test_field_uninitialized_used() async {
     var content = '''
 class C {
   String s;
@@ -4268,7 +4290,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_field_uninitalized_used_hint() async {
+  Future<void> test_field_uninitialized_used_hint() async {
     var content = '''
 class C {
   String /*?*/ s;
@@ -6344,7 +6366,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_localVariable_uninitalized_assigned_non_nullable() async {
+  Future<void> test_localVariable_uninitialized_assigned_non_nullable() async {
     var content = '''
 f() {
   String s;
@@ -6366,7 +6388,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_localVariable_uninitalized_used() async {
+  Future<void> test_localVariable_uninitialized_used() async {
     var content = '''
 f() {
   String s;
@@ -6386,7 +6408,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_localVariable_uninitalized_usedInComparison() async {
+  Future<void> test_localVariable_uninitialized_usedInComparison() async {
     var content = '''
 f() {
   String s;
@@ -6403,7 +6425,7 @@
   }
 
   Future<void>
-      test_localVariable_uninitalized_usedInExpressionStatement() async {
+      test_localVariable_uninitialized_usedInExpressionStatement() async {
     var content = '''
 f() {
   String s;
@@ -6419,7 +6441,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_localVariable_uninitalized_usedInForUpdaters() async {
+  Future<void> test_localVariable_uninitialized_usedInForUpdaters() async {
     var content = '''
 f() {
   String s;
@@ -6435,7 +6457,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_localVariable_uninitalized_usedInForVariable() async {
+  Future<void> test_localVariable_uninitialized_usedInForVariable() async {
     var content = '''
 f() {
   String s;
@@ -6586,7 +6608,6 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49106')
   Future<void> test_map_read_does_not_require_index_cast() async {
     var content = '''
 int f(Map<String, int> m, Object o) => m[o];
@@ -7275,6 +7296,158 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_null_aware_call_on_migrated_get() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D get g;
+}
+abstract class D {
+  int f2();
+}
+''';
+    // Since `.g` is a non-nullable getter in an already-migrated class, the
+    // `?.` can safely be replaced with `.`.  We can safely make this change
+    // even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C c) => c.g?.f2();
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C c) => c.g.f2();
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_call_on_migrated_get_null_shorting() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D get g;
+}
+abstract class D {
+  int f2();
+}
+''';
+    // Since `.g` is a non-nullable getter in an already-migrated class, the
+    // `?.` can safely be replaced with `.`.  We can safely make this change
+    // even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C/*?*/ c) => c?.g?.f2();
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C? c) => c?.g.f2();
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_call_on_migrated_method() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D f();
+}
+abstract class D {
+  int f2();
+}
+''';
+    // Since `.f()` is a method with a non-nullable return type in an
+    // already-migrated class, the `?.` can safely be replaced with `.`.  We can
+    // safely make this change even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C c) => c.f()?.f2();
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C c) => c.f().f2();
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_call_on_migrated_method_null_shorting() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D f();
+}
+abstract class D {
+  int f2();
+}
+''';
+    // Since `.f()` is a method with a non-nullable return type in an
+    // already-migrated class, the `?.` can safely be replaced with `.`.  We can
+    // safely make this change even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C/*?*/ c) => c?.f()?.f2();
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C? c) => c?.f().f2();
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_call_on_nullable_get() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D? get g;
+}
+abstract class D {
+  int f2();
+}
+''';
+    // Since `.g` is a nullable getter in an already-migrated class, we don't
+    // replace `?.` with `.`.
+    var content = '''
+import 'migrated.dart';
+f(C c) => c.g?.f2();
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C c) => c.g?.f2();
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput});
+  }
+
+  Future<void> test_null_aware_call_on_nullable_method() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D? f();
+}
+abstract class D {
+  int f2();
+}
+''';
+    // Since `.f()` is a method with a nullable return type in an
+    // already-migrated class, we don't replace `?.` with `.`.
+    var content = '''
+import 'migrated.dart';
+f(C c) => c.f()?.f2();
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C c) => c.f()?.f2();
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput});
+  }
+
   Future<void> test_null_aware_call_on_private_param_not_nullable() async {
     // The null-aware access on `i` is *not* considered a strong enough signal
     // that `i` is meant to be nullable, because the migration tool can see all
@@ -7320,6 +7493,62 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_null_aware_call_on_unmigrated_get() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class D {
+  int f2();
+}
+''';
+    // Since `.g` is unmigrated, we don't replace `?.` with `.` in "warn on weak
+    // code" mode.
+    var content = '''
+import 'migrated.dart';
+abstract class C {
+  D get g;
+}
+f(C c) => c.g?.f2();
+''';
+    var expected = '''
+import 'migrated.dart';
+abstract class C {
+  D get g;
+}
+f(C c) => c.g?.f2();
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_call_on_unmigrated_method() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class D {
+  int f2();
+}
+''';
+    // Since `.f()` is unmigrated, we don't replace `?.` with `.` in "warn on
+    // weak code" mode.
+    var content = '''
+import 'migrated.dart';
+abstract class C {
+  D f();
+}
+f(C c) => c.f()?.f2();
+''';
+    var expected = '''
+import 'migrated.dart';
+abstract class C {
+  D f();
+}
+f(C c) => c.f()?.f2();
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
   Future<void> test_null_aware_call_tearoff() async {
     // Kind of a weird use case because `f?.call` is equivalent to `f`, but
     // let's make sure we analyze it correctly.
@@ -7372,6 +7601,110 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_null_aware_get_on_migrated_get() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D get g;
+}
+abstract class D {
+  int get g2;
+}
+''';
+    // Since `.g` is a non-nullable getter in an already-migrated class, the
+    // `?.` can safely be replaced with `.`.  We can safely make this change
+    // even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C c) => c.g?.g2;
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C c) => c.g.g2;
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_get_on_migrated_get_null_shorting() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D get g;
+}
+abstract class D {
+  int get g2;
+}
+''';
+    // Since `.g` is a non-nullable getter in an already-migrated class, the
+    // `?.` can safely be replaced with `.`.  We can safely make this change
+    // even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C/*?*/ c) => c?.g?.g2;
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C? c) => c?.g.g2;
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_get_on_migrated_method() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D f();
+}
+abstract class D {
+  int get g2;
+}
+''';
+    // Since `.f()` is a method with a non-nullable return type in an
+    // already-migrated class, the `?.` can safely be replaced with `.`.  We can
+    // safely make this change even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C c) => c.f()?.g2;
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C c) => c.f().g2;
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_get_on_migrated_method_null_shorting() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D f();
+}
+abstract class D {
+  int get g2;
+}
+''';
+    // Since `.f()` is a method with a non-nullable return type in an
+    // already-migrated class, the `?.` can safely be replaced with `.`.  We can
+    // safely make this change even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C/*?*/ c) => c?.f()?.g2;
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C? c) => c?.f().g2;
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
   Future<void> test_null_aware_get_on_private_param_not_nullable() async {
     // The null-aware access on `i` is *not* considered a strong enough signal
     // that `i` is meant to be nullable, because the migration tool can see all
@@ -7503,6 +7836,110 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_null_aware_set_on_migrated_get() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D get g;
+}
+abstract class D {
+  set s(int i);
+}
+''';
+    // Since `.g` is a non-nullable getter in an already-migrated class, the
+    // `?.` can safely be replaced with `.`.  We can safely make this change
+    // even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C c) => c.g?.s = 0;
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C c) => c.g.s = 0;
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_set_on_migrated_get_null_shorting() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D get g;
+}
+abstract class D {
+  set s(int i);
+}
+''';
+    // Since `.g` is a non-nullable getter in an already-migrated class, the
+    // `?.` can safely be replaced with `.`.  We can safely make this change
+    // even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C/*?*/ c) => c?.g?.s = 0;
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C? c) => c?.g.s = 0;
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_set_on_migrated_method() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D f();
+}
+abstract class D {
+  set s(int i);
+}
+''';
+    // Since `.f()` is a method with a non-nullable return type in an
+    // already-migrated class, the `?.` can safely be replaced with `.`.  We can
+    // safely make this change even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C c) => c.f()?.s = 0;
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C c) => c.f().s = 0;
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
+  Future<void> test_null_aware_set_on_migrated_method_null_shorting() async {
+    var migratedInput = '''
+// @dart=2.12
+abstract class C {
+  D f();
+}
+abstract class D {
+  set s(int i);
+}
+''';
+    // Since `.f()` is a method with a non-nullable return type in an
+    // already-migrated class, the `?.` can safely be replaced with `.`.  We can
+    // safely make this change even if we are in "warn on weak code" mode.
+    var content = '''
+import 'migrated.dart';
+f(C/*?*/ c) => c?.f()?.s = 0;
+''';
+    var expected = '''
+import 'migrated.dart';
+f(C? c) => c?.f().s = 0;
+''';
+    await _checkSingleFileChanges(content, expected,
+        migratedInput: {'$projectPath/lib/migrated.dart': migratedInput},
+        warnOnWeakCode: true);
+  }
+
   Future<void> test_null_aware_set_on_private_param_not_nullable() async {
     // The null-aware access on `c` is *not* considered a strong enough signal
     // that `c` is meant to be nullable, because the migration tool can see all
@@ -8340,6 +8777,24 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_reference_to_mixin_getter() async {
+    var content = '''
+mixin M {
+  Object f() => this.x;
+
+  Object get x => null;
+}
+''';
+    var expected = '''
+mixin M {
+  Object? f() => this.x;
+
+  Object? get x => null;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_regression_40551() async {
     var content = '''
 class B<T extends Object> { // bound should not be made nullable
@@ -8841,7 +9296,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_topLevelVariable_uninitalized_used() async {
+  Future<void> test_topLevelVariable_uninitialized_used() async {
     var content = '''
 String s;
 f() {
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index b7b1121..981f404 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -3171,7 +3171,7 @@
 }
 ''');
     var xType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     assertEdge(decoratedTypeAnnotation('int').node, xType.node, hard: false);
   }
 
@@ -4676,7 +4676,7 @@
 }
 ''');
     var xType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     assertEdge(decoratedTypeAnnotation('int').node, xType.node, hard: false);
   }
 
@@ -8027,7 +8027,7 @@
 var x = f();
 ''');
     var xType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     assertEdge(decoratedTypeAnnotation('int').node, xType.node, hard: false);
   }
 
diff --git a/pkg/nnbd_migration/test/fix_aggregator_test.dart b/pkg/nnbd_migration/test/fix_aggregator_test.dart
index b028031..9c66681 100644
--- a/pkg/nnbd_migration/test/fix_aggregator_test.dart
+++ b/pkg/nnbd_migration/test/fix_aggregator_test.dart
@@ -1790,7 +1790,7 @@
     var methodInvocation = findNode.methodInvocation('?.');
     var previewInfo = run({
       methodInvocation: NodeChangeForMethodInvocation()
-        ..removeNullAwareness = true
+        ..nullAwarenessRemoval = NullAwarenessRemovalType.strong
     })!;
     expect(previewInfo.applyTo(code!), 'f(x) => x.m();');
   }
@@ -1802,7 +1802,7 @@
     var argument = findNode.simple('x);');
     var previewInfo = run({
       methodInvocation: NodeChangeForMethodInvocation()
-        ..removeNullAwareness = true,
+        ..nullAwarenessRemoval = NullAwarenessRemovalType.strong,
       argument: NodeChangeForExpression()
         ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
     })!;
@@ -1816,7 +1816,7 @@
     var cast = findNode.as_('as');
     var previewInfo = run({
       methodInvocation: NodeChangeForMethodInvocation()
-        ..removeNullAwareness = true,
+        ..nullAwarenessRemoval = NullAwarenessRemovalType.strong,
       cast: NodeChangeForAsExpression()..removeAs = true
     })!;
     expect(previewInfo.applyTo(code!), 'f(x) => x.m();');
@@ -1829,7 +1829,7 @@
     var typeAnnotation = findNode.typeAnnotation('int');
     var previewInfo = run({
       methodInvocation: NodeChangeForMethodInvocation()
-        ..removeNullAwareness = true,
+        ..nullAwarenessRemoval = NullAwarenessRemovalType.strong,
       typeAnnotation: NodeChangeForTypeAnnotation()
         ..recordNullability(
             MockDecoratedType(
@@ -1843,7 +1843,8 @@
     await analyze('f(x) => x?.y;');
     var propertyAccess = findNode.propertyAccess('?.');
     var previewInfo = run({
-      propertyAccess: NodeChangeForPropertyAccess()..removeNullAwareness = true
+      propertyAccess: NodeChangeForPropertyAccess()
+        ..nullAwarenessRemoval = NullAwarenessRemovalType.strong
     })!;
     expect(previewInfo.applyTo(code!), 'f(x) => x.y;');
   }
@@ -1853,7 +1854,8 @@
     var propertyAccess = findNode.propertyAccess('?.');
     var cast = findNode.as_('as');
     var previewInfo = run({
-      propertyAccess: NodeChangeForPropertyAccess()..removeNullAwareness = true,
+      propertyAccess: NodeChangeForPropertyAccess()
+        ..nullAwarenessRemoval = NullAwarenessRemovalType.strong,
       cast: NodeChangeForAsExpression()..removeAs = true
     })!;
     expect(previewInfo.applyTo(code!), 'f(x) => x.y;');
@@ -2057,7 +2059,7 @@
     await analyze(content);
     var previewInfo = run({
       findNode.propertyAccess('?.'): NodeChangeForPropertyAccess()
-        ..removeNullAwareness = true
+        ..nullAwarenessRemoval = NullAwarenessRemovalType.weak
     }, warnOnWeakCode: true)!;
     expect(previewInfo.applyTo(code!), content);
     expect(previewInfo, hasLength(1));
diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart
index 322ab2a..efff561 100644
--- a/pkg/nnbd_migration/test/fix_builder_test.dart
+++ b/pkg/nnbd_migration/test/fix_builder_test.dart
@@ -92,8 +92,10 @@
           'addNames', unorderedEquals(['IterableExtension']));
 
   static final isRemoveNullAwareness =
-      TypeMatcher<NodeChangeForPropertyAccess>()
-          .having((c) => c.removeNullAwareness, 'removeNullAwareness', true);
+      TypeMatcher<NodeChangeForPropertyAccess>().having(
+          (c) => c.nullAwarenessRemoval != NullAwarenessRemovalType.none,
+          'removeNullAwareness',
+          true);
 
   static final isRemoveAs = TypeMatcher<NodeChangeForAsExpression>()
       .having((c) => c.removeAs, 'removeAs', true);
@@ -457,7 +459,6 @@
         changes: {findNode.simple('c['): isNullCheck});
   }
 
-  @FailingTest(reason: 'TODO(paulberry): decide if this is worth caring about')
   Future<void>
       test_assignmentTarget_indexExpression_compound_simple_check_rhs() async {
     await analyze('''
@@ -483,7 +484,6 @@
     visitAssignmentTarget(findNode.index('c['), 'int', 'int');
   }
 
-  @FailingTest(reason: 'TODO(paulberry): decide if this is worth caring about')
   Future<void>
       test_assignmentTarget_indexExpression_compound_substituted_check_rhs() async {
     await analyze('''
@@ -3283,7 +3283,10 @@
     visitSubexpression(propertyAccess, 'int', changes: {
       propertyAccess: TypeMatcher<NodeChangeForPropertyAccess>()
           .havingNullCheckWithInfo(isNotNull)
-          .having((c) => c.removeNullAwareness, 'removeNullAwareness', true)
+          .having(
+              (c) => c.nullAwarenessRemoval != NullAwarenessRemovalType.none,
+              'removeNullAwareness',
+              true)
     });
   }
 
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index 10aa974..fe32069 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -779,6 +779,50 @@
     });
   }
 
+  test_lifecycle_import_check_handle_improper_lib_import() async {
+    Map<String, String?> computeProjectContents({required bool migrated}) => {
+          'pubspec.yaml': '''
+name: test
+environment:
+  sdk: '${migrated ? '>=2.12.0 <3.0.0' : '>=2.6.0 <3.0.0'}'
+''',
+          '.dart_tool/package_config.json':
+              _getPackageConfigText(migrated: migrated),
+          'lib/foo.dart': '''
+int${migrated ? '?' : ''} f() => null;
+''',
+          'test/foo_test.dart': '''
+import '../lib/foo.dart';
+int${migrated ? '?' : ''} g() => f();
+''',
+        };
+    var projectContents = computeProjectContents(migrated: false);
+    var projectDir = createProjectDir(projectContents);
+    var cli = _createCli();
+    bool applyHookCalled = false;
+    cli._onApplyHook = () {
+      expect(applyHookCalled, false);
+      applyHookCalled = true;
+      // Changes should have been made
+      assertProjectContents(projectDir, computeProjectContents(migrated: true));
+    };
+    await runWithPreviewServer(cli, ['--skip-import-check', projectDir],
+        (url) async {
+      expect(
+          logger.stdoutBuffer.toString(), contains('No analysis issues found'));
+      await assertPreviewServerResponsive(url!);
+      await _tellPreviewToApplyChanges(url);
+      expect(applyHookCalled, true);
+      var output = logger.stdoutBuffer.toString();
+      expect(output,
+          isNot(contains('Warning: package has unmigrated dependencies')));
+      // Output should not mention that the user can rerun without
+      // `--skip-import-check`.
+      expect(output,
+          isNot(contains('`--${CommandLineOptions.skipImportCheckFlag}`')));
+    });
+  }
+
   test_lifecycle_import_check_via_export() async {
     // If the user's code exports a library that imports a non-migrated library,
     // that's a problem too.
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index 27ef00a..4977171 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -377,7 +377,7 @@
   /// Gets the [DecoratedType] associated with the constructor declaration whose
   /// name matches [search].
   DecoratedType decoratedConstructorDeclaration(String search) => variables
-      .decoratedElementType(findNode.constructor(search).declaredElement2!);
+      .decoratedElementType(findNode.constructor(search).declaredElement!);
 
   Map<InterfaceElement, DecoratedType?> decoratedDirectSupertypes(String name) {
     return variables.decoratedDirectSupertypes(findElement.classOrMixin(name));
@@ -394,7 +394,7 @@
   /// name matches [search].
   DecoratedType decoratedMethodType(String search) =>
       variables.decoratedElementType(
-          findNode.methodDeclaration(search).declaredElement2!);
+          findNode.methodDeclaration(search).declaredElement!);
 
   /// Gets the [DecoratedType] associated with the type annotation whose text
   /// is [text].
diff --git a/pkg/nnbd_migration/test/node_builder_test.dart b/pkg/nnbd_migration/test/node_builder_test.dart
index ea57053..341a654 100644
--- a/pkg/nnbd_migration/test/node_builder_test.dart
+++ b/pkg/nnbd_migration/test/node_builder_test.dart
@@ -24,11 +24,11 @@
   /// name matches [search].
   DecoratedType decoratedFunctionType(String search) =>
       variables.decoratedElementType(
-          findNode.functionDeclaration(search).declaredElement2!);
+          findNode.functionDeclaration(search).declaredElement!);
 
   DecoratedType? decoratedTypeParameterBound(String search) =>
       variables.decoratedTypeParameterBound(
-          findNode.typeParameter(search).declaredElement2!);
+          findNode.typeParameter(search).declaredElement!);
 
   Future<void> test_catch_clause_with_stacktrace_with_on() async {
     await analyze('''
@@ -685,7 +685,7 @@
 }
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.node!.isImmutable, false);
   }
 
@@ -696,7 +696,7 @@
 }
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
   }
 
@@ -708,7 +708,7 @@
 }
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.node!.isImmutable, false);
   }
 
@@ -725,7 +725,7 @@
             .fieldDeclaration('f')
             .fields
             .variables[0]
-            .declaredElement2!),
+            .declaredElement!),
         same(decoratedType));
   }
 
@@ -1029,7 +1029,7 @@
 }
 ''');
     var functionExpressionElement =
-        findNode.simpleParameter('int i').declaredElement!.enclosingElement3!;
+        findNode.simpleParameter('int i').declaredElement!.enclosingElement!;
     var decoratedType =
         variables.decoratedElementType(functionExpressionElement);
     expect(decoratedType.positionalParameters![0],
@@ -1046,7 +1046,7 @@
 }
 ''');
     var functionExpressionElement =
-        findNode.simpleParameter('int i').declaredElement!.enclosingElement3!;
+        findNode.simpleParameter('int i').declaredElement!.enclosingElement!;
     var decoratedType =
         variables.decoratedElementType(functionExpressionElement);
     expect(
@@ -1377,7 +1377,7 @@
             .topLevelVariableDeclaration('x')
             .variables
             .variables[0]
-            .declaredElement2!)
+            .declaredElement!)
         .typeArguments[0]!
         .node!;
     expect(node.hintActions, isEmpty);
@@ -1392,7 +1392,7 @@
             .topLevelVariableDeclaration('x')
             .variables
             .variables[0]
-            .declaredElement2!)
+            .declaredElement!)
         .node!;
     expect(node.hintActions, isEmpty);
   }
@@ -1548,7 +1548,7 @@
 }
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.node!.isImmutable, false);
   }
 
@@ -1559,7 +1559,7 @@
 }
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
   }
 
@@ -1571,7 +1571,7 @@
 }
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.node!.isImmutable, false);
   }
 
@@ -1582,7 +1582,7 @@
 }
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.returnType!.node!.displayName,
         'return type of main.x (test.dart:2:7)');
   }
@@ -1594,7 +1594,7 @@
 }
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.typeArguments[0]!.node!.displayName,
         'type argument 0 of main.x (test.dart:2:7)');
     expect(decoratedType.typeArguments[1]!.node!.displayName,
@@ -1915,7 +1915,7 @@
 var x;
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.node!.isImmutable, false);
   }
 
@@ -1924,7 +1924,7 @@
 var x = 1;
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
   }
 
@@ -1934,7 +1934,7 @@
 var x = f();
 ''');
     var decoratedType = variables.decoratedElementType(
-        findNode.variableDeclaration('x').declaredElement2!);
+        findNode.variableDeclaration('x').declaredElement!);
     expect(decoratedType.node!.isImmutable, false);
   }
 
diff --git a/pkg/nnbd_migration/tool/codegen/extract_resource.dart b/pkg/nnbd_migration/tool/codegen/extract_resource.dart
index bfc2490..486fbc4 100644
--- a/pkg/nnbd_migration/tool/codegen/extract_resource.dart
+++ b/pkg/nnbd_migration/tool/codegen/extract_resource.dart
@@ -38,7 +38,7 @@
     if (declaration is TopLevelVariableDeclaration) {
       for (var variable in declaration.variables.variables) {
         if (variable.initializer == null) continue;
-        var match = variableNameRegExp.matchAsPrefix(variable.name2.lexeme);
+        var match = variableNameRegExp.matchAsPrefix(variable.name.lexeme);
         if (match == null) continue;
         var shortName = match.group(1);
         if (list) {
diff --git a/pkg/scrape/example/superclass_parameters.dart b/pkg/scrape/example/superclass_parameters.dart
index b242525..ab1461b 100644
--- a/pkg/scrape/example/superclass_parameters.dart
+++ b/pkg/scrape/example/superclass_parameters.dart
@@ -291,7 +291,7 @@
     record('Insert super args', insert ? 'Yes' : 'No');
     record('Do not merge super args', noMerge ? 'Yes' : 'No');
 
-    var subName = _constructorName(node.name2);
+    var subName = _constructorName(node.name);
     var superName = _constructorName(initializer.constructorName?.token);
 
     record('No explicit super(), call same name',
diff --git a/pkg/test_runner/analysis_options.yaml b/pkg/test_runner/analysis_options.yaml
index ff809b7..3f45629 100644
--- a/pkg/test_runner/analysis_options.yaml
+++ b/pkg/test_runner/analysis_options.yaml
@@ -12,7 +12,6 @@
     cancel_subscriptions: true
     comment_references: true
     directives_ordering: true
-    invariant_booleans: true
     omit_local_variable_types: true
     package_api_docs: true
     prefer_const_constructors: true
diff --git a/pkg/test_runner/bin/test_runner.dart b/pkg/test_runner/bin/test_runner.dart
index bd1027a..d1b230d 100644
--- a/pkg/test_runner/bin/test_runner.dart
+++ b/pkg/test_runner/bin/test_runner.dart
@@ -44,6 +44,10 @@
     exit(1);
   }
 
+  if (configurations.isEmpty) {
+    return;
+  }
+
   // Run all of the configured tests.
   await testConfigurations(configurations);
 }
diff --git a/pkg/test_runner/lib/src/browser_controller.dart b/pkg/test_runner/lib/src/browser_controller.dart
index c4300ee..a541a14 100644
--- a/pkg/test_runner/lib/src/browser_controller.dart
+++ b/pkg/test_runner/lib/src/browser_controller.dart
@@ -251,13 +251,6 @@
   /// Starts the browser loading the given url
   Future<bool> start(String url);
 
-  /// Called when the driver page is requested, that is, when the browser first
-  /// contacts the test server. At this time, it's safe to assume that the
-  /// browser process has started and opened its first window.
-  ///
-  /// This is used by [Safari] to ensure the browser window has focus.
-  Future<Null> onDriverPageRequested() => Future.value();
-
   @override
   String toString() => '$runtimeType';
 }
@@ -266,6 +259,7 @@
   WebDriver? _driver;
   final int _port;
   final Map<String, dynamic> _desiredCapabilities;
+  bool _terminated = false;
 
   WebDriverBrowser(this._port, this._desiredCapabilities);
 
@@ -273,6 +267,7 @@
   Future<bool> start(String url) async {
     _logEvent('Starting $this browser on: $url');
     await _createDriver();
+    if (_terminated) return false;
     await _driver!.get(url);
     try {
       _logEvent('Got version: ${await version}');
@@ -287,11 +282,13 @@
     for (var i = 5; i >= 0; i--) {
       // Give the driver process some time to be ready to accept connections.
       await Future.delayed(const Duration(seconds: 1));
+      if (_terminated) return;
       try {
         _driver = await createDriver(
             uri: Uri.parse('http://localhost:$_port/'),
             desired: _desiredCapabilities);
       } catch (error) {
+        if (_terminated) return;
         if (i > 0) {
           _logEvent(
               'Failed to create driver ($i retries left).\nError: $error');
@@ -307,6 +304,7 @@
 
   @override
   Future<bool> close() async {
+    _terminated = true;
     await _driver?.quit();
     // Give the driver process some time to be quit the browser.
     return true;
@@ -1255,7 +1253,6 @@
   }
 
   Future<String> getDriverPage(String browserId) async {
-    await testRunner.browserStatus[browserId]?.browser.onDriverPageRequested();
     var errorReportingUrl =
         "http://$localIp:${errorReportingServer.port}/$browserId";
     var driverContent = """
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index ba098e5..7780568 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -579,6 +579,8 @@
       'pkg/dart2wasm/bin/run_wasm.js',
       '--',
       artifact!.filename,
+      ...testFile.sharedObjects
+          .map((obj) => '${_configuration.buildDirectory}/wasm/$obj.wasm'),
     ];
   }
 }
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 7fc5926..a5402c6 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -34,6 +34,7 @@
   Class? _internalImmutableLinkedHashSet;
   Class? _internalLinkedHashMap;
   Class? _internalLinkedHashSet;
+  Class? _record;
   Class? _oneByteString;
   Class? _twoByteString;
   Class? _smi;
@@ -292,7 +293,7 @@
         isStatic: isStatic,
         isConstructor: isConstructor,
         isTopLevel: isTopLevel);
-    return new ConstructorInvocation(
+    return new StaticInvocation(
         coreTypes.noSuchMethodErrorDefaultConstructor,
         new Arguments(<Expression>[
           receiver,
@@ -442,16 +443,25 @@
   @override
   Class concreteSetLiteralClass(CoreTypes coreTypes) {
     return _internalLinkedHashSet ??=
-        coreTypes.index.getClass('dart:collection', '_CompactLinkedHashSet');
+        coreTypes.index.getClass('dart:collection', '_InternalLinkedHashSet');
   }
 
   @override
   Class concreteConstSetLiteralClass(CoreTypes coreTypes) {
     return _internalImmutableLinkedHashSet ??= coreTypes.index
-        .getClass('dart:collection', '_CompactImmutableLinkedHashSet');
+        .getClass('dart:collection', '_InternalImmutableLinkedHashSet');
   }
 
   @override
+  Class concreteRecordLiteralClass(CoreTypes coreTypes) {
+    return _record ??= coreTypes.index.getClass('dart:core', '_Record');
+  }
+
+  @override
+  Class concreteConstRecordLiteralClass(CoreTypes coreTypes) =>
+      concreteRecordLiteralClass(coreTypes);
+
+  @override
   Class? concreteIntLiteralClass(CoreTypes coreTypes, int value) {
     const int bitsPerInt32 = 32;
     const int smiBits32 = bitsPerInt32 - 2;
diff --git a/pkg/vm/lib/transformations/ffi/native.dart b/pkg/vm/lib/transformations/ffi/native.dart
index 6a3df4c..f061608 100644
--- a/pkg/vm/lib/transformations/ffi/native.dart
+++ b/pkg/vm/lib/transformations/ffi/native.dart
@@ -70,7 +70,7 @@
         super(index, coreTypes, hierarchy, diagnosticReporter,
             referenceFromIndex);
 
-  ConstantExpression? _tryGetFfiNativeAnnotation(Member node) {
+  ConstantExpression? tryGetFfiNativeAnnotation(Member node) {
     for (final Expression annotation in node.annotations) {
       if (annotation is! ConstantExpression) {
         continue;
@@ -443,26 +443,13 @@
     List<Expression> argumentList, {
     required bool checkReceiverForNullptr,
   }) {
-    if (!_verifySignatures(
-        node, dartFunctionType, ffiFunctionType, annotationOffset)) {
-      return node;
-    }
+    final wrappedDartFunctionType = checkFfiType(
+        node, dartFunctionType, ffiFunctionType, isLeaf, annotationOffset);
 
-    // int Function(Pointer<Void>)
-    final wrappedDartFunctionType =
-        _wrapFunctionType(dartFunctionType, ffiFunctionType);
-
-    final nativeType = InterfaceType(
-        nativeFunctionClass, Nullability.legacy, [ffiFunctionType]);
-    try {
-      ensureNativeTypeValid(nativeType, node);
-      ensureNativeTypeToDartType(nativeType, wrappedDartFunctionType, node,
-          allowHandle: true);
-      ensureLeafCallDoesNotUseHandles(nativeType, isLeaf, node);
-    } on FfiStaticTypeError {
-      // It's OK to swallow the exception because the diagnostics issued will
-      // cause compilation to fail. By continuing, we can report more
-      // diagnostics before compilation ends.
+    if (wrappedDartFunctionType == null) {
+      // It's OK to continue because the diagnostics issued will cause
+      // compilation to fail. By continuing, we can report more diagnostics
+      // before compilation ends.
       return node;
     }
 
@@ -609,7 +596,7 @@
     // Only transform functions that are external and have FfiNative annotation:
     //   @FfiNative<Double Function(Double)>('Math_sqrt')
     //   external double _square_root(double x);
-    final ffiNativeAnnotation = _tryGetFfiNativeAnnotation(node);
+    final ffiNativeAnnotation = tryGetFfiNativeAnnotation(node);
     if (ffiNativeAnnotation == null) {
       return node;
     }
@@ -639,4 +626,38 @@
     return _transformStaticFunction(node, ffiFunctionType, nativeFunctionName,
         isLeaf, ffiNativeAnnotation.fileOffset);
   }
+
+  /// Checks whether the FFI function type is valid and reports any errors.
+  /// Returns the Dart function type for the FFI function if the type is valid.
+  ///
+  /// For example, for FFI function type `Int8 Function(Double)`, this returns
+  /// `int Function(double)`.
+  FunctionType? checkFfiType(Procedure node, FunctionType dartFunctionType,
+      FunctionType ffiFunctionType, bool isLeaf, int annotationOffset) {
+    if (!_verifySignatures(
+        node, dartFunctionType, ffiFunctionType, annotationOffset)) {
+      return null;
+    }
+
+    // int Function(Pointer<Void>)
+    final wrappedDartFunctionType =
+        _wrapFunctionType(dartFunctionType, ffiFunctionType);
+
+    final nativeType = InterfaceType(
+        nativeFunctionClass, Nullability.legacy, [ffiFunctionType]);
+
+    try {
+      ensureNativeTypeValid(nativeType, node);
+      ensureNativeTypeToDartType(nativeType, wrappedDartFunctionType, node,
+          allowHandle: true);
+      ensureLeafCallDoesNotUseHandles(nativeType, isLeaf, node);
+    } on FfiStaticTypeError {
+      // It's OK to swallow the exception because the diagnostics issued will
+      // cause compilation to fail. By continuing, we can report more
+      // diagnostics before compilation ends.
+      return null;
+    }
+
+    return wrappedDartFunctionType;
+  }
 }
diff --git a/pkg/vm/lib/transformations/specializer/set_factory_specializer.dart b/pkg/vm/lib/transformations/specializer/set_factory_specializer.dart
index 2479e3d..f76cd70 100644
--- a/pkg/vm/lib/transformations/specializer/set_factory_specializer.dart
+++ b/pkg/vm/lib/transformations/specializer/set_factory_specializer.dart
@@ -10,10 +10,10 @@
 
 /// Replaces invocation of Set factory constructors with
 /// factories of VM-specific classes.
-/// new LinkedHashSet<E>() => new _CompactLinkedHashSet<E>()
+/// new LinkedHashSet<E>() => new _InternalLinkedHashSet<E>()
 class SetFactorySpecializer extends BaseSpecializer {
   final Procedure _linkedHashSetDefaultFactory;
-  final Constructor _compactLinkedHashSetConstructor;
+  final Constructor _internalLinkedHashSetConstructor;
 
   SetFactorySpecializer(CoreTypes coreTypes)
       : _linkedHashSetDefaultFactory = assertNotNull(
@@ -23,10 +23,10 @@
             '',
           ),
         ),
-        _compactLinkedHashSetConstructor = assertNotNull(
+        _internalLinkedHashSetConstructor = assertNotNull(
           coreTypes.index.getConstructor(
             'dart:collection',
-            '_CompactLinkedHashSet',
+            '_InternalLinkedHashSet',
             '',
           ),
         ) {
@@ -45,7 +45,7 @@
     assert(args.positional.isEmpty);
     if (args.named.isEmpty) {
       return ConstructorInvocation(
-        _compactLinkedHashSetConstructor,
+        _internalLinkedHashSetConstructor,
         Arguments([], types: args.types),
       );
     }
diff --git a/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart b/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
index ffc4b1e..bba8909c 100644
--- a/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
+++ b/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
@@ -19,9 +19,9 @@
   // All of those methods have the dart field name as second positional
   // parameter.
   // Method names are defined in:
-  // https://github.com/dart-lang/protobuf/blob/master/protobuf/lib/src/protobuf/builder_info.dart
+  // https://github.com/google/protobuf.dart/blob/master/protobuf/lib/src/protobuf/builder_info.dart
   // The code is generated by:
-  // https://github.com/dart-lang/protobuf/blob/master/protoc_plugin/lib/protobuf_field.dart.
+  // https://github.com/google/protobuf.dart/blob/master/protoc_plugin/lib/src/protobuf_field.dart
   static const Set<String> fieldAddingMethods = const <String>{
     'a',
     'aOM',
diff --git a/pkg/vm/lib/transformations/type_flow/rta.dart b/pkg/vm/lib/transformations/type_flow/rta.dart
index b6adfe4..999257b 100644
--- a/pkg/vm/lib/transformations/type_flow/rta.dart
+++ b/pkg/vm/lib/transformations/type_flow/rta.dart
@@ -459,6 +459,16 @@
   }
 
   @override
+  void visitRecordConstant(RecordConstant constant) {
+    for (var value in constant.positional) {
+      visit(value);
+    }
+    for (var value in constant.named.values) {
+      visit(value);
+    }
+  }
+
+  @override
   void visitInstanceConstant(InstanceConstant constant) {
     rta.addAllocatedClass(constant.classNode);
     for (var value in constant.fieldValues.values) {
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 7543814..d107cf1 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -1618,6 +1618,34 @@
   }
 
   @override
+  TypeExpr visitRecordLiteral(RecordLiteral node) {
+    for (var expr in node.positional) {
+      _visit(expr);
+    }
+    for (var expr in node.named) {
+      _visit(expr.value);
+    }
+    Class? concreteClass =
+        target.concreteRecordLiteralClass(_environment.coreTypes);
+    if (concreteClass != null) {
+      return _entryPointsListener.addAllocatedClass(concreteClass);
+    }
+    return _staticType(node);
+  }
+
+  @override
+  TypeExpr visitRecordIndexGet(RecordIndexGet node) {
+    _visit(node.receiver);
+    return _staticType(node);
+  }
+
+  @override
+  TypeExpr visitRecordNameGet(RecordNameGet node) {
+    _visit(node.receiver);
+    return _staticType(node);
+  }
+
+  @override
   TypeExpr visitInstanceInvocation(InstanceInvocation node) {
     final receiverNode = node.receiver;
     final receiver = _visit(receiverNode);
@@ -2562,6 +2590,24 @@
   }
 
   @override
+  Type visitRecordConstant(RecordConstant constant) {
+    for (var value in constant.positional) {
+      typeFor(value);
+    }
+    for (var value in constant.named.values) {
+      typeFor(value);
+    }
+    Class? concreteClass = summaryCollector.target
+        .concreteConstRecordLiteralClass(
+            summaryCollector._environment.coreTypes);
+    if (concreteClass != null) {
+      return summaryCollector._entryPointsListener
+          .addAllocatedClass(concreteClass);
+    }
+    return _getStaticType(constant);
+  }
+
+  @override
   Type visitInstanceConstant(InstanceConstant constant) {
     final resultClass = summaryCollector._entryPointsListener
         .addAllocatedClass(constant.classNode);
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 89a6702..9cb2422 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -986,11 +986,6 @@
   }
 
   @override
-  visitFunctionType(FunctionType node) {
-    node.visitChildren(this);
-  }
-
-  @override
   visitTypeParameterType(TypeParameterType node) {
     final parent = node.parameter.parent;
     if (parent is Class) {
@@ -1955,6 +1950,16 @@
   }
 
   @override
+  visitRecordConstant(RecordConstant constant) {
+    for (var value in constant.positional) {
+      analyzeConstant(value);
+    }
+    for (var value in constant.named.values) {
+      analyzeConstant(value);
+    }
+  }
+
+  @override
   visitInstanceConstant(InstanceConstant constant) {
     instanceConstants.add(constant);
     shaker.addClassUsedInType(constant.classNode);
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index ecffc6b..0d4c481 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -86,6 +86,9 @@
     } else if (type is FunctionType) {
       // TODO(alexmarkov): support function types
       result = const AnyType();
+    } else if (type is RecordType) {
+      // TODO(dartbug.com/49719): support inference of record types
+      result = const AnyType();
     } else if (type is FutureOrType) {
       // TODO(alexmarkov): support FutureOr types
       result = const AnyType();
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index 2b80881..6696274 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -19,7 +19,7 @@
 
 final Uri pkgVmDir = Platform.script.resolve('../../..');
 
-runTestCase(
+void runTestCase(
     Uri source, bool enableNullSafety, List<Uri>? linkedDependencies) async {
   final target =
       new TestingVmTarget(new TargetFlags(enableNullSafety: enableNullSafety));
@@ -87,7 +87,7 @@
   static const List<Option> options = [linked, nnbdStrong];
 }
 
-main(List<String> args) {
+void main(List<String> args) {
   final testNameFilter = argsTestName(args);
 
   group('transform-component', () {
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.aot.expect b/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.aot.expect
index 4c37d02..6ee149a 100644
--- a/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.aot.expect
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.aot.expect
@@ -11,10 +11,10 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on ffi::Finalizable {
+extension /* unnamed */ _extension#0 on ffi::Finalizable {
   method bar = self::_extension#0|bar;
 }
-extension _extension#1 on core::Object {
+extension /* unnamed */ _extension#1 on core::Object {
   method baz = self::_extension#1|baz;
 }
 static method main() → void {
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.expect b/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.expect
index 24ca399..7d1f3bd 100644
--- a/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.expect
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_extension_method.dart.expect
@@ -11,11 +11,11 @@
     : super core::Object::•()
     ;
 }
-extension _extension#0 on ffi::Finalizable {
+extension /* unnamed */ _extension#0 on ffi::Finalizable {
   method bar = self::_extension#0|bar;
   tearoff bar = self::_extension#0|get#bar;
 }
-extension _extension#1 on core::Object {
+extension /* unnamed */ _extension#1 on core::Object {
   method baz = self::_extension#1|baz;
   tearoff baz = self::_extension#1|get#baz;
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/const_set.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/const_set.dart.expect
index f8d211c..e64db2a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/const_set.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/const_set.dart.expect
@@ -11,7 +11,7 @@
     : super core::Object::•()
     ;
   static method fromReader() → self::_Attribute {
-    final core::bool name = [@vm.direct-call.metadata=dart.collection::__CompactImmutableLinkedHashSet&_HashVMImmutableBase&SetMixin&_HashBase&_OperatorEqualsAndCanonicalHashCode&_LinkedHashSetMixin&_UnmodifiableSetMixin&_ImmutableLinkedHashSetMixin.contains] [@vm.inferred-type.metadata=!? (skip check)] #C3.{core::Set::contains}(#C2){(core::Object?) → core::bool};
+    final core::bool name = [@vm.direct-call.metadata=dart.collection::__InternalImmutableLinkedHashSet&_HashVMImmutableBase&SetMixin&_HashBase&_OperatorEqualsAndCanonicalHashCode&_LinkedHashSetMixin&_UnmodifiableSetMixin&_ImmutableLinkedHashSetMixin.contains] [@vm.inferred-type.metadata=!? (skip check)] #C3.{core::Set::contains}(#C2){(core::Object?) → core::bool};
     return let final self::_AttributeName #t1 = #C8.{core::List::[]}(#C2){(core::int) → self::_AttributeName} in new self::_Attribute::_();
   }
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
index 860daaf..69b8d70 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
@@ -36,13 +36,13 @@
 
 class FooKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•(#C1 ?{core::String} "" : "FooKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, #C1 ?{core::String} "" : "barKeep", #C2){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::BarKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, #C1 ?{core::String} "" : "barKeep", #C2){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::BarKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(#C1 ?{core::String} "" : "mapKeep", #C2){(core::int, core::String, {defaultEnumValue: pro::ProtobufEnum?, entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, required keyFieldType: core::int, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, required valueFieldType: core::int, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(#C1 ?{core::String} "" : "mapKeep", #C2){(core::int, core::String, {defaultEnumValue: pro::ProtobufEnum?, entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, required keyFieldType: core::int, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, valueDefaultOrMaker: dynamic, required valueFieldType: core::int, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, #C1 ?{core::String} "" : "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, #C1 ?{core::String} "" : "hasKeep", #C3){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::HasKeep}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, #C1 ?{core::String} "" : "clearKeep", #C4){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::ClearKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, #C1 ?{core::String} "" : "hasKeep", #C3){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::HasKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, #C1 ?{core::String} "" : "clearKeep", #C4){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::ClearKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
   constructor _() → self::FooKeep
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
index fc7dd55..a85b04c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
@@ -29,13 +29,13 @@
 
 class FooKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•(#C1 ?{core::String} "" : "FooKeep", createEmptyInstance: #C2) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, #C1 ?{core::String} "" : "barKeep", #C3){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::BarKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, #C1 ?{core::String} "" : "barKeep", #C3){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::BarKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(#C1 ?{core::String} "" : "mapKeep", #C3){(core::int, core::String, {defaultEnumValue: pro::ProtobufEnum?, entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, required keyFieldType: core::int, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, required valueFieldType: core::int, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(#C1 ?{core::String} "" : "mapKeep", #C3){(core::int, core::String, {defaultEnumValue: pro::ProtobufEnum?, entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, required keyFieldType: core::int, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, valueDefaultOrMaker: dynamic, required valueFieldType: core::int, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, #C1 ?{core::String} "" : "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, #C1 ?{core::String} "" : "hasKeep", #C4){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::HasKeep}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, #C1 ?{core::String} "" : "clearKeep", #C5){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::ClearKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, #C1 ?{core::String} "" : "hasKeep", #C4){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::HasKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, #C1 ?{core::String} "" : "clearKeep", #C5){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::ClearKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
   constructor _() → self::FooKeep
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
index 1cc8fc6..1345581 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
@@ -43,13 +43,13 @@
 
 class FooKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•(#C1 ?{core::String} "" : "FooKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, #C1 ?{core::String} "" : "barKeep", #C2){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::BarKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, #C1 ?{core::String} "" : "barKeep", #C2){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::BarKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(3, #C1 ?{core::String} "" : "mapKeep", "FooKeep.MapKeepEntry", #C2){(core::int, core::String, {defaultEnumValue: pro::ProtobufEnum?, entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, required keyFieldType: core::int, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, required valueFieldType: core::int, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::ZopDrop>(4, #C1 ?{core::String} "" : "mapDrop", "FooKeep.MapDropEntry", #C3){(core::int, core::String, {defaultEnumValue: pro::ProtobufEnum?, entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, required keyFieldType: core::int, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, required valueFieldType: core::int, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(3, #C1 ?{core::String} "" : "mapKeep", "FooKeep.MapKeepEntry", #C2){(core::int, core::String, {defaultEnumValue: pro::ProtobufEnum?, entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, required keyFieldType: core::int, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, valueDefaultOrMaker: dynamic, required valueFieldType: core::int, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::ZopDrop>(4, #C1 ?{core::String} "" : "mapDrop", "FooKeep.MapDropEntry", #C3){(core::int, core::String, {defaultEnumValue: pro::ProtobufEnum?, entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, required keyFieldType: core::int, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, valueDefaultOrMaker: dynamic, required valueFieldType: core::int, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, #C1 ?{core::String} "" : "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, #C1 ?{core::String} "" : "hasKeep", #C4){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::HasKeep}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, #C1 ?{core::String} "" : "clearKeep", #C5){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::ClearKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, #C1 ?{core::String} "" : "hasKeep", #C4){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::HasKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, #C1 ?{core::String} "" : "clearKeep", #C5){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::ClearKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
   constructor _() → self::FooKeep
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
index 5eaaf9d..f6ef694 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
@@ -39,13 +39,13 @@
 
 class FooKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t1 = new pro::BuilderInfo::•(#C1 ?{core::String} "" : "FooKeep") in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, #C1 ?{core::String} "" : "barKeep", #C2){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::BarKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep>(1, #C1 ?{core::String} "" : "barKeep", #C2){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::BarKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(#C1 ?{core::String} "" : "mapKeep", #C2){(core::int, core::String, {defaultEnumValue: pro::ProtobufEnum?, entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, required keyFieldType: core::int, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, required valueFieldType: core::int, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String, self::BarKeep>(#C1 ?{core::String} "" : "mapKeep", #C2){(core::int, core::String, {defaultEnumValue: pro::ProtobufEnum?, entryClassName: core::String?, enumValues: core::List<pro::ProtobufEnum>?, required keyFieldType: core::int, packageName: pro::PackageName, protoName: core::String?, valueCreator: () →? pro::GeneratedMessage, valueDefaultOrMaker: dynamic, required valueFieldType: core::int, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<Null>(0, null, null, null, null){(core::int, core::String, core::int?, dynamic, () →? pro::GeneratedMessage, (core::int) →? pro::ProtobufEnum?, core::List<pro::ProtobufEnum>?, {protoName: core::String?}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int>(5, #C1 ?{core::String} "" : "aKeep"){(core::int, core::String, core::int, {defaultOrMaker: dynamic, enumValues: core::List<pro::ProtobufEnum>?, protoName: core::String?, subBuilder: () →? pro::GeneratedMessage, valueOf: (core::int) →? pro::ProtobufEnum?}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, #C1 ?{core::String} "" : "hasKeep", #C3){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::HasKeep}) → void};
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, #C1 ?{core::String} "" : "clearKeep", #C4){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::ClearKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep>(6, #C1 ?{core::String} "" : "hasKeep", #C3){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::HasKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep>(7, #C1 ?{core::String} "" : "clearKeep", #C4){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::ClearKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
   constructor _() → self::FooKeep
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
index b188464..2e8775c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
@@ -34,7 +34,7 @@
 }
 class NameManglingKeep extends pro::GeneratedMessage {
 [@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo _i = let final pro::BuilderInfo #t2 = new pro::BuilderInfo::•(#C1 ?{core::String} "" : "NameManglingKeep", #C6) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::aOM}<self::AKeep>(#C1 ?{core::String} "" : "clone", #C2){(core::int, core::String, {protoName: core::String?, subBuilder: () →? self::AKeep}) → void};
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::aOM}<self::AKeep>(#C1 ?{core::String} "" : "clone", #C2){(core::int, core::String, {protoName: core::String?, required subBuilder: () → self::AKeep}) → void};
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t2;
   constructor _() → self::NameManglingKeep
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter81068.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter81068.dart.expect
index 963f8c2..3578aaf 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter81068.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter81068.dart.expect
@@ -16,11 +16,11 @@
     ;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method noSuchMethod(core::Invocation i) → dynamic
     return throw "Not implemented";
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError) → asy::Future<self::B::T%>
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  no-such-method-forwarder method catchError(core::Function onError) → asy::Future<self::B::T%>
     return [@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=! (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 0, #C2, [@vm.inferred-type.metadata=dart.core::_ImmutableList] core::List::unmodifiable<dynamic>([@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::_GrowableList::_literal1<dynamic>(onError)), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C3: #C4}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::B::T%>;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::B::T%>
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  no-such-method-forwarder method whenComplete(() → FutureOr<void>action) → asy::Future<self::B::T%>
     return [@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=! (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C2, [@vm.inferred-type.metadata=dart.core::_ImmutableList] core::List::unmodifiable<dynamic>([@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::_GrowableList::_literal1<dynamic>(action)), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::B::T%>;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ then<R extends core::Object? = dynamic>((self::B::T%) → FutureOr<self::B::then::R%>onValue, {core::Function? onError = #C4}) → asy::Future<self::B::then::R%>
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  no-such-method-forwarder method then<R extends core::Object? = dynamic>((self::B::T%) → FutureOr<self::B::then::R%>onValue, {core::Function? onError = #C4}) → asy::Future<self::B::then::R%>
     return [@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=! (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, [@vm.inferred-type.metadata=dart.core::_ImmutableList] core::List::unmodifiable<core::Type*>([@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::Type*>] core::_GrowableList::_literal1<core::Type*>(self::B::then::R%)), [@vm.inferred-type.metadata=dart.core::_ImmutableList] core::List::unmodifiable<dynamic>([@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::_GrowableList::_literal1<dynamic>(onValue)), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C8: onError}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::B::then::R%>;
 }
 static method createB<T extends core::Object? = dynamic>() → self::B<dynamic>
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect
index cffe9fc..0dd6380 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect
@@ -6,9 +6,9 @@
 import "dart:collection";
 import "dart:core";
 
-[@vm.inferred-type.metadata=dart.collection::_CompactLinkedHashSet?<dynamic>]static field core::Set<dynamic> globalSet = new col::_CompactLinkedHashSet::•<dynamic>();
+[@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashSet?<dynamic>]static field core::Set<dynamic> globalSet = new col::_InternalLinkedHashSet::•<dynamic>();
 [@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashSet?<dynamic>]static field core::Set<dynamic> identitySet = [@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashSet<dynamic>] col::LinkedHashSet::identity<dynamic>();
-[@vm.inferred-type.metadata=dart.collection::_CompactLinkedHashSet?<dart.core::String>]static field core::Set<core::String> linkedSet = new col::_CompactLinkedHashSet::•<core::String>();
+[@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashSet?<dart.core::String>]static field core::Set<core::String> linkedSet = new col::_InternalLinkedHashSet::•<core::String>();
 static field core::Set<core::String> linkedIdentitySet = [@vm.inferred-type.metadata=!] col::LinkedHashSet::•<core::String>(#C1, #C2);
 static field core::Set<core::String> linkedCustomSet = let final (core::String, core::String) → core::bool #t1 = (core::String a, core::String b) → core::bool => [@vm.inferred-type.metadata=!? (receiver not int)] a =={core::String::==}{(core::Object) → core::bool} b in let final (core::String) → core::int #t2 = (core::String o) → core::int => o.{core::String::hashCode}{core::int} in let final (dynamic) → core::bool #t3 = (dynamic o) → core::bool => true in [@vm.inferred-type.metadata=!] col::LinkedHashSet::•<core::String>(#t1, #t2, isValidKey: #t3);
 [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap?<dynamic, dynamic>]static field core::Map<dynamic, dynamic> globalMap = [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<dynamic, dynamic>] core::Map::•<dynamic, dynamic>();
@@ -19,9 +19,9 @@
 static field core::Map<core::String, core::String> linkedIdentityMap = [@vm.inferred-type.metadata=!] col::LinkedHashMap::•<core::String, core::String>(#C1, #C2);
 static field core::Map<core::String, core::String> linkedCustomMap = let final (core::String, core::String) → core::bool #t4 = (core::String a, core::String b) → core::bool => [@vm.inferred-type.metadata=!? (receiver not int)] a =={core::String::==}{(core::Object) → core::bool} b in let final (core::String) → core::int #t5 = (core::String o) → core::int => o.{core::String::hashCode}{core::int} in let final (dynamic) → core::bool #t6 = (dynamic o) → core::bool => true in [@vm.inferred-type.metadata=!] col::LinkedHashMap::•<core::String, core::String>(#t4, #t5, isValidKey: #t6);
 static method main() → dynamic {
-  core::print([@vm.inferred-type.metadata=dart.collection::_CompactLinkedHashSet?<dynamic>] self::globalSet);
+  core::print([@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashSet?<dynamic>] self::globalSet);
   core::print([@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashSet?<dynamic>] self::identitySet);
-  core::print([@vm.inferred-type.metadata=dart.collection::_CompactLinkedHashSet?<dart.core::String>] self::linkedSet);
+  core::print([@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashSet?<dart.core::String>] self::linkedSet);
   core::print(self::linkedIdentitySet);
   core::print(self::linkedCustomSet);
   core::print([@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap?<dynamic, dynamic>] self::globalMap);
diff --git a/pkg/vm_service/analysis_options.yaml b/pkg/vm_service/analysis_options.yaml
index 382a641..e51d6bf 100644
--- a/pkg/vm_service/analysis_options.yaml
+++ b/pkg/vm_service/analysis_options.yaml
@@ -4,3 +4,6 @@
   rules:
     - directives_ordering
     - prefer_generic_function_type_aliases
+    - prefer_initializing_formals
+    - prefer_single_quotes
+    - unnecessary_this
diff --git a/pkg/vm_service/example/sample_main.dart b/pkg/vm_service/example/sample_main.dart
index 1fef21b..be9ea12 100644
--- a/pkg/vm_service/example/sample_main.dart
+++ b/pkg/vm_service/example/sample_main.dart
@@ -7,7 +7,7 @@
 void main(List<String> args) {
   String local1 = 'abcd';
   int local2 = 2;
-  var longList = [1, "hello", 3, 5, 7, 11, 13, 14, 15, 16, 17, 18, 19, 20];
+  var longList = [1, 'hello', 3, 5, 7, 11, 13, 14, 15, 16, 17, 18, 19, 20];
   var deepList = [
     Bar(),
     [
@@ -17,7 +17,7 @@
             [7]
           ]
         ],
-        "end"
+        'end'
       ]
     ]
   ];
@@ -42,7 +42,7 @@
 }
 
 class Bar extends FooBar {
-  String field1 = "my string";
+  String field1 = 'my string';
 }
 
 class FooBar {
diff --git a/pkg/vm_service/java/example/sample_exception.dart b/pkg/vm_service/java/example/sample_exception.dart
index 7afb095..56c34dd 100644
--- a/pkg/vm_service/java/example/sample_exception.dart
+++ b/pkg/vm_service/java/example/sample_exception.dart
@@ -8,7 +8,7 @@
   if (true) local1 = 'abcd';
 
   int local2 = 2;
-  var longList = [1, "hello", 3, 5, 7, 11, 13, 14, 15, 16, 17, 18, 19, 20];
+  var longList = [1, 'hello', 3, 5, 7, 11, 13, 14, 15, 16, 17, 18, 19, 20];
   var deepList = [
     Bar(),
     [
@@ -18,7 +18,7 @@
             [7]
           ]
         ],
-        "end"
+        'end'
       ]
     ]
   ];
@@ -45,7 +45,7 @@
 }
 
 class Bar extends FooBar {
-  String field1 = "my string";
+  String field1 = 'my string';
 }
 
 class FooBar {
diff --git a/pkg/vm_service/java/example/sample_main.dart b/pkg/vm_service/java/example/sample_main.dart
index 6884434..4755154 100644
--- a/pkg/vm_service/java/example/sample_main.dart
+++ b/pkg/vm_service/java/example/sample_main.dart
@@ -5,7 +5,7 @@
 void main(List<String> args) {
   String local1 = 'abcd';
   int local2 = 2;
-  var longList = [1, "hello", 3, 5, 7, 11, 13, 14, 15, 16, 17, 18, 19, 20];
+  var longList = [1, 'hello', 3, 5, 7, 11, 13, 14, 15, 16, 17, 18, 19, 20];
   var deepList = [
     Bar(),
     [
@@ -15,7 +15,7 @@
             [7]
           ]
         ],
-        "end"
+        'end'
       ]
     ]
   ];
@@ -38,7 +38,7 @@
 }
 
 class Bar extends FooBar {
-  String field1 = "my string";
+  String field1 = 'my string';
 }
 
 class FooBar {
diff --git a/pkg/vm_service/lib/src/snapshot_graph.dart b/pkg/vm_service/lib/src/snapshot_graph.dart
index 14e5818..11d437f 100644
--- a/pkg/vm_service/lib/src/snapshot_graph.dart
+++ b/pkg/vm_service/lib/src/snapshot_graph.dart
@@ -195,7 +195,12 @@
   dynamic get data => _data;
 
   /// A list of indices into [HeapSnapshotGraph.objects].
-  List<int> get references => _references;
+  Uint32List get references => Uint32List.sublistView(_graph._successors,
+      _graph._firstSuccessors[_oid], _graph._firstSuccessors[_oid + 1]);
+
+  /// A list of indices into [HeapSnapshotGraph.objects].
+  Uint32List get referrers => Uint32List.sublistView(_graph._predecessors,
+      _graph._firstPredecessors[_oid], _graph._firstPredecessors[_oid + 1]);
 
   /// The identity hash code of this object.
   ///
@@ -222,7 +227,6 @@
   int _shallowSize = -1;
   int _identityHashCode = 0;
   late final dynamic _data;
-  final List<int> _references = <int>[];
 
   HeapSnapshotObject._sentinel(this._graph)
       : _oid = 0,
@@ -234,17 +238,17 @@
     _classId = reader.readUnsigned();
     _shallowSize = reader.readUnsigned();
     _data = _getNonReferenceData(reader);
-    _graph._firstSuccessors[_oid] = _graph._eid;
     _populateReferences(reader);
   }
 
   void _populateReferences(_ReadStream reader) {
+    _graph._firstSuccessors[_oid] = _graph._eid;
     final referencesCount = reader.readUnsigned();
     for (int i = 0; i < referencesCount; ++i) {
-      int childOid = reader.readUnsigned();
-      _references.add(childOid);
-      _graph._successors[_graph._eid] = childOid;
-      _graph._eid++;
+      final currentOid = _graph._eid++;
+      final childOid = reader.readUnsigned();
+      _graph._successors[currentOid] = childOid;
+      _graph._predecessorCounts[childOid]++;
     }
   }
 }
@@ -308,8 +312,14 @@
   final List<HeapSnapshotExternalProperty> _externalProperties =
       <HeapSnapshotExternalProperty>[];
 
-  late Uint32List _firstSuccessors;
-  late Uint32List _successors;
+  late Uint32List _predecessorCounts;
+
+  late final Uint32List _firstSuccessors;
+  late final Uint32List _successors;
+
+  late final Uint32List _firstPredecessors;
+  late final Uint32List _predecessors;
+
   int _eid = 0;
 
   /// Requests a heap snapshot for a given isolate and builds a
@@ -356,6 +366,8 @@
     _populateObjects(reader);
     _populateExternalProperties(reader);
     _populateIdentityHashCodes(reader);
+
+    _calculatePredecessors();
   }
 
   void _populateClasses(_ReadStream reader) {
@@ -370,8 +382,10 @@
   void _populateObjects(_ReadStream reader) {
     _referenceCount = reader.readUnsigned();
     final objectCount = reader.readUnsigned();
+
     _firstSuccessors = _newUint32Array(objectCount + 2);
     _successors = _newUint32Array(_referenceCount);
+    _predecessorCounts = _newUint32Array(objectCount + 2);
 
     _objects.add(HeapSnapshotObject._sentinel(this));
     for (int i = 1; i <= objectCount; ++i) {
@@ -380,6 +394,37 @@
     _firstSuccessors[objectCount + 1] = _eid;
   }
 
+  void _calculatePredecessors() {
+    final objectCount = _objects.length - 1;
+
+    _firstPredecessors = _newUint32Array(objectCount + 2);
+    _predecessors = _newUint32Array(_referenceCount);
+
+    _firstPredecessors[objectCount + 1] = _eid;
+
+    // We reuse the [_predecessorCounts] array and turn it into the
+    // write cursor array.
+    final predecessorCounts = _predecessorCounts;
+    _predecessorCounts = Uint32List(0);
+    int sum = 0;
+    int totalCount = _referenceCount;
+    for (int i = objectCount; i >= 0; --i) {
+      sum += predecessorCounts[i];
+      final firstPredecessor = totalCount - sum;
+      _firstPredecessors[i] = predecessorCounts[i] = firstPredecessor;
+    }
+
+    final predecessorWriteCursor = predecessorCounts;
+    for (int i = 1; i <= objectCount; ++i) {
+      final from = _firstSuccessors[i];
+      final to = _firstSuccessors[i + 1];
+      for (int j = from; j < to; ++j) {
+        final cursor = predecessorWriteCursor[_successors[j]]++;
+        _predecessors[cursor] = i;
+      }
+    }
+  }
+
   void _populateExternalProperties(_ReadStream reader) {
     final propertiesCount = reader.readUnsigned();
     for (int i = 0; i < propertiesCount; ++i) {
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index f182689..782a241 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -26,7 +26,7 @@
         HeapSnapshotObjectNoData,
         HeapSnapshotObjectNullData;
 
-const String vmServiceVersion = '3.60.0';
+const String vmServiceVersion = '3.61.0';
 
 /// @optional
 const String optional = 'optional';
@@ -2983,11 +2983,11 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'name': name,
+      'name': name ?? '',
       'value': value?.toJson(),
-      'declarationTokenPos': declarationTokenPos,
-      'scopeStartTokenPos': scopeStartTokenPos,
-      'scopeEndTokenPos': scopeEndTokenPos,
+      'declarationTokenPos': declarationTokenPos ?? -1,
+      'scopeStartTokenPos': scopeStartTokenPos ?? -1,
+      'scopeEndTokenPos': scopeEndTokenPos ?? -1,
     });
     return json;
   }
@@ -3055,9 +3055,9 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'breakpointNumber': breakpointNumber,
-      'enabled': enabled,
-      'resolved': resolved,
+      'breakpointNumber': breakpointNumber ?? -1,
+      'enabled': enabled ?? false,
+      'resolved': resolved ?? false,
       'location': location?.toJson(),
     });
     _setIfNotNull(
@@ -3126,7 +3126,7 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
+      'name': name ?? '',
       'library': library?.toJson(),
     });
     _setIfNotNull(json, 'location', location?.toJson());
@@ -3272,11 +3272,11 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
+      'name': name ?? '',
       'library': library?.toJson(),
-      'abstract': isAbstract,
-      'const': isConst,
-      'traceAllocations': traceAllocations,
+      'abstract': isAbstract ?? false,
+      'const': isConst ?? false,
+      'traceAllocations': traceAllocations ?? false,
       'interfaces': interfaces?.map((f) => f.toJson()).toList(),
       'fields': fields?.map((f) => f.toJson()).toList(),
       'functions': functions?.map((f) => f.toJson()).toList(),
@@ -3346,10 +3346,10 @@
     json['type'] = type;
     json.addAll({
       'class': classRef?.toJson(),
-      'accumulatedSize': accumulatedSize,
-      'bytesCurrent': bytesCurrent,
-      'instancesAccumulated': instancesAccumulated,
-      'instancesCurrent': instancesCurrent,
+      'accumulatedSize': accumulatedSize ?? -1,
+      'bytesCurrent': bytesCurrent ?? -1,
+      'instancesAccumulated': instancesAccumulated ?? -1,
+      'instancesCurrent': instancesCurrent ?? -1,
     });
     return json;
   }
@@ -3423,8 +3423,8 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
-      'kind': kind,
+      'name': name ?? '',
+      'kind': kind ?? '',
     });
     return json;
   }
@@ -3468,8 +3468,8 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
-      'kind': kind,
+      'name': name ?? '',
+      'kind': kind ?? '',
     });
     return json;
   }
@@ -3507,7 +3507,7 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'length': length,
+      'length': length ?? -1,
     });
     return json;
   }
@@ -3562,7 +3562,7 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'length': length,
+      'length': length ?? -1,
       'variables': variables?.map((f) => f.toJson()).toList(),
     });
     _setIfNotNull(json, 'parent', parent?.toJson());
@@ -3682,13 +3682,13 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'samplePeriod': samplePeriod,
-      'maxStackDepth': maxStackDepth,
-      'sampleCount': sampleCount,
-      'timeSpan': timeSpan,
-      'timeOriginMicros': timeOriginMicros,
-      'timeExtentMicros': timeExtentMicros,
-      'pid': pid,
+      'samplePeriod': samplePeriod ?? -1,
+      'maxStackDepth': maxStackDepth ?? -1,
+      'sampleCount': sampleCount ?? -1,
+      'timeSpan': timeSpan ?? -1,
+      'timeOriginMicros': timeOriginMicros ?? -1,
+      'timeExtentMicros': timeExtentMicros ?? -1,
+      'pid': pid ?? -1,
       'functions': functions?.map((f) => f.toJson()).toList(),
       'samples': samples?.map((f) => f.toJson()).toList(),
     });
@@ -3768,13 +3768,13 @@
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
     json.addAll({
-      'samplePeriod': samplePeriod,
-      'maxStackDepth': maxStackDepth,
-      'sampleCount': sampleCount,
-      'timeSpan': timeSpan,
-      'timeOriginMicros': timeOriginMicros,
-      'timeExtentMicros': timeExtentMicros,
-      'pid': pid,
+      'samplePeriod': samplePeriod ?? -1,
+      'maxStackDepth': maxStackDepth ?? -1,
+      'sampleCount': sampleCount ?? -1,
+      'timeSpan': timeSpan ?? -1,
+      'timeOriginMicros': timeOriginMicros ?? -1,
+      'timeExtentMicros': timeExtentMicros ?? -1,
+      'pid': pid ?? -1,
       'functions': functions?.map((f) => f.toJson()).toList(),
       'samples': samples?.map((f) => f.toJson()).toList(),
     });
@@ -3857,8 +3857,8 @@
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
     json.addAll({
-      'tid': tid,
-      'timestamp': timestamp,
+      'tid': tid ?? -1,
+      'timestamp': timestamp ?? -1,
       'stack': stack?.map((f) => f).toList(),
     });
     _setIfNotNull(json, 'vmTag', vmTag);
@@ -3905,8 +3905,8 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'kind': kind,
-      'message': message,
+      'kind': kind ?? '',
+      'message': message ?? '',
     });
     return json;
   }
@@ -3968,8 +3968,8 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'kind': kind,
-      'message': message,
+      'kind': kind ?? '',
+      'message': message ?? '',
     });
     _setIfNotNull(json, 'exception', exception?.toJson());
     _setIfNotNull(json, 'stacktrace', stacktrace?.toJson());
@@ -4281,8 +4281,8 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'kind': kind,
-      'timestamp': timestamp,
+      'kind': kind ?? '',
+      'timestamp': timestamp ?? -1,
     });
     _setIfNotNull(json, 'isolate', isolate?.toJson());
     _setIfNotNull(json, 'vm', vm?.toJson());
@@ -4390,12 +4390,12 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
+      'name': name ?? '',
       'owner': owner?.toJson(),
       'declaredType': declaredType?.toJson(),
-      'const': isConst,
-      'final': isFinal,
-      'static': isStatic,
+      'const': isConst ?? false,
+      'final': isFinal ?? false,
+      'static': isStatic ?? false,
     });
     _setIfNotNull(json, 'location', location?.toJson());
     return json;
@@ -4490,12 +4490,12 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
+      'name': name ?? '',
       'owner': owner?.toJson(),
       'declaredType': declaredType?.toJson(),
-      'const': isConst,
-      'final': isFinal,
-      'static': isStatic,
+      'const': isConst ?? false,
+      'final': isFinal ?? false,
+      'static': isStatic ?? false,
     });
     _setIfNotNull(json, 'location', location?.toJson());
     _setIfNotNull(json, 'staticValue', staticValue?.toJson());
@@ -4548,9 +4548,9 @@
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
     json.addAll({
-      'name': name,
-      'comment': comment,
-      'modified': modified,
+      'name': name ?? '',
+      'comment': comment ?? '',
+      'modified': modified ?? false,
     });
     _setIfNotNull(json, 'valueAsString', valueAsString);
     return json;
@@ -4646,7 +4646,7 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'index': index,
+      'index': index ?? -1,
     });
     _setIfNotNull(json, 'function', function?.toJson());
     _setIfNotNull(json, 'code', code?.toJson());
@@ -4729,12 +4729,12 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
+      'name': name ?? '',
       'owner': owner?.toJson(),
-      'static': isStatic,
-      'const': isConst,
-      'implicit': implicit,
-      'abstract': isAbstract,
+      'static': isStatic ?? false,
+      'const': isConst ?? false,
+      'implicit': implicit ?? false,
+      'abstract': isAbstract ?? false,
     });
     _setIfNotNull(json, 'location', location?.toJson());
     return json;
@@ -4831,12 +4831,12 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
+      'name': name ?? '',
       'owner': owner?.toJson(),
-      'static': isStatic,
-      'const': isConst,
-      'implicit': implicit,
-      'abstract': isAbstract,
+      'static': isStatic ?? false,
+      'const': isConst ?? false,
+      'implicit': implicit ?? false,
+      'abstract': isAbstract ?? false,
       'signature': signature?.toJson(),
     });
     _setIfNotNull(json, 'location', location?.toJson());
@@ -5074,8 +5074,8 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'kind': kind,
-      'identityHashCode': identityHashCode,
+      'kind': kind ?? '',
+      'identityHashCode': identityHashCode ?? -1,
       'class': classRef?.toJson(),
     });
     _setIfNotNull(json, 'valueAsString', valueAsString);
@@ -5533,8 +5533,8 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'kind': kind,
-      'identityHashCode': identityHashCode,
+      'kind': kind ?? '',
+      'identityHashCode': identityHashCode ?? -1,
       'class': classRef?.toJson(),
     });
     _setIfNotNull(json, 'valueAsString', valueAsString);
@@ -5600,11 +5600,15 @@
   /// internal use. If `false`, this isolate is likely running user code.
   bool? isSystemIsolate;
 
+  /// The id of the isolate group that this isolate belongs to.
+  String? isolateGroupId;
+
   IsolateRef({
     this.id,
     this.number,
     this.name,
     this.isSystemIsolate,
+    this.isolateGroupId,
   });
 
   IsolateRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
@@ -5612,6 +5616,7 @@
     number = json['number'] ?? '';
     name = json['name'] ?? '';
     isSystemIsolate = json['isSystemIsolate'] ?? false;
+    isolateGroupId = json['isolateGroupId'] ?? '';
   }
 
   @override
@@ -5622,10 +5627,11 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'id': id,
-      'number': number,
-      'name': name,
-      'isSystemIsolate': isSystemIsolate,
+      'id': id ?? '',
+      'number': number ?? '',
+      'name': name ?? '',
+      'isSystemIsolate': isSystemIsolate ?? false,
+      'isolateGroupId': isolateGroupId ?? '',
     });
     return json;
   }
@@ -5635,7 +5641,8 @@
   bool operator ==(Object other) => other is IsolateRef && id == other.id;
 
   String toString() => '[IsolateRef ' //
-      'id: ${id}, number: ${number}, name: ${name}, isSystemIsolate: ${isSystemIsolate}]';
+      'id: ${id}, number: ${number}, name: ${name}, isSystemIsolate: ${isSystemIsolate}, ' //
+      'isolateGroupId: ${isolateGroupId}]';
 }
 
 /// An `Isolate` object provides information about one isolate in the VM.
@@ -5656,6 +5663,9 @@
   /// internal use. If `false`, this isolate is likely running user code.
   bool? isSystemIsolate;
 
+  /// The id of the isolate group that this isolate belongs to.
+  String? isolateGroupId;
+
   /// The list of isolate flags provided to this isolate. See Dart_IsolateFlags
   /// in dart_api.h for the list of accepted isolate flags.
   List<IsolateFlag>? isolateFlags;
@@ -5709,6 +5719,7 @@
     this.number,
     this.name,
     this.isSystemIsolate,
+    this.isolateGroupId,
     this.isolateFlags,
     this.startTime,
     this.runnable,
@@ -5728,6 +5739,7 @@
     number = json['number'] ?? '';
     name = json['name'] ?? '';
     isSystemIsolate = json['isSystemIsolate'] ?? false;
+    isolateGroupId = json['isolateGroupId'] ?? '';
     isolateFlags = List<IsolateFlag>.from(
         createServiceObject(json['isolateFlags'], const ['IsolateFlag'])
                 as List? ??
@@ -5762,19 +5774,20 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'id': id,
-      'number': number,
-      'name': name,
-      'isSystemIsolate': isSystemIsolate,
+      'id': id ?? '',
+      'number': number ?? '',
+      'name': name ?? '',
+      'isSystemIsolate': isSystemIsolate ?? false,
+      'isolateGroupId': isolateGroupId ?? '',
       'isolateFlags': isolateFlags?.map((f) => f.toJson()).toList(),
-      'startTime': startTime,
-      'runnable': runnable,
-      'livePorts': livePorts,
-      'pauseOnExit': pauseOnExit,
+      'startTime': startTime ?? -1,
+      'runnable': runnable ?? false,
+      'livePorts': livePorts ?? -1,
+      'pauseOnExit': pauseOnExit ?? false,
       'pauseEvent': pauseEvent?.toJson(),
       'libraries': libraries?.map((f) => f.toJson()).toList(),
       'breakpoints': breakpoints?.map((f) => f.toJson()).toList(),
-      'exceptionPauseMode': exceptionPauseMode,
+      'exceptionPauseMode': exceptionPauseMode ?? '',
     });
     _setIfNotNull(json, 'rootLib', rootLib?.toJson());
     _setIfNotNull(json, 'error', error?.toJson());
@@ -5813,8 +5826,8 @@
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
     json.addAll({
-      'name': name,
-      'valueAsString': valueAsString,
+      'name': name ?? '',
+      'valueAsString': valueAsString ?? '',
     });
     return json;
   }
@@ -5864,10 +5877,10 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'id': id,
-      'number': number,
-      'name': name,
-      'isSystemIsolateGroup': isSystemIsolateGroup,
+      'id': id ?? '',
+      'number': number ?? '',
+      'name': name ?? '',
+      'isSystemIsolateGroup': isSystemIsolateGroup ?? false,
     });
     return json;
   }
@@ -5928,10 +5941,10 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'id': id,
-      'number': number,
-      'name': name,
-      'isSystemIsolateGroup': isSystemIsolateGroup,
+      'id': id ?? '',
+      'number': number ?? '',
+      'name': name ?? '',
+      'isSystemIsolateGroup': isSystemIsolateGroup ?? false,
       'isolates': isolates?.map((f) => f.toJson()).toList(),
     });
     return json;
@@ -6057,7 +6070,7 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'totalCount': totalCount,
+      'totalCount': totalCount ?? -1,
       'instances': instances?.map((f) => f.toJson()).toList(),
     });
     return json;
@@ -6099,8 +6112,8 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
-      'uri': uri,
+      'name': name ?? '',
+      'uri': uri ?? '',
     });
     return json;
   }
@@ -6185,9 +6198,9 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
-      'uri': uri,
-      'debuggable': debuggable,
+      'name': name ?? '',
+      'uri': uri ?? '',
+      'debuggable': debuggable ?? false,
       'dependencies': dependencies?.map((f) => f.toJson()).toList(),
       'scripts': scripts?.map((f) => f.toJson()).toList(),
       'variables': variables?.map((f) => f.toJson()).toList(),
@@ -6251,9 +6264,9 @@
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
     json.addAll({
-      'isImport': isImport,
-      'isDeferred': isDeferred,
-      'prefix': prefix,
+      'isImport': isImport ?? false,
+      'isDeferred': isDeferred ?? false,
+      'prefix': prefix ?? '',
       'target': target?.toJson(),
     });
     _setIfNotNull(json, 'shows', shows?.map((f) => f).toList());
@@ -6333,9 +6346,9 @@
     json['type'] = type;
     json.addAll({
       'message': message?.toJson(),
-      'time': time,
-      'level': level,
-      'sequenceNumber': sequenceNumber,
+      'time': time ?? -1,
+      'level': level ?? -1,
+      'sequenceNumber': sequenceNumber ?? -1,
       'loggerName': loggerName?.toJson(),
       'zone': zone?.toJson(),
       'error': error?.toJson(),
@@ -6426,9 +6439,9 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'externalUsage': externalUsage,
-      'heapCapacity': heapCapacity,
-      'heapUsage': heapUsage,
+      'externalUsage': externalUsage ?? -1,
+      'heapCapacity': heapCapacity ?? -1,
+      'heapUsage': heapUsage ?? -1,
     });
     return json;
   }
@@ -6494,10 +6507,10 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'index': index,
-      'name': name,
-      'messageObjectId': messageObjectId,
-      'size': size,
+      'index': index ?? -1,
+      'name': name ?? '',
+      'messageObjectId': messageObjectId ?? '',
+      'size': size ?? -1,
     });
     _setIfNotNull(json, 'handler', handler?.toJson());
     _setIfNotNull(json, 'location', location?.toJson());
@@ -6529,7 +6542,7 @@
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
     json.addAll({
-      'name': name,
+      'name': name ?? '',
     });
     return json;
   }
@@ -6575,7 +6588,7 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'valueAsString': valueAsString,
+      'valueAsString': valueAsString ?? '',
     });
     return json;
   }
@@ -6627,7 +6640,7 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'valueAsString': valueAsString,
+      'valueAsString': valueAsString ?? '',
     });
     return json;
   }
@@ -6674,7 +6687,7 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'id': id,
+      'id': id ?? '',
     });
     _setIfNotNull(json, 'fixedId', fixedId);
     return json;
@@ -6748,7 +6761,7 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'id': id,
+      'id': id ?? '',
     });
     _setIfNotNull(json, 'fixedId', fixedId);
     _setIfNotNull(json, 'class', classRef?.toJson());
@@ -6804,7 +6817,7 @@
     final json = <String, dynamic>{};
     json.addAll({
       'parameterType': parameterType?.toJson(),
-      'fixed': fixed,
+      'fixed': fixed ?? false,
     });
     _setIfNotNull(json, 'name', name);
     _setIfNotNull(json, 'required', required);
@@ -6894,10 +6907,10 @@
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
     json.addAll({
-      'kind': kind,
-      'inclusiveTicks': inclusiveTicks,
-      'exclusiveTicks': exclusiveTicks,
-      'resolvedUrl': resolvedUrl,
+      'kind': kind ?? '',
+      'inclusiveTicks': inclusiveTicks ?? -1,
+      'exclusiveTicks': exclusiveTicks ?? -1,
+      'resolvedUrl': resolvedUrl ?? '',
       'function': function?.toJson(),
     });
     return json;
@@ -6974,9 +6987,9 @@
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
     json.addAll({
-      'protocolName': protocolName,
-      'major': major,
-      'minor': minor,
+      'protocolName': protocolName ?? '',
+      'major': major ?? -1,
+      'minor': minor ?? -1,
     });
     return json;
   }
@@ -7055,9 +7068,9 @@
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
     json.addAll({
-      'name': name,
-      'description': description,
-      'size': size,
+      'name': name ?? '',
+      'description': description ?? '',
+      'size': size ?? -1,
       'children': children?.map((f) => f.toJson()).toList(),
     });
     return json;
@@ -7091,7 +7104,7 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'success': success,
+      'success': success ?? false,
     });
     return json;
   }
@@ -7187,8 +7200,8 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'length': length,
-      'gcRootType': gcRootType,
+      'length': length ?? -1,
+      'gcRootType': gcRootType ?? '',
       'elements': elements?.map((f) => f.toJson()).toList(),
     });
     return json;
@@ -7257,8 +7270,8 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'kind': kind,
-      'valueAsString': valueAsString,
+      'kind': kind ?? '',
+      'valueAsString': valueAsString ?? '',
     });
     return json;
   }
@@ -7294,7 +7307,7 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'uri': uri,
+      'uri': uri ?? '',
     });
     return json;
   }
@@ -7423,7 +7436,7 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'uri': uri,
+      'uri': uri ?? '',
       'library': library?.toJson(),
     });
     _setIfNotNull(json, 'lineOffset', lineOffset);
@@ -7525,7 +7538,7 @@
     json['type'] = type;
     json.addAll({
       'script': script?.toJson(),
-      'tokenPos': tokenPos,
+      'tokenPos': tokenPos ?? -1,
     });
     _setIfNotNull(json, 'endTokenPos', endTokenPos);
     _setIfNotNull(json, 'line', line);
@@ -7701,10 +7714,10 @@
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
     json.addAll({
-      'scriptIndex': scriptIndex,
-      'startPos': startPos,
-      'endPos': endPos,
-      'compiled': compiled,
+      'scriptIndex': scriptIndex ?? -1,
+      'startPos': startPos ?? -1,
+      'endPos': endPos ?? -1,
+      'compiled': compiled ?? false,
     });
     _setIfNotNull(json, 'error', error?.toJson());
     _setIfNotNull(json, 'coverage', coverage?.toJson());
@@ -7786,7 +7799,7 @@
     json.addAll({
       'frames': frames?.map((f) => f.toJson()).toList(),
       'messages': messages?.map((f) => f.toJson()).toList(),
-      'truncated': truncated,
+      'truncated': truncated ?? false,
     });
     _setIfNotNull(json, 'asyncCausalFrames',
         asyncCausalFrames?.map((f) => f.toJson()).toList());
@@ -7861,8 +7874,8 @@
     json['type'] = type;
     json.addAll({
       'traceEvents': traceEvents?.map((f) => f.toJson()).toList(),
-      'timeOriginMicros': timeOriginMicros,
-      'timeExtentMicros': timeExtentMicros,
+      'timeOriginMicros': timeOriginMicros ?? -1,
+      'timeExtentMicros': timeExtentMicros ?? -1,
     });
     return json;
   }
@@ -7931,7 +7944,7 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'recorderName': recorderName,
+      'recorderName': recorderName ?? '',
       'availableStreams': availableStreams?.map((f) => f).toList(),
       'recordedStreams': recordedStreams?.map((f) => f).toList(),
     });
@@ -7966,7 +7979,7 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'timestamp': timestamp,
+      'timestamp': timestamp ?? -1,
     });
     return json;
   }
@@ -8002,7 +8015,7 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
+      'name': name ?? '',
     });
     return json;
   }
@@ -8052,7 +8065,7 @@
     final json = super.toJson();
     json['type'] = type;
     json.addAll({
-      'name': name,
+      'name': name ?? '',
       'types': types?.map((f) => f.toJson()).toList(),
     });
     return json;
@@ -8245,8 +8258,8 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'major': major,
-      'minor': minor,
+      'major': major ?? -1,
+      'minor': minor ?? -1,
     });
     return json;
   }
@@ -8278,7 +8291,7 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'name': name,
+      'name': name ?? '',
     });
     return json;
   }
@@ -8376,14 +8389,14 @@
     final json = <String, dynamic>{};
     json['type'] = type;
     json.addAll({
-      'name': name,
-      'architectureBits': architectureBits,
-      'hostCPU': hostCPU,
-      'operatingSystem': operatingSystem,
-      'targetCPU': targetCPU,
-      'version': version,
-      'pid': pid,
-      'startTime': startTime,
+      'name': name ?? '',
+      'architectureBits': architectureBits ?? -1,
+      'hostCPU': hostCPU ?? '',
+      'operatingSystem': operatingSystem ?? '',
+      'targetCPU': targetCPU ?? '',
+      'version': version ?? '',
+      'pid': pid ?? -1,
+      'startTime': startTime ?? -1,
       'isolates': isolates?.map((f) => f.toJson()).toList(),
       'isolateGroups': isolateGroups?.map((f) => f.toJson()).toList(),
       'systemIsolates': systemIsolates?.map((f) => f.toJson()).toList(),
diff --git a/pkg/vm_service/test/source_report_package_filters_test.dart b/pkg/vm_service/test/source_report_package_filters_test.dart
index d174524..203aa56 100644
--- a/pkg/vm_service/test/source_report_package_filters_test.dart
+++ b/pkg/vm_service/test/source_report_package_filters_test.dart
@@ -12,7 +12,7 @@
 
 void testFunction() {
   // Use functions from various packages, so we can get coverage for them.
-  print(sqrt(123)); // dart:math
+  print(Point(123, 456)); // dart:math
   print(anything); // package:test/test.dart
   print(decodeBase64("SGkh")); // package:vm_service/vm_service.dart
   print(removeAdjacentDuplicates([])); // common/service_test_common.dart
@@ -71,11 +71,11 @@
   ),
   filterTestContains(
     ['dart:math'],
-    ['dart:math'],
+    ['dart:math/point.dart'],
   ),
   filterTestContains(
-    ['package:test/', 'package:vm'],
-    ['package:test/test.dart', 'package:vm_service/vm_service.dart'],
+    ['package:vm'],
+    ['package:vm_service/src/vm_service.dart'],
   ),
   resumeIsolate,
 ];
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index f972a69..6aeae39 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -726,9 +726,9 @@
             return result;
           };
           if (m.deprecated) {
-            gen.writeln("// ignore: deprecated_member_use_from_same_package");
+            gen.writeln('// ignore: deprecated_member_use_from_same_package');
           }
-          gen.write("response = await _serviceImplementation.${m.name}(");
+          gen.write('response = await _serviceImplementation.${m.name}(');
           // Positional args
           m.args.where((arg) => !arg.optional).forEach((MethodArg arg) {
             if (arg.type.isArray) {
@@ -751,7 +751,7 @@
               }
             });
           }
-          gen.writeln(");");
+          gen.writeln(');');
         }
         gen.writeln('break;');
       }
@@ -1009,9 +1009,9 @@
         // Special case for `getAllocationProfile`. We do not want to add these
         // params if they are false.
         if (name == 'getAllocationProfile') {
-          gen.writeln("if (${arg.name} != null && ${arg.name})");
+          gen.writeln('if (${arg.name} != null && ${arg.name})');
         } else {
-          gen.writeln("if (${arg.name} != null)");
+          gen.writeln('if (${arg.name} != null)');
         }
         gen.writeln("'${arg.name}': $valueRef,");
       });
@@ -1374,7 +1374,7 @@
 
     // Build from JSON.
     gen.writeln();
-    String superCall = superName == null ? '' : ": super._fromJson(json) ";
+    String superCall = superName == null ? '' : ': super._fromJson(json) ';
     if (name == 'Response' || name == 'TimelineEvent') {
       gen.write('${name}._fromJson(this.json)');
     } else {
@@ -1397,38 +1397,8 @@
         } else {
           gen.write("${field.generatableName} = json['${field.name}']");
         }
-        if (field.defaultValue != null) {
-          gen.write(' ?? ${field.defaultValue}');
-        } else if (!field.optional) {
-          // If a default isn't provided and the field is required, generate a
-          // sane default initializer to avoid TypeErrors at runtime when
-          // running in a null-safe context.
-          dynamic defaultValue;
-          switch (field.type.name) {
-            case 'int':
-            case 'num':
-            case 'double':
-              defaultValue = -1;
-              break;
-            case 'bool':
-              defaultValue = false;
-              break;
-            case 'String':
-              defaultValue = "''";
-              break;
-            case 'ByteData':
-              defaultValue = "ByteData(0)";
-              break;
-            default:
-              {
-                if (field.type.isEnum) {
-                  // TODO(bkonyi): Figure out if there's a more correct way to
-                  // determine a default value for enums.
-                  defaultValue = "''";
-                }
-                break;
-              }
-          }
+        final defaultValue = field.defaultValue;
+        if (defaultValue != null) {
           gen.write(' ?? $defaultValue');
         }
         gen.writeln(';');
@@ -1444,39 +1414,39 @@
       } else if (name == 'Instance' && field.name == 'associations') {
         // Special case `Instance.associations`.
         gen.writeln("associations = json['associations'] == null "
-            "? null : List<MapAssociation>.from("
+            '? null : List<MapAssociation>.from('
             "_createSpecificObject(json['associations'], MapAssociation.parse));");
       } else if (name == 'Instance' && field.name == 'classRef') {
         // This is populated by `Obj`
       } else if (name == '_CpuProfile' && field.name == 'codes') {
         // Special case `_CpuProfile.codes`.
-        gen.writeln("codes = List<CodeRegion>.from("
+        gen.writeln('codes = List<CodeRegion>.from('
             "_createSpecificObject(json['codes']!, CodeRegion.parse));");
       } else if (name == '_CpuProfile' && field.name == 'functions') {
         // Special case `_CpuProfile.functions`.
-        gen.writeln("functions = List<ProfileFunction>.from("
+        gen.writeln('functions = List<ProfileFunction>.from('
             "_createSpecificObject(json['functions']!, ProfileFunction.parse));");
       } else if (name == 'SourceReport' && field.name == 'ranges') {
         // Special case `SourceReport.ranges`.
-        gen.writeln("ranges = List<SourceReportRange>.from("
+        gen.writeln('ranges = List<SourceReportRange>.from('
             "_createSpecificObject(json['ranges']!, SourceReportRange.parse));");
       } else if (name == 'SourceReportRange' && field.name == 'coverage') {
         // Special case `SourceReportRange.coverage`.
-        gen.writeln("coverage = _createSpecificObject("
+        gen.writeln('coverage = _createSpecificObject('
             "json['coverage'], SourceReportCoverage.parse);");
       } else if (name == 'Library' && field.name == 'dependencies') {
         // Special case `Library.dependencies`.
-        gen.writeln("dependencies = List<LibraryDependency>.from("
+        gen.writeln('dependencies = List<LibraryDependency>.from('
             "_createSpecificObject(json['dependencies']!, "
-            "LibraryDependency.parse));");
+            'LibraryDependency.parse));');
       } else if (name == 'Script' && field.name == 'tokenPosTable') {
         // Special case `Script.tokenPosTable`.
-        gen.write("tokenPosTable = ");
+        gen.write('tokenPosTable = ');
         if (field.optional) {
           gen.write("json['tokenPosTable'] == null ? null : ");
         }
         gen.writeln("List<List<int>>.from(json['tokenPosTable']!.map"
-            "((dynamic list) => List<int>.from(list)));");
+            '((dynamic list) => List<int>.from(list)));');
         gen.writeln('_parseTokenPosTable();');
       } else if (field.type.isArray) {
         TypeRef fieldType = field.type.types.first;
@@ -1484,41 +1454,43 @@
         String ref = "json['${field.name}']";
         if (field.optional) {
           if (fieldType.isListTypeSimple) {
-            gen.writeln("${field.generatableName} = $ref == null ? null : "
-                "List<${fieldType.listTypeArg}>.from($ref);");
+            gen.writeln('${field.generatableName} = $ref == null ? null : '
+                'List<${fieldType.listTypeArg}>.from($ref);');
           } else {
-            gen.writeln("${field.generatableName} = $ref == null ? null : "
-                "List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList)! as List);");
+            gen.writeln('${field.generatableName} = $ref == null ? null : '
+                'List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList)! as List);');
           }
         } else {
           if (fieldType.isListTypeSimple) {
             // Special case `ClassHeapStats`. Pre 3.18, responses included keys
             // `new` and `old`. Post 3.18, these will be null.
             if (name == 'ClassHeapStats') {
-              gen.writeln("${field.generatableName} = $ref == null ? null : "
-                  "List<${fieldType.listTypeArg}>.from($ref);");
+              gen.writeln('${field.generatableName} = $ref == null ? null : '
+                  'List<${fieldType.listTypeArg}>.from($ref);');
             } else {
-              gen.writeln("${field.generatableName} = "
-                  "List<${fieldType.listTypeArg}>.from($ref);");
+              gen.writeln('${field.generatableName} = '
+                  'List<${fieldType.listTypeArg}>.from($ref);');
             }
           } else {
             // Special case `InstanceSet`. Pre 3.20, instances were sent in a
             // field named 'samples' instead of 'instances'.
             if (name == 'InstanceSet') {
-              gen.writeln("${field.generatableName} = "
+              gen.writeln('${field.generatableName} = '
                   "List<${fieldType.listTypeArg}>.from(createServiceObject(($ref ?? json['samples']!) as List, $typesList)! as List);");
             } else {
-              gen.writeln("${field.generatableName} = "
-                  "List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList) as List? ?? []);");
+              gen.writeln('${field.generatableName} = '
+                  'List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList) as List? ?? []);');
             }
           }
         }
       } else {
         String typesList = _typeRefListToString(field.type.types);
         String nullable = field.type.name != 'dynamic' ? '?' : '';
-        gen.writeln("${field.generatableName} = "
-            "createServiceObject(json['${field.name}'], "
-            "$typesList) as ${field.type.name}$nullable;");
+        gen.writeln(
+          '${field.generatableName} = '
+          "createServiceObject(json['${field.name}'], "
+          '$typesList) as ${field.type.name}$nullable;',
+        );
       }
     });
     if (fields.isNotEmpty) {
@@ -1615,7 +1587,7 @@
     if (toStringFields.length <= maxFieldsShownInToString) {
       String properties = toStringFields
           .map(
-              (TypeField f) => "${f.generatableName}: \${${f.generatableName}}")
+              (TypeField f) => '${f.generatableName}: \${${f.generatableName}}')
           .join(', ');
       if (properties.length > 60) {
         int index = properties.indexOf(', ', 55);
@@ -1674,8 +1646,9 @@
   void generateSerializedFieldAccess(TypeField field, DartGenerator gen) {
     if (field.type.isSimple || field.type.isEnum) {
       gen.write('${field.generatableName}');
-      if (field.defaultValue != null) {
-        gen.write(' ?? ${field.defaultValue}');
+      final defaultValue = field.defaultValue;
+      if (defaultValue != null) {
+        gen.write(' ?? $defaultValue');
       }
     } else if (name == 'Event' && field.name == 'extensionData') {
       // Special case `Event.extensionData`.
@@ -1785,7 +1758,7 @@
   MemberType type = MemberType();
   String? name;
   bool optional = false;
-  String? defaultValue;
+  String? _defaultValue;
   bool overrides = false;
 
   TypeField(this.parent, this._docs);
@@ -1806,6 +1779,40 @@
     return _nameRemap[name] != null ? _nameRemap[name] : name;
   }
 
+  set defaultValue(String? value) {
+    _defaultValue = value;
+  }
+
+  String? get defaultValue {
+    if (_defaultValue != null) {
+      return _defaultValue;
+    }
+    if (optional) {
+      return null;
+    }
+    // If a default isn't provided and the field is required, generate a sane
+    // default initializer to avoid TypeErrors at runtime when running in a
+    // null-safe context.
+    switch (type.name) {
+      case 'int':
+      case 'num':
+      case 'double':
+        return '-1';
+      case 'bool':
+        return 'false';
+      case 'String':
+        return "''";
+      case 'ByteData':
+        return 'ByteData(0)';
+    }
+    if (type.isEnum) {
+      // TODO(bkonyi): Figure out if there's a more correct way to determine a
+      // default value for enums.
+      return "''";
+    }
+    return null;
+  }
+
   void generate(DartGenerator gen) {
     if (docs!.isNotEmpty) gen.writeDocs(docs);
     if (optional) gen.write('@optional ');
diff --git a/pkg/vm_service/tool/dart/src_gen_dart.dart b/pkg/vm_service/tool/dart/src_gen_dart.dart
index e343e37..3cc9172 100644
--- a/pkg/vm_service/tool/dart/src_gen_dart.dart
+++ b/pkg/vm_service/tool/dart/src_gen_dart.dart
@@ -15,7 +15,7 @@
 
   final int colBoundary;
 
-  String _indent = "";
+  String _indent = '';
   final StringBuffer _buf = StringBuffer();
 
   bool _previousWasEol = false;
@@ -56,27 +56,27 @@
         writeln(str);
       } else {
         writeln(str.substring(0, index + 1));
-        writeln("    ${str.substring(index + 1)}");
+        writeln('    ${str.substring(index + 1)}');
       }
     } else {
       writeln(str);
     }
   }
 
-  void writeln([String str = ""]) => _write("${str}\n");
+  void writeln([String str = '']) => _write('${str}\n');
 
   void write(String str) => _write(str);
 
   void out(String str) => _buf.write(str);
 
-  void _writeln([String str = "", bool ignoreCurlies = false]) =>
-      _write("${str}\n", ignoreCurlies);
+  void _writeln([String str = '', bool ignoreCurlies = false]) =>
+      _write('${str}\n', ignoreCurlies);
 
   void _write(String str, [bool ignoreCurlies = false]) {
     for (final int rune in str.runes) {
       if (!ignoreCurlies) {
         if (rune == RUNE_LEFT_CURLY) {
-          _indent = "${_indent}  ";
+          _indent = '${_indent}  ';
         } else if (rune == RUNE_RIGHT_CURLY && _indent.length >= 2) {
           _indent = _indent.substring(2);
         }
diff --git a/pkg/vm_service/tool/java/generate_java.dart b/pkg/vm_service/tool/java/generate_java.dart
index 9f48c01..d533c5e 100644
--- a/pkg/vm_service/tool/java/generate_java.dart
+++ b/pkg/vm_service/tool/java/generate_java.dart
@@ -213,7 +213,7 @@
         writer.addLine('logUnknownResponse(consumer, json);');
       }, modifiers: null, isOverride: true);
 
-      writer.addMethod("convertMapToJsonObject", [
+      writer.addMethod('convertMapToJsonObject', [
         JavaMethodArg('map', 'Map<String, String>')
       ], (StatementWriter writer) {
         writer.addLine('JsonObject obj = new JsonObject();');
@@ -221,17 +221,17 @@
         writer.addLine('  obj.addProperty(key, map.get(key));');
         writer.addLine('}');
         writer.addLine('return obj;');
-      }, modifiers: "private", returnType: "JsonObject");
+      }, modifiers: 'private', returnType: 'JsonObject');
 
       writer.addMethod(
-          "convertIterableToJsonArray", [JavaMethodArg('list', 'Iterable')],
+          'convertIterableToJsonArray', [JavaMethodArg('list', 'Iterable')],
           (StatementWriter writer) {
         writer.addLine('JsonArray arr = new JsonArray();');
         writer.addLine('for (Object element : list) {');
         writer.addLine('  arr.add(new JsonPrimitive(element.toString()));');
         writer.addLine('}');
         writer.addLine('return arr;');
-      }, modifiers: "private", returnType: "JsonArray");
+      }, modifiers: 'private', returnType: 'JsonArray');
     });
 
     for (var m in methods) {
@@ -534,7 +534,7 @@
       for (var t in returnType.types) {
         writer.addImport(t.elementTypeName);
         writer.addMethod(
-            "received", [JavaMethodArg('response', t.elementTypeName)], null);
+            'received', [JavaMethodArg('response', t.elementTypeName)], null);
       }
     });
   }
@@ -925,7 +925,7 @@
         for (TypeRef t in type.types) {
           String refName = t.name!;
           if (refName.endsWith('Ref')) {
-            refName = "@" + refName.substring(0, refName.length - 3);
+            refName = '@' + refName.substring(0, refName.length - 3);
           }
           w.addLine('if (elem.get("type").getAsString().equals("${refName}")) '
               'return new ${t.name}(elem);');
diff --git a/pkg/vm_service/tool/java/src_gen_java.dart b/pkg/vm_service/tool/java/src_gen_java.dart
index 4342380..9a605a0 100644
--- a/pkg/vm_service/tool/java/src_gen_java.dart
+++ b/pkg/vm_service/tool/java/src_gen_java.dart
@@ -125,10 +125,9 @@
   final Map<String, String> _methods = Map<String, String>();
   final String scriptLocation;
 
-  TypeWriter(String typeName, scriptLocation)
-      : this.pkgName = pkgNameFor(typeName),
-        this.className = classNameFor(typeName),
-        this.scriptLocation = scriptLocation;
+  TypeWriter(String typeName, this.scriptLocation)
+      : pkgName = pkgNameFor(typeName),
+        className = classNameFor(typeName);
 
   String get kind {
     if (isInterface) return 'interface';
diff --git a/pkg/wasm_builder/lib/src/module.dart b/pkg/wasm_builder/lib/src/module.dart
index ced6ed4..d38f51d 100644
--- a/pkg/wasm_builder/lib/src/module.dart
+++ b/pkg/wasm_builder/lib/src/module.dart
@@ -35,6 +35,8 @@
 
   int functionNameCount = 0;
 
+  static const int memoryBlockSize = 0x10000;
+
   /// Create a new, initially empty, module.
   ///
   /// The [watchPoints] is a list of byte offsets within the final module of
@@ -170,7 +172,8 @@
     initialContent ??= Uint8List(0);
     assert((memory != null) == (offset != null));
     assert(memory == null ||
-        offset! >= 0 && offset + initialContent.length <= memory.minSize);
+        offset! >= 0 &&
+            offset + initialContent.length <= memory.minSize * memoryBlockSize);
     final DataSegment data =
         DataSegment(dataSegments.length, initialContent, memory, offset);
     dataSegments.add(data);
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 2877fb3..a22b8ef 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -787,6 +787,9 @@
 
     if (is_win) {
       libs = [
+        # ole32.dll contains CoTaskMemAlloc. Here so that package:ffi can look
+        # CoTaskMemAlloc up with `DynamicLibrary.process()`.
+        "ole32.lib",
         "iphlpapi.lib",
         "psapi.lib",
         "ws2_32.lib",
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 5f2e056..5456c69 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -897,19 +897,13 @@
   return cobject;
 }
 
-Dart_CObject* CObject::NewUint8Array(intptr_t length) {
+Dart_CObject* CObject::NewUint8Array(const void* data, intptr_t length) {
   Dart_CObject* cobject = New(Dart_CObject_kTypedData, length);
+  memmove(reinterpret_cast<uint8_t*>(cobject + 1), data, length);
   cobject->value.as_typed_data.type = Dart_TypedData_kUint8;
   cobject->value.as_typed_data.length = length;
-  cobject->value.as_typed_data.values = reinterpret_cast<uint8_t*>(cobject + 1);
-  return cobject;
-}
-
-Dart_CObject* CObject::NewUint32Array(intptr_t length) {
-  Dart_CObject* cobject = New(Dart_CObject_kTypedData, 4 * length);
-  cobject->value.as_typed_data.type = Dart_TypedData_kUint32;
-  cobject->value.as_typed_data.length = length;
-  cobject->value.as_typed_data.values = reinterpret_cast<uint8_t*>(cobject + 1);
+  cobject->value.as_typed_data.values =
+      reinterpret_cast<const uint8_t*>(cobject + 1);
   return cobject;
 }
 
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 568e70e..694ea9e 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -344,8 +344,7 @@
   static Dart_CObject* NewString(intptr_t length);
   static Dart_CObject* NewString(const char* str);
   static Dart_CObject* NewArray(intptr_t length);
-  static Dart_CObject* NewUint8Array(intptr_t length);
-  static Dart_CObject* NewUint32Array(intptr_t length);
+  static Dart_CObject* NewUint8Array(const void* data, intptr_t length);
   static Dart_CObject* NewExternalUint8Array(intptr_t length,
                                              uint8_t* data,
                                              void* peer,
@@ -547,7 +546,7 @@
     return cobject_->value.as_typed_data.type;
   }
   intptr_t Length() const { return cobject_->value.as_typed_data.length; }
-  uint8_t* Buffer() const { return cobject_->value.as_typed_data.values; }
+  const uint8_t* Buffer() const { return cobject_->value.as_typed_data.values; }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CObjectTypedData);
@@ -558,7 +557,7 @@
   DECLARE_COBJECT_TYPED_DATA_CONSTRUCTORS(Uint8)
 
   intptr_t Length() const { return cobject_->value.as_typed_data.length; }
-  uint8_t* Buffer() const { return cobject_->value.as_typed_data.values; }
+  const uint8_t* Buffer() const { return cobject_->value.as_typed_data.values; }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CObjectUint8Array);
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index e58636e..32fb230 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -550,6 +550,25 @@
   }
 }
 
+void FUNCTION_NAME(File_CreatePipe)(Dart_NativeArguments args) {
+  Namespace* namespc = Namespace::GetNamespace(args, 0);
+
+  File* readPipe;
+  File* writePipe;
+  if (File::CreatePipe(namespc, &readPipe, &writePipe)) {
+    Dart_Handle pipes = ThrowIfError(Dart_NewList(2));
+    Dart_Handle readHandle =
+        ThrowIfError(Dart_NewInteger(reinterpret_cast<intptr_t>(readPipe)));
+    Dart_Handle writeHandle =
+        ThrowIfError(Dart_NewInteger(reinterpret_cast<intptr_t>(writePipe)));
+    ThrowIfError(Dart_ListSetAt(pipes, 0, readHandle));
+    ThrowIfError(Dart_ListSetAt(pipes, 1, writeHandle));
+    Dart_SetReturnValue(args, pipes);
+  } else {
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+  }
+}
+
 void FUNCTION_NAME(File_LinkTarget)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
   Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
@@ -915,6 +934,31 @@
              : CObject::NewOSError();
 }
 
+CObject* File::CreatePipeRequest(const CObjectArray& request) {
+  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
+    return CObject::IllegalArgumentError();
+  }
+  Namespace* namespc = CObjectToNamespacePointer(request[0]);
+  RefCntReleaseScope<Namespace> rs(namespc);
+
+  File* readPipe;
+  File* writePipe;
+  if (!CreatePipe(namespc, &readPipe, &writePipe)) {
+    return CObject::NewOSError();
+  }
+
+  CObjectArray* pipes = new CObjectArray(CObject::NewArray(2));
+  CObjectNativePointer* readHandle = new CObjectNativePointer(
+      CObject::NewNativePointer(reinterpret_cast<intptr_t>(readPipe),
+                                sizeof(*readPipe), ReleaseFile));
+  CObjectNativePointer* writeHandle = new CObjectNativePointer(
+      CObject::NewNativePointer(reinterpret_cast<intptr_t>(writePipe),
+                                sizeof(*writePipe), ReleaseFile));
+  pipes->SetAt(0, readHandle);
+  pipes->SetAt(1, writeHandle);
+  return pipes;
+}
+
 CObject* File::OpenRequest(const CObjectArray& request) {
   if ((request.Length() < 1) || !request[0]->IsIntptr()) {
     return CObject::IllegalArgumentError();
@@ -1351,7 +1395,7 @@
   int64_t start = CObjectInt32OrInt64ToInt64(request[2]);
   int64_t end = CObjectInt32OrInt64ToInt64(request[3]);
   int64_t length = end - start;
-  uint8_t* buffer_start;
+  const uint8_t* buffer_start;
   if (request[1]->IsTypedData()) {
     CObjectTypedData typed_data(request[1]);
     start = start * SizeInBytes(typed_data.Type());
@@ -1359,11 +1403,12 @@
     buffer_start = typed_data.Buffer() + start;
   } else {
     CObjectArray array(request[1]);
-    buffer_start = Dart_ScopeAllocate(length);
+    uint8_t* allocated_buffer = Dart_ScopeAllocate(length);
+    buffer_start = allocated_buffer;
     for (int i = 0; i < length; i++) {
       if (array[i + start]->IsInt32OrInt64()) {
         int64_t value = CObjectInt32OrInt64ToInt64(array[i + start]);
-        buffer_start[i] = static_cast<uint8_t>(value & 0xFF);
+        allocated_buffer[i] = static_cast<uint8_t>(value & 0xFF);
       } else {
         // Unsupported type.
         return CObject::IllegalArgumentError();
@@ -1371,7 +1416,7 @@
     }
     start = 0;
   }
-  return file->WriteFully(reinterpret_cast<void*>(buffer_start), length)
+  return file->WriteFully(reinterpret_cast<const void*>(buffer_start), length)
              ? new CObjectInt64(CObject::NewInt64(length))
              : CObject::NewOSError();
 }
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 836feb4..d58fbea 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -228,10 +228,7 @@
   // (stdin, stout or stderr).
   static File* OpenStdio(int fd);
 
-#if defined(DART_HOST_OS_FUCHSIA) || defined(DART_HOST_OS_LINUX) ||            \
-    defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_MACOS)
   static File* OpenFD(int fd);
-#endif
 
   static bool Exists(Namespace* namespc, const char* path);
   static bool ExistsUri(Namespace* namespc, const char* uri);
@@ -239,6 +236,7 @@
   static bool CreateLink(Namespace* namespc,
                          const char* path,
                          const char* target);
+  static bool CreatePipe(Namespace* namespc, File** readPipe, File** writePipe);
   static bool Delete(Namespace* namespc, const char* path);
   static bool DeleteLink(Namespace* namespc, const char* path);
   static bool Rename(Namespace* namespc,
@@ -297,6 +295,7 @@
 
   static CObject* ExistsRequest(const CObjectArray& request);
   static CObject* CreateRequest(const CObjectArray& request);
+  static CObject* CreatePipeRequest(const CObjectArray& request);
   static CObject* DeleteRequest(const CObjectArray& request);
   static CObject* RenameRequest(const CObjectArray& request);
   static CObject* CopyRequest(const CObjectArray& request);
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index 02378b5..b676fb5 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -334,6 +334,17 @@
   return NO_RETRY_EXPECTED(SymlinkAt(target, ns.fd(), ns.path())) == 0;
 }
 
+bool File::CreatePipe(Namespace* namespc, File** readPipe, File** writePipe) {
+  int pipe_fds[2];
+  int status = NO_RETRY_EXPECTED(pipe(pipe_fds));
+  if (status != 0) {
+    return false;
+  }
+  *readPipe = OpenFD(pipe_fds[0]);
+  *writePipe = OpenFD(pipe_fds[1]);
+  return true;
+}
+
 File::Type File::GetType(Namespace* namespc,
                          const char* name,
                          bool follow_links) {
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc
index 0b5e0fd..c99156c 100644
--- a/runtime/bin/file_fuchsia.cc
+++ b/runtime/bin/file_fuchsia.cc
@@ -332,6 +332,17 @@
   return NO_RETRY_EXPECTED(symlinkat(target, ns.fd(), ns.path())) == 0;
 }
 
+bool File::CreatePipe(Namespace* namespc, File** readPipe, File** writePipe) {
+  int pipe_fds[2];
+  int status = NO_RETRY_EXPECTED(pipe(pipe_fds));
+  if (status != 0) {
+    return false;
+  }
+  *readPipe = OpenFD(pipe_fds[0]);
+  *writePipe = OpenFD(pipe_fds[1]);
+  return true;
+}
+
 File::Type File::GetType(Namespace* namespc,
                          const char* name,
                          bool follow_links) {
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index e209158..6dd6e90 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -328,6 +328,17 @@
   return NO_RETRY_EXPECTED(symlinkat(target, ns.fd(), ns.path())) == 0;
 }
 
+bool File::CreatePipe(Namespace* namespc, File** readPipe, File** writePipe) {
+  int pipe_fds[2];
+  int status = NO_RETRY_EXPECTED(pipe(pipe_fds));
+  if (status != 0) {
+    return false;
+  }
+  *readPipe = OpenFD(pipe_fds[0]);
+  *writePipe = OpenFD(pipe_fds[1]);
+  return true;
+}
+
 File::Type File::GetType(Namespace* namespc,
                          const char* name,
                          bool follow_links) {
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index 15e7ec2..0ad4f1f 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -371,6 +371,17 @@
   return (status == 0);
 }
 
+bool File::CreatePipe(Namespace* namespc, File** readPipe, File** writePipe) {
+  int pipe_fds[2];
+  int status = NO_RETRY_EXPECTED(pipe(pipe_fds));
+  if (status != 0) {
+    return false;
+  }
+  *readPipe = OpenFD(pipe_fds[0]);
+  *writePipe = OpenFD(pipe_fds[1]);
+  return true;
+}
+
 File::Type File::GetType(Namespace* namespc,
                          const char* pathname,
                          bool follow_links) {
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index 22d5734..eb81d16 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -314,12 +314,16 @@
       return NULL;
     }
   }
+  return OpenFD(fd);
+}
+
+File* File::OpenFD(int fd) {
   return new File(new FileHandle(fd));
 }
 
 class StringRAII {
  public:
-  explicit StringRAII(StringRAII& origin) {
+  explicit StringRAII(StringRAII& origin) {  // NOLINT
     own_ = origin.own_;
     s_ = origin.release();
   }
@@ -616,6 +620,17 @@
   return (create_status != 0);
 }
 
+bool File::CreatePipe(Namespace* namespc, File** readPipe, File** writePipe) {
+  int pipe_fds[2];
+  int status = _pipe(pipe_fds, 4096, _O_BINARY);
+  if (status != 0) {
+    return false;
+  }
+  *readPipe = OpenFD(pipe_fds[0]);
+  *writePipe = OpenFD(pipe_fds[1]);
+  return true;
+}
+
 bool File::Delete(Namespace* namespc, const char* name) {
   Utf8ToWideScope system_name(PrefixLongFilePath(name));
   int status = _wremove(system_name.wide());
diff --git a/runtime/bin/io_impl_sources.gni b/runtime/bin/io_impl_sources.gni
index 33090f3..f2c1be7 100644
--- a/runtime/bin/io_impl_sources.gni
+++ b/runtime/bin/io_impl_sources.gni
@@ -85,6 +85,7 @@
   "socket_base_linux.h",
   "socket_base_macos.cc",
   "socket_base_macos.h",
+  "socket_base_posix.cc",
   "socket_base_win.cc",
   "socket_base_win.h",
   "socket_fuchsia.cc",
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 5258357..12e64805 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -40,6 +40,7 @@
   V(File_Copy, 3)                                                              \
   V(File_Create, 3)                                                            \
   V(File_CreateLink, 3)                                                        \
+  V(File_CreatePipe, 1)                                                        \
   V(File_Delete, 2)                                                            \
   V(File_DeleteLink, 2)                                                        \
   V(File_Exists, 2)                                                            \
diff --git a/runtime/bin/io_service.h b/runtime/bin/io_service.h
index 17d020e..e0577a8 100644
--- a/runtime/bin/io_service.h
+++ b/runtime/bin/io_service.h
@@ -48,18 +48,19 @@
   V(File, Identical, 28)                                                       \
   V(File, Stat, 29)                                                            \
   V(File, Lock, 30)                                                            \
-  V(Socket, Lookup, 31)                                                        \
-  V(Socket, ListInterfaces, 32)                                                \
-  V(Socket, ReverseLookup, 33)                                                 \
-  V(Directory, Create, 34)                                                     \
-  V(Directory, Delete, 35)                                                     \
-  V(Directory, Exists, 36)                                                     \
-  V(Directory, CreateTemp, 37)                                                 \
-  V(Directory, ListStart, 38)                                                  \
-  V(Directory, ListNext, 39)                                                   \
-  V(Directory, ListStop, 40)                                                   \
-  V(Directory, Rename, 41)                                                     \
-  V(SSLFilter, ProcessFilter, 42)
+  V(File, CreatePipe, 31)                                                      \
+  V(Socket, Lookup, 32)                                                        \
+  V(Socket, ListInterfaces, 33)                                                \
+  V(Socket, ReverseLookup, 34)                                                 \
+  V(Directory, Create, 35)                                                     \
+  V(Directory, Delete, 36)                                                     \
+  V(Directory, Exists, 37)                                                     \
+  V(Directory, CreateTemp, 38)                                                 \
+  V(Directory, ListStart, 39)                                                  \
+  V(Directory, ListNext, 40)                                                   \
+  V(Directory, ListStop, 41)                                                   \
+  V(Directory, Rename, 42)                                                     \
+  V(SSLFilter, ProcessFilter, 43)
 
 #define DECLARE_REQUEST(type, method, id) k##type##method##Request = id,
 
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index 3371314..aabad9f 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -82,10 +82,26 @@
   Namespace* namespc = Namespace::GetNamespace(args, 1);
   Dart_Handle status_handle = Dart_GetNativeArgument(args, 11);
   Dart_Handle path_handle = Dart_GetNativeArgument(args, 2);
+  Dart_Handle result;
+
+#if DART_HOST_OS_IOS
+  // Do the iOS check here because the return value of Process::Start is
+  // interpreted as a error with 0 meaning success while `ProcessException`
+  // (which will be constructed with `_errorCode`) interprets 0 to mean that
+  // no OS error code was available.
+  result = DartUtils::SetIntegerField(status_handle, "_errorCode", 0);
+  ThrowIfError(result);
+  result = DartUtils::SetStringField(
+      status_handle, "_errorMessage",
+      "Starting new processes is not supported on iOS");
+  ThrowIfError(result);
+  Dart_SetBooleanReturnValue(args, false);
+  return;
+#endif
+
   // The Dart code verifies that the path implements the String
   // interface. However, only builtin Strings are handled by
   // GetStringValue.
-  Dart_Handle result;
   if (!Dart_IsString(path_handle)) {
     result = DartUtils::SetIntegerField(status_handle, "_errorCode", 0);
     ThrowIfError(result);
diff --git a/runtime/bin/socket_base.cc b/runtime/bin/socket_base.cc
index 482163e..de4f259 100644
--- a/runtime/bin/socket_base.cc
+++ b/runtime/bin/socket_base.cc
@@ -218,14 +218,13 @@
 CObjectUint8Array* SocketAddress::ToCObject(const RawAddr& addr) {
   int in_addr_len = SocketAddress::GetInAddrLength(addr);
   const void* in_addr;
-  CObjectUint8Array* data =
-      new CObjectUint8Array(CObject::NewUint8Array(in_addr_len));
   if (addr.addr.sa_family == AF_INET6) {
     in_addr = reinterpret_cast<const void*>(&addr.in6.sin6_addr);
   } else {
     in_addr = reinterpret_cast<const void*>(&addr.in.sin_addr);
   }
-  memmove(data->Buffer(), in_addr, in_addr_len);
+  CObjectUint8Array* data =
+      new CObjectUint8Array(CObject::NewUint8Array(in_addr, in_addr_len));
   return data;
 }
 void SocketAddress::SetAddrScope(RawAddr* addr, intptr_t scope_id) {
diff --git a/runtime/bin/socket_base_linux.cc b/runtime/bin/socket_base_linux.cc
index f23c23a..dadded1 100644
--- a/runtime/bin/socket_base_linux.cc
+++ b/runtime/bin/socket_base_linux.cc
@@ -26,296 +26,6 @@
 namespace dart {
 namespace bin {
 
-SocketAddress::SocketAddress(struct sockaddr* sa, bool unnamed_unix_socket) {
-  if (unnamed_unix_socket) {
-    // This is an unnamed unix domain socket.
-    as_string_[0] = 0;
-  } else if (sa->sa_family == AF_UNIX) {
-    struct sockaddr_un* un = ((struct sockaddr_un*)sa);
-    memmove(as_string_, un->sun_path, sizeof(un->sun_path));
-  } else {
-    ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
-    if (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa),
-                                          as_string_, INET6_ADDRSTRLEN)) {
-      as_string_[0] = 0;
-    }
-  }
-  socklen_t salen =
-      GetAddrLength(*reinterpret_cast<RawAddr*>(sa), unnamed_unix_socket);
-  memmove(reinterpret_cast<void*>(&addr_), sa, salen);
-}
-
-bool SocketBase::Initialize() {
-  // Nothing to do on Linux.
-  return true;
-}
-
-bool SocketBase::FormatNumericAddress(const RawAddr& addr,
-                                      char* address,
-                                      int len) {
-  socklen_t salen = SocketAddress::GetAddrLength(addr);
-  return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL,
-                                        0, NI_NUMERICHOST) == 0)) != 0;
-}
-
-bool SocketBase::IsBindError(intptr_t error_number) {
-  return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
-         error_number == EINVAL;
-}
-
-intptr_t SocketBase::Available(intptr_t fd) {
-  return FDUtils::AvailableBytes(fd);
-}
-
-intptr_t SocketBase::Read(intptr_t fd,
-                          void* buffer,
-                          intptr_t num_bytes,
-                          SocketOpKind sync) {
-  ASSERT(fd >= 0);
-  ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
-  ASSERT(EAGAIN == EWOULDBLOCK);
-  if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
-    // If the read would block we need to retry and therefore return 0
-    // as the number of bytes written.
-    read_bytes = 0;
-  }
-  return read_bytes;
-}
-
-intptr_t SocketBase::RecvFrom(intptr_t fd,
-                              void* buffer,
-                              intptr_t num_bytes,
-                              RawAddr* addr,
-                              SocketOpKind sync) {
-  ASSERT(fd >= 0);
-  socklen_t addr_len = sizeof(addr->ss);
-  ssize_t read_bytes = TEMP_FAILURE_RETRY(
-      recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
-  if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
-    // If the read would block we need to retry and therefore return 0
-    // as the number of bytes written.
-    read_bytes = 0;
-  }
-  return read_bytes;
-}
-
-bool SocketControlMessage::is_file_descriptors_control_message() {
-  return level_ == SOL_SOCKET && type_ == SCM_RIGHTS;
-}
-
-// /proc/sys/net/core/optmem_max is corresponding kernel setting.
-const size_t kMaxSocketMessageControlLength = 2048;
-
-// if return value is positive or zero - it's number of messages read
-// if it's negative - it's error code
-intptr_t SocketBase::ReceiveMessage(intptr_t fd,
-                                    void* buffer,
-                                    int64_t* p_buffer_num_bytes,
-                                    SocketControlMessage** p_messages,
-                                    SocketOpKind sync,
-                                    OSError* p_oserror) {
-  ASSERT(fd >= 0);
-  ASSERT(p_messages != nullptr);
-  ASSERT(p_buffer_num_bytes != nullptr);
-
-  struct iovec iov[1];
-  memset(iov, 0, sizeof(iov));
-  iov[0].iov_base = buffer;
-  iov[0].iov_len = *p_buffer_num_bytes;
-
-  struct msghdr msg;
-  memset(&msg, 0, sizeof(msg));
-  msg.msg_iov = iov;
-  msg.msg_iovlen = 1;  // number of elements in iov
-  uint8_t control_buffer[kMaxSocketMessageControlLength];
-  msg.msg_control = control_buffer;
-  msg.msg_controllen = sizeof(control_buffer);
-
-  ssize_t read_bytes = TEMP_FAILURE_RETRY(recvmsg(fd, &msg, MSG_CMSG_CLOEXEC));
-  if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
-    // If the read would block we need to retry and therefore return 0
-    // as the number of bytes read.
-    return 0;
-  }
-  if (read_bytes < 0) {
-    p_oserror->Reload();
-    return read_bytes;
-  }
-  *p_buffer_num_bytes = read_bytes;
-
-  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
-  size_t num_messages = 0;
-  while (cmsg != nullptr) {
-    num_messages++;
-    cmsg = CMSG_NXTHDR(&msg, cmsg);
-  }
-  (*p_messages) = reinterpret_cast<SocketControlMessage*>(
-      Dart_ScopeAllocate(sizeof(SocketControlMessage) * num_messages));
-  SocketControlMessage* control_message = *p_messages;
-  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != nullptr;
-       cmsg = CMSG_NXTHDR(&msg, cmsg), control_message++) {
-    void* data = CMSG_DATA(cmsg);
-    size_t data_length = cmsg->cmsg_len - (reinterpret_cast<uint8_t*>(data) -
-                                           reinterpret_cast<uint8_t*>(cmsg));
-    void* copied_data = Dart_ScopeAllocate(data_length);
-    ASSERT(copied_data != nullptr);
-    memmove(copied_data, data, data_length);
-    ASSERT(cmsg->cmsg_level == SOL_SOCKET);
-    ASSERT(cmsg->cmsg_type == SCM_RIGHTS);
-    new (control_message) SocketControlMessage(
-        cmsg->cmsg_level, cmsg->cmsg_type, copied_data, data_length);
-  }
-  return num_messages;
-}
-
-bool SocketBase::AvailableDatagram(intptr_t fd,
-                                   void* buffer,
-                                   intptr_t num_bytes) {
-  ASSERT(fd >= 0);
-  ssize_t read_bytes =
-      TEMP_FAILURE_RETRY(recvfrom(fd, buffer, num_bytes, MSG_PEEK, NULL, NULL));
-  return read_bytes >= 0;
-}
-
-intptr_t SocketBase::Write(intptr_t fd,
-                           const void* buffer,
-                           intptr_t num_bytes,
-                           SocketOpKind sync) {
-  ASSERT(fd >= 0);
-  ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
-  ASSERT(EAGAIN == EWOULDBLOCK);
-  if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
-    // If the would block we need to retry and therefore return 0 as
-    // the number of bytes written.
-    written_bytes = 0;
-  }
-  return written_bytes;
-}
-
-intptr_t SocketBase::SendTo(intptr_t fd,
-                            const void* buffer,
-                            intptr_t num_bytes,
-                            const RawAddr& addr,
-                            SocketOpKind sync) {
-  ASSERT(fd >= 0);
-  ssize_t written_bytes =
-      TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr,
-                                SocketAddress::GetAddrLength(addr)));
-  ASSERT(EAGAIN == EWOULDBLOCK);
-  if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
-    // If the would block we need to retry and therefore return 0 as
-    // the number of bytes written.
-    written_bytes = 0;
-  }
-  return written_bytes;
-}
-
-intptr_t SocketBase::SendMessage(intptr_t fd,
-                                 void* buffer,
-                                 size_t num_bytes,
-                                 SocketControlMessage* messages,
-                                 intptr_t num_messages,
-                                 SocketOpKind sync,
-                                 OSError* p_oserror) {
-  ASSERT(fd >= 0);
-
-  struct iovec iov = {
-      .iov_base = buffer,
-      .iov_len = num_bytes,
-  };
-
-  struct msghdr msg;
-  memset(&msg, 0, sizeof(msg));
-  msg.msg_iov = &iov;
-  msg.msg_iovlen = 1;
-
-  if (messages != nullptr && num_messages > 0) {
-    SocketControlMessage* message = messages;
-    size_t total_length = 0;
-    for (intptr_t i = 0; i < num_messages; i++, message++) {
-      total_length += CMSG_SPACE(message->data_length());
-    }
-
-    uint8_t* control_buffer =
-        reinterpret_cast<uint8_t*>(Dart_ScopeAllocate(total_length));
-    memset(control_buffer, 0, total_length);
-    msg.msg_control = control_buffer;
-    msg.msg_controllen = total_length;
-
-    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
-    message = messages;
-    for (intptr_t i = 0; i < num_messages;
-         i++, message++, cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-      ASSERT(message->is_file_descriptors_control_message());
-      cmsg->cmsg_level = SOL_SOCKET;
-      cmsg->cmsg_type = SCM_RIGHTS;
-
-      intptr_t data_length = message->data_length();
-      cmsg->cmsg_len = CMSG_LEN(data_length);
-      memmove(CMSG_DATA(cmsg), message->data(), data_length);
-    }
-    msg.msg_controllen = total_length;
-  }
-
-  ssize_t written_bytes = TEMP_FAILURE_RETRY(sendmsg(fd, &msg, 0));
-  ASSERT(EAGAIN == EWOULDBLOCK);
-  if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
-    // If the would block we need to retry and therefore return 0 as
-    // the number of bytes written.
-    written_bytes = 0;
-  }
-  if (written_bytes < 0) {
-    p_oserror->Reload();
-  }
-
-  return written_bytes;
-}
-
-bool SocketBase::GetSocketName(intptr_t fd, SocketAddress* p_sa) {
-  ASSERT(fd >= 0);
-  ASSERT(p_sa != nullptr);
-  RawAddr raw;
-  socklen_t size = sizeof(raw);
-  if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
-    return false;
-  }
-
-  // sockaddr_un contains sa_family_t sun_family and char[] sun_path.
-  // If size is the size of sa_family_t, this is an unnamed socket and
-  // sun_path contains garbage.
-  new (p_sa) SocketAddress(&raw.addr,
-                           /*unnamed_unix_socket=*/size == sizeof(sa_family_t));
-  return true;
-}
-
-intptr_t SocketBase::GetPort(intptr_t fd) {
-  ASSERT(fd >= 0);
-  RawAddr raw;
-  socklen_t size = sizeof(raw);
-  if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
-    return 0;
-  }
-  return SocketAddress::GetAddrPort(raw);
-}
-
-SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) {
-  ASSERT(fd >= 0);
-  RawAddr raw;
-  socklen_t size = sizeof(raw);
-  if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) {
-    return NULL;
-  }
-  // sockaddr_un contains sa_family_t sun_family and char[] sun_path.
-  // If size is the size of sa_family_t, this is an unnamed socket and
-  // sun_path contains garbage.
-  if (size == sizeof(sa_family_t)) {
-    *port = 0;
-    return new SocketAddress(&raw.addr, /*unnamed_unix_socket=*/true);
-  }
-  *port = SocketAddress::GetAddrPort(raw);
-  return new SocketAddress(&raw.addr);
-}
-
 void SocketBase::GetError(intptr_t fd, OSError* os_error) {
   int len = sizeof(errno);
   int err = 0;
@@ -343,10 +53,6 @@
   return File::kOther;
 }
 
-intptr_t SocketBase::GetStdioHandle(intptr_t num) {
-  return num;
-}
-
 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host,
                                                       int type,
                                                       OSError** os_error) {
@@ -389,137 +95,6 @@
   return addresses;
 }
 
-bool SocketBase::ReverseLookup(const RawAddr& addr,
-                               char* host,
-                               intptr_t host_len,
-                               OSError** os_error) {
-  ASSERT(host_len >= NI_MAXHOST);
-  int status = NO_RETRY_EXPECTED(
-      getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host,
-                  host_len, NULL, 0, NI_NAMEREQD));
-  if (status != 0) {
-    ASSERT(*os_error == NULL);
-    *os_error =
-        new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
-    return false;
-  }
-  return true;
-}
-
-bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) {
-  int result;
-  if (type == SocketAddress::TYPE_IPV4) {
-    result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr));
-  } else {
-    ASSERT(type == SocketAddress::TYPE_IPV6);
-    result =
-        NO_RETRY_EXPECTED(inet_pton(AF_INET6, address, &addr->in6.sin6_addr));
-  }
-  return (result == 1);
-}
-
-bool SocketBase::RawAddrToString(RawAddr* addr, char* str) {
-  if (addr->addr.sa_family == AF_INET) {
-    return inet_ntop(AF_INET, &addr->in.sin_addr, str, INET_ADDRSTRLEN) != NULL;
-  } else {
-    ASSERT(addr->addr.sa_family == AF_INET6);
-    return inet_ntop(AF_INET6, &addr->in6.sin6_addr, str, INET6_ADDRSTRLEN) !=
-           NULL;
-  }
-}
-
-static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
-  if (ifa->ifa_addr == NULL) {
-    // OpenVPN's virtual device tun0.
-    return false;
-  }
-  int family = ifa->ifa_addr->sa_family;
-  return ((lookup_family == family) ||
-          (((lookup_family == AF_UNSPEC) &&
-            ((family == AF_INET) || (family == AF_INET6)))));
-}
-
-bool SocketBase::ListInterfacesSupported() {
-  return true;
-}
-
-AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
-    int type,
-    OSError** os_error) {
-  struct ifaddrs* ifaddr;
-
-  int status = NO_RETRY_EXPECTED(getifaddrs(&ifaddr));
-  if (status != 0) {
-    ASSERT(*os_error == NULL);
-    *os_error =
-        new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
-    return NULL;
-  }
-
-  int lookup_family = SocketAddress::FromType(type);
-
-  intptr_t count = 0;
-  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
-    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
-      count++;
-    }
-  }
-
-  AddressList<InterfaceSocketAddress>* addresses =
-      new AddressList<InterfaceSocketAddress>(count);
-  int i = 0;
-  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
-    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
-      char* ifa_name = DartUtils::ScopedCopyCString(ifa->ifa_name);
-      addresses->SetAt(
-          i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name,
-                                        if_nametoindex(ifa->ifa_name)));
-      i++;
-    }
-  }
-  freeifaddrs(ifaddr);
-  return addresses;
-}
-
-void SocketBase::Close(intptr_t fd) {
-  ASSERT(fd >= 0);
-  close(fd);
-}
-
-bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) {
-  int on;
-  socklen_t len = sizeof(on);
-  int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
-                                         reinterpret_cast<void*>(&on), &len));
-  if (err == 0) {
-    *enabled = (on == 1);
-  }
-  return (err == 0);
-}
-
-bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) {
-  int on = enabled ? 1 : 0;
-  return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
-                                      reinterpret_cast<char*>(&on),
-                                      sizeof(on))) == 0;
-}
-
-bool SocketBase::GetMulticastLoop(intptr_t fd,
-                                  intptr_t protocol,
-                                  bool* enabled) {
-  uint8_t on;
-  socklen_t len = sizeof(on);
-  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
-  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
-                                                     : IPV6_MULTICAST_LOOP;
-  if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
-                                   reinterpret_cast<char*>(&on), &len)) == 0) {
-    *enabled = (on == 1);
-    return true;
-  }
-  return false;
-}
-
 bool SocketBase::SetMulticastLoop(intptr_t fd,
                                   intptr_t protocol,
                                   bool enabled) {
@@ -532,55 +107,6 @@
          0;
 }
 
-bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
-  uint8_t v;
-  socklen_t len = sizeof(v);
-  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
-  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
-                                                     : IPV6_MULTICAST_HOPS;
-  if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
-                                   reinterpret_cast<char*>(&v), &len)) == 0) {
-    *value = v;
-    return true;
-  }
-  return false;
-}
-
-bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
-  int v = value;
-  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
-  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
-                                                     : IPV6_MULTICAST_HOPS;
-  return NO_RETRY_EXPECTED(setsockopt(
-             fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0;
-}
-
-bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) {
-  int on;
-  socklen_t len = sizeof(on);
-  int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST,
-                                         reinterpret_cast<char*>(&on), &len));
-  if (err == 0) {
-    *enabled = (on == 1);
-  }
-  return (err == 0);
-}
-
-bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) {
-  int on = enabled ? 1 : 0;
-  return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
-                                      reinterpret_cast<char*>(&on),
-                                      sizeof(on))) == 0;
-}
-
-bool SocketBase::SetOption(intptr_t fd,
-                           int level,
-                           int option,
-                           const char* data,
-                           int length) {
-  return NO_RETRY_EXPECTED(setsockopt(fd, level, option, data, length)) == 0;
-}
-
 bool SocketBase::GetOption(intptr_t fd,
                            int level,
                            int option,
diff --git a/runtime/bin/socket_base_macos.cc b/runtime/bin/socket_base_macos.cc
index 1b4cbcc..d29e095 100644
--- a/runtime/bin/socket_base_macos.cc
+++ b/runtime/bin/socket_base_macos.cc
@@ -25,191 +25,6 @@
 namespace dart {
 namespace bin {
 
-SocketAddress::SocketAddress(struct sockaddr* sa, bool unnamed_unix_socket) {
-  if (unnamed_unix_socket) {
-    // This is an unnamed unix domain socket.
-    as_string_[0] = 0;
-  } else if (sa->sa_family == AF_UNIX) {
-    struct sockaddr_un* un = ((struct sockaddr_un*)sa);
-    memmove(as_string_, un->sun_path, sizeof(un->sun_path));
-  } else {
-    ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
-    if (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa),
-                                          as_string_, INET6_ADDRSTRLEN)) {
-      as_string_[0] = 0;
-    }
-  }
-  socklen_t salen =
-      GetAddrLength(*reinterpret_cast<RawAddr*>(sa), unnamed_unix_socket);
-  memmove(reinterpret_cast<void*>(&addr_), sa, salen);
-}
-
-bool SocketBase::Initialize() {
-  // Nothing to do on Mac OS.
-  return true;
-}
-
-bool SocketBase::FormatNumericAddress(const RawAddr& addr,
-                                      char* address,
-                                      int len) {
-  socklen_t salen = SocketAddress::GetAddrLength(addr);
-  return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL,
-                                        0, NI_NUMERICHOST)) == 0);
-}
-
-bool SocketBase::IsBindError(intptr_t error_number) {
-  return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
-         error_number == EINVAL;
-}
-
-intptr_t SocketBase::Available(intptr_t fd) {
-  return FDUtils::AvailableBytes(fd);
-}
-
-intptr_t SocketBase::Read(intptr_t fd,
-                          void* buffer,
-                          intptr_t num_bytes,
-                          SocketOpKind sync) {
-  ASSERT(fd >= 0);
-  ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
-  ASSERT(EAGAIN == EWOULDBLOCK);
-  if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
-    // If the read would block we need to retry and therefore return 0
-    // as the number of bytes written.
-    read_bytes = 0;
-  }
-  return read_bytes;
-}
-
-intptr_t SocketBase::RecvFrom(intptr_t fd,
-                              void* buffer,
-                              intptr_t num_bytes,
-                              RawAddr* addr,
-                              SocketOpKind sync) {
-  ASSERT(fd >= 0);
-  socklen_t addr_len = sizeof(addr->ss);
-  ssize_t read_bytes = TEMP_FAILURE_RETRY(
-      recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
-  if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
-    // If the read would block we need to retry and therefore return 0
-    // as the number of bytes written.
-    read_bytes = 0;
-  }
-  return read_bytes;
-}
-
-bool SocketControlMessage::is_file_descriptors_control_message() {
-  return false;
-}
-
-intptr_t SocketBase::ReceiveMessage(intptr_t fd,
-                                    void* buffer,
-                                    int64_t* p_buffer_num_bytes,
-                                    SocketControlMessage** p_messages,
-                                    SocketOpKind sync,
-                                    OSError* p_oserror) {
-  errno = ENOSYS;
-  return -1;
-}
-
-bool SocketBase::AvailableDatagram(intptr_t fd,
-                                   void* buffer,
-                                   intptr_t num_bytes) {
-  ASSERT(fd >= 0);
-  ssize_t read_bytes =
-      TEMP_FAILURE_RETRY(recvfrom(fd, buffer, num_bytes, MSG_PEEK, NULL, NULL));
-  return read_bytes >= 0;
-}
-
-intptr_t SocketBase::Write(intptr_t fd,
-                           const void* buffer,
-                           intptr_t num_bytes,
-                           SocketOpKind sync) {
-  ASSERT(fd >= 0);
-  ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
-  ASSERT(EAGAIN == EWOULDBLOCK);
-  if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
-    // If the would block we need to retry and therefore return 0 as
-    // the number of bytes written.
-    written_bytes = 0;
-  }
-  return written_bytes;
-}
-
-intptr_t SocketBase::SendTo(intptr_t fd,
-                            const void* buffer,
-                            intptr_t num_bytes,
-                            const RawAddr& addr,
-                            SocketOpKind sync) {
-  ASSERT(fd >= 0);
-  ssize_t written_bytes =
-      TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr,
-                                SocketAddress::GetAddrLength(addr)));
-  ASSERT(EAGAIN == EWOULDBLOCK);
-  if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
-    // If the would block we need to retry and therefore return 0 as
-    // the number of bytes written.
-    written_bytes = 0;
-  }
-  return written_bytes;
-}
-
-intptr_t SocketBase::SendMessage(intptr_t fd,
-                                 void* buffer,
-                                 size_t num_bytes,
-                                 SocketControlMessage* messages,
-                                 intptr_t num_messages,
-                                 SocketOpKind sync,
-                                 OSError* p_oserror) {
-  errno = ENOSYS;
-  return -1;
-}
-
-bool SocketBase::GetSocketName(intptr_t fd, SocketAddress* p_sa) {
-  ASSERT(fd >= 0);
-  ASSERT(p_sa != nullptr);
-  RawAddr raw;
-  socklen_t size = sizeof(raw);
-  if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
-    return false;
-  }
-
-  // sockaddr_un contains sa_family_t sun_family and char[] sun_path.
-  // If size is the size of sa_family_t, this is an unnamed socket and
-  // sun_path contains garbage.
-  new (p_sa) SocketAddress(&raw.addr,
-                           /*unnamed_unix_socket=*/size == sizeof(sa_family_t));
-  return true;
-}
-
-intptr_t SocketBase::GetPort(intptr_t fd) {
-  ASSERT(fd >= 0);
-  RawAddr raw;
-  socklen_t size = sizeof(raw);
-  if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
-    return 0;
-  }
-  return SocketAddress::GetAddrPort(raw);
-}
-
-SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) {
-  ASSERT(fd >= 0);
-  RawAddr raw;
-  socklen_t size = sizeof(raw);
-  if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) {
-    return NULL;
-  }
-  // sockaddr_un contains sa_family_t sun_familty and char[] sun_path.
-  // If size is the size of sa_familty_t, this is an unnamed socket and
-  // sun_path contains garbage.
-  if (size == sizeof(sa_family_t)) {
-    *port = 0;
-    return new SocketAddress(&raw.addr, true);
-  }
-  *port = SocketAddress::GetAddrPort(raw);
-  return new SocketAddress(&raw.addr);
-}
-
 void SocketBase::GetError(intptr_t fd, OSError* os_error) {
   int len = sizeof(errno);
   getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno,
@@ -235,10 +50,6 @@
   return File::kOther;
 }
 
-intptr_t SocketBase::GetStdioHandle(intptr_t num) {
-  return num;
-}
-
 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host,
                                                       int type,
                                                       OSError** os_error) {
@@ -275,136 +86,6 @@
   return addresses;
 }
 
-bool SocketBase::ReverseLookup(const RawAddr& addr,
-                               char* host,
-                               intptr_t host_len,
-                               OSError** os_error) {
-  ASSERT(host_len >= NI_MAXHOST);
-  int status = NO_RETRY_EXPECTED(
-      getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host,
-                  host_len, NULL, 0, NI_NAMEREQD));
-  if (status != 0) {
-    ASSERT(*os_error == NULL);
-    *os_error =
-        new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
-    return false;
-  }
-  return true;
-}
-
-bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) {
-  int result;
-  if (type == SocketAddress::TYPE_IPV4) {
-    result = inet_pton(AF_INET, address, &addr->in.sin_addr);
-  } else {
-    ASSERT(type == SocketAddress::TYPE_IPV6);
-    result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr);
-  }
-  return (result == 1);
-}
-
-bool SocketBase::RawAddrToString(RawAddr* addr, char* str) {
-  if (addr->addr.sa_family == AF_INET) {
-    return inet_ntop(AF_INET, &addr->in.sin_addr, str, INET_ADDRSTRLEN) != NULL;
-  } else {
-    ASSERT(addr->addr.sa_family == AF_INET6);
-    return inet_ntop(AF_INET6, &addr->in6.sin6_addr, str, INET6_ADDRSTRLEN) !=
-           NULL;
-  }
-}
-
-static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
-  if (ifa->ifa_addr == NULL) {
-    // OpenVPN's virtual device tun0.
-    return false;
-  }
-  int family = ifa->ifa_addr->sa_family;
-  return ((lookup_family == family) ||
-          ((lookup_family == AF_UNSPEC) &&
-           ((family == AF_INET) || (family == AF_INET6))));
-}
-
-bool SocketBase::ListInterfacesSupported() {
-  return true;
-}
-
-AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
-    int type,
-    OSError** os_error) {
-  struct ifaddrs* ifaddr;
-
-  int status = getifaddrs(&ifaddr);
-  if (status != 0) {
-    ASSERT(*os_error == NULL);
-    *os_error =
-        new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
-    return NULL;
-  }
-
-  int lookup_family = SocketAddress::FromType(type);
-
-  intptr_t count = 0;
-  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
-    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
-      count++;
-    }
-  }
-
-  AddressList<InterfaceSocketAddress>* addresses =
-      new AddressList<InterfaceSocketAddress>(count);
-  int i = 0;
-  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
-    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
-      char* ifa_name = DartUtils::ScopedCopyCString(ifa->ifa_name);
-      addresses->SetAt(
-          i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name,
-                                        if_nametoindex(ifa->ifa_name)));
-      i++;
-    }
-  }
-  freeifaddrs(ifaddr);
-  return addresses;
-}
-
-void SocketBase::Close(intptr_t fd) {
-  ASSERT(fd >= 0);
-  close(fd);
-}
-
-bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) {
-  int on;
-  socklen_t len = sizeof(on);
-  int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
-                                         reinterpret_cast<void*>(&on), &len));
-  if (err == 0) {
-    *enabled = (on == 1);
-  }
-  return (err == 0);
-}
-
-bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) {
-  int on = enabled ? 1 : 0;
-  return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
-                                      reinterpret_cast<char*>(&on),
-                                      sizeof(on))) == 0;
-}
-
-bool SocketBase::GetMulticastLoop(intptr_t fd,
-                                  intptr_t protocol,
-                                  bool* enabled) {
-  uint8_t on;
-  socklen_t len = sizeof(on);
-  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
-  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
-                                                     : IPV6_MULTICAST_LOOP;
-  if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
-                                   reinterpret_cast<char*>(&on), &len)) == 0) {
-    *enabled = (on == 1);
-    return true;
-  }
-  return false;
-}
-
 bool SocketBase::SetMulticastLoop(intptr_t fd,
                                   intptr_t protocol,
                                   bool enabled) {
@@ -417,55 +98,6 @@
          0;
 }
 
-bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
-  uint8_t v;
-  socklen_t len = sizeof(v);
-  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
-  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
-                                                     : IPV6_MULTICAST_HOPS;
-  if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
-                                   reinterpret_cast<char*>(&v), &len)) == 0) {
-    *value = v;
-    return true;
-  }
-  return false;
-}
-
-bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
-  int v = value;
-  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
-  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
-                                                     : IPV6_MULTICAST_HOPS;
-  return NO_RETRY_EXPECTED(setsockopt(
-             fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0;
-}
-
-bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) {
-  int on;
-  socklen_t len = sizeof(on);
-  int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST,
-                                         reinterpret_cast<char*>(&on), &len));
-  if (err == 0) {
-    *enabled = (on == 1);
-  }
-  return (err == 0);
-}
-
-bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) {
-  int on = enabled ? 1 : 0;
-  return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
-                                      reinterpret_cast<char*>(&on),
-                                      sizeof(on))) == 0;
-}
-
-bool SocketBase::SetOption(intptr_t fd,
-                           int level,
-                           int option,
-                           const char* data,
-                           int length) {
-  return NO_RETRY_EXPECTED(setsockopt(fd, level, option, data, length)) == 0;
-}
-
 bool SocketBase::GetOption(intptr_t fd,
                            int level,
                            int option,
diff --git a/runtime/bin/socket_base_posix.cc b/runtime/bin/socket_base_posix.cc
new file mode 100644
index 0000000..e5c48c2
--- /dev/null
+++ b/runtime/bin/socket_base_posix.cc
@@ -0,0 +1,522 @@
+// 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 "platform/globals.h"
+#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS)
+#include "bin/socket_base.h"
+
+#include <errno.h>        // NOLINT
+#include <ifaddrs.h>      // NOLINT
+#include <net/if.h>       // NOLINT
+#include <netinet/tcp.h>  // NOLINT
+#include <stdio.h>        // NOLINT
+#include <stdlib.h>       // NOLINT
+#include <string.h>       // NOLINT
+#include <sys/stat.h>     // NOLINT
+#include <unistd.h>       // NOLINT
+
+#include "bin/fdutils.h"
+#include "bin/file.h"
+#include "bin/socket_base_macos.h"
+#include "platform/signal_blocker.h"
+
+namespace dart {
+namespace bin {
+
+SocketAddress::SocketAddress(struct sockaddr* sa, bool unnamed_unix_socket) {
+  if (unnamed_unix_socket) {
+    // This is an unnamed unix domain socket.
+    as_string_[0] = 0;
+  } else if (sa->sa_family == AF_UNIX) {
+    struct sockaddr_un* un = ((struct sockaddr_un*)sa);
+    memmove(as_string_, un->sun_path, sizeof(un->sun_path));
+  } else {
+    ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
+    if (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa),
+                                          as_string_, INET6_ADDRSTRLEN)) {
+      as_string_[0] = 0;
+    }
+  }
+  socklen_t salen =
+      GetAddrLength(*reinterpret_cast<RawAddr*>(sa), unnamed_unix_socket);
+  memmove(reinterpret_cast<void*>(&addr_), sa, salen);
+}
+
+bool SocketBase::Initialize() {
+  // Nothing to do on Posix.
+  return true;
+}
+
+bool SocketBase::FormatNumericAddress(const RawAddr& addr,
+                                      char* address,
+                                      int len) {
+  socklen_t salen = SocketAddress::GetAddrLength(addr);
+  return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL,
+                                        0, NI_NUMERICHOST)) == 0);
+}
+
+bool SocketBase::IsBindError(intptr_t error_number) {
+  return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
+         error_number == EINVAL;
+}
+
+intptr_t SocketBase::Available(intptr_t fd) {
+  return FDUtils::AvailableBytes(fd);
+}
+
+intptr_t SocketBase::Read(intptr_t fd,
+                          void* buffer,
+                          intptr_t num_bytes,
+                          SocketOpKind sync) {
+  ASSERT(fd >= 0);
+  ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
+  ASSERT(EAGAIN == EWOULDBLOCK);
+  if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
+    // If the read would block we need to retry and therefore return 0
+    // as the number of bytes written.
+    read_bytes = 0;
+  }
+  return read_bytes;
+}
+
+intptr_t SocketBase::RecvFrom(intptr_t fd,
+                              void* buffer,
+                              intptr_t num_bytes,
+                              RawAddr* addr,
+                              SocketOpKind sync) {
+  ASSERT(fd >= 0);
+  socklen_t addr_len = sizeof(addr->ss);
+  ssize_t read_bytes = TEMP_FAILURE_RETRY(
+      recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
+  if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
+    // If the read would block we need to retry and therefore return 0
+    // as the number of bytes written.
+    read_bytes = 0;
+  }
+  return read_bytes;
+}
+
+bool SocketControlMessage::is_file_descriptors_control_message() {
+  return level_ == SOL_SOCKET && type_ == SCM_RIGHTS;
+}
+
+// The maximum size on macOS is not documented so use the same size as Linux.
+// If the sender message size is larger than this then some
+// SocketControlMessages may not be received.
+// /proc/sys/net/core/optmem_max is corresponding kernel setting.
+const size_t kMaxSocketMessageControlLength = 2048;
+
+intptr_t SocketBase::ReceiveMessage(intptr_t fd,
+                                    void* buffer,
+                                    int64_t* p_buffer_num_bytes,
+                                    SocketControlMessage** p_messages,
+                                    SocketOpKind sync,
+                                    OSError* p_oserror) {
+  ASSERT(fd >= 0);
+  ASSERT(p_messages != nullptr);
+  ASSERT(p_buffer_num_bytes != nullptr);
+
+  struct iovec iov[1];
+  memset(iov, 0, sizeof(iov));
+  iov[0].iov_base = buffer;
+  iov[0].iov_len = *p_buffer_num_bytes;
+
+  struct msghdr msg;
+  memset(&msg, 0, sizeof(msg));
+  msg.msg_iov = iov;
+  msg.msg_iovlen = 1;  // number of elements in iov
+  uint8_t control_buffer[kMaxSocketMessageControlLength];
+  msg.msg_control = control_buffer;
+  msg.msg_controllen = sizeof(control_buffer);
+
+  int flags = 0;
+#ifdef MSG_CMSG_CLOEXEC
+  // MSG_CMSG_CLOEXEC is not supported on macOS.
+  flags &= MSG_CMSG_CLOEXEC;
+#endif
+  ssize_t read_bytes = TEMP_FAILURE_RETRY(recvmsg(fd, &msg, flags));
+  if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
+    // If the read would block we need to retry and therefore return 0
+    // as the number of bytes read.
+    return 0;
+  }
+  if (read_bytes < 0) {
+    p_oserror->Reload();
+    return read_bytes;
+  }
+  *p_buffer_num_bytes = read_bytes;
+
+  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+  size_t num_messages = 0;
+  while (cmsg != nullptr) {
+    num_messages++;
+    cmsg = CMSG_NXTHDR(&msg, cmsg);
+  }
+  (*p_messages) = reinterpret_cast<SocketControlMessage*>(
+      Dart_ScopeAllocate(sizeof(SocketControlMessage) * num_messages));
+  SocketControlMessage* control_message = *p_messages;
+  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != nullptr;
+       cmsg = CMSG_NXTHDR(&msg, cmsg), control_message++) {
+    void* data = CMSG_DATA(cmsg);
+    size_t data_length = cmsg->cmsg_len - (reinterpret_cast<uint8_t*>(data) -
+                                           reinterpret_cast<uint8_t*>(cmsg));
+    void* copied_data = Dart_ScopeAllocate(data_length);
+    ASSERT(copied_data != nullptr);
+    memmove(copied_data, data, data_length);
+    ASSERT(cmsg->cmsg_level == SOL_SOCKET);
+    ASSERT(cmsg->cmsg_type == SCM_RIGHTS);
+    new (control_message) SocketControlMessage(
+        cmsg->cmsg_level, cmsg->cmsg_type, copied_data, data_length);
+
+    int fd;
+    memmove(&fd, CMSG_DATA(cmsg), sizeof(int));
+
+#ifndef MSG_CMSG_CLOEXEC
+    // MSG_CMSG_CLOEXEC is not supported on macOS.
+    if (!FDUtils::SetCloseOnExec(fd)) {
+      FDUtils::SaveErrorAndClose(fd);
+      return -1;
+    }
+#endif
+  }
+  return num_messages;
+}
+
+bool SocketBase::AvailableDatagram(intptr_t fd,
+                                   void* buffer,
+                                   intptr_t num_bytes) {
+  ASSERT(fd >= 0);
+  ssize_t read_bytes =
+      TEMP_FAILURE_RETRY(recvfrom(fd, buffer, num_bytes, MSG_PEEK, NULL, NULL));
+  return read_bytes >= 0;
+}
+
+intptr_t SocketBase::Write(intptr_t fd,
+                           const void* buffer,
+                           intptr_t num_bytes,
+                           SocketOpKind sync) {
+  ASSERT(fd >= 0);
+  ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
+  ASSERT(EAGAIN == EWOULDBLOCK);
+  if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
+    // If the would block we need to retry and therefore return 0 as
+    // the number of bytes written.
+    written_bytes = 0;
+  }
+  return written_bytes;
+}
+
+intptr_t SocketBase::SendTo(intptr_t fd,
+                            const void* buffer,
+                            intptr_t num_bytes,
+                            const RawAddr& addr,
+                            SocketOpKind sync) {
+  ASSERT(fd >= 0);
+  ssize_t written_bytes =
+      TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr,
+                                SocketAddress::GetAddrLength(addr)));
+  ASSERT(EAGAIN == EWOULDBLOCK);
+  if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
+    // If the would block we need to retry and therefore return 0 as
+    // the number of bytes written.
+    written_bytes = 0;
+  }
+  return written_bytes;
+}
+
+intptr_t SocketBase::SendMessage(intptr_t fd,
+                                 void* buffer,
+                                 size_t num_bytes,
+                                 SocketControlMessage* messages,
+                                 intptr_t num_messages,
+                                 SocketOpKind sync,
+                                 OSError* p_oserror) {
+  ASSERT(fd >= 0);
+
+  struct iovec iov = {
+      .iov_base = buffer,
+      .iov_len = num_bytes,
+  };
+
+  struct msghdr msg;
+  memset(&msg, 0, sizeof(msg));
+  msg.msg_iov = &iov;
+  msg.msg_iovlen = 1;
+
+  if (messages != nullptr && num_messages > 0) {
+    SocketControlMessage* message = messages;
+    size_t total_length = 0;
+    for (intptr_t i = 0; i < num_messages; i++, message++) {
+      total_length += CMSG_SPACE(message->data_length());
+    }
+
+    uint8_t* control_buffer =
+        reinterpret_cast<uint8_t*>(Dart_ScopeAllocate(total_length));
+    memset(control_buffer, 0, total_length);
+    msg.msg_control = control_buffer;
+    msg.msg_controllen = total_length;
+
+    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+    message = messages;
+    for (intptr_t i = 0; i < num_messages;
+         i++, message++, cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+      ASSERT(message->is_file_descriptors_control_message());
+      cmsg->cmsg_level = SOL_SOCKET;
+      cmsg->cmsg_type = SCM_RIGHTS;
+
+      intptr_t data_length = message->data_length();
+      cmsg->cmsg_len = CMSG_LEN(data_length);
+      memmove(CMSG_DATA(cmsg), message->data(), data_length);
+    }
+    msg.msg_controllen = total_length;
+  }
+
+  ssize_t written_bytes = TEMP_FAILURE_RETRY(sendmsg(fd, &msg, 0));
+  ASSERT(EAGAIN == EWOULDBLOCK);
+  if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
+    // If the would block we need to retry and therefore return 0 as
+    // the number of bytes written.
+    written_bytes = 0;
+  }
+  if (written_bytes < 0) {
+    p_oserror->Reload();
+  }
+
+  return written_bytes;
+}
+
+bool SocketBase::GetSocketName(intptr_t fd, SocketAddress* p_sa) {
+  ASSERT(fd >= 0);
+  ASSERT(p_sa != nullptr);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
+  if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
+    return false;
+  }
+
+  // sockaddr_un contains sa_family_t sun_family and char[] sun_path.
+  // If size is the size of sa_family_t, this is an unnamed socket and
+  // sun_path contains garbage.
+  new (p_sa) SocketAddress(&raw.addr,
+                           /*unnamed_unix_socket=*/size == sizeof(sa_family_t));
+  return true;
+}
+
+intptr_t SocketBase::GetPort(intptr_t fd) {
+  ASSERT(fd >= 0);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
+  if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
+    return 0;
+  }
+  return SocketAddress::GetAddrPort(raw);
+}
+
+SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) {
+  ASSERT(fd >= 0);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
+  if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) {
+    return NULL;
+  }
+  // sockaddr_un contains sa_family_t sun_family and char[] sun_path.
+  // If size is the size of sa_family_t, this is an unnamed socket and
+  // sun_path contains garbage.
+  if (size == sizeof(sa_family_t)) {
+    *port = 0;
+    return new SocketAddress(&raw.addr, /*unnamed_unix_socket=*/true);
+  }
+  *port = SocketAddress::GetAddrPort(raw);
+  return new SocketAddress(&raw.addr);
+}
+
+intptr_t SocketBase::GetStdioHandle(intptr_t num) {
+  return num;
+}
+
+bool SocketBase::ReverseLookup(const RawAddr& addr,
+                               char* host,
+                               intptr_t host_len,
+                               OSError** os_error) {
+  ASSERT(host_len >= NI_MAXHOST);
+  int status = NO_RETRY_EXPECTED(
+      getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host,
+                  host_len, NULL, 0, NI_NAMEREQD));
+  if (status != 0) {
+    ASSERT(*os_error == NULL);
+    *os_error =
+        new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
+    return false;
+  }
+  return true;
+}
+
+bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) {
+  int result;
+  if (type == SocketAddress::TYPE_IPV4) {
+    result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr));
+  } else {
+    ASSERT(type == SocketAddress::TYPE_IPV6);
+    result =
+        NO_RETRY_EXPECTED(inet_pton(AF_INET6, address, &addr->in6.sin6_addr));
+  }
+  return (result == 1);
+}
+
+static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
+  if (ifa->ifa_addr == NULL) {
+    // OpenVPN's virtual device tun0.
+    return false;
+  }
+  int family = ifa->ifa_addr->sa_family;
+  return ((lookup_family == family) ||
+          ((lookup_family == AF_UNSPEC) &&
+           ((family == AF_INET) || (family == AF_INET6))));
+}
+
+bool SocketBase::ListInterfacesSupported() {
+  return true;
+}
+
+AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
+    int type,
+    OSError** os_error) {
+  struct ifaddrs* ifaddr;
+
+  int status = NO_RETRY_EXPECTED(getifaddrs(&ifaddr));
+  if (status != 0) {
+    ASSERT(*os_error == NULL);
+    *os_error =
+        new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
+    return NULL;
+  }
+
+  int lookup_family = SocketAddress::FromType(type);
+
+  intptr_t count = 0;
+  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
+      count++;
+    }
+  }
+
+  AddressList<InterfaceSocketAddress>* addresses =
+      new AddressList<InterfaceSocketAddress>(count);
+  int i = 0;
+  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
+      char* ifa_name = DartUtils::ScopedCopyCString(ifa->ifa_name);
+      addresses->SetAt(
+          i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name,
+                                        if_nametoindex(ifa->ifa_name)));
+      i++;
+    }
+  }
+  freeifaddrs(ifaddr);
+  return addresses;
+}
+
+void SocketBase::Close(intptr_t fd) {
+  ASSERT(fd >= 0);
+  close(fd);
+}
+
+bool SocketBase::RawAddrToString(RawAddr* addr, char* str) {
+  if (addr->addr.sa_family == AF_INET) {
+    return inet_ntop(AF_INET, &addr->in.sin_addr, str, INET_ADDRSTRLEN) != NULL;
+  } else {
+    ASSERT(addr->addr.sa_family == AF_INET6);
+    return inet_ntop(AF_INET6, &addr->in6.sin6_addr, str, INET6_ADDRSTRLEN) !=
+           NULL;
+  }
+}
+
+bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) {
+  int on;
+  socklen_t len = sizeof(on);
+  int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
+                                         reinterpret_cast<void*>(&on), &len));
+  if (err == 0) {
+    *enabled = (on == 1);
+  }
+  return (err == 0);
+}
+
+bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) {
+  int on = enabled ? 1 : 0;
+  return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
+                                      reinterpret_cast<char*>(&on),
+                                      sizeof(on))) == 0;
+}
+
+bool SocketBase::GetMulticastLoop(intptr_t fd,
+                                  intptr_t protocol,
+                                  bool* enabled) {
+  uint8_t on;
+  socklen_t len = sizeof(on);
+  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
+  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
+                                                     : IPV6_MULTICAST_LOOP;
+  if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
+                                   reinterpret_cast<char*>(&on), &len)) == 0) {
+    *enabled = (on == 1);
+    return true;
+  }
+  return false;
+}
+
+bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
+  uint8_t v;
+  socklen_t len = sizeof(v);
+  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
+  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
+                                                     : IPV6_MULTICAST_HOPS;
+  if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
+                                   reinterpret_cast<char*>(&v), &len)) == 0) {
+    *value = v;
+    return true;
+  }
+  return false;
+}
+
+bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
+  int v = value;
+  int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
+  int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
+                                                     : IPV6_MULTICAST_HOPS;
+  return NO_RETRY_EXPECTED(setsockopt(
+             fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0;
+}
+
+bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) {
+  int on;
+  socklen_t len = sizeof(on);
+  int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST,
+                                         reinterpret_cast<char*>(&on), &len));
+  if (err == 0) {
+    *enabled = (on == 1);
+  }
+  return (err == 0);
+}
+
+bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) {
+  int on = enabled ? 1 : 0;
+  return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
+                                      reinterpret_cast<char*>(&on),
+                                      sizeof(on))) == 0;
+}
+
+bool SocketBase::SetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           const char* data,
+                           int length) {
+  return NO_RETRY_EXPECTED(setsockopt(fd, level, option, data, length)) == 0;
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX) ||     \
+        // defined(DART_HOST_OS_MACOS)
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 70032a4..e590a6b 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -1444,17 +1444,22 @@
 /**
  * A message notification callback.
  *
- * This callback allows the embedder to provide an alternate wakeup
- * mechanism for the delivery of inter-isolate messages.  It is the
- * responsibility of the embedder to call Dart_HandleMessage to
- * process the message.
+ * This callback allows the embedder to provide a custom wakeup mechanism for
+ * the delivery of inter-isolate messages. This function is called once per
+ * message on an arbitrary thread. It is the responsibility of the embedder to
+ * eventually call Dart_HandleMessage once per callback received with the
+ * destination isolate set as the current isolate to process the message.
  */
-typedef void (*Dart_MessageNotifyCallback)(Dart_Isolate dest_isolate);
+typedef void (*Dart_MessageNotifyCallback)(Dart_Isolate destination_isolate);
 
 /**
- * Allows embedders to provide an alternative wakeup mechanism for the
- * delivery of inter-isolate messages. This setting only applies to
- * the current isolate.
+ * Allows embedders to provide a custom wakeup mechanism for the delivery of
+ * inter-isolate messages. This setting only applies to the current isolate.
+ *
+ * This mechanism is optional: if not provided, the isolate will be scheduled on
+ * a VM-managed thread pool. An embedder should provide this callback if it
+ * wants to run an isolate on a specific thread or to interleave handling of
+ * inter-isolate messages with other event sources.
  *
  * Most embedders will only call this function once, before isolate
  * execution begins. If this function is called after isolate
diff --git a/runtime/include/dart_native_api.h b/runtime/include/dart_native_api.h
index a938b49..318a4b7 100644
--- a/runtime/include/dart_native_api.h
+++ b/runtime/include/dart_native_api.h
@@ -50,6 +50,7 @@
   Dart_CObject_kArray,
   Dart_CObject_kTypedData,
   Dart_CObject_kExternalTypedData,
+  Dart_CObject_kUnmodifiableExternalTypedData,
   Dart_CObject_kSendPort,
   Dart_CObject_kCapability,
   Dart_CObject_kNativePointer,
@@ -79,7 +80,7 @@
     struct {
       Dart_TypedData_Type type;
       intptr_t length; /* in elements, not bytes */
-      uint8_t* values;
+      const uint8_t* values;
     } as_typed_data;
     struct {
       Dart_TypedData_Type type;
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index 4ccfe4f..90687f6 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -29,6 +29,11 @@
  */
 #define ILLEGAL_ISOLATE_ID ILLEGAL_PORT
 
+/**
+ * ILLEGAL_ISOLATE_GROUP_ID is a number guaranteed never to be associated with a
+ * valid isolate group.
+ */
+#define ILLEGAL_ISOLATE_GROUP_ID 0
 
 /*
  * =======
@@ -132,7 +137,7 @@
 } Dart_EmbedderInformation;
 
 /**
- * Callback provided by the embedder that is used by the vm to request
+ * Callback provided by the embedder that is used by the VM to request
  * information.
  *
  * \return Returns a pointer to a Dart_EmbedderInformation structure.
@@ -152,8 +157,8 @@
  * \param callback The callback to invoke.
  * \param user_data The user data passed to the callback.
  *
- * NOTE: If multiple callbacks with the same name are registered, only
- * the last callback registered will be remembered.
+ * NOTE: If multiple callbacks are registered, only the last callback registered
+ * will be remembered.
  */
 DART_EXPORT void Dart_SetEmbedderInformationCallback(
     Dart_EmbedderInformationCallback callback);
@@ -443,6 +448,82 @@
  */
 DART_EXPORT void Dart_SetThreadName(const char* name);
 
+typedef struct {
+  const char* name;
+  const char* value;
+} Dart_TimelineRecorderEvent_Argument;
+
+#define DART_TIMELINE_RECORDER_CURRENT_VERSION (0x00000001)
+
+typedef struct {
+  /* Set to DART_TIMELINE_RECORDER_CURRENT_VERSION */
+  int32_t version;
+
+  /* The event's type / phase. */
+  Dart_Timeline_Event_Type type;
+
+  /* The event's timestamp according to the same clock as
+   * Dart_TimelineGetMicros. For a duration event, this is the beginning time.
+   */
+  int64_t timestamp0;
+
+  /* For a duration event, this is the end time. For an async event, this is the
+   * async id. */
+  int64_t timestamp1_or_async_id;
+
+  /* The current isolate of the event, as if by Dart_GetMainPortId, or
+   * ILLEGAL_PORT if the event had no current isolate. */
+  Dart_Port isolate;
+
+  /* The current isolate group of the event, as if by
+   * Dart_CurrentIsolateGroupId, or ILLEGAL_PORT if the event had no current
+   * isolate group. */
+  Dart_IsolateGroupId isolate_group;
+
+  /* The name / label of the event. */
+  const char* label;
+
+  /* The stream / category of the event. */
+  const char* stream;
+
+  intptr_t argument_count;
+  Dart_TimelineRecorderEvent_Argument* arguments;
+} Dart_TimelineRecorderEvent;
+
+/**
+ * Callback provided by the embedder to handle the completion of timeline
+ * events.
+ *
+ * \param event A timeline event that has just been completed. The VM keeps
+ * ownership of the event and any field in it (i.e., the embedder should copy
+ * any values it needs after the callback returns).
+ */
+typedef void (*Dart_TimelineRecorderCallback)(
+    Dart_TimelineRecorderEvent* event);
+
+/**
+ * Register a `Dart_TimelineRecorderCallback` to be called as timeline events
+ * are completed.
+ *
+ * The callback will be invoked without a current isolate.
+ *
+ * The callback will be invoked on the thread completing the event. Because
+ * `Dart_TimelineEvent` may be called by any thread, the callback may be called
+ * on any thread.
+ *
+ * The callback may be invoked at any time after `Dart_Initialize` is called and
+ * before `Dart_Cleanup` returns.
+ *
+ * If multiple callbacks are registered, only the last callback registered
+ * will be remembered. Providing a NULL callback will clear the registration
+ * (i.e., a NULL callback produced a no-op instead of a crash).
+ *
+ * Setting a callback is insuffient to receive events through the callback. The
+ * VM flag `timeline_recorder` must also be set to `callback`.
+ */
+DART_EXPORT void Dart_SetTimelineRecorderCallback(
+    Dart_TimelineRecorderCallback callback);
+
 /*
  * =======
  * Metrics
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index b54bfa1..16f4a4b 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -274,8 +274,10 @@
   }
   // The next call cannot be in safepoint.
   if (external_size_diff > 0) {
-    thread->isolate_group()->heap()->AllocatedExternal(external_size_diff,
-                                                       space);
+    if (!thread->isolate_group()->heap()->AllocatedExternal(external_size_diff,
+                                                            space)) {
+      Exceptions::ThrowOOM();
+    }
   } else {
     thread->isolate_group()->heap()->FreedExternal(-external_size_diff, space);
   }
diff --git a/runtime/lib/ffi_dynamic_library.cc b/runtime/lib/ffi_dynamic_library.cc
index 84c6ec6..528c6bf 100644
--- a/runtime/lib/ffi_dynamic_library.cc
+++ b/runtime/lib/ffi_dynamic_library.cc
@@ -2,6 +2,15 @@
 // 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 "platform/globals.h"
+#if defined(DART_HOST_OS_WINDOWS)
+#include <Psapi.h>
+#include <Windows.h>
+#include <combaseapi.h>
+#include <stdio.h>
+#include <tchar.h>
+#endif
+
 #include "include/dart_api.h"
 #include "vm/bootstrap_natives.h"
 #include "vm/exceptions.h"
@@ -15,7 +24,7 @@
 
 namespace dart {
 
-#if defined(USING_SIMULATOR)
+#if defined(USING_SIMULATOR) || defined(DART_PRECOMPILER)
 
 DART_NORETURN static void SimulatorUnsupported() {
   Exceptions::ThrowUnsupportedError(
@@ -41,7 +50,7 @@
   SimulatorUnsupported();
 }
 
-#else  // defined(USING_SIMULATOR)
+#else  // defined(USING_SIMULATOR) || defined(DART_PRECOMPILER)
 
 static void* LoadDynamicLibrary(const char* library_file) {
   char* error = nullptr;
@@ -56,9 +65,60 @@
   return handle;
 }
 
+#if defined(DART_HOST_OS_WINDOWS)
+// On windows, nullptr signals trying a lookup in all loaded modules.
+const nullptr_t kWindowsDynamicLibraryProcessPtr = nullptr;
+
+void* co_task_mem_alloced = nullptr;
+
+void* LookupSymbolInProcess(const char* symbol, char** error) {
+  // Force loading ole32.dll.
+  if (co_task_mem_alloced == nullptr) {
+    co_task_mem_alloced = CoTaskMemAlloc(sizeof(intptr_t));
+    CoTaskMemFree(co_task_mem_alloced);
+  }
+
+  HANDLE current_process =
+      OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
+                  GetCurrentProcessId());
+  if (current_process == nullptr) {
+    *error = OS::SCreate(nullptr, "Failed to open current process.");
+    return nullptr;
+  }
+
+  HMODULE modules[1024];
+  DWORD cb_needed;
+  if (EnumProcessModules(current_process, modules, sizeof(modules),
+                         &cb_needed) != 0) {
+    for (intptr_t i = 0; i < (cb_needed / sizeof(HMODULE)); i++) {
+      if (auto result =
+              reinterpret_cast<void*>(GetProcAddress(modules[i], symbol))) {
+        CloseHandle(current_process);
+        return result;
+      }
+    }
+  }
+  CloseHandle(current_process);
+
+  *error = OS::SCreate(
+      nullptr,
+      "None of the loaded modules contained the requested symbol '%s'.",
+      symbol);
+  return nullptr;
+}
+#endif
+
 static void* ResolveSymbol(void* handle, const char* symbol) {
   char* error = nullptr;
-  void* result = Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
+#if !defined(DART_HOST_OS_WINDOWS)
+  void* const result =
+      Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
+#else
+  void* const result =
+      handle == kWindowsDynamicLibraryProcessPtr
+          ? LookupSymbolInProcess(symbol, &error)
+          : Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
+#endif
   if (error != nullptr) {
     const String& msg = String::Handle(String::NewFormatted(
         "Failed to lookup symbol '%s': %s", symbol, error));
@@ -70,7 +130,15 @@
 
 static bool SymbolExists(void* handle, const char* symbol) {
   char* error = nullptr;
+#if !defined(DART_HOST_OS_WINDOWS)
   Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
+#else
+  if (handle == nullptr) {
+    LookupSymbolInProcess(symbol, &error);
+  } else {
+    Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
+  }
+#endif
   if (error != nullptr) {
     free(error);
     return false;
@@ -91,8 +159,7 @@
     defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
   return DynamicLibrary::New(RTLD_DEFAULT);
 #else
-  Exceptions::ThrowUnsupportedError(
-      "DynamicLibrary.process is not available on this platform.");
+  return DynamicLibrary::New(kWindowsDynamicLibraryProcessPtr);
 #endif
 }
 
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 1a600c5..5babac5 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -244,8 +244,7 @@
       case kFloat64x2Cid:
         continue;
 
-      case kArrayCid:
-      {
+      case kArrayCid: {
         array ^= Array::RawCast(raw);
         visitor.VisitObject(array.GetTypeArguments());
         const intptr_t batch_size = (2 << 14) - 1;
@@ -1303,10 +1302,12 @@
   const ExternalTypedData& typed_data = ExternalTypedData::Handle(
       ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, length,
                              thread->heap()->SpaceForExternal(length)));
-  FinalizablePersistentHandle::New(thread->isolate_group(), typed_data,
-                                   /* peer= */ data,
-                                   &ExternalTypedDataFinalizer, length,
-                                   /*auto_delete=*/true);
+  FinalizablePersistentHandle* finalizable_ref =
+      FinalizablePersistentHandle::New(thread->isolate_group(), typed_data,
+                                       /* peer= */ data,
+                                       &ExternalTypedDataFinalizer, length,
+                                       /*auto_delete=*/true);
+  ASSERT(finalizable_ref != nullptr);
   return typed_data.ptr();
 }
 
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 247f5d5..872713f 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -81,7 +81,7 @@
     return Type::IntType();
   } else if (instance.IsDouble()) {
     return Type::Double();
-  } else if (instance.IsType() || instance.IsFunctionType()) {
+  } else if (instance.IsAbstractType()) {
     return Type::DartTypeType();
   } else if (IsArrayClassId(instance.GetClassId())) {
     const auto& cls = Class::Handle(
@@ -145,6 +145,26 @@
     return left_type.IsEquivalent(right_type, TypeEquality::kSyntactical);
   }
 
+  if (left_cid == kRecordCid) {
+    const auto& left_record = Record::Cast(left);
+    const auto& right_record = Record::Cast(right);
+    const intptr_t num_fields = left_record.num_fields();
+    if ((num_fields != right_record.num_fields()) ||
+        (left_record.field_names() != right_record.field_names())) {
+      return false;
+    }
+    Instance& left_field = Instance::Handle(zone);
+    Instance& right_field = Instance::Handle(zone);
+    for (intptr_t i = 0; i < num_fields; ++i) {
+      left_field ^= left_record.FieldAt(i);
+      right_field ^= right_record.FieldAt(i);
+      if (!HaveSameRuntimeTypeHelper(zone, left_field, right_field)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   const Class& cls = Class::Handle(zone, left.clazz());
   if (!cls.IsGeneric()) {
     return true;
@@ -218,6 +238,26 @@
   return type.UserVisibleName();
 }
 
+DEFINE_NATIVE_ENTRY(AbstractType_getHashCode, 0, 1) {
+  const AbstractType& type =
+      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(0));
+  intptr_t hash_val = type.Hash();
+  ASSERT(hash_val > 0);
+  ASSERT(Smi::IsValid(hash_val));
+  return Smi::New(hash_val);
+}
+
+DEFINE_NATIVE_ENTRY(AbstractType_equality, 0, 2) {
+  const AbstractType& type =
+      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(0));
+  const Instance& other =
+      Instance::CheckedHandle(zone, arguments->NativeArgAt(1));
+  if (type.ptr() == other.ptr()) {
+    return Bool::True().ptr();
+  }
+  return Bool::Get(type.IsEquivalent(other, TypeEquality::kSyntactical)).ptr();
+}
+
 DEFINE_NATIVE_ENTRY(Type_getHashCode, 0, 1) {
   const Type& type = Type::CheckedHandle(zone, arguments->NativeArgAt(0));
   intptr_t hash_val = type.Hash();
@@ -236,26 +276,6 @@
   return Bool::Get(type.IsEquivalent(other, TypeEquality::kSyntactical)).ptr();
 }
 
-DEFINE_NATIVE_ENTRY(FunctionType_getHashCode, 0, 1) {
-  const FunctionType& type =
-      FunctionType::CheckedHandle(zone, arguments->NativeArgAt(0));
-  intptr_t hash_val = type.Hash();
-  ASSERT(hash_val > 0);
-  ASSERT(Smi::IsValid(hash_val));
-  return Smi::New(hash_val);
-}
-
-DEFINE_NATIVE_ENTRY(FunctionType_equality, 0, 2) {
-  const FunctionType& type =
-      FunctionType::CheckedHandle(zone, arguments->NativeArgAt(0));
-  const Instance& other =
-      Instance::CheckedHandle(zone, arguments->NativeArgAt(1));
-  if (type.ptr() == other.ptr()) {
-    return Bool::True().ptr();
-  }
-  return Bool::Get(type.IsEquivalent(other, TypeEquality::kSyntactical)).ptr();
-}
-
 DEFINE_NATIVE_ENTRY(LibraryPrefix_isLoaded, 0, 1) {
   const LibraryPrefix& prefix =
       LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index 7deea5c..38364ee 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -36,13 +36,12 @@
   return Integer::New(OS::GetCurrentMonotonicMicros(), Heap::kNew);
 }
 
-DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 0, 5) {
+DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 0, 4) {
 #if defined(SUPPORT_TIMELINE)
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, id, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, phase, arguments->NativeArgAt(1));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(2));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(3));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(4));
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, type, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(3));
 
   TimelineEventRecorder* recorder = Timeline::recorder();
   if (recorder == NULL) {
@@ -56,57 +55,7 @@
   }
 
   DartTimelineEventHelpers::ReportTaskEvent(
-      thread, event, id.AsInt64Value(), phase.ToCString(), category.ToCString(),
-      name.ToMallocCString(), args.ToMallocCString());
-#endif  // SUPPORT_TIMELINE
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(Timeline_reportFlowEvent, 0, 5) {
-#if defined(SUPPORT_TIMELINE)
-  GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
-  GET_NON_NULL_NATIVE_ARGUMENT(Integer, type, arguments->NativeArgAt(2));
-  GET_NON_NULL_NATIVE_ARGUMENT(Integer, flow_id, arguments->NativeArgAt(3));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(4));
-
-  TimelineEventRecorder* recorder = Timeline::recorder();
-  if (recorder == NULL) {
-    return Object::null();
-  }
-
-  TimelineEvent* event = Timeline::GetDartStream()->StartEvent();
-  if (event == NULL) {
-    // Stream was turned off.
-    return Object::null();
-  }
-
-  DartTimelineEventHelpers::ReportFlowEvent(
-      thread, event, category.ToCString(), name.ToMallocCString(),
-      type.AsInt64Value(), flow_id.AsInt64Value(), args.ToMallocCString());
-#endif  // SUPPORT_TIMELINE
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(Timeline_reportInstantEvent, 0, 3) {
-#if defined(SUPPORT_TIMELINE)
-  GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(2));
-
-  TimelineEventRecorder* recorder = Timeline::recorder();
-  if (recorder == NULL) {
-    return Object::null();
-  }
-
-  TimelineEvent* event = Timeline::GetDartStream()->StartEvent();
-  if (event == NULL) {
-    // Stream was turned off.
-    return Object::null();
-  }
-
-  DartTimelineEventHelpers::ReportInstantEvent(
-      thread, event, category.ToCString(), name.ToMallocCString(),
+      event, id.AsInt64Value(), type.Value(), name.ToMallocCString(),
       args.ToMallocCString());
 #endif  // SUPPORT_TIMELINE
   return Object::null();
diff --git a/runtime/platform/allocation.cc b/runtime/platform/allocation.cc
index 6f8ae01..cd6d1b7 100644
--- a/runtime/platform/allocation.cc
+++ b/runtime/platform/allocation.cc
@@ -8,6 +8,14 @@
 
 namespace dart {
 
+void* calloc(size_t n, size_t size) {
+  void* result = ::calloc(n, size);
+  if (result == nullptr) {
+    OUT_OF_MEMORY();
+  }
+  return result;
+}
+
 void* malloc(size_t size) {
   void* result = ::malloc(size);
   if (result == nullptr) {
diff --git a/runtime/platform/allocation.h b/runtime/platform/allocation.h
index 4458f55..d732112 100644
--- a/runtime/platform/allocation.h
+++ b/runtime/platform/allocation.h
@@ -10,6 +10,10 @@
 
 namespace dart {
 
+void* calloc(size_t n, size_t size);
+void* malloc(size_t size);
+void* realloc(void* ptr, size_t size);
+
 // Stack allocated objects subclass from this base class. Objects of this type
 // cannot be allocated on either the C or object heaps. Destructors for objects
 // of this type will not be run unless the stack is unwound through normal
@@ -41,19 +45,11 @@
   // check malloc/new/new[] are paired with free/delete/delete[] respectively.
 #if !defined(USING_ADDRESS_SANITIZER)
   void* operator new(size_t size) {
-    void* result = ::malloc(size);
-    if (result == nullptr) {
-      OUT_OF_MEMORY();
-    }
-    return result;
+    return dart::malloc(size);
   }
 
   void* operator new[](size_t size) {
-    void* result = ::malloc(size);
-    if (result == nullptr) {
-      OUT_OF_MEMORY();
-    }
-    return result;
+    return dart::malloc(size);
   }
 
   void operator delete(void* pointer) { ::free(pointer); }
@@ -62,9 +58,6 @@
 #endif
 };
 
-void* malloc(size_t size);
-void* realloc(void* ptr, size_t size);
-
 }  // namespace dart
 
 #endif  // RUNTIME_PLATFORM_ALLOCATION_H_
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 98e15ed..9c8d00f 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -145,6 +145,7 @@
 struct simd128_value_t {
   union {
     int32_t int_storage[4];
+    int64_t int64_storage[2];
     float float_storage[4];
     double double_storage[2];
   };
@@ -410,10 +411,6 @@
 #define DUAL_MAPPING_SUPPORTED 1
 #endif
 
-#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
-#define SUPPORT_UNBOXED_INSTANCE_FIELDS
-#endif
-
 // Short form printf format specifiers
 #define Pd PRIdPTR
 #define Pu PRIuPTR
diff --git a/runtime/platform/memory_sanitizer.h b/runtime/platform/memory_sanitizer.h
index ee2633f..5301542 100644
--- a/runtime/platform/memory_sanitizer.h
+++ b/runtime/platform/memory_sanitizer.h
@@ -11,15 +11,21 @@
 // told about areas that are initialized by generated code.
 #if defined(__has_feature)
 #if __has_feature(memory_sanitizer)
+#define USING_MEMORY_SANITIZER
+#endif
+#endif
+
+#if defined(USING_MEMORY_SANITIZER)
 extern "C" void __msan_poison(const volatile void*, size_t);
 extern "C" void __msan_unpoison(const volatile void*, size_t);
+extern "C" void __msan_unpoison_param(size_t);
 extern "C" void __msan_check_mem_is_initialized(const volatile void*, size_t);
 #define MSAN_POISON(ptr, len) __msan_poison(ptr, len)
 #define MSAN_UNPOISON(ptr, len) __msan_unpoison(ptr, len)
 #define MSAN_CHECK_INITIALIZED(ptr, len)                                       \
   __msan_check_mem_is_initialized(ptr, len)
 #define NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory")))
-#else  // __has_feature(memory_sanitizer)
+#else  // defined(USING_MEMORY_SANITIZER)
 #define MSAN_POISON(ptr, len)                                                  \
   do {                                                                         \
   } while (false && (ptr) == 0 && (len) == 0)
@@ -29,19 +35,6 @@
 #define MSAN_CHECK_INITIALIZED(ptr, len)                                       \
   do {                                                                         \
   } while (false && (ptr) == 0 && (len) == 0)
-#define NO_SANITIZE_MEMORY
-#endif  // __has_feature(memory_sanitizer)
-#else   // defined(__has_feature)
-#define MSAN_POISON(ptr, len)                                                  \
-  do {                                                                         \
-  } while (false && (ptr) == 0 && (len) == 0)
-#define MSAN_UNPOISON(ptr, len)                                                \
-  do {                                                                         \
-  } while (false && (ptr) == 0 && (len) == 0)
-#define MSAN_CHECK_INITIALIZED(ptr, len)                                       \
-  do {                                                                         \
-  } while (false && (ptr) == 0 && (len) == 0)
-#define NO_SANITIZE_MEMORY
-#endif  // defined(__has_feature)
+#endif  // defined(USING_MEMORY_SANITIZER)
 
 #endif  // RUNTIME_PLATFORM_MEMORY_SANITIZER_H_
diff --git a/runtime/tests/concurrency/stress_test_list.json b/runtime/tests/concurrency/stress_test_list.json
index f0310dc..368c353 100644
--- a/runtime/tests/concurrency/stress_test_list.json
+++ b/runtime/tests/concurrency/stress_test_list.json
@@ -3258,6 +3258,7 @@
     "../../../tests/standalone/io/file_non_ascii_sync_test.dart",
     "../../../tests/standalone/io/file_non_ascii_test.dart",
     "../../../tests/standalone/io/file_output_stream_test.dart",
+    "../../../tests/standalone/io/file_pipe_test.dart",
     "../../../tests/standalone/io/file_read_encoded_test.dart",
     "../../../tests/standalone/io/file_stat_test.dart",
     "../../../tests/standalone/io/file_stream_test.dart",
@@ -6580,6 +6581,7 @@
     "../../../tests/standalone_2/io/file_non_ascii_sync_test.dart",
     "../../../tests/standalone_2/io/file_non_ascii_test.dart",
     "../../../tests/standalone_2/io/file_output_stream_test.dart",
+    "../../../tests/standalone_2/io/file_pipe_test.dart",
     "../../../tests/standalone_2/io/file_read_encoded_test.dart",
     "../../../tests/standalone_2/io/file_stat_test.dart",
     "../../../tests/standalone_2/io/file_stream_test.dart",
diff --git a/runtime/tests/vm/dart/heap_snapshot_referrers_test.dart b/runtime/tests/vm/dart/heap_snapshot_referrers_test.dart
new file mode 100644
index 0000000..a783034
--- /dev/null
+++ b/runtime/tests/vm/dart/heap_snapshot_referrers_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2022, 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:_internal';
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'heap_snapshot_test.dart';
+import 'use_flag_test_helper.dart';
+
+main() async {
+  if (const bool.fromEnvironment('dart.vm.product')) return;
+  if (isSimulator) return; // Takes too long on simulators.
+
+  await withTempDir('heap_snapshot_test', (String dir) async {
+    final file = path.join(dir, 'state1.heapsnapshot');
+    VMInternalsForTesting.writeHeapSnapshotToFile(file);
+    final graph = loadHeapSnapshotFromFile(file);
+    final reachable = findReachableObjects(graph);
+
+    for (int id = 0; id < graph.objects.length; ++id) {
+      final object = graph.objects[id];
+
+      // Ensure all `references` appear in `referrers`.
+      for (final rid in object.references) {
+        final users = graph.objects[rid].referrers;
+        if (!users.contains(id)) {
+          throw 'Object $id references $rid, but is not in referrers';
+        }
+      }
+
+      // Ensure all `referrers` appear in `references`.
+      for (final uid in object.referrers) {
+        final refs = graph.objects[uid].references;
+        if (!refs.contains(id)) {
+          throw 'Object $id is referenced by $uid, but is not in references.';
+        }
+      }
+    }
+  });
+}
diff --git a/runtime/tests/vm/dart/regress_50065_test.dart b/runtime/tests/vm/dart/regress_50065_test.dart
new file mode 100644
index 0000000..4873061
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_50065_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2022, 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.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/50065.
+// Runs tests/language/generic/function_bounds_test.dart in multiple isolates
+// in order to stress-test concurrent canonicalization of types.
+
+import 'dart:isolate';
+
+import 'package:expect/expect.dart';
+import '../../../../tests/language/generic/function_bounds_test.dart'
+    as function_bounds_test;
+
+const int N = 100;
+
+void run(dynamic message) {
+  function_bounds_test.main();
+}
+
+void main() async {
+  final List<ReceivePort> ports = [];
+  final List<Future> isolates = [];
+  for (int i = 0; i < N; ++i) {
+    final rp = ReceivePort();
+    isolates.add(Isolate.spawn(run, null, onExit: rp.sendPort));
+    ports.add(rp);
+  }
+  await Future.wait(isolates);
+  await Future.wait(ports.map((p) => p.first));
+}
diff --git a/runtime/tests/vm/dart/regress_flutter110715_il_test.dart b/runtime/tests/vm/dart/regress_flutter110715_il_test.dart
new file mode 100644
index 0000000..d25f23c
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_flutter110715_il_test.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2022, 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.
+
+// Regression test for https://github.com/flutter/flutter/issues/110715.
+// Verifies that compiler doesn't elide null check for a parameter in
+// a catch block in async/async* methods.
+
+import 'dart:async';
+import 'package:vm/testing/il_matchers.dart';
+
+@pragma('vm:never-inline')
+@pragma('vm:testing:print-flow-graph')
+Stream<Object> bug1(void Function()? f, void Function() g) async* {
+  try {
+    g();
+    throw 'error';
+  } catch (e) {
+    // Should not crash when 'f' is null.
+    f?.call();
+  }
+}
+
+@pragma('vm:never-inline')
+@pragma('vm:testing:print-flow-graph')
+Future<Object> bug2(void Function()? f, void Function() g) async {
+  try {
+    g();
+    throw 'error';
+  } catch (e) {
+    // Should not crash when 'f' is null.
+    f?.call();
+  }
+  return '';
+}
+
+void main() async {
+  print(await bug1(null, () {}).toList());
+  print(await bug1(() {}, () {}).toList());
+  print(await bug2(null, () {}));
+  print(await bug2(() {}, () {}));
+}
+
+void matchIL$bug1(FlowGraph graph) {
+  graph.dump();
+  graph.match([
+    match.block('Graph'),
+    match.block('Function'),
+    match.block('Join'),
+    match.block('CatchBlock', [
+      'v0' << match.Parameter(),
+      match.Branch(match.StrictCompare('v0', match.any, kind: '==='),
+          ifTrue: 'B6', ifFalse: 'B7'),
+    ]),
+    'B6' <<
+        match.block('Target', [
+          match.Goto('B4'),
+        ]),
+    'B7' <<
+        match.block('Target', [
+          match.ClosureCall(),
+          match.Goto('B4'),
+        ]),
+    'B4' <<
+        match.block('Join', [
+          match.Return(),
+        ]),
+  ]);
+}
+
+void matchIL$bug2(FlowGraph graph) {
+  graph.dump();
+  graph.match([
+    match.block('Graph'),
+    match.block('Function'),
+    match.block('Join'),
+    match.block('CatchBlock', [
+      'v0' << match.Parameter(),
+      match.Branch(match.StrictCompare('v0', match.any, kind: '==='),
+          ifTrue: 'B6', ifFalse: 'B7'),
+    ]),
+    'B6' <<
+        match.block('Target', [
+          match.Goto('B4'),
+        ]),
+    'B7' <<
+        match.block('Target', [
+          match.ClosureCall(),
+          match.Goto('B4'),
+        ]),
+    'B4' <<
+        match.block('Join', [
+          match.Return(),
+        ]),
+  ]);
+}
diff --git a/runtime/tests/vm/dart/use_add_readonly_data_symbols_flag_test.dart b/runtime/tests/vm/dart/use_add_readonly_data_symbols_flag_test.dart
new file mode 100644
index 0000000..b8895c5
--- /dev/null
+++ b/runtime/tests/vm/dart/use_add_readonly_data_symbols_flag_test.dart
@@ -0,0 +1,159 @@
+// Copyright (c) 2022, 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.
+
+// This test checks that --add-readonly-data-symbols outputs static symbols
+// for read-only data objects.
+
+// OtherResources=use_save_debugging_info_flag_program.dart
+
+import "dart:async";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:native_stack_traces/elf.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
+  }
+  if (!await testExecutable(aotRuntime)) {
+    throw "Cannot run test as $aotRuntime not available";
+  }
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+
+  await withTempDir('readonly-symbols-flag-test', (String tempDir) async {
+    final cwDir = path.dirname(Platform.script.toFilePath());
+    final script =
+        path.join(cwDir, 'use_save_debugging_info_flag_program.dart');
+    final scriptDill = path.join(tempDir, 'flag_program.dill');
+
+    // Compile script to Kernel IR.
+    await run(genKernel, <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    final scriptSnapshot = path.join(tempDir, 'dwarf.so');
+    final scriptDebuggingInfo = path.join(tempDir, 'debug_info.so');
+    await run(genSnapshot, <String>[
+      '--add-readonly-data-symbols',
+      '--dwarf-stack-traces-mode',
+      '--save-debugging-info=$scriptDebuggingInfo',
+      '--snapshot-kind=app-aot-elf',
+      '--elf=$scriptSnapshot',
+      scriptDill,
+    ]);
+
+    checkElf(scriptSnapshot);
+    checkElf(scriptDebuggingInfo);
+
+    if (Platform.isLinux && !isSimulator) {
+      final scriptAssembly = path.join(tempDir, 'snapshot.S');
+      final scriptAssemblySnapshot = path.join(tempDir, 'assembly.so');
+      final scriptAssemblyDebuggingInfo =
+          path.join(tempDir, 'assembly_debug.so');
+
+      await run(genSnapshot, <String>[
+        '--add-readonly-data-symbols',
+        '--dwarf-stack-traces-mode',
+        '--save-debugging-info=$scriptAssemblyDebuggingInfo',
+        '--snapshot-kind=app-aot-assembly',
+        '--assembly=$scriptAssembly',
+        scriptDill,
+      ]);
+
+      await assembleSnapshot(scriptAssembly, scriptAssemblySnapshot,
+          debug: true);
+
+      checkElf(scriptAssemblySnapshot, isAssembled: true);
+      checkElf(scriptAssemblyDebuggingInfo);
+    }
+  });
+}
+
+void checkElf(String filename, {bool isAssembled = false}) {
+  // Check that the static symbol table contains entries that are not in the
+  // dynamic symbol table, have STB_LOCAL binding, and are of type STT_OBJECT.
+  final elf = Elf.fromFile(filename);
+  Expect.isNotNull(elf);
+  final dynamicSymbols = elf!.dynamicSymbols.toList();
+  print('Dynamic symbols:');
+  for (final symbol in dynamicSymbols) {
+    // All symbol tables have an initial entry with zero-valued fields.
+    if (symbol.name == '') {
+      print(symbol);
+      Expect.equals(SymbolBinding.STB_LOCAL, symbol.bind);
+      Expect.equals(SymbolType.STT_NOTYPE, symbol.type);
+      Expect.equals(0, symbol.value);
+    } else {
+      if (!symbol.name.startsWith('_kDart')) {
+        // The VM only adds symbols with names starting with _kDart, so this
+        // must be an assembled snapshot.
+        Expect.isTrue(isAssembled);
+        continue;
+      }
+      Expect.equals(SymbolBinding.STB_GLOBAL, symbol.bind);
+      Expect.equals(SymbolType.STT_OBJECT, symbol.type);
+      // All VM-generated read-only object symbols should have a non-zero size.
+      Expect.notEquals(0, symbol.size);
+    }
+  }
+  print("");
+  final onlyStaticSymbols = elf.staticSymbols
+      .where((s1) => !dynamicSymbols.any((s2) => s1.name == s2.name));
+  Expect.isNotEmpty(onlyStaticSymbols, 'no static-only symbols');
+  final objectSymbols =
+      onlyStaticSymbols.where((s) => s.type == SymbolType.STT_OBJECT);
+  Expect.isNotEmpty(objectSymbols, 'no static-only object symbols');
+  print("Static-only object symbols:");
+  for (final symbol in objectSymbols) {
+    print(symbol);
+    // There should be no static-only global object symbols.
+    Expect.equals(SymbolBinding.STB_LOCAL, symbol.bind);
+    final objectTypeEnd = symbol.name.indexOf('_');
+    // All VM-generated read-only object symbols are prefixed with the type of
+    // the C++ object followed by an underscore. If assembling the snapshot,
+    // the assembler might introduce other object symbols which either start
+    // with an underscore or have no underscore.
+    if (objectTypeEnd <= 0) {
+      Expect.isTrue(isAssembled);
+      continue;
+    }
+    // All VM-generated read-only object symbols should have a non-zero size.
+    Expect.notEquals(0, symbol.size);
+    final objectType = symbol.name.substring(0, objectTypeEnd);
+    switch (objectType) {
+      // Used for entries in the non-clustered portion of the read-only data
+      // section that don't correspond to a specific Dart object.
+      case 'RawBytes':
+      // Currently the only types of objects written to the non-clustered
+      // portion of the read-only data section.
+      case 'OneByteString':
+      case 'TwoByteString':
+      case 'CodeSourceMap':
+      case 'PcDescriptors':
+      case 'CompressedStackMaps':
+        break;
+      default:
+        Expect.fail('unexpected object type $objectType');
+    }
+  }
+}
diff --git a/runtime/tests/vm/dart_2/heap_snapshot_referrers_test.dart b/runtime/tests/vm/dart_2/heap_snapshot_referrers_test.dart
new file mode 100644
index 0000000..6399764
--- /dev/null
+++ b/runtime/tests/vm/dart_2/heap_snapshot_referrers_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2022, 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:_internal';
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'heap_snapshot_test.dart';
+import 'use_flag_test_helper.dart';
+
+main() async {
+  if (const bool.fromEnvironment('dart.vm.product')) return;
+  if (isSimulator) return; // Takes too long on simulators.
+
+  await withTempDir('heap_snapshot_test', (String dir) async {
+    final file = path.join(dir, 'state1.heapsnapshot');
+    VMInternalsForTesting.writeHeapSnapshotToFile(file);
+    final graph = loadHeapSnapshotFromFile(file);
+    final reachable = findReachableObjects(graph);
+
+    for (int id = 0; id < graph.objects.length; ++id) {
+      final object = graph.objects[id];
+
+      // Ensure all `references` appear in `referrers`.
+      for (final rid in object.references) {
+        final users = graph.objects[rid].referrers;
+        if (!users.contains(id)) {
+          throw 'Object $id references $rid, but is not in referrers';
+        }
+      }
+
+      // Ensure all `referrers` appear in `references`.
+      for (final uid in object.referrers) {
+        final refs = graph.objects[uid].references;
+        if (!refs.contains(id)) {
+          throw 'Object $id is referenced by $uid, but is not in references.';
+        }
+      }
+    }
+  });
+}
diff --git a/runtime/tests/vm/dart_2/regress_50065_test.dart b/runtime/tests/vm/dart_2/regress_50065_test.dart
new file mode 100644
index 0000000..1a3514c
--- /dev/null
+++ b/runtime/tests/vm/dart_2/regress_50065_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2022, 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.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/50065.
+// Runs tests/language_2/generic/function_bounds_test.dart in multiple isolates
+// in order to stress-test concurrent canonicalization of types.
+
+// @dart = 2.9
+
+import 'dart:isolate';
+
+import 'package:expect/expect.dart';
+import '../../../../tests/language_2/generic/function_bounds_test.dart'
+    as function_bounds_test;
+
+const int N = 100;
+
+void run(dynamic message) {
+  function_bounds_test.main();
+}
+
+void main() async {
+  final List<ReceivePort> ports = [];
+  final List<Future> isolates = [];
+  for (int i = 0; i < N; ++i) {
+    final rp = ReceivePort();
+    isolates.add(Isolate.spawn(run, null, onExit: rp.sendPort));
+    ports.add(rp);
+  }
+  await Future.wait(isolates);
+  await Future.wait(ports.map((p) => p.first));
+}
diff --git a/runtime/tests/vm/dart_2/use_add_readonly_data_symbols_flag_test.dart b/runtime/tests/vm/dart_2/use_add_readonly_data_symbols_flag_test.dart
new file mode 100644
index 0000000..35fe667
--- /dev/null
+++ b/runtime/tests/vm/dart_2/use_add_readonly_data_symbols_flag_test.dart
@@ -0,0 +1,161 @@
+// Copyright (c) 2022, 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
+
+// This test checks that --add-readonly-data-symbols outputs static symbols
+// for read-only data objects.
+
+// OtherResources=use_save_debugging_info_flag_program.dart
+
+import "dart:async";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:native_stack_traces/elf.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
+  }
+  if (!await testExecutable(aotRuntime)) {
+    throw "Cannot run test as $aotRuntime not available";
+  }
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+
+  await withTempDir('readonly-symbols-flag-test', (String tempDir) async {
+    final cwDir = path.dirname(Platform.script.toFilePath());
+    final script =
+        path.join(cwDir, 'use_save_debugging_info_flag_program.dart');
+    final scriptDill = path.join(tempDir, 'flag_program.dill');
+
+    // Compile script to Kernel IR.
+    await run(genKernel, <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    final scriptSnapshot = path.join(tempDir, 'dwarf.so');
+    final scriptDebuggingInfo = path.join(tempDir, 'debug_info.so');
+    await run(genSnapshot, <String>[
+      '--add-readonly-data-symbols',
+      '--dwarf-stack-traces-mode',
+      '--save-debugging-info=$scriptDebuggingInfo',
+      '--snapshot-kind=app-aot-elf',
+      '--elf=$scriptSnapshot',
+      scriptDill,
+    ]);
+
+    checkElf(scriptSnapshot);
+    checkElf(scriptDebuggingInfo);
+
+    if (Platform.isLinux && !isSimulator) {
+      final scriptAssembly = path.join(tempDir, 'snapshot.S');
+      final scriptAssemblySnapshot = path.join(tempDir, 'assembly.so');
+      final scriptAssemblyDebuggingInfo =
+          path.join(tempDir, 'assembly_debug.so');
+
+      await run(genSnapshot, <String>[
+        '--add-readonly-data-symbols',
+        '--dwarf-stack-traces-mode',
+        '--save-debugging-info=$scriptAssemblyDebuggingInfo',
+        '--snapshot-kind=app-aot-assembly',
+        '--assembly=$scriptAssembly',
+        scriptDill,
+      ]);
+
+      await assembleSnapshot(scriptAssembly, scriptAssemblySnapshot,
+          debug: true);
+
+      checkElf(scriptAssemblySnapshot, isAssembled: true);
+      checkElf(scriptAssemblyDebuggingInfo);
+    }
+  });
+}
+
+void checkElf(String filename, {bool isAssembled = false}) {
+  // Check that the static symbol table contains entries that are not in the
+  // dynamic symbol table, have STB_LOCAL binding, and are of type STT_OBJECT.
+  final elf = Elf.fromFile(filename);
+  Expect.isNotNull(elf);
+  final dynamicSymbols = elf.dynamicSymbols.toList();
+  print('Dynamic symbols:');
+  for (final symbol in dynamicSymbols) {
+    print(symbol);
+    // All symbol tables have an initial entry with zero-valued fields.
+    if (symbol.name == '') {
+      Expect.equals(SymbolBinding.STB_LOCAL, symbol.bind);
+      Expect.equals(SymbolType.STT_NOTYPE, symbol.type);
+      Expect.equals(0, symbol.value);
+    } else {
+      if (!symbol.name.startsWith('_kDart')) {
+        // The VM only adds symbols with names starting with _kDart, so this
+        // must be an assembled snapshot.
+        Expect.isTrue(isAssembled);
+        continue;
+      }
+      Expect.equals(SymbolBinding.STB_GLOBAL, symbol.bind);
+      Expect.equals(SymbolType.STT_OBJECT, symbol.type);
+      // All VM-generated read-only object symbols should have a non-zero size.
+      Expect.notEquals(0, symbol.size);
+    }
+  }
+  print("");
+  final onlyStaticSymbols = elf.staticSymbols
+      .where((s1) => !dynamicSymbols.any((s2) => s1.name == s2.name));
+  Expect.isNotEmpty(onlyStaticSymbols, 'no static-only symbols');
+  final objectSymbols =
+      onlyStaticSymbols.where((s) => s.type == SymbolType.STT_OBJECT);
+  Expect.isNotEmpty(objectSymbols, 'no static-only object symbols');
+  print("Static-only object symbols:");
+  for (final symbol in objectSymbols) {
+    print(symbol);
+    // There should be no static-only global object symbols.
+    Expect.equals(SymbolBinding.STB_LOCAL, symbol.bind);
+    final objectTypeEnd = symbol.name.indexOf('_');
+    // All VM-generated read-only object symbols are prefixed with the type of
+    // the C++ object followed by an underscore. If assembling the snapshot,
+    // the assembler might introduce other object symbols which either start
+    // with an underscore or have no underscore.
+    if (objectTypeEnd <= 0) {
+      Expect.isTrue(isAssembled);
+      continue;
+    }
+    // All VM-generated read-only object symbols should have a non-zero size.
+    Expect.notEquals(0, symbol.size);
+    final objectType = symbol.name.substring(0, objectTypeEnd);
+    switch (objectType) {
+      // Used for entries in the non-clustered portion of the read-only data
+      // section that don't correspond to a specific Dart object.
+      case 'RawBytes':
+      // Currently the only types of objects written to the non-clustered
+      // portion of the read-only data section.
+      case 'OneByteString':
+      case 'TwoByteString':
+      case 'CodeSourceMap':
+      case 'PcDescriptors':
+      case 'CompressedStackMaps':
+        break;
+      default:
+        Expect.fail('unexpected object type $objectType');
+    }
+  }
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 7eb612a..ebe20ae 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -286,8 +286,10 @@
 
 [ $compiler == dartk && ($hot_reload || $hot_reload_rollback) ]
 dart/data_uri_spawn_test: Skip # Timeout
+dart/heap_snapshot_referrers_test: SkipSlow
 dart/kernel_determinism_test: SkipSlow
 dart_2/data_uri_spawn_test: Skip # Timeout
+dart_2/heap_snapshot_referrers_test: SkipSlow
 dart_2/isolates/reload_many_isolates_live_and_die_test: SkipSlow # The test itself does reloading of subprocesses.
 dart_2/kernel_determinism_test: SkipSlow
 
diff --git a/runtime/third_party/binary_size/src/explain_binary_size_delta.py b/runtime/third_party/binary_size/src/explain_binary_size_delta.py
index 13f7c12..ecf59a4 100755
--- a/runtime/third_party/binary_size/src/explain_binary_size_delta.py
+++ b/runtime/third_party/binary_size/src/explain_binary_size_delta.py
@@ -15,7 +15,7 @@
 
   # obtain symbol data from first binary in /tmp/nm1.dump
   cd $CHECKOUT1_SRC
-  ninja -C out/Release binary_size_tool
+  buildtools/ninja/ninja -C out/Release binary_size_tool
   tools/binary_size/run_binary_size_analysis \
       --library <path_to_library>
       --destdir /tmp/throwaway
@@ -23,7 +23,7 @@
 
   # obtain symbol data from second binary in /tmp/nm2.dump
   cd $CHECKOUT2_SRC
-  ninja -C out/Release binary_size_tool
+  buildtools/ninja/ninja -C out/Release binary_size_tool
   tools/binary_size/run_binary_size_analysis \
       --library <path_to_library>
       --destdir /tmp/throwaway
diff --git a/runtime/tools/wiki/xref_extractor/bin/main.dart b/runtime/tools/wiki/xref_extractor/bin/main.dart
index f24a9fd..b785dc7 100644
--- a/runtime/tools/wiki/xref_extractor/bin/main.dart
+++ b/runtime/tools/wiki/xref_extractor/bin/main.dart
@@ -88,7 +88,7 @@
 /// same input C++ files and this greatly confuses cquery.
 Future<void> generateCompileCommands() async {
   print('Extracting compilation commands from build files for ReleaseX64');
-  final result = await Process.run('ninja', [
+  final result = await Process.run('buildtools/ninja/ninja', [
     '-C',
     '${Platform.isMacOS ? 'xcodebuild' : 'out'}/ReleaseX64',
     '-t',
diff --git a/runtime/vm/analyze_snapshot_api_impl.cc b/runtime/vm/analyze_snapshot_api_impl.cc
index fa45dd6..7f340ab 100644
--- a/runtime/vm/analyze_snapshot_api_impl.cc
+++ b/runtime/vm/analyze_snapshot_api_impl.cc
@@ -238,7 +238,7 @@
 //   auto dispatch = thread->isolate_group()->dispatch_table();
 //   auto length = dispatch->length();
 // We must unbias the array entries so we don't crash on null access.
-//   auto entries = dispatch->ArrayOrigin() - DispatchTable::OriginElement();
+//   auto entries = dispatch->ArrayOrigin() - DispatchTable::kOriginElement;
 //   for (intptr_t i = 0; i < length; i++) {
 //     OS::Print("0x%lx at %ld\n", entries[i], i);
 //   }
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index 4ae18a2..44e2d74 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -218,7 +218,7 @@
     Serializer* s,
     intptr_t class_id) {
   const auto unboxed_fields_bitmap_host =
-      s->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
+      s->isolate_group()->class_table()->GetUnboxedFieldsMapAt(class_id);
 
   UnboxedFieldBitmap unboxed_fields_bitmap;
   if (unboxed_fields_bitmap_host.IsEmpty() ||
@@ -334,10 +334,10 @@
     }
     s->Write<uint32_t>(cls->untag()->state_bits_);
 
-    // In AOT, the bitmap of unboxed fields should also be serialized
-    if (FLAG_precompiled_mode && !ClassTable::IsTopLevelCid(class_id)) {
-      s->WriteUnsigned64(
-          CalculateTargetUnboxedFieldsBitmap(s, class_id).Value());
+    if (!ClassTable::IsTopLevelCid(class_id)) {
+      const auto unboxed_fields_map =
+          CalculateTargetUnboxedFieldsBitmap(s, class_id);
+      s->WriteUnsigned64(unboxed_fields_map.Value());
     }
   }
 
@@ -430,16 +430,10 @@
       cls->untag()->implementor_cid_ = d.ReadCid();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
       cls->untag()->state_bits_ = d.Read<uint32_t>();
-
-#if defined(DART_PRECOMPILED_RUNTIME)
       d.ReadUnsigned64();  // Skip unboxed fields bitmap.
-#endif
     }
 
     ClassTable* table = d_->isolate_group()->class_table();
-#if defined(DART_PRECOMPILED_RUNTIME)
-    auto shared_class_table = d_->isolate_group()->shared_class_table();
-#endif
     for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
       ClassPtr cls = static_cast<ClassPtr>(d.Ref(id));
       Deserializer::InitializeHeader(cls, kClassCid, Class::InstanceSize());
@@ -478,12 +472,10 @@
       table->AllocateIndex(class_id);
       table->SetAt(class_id, cls);
 
-#if defined(DART_PRECOMPILED_RUNTIME)
       if (!ClassTable::IsTopLevelCid(class_id)) {
         const UnboxedFieldBitmap unboxed_fields_map(d.ReadUnsigned64());
-        shared_class_table->SetUnboxedFieldsMapAt(class_id, unboxed_fields_map);
+        table->SetUnboxedFieldsMapAt(class_id, unboxed_fields_map);
       }
-#endif
     }
   }
 
@@ -3823,7 +3815,7 @@
     const intptr_t next_field_offset = host_next_field_offset_in_words_
                                        << kCompressedWordSizeLog2;
     const auto unboxed_fields_bitmap =
-        s->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(cid_);
+        s->isolate_group()->class_table()->GetUnboxedFieldsMapAt(cid_);
     intptr_t offset = Instance::NextFieldOffset();
     while (offset < next_field_offset) {
       // Skips unboxed fields
@@ -3861,7 +3853,7 @@
     const intptr_t count = objects_.length();
     s->WriteUnsigned64(CalculateTargetUnboxedFieldsBitmap(s, cid_).Value());
     const auto unboxed_fields_bitmap =
-        s->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(cid_);
+        s->isolate_group()->class_table()->GetUnboxedFieldsMapAt(cid_);
 
     for (intptr_t i = 0; i < count; i++) {
       InstancePtr instance = objects_[i];
@@ -4054,10 +4046,6 @@
   }
 };
 
-// Used to pack nullability into other serialized values.
-static constexpr intptr_t kNullabilityBitSize = 2;
-static constexpr intptr_t kNullabilityBitMask = (1 << kNullabilityBitSize) - 1;
-
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class TypeSerializationCluster
     : public CanonicalSetSerializationCluster<
@@ -4081,9 +4069,9 @@
 
     PushFromTo(type);
 
-    ASSERT(type->untag()->type_class_id_ != kIllegalCid);
+    ASSERT(type->untag()->type_class_id() != kIllegalCid);
     ClassPtr type_class =
-        s->isolate_group()->class_table()->At(type->untag()->type_class_id_);
+        s->isolate_group()->class_table()->At(type->untag()->type_class_id());
     s->Push(type_class);
   }
 
@@ -4116,7 +4104,7 @@
   // Keep in sync with Type::Canonicalize.
   virtual bool IsInCanonicalSet(Serializer* s, TypePtr type) {
     ClassPtr type_class =
-        s->isolate_group()->class_table()->At(type->untag()->type_class_id_);
+        s->isolate_group()->class_table()->At(type->untag()->type_class_id());
     if (type_class->untag()->declaration_type() != type) {
       return true;
     }
@@ -4131,25 +4119,12 @@
 #if defined(DART_PRECOMPILER)
     if (FLAG_write_v8_snapshot_profile_to != nullptr) {
       ClassPtr type_class =
-          s->isolate_group()->class_table()->At(type->untag()->type_class_id_);
+          s->isolate_group()->class_table()->At(type->untag()->type_class_id());
       s->AttributePropertyRef(type_class, "<type_class>");
     }
 #endif
     WriteFromTo(type);
-    COMPILE_ASSERT(
-        std::is_unsigned<decltype(UntaggedType::type_class_id_)>::value);
-    s->WriteUnsigned(type->untag()->type_class_id_);
-    ASSERT(type->untag()->type_state_ < (1 << UntaggedType::kTypeStateBitSize));
-    ASSERT(type->untag()->nullability_ < (1 << kNullabilityBitSize));
-    static_assert(UntaggedType::kTypeStateBitSize + kNullabilityBitSize <=
-                      kBitsPerByte * sizeof(uint8_t),
-                  "Cannot pack type_state_ and nullability_ into a uint8_t");
-    const uint8_t combined =
-        (type->untag()->type_state_ << kNullabilityBitSize) |
-        type->untag()->nullability_;
-    ASSERT_EQUAL(type->untag()->type_state_, combined >> kNullabilityBitSize);
-    ASSERT_EQUAL(type->untag()->nullability_, combined & kNullabilityBitMask);
-    s->Write<uint8_t>(combined);
+    s->WriteUnsigned(type->untag()->flags_);
   }
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
@@ -4178,12 +4153,7 @@
       Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
                                      mark_canonical);
       d.ReadFromTo(type);
-      COMPILE_ASSERT(
-          std::is_unsigned<decltype(UntaggedType::type_class_id_)>::value);
-      type->untag()->type_class_id_ = d.ReadUnsigned();
-      const uint8_t combined = d.Read<uint8_t>();
-      type->untag()->type_state_ = combined >> kNullabilityBitSize;
-      type->untag()->nullability_ = combined & kNullabilityBitMask;
+      type->untag()->flags_ = d.ReadUnsigned();
     }
   }
 
@@ -4265,19 +4235,8 @@
   void WriteFunctionType(Serializer* s, FunctionTypePtr type) {
     AutoTraceObject(type);
     WriteFromTo(type);
-    ASSERT(type->untag()->type_state_ <
-           (1 << UntaggedFunctionType::kTypeStateBitSize));
-    ASSERT(type->untag()->nullability_ < (1 << kNullabilityBitSize));
-    static_assert(
-        UntaggedFunctionType::kTypeStateBitSize + kNullabilityBitSize <=
-            kBitsPerByte * sizeof(uint8_t),
-        "Cannot pack type_state_ and nullability_ into a uint8_t");
-    const uint8_t combined =
-        (type->untag()->type_state_ << kNullabilityBitSize) |
-        type->untag()->nullability_;
-    ASSERT_EQUAL(type->untag()->type_state_, combined >> kNullabilityBitSize);
-    ASSERT_EQUAL(type->untag()->nullability_, combined & kNullabilityBitMask);
-    s->Write<uint8_t>(combined);
+    ASSERT(Utils::IsUint(8, type->untag()->flags_));
+    s->Write<uint8_t>(type->untag()->flags_);
     s->Write<uint32_t>(type->untag()->packed_parameter_counts_);
     s->Write<uint16_t>(type->untag()->packed_type_parameter_counts_);
   }
@@ -4308,9 +4267,7 @@
       Deserializer::InitializeHeader(
           type, kFunctionTypeCid, FunctionType::InstanceSize(), mark_canonical);
       d.ReadFromTo(type);
-      const uint8_t combined = d.Read<uint8_t>();
-      type->untag()->type_state_ = combined >> kNullabilityBitSize;
-      type->untag()->nullability_ = combined & kNullabilityBitMask;
+      type->untag()->flags_ = d.Read<uint8_t>();
       type->untag()->packed_parameter_counts_ = d.Read<uint32_t>();
       type->untag()->packed_type_parameter_counts_ = d.Read<uint16_t>();
     }
@@ -4350,6 +4307,117 @@
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
+class RecordTypeSerializationCluster
+    : public CanonicalSetSerializationCluster<CanonicalRecordTypeSet,
+                                              RecordType,
+                                              RecordTypePtr> {
+ public:
+  RecordTypeSerializationCluster(bool is_canonical,
+                                 bool represents_canonical_set)
+      : CanonicalSetSerializationCluster(
+            kRecordTypeCid,
+            is_canonical,
+            represents_canonical_set,
+            "RecordType",
+            compiler::target::RecordType::InstanceSize()) {}
+  ~RecordTypeSerializationCluster() {}
+
+  void Trace(Serializer* s, ObjectPtr object) {
+    RecordTypePtr type = RecordType::RawCast(object);
+    objects_.Add(type);
+    PushFromTo(type);
+  }
+
+  void WriteAlloc(Serializer* s) {
+    intptr_t count = objects_.length();
+    s->WriteUnsigned(count);
+    ReorderObjects(s);
+
+    for (intptr_t i = 0; i < count; i++) {
+      RecordTypePtr type = objects_[i];
+      s->AssignRef(type);
+    }
+    WriteCanonicalSetLayout(s);
+  }
+
+  void WriteFill(Serializer* s) {
+    intptr_t count = objects_.length();
+    for (intptr_t i = 0; i < count; i++) {
+      WriteRecordType(s, objects_[i]);
+    }
+  }
+
+ private:
+  void WriteRecordType(Serializer* s, RecordTypePtr type) {
+    AutoTraceObject(type);
+    WriteFromTo(type);
+    ASSERT(Utils::IsUint(8, type->untag()->flags_));
+    s->Write<uint8_t>(type->untag()->flags_);
+  }
+};
+#endif  // !DART_PRECOMPILED_RUNTIME
+
+class RecordTypeDeserializationCluster
+    : public CanonicalSetDeserializationCluster<CanonicalRecordTypeSet> {
+ public:
+  RecordTypeDeserializationCluster(bool is_canonical, bool is_root_unit)
+      : CanonicalSetDeserializationCluster(is_canonical,
+                                           is_root_unit,
+                                           "RecordType") {}
+  ~RecordTypeDeserializationCluster() {}
+
+  void ReadAlloc(Deserializer* d) {
+    ReadAllocFixedSize(d, RecordType::InstanceSize());
+    BuildCanonicalSetFromLayout(d);
+  }
+
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const bool mark_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      RecordTypePtr type = static_cast<RecordTypePtr>(d.Ref(id));
+      Deserializer::InitializeHeader(
+          type, kRecordTypeCid, RecordType::InstanceSize(), mark_canonical);
+      d.ReadFromTo(type);
+      type->untag()->flags_ = d.Read<uint8_t>();
+    }
+  }
+
+  void PostLoad(Deserializer* d, const Array& refs, bool primary) {
+    if (!table_.IsNull()) {
+      auto object_store = d->isolate_group()->object_store();
+      VerifyCanonicalSet(d, refs,
+                         Array::Handle(object_store->canonical_record_types()));
+      object_store->set_canonical_record_types(table_);
+    } else if (!primary && is_canonical()) {
+      AbstractType& type = AbstractType::Handle(d->zone());
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
+        type ^= refs.At(i);
+        type = type.Canonicalize(d->thread(), nullptr);
+        refs.SetAt(i, type);
+      }
+    }
+
+    RecordType& type = RecordType::Handle(d->zone());
+    Code& stub = Code::Handle(d->zone());
+
+    if (Snapshot::IncludesCode(d->kind())) {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+        type ^= refs.At(id);
+        type.UpdateTypeTestingStubEntryPoint();
+      }
+    } else {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+        type ^= refs.At(id);
+        stub = TypeTestingStubGenerator::DefaultCodeForType(type);
+        type.InitializeTypeTestingStubNonAtomic(stub);
+      }
+    }
+  }
+};
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
 class TypeRefSerializationCluster : public SerializationCluster {
  public:
   TypeRefSerializationCluster()
@@ -4419,16 +4487,20 @@
     }
 
     TypeRef& type_ref = TypeRef::Handle(d->zone());
+    AbstractType& type = AbstractType::Handle(d->zone());
     Code& stub = Code::Handle(d->zone());
+    const bool includes_code = Snapshot::IncludesCode(d->kind());
 
-    if (Snapshot::IncludesCode(d->kind())) {
-      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
-        type_ref ^= refs.At(id);
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      type_ref ^= refs.At(id);
+
+      // Refresh finalization state and nullability.
+      type = type_ref.type();
+      type_ref.set_type(type);
+
+      if (includes_code) {
         type_ref.UpdateTypeTestingStubEntryPoint();
-      }
-    } else {
-      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
-        type_ref ^= refs.At(id);
+      } else {
         stub = TypeTestingStubGenerator::DefaultCodeForType(type_ref);
         type_ref.InitializeTypeTestingStubNonAtomic(stub);
       }
@@ -4484,16 +4556,8 @@
     s->Write<int32_t>(type->untag()->parameterized_class_id_);
     s->Write<uint8_t>(type->untag()->base_);
     s->Write<uint8_t>(type->untag()->index_);
-    ASSERT(type->untag()->flags_ < (1 << UntaggedTypeParameter::kFlagsBitSize));
-    ASSERT(type->untag()->nullability_ < (1 << kNullabilityBitSize));
-    static_assert(UntaggedTypeParameter::kFlagsBitSize + kNullabilityBitSize <=
-                      kBitsPerByte * sizeof(uint8_t),
-                  "Cannot pack flags_ and nullability_ into a uint8_t");
-    const uint8_t combined = (type->untag()->flags_ << kNullabilityBitSize) |
-                             type->untag()->nullability_;
-    ASSERT_EQUAL(type->untag()->flags_, combined >> kNullabilityBitSize);
-    ASSERT_EQUAL(type->untag()->nullability_, combined & kNullabilityBitMask);
-    s->Write<uint8_t>(combined);
+    ASSERT(Utils::IsUint(8, type->untag()->flags_));
+    s->Write<uint8_t>(type->untag()->flags_);
   }
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
@@ -4526,9 +4590,7 @@
       type->untag()->parameterized_class_id_ = d.Read<int32_t>();
       type->untag()->base_ = d.Read<uint8_t>();
       type->untag()->index_ = d.Read<uint8_t>();
-      const uint8_t combined = d.Read<uint8_t>();
-      type->untag()->flags_ = combined >> kNullabilityBitSize;
-      type->untag()->nullability_ = combined & kNullabilityBitMask;
+      type->untag()->flags_ = d.Read<uint8_t>();
     }
   }
 
@@ -4854,6 +4916,94 @@
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
+class RecordSerializationCluster : public SerializationCluster {
+ public:
+  explicit RecordSerializationCluster(bool is_canonical)
+      : SerializationCluster("Record", kRecordCid, kSizeVaries, is_canonical) {}
+  ~RecordSerializationCluster() {}
+
+  void Trace(Serializer* s, ObjectPtr object) {
+    RecordPtr record = Record::RawCast(object);
+    objects_.Add(record);
+
+    s->Push(record->untag()->field_names());
+    const intptr_t num_fields = record->untag()->num_fields_;
+    for (intptr_t i = 0; i < num_fields; ++i) {
+      s->Push(record->untag()->field(i));
+    }
+  }
+
+  void WriteAlloc(Serializer* s) {
+    const intptr_t count = objects_.length();
+    s->WriteUnsigned(count);
+    for (intptr_t i = 0; i < count; ++i) {
+      RecordPtr record = objects_[i];
+      s->AssignRef(record);
+      AutoTraceObject(record);
+      const intptr_t num_fields = record->untag()->num_fields_;
+      s->WriteUnsigned(num_fields);
+      target_memory_size_ += compiler::target::Record::InstanceSize(num_fields);
+    }
+  }
+
+  void WriteFill(Serializer* s) {
+    const intptr_t count = objects_.length();
+    for (intptr_t i = 0; i < count; ++i) {
+      RecordPtr record = objects_[i];
+      AutoTraceObject(record);
+      const intptr_t num_fields = record->untag()->num_fields_;
+      s->WriteUnsigned(num_fields);
+      WriteField(record, field_names());
+      for (intptr_t j = 0; j < num_fields; ++j) {
+        s->WriteElementRef(record->untag()->field(j), j);
+      }
+    }
+  }
+
+ private:
+  GrowableArray<RecordPtr> objects_;
+};
+#endif  // !DART_PRECOMPILED_RUNTIME
+
+class RecordDeserializationCluster
+    : public AbstractInstanceDeserializationCluster {
+ public:
+  explicit RecordDeserializationCluster(bool is_canonical)
+      : AbstractInstanceDeserializationCluster("Record", is_canonical) {}
+  ~RecordDeserializationCluster() {}
+
+  void ReadAlloc(Deserializer* d) {
+    start_index_ = d->next_index();
+    PageSpace* old_space = d->heap()->old_space();
+    const intptr_t count = d->ReadUnsigned();
+    for (intptr_t i = 0; i < count; i++) {
+      const intptr_t num_fields = d->ReadUnsigned();
+      d->AssignRef(
+          old_space->AllocateSnapshot(Record::InstanceSize(num_fields)));
+    }
+    stop_index_ = d->next_index();
+  }
+
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const bool stamp_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      RecordPtr record = static_cast<RecordPtr>(d.Ref(id));
+      const intptr_t num_fields = d.ReadUnsigned();
+      Deserializer::InitializeHeader(record, kRecordCid,
+                                     Record::InstanceSize(num_fields),
+                                     stamp_canonical);
+      record->untag()->num_fields_ = num_fields;
+      record->untag()->field_names_ = static_cast<ArrayPtr>(d.ReadRef());
+      for (intptr_t j = 0; j < num_fields; ++j) {
+        record->untag()->data()[j] = d.ReadRef();
+      }
+    }
+  }
+};
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
 class TypedDataSerializationCluster : public SerializationCluster {
  public:
   explicit TypedDataSerializationCluster(intptr_t cid)
@@ -5994,6 +6144,7 @@
   V(canonical_types, Array, HashTables::New<CanonicalTypeSet>(4))              \
   V(canonical_function_types, Array,                                           \
     HashTables::New<CanonicalFunctionTypeSet>(4))                              \
+  V(canonical_record_types, Array, HashTables::New<CanonicalRecordTypeSet>(4)) \
   V(canonical_type_arguments, Array,                                           \
     HashTables::New<CanonicalTypeArgumentsSet>(4))                             \
   V(canonical_type_parameters, Array,                                          \
@@ -6668,6 +6819,10 @@
       type = "FunctionType";
       break;
     };
+    case kRecordTypeCid: {
+      type = "RecordType";
+      break;
+    };
     default:
       FATAL("Request to create artificial node for object with cid %d", cid);
   }
@@ -6854,6 +7009,9 @@
     case kFunctionTypeCid:
       return new (Z) FunctionTypeSerializationCluster(
           is_canonical, cluster_represents_canonical_set);
+    case kRecordTypeCid:
+      return new (Z) RecordTypeSerializationCluster(
+          is_canonical, cluster_represents_canonical_set);
     case kTypeRefCid:
       return new (Z) TypeRefSerializationCluster();
     case kTypeParameterCid:
@@ -6867,6 +7025,8 @@
       return new (Z) DoubleSerializationCluster(is_canonical);
     case kGrowableObjectArrayCid:
       return new (Z) GrowableObjectArraySerializationCluster();
+    case kRecordCid:
+      return new (Z) RecordSerializationCluster(is_canonical);
     case kStackTraceCid:
       return new (Z) StackTraceSerializationCluster();
     case kRegExpCid:
@@ -7288,7 +7448,11 @@
 }
 
 uint32_t Serializer::GetDataOffset(ObjectPtr object) const {
+#if defined(SNAPSHOT_BACKTRACE)
+  return image_writer_->GetDataOffsetFor(object, ParentOf(object));
+#else
   return image_writer_->GetDataOffsetFor(object);
+#endif
 }
 
 intptr_t Serializer::GetDataSize() const {
@@ -7393,7 +7557,16 @@
 }
 
 #if defined(SNAPSHOT_BACKTRACE)
-ObjectPtr Serializer::ParentOf(const Object& object) {
+ObjectPtr Serializer::ParentOf(ObjectPtr object) const {
+  for (intptr_t i = 0; i < parent_pairs_.length(); i += 2) {
+    if (parent_pairs_[i]->ptr() == object) {
+      return parent_pairs_[i + 1]->ptr();
+    }
+  }
+  return Object::null();
+}
+
+ObjectPtr Serializer::ParentOf(const Object& object) const {
   for (intptr_t i = 0; i < parent_pairs_.length(); i += 2) {
     if (parent_pairs_[i]->ptr() == object.ptr()) {
       return parent_pairs_[i + 1]->ptr();
@@ -7998,6 +8171,9 @@
     case kFunctionTypeCid:
       return new (Z)
           FunctionTypeDeserializationCluster(is_canonical, !is_non_root_unit_);
+    case kRecordTypeCid:
+      return new (Z)
+          RecordTypeDeserializationCluster(is_canonical, !is_non_root_unit_);
     case kTypeRefCid:
       ASSERT(!is_canonical);
       return new (Z) TypeRefDeserializationCluster();
@@ -8013,6 +8189,8 @@
     case kGrowableObjectArrayCid:
       ASSERT(!is_canonical);
       return new (Z) GrowableObjectArrayDeserializationCluster();
+    case kRecordCid:
+      return new (Z) RecordDeserializationCluster(is_canonical);
     case kStackTraceCid:
       ASSERT(!is_canonical);
       return new (Z) StackTraceDeserializationCluster();
diff --git a/runtime/vm/app_snapshot.h b/runtime/vm/app_snapshot.h
index 922c8ac..3445cb4 100644
--- a/runtime/vm/app_snapshot.h
+++ b/runtime/vm/app_snapshot.h
@@ -19,10 +19,6 @@
 #include "vm/snapshot.h"
 #include "vm/version.h"
 
-#if defined(DEBUG)
-#define SNAPSHOT_BACKTRACE
-#endif
-
 namespace dart {
 
 // For full snapshots, we use a clustered snapshot format that trades longer
@@ -244,7 +240,8 @@
 
   void UnexpectedObject(ObjectPtr object, const char* message);
 #if defined(SNAPSHOT_BACKTRACE)
-  ObjectPtr ParentOf(const Object& object);
+  ObjectPtr ParentOf(ObjectPtr object) const;
+  ObjectPtr ParentOf(const Object& object) const;
 #endif
 
   SerializationCluster* NewClusterForClass(intptr_t cid, bool is_canonical);
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 203f9ca..99ea761 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -53,13 +53,13 @@
   Class& cls = Class::Handle(zone, object_store->closure_class());
   cls.EnsureIsFinalized(thread);
 
-  // Make sure _Closure fields are not marked as unboxing candidates
-  // as they are accessed with plain loads.
+  // Make sure _Closure fields are not marked as unboxed as they are accessed
+  // with plain loads.
   const Array& fields = Array::Handle(zone, cls.fields());
   Field& field = Field::Handle(zone);
   for (intptr_t i = 0; i < fields.Length(); ++i) {
     field ^= fields.At(i);
-    field.set_is_unboxing_candidate(false);
+    field.set_is_unboxed(false);
   }
   // _Closure._hash field should be explicitly marked as nullable because
   // VM creates instances of _Closure without compiling its constructors,
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index ac4e3b4..e3d6a6e 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -26,11 +26,11 @@
   V(Function_apply, 2)                                                         \
   V(Closure_equals, 2)                                                         \
   V(Closure_computeHash, 1)                                                    \
+  V(AbstractType_equality, 2)                                                  \
+  V(AbstractType_getHashCode, 1)                                               \
   V(AbstractType_toString, 1)                                                  \
-  V(Type_getHashCode, 1)                                                       \
   V(Type_equality, 2)                                                          \
-  V(FunctionType_getHashCode, 1)                                               \
-  V(FunctionType_equality, 2)                                                  \
+  V(Type_getHashCode, 1)                                                       \
   V(LibraryPrefix_isLoaded, 1)                                                 \
   V(LibraryPrefix_setLoaded, 1)                                                \
   V(LibraryPrefix_loadingUnit, 1)                                              \
@@ -155,9 +155,7 @@
   V(Timeline_getNextTaskId, 0)                                                 \
   V(Timeline_getTraceClock, 0)                                                 \
   V(Timeline_isDartStreamEnabled, 0)                                           \
-  V(Timeline_reportFlowEvent, 5)                                               \
-  V(Timeline_reportInstantEvent, 3)                                            \
-  V(Timeline_reportTaskEvent, 5)                                               \
+  V(Timeline_reportTaskEvent, 4)                                               \
   V(TypedData_Int8Array_new, 2)                                                \
   V(TypedData_Uint8Array_new, 2)                                               \
   V(TypedData_Uint8ClampedArray_new, 2)                                        \
diff --git a/runtime/vm/canonical_tables.h b/runtime/vm/canonical_tables.h
index b6c8ca0..310444e 100644
--- a/runtime/vm/canonical_tables.h
+++ b/runtime/vm/canonical_tables.h
@@ -212,6 +212,45 @@
 };
 typedef UnorderedHashSet<CanonicalFunctionTypeTraits> CanonicalFunctionTypeSet;
 
+class CanonicalRecordTypeKey {
+ public:
+  explicit CanonicalRecordTypeKey(const RecordType& key) : key_(key) {}
+  bool Matches(const RecordType& arg) const { return key_.Equals(arg); }
+  uword Hash() const { return key_.Hash(); }
+  const RecordType& key_;
+
+ private:
+  DISALLOW_ALLOCATION();
+};
+
+// Traits for looking up Canonical RecordType based on its hash.
+class CanonicalRecordTypeTraits {
+ public:
+  static const char* Name() { return "CanonicalRecordTypeTraits"; }
+  static bool ReportStats() { return false; }
+
+  // Called when growing the table.
+  static bool IsMatch(const Object& a, const Object& b) {
+    ASSERT(a.IsRecordType() && b.IsRecordType());
+    const RecordType& arg1 = RecordType::Cast(a);
+    const RecordType& arg2 = RecordType::Cast(b);
+    return arg1.Equals(arg2) && (arg1.Hash() == arg2.Hash());
+  }
+  static bool IsMatch(const CanonicalRecordTypeKey& a, const Object& b) {
+    ASSERT(b.IsRecordType());
+    return a.Matches(RecordType::Cast(b));
+  }
+  static uword Hash(const Object& key) {
+    ASSERT(key.IsRecordType());
+    return RecordType::Cast(key).Hash();
+  }
+  static uword Hash(const CanonicalRecordTypeKey& key) { return key.Hash(); }
+  static ObjectPtr NewKey(const CanonicalRecordTypeKey& obj) {
+    return obj.key_.ptr();
+  }
+};
+typedef UnorderedHashSet<CanonicalRecordTypeTraits> CanonicalRecordTypeSet;
+
 class CanonicalTypeParameterKey {
  public:
   explicit CanonicalTypeParameterKey(const TypeParameter& key) : key_(key) {}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index bd47dc0..c7a1028 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -659,6 +659,11 @@
             AbstractType& unfinalized_type = AbstractType::Handle(zone);
             if (super_type_arg.IsTypeRef()) {
               unfinalized_type = TypeRef::Cast(super_type_arg).type();
+              if (unfinalized_type.IsFinalized()) {
+                super_type_arg.SetIsFinalized();
+                arguments.SetTypeAt(i, super_type_arg);
+                continue;
+              }
             } else {
               ASSERT(super_type_arg.IsType());
               unfinalized_type = super_type_arg.ptr();
@@ -755,10 +760,13 @@
       // is_being_finalized mark bit.
       return type.ptr();
     }
+    type.SetIsBeingFinalized();
     AbstractType& ref_type =
         AbstractType::Handle(zone, TypeRef::Cast(type).type());
     ref_type = FinalizeType(ref_type, finalization, pending_types);
+    ASSERT(ref_type.IsFinalized());
     TypeRef::Cast(type).set_type(ref_type);
+    ASSERT(type.IsFinalized());
     return type.ptr();
   }
 
@@ -822,6 +830,11 @@
                              pending_types);
   }
 
+  if (type.IsRecordType()) {
+    return FinalizeRecordType(zone, RecordType::Cast(type), finalization,
+                              pending_types);
+  }
+
   // This type is the root type of the type graph if no pending types queue is
   // allocated yet. A function type is a collection of types, but not a root.
   const bool is_root_type = pending_types == NULL;
@@ -906,6 +919,40 @@
   return signature.ptr();
 }
 
+AbstractTypePtr ClassFinalizer::FinalizeRecordType(
+    Zone* zone,
+    const RecordType& record,
+    FinalizationKind finalization,
+    PendingTypes* pending_types) {
+  AbstractType& type = AbstractType::Handle(zone);
+  AbstractType& finalized_type = AbstractType::Handle(zone);
+  // Finalize record field types.
+  const intptr_t num_fields = record.NumFields();
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    type = record.FieldTypeAt(i);
+    finalized_type = FinalizeType(type, kFinalize, pending_types);
+    if (type.ptr() != finalized_type.ptr()) {
+      record.SetFieldTypeAt(i, finalized_type);
+    }
+  }
+  // Canonicalize field names so they can be compared with pointer comparison.
+  // The field names are already sorted in the front-end.
+  Array& field_names = Array::Handle(zone, record.field_names());
+  field_names ^= field_names.Canonicalize(Thread::Current());
+  record.set_field_names(field_names);
+
+  if (FLAG_trace_type_finalization) {
+    THR_Print("Marking record type '%s' as finalized\n",
+              String::Handle(zone, record.Name()).ToCString());
+  }
+  record.SetIsFinalized();
+
+  if (finalization >= kCanonicalize) {
+    return record.Canonicalize(Thread::Current(), nullptr);
+  }
+  return record.ptr();
+}
+
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
 #if defined(TARGET_ARCH_X64)
@@ -1524,7 +1571,7 @@
           Map(param->untag()->parameterized_class_id_);
     } else if (obj->IsType()) {
       TypePtr type = Type::RawCast(obj);
-      type->untag()->type_class_id_ = Map(type->untag()->type_class_id_);
+      type->untag()->set_type_class_id(Map(type->untag()->type_class_id()));
     } else {
       intptr_t old_cid = obj->GetClassId();
       intptr_t new_cid = Map(old_cid);
@@ -1551,12 +1598,10 @@
     // The [HeapIterationScope] also safepoints all threads.
     HeapIterationScope his(T);
 
-    IG->shared_class_table()->Remap(old_to_new_cid);
-    IG->set_remapping_cids(true);
-
     // Update the class table. Do it before rewriting cids in headers, as
     // the heap walkers load an object's size *after* calling the visitor.
     IG->class_table()->Remap(old_to_new_cid);
+    IG->set_remapping_cids(true);
 
     // Rewrite cids in headers and cids in Classes, Fields, Types and
     // TypeParameters.
@@ -1582,7 +1627,7 @@
 // In the Dart VM heap the following instances directly use cids for the
 // computation of canonical hash codes:
 //
-//    * TypePtr (due to UntaggedType::type_class_id_)
+//    * TypePtr (due to UntaggedType::type_class_id)
 //    * TypeParameterPtr (due to UntaggedTypeParameter::parameterized_class_id_)
 //
 // The following instances use cids for the computation of canonical hash codes
@@ -1599,6 +1644,7 @@
 //
 //    * UntaggedType::hash_
 //    * UntaggedFunctionType::hash_
+//    * UntaggedRecordType::hash_
 //    * UntaggedTypeParameter::hash_
 //    * UntaggedTypeArguments::hash_
 //    * InstancePtr (weak table)
@@ -1613,6 +1659,7 @@
 //
 //   * ObjectStore::canonical_types()
 //   * ObjectStore::canonical_function_types()
+//   * ObjectStore::canonical_record_types()
 //   * ObjectStore::canonical_type_parameters()
 //   * ObjectStore::canonical_type_arguments()
 //   * Class::constants()
@@ -1623,6 +1670,7 @@
       : type_param_(TypeParameter::Handle(zone)),
         type_(Type::Handle(zone)),
         function_type_(FunctionType::Handle(zone)),
+        record_type_(RecordType::Handle(zone)),
         type_args_(TypeArguments::Handle(zone)) {}
 
   void VisitObject(ObjectPtr obj) {
@@ -1635,6 +1683,9 @@
     } else if (obj->IsFunctionType()) {
       function_type_ ^= obj;
       function_type_.SetHash(0);
+    } else if (obj->IsRecordType()) {
+      record_type_ ^= obj;
+      record_type_.SetHash(0);
     } else if (obj->IsTypeArguments()) {
       type_args_ ^= obj;
       type_args_.SetHash(0);
@@ -1645,6 +1696,7 @@
   TypeParameter& type_param_;
   Type& type_;
   FunctionType& function_type_;
+  RecordType& record_type_;
   TypeArguments& type_args_;
 };
 
@@ -1702,6 +1754,27 @@
   }
   object_store->set_canonical_function_types(function_types_table.Release());
 
+  // Rehash the canonical RecordTypes table.
+  Array& record_types = Array::Handle(Z);
+  RecordType& record_type = RecordType::Handle(Z);
+  {
+    CanonicalRecordTypeSet record_types_table(
+        Z, object_store->canonical_record_types());
+    record_types = HashTables::ToArray(record_types_table, false);
+    record_types_table.Release();
+  }
+
+  dict_size = Utils::RoundUpToPowerOfTwo(record_types.Length() * 4 / 3);
+  CanonicalRecordTypeSet record_types_table(
+      Z, HashTables::New<CanonicalRecordTypeSet>(dict_size, Heap::kOld));
+  for (intptr_t i = 0; i < record_types.Length(); i++) {
+    record_type ^= record_types.At(i);
+    bool present = record_types_table.Insert(record_type);
+    // Two recursive types with different topology (and hashes) may be equal.
+    ASSERT(!present || record_type.IsRecursive());
+  }
+  object_store->set_canonical_record_types(record_types_table.Release());
+
   // Rehash the canonical TypeParameters table.
   Array& typeparams = Array::Handle(Z);
   TypeParameter& typeparam = TypeParameter::Handle(Z);
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 3f7775d..48b2bb2 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -93,6 +93,12 @@
       FinalizationKind finalization = kCanonicalize,
       PendingTypes* pending_types = NULL);
 
+  static AbstractTypePtr FinalizeRecordType(
+      Zone* zone,
+      const RecordType& record,
+      FinalizationKind finalization = kCanonicalize,
+      PendingTypes* pending_types = nullptr);
+
 #if !defined(DART_PRECOMPILED_RUNTIME)
   static void AllocateEnumValues(const Class& enum_cls);
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index 1199680..22001ad 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -68,13 +68,14 @@
   V(TypeArguments)                                                             \
   V(AbstractType)                                                              \
   V(Type)                                                                      \
+  V(FunctionType)                                                              \
+  V(RecordType)                                                                \
+  V(TypeRef)                                                                   \
+  V(TypeParameter)                                                             \
   V(FinalizerBase)                                                             \
   V(Finalizer)                                                                 \
   V(NativeFinalizer)                                                           \
   V(FinalizerEntry)                                                            \
-  V(FunctionType)                                                              \
-  V(TypeRef)                                                                   \
-  V(TypeParameter)                                                             \
   V(Closure)                                                                   \
   V(Number)                                                                    \
   V(Integer)                                                                   \
@@ -85,6 +86,7 @@
   V(Float32x4)                                                                 \
   V(Int32x4)                                                                   \
   V(Float64x2)                                                                 \
+  V(Record)                                                                    \
   V(TypedDataBase)                                                             \
   V(TypedData)                                                                 \
   V(ExternalTypedData)                                                         \
@@ -358,8 +360,10 @@
 }
 
 inline bool IsTypeClassId(intptr_t index) {
-  // Only Type and FunctionType can be encountered as instance types at runtime.
-  return index == kTypeCid || index == kFunctionTypeCid;
+  // Only Type, FunctionType and RecordType can be encountered as instance
+  // types at runtime.
+  return index == kTypeCid || index == kFunctionTypeCid ||
+         index == kRecordTypeCid;
 }
 
 inline bool IsTypedDataBaseClassId(intptr_t index) {
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index edec756..12cab5e 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -20,461 +20,154 @@
 
 DEFINE_FLAG(bool, print_class_table, false, "Print initial class table.");
 
-SharedClassTable::SharedClassTable()
-    : top_(kNumPredefinedCids),
-      capacity_(0),
-      old_tables_(new MallocGrowableArray<void*>()) {
+ClassTable::ClassTable(ClassTableAllocator* allocator)
+    : allocator_(allocator),
+      classes_(allocator),
+      top_level_classes_(allocator) {
   if (Dart::vm_isolate() == NULL) {
-    ASSERT(kInitialCapacity >= kNumPredefinedCids);
-    capacity_ = kInitialCapacity;
-    // Note that [calloc] will zero-initialize the memory.
-    table_.store(reinterpret_cast<RelaxedAtomic<intptr_t>*>(
-        calloc(capacity_, sizeof(RelaxedAtomic<intptr_t>))));
-  } else {
-    // Duplicate the class table from the VM isolate.
-    auto vm_shared_class_table = Dart::vm_isolate_group()->shared_class_table();
-    capacity_ = vm_shared_class_table->capacity_;
-    // Note that [calloc] will zero-initialize the memory.
-    RelaxedAtomic<intptr_t>* table = reinterpret_cast<RelaxedAtomic<intptr_t>*>(
-        calloc(capacity_, sizeof(RelaxedAtomic<intptr_t>)));
-    // The following cids don't have a corresponding class object in Dart code.
-    // We therefore need to initialize them eagerly.
-    COMPILE_ASSERT(kFirstInternalOnlyCid == kObjectCid + 1);
-    for (intptr_t i = kObjectCid; i <= kLastInternalOnlyCid; i++) {
-      table[i] = vm_shared_class_table->SizeAt(i);
-    }
-    table[kTypeArgumentsCid] = vm_shared_class_table->SizeAt(kTypeArgumentsCid);
-    table[kFreeListElement] = vm_shared_class_table->SizeAt(kFreeListElement);
-    table[kForwardingCorpse] = vm_shared_class_table->SizeAt(kForwardingCorpse);
-    table[kDynamicCid] = vm_shared_class_table->SizeAt(kDynamicCid);
-    table[kVoidCid] = vm_shared_class_table->SizeAt(kVoidCid);
-    table_.store(table);
-  }
-#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
-  // Note that [calloc] will zero-initialize the memory.
-  unboxed_fields_map_ = static_cast<UnboxedFieldBitmap*>(
-      calloc(capacity_, sizeof(UnboxedFieldBitmap)));
-#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
-#ifndef PRODUCT
-  // Note that [calloc] will zero-initialize the memory.
-  trace_allocation_table_.store(
-      static_cast<uint8_t*>(calloc(capacity_, sizeof(uint8_t))));
-#endif  // !PRODUCT
-}
-SharedClassTable::~SharedClassTable() {
-  if (old_tables_ != NULL) {
-    FreeOldTables();
-    delete old_tables_;
-  }
-  free(table_.load());
-  free(unboxed_fields_map_);
-
-  NOT_IN_PRODUCT(free(trace_allocation_table_.load()));
-}
-
-void ClassTable::set_table(ClassPtr* table) {
-  // We don't have to stop mutators, since the old table is the prefix of the
-  // new table. But we should ensure that all writes to the current table are
-  // visible once the new table is visible.
-  table_.store(table);
-  IsolateGroup::Current()->set_cached_class_table_table(table);
-}
-
-ClassTable::ClassTable(SharedClassTable* shared_class_table)
-    : top_(kNumPredefinedCids),
-      capacity_(0),
-      tlc_top_(0),
-      tlc_capacity_(0),
-      table_(nullptr),
-      tlc_table_(nullptr),
-      old_class_tables_(new MallocGrowableArray<ClassPtr*>()),
-      shared_class_table_(shared_class_table) {
-  if (Dart::vm_isolate() == NULL) {
-    ASSERT(kInitialCapacity >= kNumPredefinedCids);
-    capacity_ = kInitialCapacity;
-    // Note that [calloc] will zero-initialize the memory.
-    // Don't use set_table because caller is supposed to set up isolates
-    // cached copy when constructing ClassTable. Isolate::Current might not
-    // be available at this point yet.
-    table_.store(static_cast<ClassPtr*>(calloc(capacity_, sizeof(ClassPtr))));
+    classes_.SetNumCidsAndCapacity(kNumPredefinedCids, kInitialCapacity);
   } else {
     // Duplicate the class table from the VM isolate.
     ClassTable* vm_class_table = Dart::vm_isolate_group()->class_table();
-    capacity_ = vm_class_table->capacity_;
-    // Note that [calloc] will zero-initialize the memory.
-    ClassPtr* table =
-        static_cast<ClassPtr*>(calloc(capacity_, sizeof(ClassPtr)));
+    classes_.SetNumCidsAndCapacity(kNumPredefinedCids,
+                                   vm_class_table->classes_.capacity());
+
+    const auto copy_info_for_cid = [&](intptr_t cid) {
+      classes_.At<kClassIndex>(cid) = vm_class_table->At(cid);
+      classes_.At<kSizeIndex>(cid) = vm_class_table->SizeAt(cid);
+    };
+
     // The following cids don't have a corresponding class object in Dart code.
     // We therefore need to initialize them eagerly.
     COMPILE_ASSERT(kFirstInternalOnlyCid == kObjectCid + 1);
     for (intptr_t i = kObjectCid; i <= kLastInternalOnlyCid; i++) {
-      table[i] = vm_class_table->At(i);
+      copy_info_for_cid(i);
     }
-    table[kTypeArgumentsCid] = vm_class_table->At(kTypeArgumentsCid);
-    table[kFreeListElement] = vm_class_table->At(kFreeListElement);
-    table[kForwardingCorpse] = vm_class_table->At(kForwardingCorpse);
-    table[kDynamicCid] = vm_class_table->At(kDynamicCid);
-    table[kVoidCid] = vm_class_table->At(kVoidCid);
-    // Don't use set_table because caller is supposed to set up isolates
-    // cached copy when constructing ClassTable. Isolate::Current might not
-    // be available at this point yet.
-    table_.store(table);
+    copy_info_for_cid(kTypeArgumentsCid);
+    copy_info_for_cid(kFreeListElement);
+    copy_info_for_cid(kForwardingCorpse);
+    copy_info_for_cid(kDynamicCid);
+    copy_info_for_cid(kVoidCid);
   }
+  UpdateCachedAllocationTracingStateTablePointer();
 }
 
 ClassTable::~ClassTable() {
-  if (old_class_tables_ != nullptr) {
-    FreeOldTables();
-    delete old_class_tables_;
-  }
-  free(table_.load());
-  free(tlc_table_.load());
-}
-
-void ClassTable::AddOldTable(ClassPtr* old_class_table) {
-  ASSERT(Thread::Current()->IsMutatorThread());
-  old_class_tables_->Add(old_class_table);
-}
-
-void ClassTable::FreeOldTables() {
-  while (old_class_tables_->length() > 0) {
-    free(old_class_tables_->RemoveLast());
-  }
-}
-
-void SharedClassTable::AddOldTable(intptr_t* old_table) {
-  ASSERT(Thread::Current()->IsMutatorThread());
-  old_tables_->Add(old_table);
-}
-
-void SharedClassTable::FreeOldTables() {
-  while (old_tables_->length() > 0) {
-    free(old_tables_->RemoveLast());
-  }
 }
 
 void ClassTable::Register(const Class& cls) {
   ASSERT(Thread::Current()->IsMutatorThread());
-
-  const classid_t cid = cls.id();
+  ASSERT(cls.id() == kIllegalCid || cls.id() < kNumPredefinedCids);
+  bool did_grow = false;
+  const classid_t cid =
+      cls.id() != kIllegalCid ? cls.id() : classes_.AddRow(&did_grow);
   ASSERT(!IsTopLevelCid(cid));
 
-  // During the transition period we would like [SharedClassTable] to operate in
-  // parallel to [ClassTable].
-
   const intptr_t instance_size =
       cls.is_abstract() ? 0 : Class::host_instance_size(cls.ptr());
 
-  const intptr_t expected_cid =
-      shared_class_table_->Register(cid, instance_size);
+  cls.set_id(cid);
+  classes_.At<kClassIndex>(cid) = cls.ptr();
+  classes_.At<kSizeIndex>(cid) = static_cast<int32_t>(instance_size);
 
-  if (cid != kIllegalCid) {
-    ASSERT(cid > 0 && cid < kNumPredefinedCids && cid < top_);
-    ASSERT(table_.load()[cid] == nullptr);
-    table_.load()[cid] = cls.ptr();
+  if (did_grow) {
+    IsolateGroup::Current()->set_cached_class_table_table(
+        classes_.GetColumn<kClassIndex>());
+    UpdateCachedAllocationTracingStateTablePointer();
   } else {
-    if (top_ == capacity_) {
-      const intptr_t new_capacity = capacity_ + kCapacityIncrement;
-      Grow(new_capacity);
-    }
-    ASSERT(top_ < capacity_);
-    cls.set_id(top_);
-    table_.load()[top_] = cls.ptr();
-    top_++;  // Increment next index.
+    std::atomic_thread_fence(std::memory_order_release);
   }
-  ASSERT(expected_cid == cls.id());
 }
 
 void ClassTable::RegisterTopLevel(const Class& cls) {
-  if (top_ >= std::numeric_limits<classid_t>::max()) {
+  if (top_level_classes_.num_cids() >= std::numeric_limits<classid_t>::max()) {
     FATAL1("Fatal error in ClassTable::RegisterTopLevel: invalid index %" Pd
            "\n",
-           top_);
+           top_level_classes_.num_cids());
   }
 
   ASSERT(Thread::Current()->IsMutatorThread());
+  ASSERT(cls.id() == kIllegalCid);
 
-  const intptr_t index = cls.id();
-  ASSERT(index == kIllegalCid);
-
-  if (tlc_top_ == tlc_capacity_) {
-    const intptr_t new_capacity = tlc_capacity_ + kCapacityIncrement;
-    GrowTopLevel(new_capacity);
-  }
-  ASSERT(tlc_top_ < tlc_capacity_);
-  cls.set_id(ClassTable::CidFromTopLevelIndex(tlc_top_));
-  tlc_table_.load()[tlc_top_] = cls.ptr();
-  tlc_top_++;  // Increment next index.
-}
-
-intptr_t SharedClassTable::Register(intptr_t index, intptr_t size) {
-  if (!Class::is_valid_id(top_)) {
-    FATAL1("Fatal error in SharedClassTable::Register: invalid index %" Pd "\n",
-           top_);
-  }
-
-  ASSERT(Thread::Current()->IsMutatorThread());
-  if (index != kIllegalCid) {
-    // We are registring the size of a predefined class.
-    ASSERT(index > 0 && index < kNumPredefinedCids);
-    SetSizeAt(index, size);
-    return index;
-  } else {
-    ASSERT(size == 0);
-    if (top_ == capacity_) {
-      const intptr_t new_capacity = capacity_ + kCapacityIncrement;
-      Grow(new_capacity);
-    }
-    ASSERT(top_ < capacity_);
-    table_.load()[top_] = size;
-    return top_++;  // Increment next index.
-  }
+  bool did_grow = false;
+  const intptr_t index = top_level_classes_.AddRow(&did_grow);
+  cls.set_id(ClassTable::CidFromTopLevelIndex(index));
+  top_level_classes_.At<kClassIndex>(index) = cls.ptr();
 }
 
 void ClassTable::AllocateIndex(intptr_t index) {
+  bool did_grow = false;
   if (IsTopLevelCid(index)) {
-    AllocateTopLevelIndex(index);
+    top_level_classes_.AllocateIndex(IndexFromTopLevelCid(index), &did_grow);
     return;
   }
 
-  // This is called by a snapshot reader.
-  shared_class_table_->AllocateIndex(index);
-  ASSERT(Class::is_valid_id(index));
-
-  if (index >= capacity_) {
-    const intptr_t new_capacity = index + kCapacityIncrement;
-    Grow(new_capacity);
+  classes_.AllocateIndex(index, &did_grow);
+  if (did_grow) {
+    IsolateGroup::Current()->set_cached_class_table_table(table());
+    UpdateCachedAllocationTracingStateTablePointer();
   }
-
-  ASSERT(table_.load()[index] == nullptr);
-  if (index >= top_) {
-    top_ = index + 1;
-  }
-
-  ASSERT(top_ == shared_class_table_->top_);
-  ASSERT(capacity_ == shared_class_table_->capacity_);
-}
-
-void ClassTable::AllocateTopLevelIndex(intptr_t cid) {
-  ASSERT(IsTopLevelCid(cid));
-  const intptr_t tlc_index = IndexFromTopLevelCid(cid);
-
-  if (tlc_index >= tlc_capacity_) {
-    const intptr_t new_capacity = tlc_index + kCapacityIncrement;
-    GrowTopLevel(new_capacity);
-  }
-
-  ASSERT(tlc_table_.load()[tlc_index] == nullptr);
-  if (tlc_index >= tlc_top_) {
-    tlc_top_ = tlc_index + 1;
-  }
-}
-
-void ClassTable::Grow(intptr_t new_capacity) {
-  ASSERT(new_capacity > capacity_);
-
-  auto old_table = table_.load();
-  auto new_table = static_cast<ClassPtr*>(
-      malloc(new_capacity * sizeof(ClassPtr)));  // NOLINT
-  intptr_t i;
-  for (i = 0; i < capacity_; i++) {
-    // Don't use memmove, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    new_table[i] = old_table[i];
-  }
-  for (; i < new_capacity; i++) {
-    // Don't use memset, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    new_table[i] = 0;
-  }
-  old_class_tables_->Add(old_table);
-  set_table(new_table);
-
-  capacity_ = new_capacity;
-}
-
-void ClassTable::GrowTopLevel(intptr_t new_capacity) {
-  ASSERT(new_capacity > tlc_capacity_);
-
-  auto old_table = tlc_table_.load();
-  auto new_table = static_cast<ClassPtr*>(
-      malloc(new_capacity * sizeof(ClassPtr)));  // NOLINT
-  intptr_t i;
-  for (i = 0; i < tlc_capacity_; i++) {
-    // Don't use memmove, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    new_table[i] = old_table[i];
-  }
-  for (; i < new_capacity; i++) {
-    // Don't use memset, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    new_table[i] = 0;
-  }
-  old_class_tables_->Add(old_table);
-
-  tlc_table_.store(new_table);
-  tlc_capacity_ = new_capacity;
-}
-
-void SharedClassTable::AllocateIndex(intptr_t index) {
-  // This is called by a snapshot reader.
-  ASSERT(Class::is_valid_id(index));
-
-  if (index >= capacity_) {
-    const intptr_t new_capacity = index + kCapacityIncrement;
-    Grow(new_capacity);
-  }
-
-  ASSERT(table_.load()[index] == 0);
-  if (index >= top_) {
-    top_ = index + 1;
-  }
-}
-
-void SharedClassTable::Grow(intptr_t new_capacity) {
-  ASSERT(new_capacity >= capacity_);
-
-  RelaxedAtomic<intptr_t>* old_table = table_.load();
-  RelaxedAtomic<intptr_t>* new_table =
-      reinterpret_cast<RelaxedAtomic<intptr_t>*>(
-          malloc(new_capacity * sizeof(RelaxedAtomic<intptr_t>)));  // NOLINT
-
-  intptr_t i;
-  for (i = 0; i < capacity_; i++) {
-    // Don't use memmove, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    new_table[i] = old_table[i];
-  }
-  for (; i < new_capacity; i++) {
-    // Don't use memset, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    new_table[i] = 0;
-  }
-
-#if !defined(PRODUCT)
-  auto old_trace_table = trace_allocation_table_.load();
-  auto new_trace_table =
-      static_cast<uint8_t*>(malloc(new_capacity * sizeof(uint8_t)));  // NOLINT
-  for (i = 0; i < capacity_; i++) {
-    // Don't use memmove, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    new_trace_table[i] = old_trace_table[i];
-  }
-  for (; i < new_capacity; i++) {
-    // Don't use memset, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    new_trace_table[i] = 0;
-  }
-#endif
-
-  old_tables_->Add(old_table);
-  table_.store(new_table);
-  NOT_IN_PRODUCT(old_tables_->Add(old_trace_table));
-  NOT_IN_PRODUCT(trace_allocation_table_.store(new_trace_table));
-
-#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
-  auto old_unboxed_fields_map = unboxed_fields_map_;
-  auto new_unboxed_fields_map = static_cast<UnboxedFieldBitmap*>(
-      malloc(new_capacity * sizeof(UnboxedFieldBitmap)));
-  for (i = 0; i < capacity_; i++) {
-    // Don't use memmove, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    new_unboxed_fields_map[i] = old_unboxed_fields_map[i];
-  }
-  for (; i < new_capacity; i++) {
-    // Don't use memset, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    new_unboxed_fields_map[i] = UnboxedFieldBitmap(0);
-  }
-  old_tables_->Add(old_unboxed_fields_map);
-  unboxed_fields_map_ = new_unboxed_fields_map;
-#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
-
-  capacity_ = new_capacity;
-}
-
-void ClassTable::Unregister(intptr_t cid) {
-  ASSERT(!IsTopLevelCid(cid));
-  shared_class_table_->Unregister(cid);
-  table_.load()[cid] = nullptr;
 }
 
 void ClassTable::UnregisterTopLevel(intptr_t cid) {
   ASSERT(IsTopLevelCid(cid));
   const intptr_t tlc_index = IndexFromTopLevelCid(cid);
-  tlc_table_.load()[tlc_index] = nullptr;
-}
-
-void SharedClassTable::Unregister(intptr_t index) {
-  table_.load()[index] = 0;
-#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
-  unboxed_fields_map_[index].Reset();
-#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
+  top_level_classes_.At<kClassIndex>(tlc_index) = nullptr;
 }
 
 void ClassTable::Remap(intptr_t* old_to_new_cid) {
   ASSERT(Thread::Current()->IsAtSafepoint(SafepointLevel::kGCAndDeopt));
-  const intptr_t num_cids = NumCids();
-  std::unique_ptr<ClassPtr[]> cls_by_old_cid(new ClassPtr[num_cids]);
-  auto* table = table_.load();
-  memmove(cls_by_old_cid.get(), table, sizeof(ClassPtr) * num_cids);
-  for (intptr_t i = 0; i < num_cids; i++) {
-    table[old_to_new_cid[i]] = cls_by_old_cid[i];
-  }
-}
-
-void SharedClassTable::Remap(intptr_t* old_to_new_cid) {
-  ASSERT(Thread::Current()->IsAtSafepoint(SafepointLevel::kGCAndDeopt));
-  const intptr_t num_cids = NumCids();
-  std::unique_ptr<intptr_t[]> size_by_old_cid(new intptr_t[num_cids]);
-  auto* table = table_.load();
-  for (intptr_t i = 0; i < num_cids; i++) {
-    size_by_old_cid[i] = table[i];
-  }
-  for (intptr_t i = 0; i < num_cids; i++) {
-    table[old_to_new_cid[i]] = size_by_old_cid[i];
-  }
-
-#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
-  std::unique_ptr<UnboxedFieldBitmap[]> unboxed_fields_by_old_cid(
-      new UnboxedFieldBitmap[num_cids]);
-  for (intptr_t i = 0; i < num_cids; i++) {
-    unboxed_fields_by_old_cid[i] = unboxed_fields_map_[i];
-  }
-  for (intptr_t i = 0; i < num_cids; i++) {
-    unboxed_fields_map_[old_to_new_cid[i]] = unboxed_fields_by_old_cid[i];
-  }
-#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
+  classes_.Remap(old_to_new_cid);
 }
 
 void ClassTable::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   ASSERT(visitor != NULL);
   visitor->set_gc_root_type("class table");
-  if (top_ != 0) {
-    auto* table = table_.load();
+
+  const auto visit = [&](ClassPtr* table, intptr_t num_cids) {
+    if (num_cids == 0) {
+      return;
+    }
     ObjectPtr* from = reinterpret_cast<ObjectPtr*>(&table[0]);
-    ObjectPtr* to = reinterpret_cast<ObjectPtr*>(&table[top_ - 1]);
+    ObjectPtr* to = reinterpret_cast<ObjectPtr*>(&table[num_cids - 1]);
     visitor->VisitPointers(from, to);
-  }
-  if (tlc_top_ != 0) {
-    auto* tlc_table = tlc_table_.load();
-    ObjectPtr* from = reinterpret_cast<ObjectPtr*>(&tlc_table[0]);
-    ObjectPtr* to = reinterpret_cast<ObjectPtr*>(&tlc_table[tlc_top_ - 1]);
-    visitor->VisitPointers(from, to);
-  }
+  };
+
+  visit(classes_.GetColumn<kClassIndex>(), classes_.num_cids());
+  visit(top_level_classes_.GetColumn<kClassIndex>(),
+        top_level_classes_.num_cids());
   visitor->clear_gc_root_type();
 }
 
 void ClassTable::CopySizesFromClassObjects() {
   ASSERT(kIllegalCid == 0);
-  for (intptr_t i = 1; i < top_; i++) {
-    SetAt(i, At(i));
+  for (intptr_t i = 1; i < classes_.num_cids(); i++) {
+    UpdateClassSize(i, classes_.At<kClassIndex>(i));
   }
 }
 
+void ClassTable::SetAt(intptr_t cid, ClassPtr raw_cls) {
+  if (IsTopLevelCid(cid)) {
+    top_level_classes_.At<kClassIndex>(IndexFromTopLevelCid(cid)) = raw_cls;
+    return;
+  }
+
+  // This is called by snapshot reader and class finalizer.
+  UpdateClassSize(cid, raw_cls);
+  classes_.At<kClassIndex>(cid) = raw_cls;
+}
+
+void ClassTable::UpdateClassSize(intptr_t cid, ClassPtr raw_cls) {
+  ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
+  ASSERT(!IsTopLevelCid(cid));  // "top-level" classes don't get instantiated
+  const intptr_t size =
+      raw_cls == nullptr ? 0 : Class::host_instance_size(raw_cls);
+  classes_.At<kSizeIndex>(cid) = static_cast<int32_t>(size);
+}
+
 void ClassTable::Validate() {
   Class& cls = Class::Handle();
-  for (intptr_t cid = kNumPredefinedCids; cid < top_; cid++) {
+  for (intptr_t cid = kNumPredefinedCids; cid < classes_.num_cids(); cid++) {
     // Some of the class table entries maybe NULL as we create some
     // top level classes but do not add them to the list of anonymous
     // classes in a library if there are no top level fields or functions.
@@ -501,7 +194,7 @@
   Class& cls = Class::Handle();
   String& name = String::Handle();
 
-  for (intptr_t i = 1; i < top_; i++) {
+  for (intptr_t i = 1; i < classes_.num_cids(); i++) {
     if (!HasValidClassAt(i)) {
       continue;
     }
@@ -513,27 +206,6 @@
   }
 }
 
-void ClassTable::SetAt(intptr_t cid, ClassPtr raw_cls) {
-  if (IsTopLevelCid(cid)) {
-    tlc_table_.load()[IndexFromTopLevelCid(cid)] = raw_cls;
-    return;
-  }
-
-  // This is called by snapshot reader and class finalizer.
-  ASSERT(cid < capacity_);
-  UpdateClassSize(cid, raw_cls);
-  table_.load()[cid] = raw_cls;
-}
-
-void ClassTable::UpdateClassSize(intptr_t cid, ClassPtr raw_cls) {
-  ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
-  ASSERT(!IsTopLevelCid(cid));  // "top-level" classes don't get instantiated
-  ASSERT(cid < capacity_);
-  const intptr_t size =
-      raw_cls == nullptr ? 0 : Class::host_instance_size(raw_cls);
-  shared_class_table_->SetSizeAt(cid, size);
-}
-
 #if defined(DART_PRECOMPILER)
 void ClassTable::PrintObjectLayout(const char* filename) {
   Class& cls = Class::Handle();
@@ -542,7 +214,7 @@
 
   JSONWriter js;
   js.OpenArray();
-  for (intptr_t i = ClassId::kObjectCid; i < top_; i++) {
+  for (intptr_t i = ClassId::kObjectCid; i < classes_.num_cids(); i++) {
     if (!HasValidClassAt(i)) {
       continue;
     }
@@ -604,7 +276,7 @@
   object->AddProperty("type", "ClassList");
   {
     JSONArray members(object, "classes");
-    for (intptr_t i = ClassId::kObjectCid; i < top_; i++) {
+    for (intptr_t i = ClassId::kObjectCid; i < classes_.num_cids(); i++) {
       if (HasValidClassAt(i)) {
         cls = At(i);
         members.AddValue(cls);
@@ -613,11 +285,6 @@
   }
 }
 
-intptr_t SharedClassTable::ClassOffsetFor(intptr_t cid) {
-  return cid * sizeof(uint8_t);  // NOLINT
-}
-
-
 void ClassTable::AllocationProfilePrintJSON(JSONStream* stream, bool internal) {
   Isolate* isolate = Isolate::Current();
   ASSERT(isolate != NULL);
@@ -659,7 +326,7 @@
   {
     JSONArray arr(&obj, "members");
     Class& cls = Class::Handle();
-    for (intptr_t i = 3; i < top_; i++) {
+    for (intptr_t i = 3; i < classes_.num_cids(); i++) {
       if (!HasValidClassAt(i)) continue;
 
       cls = At(i);
@@ -694,4 +361,36 @@
 }
 #endif  // !PRODUCT
 
+ClassTableAllocator::ClassTableAllocator()
+    : pending_freed_(new MallocGrowableArray<std::pair<void*, Deleter>>()) {}
+
+ClassTableAllocator::~ClassTableAllocator() {
+  FreePending();
+  delete pending_freed_;
+}
+
+void ClassTableAllocator::Free(ClassTable* ptr) {
+  if (ptr != nullptr) {
+    pending_freed_->Add(std::make_pair(
+        ptr, [](void* ptr) { delete static_cast<ClassTable*>(ptr); }));
+  }
+}
+
+void ClassTableAllocator::Free(void* ptr) {
+  if (ptr != nullptr) {
+    pending_freed_->Add(std::make_pair(ptr, nullptr));
+  }
+}
+
+void ClassTableAllocator::FreePending() {
+  while (!pending_freed_->is_empty()) {
+    auto [ptr, deleter] = pending_freed_->RemoveLast();
+    if (deleter == nullptr) {
+      free(ptr);
+    } else {
+      deleter(ptr);
+    }
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 1e6ca5f..81f7c90 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -6,6 +6,8 @@
 #define RUNTIME_VM_CLASS_TABLE_H_
 
 #include <memory>
+#include <tuple>
+#include <utility>
 
 #include "platform/allocation.h"
 #include "platform/assert.h"
@@ -24,8 +26,6 @@
 class ClassTable;
 class Isolate;
 class IsolateGroup;
-class IsolateGroupReloadContext;
-class ProgramReloadContext;
 class JSONArray;
 class JSONObject;
 class JSONStream;
@@ -33,8 +33,13 @@
 class MallocGrowableArray;
 class ObjectPointerVisitor;
 
-// Wraps a 64-bit integer to represent the bitmap of unboxed fields
-// stored in the shared class table.
+// A 64-bit bitmap describing unboxed fields in a class.
+//
+// There is a bit for each word in an instance of the class.
+//
+// Words corresponding to set bits must be ignored by the GC because they
+// don't contain pointers. All words beyound the first 64 words of an object
+// are expected to contain pointers.
 class UnboxedFieldBitmap {
  public:
   UnboxedFieldBitmap() : bitmap_(0) {}
@@ -50,6 +55,10 @@
     ASSERT(position < Length());
     bitmap_ |= Utils::Bit<decltype(bitmap_)>(position);
   }
+  DART_FORCE_INLINE void Clear(intptr_t position) {
+    ASSERT(position < Length());
+    bitmap_ &= ~Utils::Bit<decltype(bitmap_)>(position);
+  }
   DART_FORCE_INLINE uint64_t Value() const { return bitmap_; }
   DART_FORCE_INLINE bool IsEmpty() const { return bitmap_ == 0; }
   DART_FORCE_INLINE void Reset() { bitmap_ = 0; }
@@ -62,295 +71,296 @@
   uint64_t bitmap_;
 };
 
-// Registry of all known classes and their sizes.
+// Allocator used to manage memory for ClassTable arrays and ClassTable
+// objects themselves.
 //
-// The GC will only need the information in this shared class table to scan
-// object pointers.
-class SharedClassTable {
+// This allocator provides delayed free functionality: normally class tables
+// can't be freed unless all mutator and helper threads are stopped because
+// some of these threads might be holding a pointer to a table which we
+// want to free. Instead of stopping the world whenever we need to free
+// a table (e.g. freeing old table after growing) we delay freeing until an
+// occasional GC which will need to stop the world anyway.
+class ClassTableAllocator : public ValueObject {
  public:
-  SharedClassTable();
-  ~SharedClassTable();
+  ClassTableAllocator();
+  ~ClassTableAllocator();
 
-  // Thread-safe.
-  intptr_t SizeAt(intptr_t index) const {
-    ASSERT(IsValidIndex(index));
-    return table_.load()[index];
-  }
-
-  bool HasValidClassAt(intptr_t index) const {
-    ASSERT(IsValidIndex(index));
-    ASSERT(table_.load()[index] >= 0);
-    return table_.load()[index] != 0;
-  }
-
-  void SetSizeAt(intptr_t index, intptr_t size) {
-    ASSERT(IsValidIndex(index));
-
-    // Ensure we never change size for a given cid from one non-zero size to
-    // another non-zero size.
-    intptr_t old_size = 0;
-    if (!table_.load()[index].compare_exchange_strong(old_size, size)) {
-      RELEASE_ASSERT(old_size == size);
-    }
-  }
-
-  bool IsValidIndex(intptr_t index) const { return index > 0 && index < top_; }
-
-  intptr_t NumCids() const { return top_; }
-  intptr_t Capacity() const { return capacity_; }
-
-  UnboxedFieldBitmap GetUnboxedFieldsMapAt(intptr_t index) const {
-    ASSERT(IsValidIndex(index));
-    return FLAG_precompiled_mode ? unboxed_fields_map_[index]
-                                 : UnboxedFieldBitmap();
-  }
-
-  void SetUnboxedFieldsMapAt(intptr_t index,
-                             UnboxedFieldBitmap unboxed_fields_map) {
-    ASSERT(IsValidIndex(index));
-    ASSERT(unboxed_fields_map_[index].IsEmpty());
-    unboxed_fields_map_[index] = unboxed_fields_map;
-  }
-
-  // Used to drop recently added classes.
-  void SetNumCids(intptr_t num_cids) {
-    ASSERT(num_cids <= top_);
-    top_ = num_cids;
-  }
-
-#if !defined(PRODUCT)
-  void SetTraceAllocationFor(intptr_t cid, bool trace) {
-    ASSERT(cid > 0);
-    ASSERT(cid < top_);
-    trace_allocation_table_.load()[cid] = trace ? 1 : 0;
-  }
-  bool TraceAllocationFor(intptr_t cid);
-  void SetCollectInstancesFor(intptr_t cid, bool trace) {
-    ASSERT(cid > 0);
-    ASSERT(cid < top_);
-    if (trace) {
-      trace_allocation_table_.load()[cid] |= 2;
-    } else {
-      trace_allocation_table_.load()[cid] &= ~2;
-    }
-  }
-  bool CollectInstancesFor(intptr_t cid) {
-    ASSERT(cid > 0);
-    ASSERT(cid < top_);
-    return (trace_allocation_table_.load()[cid] & 2) != 0;
-  }
-#endif  // !defined(PRODUCT)
-
-  void CopyBeforeHotReload(intptr_t** copy, intptr_t* copy_num_cids) {
-    // The [IsolateGroupReloadContext] will need to maintain a copy of the old
-    // class table until instances have been morphed.
-    const intptr_t num_cids = NumCids();
-    const intptr_t bytes = sizeof(intptr_t) * num_cids;
-    auto size_table = static_cast<intptr_t*>(malloc(bytes));
-    auto table = table_.load();
-    for (intptr_t i = 0; i < num_cids; i++) {
-      // Don't use memmove, which changes this from a relaxed atomic operation
-      // to a non-atomic operation.
-      size_table[i] = table[i];
-    }
-    *copy_num_cids = num_cids;
-    *copy = size_table;
-  }
-
-  void ResetBeforeHotReload() {
-    // The [ProgramReloadContext] is now source-of-truth for GC.
-    auto table = table_.load();
-    for (intptr_t i = 0; i < top_; i++) {
-      // Don't use memset, which changes this from a relaxed atomic operation
-      // to a non-atomic operation.
-      table[i] = 0;
-    }
-  }
-
-  void ResetAfterHotReload(intptr_t* old_table,
-                           intptr_t num_old_cids,
-                           bool is_rollback) {
-    // The [ProgramReloadContext] is no longer source-of-truth for GC after we
-    // return, so we restore size information for all classes.
-    if (is_rollback) {
-      SetNumCids(num_old_cids);
-      auto table = table_.load();
-      for (intptr_t i = 0; i < num_old_cids; i++) {
-        // Don't use memmove, which changes this from a relaxed atomic operation
-        // to a non-atomic operation.
-        table[i] = old_table[i];
-      }
-    }
-
-    // Can't free this table immediately as another thread (e.g., concurrent
-    // marker or sweeper) may be between loading the table pointer and loading
-    // the table element. The table will be freed at the next major GC or
-    // isolate shutdown.
-    AddOldTable(old_table);
-  }
-
-  // Deallocates table copies. Do not call during concurrent access to table.
-  void FreeOldTables();
-
-  // Deallocates bitmap copies. Do not call during concurrent access to table.
-  void FreeOldUnboxedFieldsMaps();
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  bool IsReloading() const { return reload_context_ != nullptr; }
-
-  IsolateGroupReloadContext* reload_context() { return reload_context_; }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
-  // Returns the newly allocated cid.
+  // Allocate an array of T with |len| elements.
   //
-  // [index] is kIllegalCid or a predefined cid.
-  intptr_t Register(intptr_t index, intptr_t size);
-  void AllocateIndex(intptr_t index);
-  void Unregister(intptr_t index);
-
-  void Remap(intptr_t* old_to_new_cids);
-
-  // Used by the generated code.
-#ifndef PRODUCT
-  static intptr_t class_heap_stats_table_offset() {
-    return OFFSET_OF(SharedClassTable, trace_allocation_table_);
+  // Does *not* initialize the memory.
+  template <class T>
+  inline T* Alloc(intptr_t len) {
+    return reinterpret_cast<T*>(dart::malloc(len * sizeof(T)));
   }
-#endif
 
-  // Used by the generated code.
-  static intptr_t ClassOffsetFor(intptr_t cid);
+  // Allocate a zero initialized array of T with |len| elements.
+  template <class T>
+  inline T* AllocZeroInitialized(intptr_t len) {
+    return reinterpret_cast<T*>(dart::calloc(len, sizeof(T)));
+  }
 
-  static const int kInitialCapacity = 512;
-  static const int kCapacityIncrement = 256;
+  // Clone the given |array| with |size| elements.
+  template <class T>
+  inline T* Clone(T* array, intptr_t size) {
+    if (array == nullptr) {
+      ASSERT(size == 0);
+      return nullptr;
+    }
+    auto result = Alloc<T>(size);
+    memmove(result, array, size * sizeof(T));
+    return result;
+  }
+
+  // Copy |size| elements from the given |array| into a new
+  // array with space for |new_size| elements. Then |Free|
+  // the original |array|.
+  //
+  // |new_size| is expected to be larger than |size|.
+  template <class T>
+  inline T* Realloc(T* array, intptr_t size, intptr_t new_size) {
+    ASSERT(size < new_size);
+    auto result = AllocZeroInitialized<T>(new_size);
+    if (size != 0) {
+      ASSERT(result != nullptr);
+      memmove(result, array, size * sizeof(T));
+    }
+    Free(array);
+    return result;
+  }
+
+  // Schedule deletion of the given ClassTable.
+  void Free(ClassTable* table);
+
+  // Schedule freeing of the given pointer.
+  void Free(void* ptr);
+
+  // Free all objects which were scheduled by |Free|. Expected to only be
+  // called on |IsolateGroup| shutdown or when the world is stopped and no
+  // thread can be using a stale class table pointer.
+  void FreePending();
+
+ private:
+  typedef void (*Deleter)(void*);
+  MallocGrowableArray<std::pair<void*, Deleter>>* pending_freed_;
+};
+
+// A table with the given |Columns| indexed by class id.
+//
+// Each column is a continous array of a the given type. All columns have
+// the same number of used elements (|num_cids()|) and the same capacity.
+template <typename... Columns>
+class CidIndexedTable {
+ public:
+  explicit CidIndexedTable(ClassTableAllocator* allocator)
+      : allocator_(allocator) {}
+
+  ~CidIndexedTable() {
+    std::apply([&](auto&... column) { (allocator_->Free(column.load()), ...); },
+               columns_);
+  }
+
+  CidIndexedTable(const CidIndexedTable& other) = delete;
+
+  void SetNumCidsAndCapacity(intptr_t new_num_cids, intptr_t new_capacity) {
+    columns_ = std::apply(
+        [&](auto&... column) {
+          return std::make_tuple(
+              allocator_->Realloc(column.load(), num_cids_, new_capacity)...);
+        },
+        columns_);
+    capacity_ = new_capacity;
+    num_cids_ = new_num_cids;
+  }
+
+  void AllocateIndex(intptr_t index, bool* did_grow) {
+    *did_grow = EnsureCapacity(index);
+    num_cids_ = Utils::Maximum(num_cids_, index + 1);
+  }
+
+  intptr_t AddRow(bool* did_grow) {
+    *did_grow = EnsureCapacity(num_cids_);
+    return num_cids_++;
+  }
+
+  void ShrinkTo(intptr_t new_num_cids) {
+    ASSERT(new_num_cids <= num_cids_);
+    num_cids_ = new_num_cids;
+  }
+
+  bool IsValidIndex(intptr_t index) const {
+    return 0 <= index && index < num_cids_;
+  }
+
+  void CopyFrom(const CidIndexedTable& other) {
+    ASSERT(allocator_ == other.allocator_);
+
+    std::apply([&](auto&... column) { (allocator_->Free(column.load()), ...); },
+               columns_);
+
+    columns_ = std::apply(
+        [&](auto&... column) {
+          return std::make_tuple(
+              allocator_->Clone(column.load(), other.num_cids_)...);
+        },
+        other.columns_);
+    capacity_ = num_cids_ = other.num_cids_;
+  }
+
+  void Remap(intptr_t* old_to_new_cid) {
+    CidIndexedTable clone(allocator_);
+    clone.CopyFrom(*this);
+    RemapAllColumns(clone, old_to_new_cid,
+                    std::index_sequence_for<Columns...>{});
+  }
+
+  template <
+      intptr_t kColumnIndex,
+      typename T = std::tuple_element_t<kColumnIndex, std::tuple<Columns...>>>
+  T* GetColumn() {
+    return std::get<kColumnIndex>(columns_).load();
+  }
+
+  template <
+      intptr_t kColumnIndex,
+      typename T = std::tuple_element_t<kColumnIndex, std::tuple<Columns...>>>
+  const T* GetColumn() const {
+    return std::get<kColumnIndex>(columns_).load();
+  }
+
+  template <
+      intptr_t kColumnIndex,
+      typename T = std::tuple_element_t<kColumnIndex, std::tuple<Columns...>>>
+  T& At(intptr_t index) {
+    ASSERT(IsValidIndex(index));
+    return GetColumn<kColumnIndex>()[index];
+  }
+
+  template <
+      intptr_t kColumnIndex,
+      typename T = std::tuple_element_t<kColumnIndex, std::tuple<Columns...>>>
+  const T& At(intptr_t index) const {
+    ASSERT(IsValidIndex(index));
+    return GetColumn<kColumnIndex>()[index];
+  }
+
+  intptr_t num_cids() const { return num_cids_; }
+  intptr_t capacity() const { return capacity_; }
 
  private:
   friend class ClassTable;
-  friend class GCMarker;
-  friend class MarkingWeakVisitor;
-  friend class Scavenger;
-  friend class ScavengerWeakVisitor;
 
-#ifndef PRODUCT
-  // Copy-on-write is used for trace_allocation_table_, with old copies stored
-  // in old_tables_.
-  AcqRelAtomic<uint8_t*> trace_allocation_table_ = {nullptr};
-#endif  // !PRODUCT
+  // Wrapper around AcqRelAtomic<T*> which makes it assignable and copyable
+  // so that we could put it inside an std::tuple.
+  template <typename T>
+  struct Ptr {
+    Ptr() : ptr(nullptr) {}
+    Ptr(T* ptr) : ptr(ptr) {}  // NOLINT
 
-  void AddOldTable(intptr_t* old_table);
+    Ptr(const Ptr& other) { ptr.store(other.ptr.load()); }
 
-  void Grow(intptr_t new_capacity);
+    Ptr& operator=(const Ptr& other) {
+      ptr.store(other.load());
+      return *this;
+    }
 
-  intptr_t top_;
-  intptr_t capacity_;
+    T* load() const { return ptr.load(); }
 
-  // Copy-on-write is used for table_, with old copies stored in old_tables_.
-  // Maps the cid to the instance size.
-  AcqRelAtomic<RelaxedAtomic<intptr_t>*> table_ = {nullptr};
-  MallocGrowableArray<void*>* old_tables_;
+    AcqRelAtomic<T*> ptr = {nullptr};
+  };
 
-  IsolateGroupReloadContext* reload_context_ = nullptr;
+  bool EnsureCapacity(intptr_t index) {
+    if (index >= capacity_) {
+      SetNumCidsAndCapacity(num_cids_, index + kCapacityIncrement);
+      return true;
+    }
+    return false;
+  }
 
-  // Stores a 64-bit bitmap for each class. There is one bit for each word in an
-  // instance of the class. A 0 bit indicates that the word contains a pointer
-  // the GC has to scan, a 1 indicates that the word is part of e.g. an unboxed
-  // double and does not need to be scanned. (see Class::Calculate...() where
-  // the bitmap is constructed)
-  UnboxedFieldBitmap* unboxed_fields_map_ = nullptr;
+  template <intptr_t kColumnIndex>
+  void RemapColumn(const CidIndexedTable& old, intptr_t* old_to_new_cid) {
+    auto new_column = GetColumn<kColumnIndex>();
+    auto old_column = old.GetColumn<kColumnIndex>();
+    for (intptr_t i = 0; i < num_cids_; i++) {
+      new_column[old_to_new_cid[i]] = old_column[i];
+    }
+  }
 
-  DISALLOW_COPY_AND_ASSIGN(SharedClassTable);
+  template <std::size_t... Is>
+  void RemapAllColumns(const CidIndexedTable& old,
+                       intptr_t* old_to_new_cid,
+                       std::index_sequence<Is...>) {
+    (RemapColumn<Is>(old, old_to_new_cid), ...);
+  }
+
+  static constexpr intptr_t kCapacityIncrement = 256;
+
+  ClassTableAllocator* allocator_;
+  intptr_t num_cids_ = 0;
+  intptr_t capacity_ = 0;
+  std::tuple<Ptr<Columns>...> columns_;
 };
 
-class ClassTable {
+// Registry of all known classes.
+//
+// The GC will only use information about instance size and unboxed field maps
+// to scan instances and will not access class objects themselves. This
+// information is stored in separate columns of the |classes_| table.
+//
+// # Concurrency & atomicity
+//
+// This table is read concurrently without locking (e.g. by GC threads) so
+// there are some invariants that need to be observed when working with it.
+//
+// * When table is updated (e.g. when the table is grown or a new class is
+// registered in a table) there must be a release barrier after the update.
+// Such barrier will ensure that stores which populate the table are not
+// reordered past the store which exposes the new grown table or exposes
+// a new class id;
+// * Old versions of the table can only be freed when the world is stopped:
+// no mutator and no helper threads are running. To avoid freeing a table
+// which some other thread is reading from.
+//
+// Note that torn reads are not a concern (e.g. it is fine to use
+// memmove to copy class table contents) as long as an appropriate
+// barrier is issued before the copy of the table can be observed.
+//
+// # Hot reload
+//
+// Each IsolateGroup contains two ClassTable fields: |class_table| and
+// |heap_walk_class_table|. GC visitors use the second field to get ClassTable
+// instance which they will use for visiting pointers inside instances in
+// the heap. Usually these two fields will be pointing to the same table,
+// except when IsolateGroup is in the middle of reload.
+//
+// When reloading |class_table| will be pointing to a copy of the original
+// table. Kernel loading will be modifying this table, while GC
+// workers can continue using original table still available through
+// |heap_walk_class_table|. If hot reload succeeds, |heap_walk_class_table|
+// will be dropped and |class_table| will become the source of truth. Otherwise,
+// original table will be restored from |heap_walk_class_table|.
+//
+// See IsolateGroup methods CloneClassTableForReload, RestoreOriginalClassTable,
+// DropOriginalClassTable.
+class ClassTable : public MallocAllocated {
  public:
-  explicit ClassTable(SharedClassTable* shared_class_table_);
+  explicit ClassTable(ClassTableAllocator* allocator);
+
   ~ClassTable();
 
-  SharedClassTable* shared_class_table() const { return shared_class_table_; }
+  ClassTable* Clone() const { return new ClassTable(*this); }
 
-  void CopyBeforeHotReload(ClassPtr** copy,
-                           ClassPtr** tlc_copy,
-                           intptr_t* copy_num_cids,
-                           intptr_t* copy_num_tlc_cids) {
-    // The [ProgramReloadContext] will need to maintain a copy of the old class
-    // table until instances have been morphed.
-    const intptr_t num_cids = NumCids();
-    const intptr_t num_tlc_cids = NumTopLevelCids();
-    auto class_table =
-        static_cast<ClassPtr*>(malloc(sizeof(ClassPtr) * num_cids));
-    auto tlc_class_table =
-        static_cast<ClassPtr*>(malloc(sizeof(ClassPtr) * num_tlc_cids));
-
-    // Don't use memmove, which changes this from a relaxed atomic operation
-    // to a non-atomic operation.
-    auto table = table_.load();
-    for (intptr_t i = 0; i < num_cids; i++) {
-      class_table[i] = table[i];
-    }
-    auto tlc_table = tlc_table_.load();
-    for (intptr_t i = 0; i < num_tlc_cids; i++) {
-      tlc_class_table[i] = tlc_table[i];
-    }
-
-    *copy = class_table;
-    *tlc_copy = tlc_class_table;
-    *copy_num_cids = num_cids;
-    *copy_num_tlc_cids = num_tlc_cids;
-  }
-
-  void ResetBeforeHotReload() {
-    // We cannot clear out the class pointers, because a hot-reload
-    // contains only a diff: If e.g. a class included in the hot-reload has a
-    // super class not included in the diff, it will look up in this class table
-    // to find the super class (e.g. `cls.SuperClass` will cause us to come
-    // here).
-  }
-
-  void ResetAfterHotReload(ClassPtr* old_table,
-                           ClassPtr* old_tlc_table,
-                           intptr_t num_old_cids,
-                           intptr_t num_old_tlc_cids,
-                           bool is_rollback) {
-    // The [ProgramReloadContext] is no longer source-of-truth for GC after we
-    // return, so we restore size information for all classes.
-    if (is_rollback) {
-      SetNumCids(num_old_cids, num_old_tlc_cids);
-
-      // Don't use memmove, which changes this from a relaxed atomic operation
-      // to a non-atomic operation.
-      auto table = table_.load();
-      for (intptr_t i = 0; i < num_old_cids; i++) {
-        table[i] = old_table[i];
-      }
-      auto tlc_table = tlc_table_.load();
-      for (intptr_t i = 0; i < num_old_tlc_cids; i++) {
-        tlc_table[i] = old_tlc_table[i];
-      }
-    } else {
-      CopySizesFromClassObjects();
-    }
-
-    // Can't free these tables immediately as another thread (e.g., concurrent
-    // marker or sweeper) may be between loading the table pointer and loading
-    // the table element. The table will be freed at the next major GC or
-    // isolate shutdown.
-    AddOldTable(old_table);
-    AddOldTable(old_tlc_table);
-  }
-
-  // Thread-safe.
   ClassPtr At(intptr_t cid) const {
-    ASSERT(IsValidIndex(cid));
     if (IsTopLevelCid(cid)) {
-      return tlc_table_.load()[IndexFromTopLevelCid(cid)];
+      return top_level_classes_.At<kClassIndex>(IndexFromTopLevelCid(cid));
     }
-    return table_.load()[cid];
+    return classes_.At<kClassIndex>(cid);
   }
 
-  intptr_t SizeAt(intptr_t index) const {
+  int32_t SizeAt(intptr_t index) const {
     if (IsTopLevelCid(index)) {
       return 0;
     }
-    return shared_class_table_->SizeAt(index);
+    return classes_.At<kSizeIndex>(index);
   }
 
   void SetAt(intptr_t index, ClassPtr raw_cls);
@@ -358,27 +368,72 @@
 
   bool IsValidIndex(intptr_t cid) const {
     if (IsTopLevelCid(cid)) {
-      return IndexFromTopLevelCid(cid) < tlc_top_;
+      return top_level_classes_.IsValidIndex(IndexFromTopLevelCid(cid));
     }
-    return shared_class_table_->IsValidIndex(cid);
+    return classes_.IsValidIndex(cid);
   }
 
-  bool HasValidClassAt(intptr_t cid) const {
+  bool HasValidClassAt(intptr_t cid) const { return At(cid) != nullptr; }
+
+  UnboxedFieldBitmap GetUnboxedFieldsMapAt(intptr_t cid) const {
     ASSERT(IsValidIndex(cid));
-    if (IsTopLevelCid(cid)) {
-      return tlc_table_.load()[IndexFromTopLevelCid(cid)] != nullptr;
-    }
-    return table_.load()[cid] != nullptr;
+    return classes_.At<kUnboxedFieldBitmapIndex>(cid);
   }
 
-  intptr_t NumCids() const { return shared_class_table_->NumCids(); }
-  intptr_t NumTopLevelCids() const { return tlc_top_; }
-  intptr_t Capacity() const { return shared_class_table_->Capacity(); }
+  void SetUnboxedFieldsMapAt(intptr_t cid, UnboxedFieldBitmap map) {
+    ASSERT(IsValidIndex(cid));
+    classes_.At<kUnboxedFieldBitmapIndex>(cid) = map;
+  }
+
+#if !defined(PRODUCT)
+  bool ShouldTraceAllocationFor(intptr_t cid) {
+    return !IsTopLevelCid(cid) &&
+           (classes_.At<kAllocationTracingStateIndex>(cid) != kTracingDisabled);
+  }
+
+  void SetTraceAllocationFor(intptr_t cid, bool trace) {
+    classes_.At<kAllocationTracingStateIndex>(cid) =
+        trace ? kTraceAllocationBit : kTracingDisabled;
+  }
+
+  void SetCollectInstancesFor(intptr_t cid, bool trace) {
+    auto& slot = classes_.At<kAllocationTracingStateIndex>(cid);
+    if (trace) {
+      slot |= kCollectInstancesBit;
+    } else {
+      slot &= ~kCollectInstancesBit;
+    }
+  }
+
+  bool CollectInstancesFor(intptr_t cid) {
+    auto& slot = classes_.At<kAllocationTracingStateIndex>(cid);
+    return (slot & kCollectInstancesBit) != 0;
+  }
+
+  void UpdateCachedAllocationTracingStateTablePointer() {
+    cached_allocation_tracing_state_table_.store(
+        classes_.GetColumn<kAllocationTracingStateIndex>());
+  }
+
+#else
+  void UpdateCachedAllocationTracingStateTablePointer() {}
+#endif  // !defined(PRODUCT)
+
+  intptr_t NumCids() const {
+    return classes_.num_cids();
+  }
+  intptr_t Capacity() const {
+    return classes_.capacity();
+  }
+
+  intptr_t NumTopLevelCids() const {
+    return top_level_classes_.num_cids();
+  }
 
   void Register(const Class& cls);
-  void RegisterTopLevel(const Class& cls);
   void AllocateIndex(intptr_t index);
-  void Unregister(intptr_t index);
+
+  void RegisterTopLevel(const Class& cls);
   void UnregisterTopLevel(intptr_t index);
 
   void Remap(intptr_t* old_to_new_cids);
@@ -405,9 +460,11 @@
 
     static constexpr intptr_t kElementSize = sizeof(uint8_t);
   };
-#endif
 
-#ifndef PRODUCT
+  static intptr_t allocation_tracing_state_table_offset() {
+    static_assert(sizeof(cached_allocation_tracing_state_table_) == kWordSize);
+    return OFFSET_OF(ClassTable, cached_allocation_tracing_state_table_);
+  }
 
   void AllocationProfilePrintJSON(JSONStream* stream, bool internal);
 
@@ -429,6 +486,7 @@
   }
 
  private:
+  friend class ClassTableAllocator;
   friend class GCMarker;
   friend class MarkingWeakVisitor;
   friend class Scavenger;
@@ -438,57 +496,63 @@
                                                    const char* name,
                                                    char** error);
   friend class IsolateGroup;  // for table()
-  static const int kInitialCapacity = SharedClassTable::kInitialCapacity;
-  static const int kCapacityIncrement = SharedClassTable::kCapacityIncrement;
+  static const int kInitialCapacity = 512;
 
   static const intptr_t kTopLevelCidOffset = (1 << 16);
 
-  void AddOldTable(ClassPtr* old_table);
+  ClassTable(const ClassTable& original)
+      : allocator_(original.allocator_),
+        classes_(original.allocator_),
+        top_level_classes_(original.allocator_) {
+    classes_.CopyFrom(original.classes_);
+    top_level_classes_.CopyFrom(original.top_level_classes_);
+    UpdateCachedAllocationTracingStateTablePointer();
+  }
+
   void AllocateTopLevelIndex(intptr_t index);
 
-  void Grow(intptr_t index);
-  void GrowTopLevel(intptr_t index);
-
-  ClassPtr* table() { return table_.load(); }
-  void set_table(ClassPtr* table);
+  ClassPtr* table() {
+    return classes_.GetColumn<kClassIndex>();
+  }
 
   // Used to drop recently added classes.
   void SetNumCids(intptr_t num_cids, intptr_t num_tlc_cids) {
-    shared_class_table_->SetNumCids(num_cids);
-
-    ASSERT(num_cids <= top_);
-    top_ = num_cids;
-
-    ASSERT(num_tlc_cids <= tlc_top_);
-    tlc_top_ = num_tlc_cids;
+    classes_.ShrinkTo(num_cids);
+    top_level_classes_.ShrinkTo(num_tlc_cids);
   }
 
-  intptr_t top_;
-  intptr_t capacity_;
+  ClassTableAllocator* allocator_;
 
-  intptr_t tlc_top_;
-  intptr_t tlc_capacity_;
+  // Unfortunately std::tuple used by CidIndexedTable does not have a stable
+  // layout so we can't refer to its elements from generated code.
+  NOT_IN_PRODUCT(AcqRelAtomic<uint8_t*> cached_allocation_tracing_state_table_ =
+                     {nullptr});
 
-  // Copy-on-write is used for table_, with old copies stored in
-  // old_class_tables_.
-  AcqRelAtomic<ClassPtr*> table_;
-  AcqRelAtomic<ClassPtr*> tlc_table_;
-  MallocGrowableArray<ClassPtr*>* old_class_tables_;
-  SharedClassTable* shared_class_table_;
-
-  DISALLOW_COPY_AND_ASSIGN(ClassTable);
-};
+  enum {
+    kClassIndex = 0,
+    kSizeIndex,
+    kUnboxedFieldBitmapIndex,
+#if !defined(PRODUCT)
+    kAllocationTracingStateIndex
+#endif
+  };
 
 #if !defined(PRODUCT)
-DART_FORCE_INLINE bool SharedClassTable::TraceAllocationFor(intptr_t cid) {
-  ASSERT(cid > 0);
-  if (ClassTable::IsTopLevelCid(cid)) {
-    return false;
-  }
-  ASSERT(cid < top_);
-  return trace_allocation_table_.load()[cid] != 0;
-}
-#endif  // !defined(PRODUCT)
+  CidIndexedTable<ClassPtr, uint32_t, UnboxedFieldBitmap, uint8_t> classes_;
+#else
+  CidIndexedTable<ClassPtr, uint32_t, UnboxedFieldBitmap> classes_;
+#endif
+
+#ifndef PRODUCT
+  enum {
+      kTracingDisabled = 0,
+      kTraceAllocationBit = (1 << 0),
+      kCollectInstancesBit = (1 << 1),
+  };
+#endif  // !PRODUCT
+
+  CidIndexedTable<ClassPtr> top_level_classes_;
+};
 
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/aot/dispatch_table_generator.cc b/runtime/vm/compiler/aot/dispatch_table_generator.cc
index 1245c38..6d8694f 100644
--- a/runtime/vm/compiler/aot/dispatch_table_generator.cc
+++ b/runtime/vm/compiler/aot/dispatch_table_generator.cc
@@ -629,7 +629,7 @@
   table_rows_.Sort(PopularitySorter::Compare);
 
   // Try to allocate at optimal offset.
-  const int32_t optimal_offset = DispatchTable::OriginElement();
+  const int32_t optimal_offset = DispatchTable::kOriginElement;
   for (intptr_t i = 0; i < table_rows_.length(); i++) {
     fitter.FitAndAllocate(table_rows_[i], optimal_offset, optimal_offset);
   }
@@ -644,7 +644,7 @@
   table_rows_.Sort(PopularitySizeRatioSorter::Compare);
 
   // Try to allocate at small offsets.
-  const int32_t max_offset = DispatchTable::LargestSmallOffset();
+  const int32_t max_offset = DispatchTable::kLargestSmallOffset;
   for (intptr_t i = 0; i < table_rows_.length(); i++) {
     fitter.FitAndAllocate(table_rows_[i], 0, max_offset);
   }
@@ -658,7 +658,7 @@
   table_rows_.Sort(SizeSorter::Compare);
 
   // Allocate remaining rows at large offsets.
-  const int32_t min_large_offset = DispatchTable::LargestSmallOffset() + 1;
+  const int32_t min_large_offset = DispatchTable::kLargestSmallOffset + 1;
   for (intptr_t i = 0; i < table_rows_.length(); i++) {
     fitter.FitAndAllocate(table_rows_[i], min_large_offset);
   }
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index f243e82..18f9fd9 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -1187,6 +1187,13 @@
     AbstractType& type = AbstractType::Handle(Z);
     type = TypeRef::Cast(abstype).type();
     AddType(type);
+  } else if (abstype.IsRecordType()) {
+    const auto& rec = RecordType::Cast(abstype);
+    AbstractType& type = AbstractType::Handle(Z);
+    for (intptr_t i = 0, n = rec.NumFields(); i < n; ++i) {
+      type = rec.FieldTypeAt(i);
+      AddType(type);
+    }
   }
 }
 
@@ -2392,6 +2399,7 @@
       void VisitObject(ObjectPtr obj) {
         if (obj->GetClassId() == kTypeCid ||
             obj->GetClassId() == kFunctionTypeCid ||
+            obj->GetClassId() == kRecordTypeCid ||
             obj->GetClassId() == kTypeRefCid) {
           type_ ^= obj;
           types_->Add(type_);
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index c061a93..de81be7 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -1056,15 +1056,18 @@
                        Register cid,
                        Register tmp,
                        Label* target) {
-  RangeCheck(assembler, cid, tmp, kTypeCid, kFunctionTypeCid, kIfInRange,
-             target);
+  COMPILE_ASSERT((kFunctionTypeCid == kTypeCid + 1) &&
+                 (kRecordTypeCid == kTypeCid + 2));
+  RangeCheck(assembler, cid, tmp, kTypeCid, kRecordTypeCid, kIfInRange, target);
 }
 
 static void JumpIfNotType(Assembler* assembler,
                           Register cid,
                           Register tmp,
                           Label* target) {
-  RangeCheck(assembler, cid, tmp, kTypeCid, kFunctionTypeCid, kIfNotInRange,
+  COMPILE_ASSERT((kFunctionTypeCid == kTypeCid + 1) &&
+                 (kRecordTypeCid == kTypeCid + 2));
+  RangeCheck(assembler, cid, tmp, kTypeCid, kRecordTypeCid, kIfNotInRange,
              target);
 }
 
@@ -1078,6 +1081,9 @@
   __ CompareImmediate(R1, kClosureCid);
   __ b(normal_ir_body, EQ);  // Instance is a closure.
 
+  __ CompareImmediate(R1, kRecordCid);
+  __ b(normal_ir_body, EQ);  // Instance is a record.
+
   __ CompareImmediate(R1, kNumPredefinedCids);
   __ b(&use_declaration_type, HI);
 
@@ -1137,6 +1143,10 @@
   __ CompareImmediate(cid1, kClosureCid);
   __ b(normal_ir_body, EQ);
 
+  // Check if left hand side is a record. Records are handled in the runtime.
+  __ CompareImmediate(cid1, kRecordCid);
+  __ b(normal_ir_body, EQ);
+
   // Check whether class ids match. If class ids don't match types may still be
   // considered equivalent (e.g. multiple string implementation classes map to a
   // single String type).
@@ -1286,8 +1296,8 @@
 
   // Check nullability.
   __ Bind(&equiv_cids);
-  __ ldrb(R1, FieldAddress(R1, target::Type::nullability_offset()));
-  __ ldrb(R2, FieldAddress(R2, target::Type::nullability_offset()));
+  __ LoadAbstractTypeNullability(R1, R1);
+  __ LoadAbstractTypeNullability(R2, R2);
   __ cmp(R1, Operand(R2));
   __ b(&check_legacy, NE);
   // Fall through to equal case if nullability is strictly equal.
@@ -1314,7 +1324,7 @@
   __ Bind(normal_ir_body);
 }
 
-void AsmIntrinsifier::FunctionType_getHashCode(Assembler* assembler,
+void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
                                                Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
   __ ldr(R0, FieldAddress(R0, target::FunctionType::hash_offset()));
@@ -1323,7 +1333,7 @@
   __ Bind(normal_ir_body);  // Hash not yet computed.
 }
 
-void AsmIntrinsifier::FunctionType_equality(Assembler* assembler,
+void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
                                             Label* normal_ir_body) {
   __ ldm(IA, SP, (1 << R1 | 1 << R2));
   __ cmp(R1, Operand(R2));
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index 33e850c..ab1c62c 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1218,15 +1218,18 @@
                        Register cid,
                        Register tmp,
                        Label* target) {
-  RangeCheck(assembler, cid, tmp, kTypeCid, kFunctionTypeCid, kIfInRange,
-             target);
+  COMPILE_ASSERT((kFunctionTypeCid == kTypeCid + 1) &&
+                 (kRecordTypeCid == kTypeCid + 2));
+  RangeCheck(assembler, cid, tmp, kTypeCid, kRecordTypeCid, kIfInRange, target);
 }
 
 static void JumpIfNotType(Assembler* assembler,
                           Register cid,
                           Register tmp,
                           Label* target) {
-  RangeCheck(assembler, cid, tmp, kTypeCid, kFunctionTypeCid, kIfNotInRange,
+  COMPILE_ASSERT((kFunctionTypeCid == kTypeCid + 1) &&
+                 (kRecordTypeCid == kTypeCid + 2));
+  RangeCheck(assembler, cid, tmp, kTypeCid, kRecordTypeCid, kIfNotInRange,
              target);
 }
 
@@ -1240,6 +1243,9 @@
   __ CompareImmediate(R1, kClosureCid);
   __ b(normal_ir_body, EQ);  // Instance is a closure.
 
+  __ CompareImmediate(R1, kRecordCid);
+  __ b(normal_ir_body, EQ);  // Instance is a record.
+
   __ CompareImmediate(R1, kNumPredefinedCids);
   __ b(&use_declaration_type, HI);
 
@@ -1268,10 +1274,8 @@
 
   __ Bind(&use_declaration_type);
   __ LoadClassById(R2, R1);
-  __ ldr(
-      R3,
-      FieldAddress(R2, target::Class::num_type_arguments_offset(), kTwoBytes),
-      kTwoBytes);
+  __ ldr(R3, FieldAddress(R2, target::Class::num_type_arguments_offset()),
+         kTwoBytes);
   __ cbnz(normal_ir_body, R3);
 
   __ LoadCompressed(R0,
@@ -1302,6 +1306,10 @@
   __ CompareImmediate(cid1, kClosureCid);
   __ b(normal_ir_body, EQ);
 
+  // Check if left hand side is a record. Records are handled in the runtime.
+  __ CompareImmediate(cid1, kRecordCid);
+  __ b(normal_ir_body, EQ);
+
   // Check whether class ids match. If class ids don't match types may still be
   // considered equivalent (e.g. multiple string implementation classes map to a
   // single String type).
@@ -1455,10 +1463,8 @@
 
   // Check nullability.
   __ Bind(&equiv_cids);
-  __ ldr(R1, FieldAddress(R1, target::Type::nullability_offset(), kByte),
-         kUnsignedByte);
-  __ ldr(R2, FieldAddress(R2, target::Type::nullability_offset(), kByte),
-         kUnsignedByte);
+  __ LoadAbstractTypeNullability(R1, R1);
+  __ LoadAbstractTypeNullability(R2, R2);
   __ cmp(R1, Operand(R2));
   __ b(&check_legacy, NE);
   // Fall through to equal case if nullability is strictly equal.
@@ -1485,7 +1491,7 @@
   __ Bind(normal_ir_body);
 }
 
-void AsmIntrinsifier::FunctionType_getHashCode(Assembler* assembler,
+void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
                                                Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
   __ LoadCompressed(R0, FieldAddress(R0, target::FunctionType::hash_offset()));
@@ -1495,7 +1501,7 @@
   __ Bind(normal_ir_body);
 }
 
-void AsmIntrinsifier::FunctionType_equality(Assembler* assembler,
+void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
                                             Label* normal_ir_body) {
   __ ldp(R1, R2, Address(SP, 0 * target::kWordSize, Address::PairOffset));
   __ CompareObjectRegisters(R1, R2);
@@ -1515,12 +1521,11 @@
                                      Label* normal_ir_body) {
   Label not_yet_computed;
   __ ldr(R0, Address(SP, 0 * target::kWordSize));  // Object.
-  __ ldr(R0,
-         FieldAddress(R0,
-                      target::Object::tags_offset() +
-                          target::UntaggedObject::kHashTagPos / kBitsPerByte,
-                      kFourBytes),
-         kUnsignedFourBytes);
+  __ ldr(
+      R0,
+      FieldAddress(R0, target::Object::tags_offset() +
+                           target::UntaggedObject::kHashTagPos / kBitsPerByte),
+      kUnsignedFourBytes);
   __ cbz(&not_yet_computed, R0);
   __ SmiTag(R0);
   __ ret();
@@ -1925,7 +1930,7 @@
   __ AddImmediate(R6, 1);
   __ sub(R2, R2, Operand(1));
   __ cmp(R2, Operand(0));
-  __ str(R1, FieldAddress(R7, target::OneByteString::data_offset(), kByte),
+  __ str(R1, FieldAddress(R7, target::OneByteString::data_offset()),
          kUnsignedByte);
   __ AddImmediate(R7, 1);
   __ b(&loop, GT);
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index bc39517..962fc62 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -1165,11 +1165,15 @@
 }
 
 static void JumpIfType(Assembler* assembler, Register cid, Label* target) {
-  RangeCheck(assembler, cid, kTypeCid, kFunctionTypeCid, kIfInRange, target);
+  COMPILE_ASSERT((kFunctionTypeCid == kTypeCid + 1) &&
+                 (kRecordTypeCid == kTypeCid + 2));
+  RangeCheck(assembler, cid, kTypeCid, kRecordTypeCid, kIfInRange, target);
 }
 
 static void JumpIfNotType(Assembler* assembler, Register cid, Label* target) {
-  RangeCheck(assembler, cid, kTypeCid, kFunctionTypeCid, kIfNotInRange, target);
+  COMPILE_ASSERT((kFunctionTypeCid == kTypeCid + 1) &&
+                 (kRecordTypeCid == kTypeCid + 2));
+  RangeCheck(assembler, cid, kTypeCid, kRecordTypeCid, kIfNotInRange, target);
 }
 
 // Return type quickly for simple types (not parameterized and not signature).
@@ -1182,6 +1186,9 @@
   __ cmpl(EDI, Immediate(kClosureCid));
   __ j(EQUAL, normal_ir_body);  // Instance is a closure.
 
+  __ cmpl(EDI, Immediate(kRecordCid));
+  __ j(EQUAL, normal_ir_body);  // Instance is a record.
+
   __ cmpl(EDI, Immediate(kNumPredefinedCids));
   __ j(ABOVE, &use_declaration_type);
 
@@ -1258,6 +1265,10 @@
   __ cmpl(cid1, Immediate(kClosureCid));
   __ j(EQUAL, normal_ir_body);
 
+  // Check if left hand side is a record. Records are handled in the runtime.
+  __ cmpl(cid1, Immediate(kRecordCid));
+  __ j(EQUAL, normal_ir_body);
+
   // Check whether class ids match. If class ids don't match types may still be
   // considered equivalent (e.g. multiple string implementation classes map to a
   // single String type).
@@ -1421,8 +1432,8 @@
 
   // Check nullability.
   __ Bind(&equiv_cids);
-  __ movzxb(EDI, FieldAddress(EDI, target::Type::nullability_offset()));
-  __ movzxb(EBX, FieldAddress(EBX, target::Type::nullability_offset()));
+  __ LoadAbstractTypeNullability(EDI, EDI);
+  __ LoadAbstractTypeNullability(EBX, EBX);
   __ cmpl(EDI, EBX);
   __ j(NOT_EQUAL, &check_legacy, Assembler::kNearJump);
   // Fall through to equal case if nullability is strictly equal.
@@ -1449,7 +1460,7 @@
   __ Bind(normal_ir_body);
 }
 
-void AsmIntrinsifier::FunctionType_getHashCode(Assembler* assembler,
+void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
                                                Label* normal_ir_body) {
   __ movl(EAX, Address(ESP, +1 * target::kWordSize));  // FunctionType object.
   __ movl(EAX, FieldAddress(EAX, target::FunctionType::hash_offset()));
@@ -1460,7 +1471,7 @@
   // Hash not yet computed.
 }
 
-void AsmIntrinsifier::FunctionType_equality(Assembler* assembler,
+void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
                                             Label* normal_ir_body) {
   __ movl(EDI, Address(ESP, +1 * target::kWordSize));
   __ movl(EBX, Address(ESP, +2 * target::kWordSize));
diff --git a/runtime/vm/compiler/asm_intrinsifier_riscv.cc b/runtime/vm/compiler/asm_intrinsifier_riscv.cc
index e6bdde0..a7a4a7c 100644
--- a/runtime/vm/compiler/asm_intrinsifier_riscv.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_riscv.cc
@@ -1237,15 +1237,18 @@
                        Register cid,
                        Register tmp,
                        Label* target) {
-  RangeCheck(assembler, cid, tmp, kTypeCid, kFunctionTypeCid, kIfInRange,
-             target);
+  COMPILE_ASSERT((kFunctionTypeCid == kTypeCid + 1) &&
+                 (kRecordTypeCid == kTypeCid + 2));
+  RangeCheck(assembler, cid, tmp, kTypeCid, kRecordTypeCid, kIfInRange, target);
 }
 
 static void JumpIfNotType(Assembler* assembler,
                           Register cid,
                           Register tmp,
                           Label* target) {
-  RangeCheck(assembler, cid, tmp, kTypeCid, kFunctionTypeCid, kIfNotInRange,
+  COMPILE_ASSERT((kFunctionTypeCid == kTypeCid + 1) &&
+                 (kRecordTypeCid == kTypeCid + 2));
+  RangeCheck(assembler, cid, tmp, kTypeCid, kRecordTypeCid, kIfNotInRange,
              target);
 }
 
@@ -1259,6 +1262,9 @@
   __ CompareImmediate(A1, kClosureCid);
   __ BranchIf(EQ, normal_ir_body);  // Instance is a closure.
 
+  __ CompareImmediate(A1, kRecordCid);
+  __ BranchIf(EQ, normal_ir_body);  // Instance is a record.
+
   __ CompareImmediate(A1, kNumPredefinedCids);
   __ BranchIf(HI, &use_declaration_type, Assembler::kNearJump);
 
@@ -1317,6 +1323,10 @@
   __ CompareImmediate(cid1, kClosureCid);
   __ BranchIf(EQ, normal_ir_body);
 
+  // Check if left hand side is a record. Records are handled in the runtime.
+  __ CompareImmediate(cid1, kRecordCid);
+  __ BranchIf(EQ, normal_ir_body);
+
   // Check whether class ids match. If class ids don't match types may still be
   // considered equivalent (e.g. multiple string implementation classes map to a
   // single String type).
@@ -1477,8 +1487,8 @@
 
   // Check nullability.
   __ Bind(&equiv_cids);
-  __ lbu(A0, FieldAddress(A0, target::Type::nullability_offset()));
-  __ lbu(A1, FieldAddress(A1, target::Type::nullability_offset()));
+  __ LoadAbstractTypeNullability(A0, A0);
+  __ LoadAbstractTypeNullability(A1, A1);
   __ bne(A0, A1, &check_legacy);
   // Fall through to equal case if nullability is strictly equal.
 
@@ -1504,7 +1514,7 @@
   __ Bind(normal_ir_body);
 }
 
-void AsmIntrinsifier::FunctionType_getHashCode(Assembler* assembler,
+void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
                                                Label* normal_ir_body) {
   __ lx(A0, Address(SP, 0 * target::kWordSize));
   __ LoadCompressed(A0, FieldAddress(A0, target::FunctionType::hash_offset()));
@@ -1514,7 +1524,7 @@
   __ Bind(normal_ir_body);
 }
 
-void AsmIntrinsifier::FunctionType_equality(Assembler* assembler,
+void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
                                             Label* normal_ir_body) {
   __ lx(A0, Address(SP, 1 * target::kWordSize));
   __ lx(A1, Address(SP, 0 * target::kWordSize));
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index ad0d3a8..4e5953a 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -1068,11 +1068,15 @@
 }
 
 static void JumpIfType(Assembler* assembler, Register cid, Label* target) {
-  RangeCheck(assembler, cid, kTypeCid, kFunctionTypeCid, kIfInRange, target);
+  COMPILE_ASSERT((kFunctionTypeCid == kTypeCid + 1) &&
+                 (kRecordTypeCid == kTypeCid + 2));
+  RangeCheck(assembler, cid, kTypeCid, kRecordTypeCid, kIfInRange, target);
 }
 
 static void JumpIfNotType(Assembler* assembler, Register cid, Label* target) {
-  RangeCheck(assembler, cid, kTypeCid, kFunctionTypeCid, kIfNotInRange, target);
+  COMPILE_ASSERT((kFunctionTypeCid == kTypeCid + 1) &&
+                 (kRecordTypeCid == kTypeCid + 2));
+  RangeCheck(assembler, cid, kTypeCid, kRecordTypeCid, kIfNotInRange, target);
 }
 
 // Return type quickly for simple types (not parameterized and not signature).
@@ -1086,6 +1090,9 @@
   __ cmpq(RCX, Immediate(kClosureCid));
   __ j(EQUAL, normal_ir_body);  // Instance is a closure.
 
+  __ cmpq(RCX, Immediate(kRecordCid));
+  __ j(EQUAL, normal_ir_body);  // Instance is a record.
+
   __ cmpl(RCX, Immediate(kNumPredefinedCids));
   __ j(ABOVE, &use_declaration_type);
 
@@ -1163,6 +1170,10 @@
   __ cmpq(cid1, Immediate(kClosureCid));
   __ j(EQUAL, normal_ir_body);
 
+  // Check if left hand side is a record. Records are handled in the runtime.
+  __ cmpq(cid1, Immediate(kRecordCid));
+  __ j(EQUAL, normal_ir_body);
+
   // Check whether class ids match. If class ids don't match types may still be
   // considered equivalent (e.g. multiple string implementation classes map to a
   // single String type).
@@ -1330,8 +1341,8 @@
 
   // Check nullability.
   __ Bind(&equiv_cids);
-  __ movzxb(RCX, FieldAddress(RCX, target::Type::nullability_offset()));
-  __ movzxb(RDX, FieldAddress(RDX, target::Type::nullability_offset()));
+  __ LoadAbstractTypeNullability(RCX, RCX);
+  __ LoadAbstractTypeNullability(RDX, RDX);
   __ cmpq(RCX, RDX);
   __ j(NOT_EQUAL, &check_legacy, Assembler::kNearJump);
   // Fall through to equal case if nullability is strictly equal.
@@ -1358,7 +1369,7 @@
   __ Bind(normal_ir_body);
 }
 
-void AsmIntrinsifier::FunctionType_getHashCode(Assembler* assembler,
+void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
                                                Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // FunctionType object.
   __ LoadCompressed(RAX,
@@ -1372,7 +1383,7 @@
   // Hash not yet computed.
 }
 
-void AsmIntrinsifier::FunctionType_equality(Assembler* assembler,
+void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
                                             Label* normal_ir_body) {
   __ movq(RCX, Address(RSP, +1 * target::kWordSize));
   __ movq(RDX, Address(RSP, +2 * target::kWordSize));
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 2839cd8..0ee1ab7 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -1942,7 +1942,7 @@
   }
 }
 
-void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
+void Assembler::StoreIntoObjectOffsetNoBarrier(Register object,
                                                int32_t offset,
                                                Register value,
                                                MemoryOrder memory_order) {
@@ -1960,7 +1960,7 @@
   }
 }
 
-void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
+void Assembler::StoreIntoObjectOffsetNoBarrier(Register object,
                                                int32_t offset,
                                                const Object& value,
                                                MemoryOrder memory_order) {
@@ -2311,6 +2311,7 @@
   switch (cid) {
     case kArrayCid:
     case kImmutableArrayCid:
+    case kRecordCid:
     case kTypeArgumentsCid:
       return kFourBytes;
     case kOneByteStringCid:
@@ -3035,77 +3036,6 @@
   vstmd(IA, IP, first, count);
 }
 
-void Assembler::CopyDoubleField(Register dst,
-                                Register src,
-                                Register tmp1,
-                                Register tmp2,
-                                DRegister dtmp) {
-    LoadDFromOffset(dtmp, src, target::Double::value_offset() - kHeapObjectTag);
-    StoreDToOffset(dtmp, dst, target::Double::value_offset() - kHeapObjectTag);
-}
-
-void Assembler::CopyFloat32x4Field(Register dst,
-                                   Register src,
-                                   Register tmp1,
-                                   Register tmp2,
-                                   DRegister dtmp) {
-  if (TargetCPUFeatures::neon_supported()) {
-    LoadMultipleDFromOffset(dtmp, 2, src,
-                            target::Float32x4::value_offset() - kHeapObjectTag);
-    StoreMultipleDToOffset(dtmp, 2, dst,
-                           target::Float32x4::value_offset() - kHeapObjectTag);
-  } else {
-    LoadFieldFromOffset(
-        tmp1, src, target::Float32x4::value_offset() + 0 * target::kWordSize);
-    LoadFieldFromOffset(
-        tmp2, src, target::Float32x4::value_offset() + 1 * target::kWordSize);
-    StoreFieldToOffset(
-        tmp1, dst, target::Float32x4::value_offset() + 0 * target::kWordSize);
-    StoreFieldToOffset(
-        tmp2, dst, target::Float32x4::value_offset() + 1 * target::kWordSize);
-
-    LoadFieldFromOffset(
-        tmp1, src, target::Float32x4::value_offset() + 2 * target::kWordSize);
-    LoadFieldFromOffset(
-        tmp2, src, target::Float32x4::value_offset() + 3 * target::kWordSize);
-    StoreFieldToOffset(
-        tmp1, dst, target::Float32x4::value_offset() + 2 * target::kWordSize);
-    StoreFieldToOffset(
-        tmp2, dst, target::Float32x4::value_offset() + 3 * target::kWordSize);
-  }
-}
-
-void Assembler::CopyFloat64x2Field(Register dst,
-                                   Register src,
-                                   Register tmp1,
-                                   Register tmp2,
-                                   DRegister dtmp) {
-  if (TargetCPUFeatures::neon_supported()) {
-    LoadMultipleDFromOffset(dtmp, 2, src,
-                            target::Float64x2::value_offset() - kHeapObjectTag);
-    StoreMultipleDToOffset(dtmp, 2, dst,
-                           target::Float64x2::value_offset() - kHeapObjectTag);
-  } else {
-    LoadFieldFromOffset(
-        tmp1, src, target::Float64x2::value_offset() + 0 * target::kWordSize);
-    LoadFieldFromOffset(
-        tmp2, src, target::Float64x2::value_offset() + 1 * target::kWordSize);
-    StoreFieldToOffset(
-        tmp1, dst, target::Float64x2::value_offset() + 0 * target::kWordSize);
-    StoreFieldToOffset(
-        tmp2, dst, target::Float64x2::value_offset() + 1 * target::kWordSize);
-
-    LoadFieldFromOffset(
-        tmp1, src, target::Float64x2::value_offset() + 2 * target::kWordSize);
-    LoadFieldFromOffset(
-        tmp2, src, target::Float64x2::value_offset() + 3 * target::kWordSize);
-    StoreFieldToOffset(
-        tmp1, dst, target::Float64x2::value_offset() + 2 * target::kWordSize);
-    StoreFieldToOffset(
-        tmp2, dst, target::Float64x2::value_offset() + 3 * target::kWordSize);
-  }
-}
-
 void Assembler::AddImmediate(Register rd,
                              Register rn,
                              int32_t value,
@@ -3592,25 +3522,22 @@
                                      Label* trace,
                                      Register temp_reg,
                                      JumpDistance distance) {
-  LoadAllocationStatsAddress(temp_reg, cid);
+  LoadAllocationTracingStateAddress(temp_reg, cid);
   MaybeTraceAllocation(temp_reg, trace);
 }
 
-void Assembler::LoadAllocationStatsAddress(Register dest, intptr_t cid) {
+void Assembler::LoadAllocationTracingStateAddress(Register dest, intptr_t cid) {
   ASSERT(dest != kNoRegister);
   ASSERT(dest != TMP);
   ASSERT(cid > 0);
 
-  const intptr_t shared_table_offset =
-      target::IsolateGroup::shared_class_table_offset();
-  const intptr_t table_offset =
-      target::SharedClassTable::class_heap_stats_table_offset();
-  const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
-
   LoadIsolateGroup(dest);
-  ldr(dest, Address(dest, shared_table_offset));
-  ldr(dest, Address(dest, table_offset));
-  AddImmediate(dest, class_offset);
+  ldr(dest, Address(dest, target::IsolateGroup::class_table_offset()));
+  ldr(dest,
+      Address(dest,
+              target::ClassTable::allocation_tracing_state_table_offset()));
+  AddImmediate(dest,
+               target::ClassTable::AllocationTracingStateSlotOffsetFor(cid));
 }
 #endif  // !PRODUCT
 
@@ -3631,7 +3558,7 @@
                           target::ObjectAlignment::kObjectAlignment));
   if (FLAG_inline_alloc &&
       target::Heap::IsAllocatableInNewSpace(instance_size)) {
-    NOT_IN_PRODUCT(LoadAllocationStatsAddress(temp_reg, cid));
+    NOT_IN_PRODUCT(LoadAllocationTracingStateAddress(temp_reg, cid));
     ldr(instance_reg, Address(THR, target::Thread::top_offset()));
     // TODO(koda): Protect against unsigned overflow here.
     AddImmediate(instance_reg, instance_size);
@@ -3669,7 +3596,7 @@
                                  Register temp2) {
   if (FLAG_inline_alloc &&
       target::Heap::IsAllocatableInNewSpace(instance_size)) {
-    NOT_IN_PRODUCT(LoadAllocationStatsAddress(temp1, cid));
+    NOT_IN_PRODUCT(LoadAllocationTracingStateAddress(temp1, cid));
     // Potential new object start.
     ldr(instance, Address(THR, target::Thread::top_offset()));
     AddImmediateSetFlags(end_address, instance, instance_size);
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 9ccd092..326f47c 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -392,6 +392,8 @@
     }
   }
 
+  void PushValueAtOffset(Register base, int32_t offset) { UNIMPLEMENTED(); }
+
   void Bind(Label* label);
   // Unconditional jump to a given label. [distance] is ignored on ARM.
   void Jump(Label* label, JumpDistance distance = kFarJump) { b(label); }
@@ -439,17 +441,17 @@
     cmp(value, Operand(TMP));
   }
 
-  void CompareFunctionTypeNullabilityWith(Register type,
-                                          int8_t value) override {
-    EnsureHasClassIdInDEBUG(kFunctionTypeCid, type, TMP);
-    ldrb(TMP, FieldAddress(
-                  type, compiler::target::FunctionType::nullability_offset()));
-    cmp(TMP, Operand(value));
+  void LoadAbstractTypeNullability(Register dst, Register type) override {
+    ldrb(dst,
+         FieldAddress(type, compiler::target::AbstractType::flags_offset()));
+    and_(dst, dst,
+         Operand(compiler::target::UntaggedAbstractType::kNullabilityMask));
   }
-  void CompareTypeNullabilityWith(Register type, int8_t value) override {
-    EnsureHasClassIdInDEBUG(kTypeCid, type, TMP);
-    ldrb(TMP, FieldAddress(type, compiler::target::Type::nullability_offset()));
-    cmp(TMP, Operand(value));
+  void CompareAbstractTypeNullabilityWith(Register type,
+                                          /*Nullability*/ int8_t value,
+                                          Register scratch) override {
+    LoadAbstractTypeNullability(scratch, type);
+    cmp(scratch, Operand(value));
   }
 
   // Misc. functionality
@@ -834,6 +836,13 @@
   void AddRegisters(Register dest, Register src) {
     add(dest, dest, Operand(src));
   }
+  void AddScaled(Register dest,
+                 Register src,
+                 ScaleFactor scale,
+                 int32_t value) {
+    LoadImmediate(dest, value);
+    add(dest, dest, Operand(src, LSL, scale));
+  }
   void SubImmediate(Register rd,
                     Register rn,
                     int32_t value,
@@ -860,6 +869,13 @@
   void LslImmediate(Register rd, int32_t shift) {
     LslImmediate(rd, rd, shift);
   }
+  void LsrImmediate(Register rd, Register rn, int32_t shift) {
+    ASSERT((shift >= 0) && (shift < kBitsPerInt32));
+    Lsr(rd, rn, Operand(shift));
+  }
+  void LsrImmediate(Register rd, int32_t shift) override {
+    LsrImmediate(rd, rd, shift);
+  }
 
   // Test rn and immediate. May clobber IP.
   void TestImmediate(Register rn, int32_t imm, Condition cond = AL);
@@ -951,12 +967,12 @@
                                 const Address& dest,
                                 const Object& value,
                                 MemoryOrder memory_order = kRelaxedNonAtomic);
-  void StoreIntoObjectNoBarrierOffset(
+  void StoreIntoObjectOffsetNoBarrier(
       Register object,
       int32_t offset,
       Register value,
       MemoryOrder memory_order = kRelaxedNonAtomic);
-  void StoreIntoObjectNoBarrierOffset(
+  void StoreIntoObjectOffsetNoBarrier(
       Register object,
       int32_t offset,
       const Object& value,
@@ -1127,21 +1143,17 @@
                               Register base,
                               int32_t offset);
 
-  void CopyDoubleField(Register dst,
-                       Register src,
-                       Register tmp1,
-                       Register tmp2,
-                       DRegister dtmp);
-  void CopyFloat32x4Field(Register dst,
-                          Register src,
-                          Register tmp1,
-                          Register tmp2,
-                          DRegister dtmp);
-  void CopyFloat64x2Field(Register dst,
-                          Register src,
-                          Register tmp1,
-                          Register tmp2,
-                          DRegister dtmp);
+  void LoadUnboxedSimd128(FpuRegister dst, Register base, int32_t offset) {
+    LoadMultipleDFromOffset(EvenDRegisterOf(dst), 2, base, offset);
+  }
+  void StoreUnboxedSimd128(FpuRegister src, Register base, int32_t offset) {
+    StoreMultipleDToOffset(EvenDRegisterOf(src), 2, base, offset);
+  }
+  void MoveUnboxedSimd128(FpuRegister dst, FpuRegister src) {
+    if (src != dst) {
+      vmovq(dst, src);
+    }
+  }
 
   void Push(Register rd, Condition cond = AL);
   void Pop(Register rd, Condition cond = AL);
@@ -1359,12 +1371,12 @@
   void MonomorphicCheckedEntryAOT();
   void BranchOnMonomorphicCheckedEntryJIT(Label* label);
 
-  // The register into which the allocation stats table is loaded with
-  // LoadAllocationStatsAddress should be passed to MaybeTraceAllocation and
-  // IncrementAllocationStats(WithSize) as stats_addr_reg to update the
-  // allocation stats. These are separate assembler macros so we can
-  // avoid a dependent load too nearby the load of the table address.
-  void LoadAllocationStatsAddress(Register dest, intptr_t cid);
+  // The register into which the allocation tracing state table is loaded with
+  // LoadAllocationTracingStateAddress should be passed to MaybeTraceAllocation.
+  //
+  // These are separate assembler macros so we can avoid a dependent load too
+  // nearby the load of the table address.
+  void LoadAllocationTracingStateAddress(Register dest, intptr_t cid);
 
   Address ElementAddressForIntIndex(bool is_load,
                                     bool is_external,
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index a0495a0..759e524 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -860,7 +860,7 @@
                                       int32_t offset,
                                       OperandSize sz) {
   if (Address::CanHoldOffset(offset, Address::Offset, sz)) {
-    return Address(base, offset, Address::Offset, sz);
+    return Address(base, offset);
   }
   ASSERT(base != TMP2);
   Operand op;
@@ -870,7 +870,7 @@
       (Operand::CanHold(upper20, kXRegSizeInBits, &op) == Operand::Immediate) &&
       Address::CanHoldOffset(lower12, Address::Offset, sz)) {
     add(TMP2, base, op);
-    return Address(TMP2, lower12, Address::Offset, sz);
+    return Address(TMP2, lower12);
   }
   LoadImmediate(TMP2, offset);
   return Address(base, TMP2);
@@ -1103,10 +1103,8 @@
   if (can_be_smi == kValueCanBeSmi) {
     BranchIfSmi(value, &done);
   }
-  ldr(TMP, FieldAddress(object, target::Object::tags_offset(), kByte),
-      kUnsignedByte);
-  ldr(TMP2, FieldAddress(value, target::Object::tags_offset(), kByte),
-      kUnsignedByte);
+  ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
+  ldr(TMP2, FieldAddress(value, target::Object::tags_offset()), kUnsignedByte);
   and_(TMP, TMP2,
        Operand(TMP, LSR, target::UntaggedObject::kBarrierOverlapShift));
   tst(TMP, Operand(HEAP_BITS, LSR, 32));
@@ -1158,7 +1156,7 @@
                                          Register slot,
                                          Register value,
                                          CanBeSmi can_be_smi) {
-  str(value, Address(slot, 0, Address::Offset, kObjectBytes), kObjectBytes);
+  str(value, Address(slot, 0), kObjectBytes);
   StoreIntoArrayBarrier(object, slot, value, can_be_smi);
 }
 
@@ -1185,10 +1183,8 @@
   if (can_be_smi == kValueCanBeSmi) {
     BranchIfSmi(value, &done);
   }
-  ldr(TMP, FieldAddress(object, target::Object::tags_offset(), kByte),
-      kUnsignedByte);
-  ldr(TMP2, FieldAddress(value, target::Object::tags_offset(), kByte),
-      kUnsignedByte);
+  ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
+  ldr(TMP2, FieldAddress(value, target::Object::tags_offset()), kUnsignedByte);
   and_(TMP, TMP2,
        Operand(TMP, LSR, target::UntaggedObject::kBarrierOverlapShift));
   tst(TMP, Operand(HEAP_BITS, LSR, 32));
@@ -1226,8 +1222,7 @@
   Label done;
   StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
 
-  ldr(TMP, FieldAddress(object, target::Object::tags_offset(), kByte),
-      kUnsignedByte);
+  ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
   tsti(TMP, Immediate(1 << target::UntaggedObject::kOldAndNotRememberedBit));
   b(&done, ZERO);
 
@@ -1253,8 +1248,7 @@
   Label done;
   StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
 
-  ldr(TMP, FieldAddress(object, target::Object::tags_offset(), kByte),
-      kUnsignedByte);
+  ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
   tsti(TMP, Immediate(1 << target::UntaggedObject::kOldAndNotRememberedBit));
   b(&done, ZERO);
 
@@ -1296,10 +1290,11 @@
 
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
-                                         const Object& value) {
+                                         const Object& value,
+                                         MemoryOrder memory_order) {
+  RELEASE_ASSERT(memory_order == kRelaxedNonAtomic);
   ASSERT(IsOriginalObject(value));
   ASSERT(IsNotTemporaryScopedHandle(value));
-  // No store buffer update.
   if (IsSameObject(compiler::NullObject(), value)) {
     str(NULL_REG, dest);
   } else if (target::IsSmi(value) && (target::ToRawSmi(value) == 0)) {
@@ -1315,7 +1310,7 @@
                                                    const Object& value,
                                                    MemoryOrder memory_order) {
   // stlr does not feature an address operand.
-  ASSERT(memory_order == kRelaxedNonAtomic);
+  RELEASE_ASSERT(memory_order == kRelaxedNonAtomic);
   ASSERT(IsOriginalObject(value));
   ASSERT(IsNotTemporaryScopedHandle(value));
   // No store buffer update.
@@ -1904,13 +1899,13 @@
   const intptr_t count_offset = target::Array::element_offset(1);
 
   // Sadly this cannot use ldp because ldp requires aligned offsets.
-  ldr(R1, FieldAddress(R5, cid_offset, kObjectBytes), kObjectBytes);
-  ldr(R2, FieldAddress(R5, count_offset, kObjectBytes), kObjectBytes);
+  ldr(R1, FieldAddress(R5, cid_offset), kObjectBytes);
+  ldr(R2, FieldAddress(R5, count_offset), kObjectBytes);
   LoadClassIdMayBeSmi(IP0, R0);
   add(R2, R2, Operand(target::ToRawSmi(1)), kObjectBytes);
   cmp(R1, Operand(IP0, LSL, 1), kObjectBytes);
   b(&miss, NE);
-  str(R2, FieldAddress(R5, count_offset, kObjectBytes), kObjectBytes);
+  str(R2, FieldAddress(R5, count_offset), kObjectBytes);
   LoadImmediate(R4, 0);  // GC-safe for OptimizeInvokedFunction
 
   // Fall through to unchecked entry.
@@ -1966,17 +1961,14 @@
                                      JumpDistance distance) {
   ASSERT(cid > 0);
 
-  const intptr_t shared_table_offset =
-      target::IsolateGroup::shared_class_table_offset();
-  const intptr_t table_offset =
-      target::SharedClassTable::class_heap_stats_table_offset();
-  const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
-
   LoadIsolateGroup(temp_reg);
-  ldr(temp_reg, Address(temp_reg, shared_table_offset));
-  ldr(temp_reg, Address(temp_reg, table_offset));
-  AddImmediate(temp_reg, class_offset);
-  ldr(temp_reg, Address(temp_reg, 0), kUnsignedByte);
+  ldr(temp_reg, Address(temp_reg, target::IsolateGroup::class_table_offset()));
+  ldr(temp_reg,
+      Address(temp_reg,
+              target::ClassTable::allocation_tracing_state_table_offset()));
+  LoadFromOffset(temp_reg, temp_reg,
+                 target::ClassTable::AllocationTracingStateSlotOffsetFor(cid),
+                 kUnsignedByte);
   cbnz(trace, temp_reg);
 }
 #endif  // !PRODUCT
@@ -2110,7 +2102,7 @@
   ASSERT(Utils::IsInt(32, offset));
   const OperandSize size = Address::OperandSizeFor(cid);
   ASSERT(Address::CanHoldOffset(offset, Address::Offset, size));
-  return Address(array, static_cast<int32_t>(offset), Address::Offset, size);
+  return Address(array, static_cast<int32_t>(offset));
 }
 
 void Assembler::ComputeElementAddressForIntIndex(Register address,
@@ -2176,7 +2168,7 @@
     }
   }
   ASSERT(Address::CanHoldOffset(offset, Address::Offset, size));
-  return Address(temp, offset, Address::Offset, size);
+  return Address(temp, offset);
 }
 
 void Assembler::ComputeElementAddressForRegIndex(Register address,
@@ -2385,7 +2377,7 @@
 
 void Assembler::PopNativeCalleeSavedRegisters() {
   // Restore the bottom 64-bits of callee-saved V registers.
-  bool pop_single = (kAbiPreservedFpuRegCount & 1) == 1;
+  bool pop_single = (kAbiPreservedFpuRegCount & 1) != 0;
   VRegister vprev = kNoVRegister;
   for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) {
     const VRegister r = static_cast<VRegister>(i);
@@ -2405,7 +2397,7 @@
   // register when it is not holding a pool-pointer since we are returning to
   // C++ code. We also skip the dart stack pointer SP, since we are still
   // using it as the stack pointer.
-  pop_single = (kAbiPreservedCpuRegCount & 1) == 1;
+  pop_single = (kAbiPreservedCpuRegCount & 1) != 0;
   Register prev = kNoRegister;
   for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) {
     Register r = static_cast<Register>(i);
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index ea47f52..494e066 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -136,16 +136,14 @@
  public:
   Address(const Address& other)
       : ValueObject(),
-        encoding_(other.encoding_),
         type_(other.type_),
         base_(other.base_),
-        log2sz_(other.log2sz_) {}
+        offset_(other.offset_) {}
 
   Address& operator=(const Address& other) {
-    encoding_ = other.encoding_;
     type_ = other.type_;
     base_ = other.base_;
-    log2sz_ = other.log2sz_;
+    offset_ = other.offset_;
     return *this;
   }
 
@@ -167,74 +165,21 @@
   bool can_writeback_to(Register r) const {
     if (type() == PreIndex || type() == PostIndex || type() == PairPreIndex ||
         type() == PairPostIndex) {
-      return base() != r;
+      return ConcreteRegister(base()) != ConcreteRegister(r);
     }
     return true;
   }
 
-  // Offset is in bytes. For the unsigned imm12 case, we unscale based on the
-  // operand size, and assert that offset is aligned accordingly.
-  // For the smaller signed imm9 case, the offset is the number of bytes, but
-  // is unscaled.
-  Address(Register rn,
-          int32_t offset = 0,
-          AddressType at = Offset,
-          OperandSize sz = kEightBytes) {
+  // Offset is in bytes.
+  explicit Address(Register rn, int32_t offset = 0, AddressType at = Offset) {
     ASSERT((rn != kNoRegister) && (rn != R31) && (rn != ZR));
-    ASSERT(CanHoldOffset(offset, at, sz));
-    log2sz_ = -1;
-    const int32_t scale = Log2OperandSizeBytes(sz);
-    if ((at == Offset) && Utils::IsUint(12 + scale, offset) &&
-        (offset == ((offset >> scale) << scale))) {
-      encoding_ =
-          B24 | ((offset >> scale) << kImm12Shift) | Arm64Encode::Rn(rn);
-      if (offset != 0) {
-        log2sz_ = scale;
-      }
-    } else if ((at == Offset) && Utils::IsInt(9, offset)) {
-      encoding_ = ((offset & 0x1ff) << kImm9Shift) | Arm64Encode::Rn(rn);
-    } else if ((at == PreIndex) || (at == PostIndex)) {
-      ASSERT(Utils::IsInt(9, offset));
-      int32_t idx = (at == PostIndex) ? B10 : (B11 | B10);
-      encoding_ = idx | ((offset & 0x1ff) << kImm9Shift) | Arm64Encode::Rn(rn);
-    } else {
-      ASSERT((at == PairOffset) || (at == PairPreIndex) ||
-             (at == PairPostIndex));
-      ASSERT(Utils::IsInt(7 + scale, offset) &&
-             (static_cast<uint32_t>(offset) ==
-              ((static_cast<uint32_t>(offset) >> scale) << scale)));
-      int32_t idx = 0;
-      switch (at) {
-        case PairPostIndex:
-          idx = B23;
-          break;
-        case PairPreIndex:
-          idx = B24 | B23;
-          break;
-        case PairOffset:
-          idx = B24;
-          break;
-        default:
-          UNREACHABLE();
-          break;
-      }
-      encoding_ =
-          idx |
-          ((static_cast<uint32_t>(offset >> scale) << kImm7Shift) & kImm7Mask) |
-          Arm64Encode::Rn(rn);
-      if (offset != 0) {
-        log2sz_ = scale;
-      }
-    }
     type_ = at;
-    base_ = ConcreteRegister(rn);
+    base_ = rn;
+    offset_ = offset;
   }
 
   // This addressing mode does not exist.
-  Address(Register rn,
-          Register offset,
-          AddressType at,
-          OperandSize sz = kEightBytes);
+  Address(Register rn, Register offset, AddressType at) = delete;
 
   static bool CanHoldOffset(int32_t offset,
                             AddressType at = Offset,
@@ -264,22 +209,20 @@
   static Address PC(int32_t pc_off) {
     ASSERT(CanHoldOffset(pc_off, PCOffset));
     Address addr;
-    addr.encoding_ = (((pc_off >> 2) << kImm19Shift) & kImm19Mask);
     addr.base_ = kNoRegister;
     addr.type_ = PCOffset;
-    addr.log2sz_ = -1;
+    addr.offset_ = pc_off;
     return addr;
   }
 
   static Address Pair(Register rn,
                       int32_t offset = 0,
-                      AddressType at = PairOffset,
-                      OperandSize sz = kEightBytes) {
-    return Address(rn, offset, at, sz);
+                      AddressType at = PairOffset) {
+    return Address(rn, offset, at);
   }
 
   // This addressing mode does not exist.
-  static Address PC(Register r);
+  static Address PC(Register r) = delete;
 
   enum Scaling {
     Unscaled,
@@ -298,18 +241,18 @@
     // Can only scale when ext = UXTX.
     ASSERT((scale != Scaled) || (ext == UXTX));
     ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX));
-    const int32_t s = (scale == Scaled) ? B12 : 0;
-    encoding_ = B21 | B11 | s | Arm64Encode::Rn(rn) | Arm64Encode::Rm(rm) |
-                (static_cast<int32_t>(ext) << kExtendTypeShift);
     type_ = Reg;
-    base_ = ConcreteRegister(rn);
-    log2sz_ = -1;  // Any.
+    base_ = rn;
+    // Use offset_ to store pre-encoded scale, extend and rm.
+    offset_ = ((scale == Scaled) ? B12 : 0) | Arm64Encode::Rm(rm) |
+              (static_cast<int32_t>(ext) << kExtendTypeShift);
   }
 
   static OperandSize OperandSizeFor(intptr_t cid) {
     switch (cid) {
       case kArrayCid:
       case kImmutableArrayCid:
+      case kRecordCid:
       case kTypeArgumentsCid:
         return kObjectBytes;
       case kOneByteStringCid:
@@ -354,16 +297,72 @@
   }
 
  private:
-  uint32_t encoding() const { return encoding_; }
+  uint32_t encoding(OperandSize sz) const {
+    const int32_t offset = offset_;
+    const int32_t scale = Log2OperandSizeBytes(sz);
+    ASSERT((type_ == Reg) || CanHoldOffset(offset, type_, sz));
+    switch (type_) {
+      case Offset:
+        if (Utils::IsUint(12 + scale, offset) &&
+            (offset == ((offset >> scale) << scale))) {
+          return B24 | ((offset >> scale) << kImm12Shift) |
+                 Arm64Encode::Rn(base_);
+        } else if (Utils::IsInt(9, offset)) {
+          return ((offset & 0x1ff) << kImm9Shift) | Arm64Encode::Rn(base_);
+        } else {
+          FATAL("Offset %d is out of range\n", offset);
+        }
+      case PreIndex:
+      case PostIndex: {
+        ASSERT(Utils::IsInt(9, offset));
+        int32_t idx = (type_ == PostIndex) ? B10 : (B11 | B10);
+        return idx | ((offset & 0x1ff) << kImm9Shift) | Arm64Encode::Rn(base_);
+      }
+      case PairOffset:
+      case PairPreIndex:
+      case PairPostIndex: {
+        ASSERT(Utils::IsInt(7 + scale, offset) &&
+               (static_cast<uint32_t>(offset) ==
+                ((static_cast<uint32_t>(offset) >> scale) << scale)));
+        int32_t idx = 0;
+        switch (type_) {
+          case PairPostIndex:
+            idx = B23;
+            break;
+          case PairPreIndex:
+            idx = B24 | B23;
+            break;
+          case PairOffset:
+            idx = B24;
+            break;
+          default:
+            UNREACHABLE();
+            break;
+        }
+        return idx |
+               ((static_cast<uint32_t>(offset >> scale) << kImm7Shift) &
+                kImm7Mask) |
+               Arm64Encode::Rn(base_);
+      }
+      case PCOffset:
+        return (((offset >> 2) << kImm19Shift) & kImm19Mask);
+      case Reg:
+        // Offset contains pre-encoded scale, extend and rm.
+        return B21 | B11 | Arm64Encode::Rn(base_) | offset;
+      case Unknown:
+        UNREACHABLE();
+    }
+    return 0;
+  }
+
   AddressType type() const { return type_; }
   Register base() const { return base_; }
 
-  Address() : encoding_(0), type_(Unknown), base_(kNoRegister) {}
+  Address() : type_(Unknown), base_(kNoRegister), offset_(0) {}
 
-  uint32_t encoding_;
   AddressType type_;
   Register base_;
-  int32_t log2sz_;  // Required log2 of operand size (-1 means any).
+  int32_t offset_;
 
   friend class Assembler;
 };
@@ -376,11 +375,11 @@
     return Address::CanHoldOffset(offset - kHeapObjectTag, at, sz);
   }
 
-  FieldAddress(Register base, int32_t disp, OperandSize sz = kEightBytes)
-      : Address(base, disp - kHeapObjectTag, Offset, sz) {}
+  FieldAddress(Register base, int32_t disp)
+      : Address(base, disp - kHeapObjectTag) {}
 
   // This addressing mode does not exist.
-  FieldAddress(Register base, Register disp, OperandSize sz = kEightBytes);
+  FieldAddress(Register base, Register disp) = delete;
 
   FieldAddress(const FieldAddress& other) : Address(other) {}
 
@@ -518,6 +517,8 @@
   void PushRegister(Register r) { Push(r); }
   void PopRegister(Register r) { Pop(r); }
 
+  void PushValueAtOffset(Register base, int32_t offset) { UNIMPLEMENTED(); }
+
   void PushRegisterPair(Register r0, Register r1) { PushPair(r0, r1); }
   void PopRegisterPair(Register r0, Register r1) { PopPair(r0, r1); }
 
@@ -647,21 +648,17 @@
     cmp(value, Operand(TMP), sz);
   }
 
-  void CompareFunctionTypeNullabilityWith(Register type,
-                                          int8_t value) override {
-    EnsureHasClassIdInDEBUG(kFunctionTypeCid, type, TMP);
-    ldr(TMP,
-        FieldAddress(type, compiler::target::FunctionType::nullability_offset(),
-                     kByte),
+  void LoadAbstractTypeNullability(Register dst, Register type) override {
+    ldr(dst, FieldAddress(type, compiler::target::AbstractType::flags_offset()),
         kUnsignedByte);
-    cmp(TMP, Operand(value));
+    AndImmediate(dst, dst,
+                 compiler::target::UntaggedAbstractType::kNullabilityMask);
   }
-  void CompareTypeNullabilityWith(Register type, int8_t value) override {
-    EnsureHasClassIdInDEBUG(kTypeCid, type, TMP);
-    ldr(TMP,
-        FieldAddress(type, compiler::target::Type::nullability_offset(), kByte),
-        kUnsignedByte);
-    cmp(TMP, Operand(value));
+  void CompareAbstractTypeNullabilityWith(Register type,
+                                          /*Nullability*/ int8_t value,
+                                          Register scratch) override {
+    LoadAbstractTypeNullability(scratch, type);
+    cmp(scratch, Operand(value));
   }
 
   bool use_far_branches() const {
@@ -1415,11 +1412,11 @@
   void fcvtds(VRegister vd, VRegister vn) { EmitFPOneSourceOp(FCVTDS, vd, vn); }
   void fldrq(VRegister vt, Address a) {
     ASSERT(a.type() != Address::PCOffset);
-    EmitLoadStoreReg(FLDRQ, static_cast<Register>(vt), a, kByte);
+    EmitLoadStoreReg(FLDRQ, static_cast<Register>(vt), a, kQWord);
   }
   void fstrq(VRegister vt, Address a) {
     ASSERT(a.type() != Address::PCOffset);
-    EmitLoadStoreReg(FSTRQ, static_cast<Register>(vt), a, kByte);
+    EmitLoadStoreReg(FSTRQ, static_cast<Register>(vt), a, kQWord);
   }
   void fldrd(VRegister vt, Address a) {
     ASSERT(a.type() != Address::PCOffset);
@@ -1648,20 +1645,18 @@
     fldrq(reg, Address(SP, 1 * kQuadSize, Address::PostIndex));
   }
   void PushDoublePair(VRegister low, VRegister high) {
-    fstp(low, high,
-         Address(SP, -2 * kDoubleSize, Address::PairPreIndex, kDWord), kDWord);
+    fstp(low, high, Address(SP, -2 * kDoubleSize, Address::PairPreIndex),
+         kDWord);
   }
   void PopDoublePair(VRegister low, VRegister high) {
-    fldp(low, high,
-         Address(SP, 2 * kDoubleSize, Address::PairPostIndex, kDWord), kDWord);
+    fldp(low, high, Address(SP, 2 * kDoubleSize, Address::PairPostIndex),
+         kDWord);
   }
   void PushQuadPair(VRegister low, VRegister high) {
-    fstp(low, high, Address(SP, -2 * kQuadSize, Address::PairPreIndex, kQWord),
-         kQWord);
+    fstp(low, high, Address(SP, -2 * kQuadSize, Address::PairPreIndex), kQWord);
   }
   void PopQuadPair(VRegister low, VRegister high) {
-    fldp(low, high, Address(SP, 2 * kQuadSize, Address::PairPostIndex, kQWord),
-         kQWord);
+    fldp(low, high, Address(SP, 2 * kQuadSize, Address::PairPostIndex), kQWord);
   }
   void TagAndPushPP() {
     // Add the heap object tag back to PP before putting it on the stack.
@@ -1709,6 +1704,9 @@
     ASSERT((shift >= 0) && (shift < reg_size));
     ubfm(rd, rn, shift, reg_size - 1, sz);
   }
+  void LsrImmediate(Register rd, int32_t shift) override {
+    LsrImmediate(rd, rd, shift);
+  }
   void AsrImmediate(Register rd,
                     Register rn,
                     int shift,
@@ -1820,6 +1818,13 @@
   void AddRegisters(Register dest, Register src) {
     add(dest, dest, Operand(src));
   }
+  void AddScaled(Register dest,
+                 Register src,
+                 ScaleFactor scale,
+                 int32_t value) {
+    LoadImmediate(dest, value);
+    add(dest, dest, Operand(src, LSL, scale));
+  }
   void SubImmediateSetFlags(Register dest,
                             Register rn,
                             int64_t imm,
@@ -1948,6 +1953,18 @@
     }
   }
 
+  void LoadUnboxedSimd128(FpuRegister dst, Register base, int32_t offset) {
+    LoadQFromOffset(dst, base, offset);
+  }
+  void StoreUnboxedSimd128(FpuRegister src, Register base, int32_t offset) {
+    StoreQToOffset(src, base, offset);
+  }
+  void MoveUnboxedSimd128(FpuRegister dst, FpuRegister src) {
+    if (src != dst) {
+      vmov(dst, src);
+    }
+  }
+
   void LoadCompressed(Register dest, const Address& slot);
   void LoadCompressedFromOffset(Register dest, Register base, int32_t offset);
   void LoadCompressedSmi(Register dest, const Address& slot);
@@ -2018,7 +2035,8 @@
       MemoryOrder memory_order = kRelaxedNonAtomic);
   void StoreIntoObjectNoBarrier(Register object,
                                 const Address& dest,
-                                const Object& value);
+                                const Object& value,
+                                MemoryOrder memory_order = kRelaxedNonAtomic);
   void StoreCompressedIntoObjectNoBarrier(
       Register object,
       const Address& dest,
@@ -2740,9 +2758,8 @@
     ASSERT((op != LDR && op != STR && op != LDRS) || a.can_writeback_to(rt));
 
     const int32_t size = Log2OperandSizeBytes(sz);
-    ASSERT(a.log2sz_ == -1 || a.log2sz_ == size);
     const int32_t encoding =
-        op | ((size & 0x3) << kSzShift) | Arm64Encode::Rt(rt) | a.encoding();
+        op | ((size & 0x3) << kSzShift) | Arm64Encode::Rt(rt) | a.encoding(sz);
     Emit(encoding);
   }
 
@@ -2752,10 +2769,9 @@
                           OperandSize sz) {
     ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
            (sz == kUnsignedFourBytes));
-    ASSERT(a.log2sz_ == -1 || a.log2sz_ == Log2OperandSizeBytes(sz));
     ASSERT((rt != CSP) && (rt != R31));
     const int32_t size = (sz == kEightBytes) ? B30 : 0;
-    const int32_t encoding = op | size | Arm64Encode::Rt(rt) | a.encoding();
+    const int32_t encoding = op | size | Arm64Encode::Rt(rt) | a.encoding(sz);
     Emit(encoding);
   }
 
@@ -2770,7 +2786,6 @@
 
     ASSERT((sz == kEightBytes) || (sz == kFourBytes) ||
            (sz == kUnsignedFourBytes));
-    ASSERT(a.log2sz_ == -1 || a.log2sz_ == Log2OperandSizeBytes(sz));
     ASSERT((rt != CSP) && (rt != R31));
     ASSERT((rt2 != CSP) && (rt2 != R31));
     int32_t opc = 0;
@@ -2789,7 +2804,7 @@
         break;
     }
     const int32_t encoding =
-        opc | op | Arm64Encode::Rt(rt) | Arm64Encode::Rt2(rt2) | a.encoding();
+        opc | op | Arm64Encode::Rt(rt) | Arm64Encode::Rt2(rt2) | a.encoding(sz);
     Emit(encoding);
   }
 
@@ -2800,7 +2815,6 @@
                              OperandSize sz) {
     ASSERT(op != FLDP || rt != rt2);
     ASSERT((sz == kSWord) || (sz == kDWord) || (sz == kQWord));
-    ASSERT(a.log2sz_ == -1 || a.log2sz_ == Log2OperandSizeBytes(sz));
     int32_t opc = 0;
     switch (sz) {
       case kSWord:
@@ -2818,7 +2832,7 @@
     }
     const int32_t encoding =
         opc | op | Arm64Encode::Rt(static_cast<Register>(rt)) |
-        Arm64Encode::Rt2(static_cast<Register>(rt2)) | a.encoding();
+        Arm64Encode::Rt2(static_cast<Register>(rt2)) | a.encoding(sz);
     Emit(encoding);
   }
 
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index 7e36b4b..91635f7 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -666,9 +666,9 @@
          Operand(2 * target::kWordSize));  // Must not access beyond CSP.
 
   __ LoadImmediate(R1, 0xffffffff);
-  __ str(R1, Address(SP, -4, Address::PreIndex, kFourBytes), kFourBytes);
+  __ str(R1, Address(SP, -4, Address::PreIndex), kFourBytes);
   __ ldr(R0, Address(SP), kFourBytes);
-  __ ldr(R1, Address(SP, 4, Address::PostIndex, kFourBytes), kFourBytes);
+  __ ldr(R1, Address(SP, 4, Address::PostIndex), kFourBytes);
   __ RestoreCSP();
   __ ret();
 }
@@ -757,13 +757,9 @@
   __ LoadImmediate(R3, 0xBBCCDDEEFF998877);
   __ sub(SP, SP, Operand(4 * target::kWordSize));
   __ andi(CSP, SP, Immediate(~15));  // Must not access beyond CSP.
-  __ stp(R2, R3,
-         Address(SP, 2 * sizeof(uint32_t), Address::PairOffset,
-                 compiler::kUnsignedFourBytes),
+  __ stp(R2, R3, Address(SP, 2 * sizeof(uint32_t), Address::PairOffset),
          kUnsignedFourBytes);
-  __ ldp(R0, R1,
-         Address(SP, 2 * sizeof(uint32_t), Address::PairOffset,
-                 kUnsignedFourBytes),
+  __ ldp(R0, R1, Address(SP, 2 * sizeof(uint32_t), Address::PairOffset),
          kUnsignedFourBytes);
   __ add(SP, SP, Operand(4 * target::kWordSize));
   __ sub(R0, R0, Operand(R1));
@@ -801,11 +797,9 @@
   __ LoadImmediate(R3, 0xBBCCDDEEFF998877);
   __ sub(SP, SP, Operand(4 * target::kWordSize));
   __ andi(CSP, SP, Immediate(~15));  // Must not access beyond CSP.
-  __ stp(R2, R3,
-         Address(SP, 2 * sizeof(int32_t), Address::PairOffset, kFourBytes),
+  __ stp(R2, R3, Address(SP, 2 * sizeof(int32_t), Address::PairOffset),
          kFourBytes);
-  __ ldp(R0, R1,
-         Address(SP, 2 * sizeof(int32_t), Address::PairOffset, kFourBytes),
+  __ ldp(R0, R1, Address(SP, 2 * sizeof(int32_t), Address::PairOffset),
          kFourBytes);
   __ add(SP, SP, Operand(4 * target::kWordSize));
   __ sub(R0, R0, Operand(R1));
@@ -3645,7 +3639,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LoadHalfWordUnaligned, assembler) {
-  __ ldr(R1, R0, kTwoBytes);
+  __ ldr(R1, Address(R0), kTwoBytes);
   __ mov(R0, R1);
   __ ret();
 }
@@ -3672,7 +3666,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LoadHalfWordUnsignedUnaligned, assembler) {
-  __ ldr(R1, R0, kUnsignedTwoBytes);
+  __ ldr(R1, Address(R0), kUnsignedTwoBytes);
   __ mov(R0, R1);
   __ ret();
 }
@@ -3698,7 +3692,7 @@
 
 ASSEMBLER_TEST_GENERATE(StoreHalfWordUnaligned, assembler) {
   __ LoadImmediate(R1, 0xABCD);
-  __ str(R1, R0, kTwoBytes);
+  __ str(R1, Address(R0), kTwoBytes);
   __ mov(R0, R1);
   __ ret();
 }
@@ -3731,7 +3725,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LoadWordUnaligned, assembler) {
-  __ ldr(R1, R0, kUnsignedFourBytes);
+  __ ldr(R1, Address(R0), kUnsignedFourBytes);
   __ mov(R0, R1);
   __ ret();
 }
@@ -3765,7 +3759,7 @@
 
 ASSEMBLER_TEST_GENERATE(StoreWordUnaligned, assembler) {
   __ LoadImmediate(R1, 0x12345678);
-  __ str(R1, R0, kUnsignedFourBytes);
+  __ str(R1, Address(R0), kUnsignedFourBytes);
   __ mov(R0, R1);
   __ ret();
 }
@@ -5192,7 +5186,7 @@
   __ LoadDImmediate(V1, 42.0);
   __ sub(SP, SP, Operand(512 * target::kWordSize));
   __ andi(CSP, SP, Immediate(~15));  // Must not access beyond CSP.
-  __ fstrd(V1, Address(SP, 512 * target::kWordSize, Address::Offset));
+  __ fstrd(V1, Address(SP, 512 * target::kWordSize));
   __ add(SP, SP, Operand(512 * target::kWordSize));
   __ fldrd(V0, Address(SP));
   __ RestoreCSP();
diff --git a/runtime/vm/compiler/assembler/assembler_base.h b/runtime/vm/compiler/assembler/assembler_base.h
index 2d26847..dbb00a3 100644
--- a/runtime/vm/compiler/assembler/assembler_base.h
+++ b/runtime/vm/compiler/assembler/assembler_base.h
@@ -782,30 +782,24 @@
                             Register address,
                             int32_t offset = 0) = 0;
 
-  // Retrieves nullability from a FunctionTypePtr in [type] and compares it
-  // to [value].
-  //
-  // TODO(dartbug.com/47034): Change how nullability is stored so that it
-  // can be accessed without checking the class id first.
-  virtual void CompareFunctionTypeNullabilityWith(Register type,
-                                                  int8_t value) = 0;
+  // Loads nullability from an AbstractType [type] to [dst].
+  virtual void LoadAbstractTypeNullability(Register dst, Register type) = 0;
+  // Loads nullability from an AbstractType [type] and compares it
+  // to [value]. Clobbers [scratch].
+  virtual void CompareAbstractTypeNullabilityWith(Register type,
+                                                  /*Nullability*/ int8_t value,
+                                                  Register scratch) = 0;
 
-  // Retrieves nullability from a TypePtr in [type] and compares it to [value].
-  //
-  // TODO(dartbug.com/47034): Change how nullability is stored so that it
-  // can be accessed without checking the class id first.
-  virtual void CompareTypeNullabilityWith(Register type, int8_t value) = 0;
+  virtual void LsrImmediate(Register dst, int32_t shift) = 0;
 
   void LoadTypeClassId(Register dst, Register src) {
 #if !defined(TARGET_ARCH_IA32)
     EnsureHasClassIdInDEBUG(kTypeCid, src, TMP);
 #endif
-    ASSERT(!compiler::target::UntaggedType::kTypeClassIdIsSigned);
-    ASSERT_EQUAL(compiler::target::UntaggedType::kTypeClassIdBitSize,
-                 kBitsPerInt16);
     LoadFieldFromOffset(dst, src,
-                        compiler::target::Type::type_class_id_offset(),
-                        kUnsignedTwoBytes);
+                        compiler::target::AbstractType::flags_offset(),
+                        kUnsignedFourBytes);
+    LsrImmediate(dst, compiler::target::UntaggedType::kTypeClassIdShift);
   }
 
   virtual void EnsureHasClassIdInDEBUG(intptr_t cid,
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 51c1fa9..028d986 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -2619,17 +2619,15 @@
   ASSERT(cid > 0);
   Address state_address(kNoRegister, 0);
 
-  const intptr_t shared_table_offset =
-      target::IsolateGroup::shared_class_table_offset();
-  const intptr_t table_offset =
-      target::SharedClassTable::class_heap_stats_table_offset();
-  const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
-
   ASSERT(temp_reg != kNoRegister);
   LoadIsolateGroup(temp_reg);
-  movl(temp_reg, Address(temp_reg, shared_table_offset));
-  movl(temp_reg, Address(temp_reg, table_offset));
-  cmpb(Address(temp_reg, class_offset), Immediate(0));
+  movl(temp_reg, Address(temp_reg, target::IsolateGroup::class_table_offset()));
+  movl(temp_reg,
+       Address(temp_reg,
+               target::ClassTable::allocation_tracing_state_table_offset()));
+  cmpb(Address(temp_reg,
+               target::ClassTable::AllocationTracingStateSlotOffsetFor(cid)),
+       Immediate(0));
   // We are tracing for this class, jump to the trace label which will use
   // the allocation stub.
   j(NOT_ZERO, trace, distance);
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 7ef5339..3ce1e5f 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -13,6 +13,8 @@
 #error Do not include assembler_ia32.h directly; use assembler.h instead.
 #endif
 
+#include <functional>
+
 #include "platform/assert.h"
 #include "platform/utils.h"
 #include "vm/compiler/assembler/assembler_base.h"
@@ -580,6 +582,10 @@
     PushRegister(value);
   }
 
+  void PushValueAtOffset(Register base, int32_t offset) {
+    pushl(Address(base, offset));
+  }
+
   void CompareRegisters(Register a, Register b);
   void CompareObjectRegisters(Register a, Register b) {
     CompareRegisters(a, b);
@@ -686,6 +692,18 @@
     }
   }
 
+  void LoadUnboxedSimd128(FpuRegister dst, Register base, int32_t offset) {
+    movups(dst, Address(base, offset));
+  }
+  void StoreUnboxedSimd128(FpuRegister dst, Register base, int32_t offset) {
+    movups(Address(base, offset), dst);
+  }
+  void MoveUnboxedSimd128(FpuRegister dst, FpuRegister src) {
+    if (src != dst) {
+      movaps(dst, src);
+    }
+  }
+
   void LoadAcquire(Register dst, Register address, int32_t offset = 0) {
     // On intel loads have load-acquire behavior (i.e. loads are not re-ordered
     // with other loads).
@@ -728,6 +746,12 @@
   void AddRegisters(Register dest, Register src) {
     addl(dest, src);
   }
+  void AddScaled(Register dest,
+                 Register src,
+                 ScaleFactor scale,
+                 int32_t value) {
+    leal(dest, Address(src, scale, value));
+  }
 
   void SubImmediate(Register reg, const Immediate& imm);
   void SubRegisters(Register dest, Register src) {
@@ -742,6 +766,9 @@
   void LslImmediate(Register dst, int32_t shift) {
     shll(dst, Immediate(shift));
   }
+  void LsrImmediate(Register dst, int32_t shift) override {
+    shrl(dst, Immediate(shift));
+  }
 
   void CompareImmediate(Register reg, int32_t immediate) {
     cmpl(reg, Immediate(immediate));
@@ -808,6 +835,31 @@
                                 const Object& value,
                                 MemoryOrder memory_order = kRelaxedNonAtomic);
 
+  void StoreIntoObjectOffset(Register object,  // Object we are storing into.
+                             int32_t offset,   // Where we are storing into.
+                             Register value,   // Value we are storing.
+                             CanBeSmi can_value_be_smi = kValueCanBeSmi,
+                             MemoryOrder memory_order = kRelaxedNonAtomic) {
+    StoreIntoObject(object, FieldAddress(object, offset), value,
+                    can_value_be_smi, memory_order);
+  }
+  void StoreIntoObjectOffsetNoBarrier(
+      Register object,
+      int32_t offset,
+      Register value,
+      MemoryOrder memory_order = kRelaxedNonAtomic) {
+    StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
+                             memory_order);
+  }
+  void StoreIntoObjectOffsetNoBarrier(
+      Register object,
+      int32_t offset,
+      const Object& value,
+      MemoryOrder memory_order = kRelaxedNonAtomic) {
+    StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
+                             memory_order);
+  }
+
   // Stores a non-tagged value into a heap object.
   void StoreInternalPointer(Register object,
                             const Address& dest,
@@ -829,15 +881,17 @@
     cmpxchgl(address, reg);
   }
 
-  void CompareFunctionTypeNullabilityWith(Register type,
-                                          int8_t value) override {
-    cmpb(FieldAddress(type,
-                      compiler::target::FunctionType::nullability_offset()),
-         Immediate(value));
+  void LoadAbstractTypeNullability(Register dst, Register type) override {
+    movzxb(dst,
+           FieldAddress(type, compiler::target::AbstractType::flags_offset()));
+    andl(dst,
+         Immediate(compiler::target::UntaggedAbstractType::kNullabilityMask));
   }
-  void CompareTypeNullabilityWith(Register type, int8_t value) override {
-    cmpb(FieldAddress(type, compiler::target::Type::nullability_offset()),
-         Immediate(value));
+  void CompareAbstractTypeNullabilityWith(Register type,
+                                          /*Nullability*/ int8_t value,
+                                          Register scratch) override {
+    LoadAbstractTypeNullability(scratch, type);
+    cmpl(scratch, Immediate(value));
   }
 
   void EnterFrame(intptr_t frame_space);
diff --git a/runtime/vm/compiler/assembler/assembler_riscv.cc b/runtime/vm/compiler/assembler/assembler_riscv.cc
index a6724e2..11a8c87 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv.cc
+++ b/runtime/vm/compiler/assembler/assembler_riscv.cc
@@ -2368,7 +2368,7 @@
 }
 
 void Assembler::StoreRelease(Register src, Register address, int32_t offset) {
-  fence(HartEffects::kMemory, HartEffects::kRead);
+  fence(HartEffects::kMemory, HartEffects::kWrite);
   StoreToOffset(src, address, offset);
 }
 
@@ -2389,17 +2389,16 @@
   CompareRegisters(value, TMP2);
 }
 
-void Assembler::CompareFunctionTypeNullabilityWith(Register type,
-                                                   int8_t value) {
-  EnsureHasClassIdInDEBUG(kFunctionTypeCid, type, TMP);
-  lbu(TMP,
-      FieldAddress(type, compiler::target::FunctionType::nullability_offset()));
-  CompareImmediate(TMP, value);
+void Assembler::LoadAbstractTypeNullability(Register dst, Register type) {
+  lbu(dst, FieldAddress(type, compiler::target::AbstractType::flags_offset()));
+  andi(dst, dst, compiler::target::UntaggedAbstractType::kNullabilityMask);
 }
-void Assembler::CompareTypeNullabilityWith(Register type, int8_t value) {
-  EnsureHasClassIdInDEBUG(kTypeCid, type, TMP);
-  lbu(TMP, FieldAddress(type, compiler::target::Type::nullability_offset()));
-  CompareImmediate(TMP, value);
+
+void Assembler::CompareAbstractTypeNullabilityWith(Register type,
+                                                   /*Nullability*/ int8_t value,
+                                                   Register scratch) {
+  LoadAbstractTypeNullability(scratch, type);
+  CompareImmediate(scratch, value);
 }
 
 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
@@ -3168,7 +3167,7 @@
                                                Register value,
                                                MemoryOrder memory_order) {
   if (memory_order == kRelease) {
-    StoreRelease(value, object, offset);
+    StoreRelease(value, object, offset - kHeapObjectTag);
   } else {
     StoreToOffset(value, object, offset - kHeapObjectTag);
   }
@@ -3200,18 +3199,24 @@
 }
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
-                                         const Object& value) {
+                                         const Object& value,
+                                         MemoryOrder memory_order) {
   ASSERT(IsOriginalObject(value));
   ASSERT(IsNotTemporaryScopedHandle(value));
   // No store buffer update.
+  Register value_reg;
   if (IsSameObject(compiler::NullObject(), value)) {
-    sx(NULL_REG, dest);
+    value_reg = NULL_REG;
   } else if (target::IsSmi(value) && (target::ToRawSmi(value) == 0)) {
-    sx(ZR, dest);
+    value_reg = ZR;
   } else {
     LoadObject(TMP2, value);
-    sx(TMP2, dest);
+    value_reg = TMP2;
   }
+  if (memory_order == kRelease) {
+    fence(HartEffects::kMemory, HartEffects::kWrite);
+  }
+  sx(value_reg, dest);
 }
 void Assembler::StoreCompressedIntoObjectNoBarrier(Register object,
                                                    const Address& dest,
@@ -4000,22 +4005,14 @@
                                      Register temp_reg,
                                      JumpDistance distance) {
   ASSERT(cid > 0);
-
-  const intptr_t shared_table_offset =
-      target::IsolateGroup::shared_class_table_offset();
-  const intptr_t table_offset =
-      target::SharedClassTable::class_heap_stats_table_offset();
-  const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
-
   LoadIsolateGroup(temp_reg);
-  lx(temp_reg, Address(temp_reg, shared_table_offset));
-  lx(temp_reg, Address(temp_reg, table_offset));
-  if (IsITypeImm(class_offset)) {
-    lbu(temp_reg, Address(temp_reg, class_offset));
-  } else {
-    AddImmediate(temp_reg, class_offset);
-    lbu(temp_reg, Address(temp_reg, 0));
-  }
+  lx(temp_reg, Address(temp_reg, target::IsolateGroup::class_table_offset()));
+  lx(temp_reg,
+     Address(temp_reg,
+             target::ClassTable::allocation_tracing_state_table_offset()));
+  LoadFromOffset(temp_reg, temp_reg,
+                 target::ClassTable::AllocationTracingStateSlotOffsetFor(cid),
+                 kUnsignedByte);
   bnez(temp_reg, trace);
 }
 #endif  // !PRODUCT
@@ -4142,6 +4139,7 @@
   switch (cid) {
     case kArrayCid:
     case kImmutableArrayCid:
+    case kRecordCid:
     case kTypeArgumentsCid:
       return kObjectBytes;
     case kOneByteStringCid:
diff --git a/runtime/vm/compiler/assembler/assembler_riscv.h b/runtime/vm/compiler/assembler/assembler_riscv.h
index cefa220..e5da2e4 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv.h
+++ b/runtime/vm/compiler/assembler/assembler_riscv.h
@@ -780,6 +780,8 @@
 
   void PushRegistersInOrder(std::initializer_list<Register> regs);
 
+  void PushValueAtOffset(Register base, int32_t offset) { UNIMPLEMENTED(); }
+
   // Push all registers which are callee-saved according to the ARM64 ABI.
   void PushNativeCalleeSavedRegisters();
 
@@ -844,8 +846,10 @@
 
   void CompareWithMemoryValue(Register value, Address address);
 
-  void CompareFunctionTypeNullabilityWith(Register type, int8_t value) override;
-  void CompareTypeNullabilityWith(Register type, int8_t value) override;
+  void LoadAbstractTypeNullability(Register dst, Register type) override;
+  void CompareAbstractTypeNullabilityWith(Register type,
+                                          /*Nullability*/ int8_t value,
+                                          Register scratch) override;
 
   // Debugging and bringup support.
   void Breakpoint() override { trap(); }
@@ -943,6 +947,13 @@
   void AddRegisters(Register dest, Register src) {
     add(dest, dest, src);
   }
+  void AddScaled(Register dest,
+                 Register src,
+                 ScaleFactor scale,
+                 int32_t value) {
+    slli(dest, src, scale);
+    addi(dest, dest, value);
+  }
   void SubRegisters(Register dest, Register src) {
     sub(dest, dest, src);
   }
@@ -977,6 +988,9 @@
   void LslImmediate(Register rd, int32_t shift) {
     slli(rd, rd, shift);
   }
+  void LsrImmediate(Register rd, int32_t shift) override {
+    srli(rd, rd, shift);
+  }
   void TestImmediate(Register rn, intx_t imm, OperandSize sz = kWordBytes);
   void CompareImmediate(Register rn, intx_t imm, OperandSize sz = kWordBytes);
 
@@ -1058,6 +1072,19 @@
     fmvd(dst, src);
   }
 
+  void LoadUnboxedSimd128(FpuRegister dst, Register base, int32_t offset) {
+    // No single register SIMD on RISC-V.
+    UNREACHABLE();
+  }
+  void StoreUnboxedSimd128(FpuRegister src, Register base, int32_t offset) {
+    // No single register SIMD on RISC-V.
+    UNREACHABLE();
+  }
+  void MoveUnboxedSimd128(FpuRegister dst, FpuRegister src) {
+    // No single register SIMD on RISC-V.
+    UNREACHABLE();
+  }
+
   void LoadCompressed(Register dest, const Address& slot) {
     lx(dest, slot);
   }
@@ -1136,7 +1163,8 @@
       MemoryOrder memory_order = kRelaxedNonAtomic);
   void StoreIntoObjectNoBarrier(Register object,
                                 const Address& dest,
-                                const Object& value);
+                                const Object& value,
+                                MemoryOrder memory_order = kRelaxedNonAtomic);
   void StoreCompressedIntoObjectNoBarrier(
       Register object,
       const Address& dest,
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index bfed044..85ec802 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -2201,19 +2201,18 @@
                                      Register temp_reg,
                                      JumpDistance distance) {
   ASSERT(cid > 0);
-  const intptr_t shared_table_offset =
-      target::IsolateGroup::shared_class_table_offset();
-  const intptr_t table_offset =
-      target::SharedClassTable::class_heap_stats_table_offset();
-  const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
 
   if (temp_reg == kNoRegister) {
     temp_reg = TMP;
   }
   LoadIsolateGroup(temp_reg);
-  movq(temp_reg, Address(temp_reg, shared_table_offset));
-  movq(temp_reg, Address(temp_reg, table_offset));
-  cmpb(Address(temp_reg, class_offset), Immediate(0));
+  movq(temp_reg, Address(temp_reg, target::IsolateGroup::class_table_offset()));
+  movq(temp_reg,
+       Address(temp_reg,
+               target::ClassTable::allocation_tracing_state_table_offset()));
+  cmpb(Address(temp_reg,
+               target::ClassTable::AllocationTracingStateSlotOffsetFor(cid)),
+       Immediate(0));
   // We are tracing for this class, jump to the trace label which will use
   // the allocation stub.
   j(NOT_ZERO, trace, distance);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index eafff9b..0d7e0fb 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -594,6 +594,9 @@
   void LslImmediate(Register dst, int32_t shift) {
     shlq(dst, Immediate(shift));
   }
+  void LsrImmediate(Register dst, int32_t shift) override {
+    shrq(dst, Immediate(shift));
+  }
 
   void shldq(Register dst, Register src, Register shifter) {
     ASSERT(shifter == RCX);
@@ -753,6 +756,10 @@
     PopRegister(r1);
   }
 
+  void PushValueAtOffset(Register base, int32_t offset) {
+    pushq(Address(base, offset));
+  }
+
   // Methods for adding/subtracting an immediate value that may be loaded from
   // the constant pool.
   // TODO(koda): Assert that these are not used for heap objects.
@@ -767,6 +774,12 @@
   void AddRegisters(Register dest, Register src) {
     addq(dest, src);
   }
+  void AddScaled(Register dest,
+                 Register src,
+                 ScaleFactor scale,
+                 int32_t value) {
+    leaq(dest, Address(src, scale, value));
+  }
   void AddImmediate(Register dest, Register src, int32_t value);
   void AddImmediate(const Address& address, const Immediate& imm);
   void SubImmediate(Register reg,
@@ -832,12 +845,29 @@
                        Register value,       // Value we are storing.
                        CanBeSmi can_be_smi = kValueCanBeSmi,
                        MemoryOrder memory_order = kRelaxedNonAtomic) override;
+  void StoreIntoObjectOffset(Register object,  // Object we are storing into.
+                             int32_t offset,   // Where we are storing into.
+                             Register value,   // Value we are storing.
+                             CanBeSmi can_be_smi = kValueCanBeSmi,
+                             MemoryOrder memory_order = kRelaxedNonAtomic) {
+    StoreIntoObject(object, FieldAddress(object, offset), value, can_be_smi,
+                    memory_order);
+  }
   void StoreCompressedIntoObject(
       Register object,      // Object we are storing into.
       const Address& dest,  // Where we are storing into.
       Register value,       // Value we are storing.
       CanBeSmi can_be_smi = kValueCanBeSmi,
       MemoryOrder memory_order = kRelaxedNonAtomic) override;
+  void StoreCompressedIntoObjectOffset(
+      Register object,  // Object we are storing into.
+      int32_t offset,   // Where we are storing into.
+      Register value,   // Value we are storing.
+      CanBeSmi can_be_smi = kValueCanBeSmi,
+      MemoryOrder memory_order = kRelaxedNonAtomic) {
+    StoreCompressedIntoObject(object, FieldAddress(object, offset), value,
+                              can_be_smi, memory_order);
+  }
   void StoreBarrier(Register object,  // Object we are storing into.
                     Register value,   // Value we are storing.
                     CanBeSmi can_be_smi);
@@ -870,6 +900,39 @@
       const Object& value,
       MemoryOrder memory_order = kRelaxedNonAtomic);
 
+  void StoreIntoObjectOffsetNoBarrier(
+      Register object,
+      int32_t offset,
+      Register value,
+      MemoryOrder memory_order = kRelaxedNonAtomic) {
+    StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
+                             memory_order);
+  }
+  void StoreCompressedIntoObjectOffsetNoBarrier(
+      Register object,
+      int32_t offset,
+      Register value,
+      MemoryOrder memory_order = kRelaxedNonAtomic) {
+    StoreCompressedIntoObjectNoBarrier(object, FieldAddress(object, offset),
+                                       value, memory_order);
+  }
+  void StoreIntoObjectOffsetNoBarrier(
+      Register object,
+      int32_t offset,
+      const Object& value,
+      MemoryOrder memory_order = kRelaxedNonAtomic) {
+    StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
+                             memory_order);
+  }
+  void StoreCompressedIntoObjectOffsetNoBarrier(
+      Register object,
+      int32_t offset,
+      const Object& value,
+      MemoryOrder memory_order = kRelaxedNonAtomic) {
+    StoreCompressedIntoObjectNoBarrier(object, FieldAddress(object, offset),
+                                       value, memory_order);
+  }
+
   // Stores a non-tagged value into a heap object.
   void StoreInternalPointer(Register object,
                             const Address& dest,
@@ -1082,6 +1145,18 @@
     movq(Address(base, offset), src);
   }
 
+  void LoadUnboxedSimd128(FpuRegister dst, Register base, int32_t offset) {
+    movups(dst, Address(base, offset));
+  }
+  void StoreUnboxedSimd128(FpuRegister dst, Register base, int32_t offset) {
+    movups(Address(base, offset), dst);
+  }
+  void MoveUnboxedSimd128(FpuRegister dst, FpuRegister src) {
+    if (src != dst) {
+      movaps(dst, src);
+    }
+  }
+
   void LoadUnboxedDouble(FpuRegister dst, Register base, int32_t offset) {
     movsd(dst, Address(base, offset));
   }
@@ -1147,17 +1222,17 @@
     OBJ(cmp)(value, FieldAddress(base, offset));
   }
 
-  void CompareFunctionTypeNullabilityWith(Register type,
-                                          int8_t value) override {
-    EnsureHasClassIdInDEBUG(kFunctionTypeCid, type, TMP);
-    cmpb(FieldAddress(type,
-                      compiler::target::FunctionType::nullability_offset()),
-         Immediate(value));
+  void LoadAbstractTypeNullability(Register dst, Register type) override {
+    movzxb(dst,
+           FieldAddress(type, compiler::target::AbstractType::flags_offset()));
+    andl(dst,
+         Immediate(compiler::target::UntaggedAbstractType::kNullabilityMask));
   }
-  void CompareTypeNullabilityWith(Register type, int8_t value) override {
-    EnsureHasClassIdInDEBUG(kTypeCid, type, TMP);
-    cmpb(FieldAddress(type, compiler::target::Type::nullability_offset()),
-         Immediate(value));
+  void CompareAbstractTypeNullabilityWith(Register type,
+                                          /*Nullability*/ int8_t value,
+                                          Register scratch) override {
+    LoadAbstractTypeNullability(scratch, type);
+    cmpl(scratch, Immediate(value));
   }
 
   void RestoreCodePointer();
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index b2c9ad3..b7c4c9f 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -938,6 +938,10 @@
   SetValue(instr, non_constant_);
 }
 
+void ConstantPropagator::VisitAllocateRecord(AllocateRecordInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
 void ConstantPropagator::VisitLoadUntagged(LoadUntaggedInstr* instr) {
   SetValue(instr, non_constant_);
 }
diff --git a/runtime/vm/compiler/backend/constant_propagator_test.cc b/runtime/vm/compiler/backend/constant_propagator_test.cc
index 1ee3b6d..076641a 100644
--- a/runtime/vm/compiler/backend/constant_propagator_test.cc
+++ b/runtime/vm/compiler/backend/constant_propagator_test.cc
@@ -117,16 +117,8 @@
   using compiler::BlockBuilder;
 
   CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
-  FlowGraphBuilderHelper H;
-
-  // Add a variable into the scope which would provide static type for the
-  // parameter.
-  LocalVariable* v0_var =
-      new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
-                        String::Handle(Symbols::New(thread, "v0")),
-                        AbstractType::ZoneHandle(Type::IntType()));
-  v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
-  H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);
+  FlowGraphBuilderHelper H(/*num_parameters=*/1);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::IntType()));
 
   // We are going to build the following graph:
   //
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index ba01367..e983119 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -517,6 +517,57 @@
   }
 }
 
+#define __ assembler()->
+
+void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
+  if (is_optimizing()) {
+    return;
+  }
+  Definition* defn = instr->AsDefinition();
+  if (defn != nullptr && defn->HasTemp()) {
+    Location value = defn->locs()->out(0);
+    if (value.IsRegister()) {
+      __ PushRegister(value.reg());
+    } else if (value.IsFpuRegister()) {
+      const Code* stub;
+      switch (instr->representation()) {
+        case kUnboxedDouble:
+          stub = &StubCode::BoxDouble();
+          break;
+        case kUnboxedFloat32x4:
+          stub = &StubCode::BoxFloat32x4();
+          break;
+        case kUnboxedFloat64x2:
+          stub = &StubCode::BoxFloat64x2();
+          break;
+        default:
+          UNREACHABLE();
+          break;
+      }
+
+      // In unoptimized code at instruction epilogue the only
+      // live register is an output register.
+      instr->locs()->live_registers()->Clear();
+      if (instr->representation() == kUnboxedDouble) {
+        __ MoveUnboxedDouble(BoxDoubleStubABI::kValueReg, value.fpu_reg());
+      } else {
+        __ MoveUnboxedSimd128(BoxDoubleStubABI::kValueReg, value.fpu_reg());
+      }
+      GenerateNonLazyDeoptableStubCall(
+          InstructionSource(),  // No token position.
+          *stub, UntaggedPcDescriptors::kOther, instr->locs());
+      __ PushRegister(BoxDoubleStubABI::kResultReg);
+    } else if (value.IsConstant()) {
+      __ PushObject(value.constant());
+    } else {
+      ASSERT(value.IsStackSlot());
+      __ PushValueAtOffset(value.base_reg(), value.ToStackSlotOffset());
+    }
+  }
+}
+
+#undef __
+
 void FlowGraphCompiler::EmitSourceLine(Instruction* instr) {
   if (!instr->token_pos().IsReal()) {
     return;
@@ -1750,6 +1801,15 @@
                 fpu_reg, reg,
                 compiler::target::Double::value_offset() - kHeapObjectTag);
             break;
+          case kUnboxedFloat32x4:
+          case kUnboxedFloat64x2:
+            ASSERT(fpu_reg != kNoFpuRegister);
+            ASSERT(instr->SpeculativeModeOfInput(i) ==
+                   Instruction::kNotSpeculative);
+            assembler()->LoadUnboxedSimd128(
+                fpu_reg, reg,
+                compiler::target::Float32x4::value_offset() - kHeapObjectTag);
+            break;
           default:
             // No automatic unboxing for other representations.
             ASSERT(fpu_reg == kNoFpuRegister);
@@ -2582,6 +2642,13 @@
     return GenerateFunctionTypeTest(source, type, is_instance_lbl,
                                     is_not_instance_lbl);
   }
+  if (type.IsRecordType()) {
+    // Subtype test cache stubs are not useful for record types.
+    // Fall through to runtime.
+    // TODO(dartbug.com/49719): generate separate type test
+    // for each record field.
+    return SubtypeTestCache::New();
+  }
 
   if (type.IsInstantiated()) {
     const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
@@ -2698,6 +2765,7 @@
   __ Comment("InstantiatedTypeWithArgumentsTest");
   ASSERT(type.IsInstantiated());
   ASSERT(!type.IsFunctionType());
+  ASSERT(!type.IsRecordType());
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() > 0);
   const Type& smi_type = Type::Handle(zone(), Type::SmiType());
@@ -2762,6 +2830,7 @@
   __ Comment("InstantiatedTypeNoArgumentsTest");
   ASSERT(type.IsInstantiated());
   ASSERT(!type.IsFunctionType());
+  ASSERT(!type.IsRecordType());
   const Class& type_class = Class::Handle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() == 0);
 
@@ -2801,6 +2870,12 @@
     __ BranchIf(EQUAL, is_instance_lbl);
     return true;
   }
+  if (type.IsDartRecordType()) {
+    // Check if instance is a record.
+    __ CompareImmediate(kScratchReg, kRecordCid);
+    __ BranchIf(EQUAL, is_instance_lbl);
+    return true;
+  }
 
   // Fast case for cid-range based checks.
   // Warning: This code destroys the contents of [kScratchReg], so this should
@@ -2820,6 +2895,7 @@
   __ Comment("UninstantiatedTypeTest");
   ASSERT(!type.IsInstantiated());
   ASSERT(!type.IsFunctionType());
+  ASSERT(!type.IsRecordType());
   // Skip check if destination is a dynamic type.
   if (type.IsTypeParameter()) {
     // We don't use TypeTestABI::kScratchReg as it is not defined on IA32.
@@ -3183,7 +3259,7 @@
     return output_dst_type();
   }
 
-  if (dst_type.IsFunctionType()) {
+  if (dst_type.IsFunctionType() || dst_type.IsRecordType()) {
     return output_dst_type();
   }
 
@@ -3249,7 +3325,9 @@
 void FlowGraphCompiler::FrameStatePush(Definition* defn) {
   Representation rep = defn->representation();
   ASSERT(!is_optimizing());
-  if ((rep == kUnboxedDouble) && defn->locs()->out(0).IsFpuRegister()) {
+  if ((rep == kUnboxedDouble || rep == kUnboxedFloat32x4 ||
+       rep == kUnboxedFloat64x2) &&
+      defn->locs()->out(0).IsFpuRegister()) {
     // Output value is boxed in the instruction epilogue.
     rep = kTagged;
   }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 5a9918a..a47410f 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -231,31 +231,6 @@
   __ Bind(&fall_through);
 }
 
-void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
-  if (is_optimizing()) {
-    return;
-  }
-  Definition* defn = instr->AsDefinition();
-  if ((defn != NULL) && defn->HasTemp()) {
-    const Location value = defn->locs()->out(0);
-    if (value.IsRegister()) {
-      __ PushRegister(value.reg());
-    } else if (value.IsFpuRegister()) {
-      ASSERT(instr->representation() == kUnboxedDouble);
-      // In unoptimized code at instruction epilogue the only
-      // live register is an output register.
-      instr->locs()->live_registers()->Clear();
-      __ MoveUnboxedDouble(BoxDoubleStubABI::kValueReg, value.fpu_reg());
-      GenerateNonLazyDeoptableStubCall(
-          InstructionSource(),  // No token position.
-          StubCode::BoxDouble(), UntaggedPcDescriptors::kOther, instr->locs());
-      __ PushRegister(BoxDoubleStubABI::kResultReg);
-    } else {
-      UNREACHABLE();
-    }
-  }
-}
-
 void FlowGraphCompiler::GenerateMethodExtractorIntrinsic(
     const Function& extracted_method,
     intptr_t type_arguments_field_offset) {
@@ -498,7 +473,7 @@
   __ LoadFieldFromOffset(R1, R0,
                          compiler::target::Array::element_offset(edge_id));
   __ add(R1, R1, compiler::Operand(Smi::RawValue(1)));
-  __ StoreIntoObjectNoBarrierOffset(
+  __ StoreIntoObjectOffsetNoBarrier(
       R0, compiler::target::Array::element_offset(edge_id), R1);
 #if defined(DEBUG)
   assembler_->set_use_far_branches(old_use_far_branches);
@@ -695,7 +670,7 @@
   if (!arguments_descriptor.IsNull()) {
     __ LoadObject(ARGS_DESC_REG, arguments_descriptor);
   }
-  intptr_t offset = (selector_offset - DispatchTable::OriginElement()) *
+  intptr_t offset = (selector_offset - DispatchTable::kOriginElement) *
                     compiler::target::kWordSize;
   CLOBBERS_LR({
     // Would like cid_reg to be available on entry to the target function
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index fd697f2..b95f677 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -222,31 +222,6 @@
   __ Bind(&fall_through);
 }
 
-void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
-  if (is_optimizing()) {
-    return;
-  }
-  Definition* defn = instr->AsDefinition();
-  if ((defn != NULL) && defn->HasTemp()) {
-    const Location value = defn->locs()->out(0);
-    if (value.IsRegister()) {
-      __ PushRegister(value.reg());
-    } else if (value.IsFpuRegister()) {
-      ASSERT(instr->representation() == kUnboxedDouble);
-      // In unoptimized code at instruction epilogue the only
-      // live register is an output register.
-      instr->locs()->live_registers()->Clear();
-      __ MoveUnboxedDouble(BoxDoubleStubABI::kValueReg, value.fpu_reg());
-      GenerateNonLazyDeoptableStubCall(
-          InstructionSource(),  // No token position.
-          StubCode::BoxDouble(), UntaggedPcDescriptors::kOther, instr->locs());
-      __ PushRegister(BoxDoubleStubABI::kResultReg);
-    } else {
-      UNREACHABLE();
-    }
-  }
-}
-
 void FlowGraphCompiler::GenerateMethodExtractorIntrinsic(
     const Function& extracted_method,
     intptr_t type_arguments_field_offset) {
@@ -696,7 +671,7 @@
   if (!arguments_descriptor.IsNull()) {
     __ LoadObject(ARGS_DESC_REG, arguments_descriptor);
   }
-  const intptr_t offset = selector_offset - DispatchTable::OriginElement();
+  const intptr_t offset = selector_offset - DispatchTable::kOriginElement;
   CLOBBERS_LR({
     // Would like cid_reg to be available on entry to the target function
     // for checking purposes.
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index db8d71e..4720f2a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -351,34 +351,6 @@
   __ Bind(&is_assignable);
 }
 
-void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
-  if (is_optimizing()) {
-    return;
-  }
-  Definition* defn = instr->AsDefinition();
-  if ((defn != NULL) && defn->HasTemp()) {
-    Location value = defn->locs()->out(0);
-    if (value.IsRegister()) {
-      __ PushRegister(value.reg());
-    } else if (value.IsFpuRegister()) {
-      ASSERT(instr->representation() == kUnboxedDouble);
-      // In unoptimized code at instruction epilogue the only
-      // live register is an output register.
-      instr->locs()->live_registers()->Clear();
-      __ MoveUnboxedDouble(BoxDoubleStubABI::kValueReg, value.fpu_reg());
-      GenerateNonLazyDeoptableStubCall(
-          InstructionSource(),  // No token position.
-          StubCode::BoxDouble(), UntaggedPcDescriptors::kOther, instr->locs());
-      __ PushRegister(BoxDoubleStubABI::kResultReg);
-    } else if (value.IsConstant()) {
-      __ PushObject(value.constant());
-    } else {
-      ASSERT(value.IsStackSlot());
-      __ pushl(LocationToStackSlotAddress(value));
-    }
-  }
-}
-
 // NOTE: If the entry code shape changes, ReturnAddressLocator in profiler.cc
 // needs to be updated to match.
 void FlowGraphCompiler::EmitFrameEntry() {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc b/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc
index 1decc19..b2a3b1f 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc
@@ -211,31 +211,6 @@
   __ Bind(&fall_through);
 }
 
-void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
-  if (is_optimizing()) {
-    return;
-  }
-  Definition* defn = instr->AsDefinition();
-  if ((defn != NULL) && defn->HasTemp()) {
-    const Location value = defn->locs()->out(0);
-    if (value.IsRegister()) {
-      __ PushRegister(value.reg());
-    } else if (value.IsFpuRegister()) {
-      ASSERT(instr->representation() == kUnboxedDouble);
-      // In unoptimized code at instruction epilogue the only
-      // live register is an output register.
-      instr->locs()->live_registers()->Clear();
-      __ MoveUnboxedDouble(BoxDoubleStubABI::kValueReg, value.fpu_reg());
-      GenerateNonLazyDeoptableStubCall(
-          InstructionSource(),  // No token position.
-          StubCode::BoxDouble(), UntaggedPcDescriptors::kOther, instr->locs());
-      __ PushRegister(BoxDoubleStubABI::kResultReg);
-    } else {
-      UNREACHABLE();
-    }
-  }
-}
-
 void FlowGraphCompiler::GenerateMethodExtractorIntrinsic(
     const Function& extracted_method,
     intptr_t type_arguments_field_offset) {
@@ -666,7 +641,7 @@
   if (!arguments_descriptor.IsNull()) {
     __ LoadObject(ARGS_DESC_REG, arguments_descriptor);
   }
-  const intptr_t offset = selector_offset - DispatchTable::OriginElement();
+  const intptr_t offset = selector_offset - DispatchTable::kOriginElement;
   // Would like cid_reg to be available on entry to the target function
   // for checking purposes.
   ASSERT(cid_reg != TMP);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index ba0add49..e6ae0ce 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -223,34 +223,6 @@
   __ Bind(&fall_through);
 }
 
-void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
-  if (is_optimizing()) {
-    return;
-  }
-  Definition* defn = instr->AsDefinition();
-  if ((defn != NULL) && defn->HasTemp()) {
-    Location value = defn->locs()->out(0);
-    if (value.IsRegister()) {
-      __ PushRegister(value.reg());
-    } else if (value.IsFpuRegister()) {
-      ASSERT(instr->representation() == kUnboxedDouble);
-      // In unoptimized code at instruction epilogue the only
-      // live register is an output register.
-      instr->locs()->live_registers()->Clear();
-      __ MoveUnboxedDouble(BoxDoubleStubABI::kValueReg, value.fpu_reg());
-      GenerateNonLazyDeoptableStubCall(
-          InstructionSource(),  // No token position.
-          StubCode::BoxDouble(), UntaggedPcDescriptors::kOther, instr->locs());
-      __ PushRegister(BoxDoubleStubABI::kResultReg);
-    } else if (value.IsConstant()) {
-      __ PushObject(value.constant());
-    } else {
-      ASSERT(value.IsStackSlot());
-      __ pushq(LocationToStackSlotAddress(value));
-    }
-  }
-}
-
 void FlowGraphCompiler::GenerateMethodExtractorIntrinsic(
     const Function& extracted_method,
     intptr_t type_arguments_field_offset) {
@@ -682,7 +654,7 @@
   if (!arguments_descriptor.IsNull()) {
     __ LoadObject(ARGS_DESC_REG, arguments_descriptor);
   }
-  const intptr_t offset = (selector_offset - DispatchTable::OriginElement()) *
+  const intptr_t offset = (selector_offset - DispatchTable::kOriginElement) *
                           compiler::target::kWordSize;
   __ LoadDispatchTable(table_reg);
   __ call(compiler::Address(table_reg, cid_reg, TIMES_8, offset));
diff --git a/runtime/vm/compiler/backend/flow_graph_test.cc b/runtime/vm/compiler/backend/flow_graph_test.cc
index ababc2b..46b69dc5 100644
--- a/runtime/vm/compiler/backend/flow_graph_test.cc
+++ b/runtime/vm/compiler/backend/flow_graph_test.cc
@@ -23,17 +23,9 @@
 
   CompilerState S(thread, /*is_aot=*/true, /*is_optimizing=*/true);
 
-  FlowGraphBuilderHelper H;
-
-  // Add a variable into the scope which would provide static type for the
-  // parameter.
-  LocalVariable* v0_var =
-      new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
-                        String::Handle(Symbols::New(thread, "v0")),
-                        AbstractType::ZoneHandle(Type::IntType()),
-                        new CompileType(CompileType::Int()));
-  v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
-  H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);
+  FlowGraphBuilderHelper H(/*num_parameters=*/1);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::IntType()),
+                new CompileType(CompileType::Int()));
 
   auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
   auto loop_header = H.JoinEntry();
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 7182992..f3a9432 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -898,20 +898,7 @@
   return mask;
 }
 
-bool LoadFieldInstr::IsUnboxedDartFieldLoad() const {
-  return slot().representation() == kTagged && slot().IsDartField() &&
-         slot().IsUnboxed();
-}
-
-bool LoadFieldInstr::IsPotentialUnboxedDartFieldLoad() const {
-  return slot().representation() == kTagged && slot().IsDartField() &&
-         slot().IsPotentialUnboxed();
-}
-
 Representation LoadFieldInstr::representation() const {
-  if (IsUnboxedDartFieldLoad() && CompilerState::Current().is_optimizing()) {
-    return slot().UnboxedRepresentation();
-  }
   return slot().representation();
 }
 
@@ -967,16 +954,6 @@
                              locs(), deopt_id(), env());
 }
 
-bool StoreFieldInstr::IsUnboxedDartFieldStore() const {
-  return slot().representation() == kTagged && slot().IsDartField() &&
-         slot().IsUnboxed();
-}
-
-bool StoreFieldInstr::IsPotentialUnboxedDartFieldStore() const {
-  return slot().representation() == kTagged && slot().IsDartField() &&
-         slot().IsPotentialUnboxed();
-}
-
 Representation StoreFieldInstr::RequiredInputRepresentation(
     intptr_t index) const {
   ASSERT((index == 0) || (index == 1));
@@ -984,9 +961,6 @@
     // The instance is always tagged.
     return kTagged;
   }
-  if (IsUnboxedDartFieldStore() && CompilerState::Current().is_optimizing()) {
-    return slot().UnboxedRepresentation();
-  }
   return slot().representation();
 }
 
@@ -4278,6 +4252,115 @@
   }
 }
 
+LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone,
+                                                     bool opt) const {
+  const intptr_t kNumInputs = 1;
+  LocationSummary* locs = nullptr;
+  if (slot().representation() != kTagged) {
+    ASSERT(!calls_initializer());
+
+    const intptr_t kNumTemps = 0;
+    locs = new (zone)
+        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+    locs->set_in(0, Location::RequiresRegister());
+    if (RepresentationUtils::IsUnboxedInteger(slot().representation())) {
+      const size_t value_size =
+          RepresentationUtils::ValueSize(slot().representation());
+      if (value_size <= compiler::target::kWordSize) {
+        locs->set_out(0, Location::RequiresRegister());
+      } else {
+        ASSERT(value_size == 2 * compiler::target::kWordSize);
+        locs->set_out(0, Location::Pair(Location::RequiresRegister(),
+                                        Location::RequiresRegister()));
+      }
+    } else {
+      locs->set_out(0, Location::RequiresFpuRegister());
+    }
+  } else if (calls_initializer()) {
+    if (throw_exception_on_initialization()) {
+      const bool using_shared_stub = UseSharedSlowPathStub(opt);
+      const intptr_t kNumTemps = using_shared_stub ? 1 : 0;
+      locs = new (zone) LocationSummary(
+          zone, kNumInputs, kNumTemps,
+          using_shared_stub ? LocationSummary::kCallOnSharedSlowPath
+                            : LocationSummary::kCallOnSlowPath);
+      if (using_shared_stub) {
+        locs->set_temp(0, Location::RegisterLocation(
+                              LateInitializationErrorABI::kFieldReg));
+      }
+      locs->set_in(0, Location::RequiresRegister());
+      locs->set_out(0, Location::RequiresRegister());
+    } else {
+      const intptr_t kNumTemps = 0;
+      locs = new (zone)
+          LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
+      locs->set_in(
+          0, Location::RegisterLocation(InitInstanceFieldABI::kInstanceReg));
+      locs->set_out(
+          0, Location::RegisterLocation(InitInstanceFieldABI::kResultReg));
+    }
+  } else {
+    const intptr_t kNumTemps = 0;
+    locs = new (zone)
+        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+    locs->set_in(0, Location::RequiresRegister());
+    locs->set_out(0, Location::RequiresRegister());
+  }
+  return locs;
+}
+
+void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register instance_reg = locs()->in(0).reg();
+  if (representation() != kTagged) {
+    if (RepresentationUtils::IsUnboxedInteger(representation())) {
+      const size_t value_size =
+          RepresentationUtils::ValueSize(representation());
+      if (value_size <= compiler::target::kWordSize) {
+        const Register result = locs()->out(0).reg();
+        __ LoadFieldFromOffset(
+            result, instance_reg, OffsetInBytes(),
+            RepresentationUtils::OperandSize(representation()));
+      } else {
+        auto const result_pair = locs()->out(0).AsPairLocation();
+        const Register result_lo = result_pair->At(0).reg();
+        const Register result_hi = result_pair->At(1).reg();
+        __ LoadFieldFromOffset(result_lo, instance_reg, OffsetInBytes());
+        __ LoadFieldFromOffset(result_hi, instance_reg,
+                               OffsetInBytes() + compiler::target::kWordSize);
+      }
+    } else {
+      const FpuRegister result = locs()->out(0).fpu_reg();
+      const intptr_t cid = slot().field().guarded_cid();
+      switch (cid) {
+        case kDoubleCid:
+          __ LoadUnboxedDouble(result, instance_reg,
+                               OffsetInBytes() - kHeapObjectTag);
+          break;
+        case kFloat32x4Cid:
+        case kFloat64x2Cid:
+          __ LoadUnboxedSimd128(result, instance_reg,
+                                OffsetInBytes() - kHeapObjectTag);
+          break;
+        default:
+          UNREACHABLE();
+      }
+    }
+    return;
+  }
+
+  // Tagged load.
+  const Register result = locs()->out(0).reg();
+  if (slot().is_compressed()) {
+    __ LoadCompressedFieldFromOffset(result, instance_reg, OffsetInBytes());
+  } else {
+    __ LoadFieldFromOffset(result, instance_reg, OffsetInBytes());
+  }
+
+  if (calls_initializer()) {
+    EmitNativeCodeForInitializerCall(compiler);
+  }
+}
+
 void LoadFieldInstr::EmitNativeCodeForInitializerCall(
     FlowGraphCompiler* compiler) {
   ASSERT(calls_initializer());
@@ -6268,6 +6351,7 @@
     intptr_t array_cid) {
   switch (array_cid) {
     case kImmutableArrayCid:
+    case kRecordCid:
     case kTypeArgumentsCid:
       return kTagged;
     case kExternalOneByteStringCid:
@@ -6379,7 +6463,7 @@
 }
 
 bool Utf8ScanInstr::IsScanFlagsUnboxed() const {
-  return scan_flags_field_.IsUnboxed();
+  return scan_flags_field_.is_unboxed();
 }
 
 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr(
@@ -6862,6 +6946,166 @@
   compiler->assembler()->StoreMemoryValue(value_reg, base_reg, offset_);
 }
 
+LocationSummary* StoreFieldInstr::MakeLocationSummary(Zone* zone,
+                                                      bool opt) const {
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+
+  summary->set_in(kInstancePos, Location::RequiresRegister());
+  if (slot().representation() != kTagged) {
+    if (RepresentationUtils::IsUnboxedInteger(slot().representation())) {
+      const size_t value_size =
+          RepresentationUtils::ValueSize(slot().representation());
+      if (value_size <= compiler::target::kWordSize) {
+        summary->set_in(kValuePos, Location::RequiresRegister());
+      } else {
+        ASSERT(value_size == 2 * compiler::target::kWordSize);
+        summary->set_in(kValuePos,
+                        Location::Pair(Location::RequiresRegister(),
+                                       Location::RequiresRegister()));
+      }
+    } else {
+      summary->set_in(kValuePos, Location::RequiresFpuRegister());
+    }
+  } else {
+    Location value_loc;
+    if (ShouldEmitStoreBarrier()) {
+      summary->set_in(kValuePos,
+                      kWriteBarrierValueReg != kNoRegister
+                          ? Location::RegisterLocation(kWriteBarrierValueReg)
+                          : Location::WritableRegister());
+    } else {
+#if defined(TARGET_ARCH_IA32)
+      // IA32 supports emitting `mov mem, Imm32` even for heap
+      // pointer immediates.
+      summary->set_in(kValuePos, LocationRegisterOrConstant(value()));
+#elif defined(TARGET_ARCH_X64)
+      // X64 supports emitting `mov mem, Imm32` only with non-pointer
+      // immediate.
+      summary->set_in(kValuePos, LocationRegisterOrSmiConstant(value()));
+#elif defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_RISCV32) ||            \
+    defined(TARGET_ARCH_RISCV64)
+      // ARM64 and RISC-V have dedicated zero and null registers which can be
+      // used in store instructions.
+      Location value_loc = Location::RequiresRegister();
+      if (auto constant = value()->definition()->AsConstant()) {
+        const auto& value = constant->value();
+        if (value.IsNull() ||
+            (value.IsSmi() && Smi::Cast(value).Value() == 0)) {
+          value_loc = Location::Constant(constant);
+        }
+      }
+      summary->set_in(kValuePos, value_loc);
+#else
+      // No support for moving immediate to memory directly.
+      summary->set_in(kValuePos, Location::RequiresRegister());
+#endif
+    }
+  }
+  return summary;
+}
+
+void StoreFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register instance_reg = locs()->in(kInstancePos).reg();
+  const intptr_t offset_in_bytes = OffsetInBytes();
+  ASSERT(offset_in_bytes > 0);  // Field is finalized and points after header.
+
+  if (slot().representation() != kTagged) {
+    // Unboxed field.
+    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
+    if (RepresentationUtils::IsUnboxedInteger(slot().representation())) {
+      const size_t value_size =
+          RepresentationUtils::ValueSize(slot().representation());
+      if (value_size <= compiler::target::kWordSize) {
+        const Register value = locs()->in(kValuePos).reg();
+        __ StoreFieldToOffset(
+            value, instance_reg, offset_in_bytes,
+            RepresentationUtils::OperandSize(slot().representation()));
+      } else {
+        auto const value_pair = locs()->in(kValuePos).AsPairLocation();
+        const Register value_lo = value_pair->At(0).reg();
+        const Register value_hi = value_pair->At(1).reg();
+        __ StoreFieldToOffset(value_lo, instance_reg, offset_in_bytes);
+        __ StoreFieldToOffset(value_hi, instance_reg,
+                              offset_in_bytes + compiler::target::kWordSize);
+      }
+    } else {
+      // This is an FPU store.
+      const intptr_t cid = slot().field().guarded_cid();
+      const FpuRegister value = locs()->in(kValuePos).fpu_reg();
+      switch (cid) {
+        case kDoubleCid:
+          __ StoreUnboxedDouble(value, instance_reg,
+                                offset_in_bytes - kHeapObjectTag);
+          return;
+        case kFloat32x4Cid:
+        case kFloat64x2Cid:
+          __ StoreUnboxedSimd128(value, instance_reg,
+                                 offset_in_bytes - kHeapObjectTag);
+          return;
+        default:
+          UNREACHABLE();
+      }
+    }
+    return;
+  }
+
+  // Store of a tagged pointer.
+  const bool compressed = slot().is_compressed();
+  if (ShouldEmitStoreBarrier()) {
+    Register value_reg = locs()->in(kValuePos).reg();
+    if (!compressed) {
+      __ StoreIntoObjectOffset(instance_reg, offset_in_bytes, value_reg,
+                               CanValueBeSmi(), memory_order_);
+    } else {
+#if defined(DART_COMPRESSED_POINTERS)
+      __ StoreCompressedIntoObjectOffset(instance_reg, offset_in_bytes,
+                                         value_reg, CanValueBeSmi(),
+                                         memory_order_);
+#else
+      UNREACHABLE();
+#endif
+    }
+  } else {
+    if (locs()->in(kValuePos).IsConstant()) {
+#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32) ||                   \
+    defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_RISCV32) ||              \
+    defined(TARGET_ARCH_RISCV64)
+      const auto& value = locs()->in(kValuePos).constant();
+      if (!compressed) {
+        __ StoreIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes, value,
+                                          memory_order_);
+      } else {
+#if defined(DART_COMPRESSED_POINTERS)
+        __ StoreCompressedIntoObjectOffsetNoBarrier(
+            instance_reg, offset_in_bytes, value, memory_order_);
+#else
+        UNREACHABLE();
+#endif
+      }
+      return;
+#else
+      UNREACHABLE();
+#endif
+    }
+
+    Register value_reg = locs()->in(kValuePos).reg();
+    if (!compressed) {
+      __ StoreIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes,
+                                        value_reg, memory_order_);
+    } else {
+#if defined(DART_COMPRESSED_POINTERS)
+      __ StoreCompressedIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes,
+                                                  value_reg, memory_order_);
+#else
+      UNREACHABLE();
+#endif
+    }
+  }
+}
+
 const Code& ReturnInstr::GetReturnStub(FlowGraphCompiler* compiler) const {
   const Function& function = compiler->parsed_function().function();
   ASSERT(function.IsSuspendableFunction());
@@ -7401,6 +7645,26 @@
 #endif
 }
 
+LocationSummary* AllocateRecordInstr::MakeLocationSummary(Zone* zone,
+                                                          bool opt) const {
+  const intptr_t kNumInputs = 0;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
+  locs->set_out(0, Location::RegisterLocation(AllocateRecordABI::kResultReg));
+  return locs;
+}
+
+void AllocateRecordInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Code& stub = Code::ZoneHandle(
+      compiler->zone(),
+      compiler->isolate_group()->object_store()->allocate_record_stub());
+  __ LoadImmediate(AllocateRecordABI::kNumFieldsReg, num_fields());
+  __ LoadObject(AllocateRecordABI::kFieldNamesReg, field_names());
+  compiler->GenerateStubCall(source(), stub, UntaggedPcDescriptors::kOther,
+                             locs(), deopt_id(), env());
+}
+
 #undef __
 
 }  // namespace dart
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 5ac2995..b4506a6 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -457,6 +457,7 @@
   M(CreateArray, _)                                                            \
   M(AllocateObject, _)                                                         \
   M(AllocateClosure, _)                                                        \
+  M(AllocateRecord, _)                                                         \
   M(AllocateTypedData, _)                                                      \
   M(LoadField, _)                                                              \
   M(LoadUntagged, kNoGC)                                                       \
@@ -2823,8 +2824,8 @@
   virtual Representation representation() const { return representation_; }
 
   virtual Representation RequiredInputRepresentation(intptr_t index) const {
-    ASSERT(index == 0);
-    return representation();
+    UNREACHABLE();
+    return kTagged;
   }
 
   virtual bool ComputeCanDeoptimize() const { return false; }
@@ -5895,12 +5896,10 @@
                         kind) {}
 
   virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
-    // In AOT unbox is done based on TFA, therefore it was proven to be correct
-    // and it can never deoptimize.
-    return (slot().representation() != kTagged ||
-            (IsUnboxedDartFieldStore() && CompilerState::Current().is_aot()))
-               ? kNotSpeculative
-               : kGuardInputs;
+    // Slots are unboxed based on statically inferrable type information.
+    // Either sound non-nullable static types (JIT) or global type flow analysis
+    // results (AOT).
+    return slot().representation() != kTagged ? kNotSpeculative : kGuardInputs;
   }
 
   DECLARE_INSTRUCTION(StoreField)
@@ -5936,9 +5935,7 @@
     emit_store_barrier_ = value;
   }
 
-  virtual bool CanTriggerGC() const {
-    return IsUnboxedDartFieldStore() || IsPotentialUnboxedDartFieldStore();
-  }
+  virtual bool CanTriggerGC() const { return false; }
 
   virtual bool ComputeCanDeoptimize() const { return false; }
 
@@ -5950,15 +5947,6 @@
   // are marked as having no side-effects.
   virtual bool HasUnknownSideEffects() const { return false; }
 
-  // Returns whether this instruction is an unboxed store into a _boxed_ Dart
-  // field. Unboxed Dart fields are handled similar to unboxed native fields.
-  bool IsUnboxedDartFieldStore() const;
-
-  // Returns whether this instruction is an potential unboxed store into a
-  // _boxed_ Dart field. Unboxed Dart fields are handled similar to unboxed
-  // native fields.
-  bool IsPotentialUnboxedDartFieldStore() const;
-
   virtual Representation RequiredInputRepresentation(intptr_t index) const;
 
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
@@ -6992,6 +6980,46 @@
   DISALLOW_COPY_AND_ASSIGN(AllocateUninitializedContextInstr);
 };
 
+// Allocates and null initializes a record object.
+class AllocateRecordInstr : public TemplateAllocation<0> {
+ public:
+  AllocateRecordInstr(const InstructionSource& source,
+                      intptr_t num_fields,
+                      const Array& field_names,
+                      intptr_t deopt_id)
+      : TemplateAllocation(source, deopt_id),
+        num_fields_(num_fields),
+        field_names_(field_names) {
+    ASSERT(field_names.IsNotTemporaryScopedHandle());
+    ASSERT(field_names.IsCanonical());
+  }
+
+  DECLARE_INSTRUCTION(AllocateRecord)
+  virtual CompileType ComputeType() const;
+
+  intptr_t num_fields() const { return num_fields_; }
+  const Array& field_names() const { return field_names_; }
+
+  virtual bool HasUnknownSideEffects() const { return false; }
+
+  virtual bool WillAllocateNewOrRemembered() const {
+    return Heap::IsAllocatableInNewSpace(
+        compiler::target::Record::InstanceSize(num_fields_));
+  }
+
+#define FIELD_LIST(F)                                                          \
+  F(const intptr_t, num_fields_)                                               \
+  F(const Array&, field_names_)
+
+  DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(AllocateRecordInstr,
+                                          TemplateAllocation,
+                                          FIELD_LIST)
+#undef FIELD_LIST
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AllocateRecordInstr);
+};
+
 // This instruction captures the state of the object which had its allocation
 // removed during the AllocationSinking pass.
 // It does not produce any real code only deoptimization information.
@@ -7320,15 +7348,6 @@
 
   virtual Representation representation() const;
 
-  // Returns whether this instruction is an unboxed load from a _boxed_ Dart
-  // field. Unboxed Dart fields are handled similar to unboxed native fields.
-  bool IsUnboxedDartFieldLoad() const;
-
-  // Returns whether this instruction is an potential unboxed load from a
-  // _boxed_ Dart field. Unboxed Dart fields are handled similar to unboxed
-  // native fields.
-  bool IsPotentialUnboxedDartFieldLoad() const;
-
   DECLARE_INSTRUCTION(LoadField)
   DECLARE_ATTRIBUTES(&slot())
 
@@ -7361,9 +7380,7 @@
 
   virtual bool AllowsCSE() const { return slot_.is_immutable(); }
 
-  virtual bool CanTriggerGC() const {
-    return calls_initializer() || IsPotentialUnboxedDartFieldLoad();
-  }
+  virtual bool CanTriggerGC() const { return calls_initializer(); }
 
   virtual bool AttributesEqual(const Instruction& other) const;
 
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index d1360fe..87597ee 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -7,6 +7,7 @@
 
 #include "vm/compiler/backend/il.h"
 
+#include "platform/memory_sanitizer.h"
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/backend/locations.h"
@@ -1457,6 +1458,9 @@
 
   // Reserve space for the arguments that go on the stack (if any), then align.
   __ ReserveAlignedFrameSpace(marshaller_.RequiredStackSpaceInBytes());
+#if defined(USING_MEMORY_SANITIZER)
+  UNIMPLEMENTED();
+#endif
 
   EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp1, temp2);
 
@@ -2162,7 +2166,7 @@
       const Register result = locs()->out(0).reg();
       ASSERT(representation() == kTagged);
       ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid) ||
-             (class_id() == kTypeArgumentsCid));
+             (class_id() == kTypeArgumentsCid) || (class_id() == kRecordCid));
       __ ldr(result, element_address);
       break;
     }
@@ -2829,286 +2833,6 @@
   }
 }
 
-LocationSummary* StoreFieldInstr::MakeLocationSummary(Zone* zone,
-                                                      bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps =
-      ((IsUnboxedDartFieldStore() && opt)
-           ? (FLAG_precompiled_mode ? 0 : 2)
-           : (IsPotentialUnboxedDartFieldStore() ? 3 : 0));
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps,
-      (!FLAG_precompiled_mode &&
-       ((IsUnboxedDartFieldStore() && opt && is_initialization()) ||
-        IsPotentialUnboxedDartFieldStore()))
-          ? LocationSummary::kCallOnSlowPath
-          : LocationSummary::kNoCall);
-
-  summary->set_in(kInstancePos, Location::RequiresRegister());
-  if (slot().representation() != kTagged) {
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    const size_t value_size =
-        RepresentationUtils::ValueSize(slot().representation());
-    if (value_size <= compiler::target::kWordSize) {
-      summary->set_in(kValuePos, Location::RequiresRegister());
-    } else {
-      ASSERT(value_size <= 2 * compiler::target::kWordSize);
-      summary->set_in(kValuePos, Location::Pair(Location::RequiresRegister(),
-                                                Location::RequiresRegister()));
-    }
-  } else if (IsUnboxedDartFieldStore() && opt) {
-    summary->set_in(kValuePos, Location::RequiresFpuRegister());
-    if (!FLAG_precompiled_mode) {
-      summary->set_temp(0, Location::RequiresRegister());
-      summary->set_temp(1, Location::RequiresRegister());
-    }
-  } else if (IsPotentialUnboxedDartFieldStore()) {
-    summary->set_in(kValuePos, ShouldEmitStoreBarrier()
-                                   ? Location::WritableRegister()
-                                   : Location::RequiresRegister());
-    summary->set_temp(0, Location::RequiresRegister());
-    summary->set_temp(1, Location::RequiresRegister());
-    summary->set_temp(2, opt ? Location::RequiresFpuRegister()
-                             : Location::FpuRegisterLocation(Q1));
-  } else {
-    summary->set_in(kValuePos,
-                    ShouldEmitStoreBarrier()
-                        ? Location::RegisterLocation(kWriteBarrierValueReg)
-                        : LocationRegisterOrConstant(value()));
-  }
-  return summary;
-}
-
-static void EnsureMutableBox(FlowGraphCompiler* compiler,
-                             StoreFieldInstr* instruction,
-                             Register box_reg,
-                             const Class& cls,
-                             Register instance_reg,
-                             intptr_t offset,
-                             Register temp) {
-  compiler::Label done;
-  __ ldr(box_reg, compiler::FieldAddress(instance_reg, offset));
-  __ CompareObject(box_reg, Object::null_object());
-  __ b(&done, NE);
-
-  BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
-
-  __ MoveRegister(temp, box_reg);
-  __ StoreIntoObjectOffset(instance_reg, offset, temp,
-                           compiler::Assembler::kValueIsNotSmi);
-  __ Bind(&done);
-}
-
-void StoreFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(compiler::target::UntaggedObject::kClassIdTagSize == 16);
-  ASSERT(sizeof(UntaggedField::guarded_cid_) == 2);
-  ASSERT(sizeof(UntaggedField::is_nullable_) == 2);
-
-  compiler::Label skip_store;
-
-  const Register instance_reg = locs()->in(kInstancePos).reg();
-  const intptr_t offset_in_bytes = OffsetInBytes();
-  ASSERT(offset_in_bytes > 0);  // Field is finalized and points after header.
-
-  if (slot().representation() != kTagged) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    auto const rep = slot().representation();
-    ASSERT(RepresentationUtils::IsUnboxedInteger(rep));
-    const size_t value_size = RepresentationUtils::ValueSize(rep);
-    __ Comment("NativeUnboxedStoreFieldInstr");
-    if (value_size <= compiler::target::kWordSize) {
-      const Register value = locs()->in(kValuePos).reg();
-      __ StoreFieldToOffset(value, instance_reg, offset_in_bytes,
-                            RepresentationUtils::OperandSize(rep));
-    } else {
-      auto const in_pair = locs()->in(kValuePos).AsPairLocation();
-      const Register in_lo = in_pair->At(0).reg();
-      const Register in_hi = in_pair->At(1).reg();
-      const intptr_t offset_lo = OffsetInBytes() - kHeapObjectTag;
-      const intptr_t offset_hi = offset_lo + compiler::target::kWordSize;
-      __ StoreToOffset(in_lo, instance_reg, offset_lo);
-      __ StoreToOffset(in_hi, instance_reg, offset_hi);
-    }
-    return;
-  }
-
-  if (IsUnboxedDartFieldStore() && compiler->is_optimizing()) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    const intptr_t cid = slot().field().UnboxedFieldCid();
-    const DRegister value = EvenDRegisterOf(locs()->in(kValuePos).fpu_reg());
-
-    if (FLAG_precompiled_mode) {
-      switch (cid) {
-        case kDoubleCid:
-          __ Comment("UnboxedDoubleStoreFieldInstr");
-          __ StoreDToOffset(value, instance_reg,
-                            offset_in_bytes - kHeapObjectTag);
-          return;
-        case kFloat32x4Cid:
-          __ Comment("UnboxedFloat32x4StoreFieldInstr");
-          __ StoreMultipleDToOffset(value, 2, instance_reg,
-                                    offset_in_bytes - kHeapObjectTag);
-          return;
-        case kFloat64x2Cid:
-          __ Comment("UnboxedFloat64x2StoreFieldInstr");
-          __ StoreMultipleDToOffset(value, 2, instance_reg,
-                                    offset_in_bytes - kHeapObjectTag);
-          return;
-        default:
-          UNREACHABLE();
-      }
-    }
-
-    const Register temp = locs()->temp(0).reg();
-    const Register temp2 = locs()->temp(1).reg();
-
-    if (is_initialization()) {
-      const Class* cls = NULL;
-      switch (cid) {
-        case kDoubleCid:
-          cls = &compiler->double_class();
-          break;
-        case kFloat32x4Cid:
-          cls = &compiler->float32x4_class();
-          break;
-        case kFloat64x2Cid:
-          cls = &compiler->float64x2_class();
-          break;
-        default:
-          UNREACHABLE();
-      }
-
-      BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
-      __ MoveRegister(temp2, temp);
-      __ StoreIntoObjectOffset(instance_reg, offset_in_bytes, temp2,
-                               compiler::Assembler::kValueIsNotSmi);
-    } else {
-      __ ldr(temp, compiler::FieldAddress(instance_reg, offset_in_bytes));
-    }
-    switch (cid) {
-      case kDoubleCid:
-        __ Comment("UnboxedDoubleStoreFieldInstr");
-        __ StoreDToOffset(
-            value, temp,
-            compiler::target::Double::value_offset() - kHeapObjectTag);
-        break;
-      case kFloat32x4Cid:
-        __ Comment("UnboxedFloat32x4StoreFieldInstr");
-        __ StoreMultipleDToOffset(
-            value, 2, temp,
-            compiler::target::Float32x4::value_offset() - kHeapObjectTag);
-        break;
-      case kFloat64x2Cid:
-        __ Comment("UnboxedFloat64x2StoreFieldInstr");
-        __ StoreMultipleDToOffset(
-            value, 2, temp,
-            compiler::target::Float64x2::value_offset() - kHeapObjectTag);
-        break;
-      default:
-        UNREACHABLE();
-    }
-
-    return;
-  }
-
-  if (IsPotentialUnboxedDartFieldStore()) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    const Register value_reg = locs()->in(kValuePos).reg();
-    const Register temp = locs()->temp(0).reg();
-    const Register temp2 = locs()->temp(1).reg();
-    const DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg());
-
-    if (ShouldEmitStoreBarrier()) {
-      // Value input is a writable register and should be manually preserved
-      // across allocation slow-path.
-      locs()->live_registers()->Add(locs()->in(kValuePos), kTagged);
-    }
-
-    compiler::Label store_pointer;
-    compiler::Label store_double;
-    compiler::Label store_float32x4;
-    compiler::Label store_float64x2;
-
-    __ LoadObject(temp, Field::ZoneHandle(Z, slot().field().Original()));
-
-    __ ldrh(temp2, compiler::FieldAddress(
-                       temp, compiler::target::Field::is_nullable_offset()));
-    __ CompareImmediate(temp2, kNullCid);
-    __ b(&store_pointer, EQ);
-
-    __ ldrb(temp2, compiler::FieldAddress(
-                       temp, compiler::target::Field::kind_bits_offset()));
-    __ tst(temp2, compiler::Operand(1 << Field::kUnboxingCandidateBit));
-    __ b(&store_pointer, EQ);
-
-    __ ldrh(temp2, compiler::FieldAddress(
-                       temp, compiler::target::Field::guarded_cid_offset()));
-    __ CompareImmediate(temp2, kDoubleCid);
-    __ b(&store_double, EQ);
-
-    __ ldrh(temp2, compiler::FieldAddress(
-                       temp, compiler::target::Field::guarded_cid_offset()));
-    __ CompareImmediate(temp2, kFloat32x4Cid);
-    __ b(&store_float32x4, EQ);
-
-    __ ldrh(temp2, compiler::FieldAddress(
-                       temp, compiler::target::Field::guarded_cid_offset()));
-    __ CompareImmediate(temp2, kFloat64x2Cid);
-    __ b(&store_float64x2, EQ);
-
-    // Fall through.
-    __ b(&store_pointer);
-
-    if (!compiler->is_optimizing()) {
-      locs()->live_registers()->Add(locs()->in(kInstancePos));
-      locs()->live_registers()->Add(locs()->in(kValuePos));
-    }
-
-    {
-      __ Bind(&store_double);
-      EnsureMutableBox(compiler, this, temp, compiler->double_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ CopyDoubleField(temp, value_reg, TMP, temp2, fpu_temp);
-      __ b(&skip_store);
-    }
-
-    {
-      __ Bind(&store_float32x4);
-      EnsureMutableBox(compiler, this, temp, compiler->float32x4_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ CopyFloat32x4Field(temp, value_reg, TMP, temp2, fpu_temp);
-      __ b(&skip_store);
-    }
-
-    {
-      __ Bind(&store_float64x2);
-      EnsureMutableBox(compiler, this, temp, compiler->float64x2_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ CopyFloat64x2Field(temp, value_reg, TMP, temp2, fpu_temp);
-      __ b(&skip_store);
-    }
-
-    __ Bind(&store_pointer);
-  }
-
-  if (ShouldEmitStoreBarrier()) {
-    const Register value_reg = locs()->in(kValuePos).reg();
-    __ StoreIntoObjectOffset(instance_reg, offset_in_bytes, value_reg,
-                             CanValueBeSmi(), memory_order_);
-  } else {
-    if (locs()->in(kValuePos).IsConstant()) {
-      __ StoreIntoObjectNoBarrierOffset(instance_reg, offset_in_bytes,
-                                        locs()->in(kValuePos).constant(),
-                                        memory_order_);
-    } else {
-      const Register value_reg = locs()->in(kValuePos).reg();
-      __ StoreIntoObjectNoBarrierOffset(instance_reg, offset_in_bytes,
-                                        value_reg, memory_order_);
-    }
-  }
-  __ Bind(&skip_store);
-}
-
 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -3263,252 +2987,6 @@
   __ Bind(&done);
 }
 
-LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone,
-                                                     bool opt) const {
-  const intptr_t kNumInputs = 1;
-  LocationSummary* locs = nullptr;
-  if (slot().representation() != kTagged) {
-    ASSERT(!calls_initializer());
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    const size_t value_size =
-        RepresentationUtils::ValueSize(slot().representation());
-
-    const intptr_t kNumTemps = 0;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    if (value_size <= compiler::target::kWordSize) {
-      locs->set_out(0, Location::RequiresRegister());
-    } else {
-      ASSERT(value_size <= 2 * compiler::target::kWordSize);
-      locs->set_out(0, Location::Pair(Location::RequiresRegister(),
-                                      Location::RequiresRegister()));
-    }
-
-  } else if (IsUnboxedDartFieldLoad() && opt) {
-    ASSERT(!calls_initializer());
-    ASSERT(!slot().field().is_non_nullable_integer());
-
-    const intptr_t kNumTemps = FLAG_precompiled_mode ? 0 : 1;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    if (!FLAG_precompiled_mode) {
-      locs->set_temp(0, Location::RequiresRegister());
-    }
-    locs->set_out(0, Location::RequiresFpuRegister());
-
-  } else if (IsPotentialUnboxedDartFieldLoad()) {
-    ASSERT(!calls_initializer());
-    const intptr_t kNumTemps = 3;
-    locs = new (zone) LocationSummary(zone, kNumInputs, kNumTemps,
-                                      LocationSummary::kCallOnSlowPath);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_temp(0, opt ? Location::RequiresFpuRegister()
-                          : Location::FpuRegisterLocation(Q1));
-    locs->set_temp(1, Location::RequiresRegister());
-    locs->set_temp(2, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-
-  } else if (calls_initializer()) {
-    if (throw_exception_on_initialization()) {
-      const bool using_shared_stub = UseSharedSlowPathStub(opt);
-      const intptr_t kNumTemps = using_shared_stub ? 1 : 0;
-      locs = new (zone) LocationSummary(
-          zone, kNumInputs, kNumTemps,
-          using_shared_stub ? LocationSummary::kCallOnSharedSlowPath
-                            : LocationSummary::kCallOnSlowPath);
-      if (using_shared_stub) {
-        locs->set_temp(0, Location::RegisterLocation(
-                              LateInitializationErrorABI::kFieldReg));
-      }
-      locs->set_in(0, Location::RequiresRegister());
-      locs->set_out(0, Location::RequiresRegister());
-    } else {
-      const intptr_t kNumTemps = 0;
-      locs = new (zone)
-          LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-      locs->set_in(
-          0, Location::RegisterLocation(InitInstanceFieldABI::kInstanceReg));
-      locs->set_out(
-          0, Location::RegisterLocation(InitInstanceFieldABI::kResultReg));
-    }
-  } else {
-    const intptr_t kNumTemps = 0;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-  }
-  return locs;
-}
-
-void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(compiler::target::UntaggedObject::kClassIdTagSize == 16);
-  ASSERT(sizeof(UntaggedField::guarded_cid_) == 2);
-  ASSERT(sizeof(UntaggedField::is_nullable_) == 2);
-
-  const Register instance_reg = locs()->in(0).reg();
-  if (slot().representation() != kTagged) {
-    ASSERT(!calls_initializer());
-    auto const rep = slot().representation();
-    const size_t value_size = RepresentationUtils::ValueSize(rep);
-    __ Comment("NativeUnboxedLoadFieldInstr");
-    if (value_size <= compiler::target::kWordSize) {
-      auto const result = locs()->out(0).reg();
-      __ LoadFieldFromOffset(result, instance_reg, OffsetInBytes(),
-                             RepresentationUtils::OperandSize(rep));
-    } else {
-      auto const out_pair = locs()->out(0).AsPairLocation();
-      const Register out_lo = out_pair->At(0).reg();
-      const Register out_hi = out_pair->At(1).reg();
-      const intptr_t offset_lo = OffsetInBytes() - kHeapObjectTag;
-      const intptr_t offset_hi = offset_lo + compiler::target::kWordSize;
-      __ LoadFromOffset(out_lo, instance_reg, offset_lo);
-      __ LoadFromOffset(out_hi, instance_reg, offset_hi);
-    }
-    return;
-  }
-
-  if (IsUnboxedDartFieldLoad() && compiler->is_optimizing()) {
-    ASSERT_EQUAL(slot().representation(), kTagged);
-    ASSERT(!calls_initializer());
-    ASSERT(!slot().field().is_non_nullable_integer());
-    const intptr_t cid = slot().field().UnboxedFieldCid();
-    const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
-
-    if (FLAG_precompiled_mode) {
-      switch (cid) {
-        case kDoubleCid:
-          __ Comment("UnboxedDoubleLoadFieldInstr");
-          __ LoadDFromOffset(result, instance_reg,
-                             OffsetInBytes() - kHeapObjectTag);
-          return;
-        case kFloat32x4Cid:
-          __ Comment("UnboxedFloat32x4LoadFieldInstr");
-          __ LoadMultipleDFromOffset(result, 2, instance_reg,
-                                     OffsetInBytes() - kHeapObjectTag);
-          return;
-        case kFloat64x2Cid:
-          __ Comment("UnboxedFloat64x2LoadFieldInstr");
-          __ LoadMultipleDFromOffset(result, 2, instance_reg,
-                                     OffsetInBytes() - kHeapObjectTag);
-          return;
-        default:
-          UNREACHABLE();
-      }
-    }
-
-    const Register temp = locs()->temp(0).reg();
-    __ LoadFieldFromOffset(temp, instance_reg, OffsetInBytes());
-    switch (cid) {
-      case kDoubleCid:
-        __ Comment("UnboxedDoubleLoadFieldInstr");
-        __ LoadDFromOffset(
-            result, temp,
-            compiler::target::Double::value_offset() - kHeapObjectTag);
-        break;
-      case kFloat32x4Cid:
-        __ Comment("UnboxedFloat32x4LoadFieldInstr");
-        __ LoadMultipleDFromOffset(
-            result, 2, temp,
-            compiler::target::Float32x4::value_offset() - kHeapObjectTag);
-        break;
-      case kFloat64x2Cid:
-        __ Comment("UnboxedFloat64x2LoadFieldInstr");
-        __ LoadMultipleDFromOffset(
-            result, 2, temp,
-            compiler::target::Float64x2::value_offset() - kHeapObjectTag);
-        break;
-      default:
-        UNREACHABLE();
-    }
-    return;
-  }
-
-  compiler::Label done;
-  const Register result_reg = locs()->out(0).reg();
-  if (IsPotentialUnboxedDartFieldLoad()) {
-    ASSERT_EQUAL(slot().representation(), kTagged);
-    ASSERT(!calls_initializer());
-    const DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg());
-    const Register temp = locs()->temp(1).reg();
-    const Register temp2 = locs()->temp(2).reg();
-
-    compiler::Label load_pointer;
-    compiler::Label load_double;
-    compiler::Label load_float32x4;
-    compiler::Label load_float64x2;
-
-    __ LoadObject(result_reg, Field::ZoneHandle(slot().field().Original()));
-
-    compiler::FieldAddress field_cid_operand(
-        result_reg, compiler::target::Field::guarded_cid_offset());
-    compiler::FieldAddress field_nullability_operand(
-        result_reg, compiler::target::Field::is_nullable_offset());
-
-    __ ldrh(temp, field_nullability_operand);
-    __ CompareImmediate(temp, kNullCid);
-    __ b(&load_pointer, EQ);
-
-    __ ldrh(temp, field_cid_operand);
-    __ CompareImmediate(temp, kDoubleCid);
-    __ b(&load_double, EQ);
-
-    __ ldrh(temp, field_cid_operand);
-    __ CompareImmediate(temp, kFloat32x4Cid);
-    __ b(&load_float32x4, EQ);
-
-    __ ldrh(temp, field_cid_operand);
-    __ CompareImmediate(temp, kFloat64x2Cid);
-    __ b(&load_float64x2, EQ);
-
-    // Fall through.
-    __ b(&load_pointer);
-
-    if (!compiler->is_optimizing()) {
-      locs()->live_registers()->Add(locs()->in(0));
-    }
-
-    {
-      __ Bind(&load_double);
-      BoxAllocationSlowPath::Allocate(compiler, this, compiler->double_class(),
-                                      result_reg, temp);
-      __ ldr(temp, compiler::FieldAddress(instance_reg, OffsetInBytes()));
-      __ CopyDoubleField(result_reg, temp, TMP, temp2, value);
-      __ b(&done);
-    }
-
-    {
-      __ Bind(&load_float32x4);
-      BoxAllocationSlowPath::Allocate(
-          compiler, this, compiler->float32x4_class(), result_reg, temp);
-      __ ldr(temp, compiler::FieldAddress(instance_reg, OffsetInBytes()));
-      __ CopyFloat32x4Field(result_reg, temp, TMP, temp2, value);
-      __ b(&done);
-    }
-
-    {
-      __ Bind(&load_float64x2);
-      BoxAllocationSlowPath::Allocate(
-          compiler, this, compiler->float64x2_class(), result_reg, temp);
-      __ ldr(temp, compiler::FieldAddress(instance_reg, OffsetInBytes()));
-      __ CopyFloat64x2Field(result_reg, temp, TMP, temp2, value);
-      __ b(&done);
-    }
-
-    __ Bind(&load_pointer);
-  }
-
-  __ LoadFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
-
-  if (calls_initializer()) {
-    EmitNativeCodeForInitializerCall(compiler);
-  }
-
-  __ Bind(&done);
-}
-
 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
     Zone* zone,
     bool opt) const {
@@ -6894,13 +6372,11 @@
     // The unboxed int64 argument is passed through a dedicated slot in Thread.
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
-    __ StoreToOffset(
-        right_lo, THR,
-        compiler::target::Thread::unboxed_int64_runtime_arg_offset());
-    __ StoreToOffset(
-        right_hi, THR,
-        compiler::target::Thread::unboxed_int64_runtime_arg_offset() +
-            compiler::target::kWordSize);
+    __ StoreToOffset(right_lo, THR,
+                     compiler::target::Thread::unboxed_runtime_arg_offset());
+    __ StoreToOffset(right_hi, THR,
+                     compiler::target::Thread::unboxed_runtime_arg_offset() +
+                         compiler::target::kWordSize);
   }
 };
 
@@ -7033,13 +6509,11 @@
     // The unboxed int64 argument is passed through a dedicated slot in Thread.
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
-    __ StoreToOffset(
-        right_lo, THR,
-        compiler::target::Thread::unboxed_int64_runtime_arg_offset());
-    __ StoreToOffset(
-        right_hi, THR,
-        compiler::target::Thread::unboxed_int64_runtime_arg_offset() +
-            compiler::target::kWordSize);
+    __ StoreToOffset(right_lo, THR,
+                     compiler::target::Thread::unboxed_runtime_arg_offset());
+    __ StoreToOffset(right_hi, THR,
+                     compiler::target::Thread::unboxed_runtime_arg_offset() +
+                         compiler::target::kWordSize);
   }
 };
 
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index cfc9a53..418ddc7 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -7,6 +7,7 @@
 
 #include "vm/compiler/backend/il.h"
 
+#include "platform/memory_sanitizer.h"
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/backend/locations.h"
@@ -1294,7 +1295,36 @@
   }
 
   // Reserve space for the arguments that go on the stack (if any), then align.
-  __ ReserveAlignedFrameSpace(marshaller_.RequiredStackSpaceInBytes());
+  intptr_t stack_space = marshaller_.RequiredStackSpaceInBytes();
+  __ ReserveAlignedFrameSpace(stack_space);
+#if defined(USING_MEMORY_SANITIZER)
+  {
+    RegisterSet kVolatileRegisterSet(kAbiVolatileCpuRegs & ~(1 << SP),
+                                     kAbiVolatileFpuRegs);
+    __ mov(temp1, SP);
+    __ PushRegisters(kVolatileRegisterSet);
+
+    // Outgoing arguments passed on the stack to the foreign function.
+    __ mov(R0, temp1);
+    __ LoadImmediate(R1, stack_space);
+    __ CallCFunction(
+        compiler::Address(THR, kMsanUnpoisonRuntimeEntry.OffsetFromThread()));
+
+    // Incoming Dart arguments to this trampoline are potentially used as local
+    // handles.
+    __ mov(R0, is_leaf_ ? FPREG : saved_fp_or_sp);
+    __ LoadImmediate(R1, (kParamEndSlotFromFp + InputCount()) * kWordSize);
+    __ CallCFunction(
+        compiler::Address(THR, kMsanUnpoisonRuntimeEntry.OffsetFromThread()));
+
+    // Outgoing arguments passed by register to the foreign function.
+    __ LoadImmediate(R0, InputCount());
+    __ CallCFunction(compiler::Address(
+        THR, kMsanUnpoisonParamRuntimeEntry.OffsetFromThread()));
+
+    __ PopRegisters(kVolatileRegisterSet);
+  }
+#endif
 
   EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp1, temp2);
 
@@ -1652,9 +1682,7 @@
   const Register result = locs()->out(0).reg();
   __ LoadCompressedSmi(result,
                        compiler::FieldAddress(str, String::length_offset()));
-  __ ldr(TMP,
-         compiler::FieldAddress(str, OneByteString::data_offset(),
-                                compiler::kByte),
+  __ ldr(TMP, compiler::FieldAddress(str, OneByteString::data_offset()),
          compiler::kUnsignedByte);
   __ CompareImmediate(result, Smi::RawValue(1));
   __ LoadImmediate(result, -1);
@@ -1904,7 +1932,7 @@
     default:
       ASSERT(representation() == kTagged);
       ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid) ||
-             (class_id() == kTypeArgumentsCid));
+             (class_id() == kTypeArgumentsCid) || (class_id() == kRecordCid));
       __ LoadCompressed(result, element_address);
       break;
   }
@@ -2275,10 +2303,10 @@
   if (emit_full_guard) {
     __ LoadObject(field_reg, Field::ZoneHandle((field().Original())));
 
-    compiler::FieldAddress field_cid_operand(
-        field_reg, Field::guarded_cid_offset(), compiler::kUnsignedTwoBytes);
+    compiler::FieldAddress field_cid_operand(field_reg,
+                                             Field::guarded_cid_offset());
     compiler::FieldAddress field_nullability_operand(
-        field_reg, Field::is_nullable_offset(), compiler::kUnsignedTwoBytes);
+        field_reg, Field::is_nullable_offset());
 
     if (value_cid == kDynamicCid) {
       LoadValueCid(compiler, value_cid_reg, value_reg);
@@ -2460,292 +2488,6 @@
   }
 }
 
-static void EnsureMutableBox(FlowGraphCompiler* compiler,
-                             StoreFieldInstr* instruction,
-                             Register box_reg,
-                             const Class& cls,
-                             Register instance_reg,
-                             intptr_t offset,
-                             Register temp) {
-  compiler::Label done;
-  __ LoadCompressedFieldFromOffset(box_reg, instance_reg, offset);
-  __ CompareObject(box_reg, Object::null_object());
-  __ b(&done, NE);
-  BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
-  __ MoveRegister(temp, box_reg);
-  __ StoreCompressedIntoObjectOffset(instance_reg, offset, temp,
-                                     compiler::Assembler::kValueIsNotSmi);
-  __ Bind(&done);
-}
-
-LocationSummary* StoreFieldInstr::MakeLocationSummary(Zone* zone,
-                                                      bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = (IsUnboxedDartFieldStore() && opt)
-                                 ? (FLAG_precompiled_mode ? 0 : 2)
-                                 : (IsPotentialUnboxedDartFieldStore() ? 2 : 0);
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps,
-      (!FLAG_precompiled_mode &&
-       ((IsUnboxedDartFieldStore() && opt && is_initialization()) ||
-        IsPotentialUnboxedDartFieldStore()))
-          ? LocationSummary::kCallOnSlowPath
-          : LocationSummary::kNoCall);
-
-  summary->set_in(kInstancePos, Location::RequiresRegister());
-  if (slot().representation() != kTagged) {
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    ASSERT(RepresentationUtils::ValueSize(slot().representation()) <=
-           compiler::target::kWordSize);
-    summary->set_in(kValuePos, Location::RequiresRegister());
-  } else if (IsUnboxedDartFieldStore() && opt) {
-    summary->set_in(kValuePos, Location::RequiresFpuRegister());
-    if (FLAG_precompiled_mode) {
-      ConstantInstr* constant = value()->definition()->AsConstant();
-      if (constant != nullptr && constant->HasZeroRepresentation()) {
-        summary->set_in(kValuePos, Location::Constant(constant));
-      }
-    } else {
-      summary->set_temp(0, Location::RequiresRegister());
-      summary->set_temp(1, Location::RequiresRegister());
-    }
-  } else if (IsPotentialUnboxedDartFieldStore()) {
-    summary->set_in(kValuePos, ShouldEmitStoreBarrier()
-                                   ? Location::WritableRegister()
-                                   : Location::RequiresRegister());
-    summary->set_temp(0, Location::RequiresRegister());
-    summary->set_temp(1, Location::RequiresRegister());
-  } else {
-    summary->set_in(kValuePos,
-                    ShouldEmitStoreBarrier()
-                        ? Location::RegisterLocation(kWriteBarrierValueReg)
-                        : LocationRegisterOrConstant(value()));
-  }
-  return summary;
-}
-
-void StoreFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(compiler::target::UntaggedObject::kClassIdTagSize == 16);
-  ASSERT(sizeof(UntaggedField::guarded_cid_) == 2);
-  ASSERT(sizeof(UntaggedField::is_nullable_) == 2);
-
-  compiler::Label skip_store;
-
-  const Register instance_reg = locs()->in(kInstancePos).reg();
-  const intptr_t offset_in_bytes = OffsetInBytes();
-  ASSERT(offset_in_bytes > 0);  // Field is finalized and points after header.
-
-  if (slot().representation() != kTagged) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    const Register value = locs()->in(kValuePos).reg();
-    __ Comment("NativeUnboxedStoreFieldInstr");
-    __ StoreFieldToOffset(
-        value, instance_reg, offset_in_bytes,
-        RepresentationUtils::OperandSize(slot().representation()));
-    return;
-  }
-
-  if (IsUnboxedDartFieldStore() && compiler->is_optimizing()) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    const intptr_t cid = slot().field().UnboxedFieldCid();
-
-    if (FLAG_precompiled_mode) {
-      switch (cid) {
-        case kDoubleCid:
-          __ Comment("UnboxedDoubleStoreFieldInstr");
-          if (locs()->in(kValuePos).IsConstant()) {
-            ASSERT(locs()
-                       ->in(kValuePos)
-                       .constant_instruction()
-                       ->HasZeroRepresentation());
-            __ StoreFieldToOffset(ZR, instance_reg, offset_in_bytes,
-                                  compiler::kEightBytes);
-          } else {
-            __ StoreDFieldToOffset(locs()->in(kValuePos).fpu_reg(),
-                                   instance_reg, offset_in_bytes);
-          }
-          return;
-        case kFloat32x4Cid:
-          __ Comment("UnboxedFloat32x4StoreFieldInstr");
-          __ StoreQFieldToOffset(locs()->in(kValuePos).fpu_reg(), instance_reg,
-                                 offset_in_bytes);
-          return;
-        case kFloat64x2Cid:
-          __ Comment("UnboxedFloat64x2StoreFieldInstr");
-          __ StoreQFieldToOffset(locs()->in(kValuePos).fpu_reg(), instance_reg,
-                                 offset_in_bytes);
-          return;
-        default:
-          UNREACHABLE();
-      }
-    }
-
-    const Register temp = locs()->temp(0).reg();
-    const Register temp2 = locs()->temp(1).reg();
-
-    if (is_initialization()) {
-      const Class* cls = NULL;
-      switch (cid) {
-        case kDoubleCid:
-          cls = &compiler->double_class();
-          break;
-        case kFloat32x4Cid:
-          cls = &compiler->float32x4_class();
-          break;
-        case kFloat64x2Cid:
-          cls = &compiler->float64x2_class();
-          break;
-        default:
-          UNREACHABLE();
-      }
-
-      BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
-      __ MoveRegister(temp2, temp);
-      __ StoreCompressedIntoObjectOffset(instance_reg, offset_in_bytes, temp2,
-                                         compiler::Assembler::kValueIsNotSmi);
-    } else {
-      __ LoadCompressedFieldFromOffset(temp, instance_reg, offset_in_bytes);
-    }
-
-    const VRegister value = locs()->in(kValuePos).fpu_reg();
-    switch (cid) {
-      case kDoubleCid:
-        __ Comment("UnboxedDoubleStoreFieldInstr");
-        __ StoreDFieldToOffset(value, temp, Double::value_offset());
-        break;
-      case kFloat32x4Cid:
-        __ Comment("UnboxedFloat32x4StoreFieldInstr");
-        __ StoreQFieldToOffset(value, temp, Float32x4::value_offset());
-        break;
-      case kFloat64x2Cid:
-        __ Comment("UnboxedFloat64x2StoreFieldInstr");
-        __ StoreQFieldToOffset(value, temp, Float64x2::value_offset());
-        break;
-      default:
-        UNREACHABLE();
-    }
-
-    return;
-  }
-
-  if (IsPotentialUnboxedDartFieldStore()) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    const Register value_reg = locs()->in(kValuePos).reg();
-    const Register temp = locs()->temp(0).reg();
-    const Register temp2 = locs()->temp(1).reg();
-
-    if (ShouldEmitStoreBarrier()) {
-      // Value input is a writable register and should be manually preserved
-      // across allocation slow-path.
-      locs()->live_registers()->Add(locs()->in(kValuePos), kTagged);
-    }
-
-    compiler::Label store_pointer;
-    compiler::Label store_double;
-    compiler::Label store_float32x4;
-    compiler::Label store_float64x2;
-
-    __ LoadObject(temp, Field::ZoneHandle(Z, slot().field().Original()));
-
-    __ LoadFieldFromOffset(temp2, temp, Field::is_nullable_offset(),
-                           compiler::kUnsignedTwoBytes);
-    __ CompareImmediate(temp2, kNullCid);
-    __ b(&store_pointer, EQ);
-
-    __ LoadFromOffset(temp2, temp, Field::kind_bits_offset() - kHeapObjectTag,
-                      compiler::kUnsignedByte);
-    __ tsti(temp2, compiler::Immediate(1 << Field::kUnboxingCandidateBit));
-    __ b(&store_pointer, EQ);
-
-    __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(),
-                           compiler::kUnsignedTwoBytes);
-    __ CompareImmediate(temp2, kDoubleCid);
-    __ b(&store_double, EQ);
-
-    __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(),
-                           compiler::kUnsignedTwoBytes);
-    __ CompareImmediate(temp2, kFloat32x4Cid);
-    __ b(&store_float32x4, EQ);
-
-    __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(),
-                           compiler::kUnsignedTwoBytes);
-    __ CompareImmediate(temp2, kFloat64x2Cid);
-    __ b(&store_float64x2, EQ);
-
-    // Fall through.
-    __ b(&store_pointer);
-
-    if (!compiler->is_optimizing()) {
-      locs()->live_registers()->Add(locs()->in(kInstancePos));
-      locs()->live_registers()->Add(locs()->in(kValuePos));
-    }
-
-    {
-      __ Bind(&store_double);
-      EnsureMutableBox(compiler, this, temp, compiler->double_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ LoadDFieldFromOffset(VTMP, value_reg, Double::value_offset());
-      __ StoreDFieldToOffset(VTMP, temp, Double::value_offset());
-      __ b(&skip_store);
-    }
-
-    {
-      __ Bind(&store_float32x4);
-      EnsureMutableBox(compiler, this, temp, compiler->float32x4_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ LoadQFieldFromOffset(VTMP, value_reg, Float32x4::value_offset());
-      __ StoreQFieldToOffset(VTMP, temp, Float32x4::value_offset());
-      __ b(&skip_store);
-    }
-
-    {
-      __ Bind(&store_float64x2);
-      EnsureMutableBox(compiler, this, temp, compiler->float64x2_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ LoadQFieldFromOffset(VTMP, value_reg, Float64x2::value_offset());
-      __ StoreQFieldToOffset(VTMP, temp, Float64x2::value_offset());
-      __ b(&skip_store);
-    }
-
-    __ Bind(&store_pointer);
-  }
-
-  const bool compressed = slot().is_compressed();
-  if (ShouldEmitStoreBarrier()) {
-    const Register value_reg = locs()->in(kValuePos).reg();
-    if (!compressed) {
-      __ StoreIntoObjectOffset(instance_reg, offset_in_bytes, value_reg,
-                               CanValueBeSmi(), memory_order_);
-    } else {
-      __ StoreCompressedIntoObjectOffset(instance_reg, offset_in_bytes,
-                                         value_reg, CanValueBeSmi(),
-                                         memory_order_);
-    }
-  } else {
-    if (locs()->in(kValuePos).IsConstant()) {
-      const auto& value = locs()->in(kValuePos).constant();
-      if (!compressed) {
-        __ StoreIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes, value,
-                                          memory_order_);
-      } else {
-        __ StoreCompressedIntoObjectOffsetNoBarrier(
-            instance_reg, offset_in_bytes, value, memory_order_);
-      }
-    } else {
-      const Register value_reg = locs()->in(kValuePos).reg();
-      if (!compressed) {
-        __ StoreIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes,
-                                          value_reg, memory_order_);
-      } else {
-        __ StoreCompressedIntoObjectOffsetNoBarrier(
-            instance_reg, offset_in_bytes, value_reg, memory_order_);
-      }
-    }
-  }
-  __ Bind(&skip_store);
-}
-
 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -2827,15 +2569,14 @@
   __ StoreCompressedIntoObjectNoBarrier(
       AllocateArrayABI::kResultReg,
       compiler::FieldAddress(AllocateArrayABI::kResultReg,
-                             Array::type_arguments_offset(),
-                             compiler::kObjectBytes),
+                             Array::type_arguments_offset()),
       AllocateArrayABI::kTypeArgumentsReg);
 
   // Set the length field.
   __ StoreCompressedIntoObjectNoBarrier(
       AllocateArrayABI::kResultReg,
       compiler::FieldAddress(AllocateArrayABI::kResultReg,
-                             Array::length_offset(), compiler::kObjectBytes),
+                             Array::length_offset()),
       AllocateArrayABI::kLengthReg);
 
   // TODO(zra): Use stp once added.
@@ -2852,9 +2593,7 @@
       intptr_t current_offset = 0;
       while (current_offset < array_size) {
         __ StoreCompressedIntoObjectNoBarrier(
-            AllocateArrayABI::kResultReg,
-            compiler::Address(R8, current_offset, compiler::Address::Offset,
-                              compiler::kObjectBytes),
+            AllocateArrayABI::kResultReg, compiler::Address(R8, current_offset),
             NULL_REG);
         current_offset += kCompressedWordSize;
       }
@@ -2863,11 +2602,8 @@
       __ Bind(&init_loop);
       __ CompareRegisters(R8, R3);
       __ b(&end_loop, CS);
-      __ StoreCompressedIntoObjectNoBarrier(
-          AllocateArrayABI::kResultReg,
-          compiler::Address(R8, 0, compiler::Address::Offset,
-                            compiler::kObjectBytes),
-          NULL_REG);
+      __ StoreCompressedIntoObjectNoBarrier(AllocateArrayABI::kResultReg,
+                                            compiler::Address(R8, 0), NULL_REG);
       __ AddImmediate(R8, kCompressedWordSize);
       __ b(&init_loop);
       __ Bind(&end_loop);
@@ -2908,221 +2644,6 @@
   __ Bind(&done);
 }
 
-LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone,
-                                                     bool opt) const {
-  const intptr_t kNumInputs = 1;
-  LocationSummary* locs = nullptr;
-  if (slot().representation() != kTagged) {
-    ASSERT(!calls_initializer());
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    ASSERT(RepresentationUtils::ValueSize(slot().representation()) <=
-           compiler::target::kWordSize);
-
-    const intptr_t kNumTemps = 0;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-
-  } else if (IsUnboxedDartFieldLoad() && opt) {
-    ASSERT(!calls_initializer());
-    ASSERT(!slot().field().is_non_nullable_integer());
-
-    const intptr_t kNumTemps = FLAG_precompiled_mode ? 0 : 1;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    if (!FLAG_precompiled_mode) {
-      locs->set_temp(0, Location::RequiresRegister());
-    }
-    locs->set_out(0, Location::RequiresFpuRegister());
-
-  } else if (IsPotentialUnboxedDartFieldLoad()) {
-    ASSERT(!calls_initializer());
-    const intptr_t kNumTemps = 1;
-    locs = new (zone) LocationSummary(zone, kNumInputs, kNumTemps,
-                                      LocationSummary::kCallOnSlowPath);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_temp(0, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-
-  } else if (calls_initializer()) {
-    if (throw_exception_on_initialization()) {
-      const bool using_shared_stub = UseSharedSlowPathStub(opt);
-      const intptr_t kNumTemps = using_shared_stub ? 1 : 0;
-      locs = new (zone) LocationSummary(
-          zone, kNumInputs, kNumTemps,
-          using_shared_stub ? LocationSummary::kCallOnSharedSlowPath
-                            : LocationSummary::kCallOnSlowPath);
-      if (using_shared_stub) {
-        locs->set_temp(0, Location::RegisterLocation(
-                              LateInitializationErrorABI::kFieldReg));
-      }
-      locs->set_in(0, Location::RequiresRegister());
-      locs->set_out(0, Location::RequiresRegister());
-    } else {
-      const intptr_t kNumTemps = 0;
-      locs = new (zone)
-          LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-      locs->set_in(
-          0, Location::RegisterLocation(InitInstanceFieldABI::kInstanceReg));
-      locs->set_out(
-          0, Location::RegisterLocation(InitInstanceFieldABI::kResultReg));
-    }
-  } else {
-    const intptr_t kNumTemps = 0;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-  }
-  return locs;
-}
-
-void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(compiler::target::UntaggedObject::kClassIdTagSize == 16);
-  ASSERT(sizeof(UntaggedField::guarded_cid_) == 2);
-  ASSERT(sizeof(UntaggedField::is_nullable_) == 2);
-
-  const Register instance_reg = locs()->in(0).reg();
-  if (slot().representation() != kTagged) {
-    const Register result = locs()->out(0).reg();
-    __ Comment("NativeUnboxedLoadFieldInstr");
-    __ LoadFieldFromOffset(
-        result, instance_reg, OffsetInBytes(),
-        RepresentationUtils::OperandSize(slot().representation()));
-    return;
-  }
-
-  if (IsUnboxedDartFieldLoad() && compiler->is_optimizing()) {
-    const VRegister result = locs()->out(0).fpu_reg();
-    const intptr_t cid = slot().field().UnboxedFieldCid();
-
-    if (FLAG_precompiled_mode) {
-      switch (cid) {
-        case kDoubleCid:
-          __ Comment("UnboxedDoubleLoadFieldInstr");
-          __ LoadDFieldFromOffset(result, instance_reg, OffsetInBytes());
-          return;
-        case kFloat32x4Cid:
-          __ Comment("UnboxedFloat32x4LoadFieldInstr");
-          __ LoadQFieldFromOffset(result, instance_reg, OffsetInBytes());
-          return;
-        case kFloat64x2Cid:
-          __ Comment("UnboxedFloat64x2LoadFieldInstr");
-          __ LoadQFieldFromOffset(result, instance_reg, OffsetInBytes());
-          return;
-        default:
-          UNREACHABLE();
-      }
-    }
-
-    const Register temp = locs()->temp(0).reg();
-
-    __ LoadCompressedFieldFromOffset(temp, instance_reg, OffsetInBytes());
-    switch (cid) {
-      case kDoubleCid:
-        __ Comment("UnboxedDoubleLoadFieldInstr");
-        __ LoadDFieldFromOffset(result, temp, Double::value_offset());
-        break;
-      case kFloat32x4Cid:
-        __ LoadQFieldFromOffset(result, temp, Float32x4::value_offset());
-        break;
-      case kFloat64x2Cid:
-        __ LoadQFieldFromOffset(result, temp, Float64x2::value_offset());
-        break;
-      default:
-        UNREACHABLE();
-    }
-    return;
-  }
-
-  compiler::Label done;
-  const Register result_reg = locs()->out(0).reg();
-  if (IsPotentialUnboxedDartFieldLoad()) {
-    const Register temp = locs()->temp(0).reg();
-
-    compiler::Label load_pointer;
-    compiler::Label load_double;
-    compiler::Label load_float32x4;
-    compiler::Label load_float64x2;
-
-    __ LoadObject(result_reg, Field::ZoneHandle(slot().field().Original()));
-
-    compiler::FieldAddress field_cid_operand(
-        result_reg, Field::guarded_cid_offset(), compiler::kUnsignedTwoBytes);
-    compiler::FieldAddress field_nullability_operand(
-        result_reg, Field::is_nullable_offset(), compiler::kUnsignedTwoBytes);
-
-    __ ldr(temp, field_nullability_operand, compiler::kUnsignedTwoBytes);
-    __ CompareImmediate(temp, kNullCid);
-    __ b(&load_pointer, EQ);
-
-    __ ldr(temp, field_cid_operand, compiler::kUnsignedTwoBytes);
-    __ CompareImmediate(temp, kDoubleCid);
-    __ b(&load_double, EQ);
-
-    __ ldr(temp, field_cid_operand, compiler::kUnsignedTwoBytes);
-    __ CompareImmediate(temp, kFloat32x4Cid);
-    __ b(&load_float32x4, EQ);
-
-    __ ldr(temp, field_cid_operand, compiler::kUnsignedTwoBytes);
-    __ CompareImmediate(temp, kFloat64x2Cid);
-    __ b(&load_float64x2, EQ);
-
-    // Fall through.
-    __ b(&load_pointer);
-
-    if (!compiler->is_optimizing()) {
-      locs()->live_registers()->Add(locs()->in(0));
-    }
-
-    {
-      __ Bind(&load_double);
-      BoxAllocationSlowPath::Allocate(compiler, this, compiler->double_class(),
-                                      result_reg, temp);
-      __ LoadCompressedFieldFromOffset(temp, instance_reg, OffsetInBytes());
-      __ LoadDFieldFromOffset(VTMP, temp, Double::value_offset());
-      __ StoreDFieldToOffset(VTMP, result_reg, Double::value_offset());
-      __ b(&done);
-    }
-
-    {
-      __ Bind(&load_float32x4);
-      BoxAllocationSlowPath::Allocate(
-          compiler, this, compiler->float32x4_class(), result_reg, temp);
-      __ LoadCompressedFieldFromOffset(temp, instance_reg, OffsetInBytes());
-      __ LoadQFieldFromOffset(VTMP, temp, Float32x4::value_offset());
-      __ StoreQFieldToOffset(VTMP, result_reg, Float32x4::value_offset());
-      __ b(&done);
-    }
-
-    {
-      __ Bind(&load_float64x2);
-      BoxAllocationSlowPath::Allocate(
-          compiler, this, compiler->float64x2_class(), result_reg, temp);
-      __ LoadCompressedFieldFromOffset(temp, instance_reg, OffsetInBytes());
-      __ LoadQFieldFromOffset(VTMP, temp, Float64x2::value_offset());
-      __ StoreQFieldToOffset(VTMP, result_reg, Float64x2::value_offset());
-      __ b(&done);
-    }
-
-    __ Bind(&load_pointer);
-  }
-
-  if (slot().is_compressed()) {
-    __ LoadCompressedFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
-  } else {
-    __ LoadFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
-  }
-
-  if (calls_initializer()) {
-    EmitNativeCodeForInitializerCall(compiler);
-  }
-
-  __ Bind(&done);
-}
-
 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
     Zone* zone,
     bool opt) const {
@@ -5669,8 +5190,7 @@
   compiler->AddSlowPathCode(slow_path);
   __ ldr(TMP,
          compiler::FieldAddress(locs()->in(0).reg(),
-                                compiler::target::Object::tags_offset(),
-                                compiler::kUnsignedByte),
+                                compiler::target::Object::tags_offset()),
          compiler::kUnsignedByte);
   // In the first byte.
   ASSERT(compiler::target::UntaggedObject::kImmutableBit < 8);
@@ -6075,7 +5595,8 @@
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
     __ str(right,
-           compiler::Address(THR, Thread::unboxed_int64_runtime_arg_offset()));
+           compiler::Address(
+               THR, compiler::target::Thread::unboxed_runtime_arg_offset()));
   }
 };
 
@@ -6182,7 +5703,8 @@
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
     __ str(right,
-           compiler::Address(THR, Thread::unboxed_int64_runtime_arg_offset()));
+           compiler::Address(
+               THR, compiler::target::Thread::unboxed_runtime_arg_offset()));
   }
 };
 
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 0ae5fb0..16266db 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -8,6 +8,7 @@
 
 #include "vm/compiler/backend/il.h"
 
+#include "platform/memory_sanitizer.h"
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/backend/locations.h"
@@ -1050,6 +1051,9 @@
 
   // Reserve space for the arguments that go on the stack (if any), then align.
   __ ReserveAlignedFrameSpace(stack_required);
+#if defined(USING_MEMORY_SANITIZER)
+  UNIMPLEMENTED();
+#endif
 
   // No second temp: PointerToMemoryLocation is not used for arguments in ia32.
   EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp,
@@ -1661,7 +1665,7 @@
       const Register result = locs()->out(0).reg();
       ASSERT(representation() == kTagged);
       ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid) ||
-             (class_id() == kTypeArgumentsCid));
+             (class_id() == kTypeArgumentsCid) || (class_id() == kRecordCid));
       __ movl(result, element_address);
       break;
     }
@@ -2122,263 +2126,6 @@
   }
 }
 
-LocationSummary* StoreFieldInstr::MakeLocationSummary(Zone* zone,
-                                                      bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps =
-      (IsUnboxedDartFieldStore() && opt)
-          ? 2
-          : ((IsPotentialUnboxedDartFieldStore()) ? 3 : 0);
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps,
-      ((IsUnboxedDartFieldStore() && opt && is_initialization()) ||
-       IsPotentialUnboxedDartFieldStore())
-          ? LocationSummary::kCallOnSlowPath
-          : LocationSummary::kNoCall);
-
-  summary->set_in(kInstancePos, Location::RequiresRegister());
-  if (slot().representation() != kTagged) {
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    const size_t value_size =
-        RepresentationUtils::ValueSize(slot().representation());
-    if (value_size <= compiler::target::kWordSize) {
-      summary->set_in(kValuePos, Location::RequiresRegister());
-    } else {
-      ASSERT(value_size <= 2 * compiler::target::kWordSize);
-      summary->set_in(kValuePos, Location::Pair(Location::RequiresRegister(),
-                                                Location::RequiresRegister()));
-    }
-  } else if (IsUnboxedDartFieldStore() && opt) {
-    summary->set_in(kValuePos, Location::RequiresFpuRegister());
-    summary->set_temp(0, Location::RequiresRegister());
-    summary->set_temp(1, Location::RequiresRegister());
-  } else if (IsPotentialUnboxedDartFieldStore()) {
-    summary->set_in(kValuePos, ShouldEmitStoreBarrier()
-                                   ? Location::WritableRegister()
-                                   : Location::RequiresRegister());
-    summary->set_temp(0, Location::RequiresRegister());
-    summary->set_temp(1, Location::RequiresRegister());
-    summary->set_temp(2, opt ? Location::RequiresFpuRegister()
-                             : Location::FpuRegisterLocation(XMM1));
-  } else {
-    summary->set_in(kValuePos, ShouldEmitStoreBarrier()
-                                   ? Location::WritableRegister()
-                                   : LocationRegisterOrConstant(value()));
-  }
-  return summary;
-}
-
-static void EnsureMutableBox(FlowGraphCompiler* compiler,
-                             StoreFieldInstr* instruction,
-                             Register box_reg,
-                             const Class& cls,
-                             Register instance_reg,
-                             intptr_t offset,
-                             Register temp) {
-  compiler::Label done;
-  const compiler::Immediate& raw_null =
-      compiler::Immediate(static_cast<intptr_t>(Object::null()));
-  __ movl(box_reg, compiler::FieldAddress(instance_reg, offset));
-  __ cmpl(box_reg, raw_null);
-  __ j(NOT_EQUAL, &done);
-  BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
-  __ movl(temp, box_reg);
-  __ StoreIntoObject(instance_reg, compiler::FieldAddress(instance_reg, offset),
-                     temp, compiler::Assembler::kValueIsNotSmi);
-
-  __ Bind(&done);
-}
-
-void StoreFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(compiler::target::UntaggedObject::kClassIdTagSize == 16);
-  ASSERT(sizeof(UntaggedField::guarded_cid_) == 2);
-  ASSERT(sizeof(UntaggedField::is_nullable_) == 2);
-
-  compiler::Label skip_store;
-
-  const Register instance_reg = locs()->in(kInstancePos).reg();
-  const intptr_t offset_in_bytes = OffsetInBytes();
-  ASSERT(offset_in_bytes > 0);  // Field is finalized and points after header.
-
-  if (slot().representation() != kTagged) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    auto const rep = slot().representation();
-    ASSERT(RepresentationUtils::IsUnboxedInteger(rep));
-    const size_t value_size = RepresentationUtils::ValueSize(rep);
-    __ Comment("NativeUnboxedStoreFieldInstr");
-    if (value_size <= compiler::target::kWordSize) {
-      const Register value = locs()->in(kValuePos).reg();
-      __ StoreFieldToOffset(value, instance_reg, offset_in_bytes,
-                            RepresentationUtils::OperandSize(rep));
-    } else {
-      auto const in_pair = locs()->in(kValuePos).AsPairLocation();
-      const Register in_lo = in_pair->At(0).reg();
-      const Register in_hi = in_pair->At(1).reg();
-      const intptr_t offset_lo = OffsetInBytes() - kHeapObjectTag;
-      const intptr_t offset_hi = offset_lo + compiler::target::kWordSize;
-      __ StoreToOffset(in_lo, instance_reg, offset_lo);
-      __ StoreToOffset(in_hi, instance_reg, offset_hi);
-    }
-    return;
-  }
-
-  if (IsUnboxedDartFieldStore() && compiler->is_optimizing()) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    XmmRegister value = locs()->in(kValuePos).fpu_reg();
-    Register temp = locs()->temp(0).reg();
-    Register temp2 = locs()->temp(1).reg();
-    const intptr_t cid = slot().field().UnboxedFieldCid();
-
-    if (is_initialization()) {
-      const Class* cls = NULL;
-      switch (cid) {
-        case kDoubleCid:
-          cls = &compiler->double_class();
-          break;
-        case kFloat32x4Cid:
-          cls = &compiler->float32x4_class();
-          break;
-        case kFloat64x2Cid:
-          cls = &compiler->float64x2_class();
-          break;
-        default:
-          UNREACHABLE();
-      }
-
-      BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
-      __ movl(temp2, temp);
-      __ StoreIntoObject(instance_reg,
-                         compiler::FieldAddress(instance_reg, offset_in_bytes),
-                         temp2, compiler::Assembler::kValueIsNotSmi);
-    } else {
-      __ movl(temp, compiler::FieldAddress(instance_reg, offset_in_bytes));
-    }
-    switch (cid) {
-      case kDoubleCid:
-        __ Comment("UnboxedDoubleStoreFieldInstr");
-        __ movsd(compiler::FieldAddress(temp, Double::value_offset()), value);
-        break;
-      case kFloat32x4Cid:
-        __ Comment("UnboxedFloat32x4StoreFieldInstr");
-        __ movups(compiler::FieldAddress(temp, Float32x4::value_offset()),
-                  value);
-        break;
-      case kFloat64x2Cid:
-        __ Comment("UnboxedFloat64x2StoreFieldInstr");
-        __ movups(compiler::FieldAddress(temp, Float64x2::value_offset()),
-                  value);
-        break;
-      default:
-        UNREACHABLE();
-    }
-    return;
-  }
-
-  if (IsPotentialUnboxedDartFieldStore()) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    __ Comment("PotentialUnboxedStore");
-    Register value_reg = locs()->in(kValuePos).reg();
-    Register temp = locs()->temp(0).reg();
-    Register temp2 = locs()->temp(1).reg();
-    FpuRegister fpu_temp = locs()->temp(2).fpu_reg();
-
-    if (ShouldEmitStoreBarrier()) {
-      // Value input is a writable register and should be manually preserved
-      // across allocation slow-path.  Add it to live_registers set which
-      // determines which registers to preserve.
-      locs()->live_registers()->Add(locs()->in(kValuePos), kTagged);
-    }
-
-    compiler::Label store_pointer;
-    compiler::Label store_double;
-    compiler::Label store_float32x4;
-    compiler::Label store_float64x2;
-
-    __ LoadObject(temp, Field::ZoneHandle(Z, slot().field().Original()));
-
-    __ cmpw(compiler::FieldAddress(temp, Field::is_nullable_offset()),
-            compiler::Immediate(kNullCid));
-    __ j(EQUAL, &store_pointer);
-
-    __ movzxb(temp2, compiler::FieldAddress(temp, Field::kind_bits_offset()));
-    __ testl(temp2, compiler::Immediate(1 << Field::kUnboxingCandidateBit));
-    __ j(ZERO, &store_pointer);
-
-    __ cmpw(compiler::FieldAddress(temp, Field::guarded_cid_offset()),
-            compiler::Immediate(kDoubleCid));
-    __ j(EQUAL, &store_double);
-
-    __ cmpw(compiler::FieldAddress(temp, Field::guarded_cid_offset()),
-            compiler::Immediate(kFloat32x4Cid));
-    __ j(EQUAL, &store_float32x4);
-
-    __ cmpw(compiler::FieldAddress(temp, Field::guarded_cid_offset()),
-            compiler::Immediate(kFloat64x2Cid));
-    __ j(EQUAL, &store_float64x2);
-
-    // Fall through.
-    __ jmp(&store_pointer);
-
-    if (!compiler->is_optimizing()) {
-      locs()->live_registers()->Add(locs()->in(kInstancePos));
-      locs()->live_registers()->Add(locs()->in(kValuePos));
-    }
-
-    {
-      __ Bind(&store_double);
-      EnsureMutableBox(compiler, this, temp, compiler->double_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ movsd(fpu_temp,
-               compiler::FieldAddress(value_reg, Double::value_offset()));
-      __ movsd(compiler::FieldAddress(temp, Double::value_offset()), fpu_temp);
-      __ jmp(&skip_store);
-    }
-
-    {
-      __ Bind(&store_float32x4);
-      EnsureMutableBox(compiler, this, temp, compiler->float32x4_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ movups(fpu_temp,
-                compiler::FieldAddress(value_reg, Float32x4::value_offset()));
-      __ movups(compiler::FieldAddress(temp, Float32x4::value_offset()),
-                fpu_temp);
-      __ jmp(&skip_store);
-    }
-
-    {
-      __ Bind(&store_float64x2);
-      EnsureMutableBox(compiler, this, temp, compiler->float64x2_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ movups(fpu_temp,
-                compiler::FieldAddress(value_reg, Float64x2::value_offset()));
-      __ movups(compiler::FieldAddress(temp, Float64x2::value_offset()),
-                fpu_temp);
-      __ jmp(&skip_store);
-    }
-
-    __ Bind(&store_pointer);
-  }
-
-  if (ShouldEmitStoreBarrier()) {
-    Register value_reg = locs()->in(kValuePos).reg();
-    __ StoreIntoObject(instance_reg,
-                       compiler::FieldAddress(instance_reg, offset_in_bytes),
-                       value_reg, CanValueBeSmi(), memory_order_);
-  } else {
-    if (locs()->in(kValuePos).IsConstant()) {
-      __ StoreIntoObjectNoBarrier(
-          instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
-          locs()->in(kValuePos).constant(), memory_order_);
-    } else {
-      Register value_reg = locs()->in(kValuePos).reg();
-      __ StoreIntoObjectNoBarrier(
-          instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
-          value_reg, memory_order_);
-    }
-  }
-  __ Bind(&skip_store);
-}
-
 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
   LocationSummary* locs =
@@ -2532,209 +2279,6 @@
   __ Bind(&done);
 }
 
-LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone,
-                                                     bool opt) const {
-  const intptr_t kNumInputs = 1;
-  LocationSummary* locs = nullptr;
-  if (slot().representation() != kTagged) {
-    ASSERT(!calls_initializer());
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    const size_t value_size =
-        RepresentationUtils::ValueSize(slot().representation());
-
-    const intptr_t kNumTemps = 0;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    if (value_size <= compiler::target::kWordSize) {
-      locs->set_out(0, Location::RequiresRegister());
-    } else {
-      ASSERT(value_size <= 2 * compiler::target::kWordSize);
-      locs->set_out(0, Location::Pair(Location::RequiresRegister(),
-                                      Location::RequiresRegister()));
-    }
-
-  } else if (IsUnboxedDartFieldLoad() && opt) {
-    ASSERT(!calls_initializer());
-    const intptr_t kNumTemps = 1;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_temp(0, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresFpuRegister());
-
-  } else if (IsPotentialUnboxedDartFieldLoad()) {
-    ASSERT(!calls_initializer());
-    const intptr_t kNumTemps = 2;
-    locs = new (zone) LocationSummary(zone, kNumInputs, kNumTemps,
-                                      LocationSummary::kCallOnSlowPath);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_temp(0, opt ? Location::RequiresFpuRegister()
-                          : Location::FpuRegisterLocation(XMM1));
-    locs->set_temp(1, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-
-  } else if (calls_initializer()) {
-    if (throw_exception_on_initialization()) {
-      ASSERT(!UseSharedSlowPathStub(opt));
-      const intptr_t kNumTemps = 0;
-      locs = new (zone) LocationSummary(zone, kNumInputs, kNumTemps,
-                                        LocationSummary::kCallOnSlowPath);
-      locs->set_in(0, Location::RequiresRegister());
-      locs->set_out(0, Location::RequiresRegister());
-    } else {
-      const intptr_t kNumTemps = 0;
-      locs = new (zone)
-          LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-      locs->set_in(
-          0, Location::RegisterLocation(InitInstanceFieldABI::kInstanceReg));
-      locs->set_out(
-          0, Location::RegisterLocation(InitInstanceFieldABI::kResultReg));
-    }
-  } else {
-    const intptr_t kNumTemps = 0;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-  }
-  return locs;
-}
-
-void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(compiler::target::UntaggedObject::kClassIdTagSize == 16);
-  ASSERT(sizeof(UntaggedField::guarded_cid_) == 2);
-  ASSERT(sizeof(UntaggedField::is_nullable_) == 2);
-
-  const Register instance_reg = locs()->in(0).reg();
-  if (slot().representation() != kTagged) {
-    ASSERT(!calls_initializer());
-    auto const rep = slot().representation();
-    const size_t value_size = RepresentationUtils::ValueSize(rep);
-    __ Comment("NativeUnboxedLoadFieldInstr");
-    if (value_size <= compiler::target::kWordSize) {
-      auto const result = locs()->out(0).reg();
-      __ LoadFieldFromOffset(result, instance_reg, OffsetInBytes(),
-                             RepresentationUtils::OperandSize(rep));
-    } else {
-      auto const out_pair = locs()->out(0).AsPairLocation();
-      const Register out_lo = out_pair->At(0).reg();
-      const Register out_hi = out_pair->At(1).reg();
-      const intptr_t offset_lo = OffsetInBytes() - kHeapObjectTag;
-      const intptr_t offset_hi = offset_lo + compiler::target::kWordSize;
-      __ LoadFromOffset(out_lo, instance_reg, offset_lo);
-      __ LoadFromOffset(out_hi, instance_reg, offset_hi);
-    }
-    return;
-  }
-
-  if (IsUnboxedDartFieldLoad() && compiler->is_optimizing()) {
-    XmmRegister result = locs()->out(0).fpu_reg();
-    Register temp = locs()->temp(0).reg();
-    __ movl(temp, compiler::FieldAddress(instance_reg, OffsetInBytes()));
-    const intptr_t cid = slot().field().UnboxedFieldCid();
-    switch (cid) {
-      case kDoubleCid:
-        __ Comment("UnboxedDoubleLoadFieldInstr");
-        __ movsd(result, compiler::FieldAddress(temp, Double::value_offset()));
-        break;
-      case kFloat32x4Cid:
-        __ Comment("UnboxedFloat32x4LoadFieldInstr");
-        __ movups(result,
-                  compiler::FieldAddress(temp, Float32x4::value_offset()));
-        break;
-      case kFloat64x2Cid:
-        __ Comment("UnboxedFloat64x2LoadFieldInstr");
-        __ movups(result,
-                  compiler::FieldAddress(temp, Float64x2::value_offset()));
-        break;
-      default:
-        UNREACHABLE();
-    }
-    return;
-  }
-
-  compiler::Label done;
-  const Register result = locs()->out(0).reg();
-  if (IsPotentialUnboxedDartFieldLoad()) {
-    Register temp = locs()->temp(1).reg();
-    XmmRegister value = locs()->temp(0).fpu_reg();
-
-    compiler::Label load_pointer;
-    compiler::Label load_double;
-    compiler::Label load_float32x4;
-    compiler::Label load_float64x2;
-
-    __ LoadObject(result, Field::ZoneHandle(slot().field().Original()));
-
-    compiler::FieldAddress field_cid_operand(result,
-                                             Field::guarded_cid_offset());
-    compiler::FieldAddress field_nullability_operand(
-        result, Field::is_nullable_offset());
-
-    __ cmpw(field_nullability_operand, compiler::Immediate(kNullCid));
-    __ j(EQUAL, &load_pointer);
-
-    __ cmpw(field_cid_operand, compiler::Immediate(kDoubleCid));
-    __ j(EQUAL, &load_double);
-
-    __ cmpw(field_cid_operand, compiler::Immediate(kFloat32x4Cid));
-    __ j(EQUAL, &load_float32x4);
-
-    __ cmpw(field_cid_operand, compiler::Immediate(kFloat64x2Cid));
-    __ j(EQUAL, &load_float64x2);
-
-    // Fall through.
-    __ jmp(&load_pointer);
-
-    if (!compiler->is_optimizing()) {
-      locs()->live_registers()->Add(locs()->in(0));
-    }
-
-    {
-      __ Bind(&load_double);
-      BoxAllocationSlowPath::Allocate(compiler, this, compiler->double_class(),
-                                      result, temp);
-      __ movl(temp, compiler::FieldAddress(instance_reg, OffsetInBytes()));
-      __ movsd(value, compiler::FieldAddress(temp, Double::value_offset()));
-      __ movsd(compiler::FieldAddress(result, Double::value_offset()), value);
-      __ jmp(&done);
-    }
-
-    {
-      __ Bind(&load_float32x4);
-      BoxAllocationSlowPath::Allocate(
-          compiler, this, compiler->float32x4_class(), result, temp);
-      __ movl(temp, compiler::FieldAddress(instance_reg, OffsetInBytes()));
-      __ movups(value, compiler::FieldAddress(temp, Float32x4::value_offset()));
-      __ movups(compiler::FieldAddress(result, Float32x4::value_offset()),
-                value);
-      __ jmp(&done);
-    }
-
-    {
-      __ Bind(&load_float64x2);
-      BoxAllocationSlowPath::Allocate(
-          compiler, this, compiler->float64x2_class(), result, temp);
-      __ movl(temp, compiler::FieldAddress(instance_reg, OffsetInBytes()));
-      __ movups(value, compiler::FieldAddress(temp, Float64x2::value_offset()));
-      __ movups(compiler::FieldAddress(result, Float64x2::value_offset()),
-                value);
-      __ jmp(&done);
-    }
-
-    __ Bind(&load_pointer);
-  }
-
-  __ movl(result, compiler::FieldAddress(instance_reg, OffsetInBytes()));
-
-  if (calls_initializer()) {
-    EmitNativeCodeForInitializerCall(compiler);
-  }
-
-  __ Bind(&done);
-}
-
 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
     Zone* zone,
     bool opt) const {
@@ -6041,10 +5585,12 @@
     // The unboxed int64 argument is passed through a dedicated slot in Thread.
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
-    __ movl(compiler::Address(THR, Thread::unboxed_int64_runtime_arg_offset()),
+    __ movl(compiler::Address(
+                THR, compiler::target::Thread::unboxed_runtime_arg_offset()),
             right_lo);
     __ movl(compiler::Address(
-                THR, Thread::unboxed_int64_runtime_arg_offset() + kWordSize),
+                THR, compiler::target::Thread::unboxed_runtime_arg_offset() +
+                         kWordSize),
             right_hi);
   }
 };
@@ -6181,10 +5727,12 @@
     // The unboxed int64 argument is passed through a dedicated slot in Thread.
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
-    __ movl(compiler::Address(THR, Thread::unboxed_int64_runtime_arg_offset()),
+    __ movl(compiler::Address(
+                THR, compiler::target::Thread::unboxed_runtime_arg_offset()),
             right_lo);
     __ movl(compiler::Address(
-                THR, Thread::unboxed_int64_runtime_arg_offset() + kWordSize),
+                THR, compiler::target::Thread::unboxed_runtime_arg_offset() +
+                         kWordSize),
             right_hi);
   }
 };
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index 05b7050..0caa76e 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -29,6 +29,42 @@
 
 DECLARE_FLAG(bool, trace_inlining_intervals);
 
+const char* RepresentationToCString(Representation rep) {
+  switch (rep) {
+    case kTagged:
+      return "tagged";
+    case kUntagged:
+      return "untagged";
+    case kUnboxedDouble:
+      return "double";
+    case kUnboxedFloat:
+      return "float";
+    case kUnboxedUint8:
+      return "uint8";
+    case kUnboxedUint16:
+      return "uint16";
+    case kUnboxedInt32:
+      return "int32";
+    case kUnboxedUint32:
+      return "uint32";
+    case kUnboxedInt64:
+      return "int64";
+    case kUnboxedFloat32x4:
+      return "float32x4";
+    case kUnboxedInt32x4:
+      return "int32x4";
+    case kUnboxedFloat64x2:
+      return "float64x2";
+    case kPairOfTagged:
+      return "tagged-pair";
+    case kNoRepresentation:
+      return "none";
+    case kNumRepresentations:
+      UNREACHABLE();
+  }
+  return "?";
+}
+
 class IlTestPrinter : public AllStatic {
  public:
   static void PrintGraph(const char* phase, FlowGraph* flow_graph) {
@@ -788,6 +824,9 @@
   instance()->PrintTo(f);
   f->Printf(" . %s = ", slot().Name());
   value()->PrintTo(f);
+  if (slot().representation() != kTagged) {
+    f->Printf(" <%s>", RepresentationToCString(slot().representation()));
+  }
 
   // Here, we just print the value of the enum field. We would prefer to get
   // the final decision on whether a store barrier will be emitted by calling
@@ -1100,42 +1139,6 @@
   }
 }
 
-const char* RepresentationToCString(Representation rep) {
-  switch (rep) {
-    case kTagged:
-      return "tagged";
-    case kUntagged:
-      return "untagged";
-    case kUnboxedDouble:
-      return "double";
-    case kUnboxedFloat:
-      return "float";
-    case kUnboxedUint8:
-      return "uint8";
-    case kUnboxedUint16:
-      return "uint16";
-    case kUnboxedInt32:
-      return "int32";
-    case kUnboxedUint32:
-      return "uint32";
-    case kUnboxedInt64:
-      return "int64";
-    case kUnboxedFloat32x4:
-      return "float32x4";
-    case kUnboxedInt32x4:
-      return "int32x4";
-    case kUnboxedFloat64x2:
-      return "float64x2";
-    case kPairOfTagged:
-      return "tagged-pair";
-    case kNoRepresentation:
-      return "none";
-    case kNumRepresentations:
-      UNREACHABLE();
-  }
-  return "?";
-}
-
 void PhiInstr::PrintTo(BaseTextBuffer* f) const {
   f->Printf("v%" Pd " <- phi(", ssa_temp_index());
   for (intptr_t i = 0; i < inputs_.length(); ++i) {
diff --git a/runtime/vm/compiler/backend/il_riscv.cc b/runtime/vm/compiler/backend/il_riscv.cc
index 7a10f8c..2028c10 100644
--- a/runtime/vm/compiler/backend/il_riscv.cc
+++ b/runtime/vm/compiler/backend/il_riscv.cc
@@ -7,6 +7,7 @@
 
 #include "vm/compiler/backend/il.h"
 
+#include "platform/memory_sanitizer.h"
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/backend/locations.h"
@@ -1539,7 +1540,35 @@
   }
 
   // Reserve space for the arguments that go on the stack (if any), then align.
-  __ ReserveAlignedFrameSpace(marshaller_.RequiredStackSpaceInBytes());
+  intptr_t stack_space = marshaller_.RequiredStackSpaceInBytes();
+  __ ReserveAlignedFrameSpace(stack_space);
+#if defined(USING_MEMORY_SANITIZER)
+  {
+    RegisterSet kVolatileRegisterSet(kAbiVolatileCpuRegs, kAbiVolatileFpuRegs);
+    __ mv(temp1, SP);
+    __ PushRegisters(kVolatileRegisterSet);
+
+    // Outgoing arguments passed on the stack to the foreign function.
+    __ mv(A0, temp1);
+    __ LoadImmediate(A1, stack_space);
+    __ CallCFunction(
+        compiler::Address(THR, kMsanUnpoisonRuntimeEntry.OffsetFromThread()));
+
+    // Incoming Dart arguments to this trampoline are potentially used as local
+    // handles.
+    __ mv(A0, is_leaf_ ? FPREG : saved_fp_or_sp);
+    __ LoadImmediate(A1, (kParamEndSlotFromFp + InputCount()) * kWordSize);
+    __ CallCFunction(
+        compiler::Address(THR, kMsanUnpoisonRuntimeEntry.OffsetFromThread()));
+
+    // Outgoing arguments passed by register to the foreign function.
+    __ LoadImmediate(A0, InputCount());
+    __ CallCFunction(compiler::Address(
+        THR, kMsanUnpoisonParamRuntimeEntry.OffsetFromThread()));
+
+    __ PopRegisters(kVolatileRegisterSet);
+  }
+#endif
 
   EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp1, temp2);
 
@@ -2143,7 +2172,7 @@
     default: {
       ASSERT(representation() == kTagged);
       ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid) ||
-             (class_id() == kTypeArgumentsCid));
+             (class_id() == kTypeArgumentsCid) || (class_id() == kRecordCid));
       const Register result = locs()->out(0).reg();
       __ lx(result, element_address);
       break;
@@ -2785,290 +2814,6 @@
   }
 }
 
-static void EnsureMutableBox(FlowGraphCompiler* compiler,
-                             StoreFieldInstr* instruction,
-                             Register box_reg,
-                             const Class& cls,
-                             Register instance_reg,
-                             intptr_t offset,
-                             Register temp) {
-  compiler::Label done;
-  __ LoadCompressedFieldFromOffset(box_reg, instance_reg, offset);
-  __ CompareObject(box_reg, Object::null_object());
-  __ BranchIf(NE, &done);
-  BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
-  __ MoveRegister(temp, box_reg);
-  __ StoreCompressedIntoObjectOffset(instance_reg, offset, temp,
-                                     compiler::Assembler::kValueIsNotSmi);
-  __ Bind(&done);
-}
-
-LocationSummary* StoreFieldInstr::MakeLocationSummary(Zone* zone,
-                                                      bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = (IsUnboxedDartFieldStore() && opt)
-                                 ? (FLAG_precompiled_mode ? 0 : 2)
-                                 : (IsPotentialUnboxedDartFieldStore() ? 2 : 0);
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps,
-      (!FLAG_precompiled_mode &&
-       ((IsUnboxedDartFieldStore() && opt && is_initialization()) ||
-        IsPotentialUnboxedDartFieldStore()))
-          ? LocationSummary::kCallOnSlowPath
-          : LocationSummary::kNoCall);
-
-  summary->set_in(kInstancePos, Location::RequiresRegister());
-  if (slot().representation() != kTagged) {
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    const size_t value_size =
-        RepresentationUtils::ValueSize(slot().representation());
-    if (value_size <= compiler::target::kWordSize) {
-      summary->set_in(kValuePos, Location::RequiresRegister());
-    } else {
-#if XLEN == 32
-      ASSERT(value_size <= 2 * compiler::target::kWordSize);
-      summary->set_in(kValuePos, Location::Pair(Location::RequiresRegister(),
-                                                Location::RequiresRegister()));
-#else
-      UNREACHABLE();
-#endif
-    }
-  } else if (IsUnboxedDartFieldStore() && opt) {
-    summary->set_in(kValuePos, Location::RequiresFpuRegister());
-    if (FLAG_precompiled_mode) {
-#if XLEN >= 64
-      ConstantInstr* constant = value()->definition()->AsConstant();
-      if (constant != nullptr && constant->HasZeroRepresentation()) {
-        summary->set_in(kValuePos, Location::Constant(constant));
-      }
-#endif
-    } else {
-      summary->set_temp(0, Location::RequiresRegister());
-      summary->set_temp(1, Location::RequiresRegister());
-    }
-  } else if (IsPotentialUnboxedDartFieldStore()) {
-    summary->set_in(kValuePos, ShouldEmitStoreBarrier()
-                                   ? Location::WritableRegister()
-                                   : Location::RequiresRegister());
-    summary->set_temp(0, Location::RequiresRegister());
-    summary->set_temp(1, Location::RequiresRegister());
-  } else {
-    summary->set_in(kValuePos,
-                    ShouldEmitStoreBarrier()
-                        ? Location::RegisterLocation(kWriteBarrierValueReg)
-                        : LocationRegisterOrConstant(value()));
-  }
-  return summary;
-}
-
-void StoreFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(compiler::target::UntaggedObject::kClassIdTagSize == 16);
-  ASSERT(sizeof(UntaggedField::guarded_cid_) == 2);
-  ASSERT(sizeof(UntaggedField::is_nullable_) == 2);
-
-  compiler::Label skip_store;
-
-  const Register instance_reg = locs()->in(kInstancePos).reg();
-  const intptr_t offset_in_bytes = OffsetInBytes();
-  ASSERT(offset_in_bytes > 0);  // Field is finalized and points after header.
-
-  if (slot().representation() != kTagged) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    auto const rep = slot().representation();
-    ASSERT(RepresentationUtils::IsUnboxedInteger(rep));
-    const size_t value_size = RepresentationUtils::ValueSize(rep);
-    __ Comment("NativeUnboxedStoreFieldInstr");
-    if (value_size <= compiler::target::kWordSize) {
-      const Register value = locs()->in(kValuePos).reg();
-      __ StoreFieldToOffset(value, instance_reg, offset_in_bytes,
-                            RepresentationUtils::OperandSize(rep));
-    } else {
-#if XLEN == 32
-      auto const in_pair = locs()->in(kValuePos).AsPairLocation();
-      const Register in_lo = in_pair->At(0).reg();
-      const Register in_hi = in_pair->At(1).reg();
-      const intptr_t offset_lo = OffsetInBytes() - kHeapObjectTag;
-      const intptr_t offset_hi = offset_lo + compiler::target::kWordSize;
-      __ StoreToOffset(in_lo, instance_reg, offset_lo);
-      __ StoreToOffset(in_hi, instance_reg, offset_hi);
-#else
-      UNREACHABLE();
-#endif
-    }
-    return;
-  }
-
-  if (IsUnboxedDartFieldStore() && compiler->is_optimizing()) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    const intptr_t cid = slot().field().UnboxedFieldCid();
-    if (FLAG_precompiled_mode) {
-      switch (cid) {
-        case kDoubleCid:
-          __ Comment("UnboxedDoubleStoreFieldInstr");
-#if XLEN >= 64
-          if (locs()->in(kValuePos).IsConstant()) {
-            ASSERT(locs()
-                       ->in(kValuePos)
-                       .constant_instruction()
-                       ->HasZeroRepresentation());
-            __ StoreFieldToOffset(ZR, instance_reg, offset_in_bytes,
-                                  compiler::kEightBytes);
-            return;
-          }
-#endif
-          __ StoreDFieldToOffset(locs()->in(kValuePos).fpu_reg(), instance_reg,
-                                 offset_in_bytes);
-          return;
-        case kFloat32x4Cid:
-          __ Comment("UnboxedFloat32x4StoreFieldInstr");
-          UNIMPLEMENTED();
-          return;
-        case kFloat64x2Cid:
-          __ Comment("UnboxedFloat64x2StoreFieldInstr");
-          UNIMPLEMENTED();
-          return;
-        default:
-          UNREACHABLE();
-      }
-    }
-
-    const Register temp = locs()->temp(0).reg();
-    const Register temp2 = locs()->temp(1).reg();
-
-    if (is_initialization()) {
-      const Class* cls = NULL;
-      switch (cid) {
-        case kDoubleCid:
-          cls = &compiler->double_class();
-          break;
-        case kFloat32x4Cid:
-          cls = &compiler->float32x4_class();
-          break;
-        case kFloat64x2Cid:
-          cls = &compiler->float64x2_class();
-          break;
-        default:
-          UNREACHABLE();
-      }
-
-      BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
-      __ MoveRegister(temp2, temp);
-      __ StoreCompressedIntoObjectOffset(instance_reg, offset_in_bytes, temp2,
-                                         compiler::Assembler::kValueIsNotSmi);
-    } else {
-      __ LoadCompressedFieldFromOffset(temp, instance_reg, offset_in_bytes);
-    }
-
-    const FRegister value = locs()->in(kValuePos).fpu_reg();
-    switch (cid) {
-      case kDoubleCid:
-        __ Comment("UnboxedDoubleStoreFieldInstr");
-        __ StoreDFieldToOffset(value, temp, Double::value_offset());
-        break;
-      case kFloat32x4Cid:
-        __ Comment("UnboxedFloat32x4StoreFieldInstr");
-        UNIMPLEMENTED();
-        break;
-      case kFloat64x2Cid:
-        __ Comment("UnboxedFloat64x2StoreFieldInstr");
-        UNIMPLEMENTED();
-        break;
-      default:
-        UNREACHABLE();
-    }
-
-    return;
-  }
-
-  if (IsPotentialUnboxedDartFieldStore()) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    const Register value_reg = locs()->in(kValuePos).reg();
-    const Register temp = locs()->temp(0).reg();
-    const Register temp2 = locs()->temp(1).reg();
-
-    if (ShouldEmitStoreBarrier()) {
-      // Value input is a writable register and should be manually preserved
-      // across allocation slow-path.
-      locs()->live_registers()->Add(locs()->in(kValuePos), kTagged);
-    }
-
-    compiler::Label store_pointer;
-    compiler::Label store_double;
-    compiler::Label store_float32x4;
-    compiler::Label store_float64x2;
-
-    __ LoadObject(temp, Field::ZoneHandle(Z, slot().field().Original()));
-
-    __ LoadFieldFromOffset(temp2, temp, Field::is_nullable_offset(),
-                           compiler::kUnsignedTwoBytes);
-    __ CompareImmediate(temp2, kNullCid);
-    __ BranchIf(EQ, &store_pointer);
-
-    __ LoadFromOffset(temp2, temp, Field::kind_bits_offset() - kHeapObjectTag,
-                      compiler::kUnsignedByte);
-    __ TestImmediate(temp2, 1 << Field::kUnboxingCandidateBit);
-    __ BranchIf(EQ, &store_pointer);
-
-    __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(),
-                           compiler::kUnsignedTwoBytes);
-    __ CompareImmediate(temp2, kDoubleCid);
-    __ BranchIf(EQ, &store_double);
-
-    // Fall through.
-    __ j(&store_pointer);
-
-    if (!compiler->is_optimizing()) {
-      locs()->live_registers()->Add(locs()->in(kInstancePos));
-      locs()->live_registers()->Add(locs()->in(kValuePos));
-    }
-
-    {
-      __ Bind(&store_double);
-      EnsureMutableBox(compiler, this, temp, compiler->double_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ LoadDFieldFromOffset(FTMP, value_reg, Double::value_offset());
-      __ StoreDFieldToOffset(FTMP, temp, Double::value_offset());
-      __ j(&skip_store);
-    }
-
-    __ Bind(&store_pointer);
-  }
-
-  const bool compressed = slot().is_compressed();
-  if (ShouldEmitStoreBarrier()) {
-    const Register value_reg = locs()->in(kValuePos).reg();
-    if (!compressed) {
-      __ StoreIntoObjectOffset(instance_reg, offset_in_bytes, value_reg,
-                               CanValueBeSmi(), memory_order_);
-    } else {
-      __ StoreCompressedIntoObjectOffset(instance_reg, offset_in_bytes,
-                                         value_reg, CanValueBeSmi(),
-                                         memory_order_);
-    }
-  } else {
-    if (locs()->in(kValuePos).IsConstant()) {
-      const auto& value = locs()->in(kValuePos).constant();
-      if (!compressed) {
-        __ StoreIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes, value,
-                                          memory_order_);
-      } else {
-        __ StoreCompressedIntoObjectOffsetNoBarrier(
-            instance_reg, offset_in_bytes, value, memory_order_);
-      }
-    } else {
-      const Register value_reg = locs()->in(kValuePos).reg();
-      if (!compressed) {
-        __ StoreIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes,
-                                          value_reg, memory_order_);
-      } else {
-        __ StoreCompressedIntoObjectOffsetNoBarrier(
-            instance_reg, offset_in_bytes, value_reg, memory_order_);
-      }
-    }
-  }
-  __ Bind(&skip_store);
-}
-
 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -3222,238 +2967,6 @@
   __ Bind(&done);
 }
 
-LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone,
-                                                     bool opt) const {
-  const intptr_t kNumInputs = 1;
-  LocationSummary* locs = nullptr;
-  if (slot().representation() != kTagged) {
-    ASSERT(!calls_initializer());
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    const size_t value_size =
-        RepresentationUtils::ValueSize(slot().representation());
-
-    const intptr_t kNumTemps = 0;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    if (value_size <= compiler::target::kWordSize) {
-      locs->set_out(0, Location::RequiresRegister());
-    } else {
-#if XLEN == 32
-      ASSERT(value_size <= 2 * compiler::target::kWordSize);
-      locs->set_out(0, Location::Pair(Location::RequiresRegister(),
-                                      Location::RequiresRegister()));
-#else
-      UNREACHABLE();
-#endif
-    }
-
-  } else if (IsUnboxedDartFieldLoad() && opt) {
-    ASSERT(!calls_initializer());
-    ASSERT(!slot().field().is_non_nullable_integer());
-
-    const intptr_t kNumTemps = FLAG_precompiled_mode ? 0 : 1;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    if (!FLAG_precompiled_mode) {
-      locs->set_temp(0, Location::RequiresRegister());
-    }
-    locs->set_out(0, Location::RequiresFpuRegister());
-
-  } else if (IsPotentialUnboxedDartFieldLoad()) {
-    ASSERT(!calls_initializer());
-    const intptr_t kNumTemps = 1;
-    locs = new (zone) LocationSummary(zone, kNumInputs, kNumTemps,
-                                      LocationSummary::kCallOnSlowPath);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_temp(0, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-
-  } else if (calls_initializer()) {
-    if (throw_exception_on_initialization()) {
-      const bool using_shared_stub = UseSharedSlowPathStub(opt);
-      const intptr_t kNumTemps = using_shared_stub ? 1 : 0;
-      locs = new (zone) LocationSummary(
-          zone, kNumInputs, kNumTemps,
-          using_shared_stub ? LocationSummary::kCallOnSharedSlowPath
-                            : LocationSummary::kCallOnSlowPath);
-      if (using_shared_stub) {
-        locs->set_temp(0, Location::RegisterLocation(
-                              LateInitializationErrorABI::kFieldReg));
-      }
-      locs->set_in(0, Location::RequiresRegister());
-      locs->set_out(0, Location::RequiresRegister());
-    } else {
-      const intptr_t kNumTemps = 0;
-      locs = new (zone)
-          LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-      locs->set_in(
-          0, Location::RegisterLocation(InitInstanceFieldABI::kInstanceReg));
-      locs->set_out(
-          0, Location::RegisterLocation(InitInstanceFieldABI::kResultReg));
-    }
-  } else {
-    const intptr_t kNumTemps = 0;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-  }
-  return locs;
-}
-
-void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(compiler::target::UntaggedObject::kClassIdTagSize == 16);
-  ASSERT(sizeof(UntaggedField::guarded_cid_) == 2);
-  ASSERT(sizeof(UntaggedField::is_nullable_) == 2);
-
-  const Register instance_reg = locs()->in(0).reg();
-  if (slot().representation() != kTagged) {
-    auto const rep = slot().representation();
-    const size_t value_size = RepresentationUtils::ValueSize(rep);
-    __ Comment("NativeUnboxedLoadFieldInstr");
-    if (value_size <= compiler::target::kWordSize) {
-      auto const result = locs()->out(0).reg();
-      __ LoadFieldFromOffset(result, instance_reg, OffsetInBytes(),
-                             RepresentationUtils::OperandSize(rep));
-    } else {
-#if XLEN == 32
-      auto const out_pair = locs()->out(0).AsPairLocation();
-      const Register out_lo = out_pair->At(0).reg();
-      const Register out_hi = out_pair->At(1).reg();
-      const intptr_t offset_lo = OffsetInBytes() - kHeapObjectTag;
-      const intptr_t offset_hi = offset_lo + compiler::target::kWordSize;
-      __ LoadFromOffset(out_lo, instance_reg, offset_lo);
-      __ LoadFromOffset(out_hi, instance_reg, offset_hi);
-#else
-      UNREACHABLE();
-#endif
-    }
-    return;
-  }
-
-  if (IsUnboxedDartFieldLoad() && compiler->is_optimizing()) {
-    const FRegister result = locs()->out(0).fpu_reg();
-    const intptr_t cid = slot().field().UnboxedFieldCid();
-
-    if (FLAG_precompiled_mode) {
-      switch (cid) {
-        case kDoubleCid:
-          __ Comment("UnboxedDoubleLoadFieldInstr");
-          __ LoadDFieldFromOffset(result, instance_reg, OffsetInBytes());
-          return;
-        case kFloat32x4Cid:
-          __ Comment("UnboxedFloat32x4LoadFieldInstr");
-          UNIMPLEMENTED();
-          return;
-        case kFloat64x2Cid:
-          __ Comment("UnboxedFloat64x2LoadFieldInstr");
-          UNIMPLEMENTED();
-          return;
-        default:
-          UNREACHABLE();
-      }
-    }
-
-    const Register temp = locs()->temp(0).reg();
-
-    __ LoadCompressedFieldFromOffset(temp, instance_reg, OffsetInBytes());
-    switch (cid) {
-      case kDoubleCid:
-        __ Comment("UnboxedDoubleLoadFieldInstr");
-        __ LoadDFieldFromOffset(result, temp, Double::value_offset());
-        break;
-      case kFloat32x4Cid:
-        UNIMPLEMENTED();
-        break;
-      case kFloat64x2Cid:
-        UNIMPLEMENTED();
-        break;
-      default:
-        UNREACHABLE();
-    }
-    return;
-  }
-
-  compiler::Label done;
-  const Register result_reg = locs()->out(0).reg();
-  if (IsPotentialUnboxedDartFieldLoad()) {
-    const Register temp = locs()->temp(0).reg();
-
-    compiler::Label load_pointer;
-    compiler::Label load_double;
-    compiler::Label load_float32x4;
-    compiler::Label load_float64x2;
-
-    __ LoadObject(result_reg, Field::ZoneHandle(slot().field().Original()));
-
-    compiler::FieldAddress field_cid_operand(result_reg,
-                                             Field::guarded_cid_offset());
-    compiler::FieldAddress field_nullability_operand(
-        result_reg, Field::is_nullable_offset());
-
-    __ lhu(temp, field_nullability_operand);
-    __ CompareImmediate(temp, kNullCid);
-    __ BranchIf(EQ, &load_pointer, compiler::Assembler::kNearJump);
-
-    __ lhu(temp, field_cid_operand);
-    __ CompareImmediate(temp, kDoubleCid);
-    __ BranchIf(EQ, &load_double, compiler::Assembler::kNearJump);
-
-    __ lhu(temp, field_cid_operand);
-    __ CompareImmediate(temp, kFloat32x4Cid);
-    __ BranchIf(EQ, &load_float32x4, compiler::Assembler::kNearJump);
-
-    __ lhu(temp, field_cid_operand);
-    __ CompareImmediate(temp, kFloat64x2Cid);
-    __ BranchIf(EQ, &load_float64x2, compiler::Assembler::kNearJump);
-
-    // Fall through.
-    __ j(&load_pointer);
-
-    if (!compiler->is_optimizing()) {
-      locs()->live_registers()->Add(locs()->in(0));
-    }
-
-    {
-      __ Bind(&load_double);
-      BoxAllocationSlowPath::Allocate(compiler, this, compiler->double_class(),
-                                      result_reg, temp);
-      __ LoadCompressedFieldFromOffset(temp, instance_reg, OffsetInBytes());
-      __ LoadDFieldFromOffset(FTMP, temp, Double::value_offset());
-      __ StoreDFieldToOffset(FTMP, result_reg, Double::value_offset());
-      __ j(&done);
-    }
-
-    {
-      __ Bind(&load_float32x4);
-      __ ebreak();  // Unimplemented
-      __ j(&done);
-    }
-
-    {
-      __ Bind(&load_float64x2);
-      __ ebreak();  // Unimplemented
-      __ j(&done);
-    }
-
-    __ Bind(&load_pointer);
-  }
-
-  if (slot().is_compressed()) {
-    __ LoadCompressedFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
-  } else {
-    __ LoadFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
-  }
-
-  if (calls_initializer()) {
-    EmitNativeCodeForInitializerCall(compiler);
-  }
-
-  __ Bind(&done);
-}
-
 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
     Zone* zone,
     bool opt) const {
@@ -6431,13 +5944,11 @@
     // The unboxed int64 argument is passed through a dedicated slot in Thread.
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
-    __ StoreToOffset(
-        right_lo, THR,
-        compiler::target::Thread::unboxed_int64_runtime_arg_offset());
-    __ StoreToOffset(
-        right_hi, THR,
-        compiler::target::Thread::unboxed_int64_runtime_arg_offset() +
-            compiler::target::kWordSize);
+    __ StoreToOffset(right_lo, THR,
+                     compiler::target::Thread::unboxed_runtime_arg_offset());
+    __ StoreToOffset(right_hi, THR,
+                     compiler::target::Thread::unboxed_runtime_arg_offset() +
+                         compiler::target::kWordSize);
 #else
     const Register left = instruction()->locs()->in(0).reg();
     const Register right = instruction()->locs()->in(1).reg();
@@ -6468,7 +5979,8 @@
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
     __ sx(right,
-          compiler::Address(THR, Thread::unboxed_int64_runtime_arg_offset()));
+          compiler::Address(
+              THR, compiler::target::Thread::unboxed_runtime_arg_offset()));
 #endif
   }
 };
@@ -6680,13 +6192,11 @@
     // The unboxed int64 argument is passed through a dedicated slot in Thread.
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
-    __ StoreToOffset(
-        right_lo, THR,
-        compiler::target::Thread::unboxed_int64_runtime_arg_offset());
-    __ StoreToOffset(
-        right_hi, THR,
-        compiler::target::Thread::unboxed_int64_runtime_arg_offset() +
-            compiler::target::kWordSize);
+    __ StoreToOffset(right_lo, THR,
+                     compiler::target::Thread::unboxed_runtime_arg_offset());
+    __ StoreToOffset(right_hi, THR,
+                     compiler::target::Thread::unboxed_runtime_arg_offset() +
+                         compiler::target::kWordSize);
 #else
     const Register right = instruction()->locs()->in(1).reg();
 
@@ -6696,7 +6206,8 @@
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
     __ sx(right,
-          compiler::Address(THR, Thread::unboxed_int64_runtime_arg_offset()));
+          compiler::Address(
+              THR, compiler::target::Thread::unboxed_runtime_arg_offset()));
 #endif
   }
 };
diff --git a/runtime/vm/compiler/backend/il_serializer.cc b/runtime/vm/compiler/backend/il_serializer.cc
index 6a0dfa6..5910c8c 100644
--- a/runtime/vm/compiler/backend/il_serializer.cc
+++ b/runtime/vm/compiler/backend/il_serializer.cc
@@ -1598,6 +1598,29 @@
       stream_->WriteBytes(latin1, length);
       break;
     }
+    case kRecordCid: {
+      ASSERT(x.IsCanonical());
+      const auto& record = Record::Cast(x);
+      const intptr_t num_fields = record.num_fields();
+      Write<intptr_t>(num_fields);
+      Write<const Array&>(Array::Handle(Z, record.field_names()));
+      auto& field = Object::Handle(Z);
+      for (intptr_t i = 0; i < num_fields; ++i) {
+        field = record.FieldAt(i);
+        Write<const Object&>(field);
+      }
+      break;
+    }
+    case kRecordTypeCid: {
+      const auto& rec = RecordType::Cast(x);
+      ASSERT(rec.IsFinalized());
+      TypeScope type_scope(this, rec.IsRecursive());
+      Write<int8_t>(static_cast<int8_t>(rec.nullability()));
+      Write<const Array&>(Array::Handle(Z, rec.field_names()));
+      Write<const Array&>(Array::Handle(Z, rec.field_types()));
+      Write<bool>(type_scope.CanBeCanonicalized());
+      break;
+    }
     case kSentinelCid:
       if (x.ptr() == Object::sentinel().ptr()) {
         Write<bool>(true);
@@ -1685,7 +1708,7 @@
         const auto& cls =
             Class::Handle(Z, isolate_group()->class_table()->At(cid));
         const auto unboxed_fields_bitmap =
-            isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(cid);
+            isolate_group()->class_table()->GetUnboxedFieldsMapAt(cid);
         const intptr_t next_field_offset = cls.host_next_field_offset();
         auto& obj = Object::Handle(Z);
         for (intptr_t offset = Instance::NextFieldOffset();
@@ -1858,6 +1881,27 @@
       return String::ZoneHandle(Z,
                                 Symbols::FromLatin1(thread(), latin1, length));
     }
+    case kRecordCid: {
+      const intptr_t num_fields = Read<intptr_t>();
+      const auto& field_names = Read<const Array&>();
+      auto& record =
+          Record::ZoneHandle(Z, Record::New(num_fields, field_names));
+      for (intptr_t i = 0; i < num_fields; ++i) {
+        record.SetFieldAt(i, Read<const Object&>());
+      }
+      record ^= record.Canonicalize(thread());
+      return record;
+    }
+    case kRecordTypeCid: {
+      const Nullability nullability = static_cast<Nullability>(Read<int8_t>());
+      const Array& field_names = Read<const Array&>();
+      const Array& field_types = Read<const Array&>();
+      RecordType& rec = RecordType::ZoneHandle(
+          Z, RecordType::New(field_types, field_names, nullability));
+      rec.SetIsFinalized();
+      rec ^= MaybeCanonicalize(rec, object_index, Read<bool>());
+      return rec;
+    }
     case kSentinelCid:
       return Read<bool>() ? Object::sentinel() : Object::transition_sentinel();
     case kSmiCid:
@@ -1939,7 +1983,7 @@
       if ((cid >= kNumPredefinedCids) || (cid == kInstanceCid)) {
         const auto& cls = Class::Handle(Z, GetClassById(cid));
         const auto unboxed_fields_bitmap =
-            isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(cid);
+            isolate_group()->class_table()->GetUnboxedFieldsMapAt(cid);
         const intptr_t next_field_offset = cls.host_next_field_offset();
         auto& instance = Instance::ZoneHandle(Z, Instance::New(cls));
         for (intptr_t offset = Instance::NextFieldOffset();
@@ -2161,6 +2205,9 @@
     case Kind::kArrayElement:
       s->Write<intptr_t>(offset_in_bytes_);
       break;
+    case Kind::kRecordField:
+      s->Write<intptr_t>(offset_in_bytes_);
+      break;
     case Kind::kCapturedVariable:
       s->Write<int8_t>(flags_);
       s->Write<intptr_t>(offset_in_bytes_);
@@ -2204,6 +2251,12 @@
       offset = d->Read<intptr_t>();
       data = ":array_element";
       break;
+    case Kind::kRecordField:
+      flags = IsNullableBit::encode(true) |
+              IsCompressedBit::encode(Record::ContainsCompressedPointers());
+      offset = d->Read<intptr_t>();
+      data = ":record_field";
+      break;
     case Kind::kCapturedVariable:
       flags = d->Read<int8_t>();
       offset = d->Read<intptr_t>();
diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc
index 8ae38a1..21ffae7 100644
--- a/runtime/vm/compiler/backend/il_test.cc
+++ b/runtime/vm/compiler/backend/il_test.cc
@@ -207,16 +207,8 @@
 
   CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
 
-  FlowGraphBuilderHelper H;
-
-  // Add a variable into the scope which would provide static type for the
-  // parameter.
-  LocalVariable* v0_var =
-      new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
-                        String::Handle(Symbols::New(thread, "v0")),
-                        AbstractType::ZoneHandle(Type::IntType()));
-  v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
-  H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);
+  FlowGraphBuilderHelper H(/*num_parameters=*/1);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::IntType()));
 
   auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
 
@@ -269,7 +261,8 @@
 
   CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
 
-  FlowGraphBuilderHelper H;
+  FlowGraphBuilderHelper H(/*num_parameters=*/1);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::DynamicType()));
 
   auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
   auto b2 = H.JoinEntry();
@@ -322,7 +315,9 @@
 
   CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
 
-  FlowGraphBuilderHelper H;
+  FlowGraphBuilderHelper H(/*num_parameters=*/2);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::DynamicType()));
+  H.AddVariable("v1", AbstractType::ZoneHandle(Type::DynamicType()));
 
   auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
   Definition* unbox;
@@ -397,7 +392,9 @@
 
   CompilerState S(thread, /*is_aot=*/true, /*is_optimizing=*/true);
 
-  FlowGraphBuilderHelper H;
+  FlowGraphBuilderHelper H(/*num_parameters=*/2);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::IntType()));
+  H.AddVariable("v1", AbstractType::ZoneHandle(Type::IntType()));
 
   auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
 
diff --git a/runtime/vm/compiler/backend/il_test_helper.h b/runtime/vm/compiler/backend/il_test_helper.h
index 6e77ecc..4381a0a 100644
--- a/runtime/vm/compiler/backend/il_test_helper.h
+++ b/runtime/vm/compiler/backend/il_test_helper.h
@@ -261,9 +261,9 @@
 
 class FlowGraphBuilderHelper {
  public:
-  FlowGraphBuilderHelper()
+  explicit FlowGraphBuilderHelper(intptr_t num_parameters = 0)
       : state_(CompilerState::Current()),
-        flow_graph_(MakeDummyGraph(Thread::Current())) {
+        flow_graph_(MakeDummyGraph(Thread::Current(), num_parameters)) {
     flow_graph_.CreateCommonConstants();
   }
 
@@ -286,6 +286,19 @@
     return flow_graph_.GetConstant(Double::Handle(Double::NewCanonical(value)));
   }
 
+  // Adds a variable into the scope which would provide static type for the
+  // parameter.
+  void AddVariable(const char* name,
+                   const AbstractType& static_type,
+                   CompileType* param_type = nullptr) {
+    LocalVariable* v =
+        new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
+                          String::Handle(Symbols::New(Thread::Current(), name)),
+                          static_type, param_type);
+    v->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
+    flow_graph()->parsed_function().scope()->AddVariable(v);
+  }
+
   enum class IncomingDefKind {
     kImmediate,
     kDelayed,
@@ -349,9 +362,10 @@
   FlowGraph* flow_graph() { return &flow_graph_; }
 
  private:
-  static FlowGraph& MakeDummyGraph(Thread* thread) {
+  static FlowGraph& MakeDummyGraph(Thread* thread, intptr_t num_parameters) {
     const FunctionType& signature =
         FunctionType::ZoneHandle(FunctionType::New());
+    signature.set_num_fixed_parameters(num_parameters);
     const Function& func = Function::ZoneHandle(Function::New(
         signature, String::Handle(Symbols::New(thread, "dummy")),
         UntaggedFunction::kRegularFunction,
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 4c59193..d17f765 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -8,6 +8,7 @@
 
 #include "vm/compiler/backend/il.h"
 
+#include "platform/memory_sanitizer.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
@@ -1231,7 +1232,37 @@
   }
 
   // Reserve space for the arguments that go on the stack (if any), then align.
-  __ ReserveAlignedFrameSpace(marshaller_.RequiredStackSpaceInBytes());
+  intptr_t stack_space = marshaller_.RequiredStackSpaceInBytes();
+  __ ReserveAlignedFrameSpace(stack_space);
+#if defined(USING_MEMORY_SANITIZER)
+  {
+    RegisterSet kVolatileRegisterSet(CallingConventions::kVolatileCpuRegisters,
+                                     CallingConventions::kVolatileXmmRegisters);
+    __ movq(temp, RSP);
+    __ PushRegisters(kVolatileRegisterSet);
+
+    // Outgoing arguments passed on the stack to the foreign function.
+    __ movq(CallingConventions::kArg1Reg, temp);
+    __ LoadImmediate(CallingConventions::kArg2Reg, stack_space);
+    __ CallCFunction(
+        compiler::Address(THR, kMsanUnpoisonRuntimeEntry.OffsetFromThread()));
+
+    // Incoming Dart arguments to this trampoline are potentially used as local
+    // handles.
+    __ movq(CallingConventions::kArg1Reg, is_leaf_ ? FPREG : saved_fp);
+    __ LoadImmediate(CallingConventions::kArg2Reg,
+                     (kParamEndSlotFromFp + InputCount()) * kWordSize);
+    __ CallCFunction(
+        compiler::Address(THR, kMsanUnpoisonRuntimeEntry.OffsetFromThread()));
+
+    // Outgoing arguments passed by register to the foreign function.
+    __ LoadImmediate(CallingConventions::kArg1Reg, InputCount());
+    __ CallCFunction(compiler::Address(
+        THR, kMsanUnpoisonParamRuntimeEntry.OffsetFromThread()));
+
+    __ PopRegisters(kVolatileRegisterSet);
+  }
+#endif
 
   if (is_leaf_) {
     EmitParamMoves(compiler, FPREG, saved_fp, TMP);
@@ -1844,7 +1875,7 @@
     default:
       ASSERT(representation() == kTagged);
       ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid) ||
-             (class_id() == kTypeArgumentsCid));
+             (class_id() == kTypeArgumentsCid) || (class_id() == kRecordCid));
       __ LoadCompressed(result, element_address);
       break;
   }
@@ -2463,291 +2494,6 @@
   __ Bind(&ok);
 }
 
-LocationSummary* StoreFieldInstr::MakeLocationSummary(Zone* zone,
-                                                      bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = (IsUnboxedDartFieldStore() && opt)
-                                 ? (FLAG_precompiled_mode ? 0 : 2)
-                                 : (IsPotentialUnboxedDartFieldStore() ? 3 : 0);
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps,
-      (!FLAG_precompiled_mode &&
-       ((IsUnboxedDartFieldStore() && opt && is_initialization()) ||
-        IsPotentialUnboxedDartFieldStore()))
-          ? LocationSummary::kCallOnSlowPath
-          : LocationSummary::kNoCall);
-
-  summary->set_in(kInstancePos, Location::RequiresRegister());
-  if (slot().representation() != kTagged) {
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    ASSERT(RepresentationUtils::ValueSize(slot().representation()) <=
-           compiler::target::kWordSize);
-    summary->set_in(kValuePos, Location::RequiresRegister());
-  } else if (IsUnboxedDartFieldStore() && opt) {
-    summary->set_in(kValuePos, Location::RequiresFpuRegister());
-    if (!FLAG_precompiled_mode) {
-      summary->set_temp(0, Location::RequiresRegister());
-      summary->set_temp(1, Location::RequiresRegister());
-    }
-  } else if (IsPotentialUnboxedDartFieldStore()) {
-    summary->set_in(kValuePos, ShouldEmitStoreBarrier()
-                                   ? Location::WritableRegister()
-                                   : Location::RequiresRegister());
-    summary->set_temp(0, Location::RequiresRegister());
-    summary->set_temp(1, Location::RequiresRegister());
-    summary->set_temp(2, opt ? Location::RequiresFpuRegister()
-                             : Location::FpuRegisterLocation(XMM1));
-  } else {
-    summary->set_in(kValuePos,
-                    ShouldEmitStoreBarrier()
-                        ? Location::RegisterLocation(kWriteBarrierValueReg)
-                        : LocationRegisterOrConstant(value()));
-  }
-  return summary;
-}
-
-static void EnsureMutableBox(FlowGraphCompiler* compiler,
-                             StoreFieldInstr* instruction,
-                             Register box_reg,
-                             const Class& cls,
-                             Register instance_reg,
-                             intptr_t offset,
-                             Register temp) {
-  compiler::Label done;
-  __ LoadCompressed(box_reg, compiler::FieldAddress(instance_reg, offset));
-  __ CompareObject(box_reg, Object::null_object());
-  __ j(NOT_EQUAL, &done);
-  BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
-  __ movq(temp, box_reg);
-  __ StoreCompressedIntoObject(instance_reg,
-                               compiler::FieldAddress(instance_reg, offset),
-                               temp, compiler::Assembler::kValueIsNotSmi);
-
-  __ Bind(&done);
-}
-
-void StoreFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(compiler::target::UntaggedObject::kClassIdTagSize == 16);
-  ASSERT(sizeof(UntaggedField::guarded_cid_) == 2);
-  ASSERT(sizeof(UntaggedField::is_nullable_) == 2);
-
-  compiler::Label skip_store;
-
-  const Register instance_reg = locs()->in(kInstancePos).reg();
-  const intptr_t offset_in_bytes = OffsetInBytes();
-  ASSERT(offset_in_bytes > 0);  // Field is finalized and points after header.
-
-  if (slot().representation() != kTagged) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    const Register value = locs()->in(kValuePos).reg();
-    __ Comment("NativeUnboxedStoreFieldInstr");
-    __ StoreFieldToOffset(
-        value, instance_reg, offset_in_bytes,
-        RepresentationUtils::OperandSize(slot().representation()));
-    return;
-  }
-
-  if (IsUnboxedDartFieldStore() && compiler->is_optimizing()) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    XmmRegister value = locs()->in(kValuePos).fpu_reg();
-    const intptr_t cid = slot().field().UnboxedFieldCid();
-
-    // Real unboxed field
-    if (FLAG_precompiled_mode) {
-      switch (cid) {
-        case kDoubleCid:
-          __ Comment("UnboxedDoubleStoreFieldInstr");
-          __ movsd(compiler::FieldAddress(instance_reg, offset_in_bytes),
-                   value);
-          return;
-        case kFloat32x4Cid:
-          __ Comment("UnboxedFloat32x4StoreFieldInstr");
-          __ movups(compiler::FieldAddress(instance_reg, offset_in_bytes),
-                    value);
-          return;
-        case kFloat64x2Cid:
-          __ Comment("UnboxedFloat64x2StoreFieldInstr");
-          __ movups(compiler::FieldAddress(instance_reg, offset_in_bytes),
-                    value);
-          return;
-        default:
-          UNREACHABLE();
-      }
-    }
-
-    Register temp = locs()->temp(0).reg();
-    Register temp2 = locs()->temp(1).reg();
-
-    if (is_initialization()) {
-      const Class* cls = NULL;
-      switch (cid) {
-        case kDoubleCid:
-          cls = &compiler->double_class();
-          break;
-        case kFloat32x4Cid:
-          cls = &compiler->float32x4_class();
-          break;
-        case kFloat64x2Cid:
-          cls = &compiler->float64x2_class();
-          break;
-        default:
-          UNREACHABLE();
-      }
-
-      BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
-      __ movq(temp2, temp);
-      __ StoreCompressedIntoObject(
-          instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
-          temp2, compiler::Assembler::kValueIsNotSmi);
-    } else {
-      __ LoadCompressed(temp,
-                        compiler::FieldAddress(instance_reg, offset_in_bytes));
-    }
-    switch (cid) {
-      case kDoubleCid:
-        __ Comment("UnboxedDoubleStoreFieldInstr");
-        __ movsd(compiler::FieldAddress(temp, Double::value_offset()), value);
-        break;
-      case kFloat32x4Cid:
-        __ Comment("UnboxedFloat32x4StoreFieldInstr");
-        __ movups(compiler::FieldAddress(temp, Float32x4::value_offset()),
-                  value);
-        break;
-      case kFloat64x2Cid:
-        __ Comment("UnboxedFloat64x2StoreFieldInstr");
-        __ movups(compiler::FieldAddress(temp, Float64x2::value_offset()),
-                  value);
-        break;
-      default:
-        UNREACHABLE();
-    }
-    return;
-  }
-
-  if (IsPotentialUnboxedDartFieldStore()) {
-    ASSERT(memory_order_ != compiler::AssemblerBase::kRelease);
-    Register value_reg = locs()->in(kValuePos).reg();
-    Register temp = locs()->temp(0).reg();
-    Register temp2 = locs()->temp(1).reg();
-    FpuRegister fpu_temp = locs()->temp(2).fpu_reg();
-
-    if (ShouldEmitStoreBarrier()) {
-      // Value input is a writable register and should be manually preserved
-      // across allocation slow-path.
-      locs()->live_registers()->Add(locs()->in(kValuePos), kTagged);
-    }
-
-    compiler::Label store_pointer;
-    compiler::Label store_double;
-    compiler::Label store_float32x4;
-    compiler::Label store_float64x2;
-
-    __ LoadObject(temp, Field::ZoneHandle(Z, slot().field().Original()));
-
-    __ cmpw(compiler::FieldAddress(temp, Field::is_nullable_offset()),
-            compiler::Immediate(kNullCid));
-    __ j(EQUAL, &store_pointer);
-
-    __ movzxb(temp2, compiler::FieldAddress(temp, Field::kind_bits_offset()));
-    __ testq(temp2, compiler::Immediate(1 << Field::kUnboxingCandidateBit));
-    __ j(ZERO, &store_pointer);
-
-    __ cmpw(compiler::FieldAddress(temp, Field::guarded_cid_offset()),
-            compiler::Immediate(kDoubleCid));
-    __ j(EQUAL, &store_double);
-
-    __ cmpw(compiler::FieldAddress(temp, Field::guarded_cid_offset()),
-            compiler::Immediate(kFloat32x4Cid));
-    __ j(EQUAL, &store_float32x4);
-
-    __ cmpw(compiler::FieldAddress(temp, Field::guarded_cid_offset()),
-            compiler::Immediate(kFloat64x2Cid));
-    __ j(EQUAL, &store_float64x2);
-
-    // Fall through.
-    __ jmp(&store_pointer);
-
-    if (!compiler->is_optimizing()) {
-      locs()->live_registers()->Add(locs()->in(kInstancePos));
-      locs()->live_registers()->Add(locs()->in(kValuePos));
-    }
-
-    {
-      __ Bind(&store_double);
-      EnsureMutableBox(compiler, this, temp, compiler->double_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ movsd(fpu_temp,
-               compiler::FieldAddress(value_reg, Double::value_offset()));
-      __ movsd(compiler::FieldAddress(temp, Double::value_offset()), fpu_temp);
-      __ jmp(&skip_store);
-    }
-
-    {
-      __ Bind(&store_float32x4);
-      EnsureMutableBox(compiler, this, temp, compiler->float32x4_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ movups(fpu_temp,
-                compiler::FieldAddress(value_reg, Float32x4::value_offset()));
-      __ movups(compiler::FieldAddress(temp, Float32x4::value_offset()),
-                fpu_temp);
-      __ jmp(&skip_store);
-    }
-
-    {
-      __ Bind(&store_float64x2);
-      EnsureMutableBox(compiler, this, temp, compiler->float64x2_class(),
-                       instance_reg, offset_in_bytes, temp2);
-      __ movups(fpu_temp,
-                compiler::FieldAddress(value_reg, Float64x2::value_offset()));
-      __ movups(compiler::FieldAddress(temp, Float64x2::value_offset()),
-                fpu_temp);
-      __ jmp(&skip_store);
-    }
-
-    __ Bind(&store_pointer);
-  }
-
-  const bool compressed = slot().is_compressed();
-  if (ShouldEmitStoreBarrier()) {
-    Register value_reg = locs()->in(kValuePos).reg();
-    if (!compressed) {
-      __ StoreIntoObject(instance_reg,
-                         compiler::FieldAddress(instance_reg, offset_in_bytes),
-                         value_reg, CanValueBeSmi(), memory_order_);
-    } else {
-      __ StoreCompressedIntoObject(
-          instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
-          value_reg, CanValueBeSmi(), memory_order_);
-    }
-  } else {
-    if (locs()->in(kValuePos).IsConstant()) {
-      const auto& value = locs()->in(kValuePos).constant();
-      if (!compressed) {
-        __ StoreIntoObjectNoBarrier(
-            instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
-            value, memory_order_);
-      } else {
-        __ StoreCompressedIntoObjectNoBarrier(
-            instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
-            value, memory_order_);
-      }
-    } else {
-      Register value_reg = locs()->in(kValuePos).reg();
-      if (!compressed) {
-        __ StoreIntoObjectNoBarrier(
-            instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
-            value_reg, memory_order_);
-      } else {
-        __ StoreCompressedIntoObjectNoBarrier(
-            instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
-            value_reg, memory_order_);
-      }
-    }
-  }
-  __ Bind(&skip_store);
-}
-
 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -2906,235 +2652,6 @@
   __ Bind(&done);
 }
 
-LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone,
-                                                     bool opt) const {
-  const intptr_t kNumInputs = 1;
-  LocationSummary* locs = nullptr;
-  if (slot().representation() != kTagged) {
-    ASSERT(!calls_initializer());
-    ASSERT(RepresentationUtils::IsUnboxedInteger(slot().representation()));
-    ASSERT(RepresentationUtils::ValueSize(slot().representation()) <=
-           compiler::target::kWordSize);
-
-    const intptr_t kNumTemps = 0;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-
-  } else if (IsUnboxedDartFieldLoad() && opt) {
-    ASSERT(!calls_initializer());
-    ASSERT(!slot().field().is_non_nullable_integer());
-
-    const intptr_t kNumTemps = FLAG_precompiled_mode ? 0 : 1;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    if (!FLAG_precompiled_mode) {
-      locs->set_temp(0, Location::RequiresRegister());
-    }
-    locs->set_out(0, Location::RequiresFpuRegister());
-
-  } else if (IsPotentialUnboxedDartFieldLoad()) {
-    ASSERT(!calls_initializer());
-    const intptr_t kNumTemps = 2;
-    locs = new (zone) LocationSummary(zone, kNumInputs, kNumTemps,
-                                      LocationSummary::kCallOnSlowPath);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_temp(0, opt ? Location::RequiresFpuRegister()
-                          : Location::FpuRegisterLocation(XMM1));
-    locs->set_temp(1, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-
-  } else if (calls_initializer()) {
-    if (throw_exception_on_initialization()) {
-      const bool using_shared_stub = UseSharedSlowPathStub(opt);
-      const intptr_t kNumTemps = using_shared_stub ? 1 : 0;
-      locs = new (zone) LocationSummary(
-          zone, kNumInputs, kNumTemps,
-          using_shared_stub ? LocationSummary::kCallOnSharedSlowPath
-                            : LocationSummary::kCallOnSlowPath);
-      if (using_shared_stub) {
-        locs->set_temp(0, Location::RegisterLocation(
-                              LateInitializationErrorABI::kFieldReg));
-      }
-      locs->set_in(0, Location::RequiresRegister());
-      locs->set_out(0, Location::RequiresRegister());
-    } else {
-      const intptr_t kNumTemps = 0;
-      locs = new (zone)
-          LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-      locs->set_in(
-          0, Location::RegisterLocation(InitInstanceFieldABI::kInstanceReg));
-      locs->set_out(
-          0, Location::RegisterLocation(InitInstanceFieldABI::kResultReg));
-    }
-  } else {
-    const intptr_t kNumTemps = 0;
-    locs = new (zone)
-        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, Location::RequiresRegister());
-    locs->set_out(0, Location::RequiresRegister());
-  }
-  return locs;
-}
-
-void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(compiler::target::UntaggedObject::kClassIdTagSize == 16);
-  ASSERT(sizeof(UntaggedField::guarded_cid_) == 2);
-  ASSERT(sizeof(UntaggedField::is_nullable_) == 2);
-
-  const Register instance_reg = locs()->in(0).reg();
-  if (slot().representation() != kTagged) {
-    const Register result = locs()->out(0).reg();
-    __ Comment("NativeUnboxedLoadFieldInstr");
-    __ LoadFieldFromOffset(
-        result, instance_reg, OffsetInBytes(),
-        RepresentationUtils::OperandSize(slot().representation()));
-    return;
-  }
-
-  if (IsUnboxedDartFieldLoad() && compiler->is_optimizing()) {
-    XmmRegister result = locs()->out(0).fpu_reg();
-    const intptr_t cid = slot().field().UnboxedFieldCid();
-
-    // Real unboxed field
-    if (FLAG_precompiled_mode) {
-      switch (cid) {
-        case kDoubleCid:
-          __ Comment("UnboxedDoubleLoadFieldInstr");
-          __ movsd(result,
-                   compiler::FieldAddress(instance_reg, OffsetInBytes()));
-          break;
-        case kFloat32x4Cid:
-          __ Comment("UnboxedFloat32x4LoadFieldInstr");
-          __ movups(result,
-                    compiler::FieldAddress(instance_reg, OffsetInBytes()));
-          break;
-        case kFloat64x2Cid:
-          __ Comment("UnboxedFloat64x2LoadFieldInstr");
-          __ movups(result,
-                    compiler::FieldAddress(instance_reg, OffsetInBytes()));
-          break;
-        default:
-          UNREACHABLE();
-      }
-      return;
-    }
-
-    Register temp = locs()->temp(0).reg();
-    __ LoadCompressed(temp,
-                      compiler::FieldAddress(instance_reg, OffsetInBytes()));
-    switch (cid) {
-      case kDoubleCid:
-        __ Comment("UnboxedDoubleLoadFieldInstr");
-        __ movsd(result, compiler::FieldAddress(temp, Double::value_offset()));
-        break;
-      case kFloat32x4Cid:
-        __ Comment("UnboxedFloat32x4LoadFieldInstr");
-        __ movups(result,
-                  compiler::FieldAddress(temp, Float32x4::value_offset()));
-        break;
-      case kFloat64x2Cid:
-        __ Comment("UnboxedFloat64x2LoadFieldInstr");
-        __ movups(result,
-                  compiler::FieldAddress(temp, Float64x2::value_offset()));
-        break;
-      default:
-        UNREACHABLE();
-    }
-    return;
-  }
-
-  compiler::Label done;
-  const Register result = locs()->out(0).reg();
-  if (IsPotentialUnboxedDartFieldLoad()) {
-    Register temp = locs()->temp(1).reg();
-    XmmRegister value = locs()->temp(0).fpu_reg();
-
-    compiler::Label load_pointer;
-    compiler::Label load_double;
-    compiler::Label load_float32x4;
-    compiler::Label load_float64x2;
-
-    __ LoadObject(result, Field::ZoneHandle(slot().field().Original()));
-
-    compiler::FieldAddress field_cid_operand(result,
-                                             Field::guarded_cid_offset());
-    compiler::FieldAddress field_nullability_operand(
-        result, Field::is_nullable_offset());
-
-    __ cmpw(field_nullability_operand, compiler::Immediate(kNullCid));
-    __ j(EQUAL, &load_pointer);
-
-    __ cmpw(field_cid_operand, compiler::Immediate(kDoubleCid));
-    __ j(EQUAL, &load_double);
-
-    __ cmpw(field_cid_operand, compiler::Immediate(kFloat32x4Cid));
-    __ j(EQUAL, &load_float32x4);
-
-    __ cmpw(field_cid_operand, compiler::Immediate(kFloat64x2Cid));
-    __ j(EQUAL, &load_float64x2);
-
-    // Fall through.
-    __ jmp(&load_pointer);
-
-    if (!compiler->is_optimizing()) {
-      locs()->live_registers()->Add(locs()->in(0));
-    }
-
-    {
-      __ Bind(&load_double);
-      BoxAllocationSlowPath::Allocate(compiler, this, compiler->double_class(),
-                                      result, temp);
-      __ LoadCompressed(temp,
-                        compiler::FieldAddress(instance_reg, OffsetInBytes()));
-      __ movsd(value, compiler::FieldAddress(temp, Double::value_offset()));
-      __ movsd(compiler::FieldAddress(result, Double::value_offset()), value);
-      __ jmp(&done);
-    }
-
-    {
-      __ Bind(&load_float32x4);
-      BoxAllocationSlowPath::Allocate(
-          compiler, this, compiler->float32x4_class(), result, temp);
-      __ LoadCompressed(temp,
-                        compiler::FieldAddress(instance_reg, OffsetInBytes()));
-      __ movups(value, compiler::FieldAddress(temp, Float32x4::value_offset()));
-      __ movups(compiler::FieldAddress(result, Float32x4::value_offset()),
-                value);
-      __ jmp(&done);
-    }
-
-    {
-      __ Bind(&load_float64x2);
-      BoxAllocationSlowPath::Allocate(
-          compiler, this, compiler->float64x2_class(), result, temp);
-      __ LoadCompressed(temp,
-                        compiler::FieldAddress(instance_reg, OffsetInBytes()));
-      __ movups(value, compiler::FieldAddress(temp, Float64x2::value_offset()));
-      __ movups(compiler::FieldAddress(result, Float64x2::value_offset()),
-                value);
-      __ jmp(&done);
-    }
-
-    __ Bind(&load_pointer);
-  }
-
-  if (slot().is_compressed()) {
-    __ LoadCompressed(result,
-                      compiler::FieldAddress(instance_reg, OffsetInBytes()));
-  } else {
-    __ movq(result, compiler::FieldAddress(instance_reg, OffsetInBytes()));
-  }
-
-  if (calls_initializer()) {
-    EmitNativeCodeForInitializerCall(compiler);
-  }
-
-  __ Bind(&done);
-}
-
 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
     Zone* zone,
     bool opt) const {
@@ -6479,7 +5996,8 @@
     // The unboxed int64 argument is passed through a dedicated slot in Thread.
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
-    __ movq(compiler::Address(THR, Thread::unboxed_int64_runtime_arg_offset()),
+    __ movq(compiler::Address(
+                THR, compiler::target::Thread::unboxed_runtime_arg_offset()),
             RCX);
   }
 };
@@ -6595,7 +6113,8 @@
     // The unboxed int64 argument is passed through a dedicated slot in Thread.
     // TODO(dartbug.com/33549): Clean this up when unboxed values
     // could be passed as arguments.
-    __ movq(compiler::Address(THR, Thread::unboxed_int64_runtime_arg_offset()),
+    __ movq(compiler::Address(
+                THR, compiler::target::Thread::unboxed_runtime_arg_offset()),
             RCX);
   }
 };
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 7aa88d6..6764ade 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -4216,7 +4216,8 @@
         type = Type::IntType();
       } else if (IsTypeClassId(receiver_cid)) {
         type = Type::DartTypeType();
-      } else if (receiver_cid != kClosureCid) {
+      } else if ((receiver_cid != kClosureCid) &&
+                 (receiver_cid != kRecordCid)) {
         const Class& cls = Class::Handle(
             Z, flow_graph->isolate_group()->class_table()->At(receiver_cid));
         if (!cls.IsGeneric()) {
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 9025738..2d83006 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -2780,6 +2780,7 @@
 
     case Slot::Kind::kDartField:
     case Slot::Kind::kCapturedVariable:
+    case Slot::Kind::kRecordField:
       // Use default value.
       Definition::InferRange(analysis, range);
       break;
@@ -2814,6 +2815,7 @@
     case Slot::Kind::kFunctionType_parameter_types:
     case Slot::Kind::kFunctionType_type_parameters:
     case Slot::Kind::kInstance_native_fields_array:
+    case Slot::Kind::kRecord_field_names:
     case Slot::Kind::kSuspendState_function_data:
     case Slot::Kind::kSuspendState_then_callback:
     case Slot::Kind::kSuspendState_error_callback:
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index da13b09..42edaaf 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -3042,7 +3042,9 @@
   bool CanEliminateStore(Instruction* instr) {
     if (CompilerState::Current().is_aot()) {
       // Tracking initializing stores is important for proper shared boxes
-      // initialization, which doesn't happen in AOT.
+      // initialization, which doesn't happen in AOT and for
+      // LowerContextAllocation optimization which creates unitialized objects
+      // which is also JIT-only currently.
       return true;
     }
     switch (instr->tag()) {
@@ -3065,6 +3067,28 @@
     BitVector* all_places =
         new (zone) BitVector(zone, aliased_set_->max_place_id());
     all_places->SetAll();
+
+    BitVector* all_aliased_places =
+        new (zone) BitVector(zone, aliased_set_->max_place_id());
+    if (CompilerState::Current().is_aot()) {
+      const auto& places = aliased_set_->places();
+      // Go through all places and identify those which are escaping.
+      // We find such places by inspecting definition allocation
+      // [AliasIdentity] field, which is populated above by
+      // [AliasedSet::ComputeAliasing].
+      for (intptr_t i = 0; i < places.length(); i++) {
+        Place* place = places[i];
+        if (place->DependsOnInstance()) {
+          Definition* instance = place->instance();
+          if (Place::IsAllocation(instance) &&
+              !instance->Identity().IsAliased()) {
+            continue;
+          }
+        }
+        all_aliased_places->Add(i);
+      }
+    }
+
     for (BlockIterator block_it = graph_->postorder_iterator();
          !block_it.Done(); block_it.Advance()) {
       BlockEntryInstr* block = block_it.Current();
@@ -3118,19 +3142,52 @@
           continue;
         }
 
+        if (instr->IsThrow() || instr->IsReThrow() || instr->IsReturn()) {
+          // Initialize live-out for exit blocks since it won't be computed
+          // otherwise during the fixed point iteration.
+          live_out->CopyFrom(all_places);
+        }
+
         // Handle side effects, deoptimization and function return.
-        if (instr->HasUnknownSideEffects() || instr->CanDeoptimize() ||
-            instr->MayThrow() || instr->IsReturn()) {
-          // Instructions that return from the function, instructions with side
-          // effects and instructions that can deoptimize are considered as
-          // loads from all places.
-          live_in->CopyFrom(all_places);
-          if (instr->IsThrow() || instr->IsReThrow() || instr->IsReturn()) {
-            // Initialize live-out for exit blocks since it won't be computed
-            // otherwise during the fixed point iteration.
-            live_out->CopyFrom(all_places);
+        if (CompilerState::Current().is_aot()) {
+          // Instructions that return from the function, instructions with
+          // side effects are considered as loads from all places.
+          if (instr->HasUnknownSideEffects() || instr->IsReturn() ||
+              instr->MayThrow()) {
+            if (instr->HasUnknownSideEffects() || instr->IsReturn()) {
+              // Instructions that may throw and has unknown side effects
+              // still load from all places.
+              live_in->CopyFrom(all_places);
+            } else {
+              // If we are oustide of try-catch block, instructions that "may
+              // throw" only "load from escaping places".
+              // If we are inside of try-catch block, instructions that "may
+              // throw" also "load from all places".
+              if (block->try_index() == kInvalidTryIndex) {
+                live_in->AddAll(all_aliased_places);
+              } else {
+                live_in->CopyFrom(all_places);
+              }
+            }
+            continue;
           }
-          continue;
+        } else {  // jit
+          // Similar optimization to the above could be implemented in JIT
+          // as long as deoptimization side-effects are taken into account.
+          // Conceptually variables in deoptimization environment for
+          // "MayThrow" instructions have to be also added to the
+          // [live_in] set as they can be considered as escaping (to
+          // unoptimized code). However those deoptimization environment
+          // variables include also non-escaping(not aliased) ones, so
+          // how to deal with that needs to be figured out.
+          if (instr->HasUnknownSideEffects() || instr->CanDeoptimize() ||
+              instr->MayThrow() || instr->IsReturn()) {
+            // Instructions that return from the function, instructions with
+            // side effects and instructions that can deoptimize are considered
+            // as loads from all places.
+            live_in->CopyFrom(all_places);
+            continue;
+          }
         }
 
         // Handle loads.
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index cd7f791..4518130 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -1152,6 +1152,48 @@
   EXPECT(store3->instance()->definition() == allocate);
 }
 
+ISOLATE_UNIT_TEST_CASE(LoadOptimizer_RedundantStoreAOT) {
+  const char* kScript = R"(
+class Foo {
+  int x = -1;
+
+  toString() => "Foo x: $x";
+}
+
+class Bar {}
+
+main() {
+  final foo = Foo();
+  foo.x = 11;
+  new Bar();
+  foo.x = 12;
+  new Bar();
+  foo.x = 13;
+  return foo;
+}
+  )";
+
+  const auto& root_library = Library::Handle(LoadTestScript(kScript));
+  Invoke(root_library, "main");
+  const auto& function = Function::Handle(GetFunction(root_library, "main"));
+  TestPipeline pipeline(function, CompilerPass::kAOT);
+  FlowGraph* flow_graph = pipeline.RunPasses({});
+  auto entry = flow_graph->graph_entry()->normal_entry();
+
+  AllocateObjectInstr* allocate;
+  StoreFieldInstr* store1;
+
+  ILMatcher cursor(flow_graph, entry, true, ParallelMovesHandling::kSkip);
+  RELEASE_ASSERT(cursor.TryMatch({
+      kMoveGlob,
+      {kMatchAndMoveAllocateObject, &allocate},
+      {kMatchAndMoveStoreField, &store1},  // initializing store
+      kMatchReturn,
+  }));
+
+  EXPECT(store1->instance()->definition() == allocate);
+}
+
 #endif  // !defined(TARGET_ARCH_IA32)
 
 ISOLATE_UNIT_TEST_CASE(AllocationSinking_Arrays) {
@@ -1473,7 +1515,9 @@
 
   using compiler::BlockBuilder;
   CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
-  FlowGraphBuilderHelper H;
+  FlowGraphBuilderHelper H(/*num_parameters=*/2);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::DynamicType()));
+  H.AddVariable("v1", AbstractType::ZoneHandle(Type::DynamicType()));
 
   auto b1 = H.flow_graph()->graph_entry()->normal_entry();
 
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index 46acba6..93f6f2a 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -46,61 +46,6 @@
   PointerSet<const Slot> fields_;
 };
 
-#define NATIVE_SLOT_NAME(C, F) Kind::k##C##_##F
-#define NATIVE_TO_STR(C, F) #C "_" #F
-
-const char* Slot::KindToCString(Kind k) {
-  switch (k) {
-#define NATIVE_CASE(C, __, F, ___, ____)                                       \
-  case NATIVE_SLOT_NAME(C, F):                                                 \
-    return NATIVE_TO_STR(C, F);
-    NATIVE_SLOTS_LIST(NATIVE_CASE)
-#undef NATIVE_CASE
-    case Kind::kTypeArguments:
-      return "TypeArguments";
-    case Kind::kArrayElement:
-      return "ArrayElement";
-    case Kind::kCapturedVariable:
-      return "CapturedVariable";
-    case Kind::kDartField:
-      return "DartField";
-    default:
-      UNREACHABLE();
-      return nullptr;
-  }
-}
-
-bool Slot::ParseKind(const char* str, Kind* out) {
-  ASSERT(str != nullptr && out != nullptr);
-#define NATIVE_CASE(C, __, F, ___, ____)                                       \
-  if (strcmp(str, NATIVE_TO_STR(C, F)) == 0) {                                 \
-    *out = NATIVE_SLOT_NAME(C, F);                                             \
-    return true;                                                               \
-  }
-  NATIVE_SLOTS_LIST(NATIVE_CASE)
-#undef NATIVE_CASE
-  if (strcmp(str, "TypeArguments") == 0) {
-    *out = Kind::kTypeArguments;
-    return true;
-  }
-  if (strcmp(str, "ArrayElement") == 0) {
-    *out = Kind::kArrayElement;
-    return true;
-  }
-  if (strcmp(str, "CapturedVariable") == 0) {
-    *out = Kind::kCapturedVariable;
-    return true;
-  }
-  if (strcmp(str, "DartField") == 0) {
-    *out = Kind::kDartField;
-    return true;
-  }
-  return false;
-}
-
-#undef NATIVE_TO_STR
-#undef NATIVE_SLOT_NAME
-
 static classid_t GetUnboxedNativeSlotCid(Representation rep) {
   // Currently we only support integer unboxed fields.
   if (RepresentationUtils::IsUnboxedInteger(rep)) {
@@ -243,6 +188,8 @@
     case Slot::Kind::kFunctionType_named_parameter_names:
     case Slot::Kind::kFunctionType_parameter_types:
     case Slot::Kind::kFunctionType_type_parameters:
+    case Slot::Kind::kRecordField:
+    case Slot::Kind::kRecord_field_names:
     case Slot::Kind::kSuspendState_function_data:
     case Slot::Kind::kSuspendState_then_callback:
     case Slot::Kind::kSuspendState_error_callback:
@@ -345,6 +292,15 @@
       /*static_type=*/nullptr, kTagged);
 }
 
+const Slot& Slot::GetRecordFieldSlot(Thread* thread, intptr_t offset_in_bytes) {
+  return GetCanonicalSlot(
+      thread, Kind::kRecordField,
+      IsNullableBit::encode(true) |
+          IsCompressedBit::encode(Record::ContainsCompressedPointers()),
+      kDynamicCid, offset_in_bytes, ":record_field",
+      /*static_type=*/nullptr, kTagged);
+}
+
 const Slot& Slot::GetCanonicalSlot(Thread* thread,
                                    Slot::Kind kind,
                                    int8_t flags,
@@ -361,42 +317,8 @@
 
 FieldGuardState::FieldGuardState(const Field& field)
     : state_(GuardedCidBits::encode(field.guarded_cid()) |
-             IsNonNullableIntegerBit::encode(field.is_non_nullable_integer()) |
-             IsUnboxingCandidateBit::encode(field.is_unboxing_candidate()) |
              IsNullableBit::encode(field.is_nullable())) {}
 
-bool FieldGuardState::IsUnboxed() const {
-  ASSERT(!is_non_nullable_integer() || FLAG_precompiled_mode);
-  const bool valid_class = ((FlowGraphCompiler::SupportsUnboxedDoubles() &&
-                             (guarded_cid() == kDoubleCid)) ||
-                            (FlowGraphCompiler::SupportsUnboxedSimd128() &&
-                             (guarded_cid() == kFloat32x4Cid)) ||
-                            (FlowGraphCompiler::SupportsUnboxedSimd128() &&
-                             (guarded_cid() == kFloat64x2Cid)) ||
-                            is_non_nullable_integer());
-  return is_unboxing_candidate() && !is_nullable() && valid_class;
-}
-
-bool FieldGuardState::IsPotentialUnboxed() const {
-  if (FLAG_precompiled_mode) {
-    // kernel_loader.cc:ReadInferredType sets the guarded cid for fields based
-    // on inferred types from TFA (if available). The guarded cid is therefore
-    // proven to be correct.
-    return IsUnboxed();
-  }
-
-  return is_unboxing_candidate() &&
-         (IsUnboxed() || (guarded_cid() == kIllegalCid));
-}
-
-bool Slot::IsUnboxed() const {
-  return field_guard_state().IsUnboxed();
-}
-
-bool Slot::IsPotentialUnboxed() const {
-  return field_guard_state().IsPotentialUnboxed();
-}
-
 Representation Slot::UnboxedRepresentation() const {
   switch (field_guard_state().guarded_cid()) {
     case kDoubleCid:
@@ -406,7 +328,6 @@
     case kFloat64x2Cid:
       return kUnboxedFloat64x2;
     default:
-      RELEASE_ASSERT(field_guard_state().is_non_nullable_integer());
       return kUnboxedInt64;
   }
 }
@@ -459,11 +380,22 @@
     used_guarded_state = false;
   }
 
-  if (field_guard_state.is_non_nullable_integer()) {
-    ASSERT(FLAG_precompiled_mode);
+  const bool is_unboxed = field.is_unboxed();
+  if (is_unboxed) {
     is_nullable = false;
-    if (field_guard_state.IsUnboxed()) {
-      rep = kUnboxedInt64;
+    switch (field_guard_state.guarded_cid()) {
+      case kDoubleCid:
+        rep = kUnboxedDouble;
+        break;
+      case kFloat32x4Cid:
+        rep = kUnboxedFloat32x4;
+        break;
+      case kFloat64x2Cid:
+        rep = kUnboxedFloat64x2;
+        break;
+      default:
+        rep = kUnboxedInt64;
+        break;
     }
   }
 
@@ -477,7 +409,8 @@
           IsCompressedBit::encode(
               compiler::target::Class::HasCompressedPointers(owner)) |
           IsSentinelVisibleBit::encode(field.is_late() && field.is_final() &&
-                                       !field.has_initializer()),
+                                       !field.has_initializer()) |
+          IsUnboxedBit::encode(is_unboxed),
       nullable_cid, compiler::target::Field::OffsetOf(field), &field, &type,
       rep, field_guard_state);
 
@@ -567,6 +500,7 @@
     case Kind::kTypeArguments:
     case Kind::kTypeArgumentsIndex:
     case Kind::kArrayElement:
+    case Kind::kRecordField:
       return true;
 
     case Kind::kCapturedVariable:
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index 90838c9..61d395b 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -125,6 +125,7 @@
   V(ArgumentsDescriptor, UntaggedArray, positional_count, Smi, FINAL)          \
   V(ArgumentsDescriptor, UntaggedArray, count, Smi, FINAL)                     \
   V(ArgumentsDescriptor, UntaggedArray, size, Smi, FINAL)                      \
+  V(Record, UntaggedRecord, field_names, Array, FINAL)                         \
   V(TypeArguments, UntaggedTypeArguments, length, Smi, FINAL)                  \
   V(TypeParameters, UntaggedTypeParameters, names, Array, FINAL)               \
   V(TypeParameter, UntaggedTypeParameter, bound, Dynamic, FINAL)               \
@@ -182,7 +183,7 @@
   V(FunctionType, UntaggedFunctionType, packed_type_parameter_counts, Uint16,  \
     FINAL)                                                                     \
   V(PointerBase, UntaggedPointerBase, data, IntPtr, VAR)                       \
-  V(TypeParameter, UntaggedTypeParameter, flags, Uint8, FINAL)
+  V(Record, UntaggedRecord, num_fields, Int32, FINAL)
 
 // For uses that do not need the exact_type (boxed) or representation (unboxed)
 // or whether a boxed native slot is nullable. (Generally, such users only need
@@ -198,25 +199,11 @@
   explicit FieldGuardState(const Field& field);
 
   intptr_t guarded_cid() const { return GuardedCidBits::decode(state_); }
-  bool is_non_nullable_integer() const {
-    return IsNonNullableIntegerBit::decode(state_);
-  }
-  bool is_unboxing_candidate() const {
-    return IsUnboxingCandidateBit::decode(state_);
-  }
   bool is_nullable() const { return IsNullableBit::decode(state_); }
 
-  bool IsUnboxed() const;
-  bool IsPotentialUnboxed() const;
-
  private:
   using GuardedCidBits = BitField<int32_t, ClassIdTagType, 0, 16>;
-  using IsNonNullableIntegerBit =
-      BitField<int32_t, bool, GuardedCidBits::kNextBit, 1>;
-  using IsUnboxingCandidateBit =
-      BitField<int32_t, bool, IsNonNullableIntegerBit::kNextBit, 1>;
-  using IsNullableBit =
-      BitField<int32_t, bool, IsUnboxingCandidateBit::kNextBit, 1>;
+  using IsNullableBit = BitField<int32_t, bool, GuardedCidBits::kNextBit, 1>;
 
   const int32_t state_;
 };
@@ -248,6 +235,9 @@
     // Only used during allocation sinking and in MaterializeObjectInstr.
     kArrayElement,
 
+    // A slot corresponding to a record field at the given offset.
+    kRecordField,
+
     // A slot within a Context object that contains a value of a captured
     // local variable.
     kCapturedVariable,
@@ -257,9 +247,6 @@
   };
   // clang-format on
 
-  static const char* KindToCString(Kind k);
-  static bool ParseKind(const char* str, Kind* k);
-
   // Returns a slot that represents length field for the given [array_cid].
   static const Slot& GetLengthFieldForArrayCid(intptr_t array_cid);
 
@@ -278,6 +265,12 @@
   static const Slot& GetArrayElementSlot(Thread* thread,
                                          intptr_t offset_in_bytes);
 
+  // Returns a slot corresponding to a record field at [offset_in_bytes].
+  // TODO(dartbug.com/49719): distinguish slots of records with different
+  // shapes.
+  static const Slot& GetRecordFieldSlot(Thread* thread,
+                                        intptr_t offset_in_bytes);
+
   // Returns a slot that represents the given captured local variable.
   static const Slot& GetContextVariableSlotFor(Thread* thread,
                                                const LocalVariable& var);
@@ -301,6 +294,9 @@
   bool IsTypeArguments() const { return kind() == Kind::kTypeArguments; }
   bool IsArgumentOfType() const { return kind() == Kind::kTypeArgumentsIndex; }
   bool IsArrayElement() const { return kind() == Kind::kArrayElement; }
+  bool IsRecordField() const {
+    return kind() == Kind::kRecordField;
+  }
   bool IsImmutableLengthSlot() const;
 
   const char* Name() const;
@@ -353,8 +349,9 @@
     return kind() == Kind::kCapturedVariable || kind() == Kind::kContext_parent;
   }
 
-  bool IsUnboxed() const;
-  bool IsPotentialUnboxed() const;
+  bool is_unboxed() const {
+    return IsUnboxedBit::decode(flags_);
+  }
   Representation UnboxedRepresentation() const;
 
   void Write(FlowGraphSerializer* s) const;
@@ -394,6 +391,8 @@
   using IsCompressedBit = BitField<int8_t, bool, IsGuardedBit::kNextBit, 1>;
   using IsSentinelVisibleBit =
       BitField<int8_t, bool, IsCompressedBit::kNextBit, 1>;
+  using IsUnboxedBit =
+      BitField<int8_t, bool, IsSentinelVisibleBit::kNextBit, 1>;
 
   template <typename T>
   const T* DataAs() const {
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 903393e..d56c09b 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -599,7 +599,7 @@
   // Climb up the hierarchy to find a suitable supertype. Note that interface
   // types are not considered, making the union potentially non-commutative
   if (abstract_type->IsInstantiated() && !abstract_type->IsDynamicType() &&
-      !abstract_type->IsFunctionType()) {
+      !abstract_type->IsFunctionType() && !abstract_type->IsRecordType()) {
     Class& cls = Class::Handle(abstract_type->type_class());
     for (; !cls.IsNull() && !cls.IsGeneric(); cls = cls.SuperClass()) {
       type_ = &AbstractType::ZoneHandle(cls.RareType());
@@ -773,6 +773,8 @@
       cid_ = kSentinelCid;
     } else if (type_->IsFunctionType() || type_->IsDartFunctionType()) {
       cid_ = kClosureCid;
+    } else if (type_->IsRecordType() || type_->IsDartRecordType()) {
+      cid_ = kRecordCid;
     } else if (type_->type_class_id() != kIllegalCid) {
       const Class& type_class = Class::Handle(type_->type_class());
       intptr_t implementation_cid = kIllegalCid;
@@ -1158,7 +1160,8 @@
     return CompileType::Dynamic();
   }
 
-  const Function& function = graph_entry->parsed_function().function();
+  const ParsedFunction& pf = graph_entry->parsed_function();
+  const Function& function = pf.function();
   if (function.IsIrregexpFunction()) {
     // In irregexp functions, types of input parameters are known and immutable.
     // Set parameter types here in order to prevent unnecessary CheckClassInstr
@@ -1177,64 +1180,72 @@
     return CompileType::Dynamic();
   }
 
-  // Parameter is the receiver.
-  if ((index() == 0) &&
-      (function.IsDynamicFunction() || function.IsGenerativeConstructor())) {
-    const AbstractType& type =
-        graph_entry->parsed_function().RawParameterVariable(0)->type();
-    if (type.IsObjectType() || type.IsNullType()) {
-      // Receiver can be null.
-      return CompileType::FromAbstractType(type, CompileType::kCanBeNull,
-                                           CompileType::kCannotBeSentinel);
-    }
+  // Figure out if this Parameter instruction corresponds to a direct
+  // parameter. See FlowGraph::EnvIndex and initialization of
+  // num_direct_parameters_ in FlowGraph constructor.
+  const bool is_direct_parameter =
+      !function.MakesCopyOfParameters() && (index() < function.NumParameters());
+  // Parameter instructions in a function entry are only used for direct
+  // parameters. Parameter instructions in OsrEntry and CatchBlockEntry
+  // correspond to all local variables, not just direct parameters.
+  // OsrEntry is already checked above.
+  ASSERT(is_direct_parameter || block_->IsCatchBlockEntry());
 
-    // Receiver can't be null but can be an instance of a subclass.
-    intptr_t cid = kDynamicCid;
+  // The code below assumes that env index matches parameter index.
+  // This is true only for direct parameters.
+  if (is_direct_parameter) {
+    const intptr_t param_index = index();
+    // Parameter is the receiver.
+    if ((param_index == 0) &&
+        (function.IsDynamicFunction() || function.IsGenerativeConstructor())) {
+      const AbstractType& type = pf.RawParameterVariable(0)->type();
+      if (type.IsObjectType() || type.IsNullType()) {
+        // Receiver can be null.
+        return CompileType::FromAbstractType(type, CompileType::kCanBeNull,
+                                             CompileType::kCannotBeSentinel);
+      }
 
-    if (type.type_class_id() != kIllegalCid) {
-      Thread* thread = Thread::Current();
-      const Class& type_class = Class::Handle(type.type_class());
-      if (!CHA::HasSubclasses(type_class)) {
-        if (type_class.IsPrivate()) {
-          // Private classes can never be subclassed by later loaded libs.
-          cid = type_class.id();
-        } else {
-          if (FLAG_use_cha_deopt ||
-              thread->isolate_group()->all_classes_finalized()) {
-            if (FLAG_trace_cha) {
-              THR_Print(
-                  "  **(CHA) Computing exact type of receiver, "
-                  "no subclasses: %s\n",
-                  type_class.ToCString());
-            }
-            if (FLAG_use_cha_deopt) {
-              thread->compiler_state().cha().AddToGuardedClasses(
-                  type_class,
-                  /*subclass_count=*/0);
-            }
+      // Receiver can't be null but can be an instance of a subclass.
+      intptr_t cid = kDynamicCid;
+
+      if (type.type_class_id() != kIllegalCid) {
+        Thread* thread = Thread::Current();
+        const Class& type_class = Class::Handle(type.type_class());
+        if (!CHA::HasSubclasses(type_class)) {
+          if (type_class.IsPrivate()) {
+            // Private classes can never be subclassed by later loaded libs.
             cid = type_class.id();
+          } else {
+            if (FLAG_use_cha_deopt ||
+                thread->isolate_group()->all_classes_finalized()) {
+              if (FLAG_trace_cha) {
+                THR_Print(
+                    "  **(CHA) Computing exact type of receiver, "
+                    "no subclasses: %s\n",
+                    type_class.ToCString());
+              }
+              if (FLAG_use_cha_deopt) {
+                thread->compiler_state().cha().AddToGuardedClasses(
+                    type_class,
+                    /*subclass_count=*/0);
+              }
+              cid = type_class.id();
+            }
           }
         }
       }
+
+      return CompileType(CompileType::kCannotBeNull,
+                         CompileType::kCannotBeSentinel, cid, &type);
     }
 
-    return CompileType(CompileType::kCannotBeNull,
-                       CompileType::kCannotBeSentinel, cid, &type);
-  }
+    const bool is_unchecked_entry_param =
+        graph_entry->unchecked_entry() == block_;
 
-  const bool is_unchecked_entry_param =
-      graph_entry->unchecked_entry() == block_;
-
-  LocalScope* scope = graph_entry->parsed_function().scope();
-  // Note: in catch-blocks we have ParameterInstr for each local variable
-  // not only for normal parameters.
-  const LocalVariable* param = nullptr;
-  if (scope != nullptr && (index() < scope->num_variables())) {
-    param = scope->VariableAt(index());
-  } else if (index() < function.NumParameters()) {
-    param = graph_entry->parsed_function().RawParameterVariable(index());
-  }
-  if (param != nullptr) {
+    const LocalVariable* param = (pf.scope() != nullptr)
+                                     ? pf.ParameterVariable(param_index)
+                                     : pf.RawParameterVariable(param_index);
+    ASSERT(param != nullptr);
     CompileType* inferred_type = NULL;
     if (!block_->IsCatchBlockEntry()) {
       inferred_type = param->parameter_type();
@@ -1638,6 +1649,10 @@
   return CompileType::FromCid(kClosureCid);
 }
 
+CompileType AllocateRecordInstr::ComputeType() const {
+  return CompileType::FromCid(kRecordCid);
+}
+
 CompileType LoadUntaggedInstr::ComputeType() const {
   return CompileType::Dynamic();
 }
@@ -1975,6 +1990,9 @@
     case kTypedDataUint64ArrayCid:
       return CompileType::Int();
 
+    case kRecordCid:
+      return CompileType::Dynamic();
+
     default:
       UNIMPLEMENTED();
       return CompileType::Dynamic();
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index 899e485..3d8aa3f 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -28,16 +28,8 @@
 ISOLATE_UNIT_TEST_CASE(TypePropagator_RedefinitionAfterStrictCompareWithNull) {
   CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
 
-  FlowGraphBuilderHelper H;
-
-  // Add a variable into the scope which would provide static type for the
-  // parameter.
-  LocalVariable* v0_var =
-      new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
-                        String::Handle(Symbols::New(thread, "v0")),
-                        AbstractType::ZoneHandle(Type::IntType()));
-  v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
-  H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);
+  FlowGraphBuilderHelper H(/*num_parameters=*/1);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::IntType()));
 
   auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
 
@@ -103,7 +95,8 @@
     TypePropagator_RedefinitionAfterStrictCompareWithLoadClassId) {
   CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
 
-  FlowGraphBuilderHelper H;
+  FlowGraphBuilderHelper H(/*num_parameters=*/1);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::DynamicType()));
 
   // We are going to build the following graph:
   //
@@ -194,7 +187,8 @@
     thread->isolate_group()->RegisterStaticField(field, Object::Handle());
   }
 
-  FlowGraphBuilderHelper H;
+  FlowGraphBuilderHelper H(/*num_parameters=*/1);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::DynamicType()));
 
   // We are going to build the following graph:
   //
@@ -273,7 +267,8 @@
 // as reaching types after inference.
 ISOLATE_UNIT_TEST_CASE(TypePropagator_Regress36156) {
   CompilerState S(thread, /*is_aot=*/false, /*is_optimizing=*/true);
-  FlowGraphBuilderHelper H;
+  FlowGraphBuilderHelper H(/*num_parameters=*/1);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::DynamicType()));
 
   // We are going to build the following graph:
   //
@@ -498,16 +493,8 @@
 ISOLATE_UNIT_TEST_CASE(TypePropagator_RegressFlutter76919) {
   CompilerState S(thread, /*is_aot=*/true, /*is_optimizing=*/true);
 
-  FlowGraphBuilderHelper H;
-
-  // Add a variable into the scope which would provide static type for the
-  // parameter.
-  LocalVariable* v0_var =
-      new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
-                        String::Handle(Symbols::New(thread, "v0")),
-                        AbstractType::ZoneHandle(Type::DynamicType()));
-  v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
-  H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);
+  FlowGraphBuilderHelper H(/*num_parameters=*/1);
+  H.AddVariable("v0", AbstractType::ZoneHandle(Type::DynamicType()));
 
   auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
 
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index f9198c3..b5b1671 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -1041,7 +1041,7 @@
   ASSERT(results->is_empty());
   ASSERT(ic_data.NumArgsTested() == 1);  // Unary checks only.
   if (type.IsFunctionType() || type.IsDartFunctionType() ||
-      !type.IsInstantiated()) {
+      type.IsRecordType() || !type.IsInstantiated()) {
     return Bool::null();
   }
   const Class& type_class = Class::Handle(Z, type.type_class());
@@ -1108,8 +1108,8 @@
   ASSERT(type.IsFinalized());
   // Requires CHA.
   if (!type.IsInstantiated()) return false;
-  // Function types have different type checking rules.
-  if (type.IsFunctionType()) return false;
+  // Function and record types have different type checking rules.
+  if (type.IsFunctionType() || type.IsRecordType()) return false;
 
   const Class& type_class = Class::Handle(type.type_class());
   if (!CHA::HasSingleConcreteImplementation(type_class, type_cid)) {
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index e07ef88..4e7ec53 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -547,8 +547,14 @@
   const Field& field_clone = MayCloneField(Z, field);
   if (IG->use_field_guards()) {
     LocalVariable* store_expression = MakeTemporary();
-    instructions += LoadLocal(store_expression);
-    instructions += GuardFieldClass(field_clone, GetNextDeoptId());
+
+    // Note: unboxing decision can only change due to hot reload at which
+    // point all code will be cleared, so there is no need to worry about
+    // stability of deopt id numbering.
+    if (!field_clone.is_unboxed()) {
+      instructions += LoadLocal(store_expression);
+      instructions += GuardFieldClass(field_clone, GetNextDeoptId());
+    }
 
     // Field length guard can be omitted if it is not needed.
     // However, it is possible that we were tracking list length previously,
@@ -933,6 +939,15 @@
   return Fragment(array);
 }
 
+Fragment BaseFlowGraphBuilder::AllocateRecord(TokenPosition position,
+                                              intptr_t num_fields,
+                                              const Array& field_names) {
+  AllocateRecordInstr* allocate = new (Z) AllocateRecordInstr(
+      InstructionSource(position), num_fields, field_names, GetNextDeoptId());
+  Push(allocate);
+  return Fragment(allocate);
+}
+
 Fragment BaseFlowGraphBuilder::AllocateTypedData(TokenPosition position,
                                                  classid_t class_id) {
   Value* num_elements = Pop();
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index ab19fdd..95d297c 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -353,6 +353,9 @@
   // Top of the stack should be the closure function.
   Fragment AllocateClosure(TokenPosition position = TokenPosition::kNoSource);
   Fragment CreateArray();
+  Fragment AllocateRecord(TokenPosition position,
+                          intptr_t num_fields,
+                          const Array& field_names);
   Fragment AllocateTypedData(TokenPosition position, classid_t class_id);
   Fragment InstantiateType(const AbstractType& type);
   Fragment InstantiateTypeArguments(const TypeArguments& type_arguments);
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index ca1f9dc..753e55a 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -312,6 +312,48 @@
       instance = map.ptr();
       break;
     }
+    case kRecordConstant: {
+      const intptr_t num_positional = reader.ReadListLength();
+      intptr_t num_named = 0;
+      const Array* field_names = &Array::empty_array();
+      {
+        AlternativeReadingScope alt(&reader.reader_);
+        for (intptr_t j = 0; j < num_positional; ++j) {
+          reader.ReadUInt();
+        }
+        num_named = reader.ReadListLength();
+        if (num_named > 0) {
+          auto& names = Array::Handle(Z, Array::New(num_named));
+          for (intptr_t j = 0; j < num_named; ++j) {
+            String& name = H.DartSymbolObfuscate(reader.ReadStringReference());
+            names.SetAt(j, name);
+            reader.ReadUInt();
+          }
+          names ^= H.Canonicalize(names);
+          field_names = &names;
+        }
+      }
+      const intptr_t num_fields = num_positional + num_named;
+      const auto& record =
+          Record::Handle(Z, Record::New(num_fields, *field_names));
+      intptr_t pos = 0;
+      for (intptr_t j = 0; j < num_positional; ++j) {
+        const intptr_t entry_index = reader.ReadUInt();
+        ASSERT(entry_index < constant_offset);  // DAG!
+        instance = ReadConstant(entry_index);
+        record.SetFieldAt(pos++, instance);
+      }
+      reader.ReadListLength();
+      for (intptr_t j = 0; j < num_named; ++j) {
+        reader.ReadStringReference();
+        const intptr_t entry_index = reader.ReadUInt();
+        ASSERT(entry_index < constant_offset);  // DAG!
+        instance = ReadConstant(entry_index);
+        record.SetFieldAt(pos++, instance);
+      }
+      instance = record.ptr();
+      break;
+    }
     case kSetConstant: {
       const auto& set_class = Class::Handle(
           Z,
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index 110dbc0..b580536 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -373,8 +373,11 @@
   // Bail if the type is still uninstantiated at compile time.
   if (!type.IsInstantiated()) return false;
 
-  // Bail if the type is a function or a Dart Function type.
-  if (type.IsFunctionType() || type.IsDartFunctionType()) return false;
+  // Bail if the type is a function, record or a Dart Function type.
+  if (type.IsFunctionType() || type.IsRecordType() ||
+      type.IsDartFunctionType()) {
+    return false;
+  }
 
   ASSERT(type.HasTypeClass());
   const Class& type_class = Class::Handle(type.type_class());
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index c453878..14c268f 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -678,11 +678,11 @@
 
   if (dart_function.is_native()) {
     body += B->NativeFunctionBody(dart_function, first_parameter);
-  } else if (has_body) {
-    body += BuildStatement();
   } else if (dart_function.is_external()) {
     body +=
         ThrowNoSuchMethodError(dart_function, /*incompatible_arguments=*/false);
+  } else if (has_body) {
+    body += BuildStatement();
   }
 
   if (body.is_open()) {
@@ -1129,6 +1129,12 @@
       break;
     case kMapLiteral:
       return BuildMapLiteral(position);
+    case kRecordLiteral:
+      return BuildRecordLiteral(position);
+    case kRecordIndexGet:
+      return BuildRecordFieldGet(position, /*is_named=*/false);
+    case kRecordNameGet:
+      return BuildRecordFieldGet(position, /*is_named=*/true);
     case kFunctionExpression:
       return BuildFunctionExpression();
     case kLet:
@@ -2828,7 +2834,6 @@
   } else {
     const Field& field =
         Field::ZoneHandle(Z, H.LookupFieldByKernelGetterOrSetter(target));
-    ASSERT(!field.NeedsSetter());
     if (NeedsDebugStepCheck(stack(), position)) {
       instructions = DebugStepCheck(position) + instructions;
     }
@@ -4026,6 +4031,99 @@
          StaticCall(position, factory_method, 2, ICData::kStatic);
 }
 
+Fragment StreamingFlowGraphBuilder::BuildRecordLiteral(TokenPosition* p) {
+  const TokenPosition position = ReadPosition();  // read position.
+  if (p != nullptr) *p = position;
+
+  // Figure out record shape.
+  const intptr_t positional_count = ReadListLength();
+  intptr_t named_count = -1;
+  const Array* field_names = &Object::empty_array();
+  {
+    AlternativeReadingScope alt(&reader_);
+    for (intptr_t i = 0; i < positional_count; ++i) {
+      SkipExpression();
+    }
+    named_count = ReadListLength();
+    if (named_count > 0) {
+      Array& names = Array::ZoneHandle(Z, Array::New(named_count, Heap::kOld));
+      for (intptr_t i = 0; i < named_count; ++i) {
+        String& name =
+            H.DartSymbolObfuscate(ReadStringReference());  // read ith name.
+        SkipExpression();  // read ith expression.
+        names.SetAt(i, name);
+      }
+      names ^= H.Canonicalize(names);
+      field_names = &names;
+    }
+  }
+  const intptr_t num_fields = positional_count + named_count;
+
+  // TODO(dartbug.com/49719): provide specialized allocation stubs for small
+  // records.
+
+  Fragment instructions;
+  instructions += B->AllocateRecord(position, num_fields, *field_names);
+  LocalVariable* record = MakeTemporary();
+
+  // List of positional.
+  intptr_t pos = 0;
+  for (intptr_t i = 0; i < positional_count; ++i, ++pos) {
+    instructions += LoadLocal(record);
+    instructions += BuildExpression();  // read ith expression.
+    instructions += B->StoreNativeField(
+        Slot::GetRecordFieldSlot(thread(),
+                                 compiler::target::Record::field_offset(pos)),
+        StoreFieldInstr::Kind::kInitializing);
+  }
+
+  // List of named.
+  ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < named_count; ++i, ++pos) {
+    SkipStringReference();  // read ith name.
+    instructions += LoadLocal(record);
+    instructions += BuildExpression();  // read ith expression.
+    instructions += B->StoreNativeField(
+        Slot::GetRecordFieldSlot(thread(),
+                                 compiler::target::Record::field_offset(pos)),
+        StoreFieldInstr::Kind::kInitializing);
+  }
+
+  SkipDartType();  // read recordType.
+
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildRecordFieldGet(TokenPosition* p,
+                                                        bool is_named) {
+  const TokenPosition position = ReadPosition();  // read position.
+  if (p != nullptr) *p = position;
+
+  Fragment instructions = BuildExpression();  // read receiver.
+  const RecordType& record_type =
+      RecordType::Cast(T.BuildType());  // read recordType.
+
+  intptr_t field_index = -1;
+  if (is_named) {
+    const String& field_name = H.DartSymbolPlain(ReadStringReference());
+    for (intptr_t i = 0, n = record_type.NumNamedFields(); i < n; ++i) {
+      if (record_type.FieldNameAt(i) == field_name.ptr()) {
+        field_index = i;
+        break;
+      }
+    }
+    ASSERT(field_index >= 0 && field_index < record_type.NumNamedFields());
+    field_index += record_type.NumPositionalFields();
+  } else {
+    field_index = ReadUInt();
+    ASSERT(field_index < record_type.NumPositionalFields());
+  }
+
+  instructions += B->LoadNativeField(Slot::GetRecordFieldSlot(
+      thread(), compiler::target::Record::field_offset(field_index)));
+  return instructions;
+}
+
 Fragment StreamingFlowGraphBuilder::BuildFunctionExpression() {
   ReadPosition();  // read position.
   return BuildFunctionNode(TokenPosition::kNoSource, StringIndex(),
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 22da387..3d31bcc 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -320,6 +320,8 @@
   Fragment BuildThrow(TokenPosition* position);
   Fragment BuildListLiteral(TokenPosition* position);
   Fragment BuildMapLiteral(TokenPosition* position);
+  Fragment BuildRecordLiteral(TokenPosition* position);
+  Fragment BuildRecordFieldGet(TokenPosition* position, bool is_named);
   Fragment BuildFunctionExpression();
   Fragment BuildLet(TokenPosition* position);
   Fragment BuildBlockExpression();
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index 3896a91..1bca22a 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -40,6 +40,7 @@
   void CalculateVariableDeclarationFingerprint();
   void CalculateStatementListFingerprint();
   void CalculateListOfExpressionsFingerprint();
+  void CalculateListOfNamedExpressionsFingerprint();
   void CalculateListOfDartTypesFingerprint();
   void CalculateListOfVariableDeclarationsFingerprint();
   void CalculateStringReferenceFingerprint();
@@ -87,14 +88,8 @@
   BuildHash(ReadUInt());  // read argument count.
 
   CalculateListOfDartTypesFingerprint();    // read list of types.
-  CalculateListOfExpressionsFingerprint();  // read positionals.
-
-  // List of named.
-  intptr_t list_length = ReadListLength();  // read list length.
-  for (intptr_t i = 0; i < list_length; ++i) {
-    CalculateStringReferenceFingerprint();  // read ith name index.
-    CalculateExpressionFingerprint();       // read ith expression.
-  }
+  CalculateListOfExpressionsFingerprint();  // read positional.
+  CalculateListOfNamedExpressionsFingerprint();  // read named.
 }
 
 void KernelFingerprintHelper::CalculateVariableDeclarationFingerprint() {
@@ -128,6 +123,14 @@
   }
 }
 
+void KernelFingerprintHelper::CalculateListOfNamedExpressionsFingerprint() {
+  const intptr_t list_length = ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    CalculateStringReferenceFingerprint();  // read ith name index.
+    CalculateExpressionFingerprint();       // read ith expression.
+  }
+}
+
 void KernelFingerprintHelper::CalculateListOfDartTypesFingerprint() {
   intptr_t list_length = ReadListLength();  // read list length.
   for (intptr_t i = 0; i < list_length; ++i) {
@@ -257,6 +260,18 @@
       CalculateDartTypeFingerprint();  // read left;
       CalculateDartTypeFingerprint();  // read right;
       break;
+    case kRecordType: {
+      BuildHash(static_cast<uint32_t>(ReadNullability()));
+      CalculateListOfDartTypesFingerprint();
+      const intptr_t named_count = ReadListLength();
+      BuildHash(named_count);
+      for (intptr_t i = 0; i < named_count; ++i) {
+        CalculateStringReferenceFingerprint();
+        CalculateDartTypeFingerprint();
+        ReadFlags();
+      }
+      break;
+    }
     default:
       ReportUnexpectedTag("type", tag);
       UNREACHABLE();
@@ -577,6 +592,24 @@
       }
       return;
     }
+    case kRecordLiteral:
+      ReadPosition();                                // read position.
+      CalculateListOfExpressionsFingerprint();       // read positionals.
+      CalculateListOfNamedExpressionsFingerprint();  // read named.
+      CalculateDartTypeFingerprint();                // read recordType.
+      return;
+    case kRecordIndexGet:
+      ReadPosition();                    // read position.
+      CalculateExpressionFingerprint();  // read receiver.
+      CalculateDartTypeFingerprint();    // read recordType.
+      BuildHash(ReadUInt());             // read index.
+      return;
+    case kRecordNameGet:
+      ReadPosition();                         // read position.
+      CalculateExpressionFingerprint();       // read receiver.
+      CalculateDartTypeFingerprint();         // read recordType.
+      CalculateStringReferenceFingerprint();  // read name.
+      return;
     case kFunctionExpression:
       ReadPosition();                      // read position.
       CalculateFunctionNodeFingerprint();  // read function node.
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 3e8a235..836ecce 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -873,6 +873,8 @@
   V(LinkedHashBase_getIndex, LinkedHashBase_index)                             \
   V(LinkedHashBase_getUsedData, LinkedHashBase_used_data)                      \
   V(ObjectArrayLength, Array_length)                                           \
+  V(Record_fieldNames, Record_field_names)                                     \
+  V(Record_numFields, Record_num_fields)                                       \
   V(SuspendState_getFunctionData, SuspendState_function_data)                  \
   V(SuspendState_getThenCallback, SuspendState_then_callback)                  \
   V(SuspendState_getErrorCallback, SuspendState_error_callback)                \
@@ -908,6 +910,7 @@
   const MethodRecognizer::Kind kind = function.recognized_kind();
 
   switch (kind) {
+    case MethodRecognizer::kRecord_fieldAt:
     case MethodRecognizer::kSuspendState_clone:
     case MethodRecognizer::kSuspendState_resume:
     case MethodRecognizer::kTypedData_ByteDataView_factory:
@@ -1072,6 +1075,13 @@
 
   const MethodRecognizer::Kind kind = function.recognized_kind();
   switch (kind) {
+    case MethodRecognizer::kRecord_fieldAt:
+      ASSERT_EQUAL(function.NumParameters(), 2);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
+      body += LoadIndexed(
+          kRecordCid, /*index_scale*/ compiler::target::kCompressedWordSize);
+      break;
     case MethodRecognizer::kSuspendState_clone: {
       ASSERT_EQUAL(function.NumParameters(), 1);
       body += LoadLocal(parsed_function_->RawParameterVariable(0));
@@ -4866,27 +4876,9 @@
                                                 : try_catch_block->try_index());
 }
 
-bool FlowGraphBuilder::NeedsNullAssertion(const AbstractType& type) {
-  if (!type.IsNonNullable()) {
-    return false;
-  }
-  if (type.IsTypeRef()) {
-    return NeedsNullAssertion(
-        AbstractType::Handle(Z, TypeRef::Cast(type).type()));
-  }
-  if (type.IsTypeParameter()) {
-    return NeedsNullAssertion(
-        AbstractType::Handle(Z, TypeParameter::Cast(type).bound()));
-  }
-  if (type.IsFutureOrType()) {
-    return NeedsNullAssertion(AbstractType::Handle(Z, type.UnwrapFutureOr()));
-  }
-  return true;
-}
-
 Fragment FlowGraphBuilder::NullAssertion(LocalVariable* variable) {
   Fragment code;
-  if (!NeedsNullAssertion(variable->type())) {
+  if (!variable->type().NeedsNullAssertion()) {
     return code;
   }
 
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index ced4d94..9e044e73 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2213,6 +2213,17 @@
     case kSimpleFunctionType:
       SkipFunctionType(true);
       return;
+    case kRecordType: {
+      ReadNullability();
+      SkipListOfDartTypes();
+      const intptr_t named_count = ReadListLength();
+      for (intptr_t i = 0; i < named_count; ++i) {
+        SkipStringReference();
+        SkipDartType();
+        ReadFlags();
+      }
+      return;
+    }
     case kTypedefType:
       ReadNullability();      // read nullability.
       ReadUInt();             // read index for canonical name.
@@ -2289,6 +2300,14 @@
   }
 }
 
+void KernelReaderHelper::SkipListOfNamedExpressions() {
+  const intptr_t list_length = ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    SkipStringReference();  // read ith name index.
+    SkipExpression();       // read ith expression.
+  }
+}
+
 void KernelReaderHelper::SkipListOfDartTypes() {
   intptr_t list_length = ReadListLength();  // read list length.
   for (intptr_t i = 0; i < list_length; ++i) {
@@ -2592,6 +2611,24 @@
       }
       return;
     }
+    case kRecordLiteral:
+      ReadPosition();                // read position.
+      SkipListOfExpressions();       // read positionals.
+      SkipListOfNamedExpressions();  // read named.
+      SkipDartType();                // read recordType.
+      return;
+    case kRecordIndexGet:
+      ReadPosition();    // read position.
+      SkipExpression();  // read receiver.
+      SkipDartType();    // read recordType.
+      ReadUInt();        // read index.
+      return;
+    case kRecordNameGet:
+      ReadPosition();         // read position.
+      SkipExpression();       // read receiver.
+      SkipDartType();         // read recordType.
+      SkipStringReference();  // read name.
+      return;
     case kFunctionExpression:
       ReadPosition();      // read position.
       SkipFunctionNode();  // read function node.
@@ -2818,14 +2855,8 @@
   ReadUInt();  // read argument count.
 
   SkipListOfDartTypes();    // read list of types.
-  SkipListOfExpressions();  // read positionals.
-
-  // List of named.
-  intptr_t list_length = ReadListLength();  // read list length.
-  for (intptr_t i = 0; i < list_length; ++i) {
-    SkipStringReference();  // read ith name index.
-    SkipExpression();       // read ith expression.
-  }
+  SkipListOfExpressions();  // read positional.
+  SkipListOfNamedExpressions();  // read named.
 }
 
 void KernelReaderHelper::SkipVariableDeclaration() {
@@ -3148,6 +3179,9 @@
     case kSimpleFunctionType:
       BuildFunctionType(true);
       break;
+    case kRecordType:
+      BuildRecordType();
+      break;
     case kTypeParameterType:
       BuildTypeParameterType();
       if (result_.IsTypeParameter() &&
@@ -3299,6 +3333,62 @@
   result_ = signature.ptr();
 }
 
+void TypeTranslator::BuildRecordType() {
+  Nullability nullability = helper_->ReadNullability();
+  if (apply_canonical_type_erasure_ && nullability != Nullability::kNullable) {
+    nullability = Nullability::kLegacy;
+  }
+
+  const intptr_t positional_count = helper_->ReadListLength();
+  intptr_t named_count = 0;
+  {
+    AlternativeReadingScope alt(&helper_->reader_);
+    for (intptr_t i = 0; i < positional_count; ++i) {
+      helper_->SkipDartType();
+    }
+    named_count = helper_->ReadListLength();
+  }
+
+  const intptr_t num_fields = positional_count + named_count;
+  const Array& field_types =
+      Array::Handle(Z, Array::New(num_fields, Heap::kOld));
+  const Array& field_names =
+      (named_count == 0)
+          ? Object::empty_array()
+          : Array::Handle(Z, Array::New(named_count, Heap::kOld));
+
+  // Suspend finalization of types inside this one. They will be finalized after
+  // the whole record type is constructed.
+  bool finalize = finalize_;
+  finalize_ = false;
+
+  intptr_t pos = 0;
+  for (intptr_t i = 0; i < positional_count; ++i) {
+    BuildTypeInternal();  // read ith positional field.
+    field_types.SetAt(pos++, result_);
+  }
+
+  helper_->ReadListLength();
+  for (intptr_t i = 0; i < named_count; ++i) {
+    String& name = H.DartSymbolObfuscate(helper_->ReadStringReference());
+    field_names.SetAt(i, name);
+    BuildTypeInternal();
+    field_types.SetAt(pos++, result_);
+    helper_->ReadFlags();
+  }
+
+  finalize_ = finalize;
+
+  RecordType& rec = RecordType::Handle(
+      Z, RecordType::New(field_types, field_names, nullability));
+
+  if (finalize_) {
+    rec ^= ClassFinalizer::FinalizeType(rec);
+  }
+
+  result_ = rec.ptr();
+}
+
 void TypeTranslator::BuildTypeParameterType() {
   Nullability nullability = helper_->ReadNullability();
   if (apply_canonical_type_erasure_ && nullability != Nullability::kNullable) {
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 945a01e..76c66db 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -1275,6 +1275,7 @@
   void SkipFunctionType(bool simple);
   void SkipStatementList();
   void SkipListOfExpressions();
+  void SkipListOfNamedExpressions();
   void SkipListOfDartTypes();
   void SkipListOfStrings();
   void SkipListOfVariableDeclarations();
@@ -1542,6 +1543,7 @@
   void BuildTypeInternal();
   void BuildInterfaceType(bool simple);
   void BuildFunctionType(bool simple);
+  void BuildRecordType();
   void BuildTypeParameterType();
   void BuildIntersectionType();
 
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 037d9ae..21ae2e8 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -823,10 +823,7 @@
     }
     case kStringConcatenation: {
       helper_.ReadPosition();                           // read position.
-      intptr_t list_length = helper_.ReadListLength();  // read list length.
-      for (intptr_t i = 0; i < list_length; ++i) {
-        VisitExpression();  // read ith expression.
-      }
+      VisitListOfExpressions();
       return;
     }
     case kIsExpression:
@@ -859,10 +856,7 @@
     case kListLiteral: {
       helper_.ReadPosition();                           // read position.
       VisitDartType();                                  // read type.
-      intptr_t list_length = helper_.ReadListLength();  // read list length.
-      for (intptr_t i = 0; i < list_length; ++i) {
-        VisitExpression();  // read ith expression.
-      }
+      VisitListOfExpressions();
       return;
     }
     case kSetLiteral: {
@@ -882,6 +876,24 @@
       }
       return;
     }
+    case kRecordLiteral:
+      helper_.ReadPosition();         // read position.
+      VisitListOfExpressions();       // read positionals.
+      VisitListOfNamedExpressions();  // read named.
+      VisitDartType();                // read recordType.
+      return;
+    case kRecordIndexGet:
+      helper_.ReadPosition();  // read position.
+      VisitExpression();       // read receiver.
+      helper_.SkipDartType();  // read recordType.
+      helper_.ReadUInt();      // read index.
+      return;
+    case kRecordNameGet:
+      helper_.ReadPosition();         // read position.
+      VisitExpression();              // read receiver.
+      helper_.SkipDartType();         // read recordType.
+      helper_.SkipStringReference();  // read name.
+      return;
     case kFunctionExpression: {
       intptr_t offset = helper_.ReaderOffset() - 1;  // -1 to include tag byte.
       helper_.ReadPosition();                        // read position.
@@ -1085,10 +1097,7 @@
       if (tag == kSomething) {
         VisitExpression();  // read rest of condition.
       }
-      list_length = helper_.ReadListLength();  // read number of updates.
-      for (intptr_t i = 0; i < list_length; ++i) {
-        VisitExpression();  // read ith update.
-      }
+      VisitListOfExpressions();  // read updates.
       VisitStatement();  // read body.
 
       ExitScope(position, helper_.reader_.max_position());
@@ -1259,6 +1268,21 @@
   }
 }
 
+void ScopeBuilder::VisitListOfExpressions() {
+  const intptr_t list_length = helper_.ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    VisitExpression();
+  }
+}
+
+void ScopeBuilder::VisitListOfNamedExpressions() {
+  const intptr_t list_length = helper_.ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    helper_.SkipStringReference();  // read ith name index.
+    VisitExpression();              // read ith expression.
+  }
+}
+
 void ScopeBuilder::VisitArguments() {
   helper_.ReadUInt();  // read argument_count.
 
@@ -1268,18 +1292,8 @@
     VisitDartType();  // read ith type.
   }
 
-  // Positional.
-  list_length = helper_.ReadListLength();  // read list length.
-  for (intptr_t i = 0; i < list_length; ++i) {
-    VisitExpression();  // read ith positional.
-  }
-
-  // Named.
-  list_length = helper_.ReadListLength();  // read list length.
-  for (intptr_t i = 0; i < list_length; ++i) {
-    helper_.SkipStringReference();  // read ith name index.
-    VisitExpression();              // read ith expression.
-  }
+  VisitListOfExpressions();       // Positional.
+  VisitListOfNamedExpressions();  // Named.
 }
 
 void ScopeBuilder::VisitVariableDeclaration() {
@@ -1355,6 +1369,9 @@
     case kSimpleFunctionType:
       VisitFunctionType(true);
       return;
+    case kRecordType:
+      VisitRecordType();
+      return;
     case kTypeParameterType:
       VisitTypeParameterType();
       return;
@@ -1417,6 +1434,22 @@
   VisitDartType();  // read return type.
 }
 
+void ScopeBuilder::VisitRecordType() {
+  helper_.ReadNullability();  // read nullability.
+  const intptr_t positional_count =
+      helper_.ReadListLength();  // read positional list length.
+  for (intptr_t i = 0; i < positional_count; ++i) {
+    VisitDartType();  // read positional[i].
+  }
+  const intptr_t named_count =
+      helper_.ReadListLength();  // read named list length.
+  for (intptr_t i = 0; i < named_count; ++i) {
+    helper_.SkipStringReference();  // read named[i].name.
+    VisitDartType();                // read named[i].type.
+    helper_.ReadFlags();            // read named[i].flags
+  }
+}
+
 void ScopeBuilder::VisitTypeParameterType() {
   Function& function = Function::Handle(Z, parsed_function_->function().ptr());
 
@@ -1673,7 +1706,7 @@
                      AbstractType::dynamic_type());
 
     // If transformer did not lift the variable then there is no need
-    // to lift it into the context when we encouter a YieldStatement.
+    // to lift it into the context when we encounter a YieldStatement.
     v->set_is_forced_stack();
     current_function_scope_->AddVariable(v);
   }
diff --git a/runtime/vm/compiler/frontend/scope_builder.h b/runtime/vm/compiler/frontend/scope_builder.h
index 619a686..648c925 100644
--- a/runtime/vm/compiler/frontend/scope_builder.h
+++ b/runtime/vm/compiler/frontend/scope_builder.h
@@ -40,12 +40,15 @@
   void VisitInitializer();
   void VisitExpression();
   void VisitStatement();
+  void VisitListOfExpressions();
+  void VisitListOfNamedExpressions();
   void VisitArguments();
   void VisitVariableDeclaration();
   void VisitVariableGet(intptr_t declaration_binary_offset);
   void VisitDartType();
   void VisitInterfaceType(bool simple);
   void VisitFunctionType(bool simple);
+  void VisitRecordType();
   void VisitTypeParameterType();
   void VisitIntersectionType();
   void HandleLocalFunction(intptr_t parent_kernel_offset);
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index 4f4963b..bc98001 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -1054,10 +1054,10 @@
 
   // We only support cases where we do not have to create a box (whose
   // allocation could fail).
-  ASSERT(function.HasUnboxedReturnValue() || !slot.IsUnboxed());
+  ASSERT(function.HasUnboxedReturnValue() || !slot.is_unboxed());
 
   // We might need to unbox the field value before returning.
-  if (function.HasUnboxedReturnValue() && !slot.IsUnboxed()) {
+  if (function.HasUnboxedReturnValue() && !slot.is_unboxed()) {
     ASSERT(FLAG_precompiled_mode);
     field_value = builder.AddUnboxInstr(
         FlowGraph::ReturnRepresentationOf(flow_graph->function()),
@@ -1082,10 +1082,10 @@
   }
   ASSERT(field.is_instance() && !field.is_final());
   const auto& slot = Slot::Get(field, &flow_graph->parsed_function());
-  ASSERT(!function.HasUnboxedParameters() || slot.IsUnboxed());
+  ASSERT(!function.HasUnboxedParameters() || slot.is_unboxed());
 
   const auto barrier_mode =
-      slot.IsUnboxed() ? kNoStoreBarrier : kEmitStoreBarrier;
+      slot.is_unboxed() ? kNoStoreBarrier : kEmitStoreBarrier;
 
   flow_graph->CreateCommonConstants();
   GraphEntryInstr* graph_entry = flow_graph->graph_entry();
@@ -1096,7 +1096,7 @@
   auto value = builder.AddParameter(1, /*with_frame=*/false);
   VerifyParameterIsBoxed(&builder, 0);
 
-  if (!function.HasUnboxedParameters() && slot.IsUnboxed()) {
+  if (!function.HasUnboxedParameters() && slot.is_unboxed()) {
     // We do not support storing to possibly guarded fields in JIT in graph
     // intrinsics.
     ASSERT(FLAG_precompiled_mode);
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index ba448a7..52b819e 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -109,14 +109,13 @@
     // We don't support complex getter cases.
     if (field.is_late() || field.needs_load_guard()) return false;
 
-    if (slot.IsPotentialUnboxed()) {
+    if (slot.is_unboxed()) {
       if (function.HasUnboxedReturnValue()) {
         // In AOT mode: Unboxed fields contain the unboxed value and can be
         // returned in unboxed form.
         ASSERT(FLAG_precompiled_mode);
       } else {
-        // In JIT mode: Unboxed fields contain a mutable box which we cannot
-        // return.
+        // In JIT mode: Can't return unboxed value directly.
         return false;
       }
     } else {
@@ -144,7 +143,7 @@
     // avoid the need for boxing (which we cannot do in the intrinsic).
     if (function.HasUnboxedParameters()) {
       ASSERT(FLAG_precompiled_mode);
-      if (!slot.IsUnboxed()) {
+      if (!slot.is_unboxed()) {
         return false;
       }
     }
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 2147382..bc96a84 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -20,6 +20,9 @@
   V(_List, []=, ObjectArraySetIndexed, 0x050cd2ba)                             \
   V(_GrowableList, ._withData, GrowableArrayAllocateWithData, 0x1947d8a1)      \
   V(_GrowableList, []=, GrowableArraySetIndexed, 0x050cd2ba)                   \
+  V(_Record, get:_fieldNames, Record_fieldNames, 0x68e5459d)                   \
+  V(_Record, get:_numFields, Record_numFields, 0x7bc20792)                     \
+  V(_Record, _fieldAt, Record_fieldAt, 0xb49cb873)                             \
   V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x1623dc34)                    \
   V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x177ffe2a)                  \
   V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x2e40964f)                  \
@@ -241,8 +244,8 @@
   V(_Int32x4, _withFlagW, Int32x4WithFlagW, 0xb333f958)                        \
   V(_HashVMBase, get:_index, LinkedHashBase_getIndex, 0x882671dc)              \
   V(_HashVMBase, set:_index, LinkedHashBase_setIndex, 0xa2be9418)              \
-  V(_HashVMBase, get:_data, LinkedHashBase_getData, 0x780e14ad)                \
-  V(_HashVMBase, set:_data, LinkedHashBase_setData, 0xb6a5c369)                \
+  V(_HashVMBase, get:_data, LinkedHashBase_getData, 0x2c8b5e83)                \
+  V(_HashVMBase, set:_data, LinkedHashBase_setData, 0x40f7efbf)                \
   V(_HashVMBase, get:_usedData, LinkedHashBase_getUsedData, 0x470893ed)        \
   V(_HashVMBase, set:_usedData, LinkedHashBase_setUsedData, 0xb3c887a9)        \
   V(_HashVMBase, get:_hashMask, LinkedHashBase_getHashMask, 0x4f0ec79c)        \
@@ -250,7 +253,7 @@
   V(_HashVMBase, get:_deletedKeys, LinkedHashBase_getDeletedKeys, 0x510dc4a0)  \
   V(_HashVMBase, set:_deletedKeys, LinkedHashBase_setDeletedKeys, 0xbdcdb85c)  \
   V(_HashVMImmutableBase, get:_data, ImmutableLinkedHashBase_getData,          \
-    0x780e14ad)                                                                \
+    0x2c8b5e83)                                                                \
   V(_HashVMImmutableBase, get:_indexNullable,                                  \
     ImmutableLinkedHashBase_getIndex, 0xfd877bfb)                              \
   V(_HashVMImmutableBase, set:_index,                                          \
@@ -362,10 +365,10 @@
     OneByteString_substringUnchecked,  0x9b18195e)                             \
   V(_OneByteString, ==, OneByteString_equality, 0xb5003d69)                    \
   V(_TwoByteString, ==, TwoByteString_equality, 0xb5003d69)                    \
+  V(_AbstractType, get:hashCode, AbstractType_getHashCode, 0x75e0d454)         \
+  V(_AbstractType, ==, AbstractType_equality, 0x465868ae)                      \
   V(_Type, get:hashCode, Type_getHashCode, 0x75e0d454)                         \
   V(_Type, ==, Type_equality, 0x465868ae)                                      \
-  V(_FunctionType, get:hashCode, FunctionType_getHashCode, 0x75e0d454)         \
-  V(_FunctionType, ==, FunctionType_equality, 0x465868ae)                      \
   V(::, _getHash, Object_getHash, 0xc60ff758)                                  \
 
 #define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc
index 08641a0..f17ae04 100644
--- a/runtime/vm/compiler/relocation.cc
+++ b/runtime/vm/compiler/relocation.cc
@@ -344,7 +344,7 @@
     auto const caller = unresolved_call->caller;
     uword addr = Code::PayloadStartOf(caller) + call_offset;
     if (FLAG_write_protect_code) {
-      addr -= OldPage::Of(Code::InstructionsOf(caller))->AliasOffset();
+      addr -= Page::Of(Code::InstructionsOf(caller))->AliasOffset();
     }
     if (unresolved_call->is_tail_call) {
       PcRelativeTailCallPattern call(addr);
diff --git a/runtime/vm/compiler/relocation_test.cc b/runtime/vm/compiler/relocation_test.cc
index 4aec712..ebced27 100644
--- a/runtime/vm/compiler/relocation_test.cc
+++ b/runtime/vm/compiler/relocation_test.cc
@@ -136,7 +136,7 @@
 
     if (FLAG_write_protect_code && FLAG_dual_map_code) {
       auto& instructions = Instructions::Handle(code.instructions());
-      instructions ^= OldPage::ToExecutable(instructions.ptr());
+      instructions ^= Page::ToExecutable(instructions.ptr());
       code.set_instructions(instructions);
     }
     if (FLAG_disassemble) {
@@ -245,7 +245,7 @@
             const auto current_size =
                 ImageWriter::SizeInSnapshot(Code::InstructionsOf(entry.code));
             const auto alias_offset =
-                OldPage::Of(Code::InstructionsOf(entry.code))->AliasOffset();
+                Page::Of(Code::InstructionsOf(entry.code))->AliasOffset();
             memmove(
                 reinterpret_cast<void*>(addr),
                 reinterpret_cast<void*>(Instructions::PayloadStart(
@@ -262,7 +262,7 @@
         const uword address = UntaggedObject::ToAddr(instructions.ptr());
         const auto size = instructions.ptr()->untag()->HeapSize();
         instructions =
-            Instructions::RawCast(OldPage::ToExecutable(instructions.ptr()));
+            Instructions::RawCast(Page::ToExecutable(instructions.ptr()));
 
         const auto prot = FLAG_dual_map_code ? VirtualMemory::kReadOnly
                                              : VirtualMemory::kReadExecute;
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index a4e6df0..0ae58f0 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -9,6 +9,7 @@
 #include "vm/object.h"
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/runtime_offsets_list.h"
 #include "vm/dart_api_state.h"
 #include "vm/dart_entry.h"
@@ -327,9 +328,9 @@
 
 namespace target {
 
-const word kOldPageSize = dart::kOldPageSize;
-const word kOldPageSizeInWords = dart::kOldPageSize / kWordSize;
-const word kOldPageMask = dart::kOldPageMask;
+const word kPageSize = dart::kPageSize;
+const word kPageSizeInWords = dart::kPageSize / kWordSize;
+const word kPageMask = dart::kPageMask;
 
 static word TranslateOffsetInWordsToHost(word offset) {
   RELEASE_ASSERT((offset % kCompressedWordSize) == 0);
@@ -390,12 +391,15 @@
 
 const word UntaggedAbstractType::kTypeStateFinalizedInstantiated =
     dart::UntaggedAbstractType::kFinalizedInstantiated;
+const word UntaggedAbstractType::kTypeStateShift =
+    dart::UntaggedAbstractType::kTypeStateShift;
+const word UntaggedAbstractType::kTypeStateBits =
+    dart::UntaggedAbstractType::kTypeStateBits;
+const word UntaggedAbstractType::kNullabilityMask =
+    dart::UntaggedAbstractType::kNullabilityMask;
 
-const bool UntaggedType::kTypeClassIdIsSigned =
-    std::is_signed<decltype(dart::UntaggedType::type_class_id_)>::value;
-
-const word UntaggedType::kTypeClassIdBitSize =
-    sizeof(dart::UntaggedType::type_class_id_) * kBitsPerByte;
+const word UntaggedType::kTypeClassIdShift =
+    dart::UntaggedType::kTypeClassIdShift;
 
 const word UntaggedObject::kBarrierOverlapShift =
     dart::UntaggedObject::kBarrierOverlapShift;
@@ -545,6 +549,8 @@
       return OneByteString::data_offset();
     case kTwoByteStringCid:
       return TwoByteString::data_offset();
+    case kRecordCid:
+      return Record::field_offset(0);
     default:
       UNIMPLEMENTED();
       return Array::data_offset();
@@ -1046,6 +1052,49 @@
   return TranslateOffsetInWords(dart::Number::NextFieldOffset());
 }
 
+void UnboxFieldIfSupported(const dart::Field& field,
+                           const dart::AbstractType& type) {
+  if (field.is_static() || field.is_late()) {
+    return;
+  }
+
+  if (type.IsNullable()) {
+    return;
+  }
+
+  // In JIT mode we can unbox fields which are guaranteed to be non-nullable
+  // based on their static type. We can only rely on this information
+  // when running in sound null safety. AOT instead uses TFA results, see
+  // |KernelLoader::ReadInferredType|.
+  if (!dart::Thread::Current()->isolate_group()->null_safety()) {
+    return;
+  }
+
+  classid_t cid = kIllegalCid;
+  if (type.IsDoubleType()) {
+    if (FlowGraphCompiler::SupportsUnboxedDoubles()) {
+      cid = kDoubleCid;
+    }
+  } else if (type.IsFloat32x4Type()) {
+    if (FlowGraphCompiler::SupportsUnboxedSimd128()) {
+      cid = kFloat32x4Cid;
+    }
+  } else if (type.IsFloat64x2Type()) {
+    if (FlowGraphCompiler::SupportsUnboxedSimd128()) {
+      cid = kFloat64x2Cid;
+    }
+  }
+
+  if (cid != kIllegalCid) {
+    field.set_guarded_cid(cid);
+    field.set_is_nullable(false);
+    field.set_is_unboxed(true);
+    field.set_guarded_list_length(dart::Field::kNoFixedLength);
+    field.set_guarded_list_length_in_object_offset(
+        dart::Field::kUnknownLengthOffset);
+  }
+}
+
 }  // namespace target
 }  // namespace compiler
 }  // namespace dart
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index dfa58a3..7afa8c7 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -77,9 +77,9 @@
 extern InvalidClass kNewObjectAlignmentOffset;
 extern InvalidClass kOldObjectAlignmentOffset;
 extern InvalidClass kNewObjectBitPosition;
-extern InvalidClass kOldPageSize;
-extern InvalidClass kOldPageSizeInWords;
-extern InvalidClass kOldPageMask;
+extern InvalidClass kPageSize;
+extern InvalidClass kPageSizeInWords;
+extern InvalidClass kPageMask;
 extern InvalidClass kObjectAlignment;
 extern InvalidClass kObjectAlignmentLog2;
 extern InvalidClass kObjectAlignmentMask;
@@ -301,9 +301,9 @@
 constexpr word kSmiMin = -(static_cast<uword>(1) << kSmiBits);
 
 // Information about heap pages.
-extern const word kOldPageSize;
-extern const word kOldPageSizeInWords;
-extern const word kOldPageMask;
+extern const word kPageSize;
+extern const word kPageSizeInWords;
+extern const word kPageMask;
 
 static constexpr intptr_t kObjectAlignment = ObjectAlignment::kObjectAlignment;
 
@@ -432,12 +432,14 @@
 class UntaggedAbstractType : public AllStatic {
  public:
   static const word kTypeStateFinalizedInstantiated;
+  static const word kTypeStateShift;
+  static const word kTypeStateBits;
+  static const word kNullabilityMask;
 };
 
 class UntaggedType : public AllStatic {
  public:
-  static const bool kTypeClassIdIsSigned;
-  static const word kTypeClassIdBitSize;
+  static const word kTypeClassIdShift;
 };
 
 class Object : public AllStatic {
@@ -589,6 +591,16 @@
   FINAL_CLASS();
 };
 
+class Record : public AllStatic {
+ public:
+  static word num_fields_offset();
+  static word field_names_offset();
+  static word field_offset(intptr_t index);
+  static word InstanceSize(intptr_t length);
+  static word InstanceSize();
+  FINAL_CLASS();
+};
+
 class PointerBase : public AllStatic {
  public:
   static word data_offset();
@@ -685,6 +697,7 @@
 
 class AbstractType : public AllStatic {
  public:
+  static word flags_offset();
   static word type_test_stub_entry_point_offset();
   static word InstanceSize();
   FINAL_CLASS();
@@ -693,10 +706,7 @@
 class Type : public AllStatic {
  public:
   static word hash_offset();
-  static word type_state_offset();
   static word arguments_offset();
-  static word type_class_id_offset();
-  static word nullability_offset();
   static word InstanceSize();
   FINAL_CLASS();
 };
@@ -704,13 +714,17 @@
 class FunctionType : public AllStatic {
  public:
   static word hash_offset();
-  static word type_state_offset();
   static word packed_parameter_counts_offset();
   static word packed_type_parameter_counts_offset();
   static word named_parameter_names_offset();
   static word parameter_types_offset();
   static word type_parameters_offset();
-  static word nullability_offset();
+  static word InstanceSize();
+  FINAL_CLASS();
+};
+
+class RecordType : public AllStatic {
+ public:
   static word InstanceSize();
   FINAL_CLASS();
 };
@@ -950,12 +964,10 @@
 class TypeParameter : public AllStatic {
  public:
   static word bound_offset();
-  static word flags_offset();
   static word InstanceSize();
   FINAL_CLASS();
   static word parameterized_class_id_offset();
   static word index_offset();
-  static word nullability_offset();
 };
 
 class LibraryPrefix : public AllStatic {
@@ -1180,8 +1192,7 @@
   static word stack_overflow_shared_stub_entry_point_offset(bool fpu_regs);
   static word stack_limit_offset();
   static word saved_stack_limit_offset();
-  static word unboxed_int64_runtime_arg_offset();
-  static word unboxed_double_runtime_arg_offset();
+  static word unboxed_runtime_arg_offset();
 
   static word callback_code_offset();
   static word callback_stack_return_offset();
@@ -1322,23 +1333,16 @@
 class IsolateGroup : public AllStatic {
  public:
   static word object_store_offset();
-  static word shared_class_table_offset();
+  static word class_table_offset();
   static word cached_class_table_table_offset();
 };
 
-class SharedClassTable : public AllStatic {
- public:
-  static word class_heap_stats_table_offset();
-};
-
 class ClassTable : public AllStatic {
  public:
 #if !defined(PRODUCT)
-  static word ClassOffsetFor(intptr_t cid);
-  static word SharedTableOffsetFor();
-  static word SizeOffsetFor(intptr_t cid, bool is_new);
+  static word allocation_tracing_state_table_offset();
+  static word AllocationTracingStateSlotOffsetFor(intptr_t cid);
 #endif  // !defined(PRODUCT)
-  static const word kSizeOfClassPairLog2;
 };
 
 class InstructionsSection : public AllStatic {
@@ -1458,7 +1462,7 @@
   FINAL_CLASS();
 };
 
-class OldPage : public AllStatic {
+class Page : public AllStatic {
  public:
   static const word kBytesPerCardLog2;
 
@@ -1569,6 +1573,9 @@
   static word OffsetOf(const dart::Field& field);
 };
 
+void UnboxFieldIfSupported(const dart::Field& field,
+                           const dart::AbstractType& type);
+
 }  // namespace target
 }  // namespace compiler
 }  // namespace dart
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 4628329..6935a83 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -49,6 +49,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 12;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 12;
+static constexpr dart::compiler::target::word Record_element_size = 4;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 20;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
@@ -71,7 +73,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 4;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
@@ -94,6 +96,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 8;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 4;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -124,7 +127,7 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
-    SharedClassTable_class_heap_stats_table_offset = 0;
+    ClassTable_allocation_tracing_state_table_offset = 4;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -173,7 +176,7 @@
     GrowableObjectArray_length_offset = 8;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 4;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word Page_card_table_offset = 16;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -189,11 +192,11 @@
     Isolate_has_resumption_breakpoints_offset = 45;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 32;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    20;
+    16;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    8;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 8;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 16;
+    IsolateGroup_cached_class_table_table_offset = 12;
 static constexpr dart::compiler::target::word Isolate_single_step_offset = 44;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 20;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 12;
@@ -230,28 +233,30 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     112;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 492;
+    ObjectStore_suspend_state_await_offset = 496;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 524;
+    ObjectStore_suspend_state_handle_exception_offset = 528;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 488;
+    ObjectStore_suspend_state_init_async_offset = 492;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 504;
+    ObjectStore_suspend_state_init_async_star_offset = 508;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 516;
+    ObjectStore_suspend_state_init_sync_star_offset = 520;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 496;
+    ObjectStore_suspend_state_return_async_offset = 500;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 500;
+    ObjectStore_suspend_state_return_async_not_future_offset = 504;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 512;
+    ObjectStore_suspend_state_return_async_star_offset = 516;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 520;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 524;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 508;
+    ObjectStore_suspend_state_yield_async_star_offset = 512;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 4;
+static constexpr dart::compiler::target::word Record_field_names_offset = 8;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -282,9 +287,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 408;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    840;
+    860;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    844;
+    864;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 300;
 static constexpr dart::compiler::target::word
@@ -307,7 +312,7 @@
     Thread_allocate_object_slow_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 208;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 880;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 900;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 212;
 static constexpr dart::compiler::target::word
@@ -320,13 +325,13 @@
     Thread_call_to_runtime_entry_point_offset = 304;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 912;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 936;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 884;
+    Thread_double_truncate_round_supported_offset = 904;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 916;
+    Thread_service_extension_stream_offset = 940;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     344;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 256;
@@ -342,7 +347,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 280;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    860;
+    880;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 284;
 static constexpr dart::compiler::target::word
@@ -364,13 +369,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 404;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    848;
+    868;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    876;
+    896;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 920;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 944;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -423,11 +428,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 376;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 852;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 872;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 856;
+    Thread_saved_shadow_call_stack_offset = 876;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    864;
+    884;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -448,47 +453,45 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 804;
+    Thread_suspend_state_await_entry_point_offset = 824;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 800;
+    Thread_suspend_state_init_async_entry_point_offset = 820;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 808;
+    Thread_suspend_state_return_async_entry_point_offset = 828;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 812;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 832;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 816;
+    Thread_suspend_state_init_async_star_entry_point_offset = 836;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 820;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 840;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 824;
+    Thread_suspend_state_return_async_star_entry_point_offset = 844;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 828;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 848;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 832;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 852;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 836;
+    Thread_suspend_state_handle_exception_entry_point_offset = 856;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 96;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 104;
+    Thread_unboxed_runtime_arg_offset = 96;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 296;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 868;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 888;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 872;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 888;
-static constexpr dart::compiler::target::word Thread_random_offset = 896;
+    Thread_callback_stack_return_offset = 892;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 912;
+static constexpr dart::compiler::target::word Thread_random_offset = 920;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 356;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 904;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 928;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -500,11 +503,8 @@
     16;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 12;
-static constexpr dart::compiler::target::word Type_hash_offset = 16;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
-static constexpr dart::compiler::target::word Type_type_state_offset = 22;
-static constexpr dart::compiler::target::word Type_nullability_offset = 23;
+static constexpr dart::compiler::target::word Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word Type_hash_offset = 20;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     24;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 20;
@@ -525,24 +525,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 4;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     20;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    39;
+    FunctionType_named_parameter_names_offset = 28;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 32;
+    FunctionType_packed_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 36;
+    FunctionType_packed_type_parameter_counts_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 20;
+    FunctionType_parameter_types_offset = 24;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 12;
+    FunctionType_type_parameters_offset = 16;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 20;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 23;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    25;
+    TypeParameter_parameterized_class_id_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 27;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -554,9 +550,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     16;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 16;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 24;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     12;
@@ -581,8 +576,8 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        768, 772, 776, 780, 784, -1, 788, -1, 792, 796, -1, -1, -1, -1, -1, -1};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
+        788, 792, 796, 800, 804, -1, 808, -1, 812, 816, -1, -1, -1, -1, -1, -1};
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 16;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
@@ -613,7 +608,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 88;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 40;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 44;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 8;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     16;
@@ -648,6 +643,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 28;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -664,7 +660,7 @@
 static constexpr dart::compiler::target::word Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
@@ -711,6 +707,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 24;
+static constexpr dart::compiler::target::word Record_element_size = 8;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
@@ -735,7 +733,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 10;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements =
@@ -759,6 +757,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 16;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -789,7 +788,7 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 180;
 static constexpr dart::compiler::target::word
-    SharedClassTable_class_heap_stats_table_offset = 0;
+    ClassTable_allocation_tracing_state_table_offset = 8;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -838,7 +837,7 @@
     GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -854,11 +853,11 @@
     Isolate_has_resumption_breakpoints_offset = 89;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 64;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    40;
+    32;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    16;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 32;
+    IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word Isolate_single_step_offset = 88;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 40;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 24;
@@ -895,29 +894,31 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 984;
+    ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 1048;
+    ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 976;
+    ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 1008;
+    ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 992;
+    ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 1024;
+    ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
     16;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word Record_field_names_offset = 16;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -948,9 +949,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1680;
+    1720;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1688;
+    1728;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -974,7 +975,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -987,13 +988,13 @@
     Thread_call_to_runtime_entry_point_offset = 584;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1808;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1848;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1768;
+    Thread_double_truncate_round_supported_offset = 1808;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1816;
+    Thread_service_extension_stream_offset = 1856;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 488;
@@ -1009,7 +1010,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1720;
+    1760;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -1031,14 +1032,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1696;
+    1736;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1752;
+    1792;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -1091,11 +1092,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1704;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1744;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1712;
+    Thread_saved_shadow_call_stack_offset = 1752;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1728;
+    1768;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -1116,33 +1117,31 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 1608;
+    Thread_suspend_state_await_entry_point_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 1600;
+    Thread_suspend_state_init_async_entry_point_offset = 1640;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 1616;
+    Thread_suspend_state_return_async_entry_point_offset = 1656;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 1624;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1664;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 1632;
+    Thread_suspend_state_init_async_star_entry_point_offset = 1672;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 1640;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 1680;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 1648;
+    Thread_suspend_state_return_async_star_entry_point_offset = 1688;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 1656;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1664;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1704;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 1672;
+    Thread_suspend_state_handle_exception_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 192;
+    Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 568;
@@ -1150,14 +1149,14 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1736;
+    1776;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1744;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1776;
-static constexpr dart::compiler::target::word Thread_random_offset = 1784;
+    Thread_callback_stack_return_offset = 1784;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1816;
+static constexpr dart::compiler::target::word Thread_random_offset = 1824;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 688;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1792;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1832;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -1171,11 +1170,8 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
-static constexpr dart::compiler::target::word Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word Type_hash_offset = 40;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     48;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 40;
@@ -1196,24 +1192,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 8;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     40;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    71;
+    FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 64;
+    FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 68;
+    FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 40;
+    FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 24;
+    FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 43;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    45;
+    TypeParameter_parameterized_class_id_offset = 48;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 51;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -1225,9 +1217,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     32;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 32;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 44;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     24;
@@ -1252,9 +1243,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, -1,   -1,   1544, 1552,
-        1560, 1568, 1576, -1,   1584, 1592, -1,   -1};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
+        1552, 1560, 1568, 1576, -1,   -1,   1584, 1592,
+        1600, 1608, 1616, -1,   1624, 1632, -1,   -1};
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 32;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
@@ -1285,7 +1276,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 128;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 80;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     32;
@@ -1320,6 +1311,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word Script_InstanceSize = 80;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -1335,9 +1327,9 @@
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word Type_InstanceSize = 48;
-static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
+static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
@@ -1384,6 +1376,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 12;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 12;
+static constexpr dart::compiler::target::word Record_element_size = 4;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 20;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
@@ -1406,7 +1400,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 4;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
@@ -1429,6 +1423,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 8;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 4;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -1459,7 +1454,7 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
-    SharedClassTable_class_heap_stats_table_offset = 0;
+    ClassTable_allocation_tracing_state_table_offset = 4;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -1508,7 +1503,7 @@
     GrowableObjectArray_length_offset = 8;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 4;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word Page_card_table_offset = 16;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -1524,11 +1519,11 @@
     Isolate_has_resumption_breakpoints_offset = 45;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 32;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    20;
+    16;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    8;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 8;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 16;
+    IsolateGroup_cached_class_table_table_offset = 12;
 static constexpr dart::compiler::target::word Isolate_single_step_offset = 44;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 20;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 12;
@@ -1565,28 +1560,30 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     112;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 492;
+    ObjectStore_suspend_state_await_offset = 496;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 524;
+    ObjectStore_suspend_state_handle_exception_offset = 528;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 488;
+    ObjectStore_suspend_state_init_async_offset = 492;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 504;
+    ObjectStore_suspend_state_init_async_star_offset = 508;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 516;
+    ObjectStore_suspend_state_init_sync_star_offset = 520;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 496;
+    ObjectStore_suspend_state_return_async_offset = 500;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 500;
+    ObjectStore_suspend_state_return_async_not_future_offset = 504;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 512;
+    ObjectStore_suspend_state_return_async_star_offset = 516;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 520;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 524;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 508;
+    ObjectStore_suspend_state_yield_async_star_offset = 512;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 4;
+static constexpr dart::compiler::target::word Record_field_names_offset = 8;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -1617,9 +1614,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 408;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    808;
+    828;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    812;
+    832;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 300;
 static constexpr dart::compiler::target::word
@@ -1642,7 +1639,7 @@
     Thread_allocate_object_slow_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 208;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 848;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 868;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 212;
 static constexpr dart::compiler::target::word
@@ -1655,13 +1652,13 @@
     Thread_call_to_runtime_entry_point_offset = 304;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 880;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 904;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 852;
+    Thread_double_truncate_round_supported_offset = 872;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 884;
+    Thread_service_extension_stream_offset = 908;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     344;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 256;
@@ -1677,7 +1674,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 280;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    828;
+    848;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 284;
 static constexpr dart::compiler::target::word
@@ -1699,13 +1696,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 404;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    816;
+    836;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    844;
+    864;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 888;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 912;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -1758,11 +1755,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 376;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 820;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 840;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 824;
+    Thread_saved_shadow_call_stack_offset = 844;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    832;
+    852;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -1783,47 +1780,45 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 772;
+    Thread_suspend_state_await_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 768;
+    Thread_suspend_state_init_async_entry_point_offset = 788;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 776;
+    Thread_suspend_state_return_async_entry_point_offset = 796;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 780;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 800;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 784;
+    Thread_suspend_state_init_async_star_entry_point_offset = 804;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 788;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 808;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 792;
+    Thread_suspend_state_return_async_star_entry_point_offset = 812;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 796;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 816;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 800;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 820;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 804;
+    Thread_suspend_state_handle_exception_entry_point_offset = 824;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 96;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 104;
+    Thread_unboxed_runtime_arg_offset = 96;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 296;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 836;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 856;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 840;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 856;
-static constexpr dart::compiler::target::word Thread_random_offset = 864;
+    Thread_callback_stack_return_offset = 860;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 880;
+static constexpr dart::compiler::target::word Thread_random_offset = 888;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 356;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 872;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 896;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -1835,11 +1830,8 @@
     16;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 12;
-static constexpr dart::compiler::target::word Type_hash_offset = 16;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
-static constexpr dart::compiler::target::word Type_type_state_offset = 22;
-static constexpr dart::compiler::target::word Type_nullability_offset = 23;
+static constexpr dart::compiler::target::word Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word Type_hash_offset = 20;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     24;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 20;
@@ -1860,24 +1852,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 4;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     20;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    39;
+    FunctionType_named_parameter_names_offset = 28;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 32;
+    FunctionType_packed_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 36;
+    FunctionType_packed_type_parameter_counts_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 20;
+    FunctionType_parameter_types_offset = 24;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 12;
+    FunctionType_type_parameters_offset = 16;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 20;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 23;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    25;
+    TypeParameter_parameterized_class_id_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 27;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -1889,9 +1877,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     16;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 16;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 24;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     12;
@@ -1914,7 +1901,7 @@
     WeakReference_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
     4, 12, 8, 16};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 16;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
@@ -1945,7 +1932,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 88;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 40;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 44;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 8;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     16;
@@ -1980,6 +1967,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 28;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -1996,7 +1984,7 @@
 static constexpr dart::compiler::target::word Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
@@ -2043,6 +2031,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 24;
+static constexpr dart::compiler::target::word Record_element_size = 8;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
@@ -2067,7 +2057,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 10;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements =
@@ -2091,6 +2081,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 16;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -2121,7 +2112,7 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 180;
 static constexpr dart::compiler::target::word
-    SharedClassTable_class_heap_stats_table_offset = 0;
+    ClassTable_allocation_tracing_state_table_offset = 8;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -2170,7 +2161,7 @@
     GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -2186,11 +2177,11 @@
     Isolate_has_resumption_breakpoints_offset = 89;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 64;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    40;
+    32;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    16;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 32;
+    IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word Isolate_single_step_offset = 88;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 40;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 24;
@@ -2227,29 +2218,31 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 984;
+    ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 1048;
+    ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 976;
+    ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 1008;
+    ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 992;
+    ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 1024;
+    ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
     16;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word Record_field_names_offset = 16;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -2280,9 +2273,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1752;
+    1792;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -2306,7 +2299,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1832;
+    1872;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -2319,13 +2312,13 @@
     Thread_call_to_runtime_entry_point_offset = 584;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1880;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1920;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1840;
+    Thread_double_truncate_round_supported_offset = 1880;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1888;
+    Thread_service_extension_stream_offset = 1928;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 488;
@@ -2341,7 +2334,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1792;
+    1832;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -2363,14 +2356,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1768;
+    1808;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1896;
+    1936;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -2423,11 +2416,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1776;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1816;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1784;
+    Thread_saved_shadow_call_stack_offset = 1824;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1800;
+    1840;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -2448,33 +2441,31 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 1680;
+    Thread_suspend_state_await_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 1672;
+    Thread_suspend_state_init_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 1688;
+    Thread_suspend_state_return_async_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 1696;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 1704;
+    Thread_suspend_state_init_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 1712;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 1720;
+    Thread_suspend_state_return_async_star_entry_point_offset = 1760;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 1728;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1736;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1776;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 1744;
+    Thread_suspend_state_handle_exception_entry_point_offset = 1784;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 192;
+    Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 568;
@@ -2482,14 +2473,14 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1808;
+    1848;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1816;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1848;
-static constexpr dart::compiler::target::word Thread_random_offset = 1856;
+    Thread_callback_stack_return_offset = 1856;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1888;
+static constexpr dart::compiler::target::word Thread_random_offset = 1896;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 688;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1864;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1904;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -2503,11 +2494,8 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
-static constexpr dart::compiler::target::word Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word Type_hash_offset = 40;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     48;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 40;
@@ -2528,24 +2516,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 8;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     40;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    71;
+    FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 64;
+    FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 68;
+    FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 40;
+    FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 24;
+    FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 43;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    45;
+    TypeParameter_parameterized_class_id_offset = 48;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 51;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -2557,9 +2541,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     32;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 32;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 44;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     24;
@@ -2584,10 +2567,10 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, 1592,
-        1600, 1608, 1616, 1624, -1,   -1,   -1,   -1,   1632, 1640, -1,
-        -1,   1648, 1656, 1664, -1,   -1,   -1,   -1,   -1,   -1};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
+        1552, 1560, 1568, 1576, 1584, 1592, 1600, 1608, 1616, 1624, 1632,
+        1640, 1648, 1656, 1664, -1,   -1,   -1,   -1,   1672, 1680, -1,
+        -1,   1688, 1696, 1704, -1,   -1,   -1,   -1,   -1,   -1};
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 32;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
@@ -2618,7 +2601,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 128;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 80;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     32;
@@ -2653,6 +2636,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word Script_InstanceSize = 80;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -2668,9 +2652,9 @@
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word Type_InstanceSize = 48;
-static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
+static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
@@ -2717,6 +2701,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 16;
+static constexpr dart::compiler::target::word Record_element_size = 4;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 24;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
@@ -2739,7 +2725,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
@@ -2762,6 +2748,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 16;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -2792,7 +2779,7 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 108;
 static constexpr dart::compiler::target::word
-    SharedClassTable_class_heap_stats_table_offset = 0;
+    ClassTable_allocation_tracing_state_table_offset = 8;
 static constexpr dart::compiler::target::word Closure_context_offset = 24;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 16;
@@ -2841,7 +2828,7 @@
     GrowableObjectArray_length_offset = 12;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -2857,11 +2844,11 @@
     Isolate_has_resumption_breakpoints_offset = 89;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 64;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    40;
+    32;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    16;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 32;
+    IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word Isolate_single_step_offset = 88;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 40;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 16;
@@ -2898,29 +2885,31 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 984;
+    ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 1048;
+    ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 976;
+    ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 1008;
+    ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 992;
+    ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 1024;
+    ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
     16;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word Record_field_names_offset = 12;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -2951,9 +2940,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1680;
+    1720;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1688;
+    1728;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -2977,7 +2966,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -2990,13 +2979,13 @@
     Thread_call_to_runtime_entry_point_offset = 584;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1808;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1848;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1768;
+    Thread_double_truncate_round_supported_offset = 1808;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1816;
+    Thread_service_extension_stream_offset = 1856;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 488;
@@ -3012,7 +3001,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1720;
+    1760;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -3034,14 +3023,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1696;
+    1736;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1752;
+    1792;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -3094,11 +3083,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1704;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1744;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1712;
+    Thread_saved_shadow_call_stack_offset = 1752;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1728;
+    1768;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -3119,33 +3108,31 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 1608;
+    Thread_suspend_state_await_entry_point_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 1600;
+    Thread_suspend_state_init_async_entry_point_offset = 1640;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 1616;
+    Thread_suspend_state_return_async_entry_point_offset = 1656;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 1624;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1664;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 1632;
+    Thread_suspend_state_init_async_star_entry_point_offset = 1672;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 1640;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 1680;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 1648;
+    Thread_suspend_state_return_async_star_entry_point_offset = 1688;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 1656;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1664;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1704;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 1672;
+    Thread_suspend_state_handle_exception_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 192;
+    Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 568;
@@ -3153,14 +3140,14 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1736;
+    1776;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1744;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1776;
-static constexpr dart::compiler::target::word Thread_random_offset = 1784;
+    Thread_callback_stack_return_offset = 1784;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1816;
+static constexpr dart::compiler::target::word Thread_random_offset = 1824;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 688;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1792;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1832;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -3176,9 +3163,6 @@
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
 static constexpr dart::compiler::target::word Type_arguments_offset = 24;
 static constexpr dart::compiler::target::word Type_hash_offset = 28;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
-static constexpr dart::compiler::target::word Type_type_state_offset = 34;
-static constexpr dart::compiler::target::word Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     36;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 32;
@@ -3202,8 +3186,6 @@
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    51;
 static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
@@ -3215,8 +3197,6 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 35;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    37;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 12;
@@ -3229,7 +3209,6 @@
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     20;
 static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 36;
 static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 20;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
@@ -3255,8 +3234,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, -1,   -1,   1544, 1552,
-        1560, 1568, 1576, -1,   1584, 1592, -1,   -1};
+        1552, 1560, 1568, 1576, -1,   -1,   1584, 1592,
+        1600, 1608, 1616, -1,   1624, 1632, -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 16;
@@ -3323,6 +3302,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 40;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
 static constexpr dart::compiler::target::word Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -3337,7 +3317,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 40;
+static constexpr dart::compiler::target::word Type_InstanceSize = 32;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -3387,6 +3367,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 16;
+static constexpr dart::compiler::target::word Record_element_size = 4;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 24;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
@@ -3409,7 +3391,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
@@ -3432,6 +3414,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 16;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -3462,7 +3445,7 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 108;
 static constexpr dart::compiler::target::word
-    SharedClassTable_class_heap_stats_table_offset = 0;
+    ClassTable_allocation_tracing_state_table_offset = 8;
 static constexpr dart::compiler::target::word Closure_context_offset = 24;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 16;
@@ -3511,7 +3494,7 @@
     GrowableObjectArray_length_offset = 12;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -3527,11 +3510,11 @@
     Isolate_has_resumption_breakpoints_offset = 89;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 64;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    40;
+    32;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    16;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 32;
+    IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word Isolate_single_step_offset = 88;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 40;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 16;
@@ -3568,29 +3551,31 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 984;
+    ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 1048;
+    ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 976;
+    ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 1008;
+    ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 992;
+    ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 1024;
+    ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
     16;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word Record_field_names_offset = 12;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -3621,9 +3606,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1752;
+    1792;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -3647,7 +3632,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1832;
+    1872;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -3660,13 +3645,13 @@
     Thread_call_to_runtime_entry_point_offset = 584;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1880;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1920;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1840;
+    Thread_double_truncate_round_supported_offset = 1880;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1888;
+    Thread_service_extension_stream_offset = 1928;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 488;
@@ -3682,7 +3667,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1792;
+    1832;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -3704,14 +3689,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1768;
+    1808;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1896;
+    1936;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -3764,11 +3749,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1776;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1816;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1784;
+    Thread_saved_shadow_call_stack_offset = 1824;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1800;
+    1840;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -3789,33 +3774,31 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 1680;
+    Thread_suspend_state_await_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 1672;
+    Thread_suspend_state_init_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 1688;
+    Thread_suspend_state_return_async_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 1696;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 1704;
+    Thread_suspend_state_init_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 1712;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 1720;
+    Thread_suspend_state_return_async_star_entry_point_offset = 1760;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 1728;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1736;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1776;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 1744;
+    Thread_suspend_state_handle_exception_entry_point_offset = 1784;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 192;
+    Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 568;
@@ -3823,14 +3806,14 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1808;
+    1848;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1816;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1848;
-static constexpr dart::compiler::target::word Thread_random_offset = 1856;
+    Thread_callback_stack_return_offset = 1856;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1888;
+static constexpr dart::compiler::target::word Thread_random_offset = 1896;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 688;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1864;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1904;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -3846,9 +3829,6 @@
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
 static constexpr dart::compiler::target::word Type_arguments_offset = 24;
 static constexpr dart::compiler::target::word Type_hash_offset = 28;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
-static constexpr dart::compiler::target::word Type_type_state_offset = 34;
-static constexpr dart::compiler::target::word Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     36;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 32;
@@ -3872,8 +3852,6 @@
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    51;
 static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
@@ -3885,8 +3863,6 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 35;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    37;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 12;
@@ -3899,7 +3875,6 @@
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     20;
 static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 36;
 static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 20;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
@@ -3925,9 +3900,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, 1592,
-        1600, 1608, 1616, 1624, -1,   -1,   -1,   -1,   1632, 1640, -1,
-        -1,   1648, 1656, 1664, -1,   -1,   -1,   -1,   -1,   -1};
+        1552, 1560, 1568, 1576, 1584, 1592, 1600, 1608, 1616, 1624, 1632,
+        1640, 1648, 1656, 1664, -1,   -1,   -1,   -1,   1672, 1680, -1,
+        -1,   1688, 1696, 1704, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 16;
@@ -3994,6 +3969,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 40;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
 static constexpr dart::compiler::target::word Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -4008,7 +3984,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 40;
+static constexpr dart::compiler::target::word Type_InstanceSize = 32;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -4058,6 +4034,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 12;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 12;
+static constexpr dart::compiler::target::word Record_element_size = 4;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 20;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
@@ -4080,7 +4058,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 4;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
@@ -4103,6 +4081,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 8;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 4;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -4133,7 +4112,7 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
-    SharedClassTable_class_heap_stats_table_offset = 0;
+    ClassTable_allocation_tracing_state_table_offset = 4;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -4182,7 +4161,7 @@
     GrowableObjectArray_length_offset = 8;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 4;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word Page_card_table_offset = 16;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -4198,11 +4177,11 @@
     Isolate_has_resumption_breakpoints_offset = 45;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 32;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    20;
+    16;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    8;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 8;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 16;
+    IsolateGroup_cached_class_table_table_offset = 12;
 static constexpr dart::compiler::target::word Isolate_single_step_offset = 44;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 20;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 12;
@@ -4239,28 +4218,30 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     112;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 492;
+    ObjectStore_suspend_state_await_offset = 496;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 524;
+    ObjectStore_suspend_state_handle_exception_offset = 528;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 488;
+    ObjectStore_suspend_state_init_async_offset = 492;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 504;
+    ObjectStore_suspend_state_init_async_star_offset = 508;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 516;
+    ObjectStore_suspend_state_init_sync_star_offset = 520;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 496;
+    ObjectStore_suspend_state_return_async_offset = 500;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 500;
+    ObjectStore_suspend_state_return_async_not_future_offset = 504;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 512;
+    ObjectStore_suspend_state_return_async_star_offset = 516;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 520;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 524;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 508;
+    ObjectStore_suspend_state_yield_async_star_offset = 512;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 4;
+static constexpr dart::compiler::target::word Record_field_names_offset = 8;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -4291,9 +4272,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 408;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    880;
+    900;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    884;
+    904;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 300;
 static constexpr dart::compiler::target::word
@@ -4316,7 +4297,7 @@
     Thread_allocate_object_slow_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 208;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 920;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 940;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 212;
 static constexpr dart::compiler::target::word
@@ -4329,13 +4310,13 @@
     Thread_call_to_runtime_entry_point_offset = 304;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 952;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 976;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 924;
+    Thread_double_truncate_round_supported_offset = 944;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 956;
+    Thread_service_extension_stream_offset = 980;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     344;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 256;
@@ -4351,7 +4332,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 280;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    900;
+    920;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 284;
 static constexpr dart::compiler::target::word
@@ -4373,13 +4354,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 404;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    888;
+    908;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    916;
+    936;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 960;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 984;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -4432,11 +4413,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 376;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 892;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 912;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 896;
+    Thread_saved_shadow_call_stack_offset = 916;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    904;
+    924;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -4457,47 +4438,45 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 844;
+    Thread_suspend_state_await_entry_point_offset = 864;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 840;
+    Thread_suspend_state_init_async_entry_point_offset = 860;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 848;
+    Thread_suspend_state_return_async_entry_point_offset = 868;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 852;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 872;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 856;
+    Thread_suspend_state_init_async_star_entry_point_offset = 876;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 860;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 880;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 864;
+    Thread_suspend_state_return_async_star_entry_point_offset = 884;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 868;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 888;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 872;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 892;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 876;
+    Thread_suspend_state_handle_exception_entry_point_offset = 896;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 96;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 104;
+    Thread_unboxed_runtime_arg_offset = 96;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 296;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 908;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 928;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 912;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 928;
-static constexpr dart::compiler::target::word Thread_random_offset = 936;
+    Thread_callback_stack_return_offset = 932;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 952;
+static constexpr dart::compiler::target::word Thread_random_offset = 960;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 356;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 944;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 968;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -4509,11 +4488,8 @@
     16;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 12;
-static constexpr dart::compiler::target::word Type_hash_offset = 16;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
-static constexpr dart::compiler::target::word Type_type_state_offset = 22;
-static constexpr dart::compiler::target::word Type_nullability_offset = 23;
+static constexpr dart::compiler::target::word Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word Type_hash_offset = 20;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     24;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 20;
@@ -4534,24 +4510,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 4;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     20;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    39;
+    FunctionType_named_parameter_names_offset = 28;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 32;
+    FunctionType_packed_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 36;
+    FunctionType_packed_type_parameter_counts_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 20;
+    FunctionType_parameter_types_offset = 24;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 12;
+    FunctionType_type_parameters_offset = 16;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 20;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 23;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    25;
+    TypeParameter_parameterized_class_id_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 27;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -4563,9 +4535,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     16;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 16;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 24;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     12;
@@ -4590,10 +4561,10 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,  -1,  -1, -1, -1, 768, 772, 776, -1,  -1,  780,
-        784, 788, -1, -1, -1, 792, 796, 800, 804, 808, 812,
-        816, 820, -1, -1, -1, -1,  824, 828, 832, 836};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
+        -1,  -1,  -1, -1, -1, 788, 792, 796, -1,  -1,  800,
+        804, 808, -1, -1, -1, 812, 816, 820, 824, 828, 832,
+        836, 840, -1, -1, -1, -1,  844, 848, 852, 856};
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 16;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
@@ -4624,7 +4595,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 88;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 40;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 44;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 8;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     16;
@@ -4659,6 +4630,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 28;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -4675,7 +4647,7 @@
 static constexpr dart::compiler::target::word Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
@@ -4722,6 +4694,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 24;
+static constexpr dart::compiler::target::word Record_element_size = 8;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
@@ -4746,7 +4720,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 10;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements =
@@ -4770,6 +4744,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 16;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -4800,7 +4775,7 @@
 static constexpr dart::compiler::target::word
     Class_host_type_arguments_field_offset_in_words_offset = 180;
 static constexpr dart::compiler::target::word
-    SharedClassTable_class_heap_stats_table_offset = 0;
+    ClassTable_allocation_tracing_state_table_offset = 8;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -4849,7 +4824,7 @@
     GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -4865,11 +4840,11 @@
     Isolate_has_resumption_breakpoints_offset = 89;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 64;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    40;
+    32;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    16;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 32;
+    IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word Isolate_single_step_offset = 88;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 40;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 24;
@@ -4906,29 +4881,31 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 984;
+    ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 1048;
+    ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 976;
+    ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 1008;
+    ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 992;
+    ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 1024;
+    ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
     16;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word Record_field_names_offset = 16;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -4959,9 +4936,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1736;
+    1776;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1744;
+    1784;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -4985,7 +4962,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1816;
+    1856;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -4998,13 +4975,13 @@
     Thread_call_to_runtime_entry_point_offset = 584;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1864;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1904;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1824;
+    Thread_double_truncate_round_supported_offset = 1864;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1872;
+    Thread_service_extension_stream_offset = 1912;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 488;
@@ -5020,7 +4997,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1776;
+    1816;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -5042,14 +5019,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1752;
+    1792;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1808;
+    1848;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1880;
+    1920;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -5102,11 +5079,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1760;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1800;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1768;
+    Thread_saved_shadow_call_stack_offset = 1808;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1784;
+    1824;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -5127,33 +5104,31 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 1664;
+    Thread_suspend_state_await_entry_point_offset = 1704;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 1656;
+    Thread_suspend_state_init_async_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 1672;
+    Thread_suspend_state_return_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 1680;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 1688;
+    Thread_suspend_state_init_async_star_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 1696;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 1704;
+    Thread_suspend_state_return_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 1712;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1720;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1760;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 1728;
+    Thread_suspend_state_handle_exception_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 192;
+    Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 568;
@@ -5161,14 +5136,14 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1792;
+    1832;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1800;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1832;
-static constexpr dart::compiler::target::word Thread_random_offset = 1840;
+    Thread_callback_stack_return_offset = 1840;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1872;
+static constexpr dart::compiler::target::word Thread_random_offset = 1880;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 688;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1848;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1888;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -5182,11 +5157,8 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
-static constexpr dart::compiler::target::word Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word Type_hash_offset = 40;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     48;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 40;
@@ -5207,24 +5179,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 8;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     40;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    71;
+    FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 64;
+    FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 68;
+    FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 40;
+    FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 24;
+    FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 43;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    45;
+    TypeParameter_parameterized_class_id_offset = 48;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 51;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -5236,9 +5204,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     32;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 32;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 44;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     24;
@@ -5263,10 +5230,10 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,   -1,   -1, -1, -1, 1512, 1520, 1528, -1,   -1,   1536,
-        1544, 1552, -1, -1, -1, 1560, 1568, 1576, 1584, 1592, 1600,
-        1608, 1616, -1, -1, -1, -1,   1624, 1632, 1640, 1648};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
+        -1,   -1,   -1, -1, -1, 1552, 1560, 1568, -1,   -1,   1576,
+        1584, 1592, -1, -1, -1, 1600, 1608, 1616, 1624, 1632, 1640,
+        1648, 1656, -1, -1, -1, -1,   1664, 1672, 1680, 1688};
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 32;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
@@ -5297,7 +5264,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 128;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 80;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     32;
@@ -5332,6 +5299,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word Script_InstanceSize = 80;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -5347,9 +5315,9 @@
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word Type_InstanceSize = 48;
-static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
+static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
@@ -5395,6 +5363,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 12;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 12;
+static constexpr dart::compiler::target::word Record_element_size = 4;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 20;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
@@ -5417,7 +5387,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 4;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
@@ -5440,6 +5410,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 8;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 4;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -5517,7 +5488,7 @@
     GrowableObjectArray_length_offset = 8;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 4;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word Page_card_table_offset = 16;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -5531,11 +5502,11 @@
 static constexpr dart::compiler::target::word Isolate_finalizers_offset = 36;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    20;
+    16;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    8;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 8;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 16;
+    IsolateGroup_cached_class_table_table_offset = 12;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 12;
 static constexpr dart::compiler::target::word
@@ -5571,28 +5542,30 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     112;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 492;
+    ObjectStore_suspend_state_await_offset = 496;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 524;
+    ObjectStore_suspend_state_handle_exception_offset = 528;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 488;
+    ObjectStore_suspend_state_init_async_offset = 492;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 504;
+    ObjectStore_suspend_state_init_async_star_offset = 508;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 516;
+    ObjectStore_suspend_state_init_sync_star_offset = 520;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 496;
+    ObjectStore_suspend_state_return_async_offset = 500;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 500;
+    ObjectStore_suspend_state_return_async_not_future_offset = 504;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 512;
+    ObjectStore_suspend_state_return_async_star_offset = 516;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 520;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 524;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 508;
+    ObjectStore_suspend_state_yield_async_star_offset = 512;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 4;
+static constexpr dart::compiler::target::word Record_field_names_offset = 8;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -5623,9 +5596,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 408;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    840;
+    860;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    844;
+    864;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 300;
 static constexpr dart::compiler::target::word
@@ -5648,7 +5621,7 @@
     Thread_allocate_object_slow_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 208;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 880;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 900;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 212;
 static constexpr dart::compiler::target::word
@@ -5661,13 +5634,13 @@
     Thread_call_to_runtime_entry_point_offset = 304;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 912;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 936;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 884;
+    Thread_double_truncate_round_supported_offset = 904;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 916;
+    Thread_service_extension_stream_offset = 940;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     344;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 256;
@@ -5683,7 +5656,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 280;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    860;
+    880;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 284;
 static constexpr dart::compiler::target::word
@@ -5705,13 +5678,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 404;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    848;
+    868;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    876;
+    896;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 920;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 944;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -5764,11 +5737,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 376;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 852;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 872;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 856;
+    Thread_saved_shadow_call_stack_offset = 876;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    864;
+    884;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -5789,47 +5762,45 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 804;
+    Thread_suspend_state_await_entry_point_offset = 824;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 800;
+    Thread_suspend_state_init_async_entry_point_offset = 820;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 808;
+    Thread_suspend_state_return_async_entry_point_offset = 828;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 812;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 832;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 816;
+    Thread_suspend_state_init_async_star_entry_point_offset = 836;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 820;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 840;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 824;
+    Thread_suspend_state_return_async_star_entry_point_offset = 844;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 828;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 848;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 832;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 852;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 836;
+    Thread_suspend_state_handle_exception_entry_point_offset = 856;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 96;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 104;
+    Thread_unboxed_runtime_arg_offset = 96;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 296;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 868;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 888;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 872;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 888;
-static constexpr dart::compiler::target::word Thread_random_offset = 896;
+    Thread_callback_stack_return_offset = 892;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 912;
+static constexpr dart::compiler::target::word Thread_random_offset = 920;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 356;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 904;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 928;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -5841,11 +5812,8 @@
     16;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 12;
-static constexpr dart::compiler::target::word Type_hash_offset = 16;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
-static constexpr dart::compiler::target::word Type_type_state_offset = 22;
-static constexpr dart::compiler::target::word Type_nullability_offset = 23;
+static constexpr dart::compiler::target::word Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word Type_hash_offset = 20;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     24;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 20;
@@ -5866,24 +5834,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 4;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     20;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    39;
+    FunctionType_named_parameter_names_offset = 28;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 32;
+    FunctionType_packed_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 36;
+    FunctionType_packed_type_parameter_counts_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 20;
+    FunctionType_parameter_types_offset = 24;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 12;
+    FunctionType_type_parameters_offset = 16;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 20;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 23;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    25;
+    TypeParameter_parameterized_class_id_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 27;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -5895,9 +5859,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     16;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 16;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 24;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     12;
@@ -5922,8 +5885,8 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        768, 772, 776, 780, 784, -1, 788, -1, 792, 796, -1, -1, -1, -1, -1, -1};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
+        788, 792, 796, 800, 804, -1, 808, -1, 812, 816, -1, -1, -1, -1, -1, -1};
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 16;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
@@ -5954,7 +5917,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 88;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 40;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 44;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 8;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     16;
@@ -5989,6 +5952,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 12;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 28;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -6005,7 +5969,7 @@
 static constexpr dart::compiler::target::word Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
@@ -6049,6 +6013,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 24;
+static constexpr dart::compiler::target::word Record_element_size = 8;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
@@ -6073,7 +6039,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 10;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements =
@@ -6097,6 +6063,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 16;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -6174,7 +6141,7 @@
     GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -6188,11 +6155,11 @@
 static constexpr dart::compiler::target::word Isolate_finalizers_offset = 72;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    40;
+    32;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    16;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 32;
+    IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 24;
 static constexpr dart::compiler::target::word
@@ -6228,29 +6195,31 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 984;
+    ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 1048;
+    ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 976;
+    ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 1008;
+    ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 992;
+    ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 1024;
+    ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
     16;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word Record_field_names_offset = 16;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -6281,9 +6250,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1680;
+    1720;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1688;
+    1728;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -6307,7 +6276,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -6320,13 +6289,13 @@
     Thread_call_to_runtime_entry_point_offset = 584;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1808;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1848;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1768;
+    Thread_double_truncate_round_supported_offset = 1808;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1816;
+    Thread_service_extension_stream_offset = 1856;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 488;
@@ -6342,7 +6311,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1720;
+    1760;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -6364,14 +6333,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1696;
+    1736;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1752;
+    1792;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -6424,11 +6393,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1704;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1744;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1712;
+    Thread_saved_shadow_call_stack_offset = 1752;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1728;
+    1768;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -6449,33 +6418,31 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 1608;
+    Thread_suspend_state_await_entry_point_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 1600;
+    Thread_suspend_state_init_async_entry_point_offset = 1640;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 1616;
+    Thread_suspend_state_return_async_entry_point_offset = 1656;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 1624;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1664;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 1632;
+    Thread_suspend_state_init_async_star_entry_point_offset = 1672;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 1640;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 1680;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 1648;
+    Thread_suspend_state_return_async_star_entry_point_offset = 1688;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 1656;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1664;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1704;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 1672;
+    Thread_suspend_state_handle_exception_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 192;
+    Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 568;
@@ -6483,14 +6450,14 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1736;
+    1776;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1744;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1776;
-static constexpr dart::compiler::target::word Thread_random_offset = 1784;
+    Thread_callback_stack_return_offset = 1784;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1816;
+static constexpr dart::compiler::target::word Thread_random_offset = 1824;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 688;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1792;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1832;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -6504,11 +6471,8 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
-static constexpr dart::compiler::target::word Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word Type_hash_offset = 40;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     48;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 40;
@@ -6529,24 +6493,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 8;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     40;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    71;
+    FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 64;
+    FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 68;
+    FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 40;
+    FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 24;
+    FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 43;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    45;
+    TypeParameter_parameterized_class_id_offset = 48;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 51;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -6558,9 +6518,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     32;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 32;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 44;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     24;
@@ -6585,9 +6544,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, -1,   -1,   1544, 1552,
-        1560, 1568, 1576, -1,   1584, 1592, -1,   -1};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
+        1552, 1560, 1568, 1576, -1,   -1,   1584, 1592,
+        1600, 1608, 1616, -1,   1624, 1632, -1,   -1};
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 32;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
@@ -6618,7 +6577,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 128;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 80;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     32;
@@ -6653,6 +6612,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word Script_InstanceSize = 80;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -6668,9 +6628,9 @@
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word Type_InstanceSize = 48;
-static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
+static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
@@ -6714,6 +6674,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 12;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 12;
+static constexpr dart::compiler::target::word Record_element_size = 4;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 20;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
@@ -6736,7 +6698,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 4;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
@@ -6759,6 +6721,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 8;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 4;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -6836,7 +6799,7 @@
     GrowableObjectArray_length_offset = 8;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 4;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word Page_card_table_offset = 16;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -6850,11 +6813,11 @@
 static constexpr dart::compiler::target::word Isolate_finalizers_offset = 36;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    20;
+    16;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    8;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 8;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 16;
+    IsolateGroup_cached_class_table_table_offset = 12;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 12;
 static constexpr dart::compiler::target::word
@@ -6890,28 +6853,30 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     112;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 492;
+    ObjectStore_suspend_state_await_offset = 496;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 524;
+    ObjectStore_suspend_state_handle_exception_offset = 528;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 488;
+    ObjectStore_suspend_state_init_async_offset = 492;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 504;
+    ObjectStore_suspend_state_init_async_star_offset = 508;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 516;
+    ObjectStore_suspend_state_init_sync_star_offset = 520;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 496;
+    ObjectStore_suspend_state_return_async_offset = 500;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 500;
+    ObjectStore_suspend_state_return_async_not_future_offset = 504;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 512;
+    ObjectStore_suspend_state_return_async_star_offset = 516;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 520;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 524;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 508;
+    ObjectStore_suspend_state_yield_async_star_offset = 512;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 4;
+static constexpr dart::compiler::target::word Record_field_names_offset = 8;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -6942,9 +6907,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 408;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    808;
+    828;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    812;
+    832;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 300;
 static constexpr dart::compiler::target::word
@@ -6967,7 +6932,7 @@
     Thread_allocate_object_slow_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 208;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 848;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 868;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 212;
 static constexpr dart::compiler::target::word
@@ -6980,13 +6945,13 @@
     Thread_call_to_runtime_entry_point_offset = 304;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 880;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 904;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 852;
+    Thread_double_truncate_round_supported_offset = 872;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 884;
+    Thread_service_extension_stream_offset = 908;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     344;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 256;
@@ -7002,7 +6967,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 280;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    828;
+    848;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 284;
 static constexpr dart::compiler::target::word
@@ -7024,13 +6989,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 404;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    816;
+    836;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    844;
+    864;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 888;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 912;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -7083,11 +7048,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 376;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 820;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 840;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 824;
+    Thread_saved_shadow_call_stack_offset = 844;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    832;
+    852;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -7108,47 +7073,45 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 772;
+    Thread_suspend_state_await_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 768;
+    Thread_suspend_state_init_async_entry_point_offset = 788;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 776;
+    Thread_suspend_state_return_async_entry_point_offset = 796;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 780;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 800;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 784;
+    Thread_suspend_state_init_async_star_entry_point_offset = 804;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 788;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 808;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 792;
+    Thread_suspend_state_return_async_star_entry_point_offset = 812;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 796;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 816;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 800;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 820;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 804;
+    Thread_suspend_state_handle_exception_entry_point_offset = 824;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 96;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 104;
+    Thread_unboxed_runtime_arg_offset = 96;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 296;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 836;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 856;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 840;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 856;
-static constexpr dart::compiler::target::word Thread_random_offset = 864;
+    Thread_callback_stack_return_offset = 860;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 880;
+static constexpr dart::compiler::target::word Thread_random_offset = 888;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 356;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 872;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 896;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -7160,11 +7123,8 @@
     16;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 12;
-static constexpr dart::compiler::target::word Type_hash_offset = 16;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
-static constexpr dart::compiler::target::word Type_type_state_offset = 22;
-static constexpr dart::compiler::target::word Type_nullability_offset = 23;
+static constexpr dart::compiler::target::word Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word Type_hash_offset = 20;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     24;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 20;
@@ -7185,24 +7145,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 4;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     20;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    39;
+    FunctionType_named_parameter_names_offset = 28;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 32;
+    FunctionType_packed_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 36;
+    FunctionType_packed_type_parameter_counts_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 20;
+    FunctionType_parameter_types_offset = 24;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 12;
+    FunctionType_type_parameters_offset = 16;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 20;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 23;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    25;
+    TypeParameter_parameterized_class_id_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 27;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -7214,9 +7170,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     16;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 16;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 24;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     12;
@@ -7239,7 +7194,7 @@
     WeakReference_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
     4, 12, 8, 16};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 16;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
@@ -7270,7 +7225,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 88;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 40;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 44;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 8;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     16;
@@ -7305,6 +7260,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 12;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 28;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -7321,7 +7277,7 @@
 static constexpr dart::compiler::target::word Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
@@ -7365,6 +7321,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 24;
+static constexpr dart::compiler::target::word Record_element_size = 8;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
@@ -7389,7 +7347,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 10;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements =
@@ -7413,6 +7371,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 16;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -7490,7 +7449,7 @@
     GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -7504,11 +7463,11 @@
 static constexpr dart::compiler::target::word Isolate_finalizers_offset = 72;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    40;
+    32;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    16;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 32;
+    IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 24;
 static constexpr dart::compiler::target::word
@@ -7544,29 +7503,31 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 984;
+    ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 1048;
+    ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 976;
+    ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 1008;
+    ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 992;
+    ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 1024;
+    ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
     16;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word Record_field_names_offset = 16;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -7597,9 +7558,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1752;
+    1792;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -7623,7 +7584,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1832;
+    1872;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -7636,13 +7597,13 @@
     Thread_call_to_runtime_entry_point_offset = 584;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1880;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1920;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1840;
+    Thread_double_truncate_round_supported_offset = 1880;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1888;
+    Thread_service_extension_stream_offset = 1928;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 488;
@@ -7658,7 +7619,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1792;
+    1832;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -7680,14 +7641,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1768;
+    1808;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1896;
+    1936;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -7740,11 +7701,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1776;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1816;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1784;
+    Thread_saved_shadow_call_stack_offset = 1824;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1800;
+    1840;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -7765,33 +7726,31 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 1680;
+    Thread_suspend_state_await_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 1672;
+    Thread_suspend_state_init_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 1688;
+    Thread_suspend_state_return_async_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 1696;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 1704;
+    Thread_suspend_state_init_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 1712;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 1720;
+    Thread_suspend_state_return_async_star_entry_point_offset = 1760;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 1728;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1736;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1776;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 1744;
+    Thread_suspend_state_handle_exception_entry_point_offset = 1784;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 192;
+    Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 568;
@@ -7799,14 +7758,14 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1808;
+    1848;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1816;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1848;
-static constexpr dart::compiler::target::word Thread_random_offset = 1856;
+    Thread_callback_stack_return_offset = 1856;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1888;
+static constexpr dart::compiler::target::word Thread_random_offset = 1896;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 688;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1864;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1904;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -7820,11 +7779,8 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
-static constexpr dart::compiler::target::word Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word Type_hash_offset = 40;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     48;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 40;
@@ -7845,24 +7801,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 8;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     40;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    71;
+    FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 64;
+    FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 68;
+    FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 40;
+    FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 24;
+    FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 43;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    45;
+    TypeParameter_parameterized_class_id_offset = 48;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 51;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -7874,9 +7826,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     32;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 32;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 44;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     24;
@@ -7901,10 +7852,10 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, 1592,
-        1600, 1608, 1616, 1624, -1,   -1,   -1,   -1,   1632, 1640, -1,
-        -1,   1648, 1656, 1664, -1,   -1,   -1,   -1,   -1,   -1};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
+        1552, 1560, 1568, 1576, 1584, 1592, 1600, 1608, 1616, 1624, 1632,
+        1640, 1648, 1656, 1664, -1,   -1,   -1,   -1,   1672, 1680, -1,
+        -1,   1688, 1696, 1704, -1,   -1,   -1,   -1,   -1,   -1};
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 32;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
@@ -7935,7 +7886,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 128;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 80;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     32;
@@ -7970,6 +7921,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word Script_InstanceSize = 80;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -7985,9 +7937,9 @@
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word Type_InstanceSize = 48;
-static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
+static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
@@ -8031,6 +7983,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 16;
+static constexpr dart::compiler::target::word Record_element_size = 4;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 24;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
@@ -8053,7 +8007,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
@@ -8076,6 +8030,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 16;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -8153,7 +8108,7 @@
     GrowableObjectArray_length_offset = 12;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -8167,11 +8122,11 @@
 static constexpr dart::compiler::target::word Isolate_finalizers_offset = 72;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    40;
+    32;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    16;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 32;
+    IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -8207,29 +8162,31 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 984;
+    ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 1048;
+    ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 976;
+    ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 1008;
+    ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 992;
+    ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 1024;
+    ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
     16;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word Record_field_names_offset = 12;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -8260,9 +8217,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1680;
+    1720;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1688;
+    1728;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -8286,7 +8243,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -8299,13 +8256,13 @@
     Thread_call_to_runtime_entry_point_offset = 584;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1808;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1848;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1768;
+    Thread_double_truncate_round_supported_offset = 1808;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1816;
+    Thread_service_extension_stream_offset = 1856;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 488;
@@ -8321,7 +8278,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1720;
+    1760;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -8343,14 +8300,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1696;
+    1736;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1752;
+    1792;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -8403,11 +8360,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1704;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1744;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1712;
+    Thread_saved_shadow_call_stack_offset = 1752;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1728;
+    1768;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -8428,33 +8385,31 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 1608;
+    Thread_suspend_state_await_entry_point_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 1600;
+    Thread_suspend_state_init_async_entry_point_offset = 1640;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 1616;
+    Thread_suspend_state_return_async_entry_point_offset = 1656;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 1624;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1664;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 1632;
+    Thread_suspend_state_init_async_star_entry_point_offset = 1672;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 1640;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 1680;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 1648;
+    Thread_suspend_state_return_async_star_entry_point_offset = 1688;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 1656;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1664;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1704;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 1672;
+    Thread_suspend_state_handle_exception_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 192;
+    Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 568;
@@ -8462,14 +8417,14 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1736;
+    1776;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1744;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1776;
-static constexpr dart::compiler::target::word Thread_random_offset = 1784;
+    Thread_callback_stack_return_offset = 1784;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1816;
+static constexpr dart::compiler::target::word Thread_random_offset = 1824;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 688;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1792;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1832;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -8485,9 +8440,6 @@
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
 static constexpr dart::compiler::target::word Type_arguments_offset = 24;
 static constexpr dart::compiler::target::word Type_hash_offset = 28;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
-static constexpr dart::compiler::target::word Type_type_state_offset = 34;
-static constexpr dart::compiler::target::word Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     36;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 32;
@@ -8511,8 +8463,6 @@
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    51;
 static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
@@ -8524,8 +8474,6 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 35;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    37;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 12;
@@ -8538,7 +8486,6 @@
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     20;
 static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 36;
 static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 20;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
@@ -8564,8 +8511,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, -1,   -1,   1544, 1552,
-        1560, 1568, 1576, -1,   1584, 1592, -1,   -1};
+        1552, 1560, 1568, 1576, -1,   -1,   1584, 1592,
+        1600, 1608, 1616, -1,   1624, 1632, -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 16;
@@ -8632,6 +8579,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 16;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 40;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
 static constexpr dart::compiler::target::word Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -8646,7 +8594,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 40;
+static constexpr dart::compiler::target::word Type_InstanceSize = 32;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -8693,6 +8641,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 16;
+static constexpr dart::compiler::target::word Record_element_size = 4;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 24;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
@@ -8715,7 +8665,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
@@ -8738,6 +8688,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 16;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -8815,7 +8766,7 @@
     GrowableObjectArray_length_offset = 12;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -8829,11 +8780,11 @@
 static constexpr dart::compiler::target::word Isolate_finalizers_offset = 72;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    40;
+    32;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    16;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 32;
+    IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -8869,29 +8820,31 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 984;
+    ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 1048;
+    ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 976;
+    ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 1008;
+    ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 992;
+    ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 1024;
+    ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
     16;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word Record_field_names_offset = 12;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -8922,9 +8875,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1752;
+    1792;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -8948,7 +8901,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1832;
+    1872;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -8961,13 +8914,13 @@
     Thread_call_to_runtime_entry_point_offset = 584;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1880;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1920;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1840;
+    Thread_double_truncate_round_supported_offset = 1880;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1888;
+    Thread_service_extension_stream_offset = 1928;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 488;
@@ -8983,7 +8936,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1792;
+    1832;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -9005,14 +8958,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1768;
+    1808;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1896;
+    1936;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -9065,11 +9018,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1776;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1816;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1784;
+    Thread_saved_shadow_call_stack_offset = 1824;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1800;
+    1840;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -9090,33 +9043,31 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 1680;
+    Thread_suspend_state_await_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 1672;
+    Thread_suspend_state_init_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 1688;
+    Thread_suspend_state_return_async_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 1696;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 1704;
+    Thread_suspend_state_init_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 1712;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 1720;
+    Thread_suspend_state_return_async_star_entry_point_offset = 1760;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 1728;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1736;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1776;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 1744;
+    Thread_suspend_state_handle_exception_entry_point_offset = 1784;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 192;
+    Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 568;
@@ -9124,14 +9075,14 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1808;
+    1848;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1816;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1848;
-static constexpr dart::compiler::target::word Thread_random_offset = 1856;
+    Thread_callback_stack_return_offset = 1856;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1888;
+static constexpr dart::compiler::target::word Thread_random_offset = 1896;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 688;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1864;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1904;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -9147,9 +9098,6 @@
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
 static constexpr dart::compiler::target::word Type_arguments_offset = 24;
 static constexpr dart::compiler::target::word Type_hash_offset = 28;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
-static constexpr dart::compiler::target::word Type_type_state_offset = 34;
-static constexpr dart::compiler::target::word Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     36;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 32;
@@ -9173,8 +9121,6 @@
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    51;
 static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
@@ -9186,8 +9132,6 @@
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
 static constexpr dart::compiler::target::word TypeParameter_index_offset = 35;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    37;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 12;
@@ -9200,7 +9144,6 @@
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     20;
 static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 36;
 static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 20;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
@@ -9226,9 +9169,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, 1592,
-        1600, 1608, 1616, 1624, -1,   -1,   -1,   -1,   1632, 1640, -1,
-        -1,   1648, 1656, 1664, -1,   -1,   -1,   -1,   -1,   -1};
+        1552, 1560, 1568, 1576, 1584, 1592, 1600, 1608, 1616, 1624, 1632,
+        1640, 1648, 1656, 1664, -1,   -1,   -1,   -1,   1672, 1680, -1,
+        -1,   1688, 1696, 1704, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 16;
@@ -9295,6 +9238,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 16;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 40;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
 static constexpr dart::compiler::target::word Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -9309,7 +9253,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 40;
+static constexpr dart::compiler::target::word Type_InstanceSize = 32;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -9356,6 +9300,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 12;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 12;
+static constexpr dart::compiler::target::word Record_element_size = 4;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 20;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
@@ -9378,7 +9324,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 4;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
@@ -9401,6 +9347,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 8;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 4;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -9478,7 +9425,7 @@
     GrowableObjectArray_length_offset = 8;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 4;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word Page_card_table_offset = 16;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -9492,11 +9439,11 @@
 static constexpr dart::compiler::target::word Isolate_finalizers_offset = 36;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    20;
+    16;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    8;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 8;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 16;
+    IsolateGroup_cached_class_table_table_offset = 12;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 12;
 static constexpr dart::compiler::target::word
@@ -9532,28 +9479,30 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     112;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 492;
+    ObjectStore_suspend_state_await_offset = 496;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 524;
+    ObjectStore_suspend_state_handle_exception_offset = 528;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 488;
+    ObjectStore_suspend_state_init_async_offset = 492;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 504;
+    ObjectStore_suspend_state_init_async_star_offset = 508;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 516;
+    ObjectStore_suspend_state_init_sync_star_offset = 520;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 496;
+    ObjectStore_suspend_state_return_async_offset = 500;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 500;
+    ObjectStore_suspend_state_return_async_not_future_offset = 504;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 512;
+    ObjectStore_suspend_state_return_async_star_offset = 516;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 520;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 524;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 508;
+    ObjectStore_suspend_state_yield_async_star_offset = 512;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 4;
+static constexpr dart::compiler::target::word Record_field_names_offset = 8;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -9584,9 +9533,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 408;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    880;
+    900;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    884;
+    904;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 300;
 static constexpr dart::compiler::target::word
@@ -9609,7 +9558,7 @@
     Thread_allocate_object_slow_entry_point_offset = 324;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 208;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 920;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 940;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 212;
 static constexpr dart::compiler::target::word
@@ -9622,13 +9571,13 @@
     Thread_call_to_runtime_entry_point_offset = 304;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 952;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 976;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 924;
+    Thread_double_truncate_round_supported_offset = 944;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 956;
+    Thread_service_extension_stream_offset = 980;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     344;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 256;
@@ -9644,7 +9593,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 280;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    900;
+    920;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 284;
 static constexpr dart::compiler::target::word
@@ -9666,13 +9615,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 404;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    888;
+    908;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    916;
+    936;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 960;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 984;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -9725,11 +9674,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 376;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 892;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 912;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 896;
+    Thread_saved_shadow_call_stack_offset = 916;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    904;
+    924;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -9750,47 +9699,45 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 844;
+    Thread_suspend_state_await_entry_point_offset = 864;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 840;
+    Thread_suspend_state_init_async_entry_point_offset = 860;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 848;
+    Thread_suspend_state_return_async_entry_point_offset = 868;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 852;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 872;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 856;
+    Thread_suspend_state_init_async_star_entry_point_offset = 876;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 860;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 880;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 864;
+    Thread_suspend_state_return_async_star_entry_point_offset = 884;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 868;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 888;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 872;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 892;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 876;
+    Thread_suspend_state_handle_exception_entry_point_offset = 896;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 96;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 104;
+    Thread_unboxed_runtime_arg_offset = 96;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 296;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 908;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 928;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 912;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 928;
-static constexpr dart::compiler::target::word Thread_random_offset = 936;
+    Thread_callback_stack_return_offset = 932;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 952;
+static constexpr dart::compiler::target::word Thread_random_offset = 960;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 356;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 944;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 968;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -9802,11 +9749,8 @@
     16;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 12;
-static constexpr dart::compiler::target::word Type_hash_offset = 16;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
-static constexpr dart::compiler::target::word Type_type_state_offset = 22;
-static constexpr dart::compiler::target::word Type_nullability_offset = 23;
+static constexpr dart::compiler::target::word Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word Type_hash_offset = 20;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     24;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 20;
@@ -9827,24 +9771,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 4;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     20;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    39;
+    FunctionType_named_parameter_names_offset = 28;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 32;
+    FunctionType_packed_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 36;
+    FunctionType_packed_type_parameter_counts_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 20;
+    FunctionType_parameter_types_offset = 24;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 12;
+    FunctionType_type_parameters_offset = 16;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 20;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 23;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    25;
+    TypeParameter_parameterized_class_id_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 27;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 8;
@@ -9856,9 +9796,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     16;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 16;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 24;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     12;
@@ -9883,10 +9822,10 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,  -1,  -1, -1, -1, 768, 772, 776, -1,  -1,  780,
-        784, 788, -1, -1, -1, 792, 796, 800, 804, 808, 812,
-        816, 820, -1, -1, -1, -1,  824, 828, 832, 836};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
+        -1,  -1,  -1, -1, -1, 788, 792, 796, -1,  -1,  800,
+        804, 808, -1, -1, -1, 812, 816, 820, 824, 828, 832,
+        836, 840, -1, -1, -1, -1,  844, 848, 852, 856};
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 16;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
@@ -9917,7 +9856,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 88;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 40;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 44;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 8;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     16;
@@ -9952,6 +9891,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 12;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 28;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -9968,7 +9908,7 @@
 static constexpr dart::compiler::target::word Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
@@ -10012,6 +9952,8 @@
 static constexpr dart::compiler::target::word
     OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word OneByteString_element_size = 1;
+static constexpr dart::compiler::target::word Record_elements_start_offset = 24;
+static constexpr dart::compiler::target::word Record_element_size = 8;
 static constexpr dart::compiler::target::word
     TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
@@ -10036,7 +9978,7 @@
     Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word OldPage_kBytesPerCardLog2 = 10;
+static constexpr dart::compiler::target::word Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word String_kMaxElements =
@@ -10060,6 +10002,7 @@
 static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
 static constexpr dart::compiler::target::word TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AbstractType_flags_offset = 16;
 static constexpr dart::compiler::target::word
     AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
@@ -10137,7 +10080,7 @@
     GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word OldPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
@@ -10151,11 +10094,11 @@
 static constexpr dart::compiler::target::word Isolate_finalizers_offset = 72;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
 static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
-    40;
+    32;
+static constexpr dart::compiler::target::word IsolateGroup_class_table_offset =
+    16;
 static constexpr dart::compiler::target::word
-    IsolateGroup_shared_class_table_offset = 16;
-static constexpr dart::compiler::target::word
-    IsolateGroup_cached_class_table_table_offset = 32;
+    IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 24;
 static constexpr dart::compiler::target::word
@@ -10191,29 +10134,31 @@
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_await_offset = 984;
+    ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_handle_exception_offset = 1048;
+    ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_offset = 976;
+    ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_async_star_offset = 1008;
+    ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_offset = 992;
+    ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_return_async_star_offset = 1024;
+    ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
     16;
+static constexpr dart::compiler::target::word Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word Record_field_names_offset = 16;
 static constexpr dart::compiler::target::word
     SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -10244,9 +10189,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1736;
+    1776;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1744;
+    1784;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -10270,7 +10215,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1816;
+    1856;
 static constexpr dart::compiler::target::word
     Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -10283,13 +10228,13 @@
     Thread_call_to_runtime_entry_point_offset = 584;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1864;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1904;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1824;
+    Thread_double_truncate_round_supported_offset = 1864;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1872;
+    Thread_service_extension_stream_offset = 1912;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 488;
@@ -10305,7 +10250,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1776;
+    1816;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -10327,14 +10272,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1752;
+    1792;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1808;
+    1848;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1880;
+    1920;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -10387,11 +10332,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 728;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1760;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1800;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1768;
+    Thread_saved_shadow_call_stack_offset = 1808;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1784;
+    1824;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -10412,33 +10357,31 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_await_entry_point_offset = 1664;
+    Thread_suspend_state_await_entry_point_offset = 1704;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_entry_point_offset = 1656;
+    Thread_suspend_state_init_async_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_entry_point_offset = 1672;
+    Thread_suspend_state_return_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_not_future_entry_point_offset = 1680;
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_async_star_entry_point_offset = 1688;
+    Thread_suspend_state_init_async_star_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_yield_async_star_entry_point_offset = 1696;
+    Thread_suspend_state_yield_async_star_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_return_async_star_entry_point_offset = 1704;
+    Thread_suspend_state_return_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_init_sync_star_entry_point_offset = 1712;
+    Thread_suspend_state_init_sync_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1720;
+    Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset = 1760;
 static constexpr dart::compiler::target::word
-    Thread_suspend_state_handle_exception_entry_point_offset = 1728;
+    Thread_suspend_state_handle_exception_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
 static constexpr dart::compiler::target::word
-    Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    Thread_unboxed_double_runtime_arg_offset = 192;
+    Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     Thread_write_barrier_entry_point_offset = 568;
@@ -10446,14 +10389,14 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1792;
+    1832;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1800;
-static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1832;
-static constexpr dart::compiler::target::word Thread_random_offset = 1840;
+    Thread_callback_stack_return_offset = 1840;
+static constexpr dart::compiler::target::word Thread_next_task_id_offset = 1872;
+static constexpr dart::compiler::target::word Thread_random_offset = 1880;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 688;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1848;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1888;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -10467,11 +10410,8 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
-static constexpr dart::compiler::target::word Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word Type_hash_offset = 40;
 static constexpr dart::compiler::target::word Finalizer_type_arguments_offset =
     48;
 static constexpr dart::compiler::target::word Finalizer_callback_offset = 40;
@@ -10492,24 +10432,20 @@
 static constexpr dart::compiler::target::word FinalizerEntry_value_offset = 8;
 static constexpr dart::compiler::target::word NativeFinalizer_callback_offset =
     40;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word FunctionType_nullability_offset =
-    71;
+    FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_parameter_counts_offset = 64;
+    FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_type_parameter_counts_offset = 68;
+    FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 40;
+    FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 24;
+    FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 43;
-static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    45;
+    TypeParameter_parameterized_class_id_offset = 48;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 51;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
@@ -10521,9 +10457,8 @@
 static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
 static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
     32;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 32;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 44;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
 static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
     24;
@@ -10548,10 +10483,10 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,   -1,   -1, -1, -1, 1512, 1520, 1528, -1,   -1,   1536,
-        1544, 1552, -1, -1, -1, 1560, 1568, 1576, 1584, 1592, 1600,
-        1608, 1616, -1, -1, -1, -1,   1624, 1632, 1640, 1648};
-static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
+        -1,   -1,   -1, -1, -1, 1552, 1560, 1568, -1,   -1,   1576,
+        1584, 1592, -1, -1, -1, 1600, 1608, 1616, 1624, 1632, 1640,
+        1648, 1656, -1, -1, -1, -1,   1664, 1672, 1680, 1688};
+static constexpr dart::compiler::target::word AbstractType_InstanceSize = 32;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
@@ -10582,7 +10517,7 @@
 static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word Function_InstanceSize = 128;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 80;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     32;
@@ -10617,6 +10552,7 @@
 static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word Script_InstanceSize = 80;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
@@ -10632,9 +10568,9 @@
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word Type_InstanceSize = 48;
-static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
+static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
@@ -10683,6 +10619,9 @@
     AOT_OneByteString_elements_start_offset = 12;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 4;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -10709,7 +10648,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 4;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -10734,6 +10673,7 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 4;
 static constexpr dart::compiler::target::word
@@ -10765,7 +10705,7 @@
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 84;
 static constexpr dart::compiler::target::word
-    AOT_SharedClassTable_class_heap_stats_table_offset = 0;
+    AOT_ClassTable_allocation_tracing_state_table_offset = 4;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 12;
@@ -10816,8 +10756,7 @@
     AOT_GrowableObjectArray_length_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 4;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    20;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -10837,11 +10776,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 20;
+    AOT_IsolateGroup_object_store_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 8;
+    AOT_IsolateGroup_class_table_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 16;
+    AOT_IsolateGroup_cached_class_table_table_offset = 12;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
     44;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 20;
@@ -10886,30 +10825,32 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     112;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 492;
+    AOT_ObjectStore_suspend_state_await_offset = 496;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 524;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 488;
+    AOT_ObjectStore_suspend_state_init_async_offset = 492;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 504;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 508;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 516;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 496;
+    AOT_ObjectStore_suspend_state_return_async_offset = 500;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 500;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 512;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 516;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 520;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 524;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 508;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 512;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     12;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 4;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 4;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -10943,9 +10884,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 408;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 840;
+    AOT_Thread_active_exception_offset = 860;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 844;
+    AOT_Thread_active_stacktrace_offset = 864;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 300;
 static constexpr dart::compiler::target::word
@@ -10969,7 +10910,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 208;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    880;
+    900;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 212;
 static constexpr dart::compiler::target::word
@@ -10984,13 +10925,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 140;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    912;
+    936;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 884;
+    AOT_Thread_double_truncate_round_supported_offset = 904;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 916;
+    AOT_Thread_service_extension_stream_offset = 940;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     344;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -11007,7 +10948,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 860;
+    AOT_Thread_execution_state_offset = 880;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 284;
 static constexpr dart::compiler::target::word
@@ -11029,14 +10970,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 404;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 848;
+    AOT_Thread_global_object_pool_offset = 868;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 876;
+    AOT_Thread_exit_through_ffi_offset = 896;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    920;
+    944;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 64;
 static constexpr dart::compiler::target::word
@@ -11092,11 +11033,11 @@
     112;
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 376;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 852;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 872;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 856;
+    AOT_Thread_saved_shadow_call_stack_offset = 876;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 864;
+    AOT_Thread_safepoint_state_offset = 884;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -11118,35 +11059,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 804;
+    AOT_Thread_suspend_state_await_entry_point_offset = 824;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 800;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 820;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 808;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 828;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 812;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 832;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 816;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 836;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 820;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 840;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 824;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 844;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 828;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 848;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        832;
+        852;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 836;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 856;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     16;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 96;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 104;
+    AOT_Thread_unboxed_runtime_arg_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 296;
@@ -11154,16 +11093,16 @@
     AOT_Thread_write_barrier_mask_offset = 32;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    868;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 872;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     888;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 896;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 892;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    912;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 920;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 356;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    904;
+    928;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -11178,12 +11117,8 @@
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     12;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 12;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 16;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    20;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 22;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 23;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 24;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -11210,25 +11145,21 @@
     4;
 static constexpr dart::compiler::target::word
     AOT_NativeFinalizer_callback_offset = 20;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 28;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 24;
+    AOT_FunctionType_named_parameter_names_offset = 28;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 39;
+    AOT_FunctionType_packed_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_parameter_counts_offset = 32;
+    AOT_FunctionType_packed_type_parameter_counts_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_type_parameter_counts_offset = 36;
+    AOT_FunctionType_parameter_types_offset = 24;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 20;
+    AOT_FunctionType_type_parameters_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 12;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 20;
+    AOT_TypeParameter_parameterized_class_id_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    23;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 25;
+    27;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -11246,10 +11177,8 @@
 static constexpr dart::compiler::target::word
     AOT_TypeParameters_defaults_offset = 16;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    16;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 12;
+    20;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 16;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     8;
 static constexpr dart::compiler::target::word
@@ -11276,9 +11205,9 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        768, 772, 776, 780, 784, -1, 788, -1, 792, 796, -1, -1, -1, -1, -1, -1};
+        788, 792, 796, 800, 804, -1, 808, -1, 812, 816, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
 static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 8;
@@ -11313,7 +11242,7 @@
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 44;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    40;
+    44;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 8;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 16;
@@ -11353,6 +11282,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 20;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 28;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -11372,7 +11302,7 @@
     28;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
     20;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 20;
 static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 12;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     12;
@@ -11422,6 +11352,9 @@
     AOT_OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 8;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -11448,8 +11381,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 =
-    10;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -11474,6 +11406,8 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -11505,7 +11439,7 @@
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_SharedClassTable_class_heap_stats_table_offset = 0;
+    AOT_ClassTable_allocation_tracing_state_table_offset = 8;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 24;
@@ -11556,8 +11490,7 @@
     AOT_GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    40;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -11577,11 +11510,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     64;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 40;
+    AOT_IsolateGroup_object_store_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 16;
+    AOT_IsolateGroup_class_table_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 32;
+    AOT_IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
     88;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 40;
@@ -11626,30 +11559,33 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 984;
+    AOT_ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 1048;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 976;
+    AOT_ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 1008;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 992;
+    AOT_ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 1024;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -11683,9 +11619,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1680;
+    AOT_Thread_active_exception_offset = 1720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1688;
+    AOT_Thread_active_stacktrace_offset = 1728;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -11709,7 +11645,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -11724,13 +11660,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1808;
+    1848;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1768;
+    AOT_Thread_double_truncate_round_supported_offset = 1808;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1816;
+    AOT_Thread_service_extension_stream_offset = 1856;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -11747,7 +11683,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1720;
+    AOT_Thread_execution_state_offset = 1760;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -11769,14 +11705,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1696;
+    AOT_Thread_global_object_pool_offset = 1736;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1752;
+    AOT_Thread_exit_through_ffi_offset = 1792;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -11833,11 +11769,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 728;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1704;
+    1744;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1712;
+    AOT_Thread_saved_shadow_call_stack_offset = 1752;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1728;
+    AOT_Thread_safepoint_state_offset = 1768;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -11859,35 +11795,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 1608;
+    AOT_Thread_suspend_state_await_entry_point_offset = 1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 1600;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1640;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 1616;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1656;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1624;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1664;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1632;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1672;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1640;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1648;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1656;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        1664;
+        1704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1672;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 192;
+    AOT_Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 568;
@@ -11895,16 +11829,16 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1736;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1744;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     1776;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1784;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 1784;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    1816;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1824;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 688;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1792;
+    1832;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -11919,12 +11853,8 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    40;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 48;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -11951,25 +11881,21 @@
     8;
 static constexpr dart::compiler::target::word
     AOT_NativeFinalizer_callback_offset = 40;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 48;
+    AOT_FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 71;
+    AOT_FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_parameter_counts_offset = 64;
+    AOT_FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_type_parameter_counts_offset = 68;
+    AOT_FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 40;
+    AOT_FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 24;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 40;
+    AOT_TypeParameter_parameterized_class_id_offset = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    43;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 45;
+    51;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -11987,10 +11913,8 @@
 static constexpr dart::compiler::target::word
     AOT_TypeParameters_defaults_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    32;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    44;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+    40;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -12018,10 +11942,10 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, -1,   -1,   1544, 1552,
-        1560, 1568, 1576, -1,   1584, 1592, -1,   -1};
+        1552, 1560, 1568, 1576, -1,   -1,   1584, 1592,
+        1600, 1608, 1616, -1,   1624, 1632, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
-    24;
+    32;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
 static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
@@ -12056,7 +11980,7 @@
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 80;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    72;
+    80;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 32;
@@ -12096,6 +12020,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -12112,10 +12037,10 @@
     AOT_TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
-    48;
+    56;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
     40;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     24;
@@ -12168,6 +12093,9 @@
     AOT_OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 8;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -12194,8 +12122,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 =
-    10;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -12220,6 +12147,8 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -12251,7 +12180,7 @@
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_SharedClassTable_class_heap_stats_table_offset = 0;
+    AOT_ClassTable_allocation_tracing_state_table_offset = 8;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 24;
@@ -12302,8 +12231,7 @@
     AOT_GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    40;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -12323,11 +12251,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     64;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 40;
+    AOT_IsolateGroup_object_store_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 16;
+    AOT_IsolateGroup_class_table_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 32;
+    AOT_IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
     88;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 40;
@@ -12372,30 +12300,33 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 984;
+    AOT_ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 1048;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 976;
+    AOT_ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 1008;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 992;
+    AOT_ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 1024;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -12429,9 +12360,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1752;
+    AOT_Thread_active_exception_offset = 1792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1760;
+    AOT_Thread_active_stacktrace_offset = 1800;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -12455,7 +12386,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1832;
+    1872;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -12470,13 +12401,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1880;
+    1920;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1840;
+    AOT_Thread_double_truncate_round_supported_offset = 1880;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1888;
+    AOT_Thread_service_extension_stream_offset = 1928;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -12493,7 +12424,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1792;
+    AOT_Thread_execution_state_offset = 1832;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -12515,14 +12446,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1768;
+    AOT_Thread_global_object_pool_offset = 1808;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1824;
+    AOT_Thread_exit_through_ffi_offset = 1864;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1896;
+    1936;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -12579,11 +12510,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 728;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1776;
+    1816;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1784;
+    AOT_Thread_saved_shadow_call_stack_offset = 1824;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1800;
+    AOT_Thread_safepoint_state_offset = 1840;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -12605,35 +12536,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 1680;
+    AOT_Thread_suspend_state_await_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 1672;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 1688;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1696;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1704;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1712;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1720;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1760;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1728;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        1736;
+        1776;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1744;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1784;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 192;
+    AOT_Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 568;
@@ -12641,16 +12570,16 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1808;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1816;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     1848;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1856;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 1856;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    1888;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1896;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 688;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1864;
+    1904;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -12665,12 +12594,8 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    40;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 48;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -12697,25 +12622,21 @@
     8;
 static constexpr dart::compiler::target::word
     AOT_NativeFinalizer_callback_offset = 40;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 48;
+    AOT_FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 71;
+    AOT_FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_parameter_counts_offset = 64;
+    AOT_FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_type_parameter_counts_offset = 68;
+    AOT_FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 40;
+    AOT_FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 24;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 40;
+    AOT_TypeParameter_parameterized_class_id_offset = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    43;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 45;
+    51;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -12733,10 +12654,8 @@
 static constexpr dart::compiler::target::word
     AOT_TypeParameters_defaults_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    32;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    44;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+    40;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -12764,11 +12683,11 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, 1592,
-        1600, 1608, 1616, 1624, -1,   -1,   -1,   -1,   1632, 1640, -1,
-        -1,   1648, 1656, 1664, -1,   -1,   -1,   -1,   -1,   -1};
+        1552, 1560, 1568, 1576, 1584, 1592, 1600, 1608, 1616, 1624, 1632,
+        1640, 1648, 1656, 1664, -1,   -1,   -1,   -1,   1672, 1680, -1,
+        -1,   1688, 1696, 1704, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
-    24;
+    32;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
 static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
@@ -12803,7 +12722,7 @@
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 80;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    72;
+    80;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 32;
@@ -12843,6 +12762,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -12859,10 +12779,10 @@
     AOT_TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
-    48;
+    56;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
     40;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     24;
@@ -12912,6 +12832,9 @@
     AOT_OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 4;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -12938,7 +12861,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -12963,6 +12886,8 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -12994,7 +12919,7 @@
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_SharedClassTable_class_heap_stats_table_offset = 0;
+    AOT_ClassTable_allocation_tracing_state_table_offset = 8;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 16;
@@ -13045,8 +12970,7 @@
     AOT_GrowableObjectArray_length_offset = 12;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    40;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -13066,11 +12990,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     64;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 40;
+    AOT_IsolateGroup_object_store_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 16;
+    AOT_IsolateGroup_class_table_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 32;
+    AOT_IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
     88;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 40;
@@ -13115,30 +13039,33 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 984;
+    AOT_ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 1048;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 976;
+    AOT_ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 1008;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 992;
+    AOT_ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 1024;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset =
+    12;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -13172,9 +13099,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1680;
+    AOT_Thread_active_exception_offset = 1720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1688;
+    AOT_Thread_active_stacktrace_offset = 1728;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -13198,7 +13125,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -13213,13 +13140,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1808;
+    1848;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1768;
+    AOT_Thread_double_truncate_round_supported_offset = 1808;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1816;
+    AOT_Thread_service_extension_stream_offset = 1856;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -13236,7 +13163,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1720;
+    AOT_Thread_execution_state_offset = 1760;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -13258,14 +13185,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1696;
+    AOT_Thread_global_object_pool_offset = 1736;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1752;
+    AOT_Thread_exit_through_ffi_offset = 1792;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -13322,11 +13249,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 728;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1704;
+    1744;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1712;
+    AOT_Thread_saved_shadow_call_stack_offset = 1752;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1728;
+    AOT_Thread_safepoint_state_offset = 1768;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -13348,35 +13275,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 1608;
+    AOT_Thread_suspend_state_await_entry_point_offset = 1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 1600;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1640;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 1616;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1656;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1624;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1664;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1632;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1672;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1640;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1648;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1656;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        1664;
+        1704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1672;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 192;
+    AOT_Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 568;
@@ -13384,16 +13309,16 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1736;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1744;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     1776;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1784;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 1784;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    1816;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1824;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 688;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1792;
+    1832;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -13410,10 +13335,6 @@
     16;
 static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
 static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    32;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 36;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -13444,8 +13365,6 @@
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 51;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 48;
@@ -13458,8 +13377,6 @@
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
     35;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 37;
-static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
     12;
@@ -13477,8 +13394,6 @@
     AOT_TypeParameters_defaults_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
     28;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    36;
 static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     20;
@@ -13507,8 +13422,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, -1,   -1,   1544, 1552,
-        1560, 1568, 1576, -1,   1584, 1592, -1,   -1};
+        1552, 1560, 1568, 1576, -1,   -1,   1584, 1592,
+        1600, 1608, 1616, -1,   1624, 1632, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -13585,6 +13500,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -13599,7 +13515,7 @@
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -13654,6 +13570,9 @@
     AOT_OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 4;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -13680,7 +13599,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -13705,6 +13624,8 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -13736,7 +13657,7 @@
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_SharedClassTable_class_heap_stats_table_offset = 0;
+    AOT_ClassTable_allocation_tracing_state_table_offset = 8;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 16;
@@ -13787,8 +13708,7 @@
     AOT_GrowableObjectArray_length_offset = 12;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    40;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -13808,11 +13728,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     64;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 40;
+    AOT_IsolateGroup_object_store_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 16;
+    AOT_IsolateGroup_class_table_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 32;
+    AOT_IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
     88;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 40;
@@ -13857,30 +13777,33 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 984;
+    AOT_ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 1048;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 976;
+    AOT_ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 1008;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 992;
+    AOT_ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 1024;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset =
+    12;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -13914,9 +13837,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1752;
+    AOT_Thread_active_exception_offset = 1792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1760;
+    AOT_Thread_active_stacktrace_offset = 1800;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -13940,7 +13863,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1832;
+    1872;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -13955,13 +13878,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1880;
+    1920;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1840;
+    AOT_Thread_double_truncate_round_supported_offset = 1880;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1888;
+    AOT_Thread_service_extension_stream_offset = 1928;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -13978,7 +13901,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1792;
+    AOT_Thread_execution_state_offset = 1832;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -14000,14 +13923,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1768;
+    AOT_Thread_global_object_pool_offset = 1808;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1824;
+    AOT_Thread_exit_through_ffi_offset = 1864;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1896;
+    1936;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -14064,11 +13987,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 728;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1776;
+    1816;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1784;
+    AOT_Thread_saved_shadow_call_stack_offset = 1824;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1800;
+    AOT_Thread_safepoint_state_offset = 1840;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -14090,35 +14013,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 1680;
+    AOT_Thread_suspend_state_await_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 1672;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 1688;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1696;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1704;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1712;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1720;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1760;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1728;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        1736;
+        1776;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1744;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1784;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 192;
+    AOT_Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 568;
@@ -14126,16 +14047,16 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1808;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1816;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     1848;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1856;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 1856;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    1888;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1896;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 688;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1864;
+    1904;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -14152,10 +14073,6 @@
     16;
 static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
 static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    32;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 36;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -14186,8 +14103,6 @@
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 51;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 48;
@@ -14200,8 +14115,6 @@
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
     35;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 37;
-static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
     12;
@@ -14219,8 +14132,6 @@
     AOT_TypeParameters_defaults_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
     28;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    36;
 static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     20;
@@ -14249,9 +14160,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, 1592,
-        1600, 1608, 1616, 1624, -1,   -1,   -1,   -1,   1632, 1640, -1,
-        -1,   1648, 1656, 1664, -1,   -1,   -1,   -1,   -1,   -1};
+        1552, 1560, 1568, 1576, 1584, 1592, 1600, 1608, 1616, 1624, 1632,
+        1640, 1648, 1656, 1664, -1,   -1,   -1,   -1,   1672, 1680, -1,
+        -1,   1688, 1696, 1704, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -14328,6 +14239,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -14342,7 +14254,7 @@
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -14397,6 +14309,9 @@
     AOT_OneByteString_elements_start_offset = 12;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 4;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -14423,7 +14338,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 4;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -14448,6 +14363,7 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 4;
 static constexpr dart::compiler::target::word
@@ -14479,7 +14395,7 @@
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 84;
 static constexpr dart::compiler::target::word
-    AOT_SharedClassTable_class_heap_stats_table_offset = 0;
+    AOT_ClassTable_allocation_tracing_state_table_offset = 4;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 12;
@@ -14530,8 +14446,7 @@
     AOT_GrowableObjectArray_length_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 4;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    20;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -14551,11 +14466,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 20;
+    AOT_IsolateGroup_object_store_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 8;
+    AOT_IsolateGroup_class_table_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 16;
+    AOT_IsolateGroup_cached_class_table_table_offset = 12;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
     44;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 20;
@@ -14600,30 +14515,32 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     112;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 492;
+    AOT_ObjectStore_suspend_state_await_offset = 496;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 524;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 488;
+    AOT_ObjectStore_suspend_state_init_async_offset = 492;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 504;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 508;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 516;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 496;
+    AOT_ObjectStore_suspend_state_return_async_offset = 500;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 500;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 512;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 516;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 520;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 524;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 508;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 512;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     12;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 4;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 4;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -14657,9 +14574,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 408;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 880;
+    AOT_Thread_active_exception_offset = 900;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 884;
+    AOT_Thread_active_stacktrace_offset = 904;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 300;
 static constexpr dart::compiler::target::word
@@ -14683,7 +14600,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 208;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    920;
+    940;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 212;
 static constexpr dart::compiler::target::word
@@ -14698,13 +14615,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 140;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    952;
+    976;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 924;
+    AOT_Thread_double_truncate_round_supported_offset = 944;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 956;
+    AOT_Thread_service_extension_stream_offset = 980;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     344;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -14721,7 +14638,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 900;
+    AOT_Thread_execution_state_offset = 920;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 284;
 static constexpr dart::compiler::target::word
@@ -14743,14 +14660,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 404;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 888;
+    AOT_Thread_global_object_pool_offset = 908;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 916;
+    AOT_Thread_exit_through_ffi_offset = 936;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    960;
+    984;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 64;
 static constexpr dart::compiler::target::word
@@ -14806,11 +14723,11 @@
     112;
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 376;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 892;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 912;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 896;
+    AOT_Thread_saved_shadow_call_stack_offset = 916;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 904;
+    AOT_Thread_safepoint_state_offset = 924;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -14832,35 +14749,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 844;
+    AOT_Thread_suspend_state_await_entry_point_offset = 864;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 840;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 860;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 848;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 868;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 852;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 872;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 856;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 876;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 860;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 880;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 864;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 884;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 868;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 888;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        872;
+        892;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 876;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 896;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     16;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 96;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 104;
+    AOT_Thread_unboxed_runtime_arg_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 296;
@@ -14868,16 +14783,16 @@
     AOT_Thread_write_barrier_mask_offset = 32;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    908;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 912;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     928;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 936;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 932;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    952;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 960;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 356;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    944;
+    968;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -14892,12 +14807,8 @@
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     12;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 12;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 16;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    20;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 22;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 23;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 24;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -14924,25 +14835,21 @@
     4;
 static constexpr dart::compiler::target::word
     AOT_NativeFinalizer_callback_offset = 20;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 28;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 24;
+    AOT_FunctionType_named_parameter_names_offset = 28;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 39;
+    AOT_FunctionType_packed_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_parameter_counts_offset = 32;
+    AOT_FunctionType_packed_type_parameter_counts_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_type_parameter_counts_offset = 36;
+    AOT_FunctionType_parameter_types_offset = 24;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 20;
+    AOT_FunctionType_type_parameters_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 12;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 20;
+    AOT_TypeParameter_parameterized_class_id_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    23;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 25;
+    27;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -14960,10 +14867,8 @@
 static constexpr dart::compiler::target::word
     AOT_TypeParameters_defaults_offset = 16;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    16;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 12;
+    20;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 16;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     8;
 static constexpr dart::compiler::target::word
@@ -14990,11 +14895,11 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,  -1,  -1, -1, -1, 768, 772, 776, -1,  -1,  780,
-        784, 788, -1, -1, -1, 792, 796, 800, 804, 808, 812,
-        816, 820, -1, -1, -1, -1,  824, 828, 832, 836};
+        -1,  -1,  -1, -1, -1, 788, 792, 796, -1,  -1,  800,
+        804, 808, -1, -1, -1, 812, 816, 820, 824, 828, 832,
+        836, 840, -1, -1, -1, -1,  844, 848, 852, 856};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
 static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 8;
@@ -15029,7 +14934,7 @@
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 44;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    40;
+    44;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 8;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 16;
@@ -15069,6 +14974,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 20;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 28;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -15088,7 +14994,7 @@
     28;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
     20;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 20;
 static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 12;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     12;
@@ -15138,6 +15044,9 @@
     AOT_OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 8;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -15164,8 +15073,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 =
-    10;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -15190,6 +15098,8 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -15221,7 +15131,7 @@
 static constexpr dart::compiler::target::word
     AOT_Class_host_type_arguments_field_offset_in_words_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_SharedClassTable_class_heap_stats_table_offset = 0;
+    AOT_ClassTable_allocation_tracing_state_table_offset = 8;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 24;
@@ -15272,8 +15182,7 @@
     AOT_GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    40;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -15293,11 +15202,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     64;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 40;
+    AOT_IsolateGroup_object_store_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 16;
+    AOT_IsolateGroup_class_table_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 32;
+    AOT_IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
     88;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 40;
@@ -15342,30 +15251,33 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 984;
+    AOT_ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 1048;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 976;
+    AOT_ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 1008;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 992;
+    AOT_ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 1024;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -15399,9 +15311,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1736;
+    AOT_Thread_active_exception_offset = 1776;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1744;
+    AOT_Thread_active_stacktrace_offset = 1784;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -15425,7 +15337,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1816;
+    1856;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -15440,13 +15352,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1864;
+    1904;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1824;
+    AOT_Thread_double_truncate_round_supported_offset = 1864;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1872;
+    AOT_Thread_service_extension_stream_offset = 1912;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -15463,7 +15375,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1776;
+    AOT_Thread_execution_state_offset = 1816;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -15485,14 +15397,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1752;
+    AOT_Thread_global_object_pool_offset = 1792;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1808;
+    AOT_Thread_exit_through_ffi_offset = 1848;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1880;
+    1920;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -15549,11 +15461,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 728;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1768;
+    AOT_Thread_saved_shadow_call_stack_offset = 1808;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1784;
+    AOT_Thread_safepoint_state_offset = 1824;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -15575,35 +15487,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 1664;
+    AOT_Thread_suspend_state_await_entry_point_offset = 1704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 1656;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 1672;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1680;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1688;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1696;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1704;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1712;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        1720;
+        1760;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1728;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 192;
+    AOT_Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 568;
@@ -15611,16 +15521,16 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1792;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1800;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     1832;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1840;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 1840;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    1872;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1880;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 688;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1848;
+    1888;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -15635,12 +15545,8 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    40;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 48;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -15667,25 +15573,21 @@
     8;
 static constexpr dart::compiler::target::word
     AOT_NativeFinalizer_callback_offset = 40;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 48;
+    AOT_FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 71;
+    AOT_FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_parameter_counts_offset = 64;
+    AOT_FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_type_parameter_counts_offset = 68;
+    AOT_FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 40;
+    AOT_FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 24;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 40;
+    AOT_TypeParameter_parameterized_class_id_offset = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    43;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 45;
+    51;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -15703,10 +15605,8 @@
 static constexpr dart::compiler::target::word
     AOT_TypeParameters_defaults_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    32;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    44;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+    40;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -15734,11 +15634,11 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,   -1,   -1, -1, -1, 1512, 1520, 1528, -1,   -1,   1536,
-        1544, 1552, -1, -1, -1, 1560, 1568, 1576, 1584, 1592, 1600,
-        1608, 1616, -1, -1, -1, -1,   1624, 1632, 1640, 1648};
+        -1,   -1,   -1, -1, -1, 1552, 1560, 1568, -1,   -1,   1576,
+        1584, 1592, -1, -1, -1, 1600, 1608, 1616, 1624, 1632, 1640,
+        1648, 1656, -1, -1, -1, -1,   1664, 1672, 1680, 1688};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
-    24;
+    32;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
 static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
@@ -15773,7 +15673,7 @@
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 80;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    72;
+    80;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 32;
@@ -15813,6 +15713,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -15829,10 +15730,10 @@
     AOT_TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
-    48;
+    56;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
     40;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     24;
@@ -15881,6 +15782,9 @@
     AOT_OneByteString_elements_start_offset = 12;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 4;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -15907,7 +15811,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 4;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -15932,6 +15836,7 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 4;
 static constexpr dart::compiler::target::word
@@ -16012,8 +15917,7 @@
     AOT_GrowableObjectArray_length_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 4;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    20;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -16031,11 +15935,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     28;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 20;
+    AOT_IsolateGroup_object_store_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 8;
+    AOT_IsolateGroup_class_table_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 16;
+    AOT_IsolateGroup_cached_class_table_table_offset = 12;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset =
     12;
@@ -16078,30 +15982,32 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     112;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 492;
+    AOT_ObjectStore_suspend_state_await_offset = 496;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 524;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 488;
+    AOT_ObjectStore_suspend_state_init_async_offset = 492;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 504;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 508;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 516;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 496;
+    AOT_ObjectStore_suspend_state_return_async_offset = 500;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 500;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 512;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 516;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 520;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 524;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 508;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 512;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     12;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 4;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 4;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -16135,9 +16041,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 408;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 840;
+    AOT_Thread_active_exception_offset = 860;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 844;
+    AOT_Thread_active_stacktrace_offset = 864;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 300;
 static constexpr dart::compiler::target::word
@@ -16161,7 +16067,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 208;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    880;
+    900;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 212;
 static constexpr dart::compiler::target::word
@@ -16176,13 +16082,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 140;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    912;
+    936;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 884;
+    AOT_Thread_double_truncate_round_supported_offset = 904;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 916;
+    AOT_Thread_service_extension_stream_offset = 940;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     344;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -16199,7 +16105,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 860;
+    AOT_Thread_execution_state_offset = 880;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 284;
 static constexpr dart::compiler::target::word
@@ -16221,14 +16127,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 404;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 848;
+    AOT_Thread_global_object_pool_offset = 868;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 876;
+    AOT_Thread_exit_through_ffi_offset = 896;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    920;
+    944;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 64;
 static constexpr dart::compiler::target::word
@@ -16284,11 +16190,11 @@
     112;
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 376;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 852;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 872;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 856;
+    AOT_Thread_saved_shadow_call_stack_offset = 876;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 864;
+    AOT_Thread_safepoint_state_offset = 884;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -16310,35 +16216,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 804;
+    AOT_Thread_suspend_state_await_entry_point_offset = 824;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 800;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 820;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 808;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 828;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 812;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 832;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 816;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 836;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 820;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 840;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 824;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 844;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 828;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 848;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        832;
+        852;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 836;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 856;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     16;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 96;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 104;
+    AOT_Thread_unboxed_runtime_arg_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 296;
@@ -16346,16 +16250,16 @@
     AOT_Thread_write_barrier_mask_offset = 32;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    868;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 872;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     888;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 896;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 892;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    912;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 920;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 356;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    904;
+    928;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -16370,12 +16274,8 @@
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     12;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 12;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 16;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    20;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 22;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 23;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 24;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -16402,25 +16302,21 @@
     4;
 static constexpr dart::compiler::target::word
     AOT_NativeFinalizer_callback_offset = 20;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 28;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 24;
+    AOT_FunctionType_named_parameter_names_offset = 28;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 39;
+    AOT_FunctionType_packed_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_parameter_counts_offset = 32;
+    AOT_FunctionType_packed_type_parameter_counts_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_type_parameter_counts_offset = 36;
+    AOT_FunctionType_parameter_types_offset = 24;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 20;
+    AOT_FunctionType_type_parameters_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 12;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 20;
+    AOT_TypeParameter_parameterized_class_id_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    23;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 25;
+    27;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -16438,10 +16334,8 @@
 static constexpr dart::compiler::target::word
     AOT_TypeParameters_defaults_offset = 16;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    16;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 12;
+    20;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 16;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     8;
 static constexpr dart::compiler::target::word
@@ -16468,9 +16362,9 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        768, 772, 776, 780, 784, -1, 788, -1, 792, 796, -1, -1, -1, -1, -1, -1};
+        788, 792, 796, 800, 804, -1, 808, -1, 812, 816, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
 static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 8;
@@ -16505,7 +16399,7 @@
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    40;
+    44;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 8;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 16;
@@ -16545,6 +16439,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 12;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 28;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -16564,7 +16459,7 @@
     28;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
     20;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 20;
 static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 12;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     12;
@@ -16611,6 +16506,9 @@
     AOT_OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 8;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -16637,8 +16535,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 =
-    10;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -16663,6 +16560,8 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -16743,8 +16642,7 @@
     AOT_GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    40;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -16762,11 +16660,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 40;
+    AOT_IsolateGroup_object_store_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 16;
+    AOT_IsolateGroup_class_table_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 32;
+    AOT_IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset =
     24;
@@ -16809,30 +16707,33 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 984;
+    AOT_ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 1048;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 976;
+    AOT_ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 1008;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 992;
+    AOT_ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 1024;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -16866,9 +16767,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1680;
+    AOT_Thread_active_exception_offset = 1720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1688;
+    AOT_Thread_active_stacktrace_offset = 1728;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -16892,7 +16793,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -16907,13 +16808,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1808;
+    1848;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1768;
+    AOT_Thread_double_truncate_round_supported_offset = 1808;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1816;
+    AOT_Thread_service_extension_stream_offset = 1856;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -16930,7 +16831,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1720;
+    AOT_Thread_execution_state_offset = 1760;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -16952,14 +16853,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1696;
+    AOT_Thread_global_object_pool_offset = 1736;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1752;
+    AOT_Thread_exit_through_ffi_offset = 1792;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -17016,11 +16917,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 728;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1704;
+    1744;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1712;
+    AOT_Thread_saved_shadow_call_stack_offset = 1752;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1728;
+    AOT_Thread_safepoint_state_offset = 1768;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -17042,35 +16943,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 1608;
+    AOT_Thread_suspend_state_await_entry_point_offset = 1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 1600;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1640;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 1616;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1656;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1624;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1664;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1632;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1672;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1640;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1648;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1656;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        1664;
+        1704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1672;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 192;
+    AOT_Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 568;
@@ -17078,16 +16977,16 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1736;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1744;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     1776;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1784;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 1784;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    1816;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1824;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 688;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1792;
+    1832;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -17102,12 +17001,8 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    40;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 48;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -17134,25 +17029,21 @@
     8;
 static constexpr dart::compiler::target::word
     AOT_NativeFinalizer_callback_offset = 40;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 48;
+    AOT_FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 71;
+    AOT_FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_parameter_counts_offset = 64;
+    AOT_FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_type_parameter_counts_offset = 68;
+    AOT_FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 40;
+    AOT_FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 24;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 40;
+    AOT_TypeParameter_parameterized_class_id_offset = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    43;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 45;
+    51;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -17170,10 +17061,8 @@
 static constexpr dart::compiler::target::word
     AOT_TypeParameters_defaults_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    32;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    44;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+    40;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -17201,10 +17090,10 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, -1,   -1,   1544, 1552,
-        1560, 1568, 1576, -1,   1584, 1592, -1,   -1};
+        1552, 1560, 1568, 1576, -1,   -1,   1584, 1592,
+        1600, 1608, 1616, -1,   1624, 1632, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
-    24;
+    32;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
 static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
@@ -17239,7 +17128,7 @@
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 80;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    72;
+    80;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 32;
@@ -17279,6 +17168,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -17295,10 +17185,10 @@
     AOT_TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
-    48;
+    56;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
     40;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     24;
@@ -17348,6 +17238,9 @@
     AOT_OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 8;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -17374,8 +17267,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 =
-    10;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -17400,6 +17292,8 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -17480,8 +17374,7 @@
     AOT_GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    40;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -17499,11 +17392,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 40;
+    AOT_IsolateGroup_object_store_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 16;
+    AOT_IsolateGroup_class_table_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 32;
+    AOT_IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset =
     24;
@@ -17546,30 +17439,33 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 984;
+    AOT_ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 1048;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 976;
+    AOT_ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 1008;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 992;
+    AOT_ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 1024;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -17603,9 +17499,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1752;
+    AOT_Thread_active_exception_offset = 1792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1760;
+    AOT_Thread_active_stacktrace_offset = 1800;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -17629,7 +17525,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1832;
+    1872;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -17644,13 +17540,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1880;
+    1920;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1840;
+    AOT_Thread_double_truncate_round_supported_offset = 1880;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1888;
+    AOT_Thread_service_extension_stream_offset = 1928;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -17667,7 +17563,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1792;
+    AOT_Thread_execution_state_offset = 1832;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -17689,14 +17585,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1768;
+    AOT_Thread_global_object_pool_offset = 1808;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1824;
+    AOT_Thread_exit_through_ffi_offset = 1864;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1896;
+    1936;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -17753,11 +17649,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 728;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1776;
+    1816;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1784;
+    AOT_Thread_saved_shadow_call_stack_offset = 1824;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1800;
+    AOT_Thread_safepoint_state_offset = 1840;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -17779,35 +17675,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 1680;
+    AOT_Thread_suspend_state_await_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 1672;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 1688;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1696;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1704;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1712;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1720;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1760;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1728;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        1736;
+        1776;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1744;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1784;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 192;
+    AOT_Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 568;
@@ -17815,16 +17709,16 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1808;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1816;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     1848;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1856;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 1856;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    1888;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1896;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 688;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1864;
+    1904;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -17839,12 +17733,8 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    40;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 48;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -17871,25 +17761,21 @@
     8;
 static constexpr dart::compiler::target::word
     AOT_NativeFinalizer_callback_offset = 40;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 48;
+    AOT_FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 71;
+    AOT_FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_parameter_counts_offset = 64;
+    AOT_FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_type_parameter_counts_offset = 68;
+    AOT_FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 40;
+    AOT_FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 24;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 40;
+    AOT_TypeParameter_parameterized_class_id_offset = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    43;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 45;
+    51;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -17907,10 +17793,8 @@
 static constexpr dart::compiler::target::word
     AOT_TypeParameters_defaults_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    32;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    44;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+    40;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -17938,11 +17822,11 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, 1592,
-        1600, 1608, 1616, 1624, -1,   -1,   -1,   -1,   1632, 1640, -1,
-        -1,   1648, 1656, 1664, -1,   -1,   -1,   -1,   -1,   -1};
+        1552, 1560, 1568, 1576, 1584, 1592, 1600, 1608, 1616, 1624, 1632,
+        1640, 1648, 1656, 1664, -1,   -1,   -1,   -1,   1672, 1680, -1,
+        -1,   1688, 1696, 1704, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
-    24;
+    32;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
 static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
@@ -17977,7 +17861,7 @@
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 80;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    72;
+    80;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 32;
@@ -18017,6 +17901,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -18033,10 +17918,10 @@
     AOT_TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
-    48;
+    56;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
     40;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     24;
@@ -18083,6 +17968,9 @@
     AOT_OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 4;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -18109,7 +17997,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -18134,6 +18022,8 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -18214,8 +18104,7 @@
     AOT_GrowableObjectArray_length_offset = 12;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    40;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -18233,11 +18122,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 40;
+    AOT_IsolateGroup_object_store_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 16;
+    AOT_IsolateGroup_class_table_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 32;
+    AOT_IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset =
     16;
@@ -18280,30 +18169,33 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 984;
+    AOT_ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 1048;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 976;
+    AOT_ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 1008;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 992;
+    AOT_ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 1024;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset =
+    12;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -18337,9 +18229,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1680;
+    AOT_Thread_active_exception_offset = 1720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1688;
+    AOT_Thread_active_stacktrace_offset = 1728;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -18363,7 +18255,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -18378,13 +18270,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1808;
+    1848;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1768;
+    AOT_Thread_double_truncate_round_supported_offset = 1808;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1816;
+    AOT_Thread_service_extension_stream_offset = 1856;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -18401,7 +18293,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1720;
+    AOT_Thread_execution_state_offset = 1760;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -18423,14 +18315,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1696;
+    AOT_Thread_global_object_pool_offset = 1736;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1752;
+    AOT_Thread_exit_through_ffi_offset = 1792;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1824;
+    1864;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -18487,11 +18379,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 728;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1704;
+    1744;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1712;
+    AOT_Thread_saved_shadow_call_stack_offset = 1752;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1728;
+    AOT_Thread_safepoint_state_offset = 1768;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -18513,35 +18405,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 1608;
+    AOT_Thread_suspend_state_await_entry_point_offset = 1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 1600;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1640;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 1616;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1656;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1624;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1664;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1632;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1672;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1640;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1648;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1688;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1656;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        1664;
+        1704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1672;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 192;
+    AOT_Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 568;
@@ -18549,16 +18439,16 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1736;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1744;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     1776;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1784;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 1784;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    1816;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1824;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 688;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1792;
+    1832;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -18575,10 +18465,6 @@
     16;
 static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
 static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    32;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 36;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -18609,8 +18495,6 @@
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 51;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 48;
@@ -18623,8 +18507,6 @@
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
     35;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 37;
-static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
     12;
@@ -18642,8 +18524,6 @@
     AOT_TypeParameters_defaults_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
     28;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    36;
 static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     20;
@@ -18672,8 +18552,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, -1,   -1,   1544, 1552,
-        1560, 1568, 1576, -1,   1584, 1592, -1,   -1};
+        1552, 1560, 1568, 1576, -1,   -1,   1584, 1592,
+        1600, 1608, 1616, -1,   1624, 1632, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -18750,6 +18630,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -18764,7 +18645,7 @@
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -18816,6 +18697,9 @@
     AOT_OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 4;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -18842,7 +18726,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -18867,6 +18751,8 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -18947,8 +18833,7 @@
     AOT_GrowableObjectArray_length_offset = 12;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    40;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -18966,11 +18851,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 40;
+    AOT_IsolateGroup_object_store_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 16;
+    AOT_IsolateGroup_class_table_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 32;
+    AOT_IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset =
     16;
@@ -19013,30 +18898,33 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 984;
+    AOT_ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 1048;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 976;
+    AOT_ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 1008;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 992;
+    AOT_ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 1024;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset =
+    12;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -19070,9 +18958,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1752;
+    AOT_Thread_active_exception_offset = 1792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1760;
+    AOT_Thread_active_stacktrace_offset = 1800;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -19096,7 +18984,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1832;
+    1872;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -19111,13 +18999,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1880;
+    1920;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1840;
+    AOT_Thread_double_truncate_round_supported_offset = 1880;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1888;
+    AOT_Thread_service_extension_stream_offset = 1928;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -19134,7 +19022,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1792;
+    AOT_Thread_execution_state_offset = 1832;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -19156,14 +19044,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1768;
+    AOT_Thread_global_object_pool_offset = 1808;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1824;
+    AOT_Thread_exit_through_ffi_offset = 1864;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1896;
+    1936;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -19220,11 +19108,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 728;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1776;
+    1816;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1784;
+    AOT_Thread_saved_shadow_call_stack_offset = 1824;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1800;
+    AOT_Thread_safepoint_state_offset = 1840;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -19246,35 +19134,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 1680;
+    AOT_Thread_suspend_state_await_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 1672;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 1688;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1696;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1704;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1712;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1720;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1760;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1728;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        1736;
+        1776;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1744;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1784;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 192;
+    AOT_Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 568;
@@ -19282,16 +19168,16 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1808;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1816;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     1848;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1856;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 1856;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    1888;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1896;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 688;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1864;
+    1904;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -19308,10 +19194,6 @@
     16;
 static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
 static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    32;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 36;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -19342,8 +19224,6 @@
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 51;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 48;
@@ -19356,8 +19236,6 @@
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
     35;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 37;
-static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
     12;
@@ -19375,8 +19253,6 @@
     AOT_TypeParameters_defaults_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
     28;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    36;
 static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     20;
@@ -19405,9 +19281,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1512, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, 1592,
-        1600, 1608, 1616, 1624, -1,   -1,   -1,   -1,   1632, 1640, -1,
-        -1,   1648, 1656, 1664, -1,   -1,   -1,   -1,   -1,   -1};
+        1552, 1560, 1568, 1576, 1584, 1592, 1600, 1608, 1616, 1624, 1632,
+        1640, 1648, 1656, 1664, -1,   -1,   -1,   -1,   1672, 1680, -1,
+        -1,   1688, 1696, 1704, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -19484,6 +19360,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -19498,7 +19375,7 @@
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -19550,6 +19427,9 @@
     AOT_OneByteString_elements_start_offset = 12;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 4;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -19576,7 +19456,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 4;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 9;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -19601,6 +19481,7 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     268435455;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 4;
 static constexpr dart::compiler::target::word
@@ -19681,8 +19562,7 @@
     AOT_GrowableObjectArray_length_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 4;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    20;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 8;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -19700,11 +19580,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     28;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 20;
+    AOT_IsolateGroup_object_store_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 8;
+    AOT_IsolateGroup_class_table_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 16;
+    AOT_IsolateGroup_cached_class_table_table_offset = 12;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset =
     12;
@@ -19747,30 +19627,32 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     112;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 492;
+    AOT_ObjectStore_suspend_state_await_offset = 496;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 524;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 528;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 488;
+    AOT_ObjectStore_suspend_state_init_async_offset = 492;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 504;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 508;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 516;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 520;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 496;
+    AOT_ObjectStore_suspend_state_return_async_offset = 500;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 500;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 504;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 512;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 516;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 520;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 524;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 508;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 512;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     12;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 4;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 4;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -19804,9 +19686,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 408;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 880;
+    AOT_Thread_active_exception_offset = 900;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 884;
+    AOT_Thread_active_stacktrace_offset = 904;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 300;
 static constexpr dart::compiler::target::word
@@ -19830,7 +19712,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 208;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    920;
+    940;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 212;
 static constexpr dart::compiler::target::word
@@ -19845,13 +19727,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 140;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    952;
+    976;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 924;
+    AOT_Thread_double_truncate_round_supported_offset = 944;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 956;
+    AOT_Thread_service_extension_stream_offset = 980;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     344;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -19868,7 +19750,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 280;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 900;
+    AOT_Thread_execution_state_offset = 920;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 284;
 static constexpr dart::compiler::target::word
@@ -19890,14 +19772,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 404;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 888;
+    AOT_Thread_global_object_pool_offset = 908;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 916;
+    AOT_Thread_exit_through_ffi_offset = 936;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    960;
+    984;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 64;
 static constexpr dart::compiler::target::word
@@ -19953,11 +19835,11 @@
     112;
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 376;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 892;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 912;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 896;
+    AOT_Thread_saved_shadow_call_stack_offset = 916;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 904;
+    AOT_Thread_safepoint_state_offset = 924;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 272;
 static constexpr dart::compiler::target::word
@@ -19979,35 +19861,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 844;
+    AOT_Thread_suspend_state_await_entry_point_offset = 864;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 840;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 860;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 848;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 868;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 852;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 872;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 856;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 876;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 860;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 880;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 864;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 884;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 868;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 888;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        872;
+        892;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 876;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 896;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     16;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 96;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 104;
+    AOT_Thread_unboxed_runtime_arg_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 296;
@@ -20015,16 +19895,16 @@
     AOT_Thread_write_barrier_mask_offset = 32;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    908;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 912;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     928;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 936;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 932;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    952;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 960;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 356;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    944;
+    968;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -20039,12 +19919,8 @@
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     12;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 12;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 16;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    20;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 22;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 23;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 24;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -20071,25 +19947,21 @@
     4;
 static constexpr dart::compiler::target::word
     AOT_NativeFinalizer_callback_offset = 20;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 28;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 24;
+    AOT_FunctionType_named_parameter_names_offset = 28;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 39;
+    AOT_FunctionType_packed_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_parameter_counts_offset = 32;
+    AOT_FunctionType_packed_type_parameter_counts_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_type_parameter_counts_offset = 36;
+    AOT_FunctionType_parameter_types_offset = 24;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 20;
+    AOT_FunctionType_type_parameters_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 12;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 20;
+    AOT_TypeParameter_parameterized_class_id_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    23;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 25;
+    27;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 4;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -20107,10 +19979,8 @@
 static constexpr dart::compiler::target::word
     AOT_TypeParameters_defaults_offset = 16;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    16;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 12;
+    20;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 16;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     8;
 static constexpr dart::compiler::target::word
@@ -20137,11 +20007,11 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,  -1,  -1, -1, -1, 768, 772, 776, -1,  -1,  780,
-        784, 788, -1, -1, -1, 792, 796, 800, 804, 808, 812,
-        816, 820, -1, -1, -1, -1,  824, 828, 832, 836};
+        -1,  -1,  -1, -1, -1, 788, 792, 796, -1,  -1,  800,
+        804, 808, -1, -1, -1, 812, 816, 820, 824, 828, 832,
+        836, 840, -1, -1, -1, -1,  844, 848, 852, 856};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
-    12;
+    16;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
 static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 8;
@@ -20176,7 +20046,7 @@
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    40;
+    44;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 8;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 16;
@@ -20216,6 +20086,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 8;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 12;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 28;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -20235,7 +20106,7 @@
     28;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
     20;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 20;
 static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 12;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     12;
@@ -20282,6 +20153,9 @@
     AOT_OneByteString_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_element_size =
     1;
+static constexpr dart::compiler::target::word AOT_Record_elements_start_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Record_element_size = 8;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_elements_start_offset = 40;
 static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
@@ -20308,8 +20182,7 @@
     AOT_Instructions_kBarePayloadAlignment = 4;
 static constexpr dart::compiler::target::word
     AOT_Instructions_kNonBarePayloadAlignment = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_kBytesPerCardLog2 =
-    10;
+static constexpr dart::compiler::target::word AOT_Page_kBytesPerCardLog2 = 10;
 static constexpr dart::compiler::target::word
     AOT_NativeEntry_kNumCallWrapperArguments = 2;
 static constexpr dart::compiler::target::word AOT_String_kMaxElements =
@@ -20334,6 +20207,8 @@
     0;
 static constexpr dart::compiler::target::word AOT_TypeArguments_kMaxElements =
     576460752303423487;
+static constexpr dart::compiler::target::word AOT_AbstractType_flags_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_AbstractType_type_test_stub_entry_point_offset = 8;
 static constexpr dart::compiler::target::word
@@ -20414,8 +20289,7 @@
     AOT_GrowableObjectArray_length_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_type_arguments_offset = 8;
-static constexpr dart::compiler::target::word AOT_OldPage_card_table_offset =
-    40;
+static constexpr dart::compiler::target::word AOT_Page_card_table_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_CallSiteData_arguments_descriptor_offset = 16;
 static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
@@ -20433,11 +20307,11 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_object_store_offset = 40;
+    AOT_IsolateGroup_object_store_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_shared_class_table_offset = 16;
+    AOT_IsolateGroup_class_table_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_IsolateGroup_cached_class_table_table_offset = 32;
+    AOT_IsolateGroup_cached_class_table_table_offset = 24;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset =
     24;
@@ -20480,30 +20354,33 @@
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
     224;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_await_offset = 984;
+    AOT_ObjectStore_suspend_state_await_offset = 992;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_handle_exception_offset = 1048;
+    AOT_ObjectStore_suspend_state_handle_exception_offset = 1056;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_offset = 976;
+    AOT_ObjectStore_suspend_state_init_async_offset = 984;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_async_star_offset = 1008;
+    AOT_ObjectStore_suspend_state_init_async_star_offset = 1016;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1032;
+    AOT_ObjectStore_suspend_state_init_sync_star_offset = 1040;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_offset = 992;
+    AOT_ObjectStore_suspend_state_return_async_offset = 1000;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1000;
+    AOT_ObjectStore_suspend_state_return_async_not_future_offset = 1008;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_return_async_star_offset = 1024;
+    AOT_ObjectStore_suspend_state_return_async_star_offset = 1032;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1040;
+    AOT_ObjectStore_suspend_state_suspend_sync_star_at_start_offset = 1048;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1016;
+    AOT_ObjectStore_suspend_state_yield_async_star_offset = 1024;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word AOT_PointerBase_data_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_Pointer_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Record_num_fields_offset = 8;
+static constexpr dart::compiler::target::word AOT_Record_field_names_offset =
+    16;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_entry_point_offset = 16;
 static constexpr dart::compiler::target::word
@@ -20537,9 +20414,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1736;
+    AOT_Thread_active_exception_offset = 1776;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1744;
+    AOT_Thread_active_stacktrace_offset = 1784;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 576;
 static constexpr dart::compiler::target::word
@@ -20563,7 +20440,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 392;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1816;
+    1856;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_exception_handler_stub_offset = 400;
 static constexpr dart::compiler::target::word
@@ -20578,13 +20455,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1864;
+    1904;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1824;
+    AOT_Thread_double_truncate_round_supported_offset = 1864;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1872;
+    AOT_Thread_service_extension_stream_offset = 1912;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     664;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -20601,7 +20478,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 536;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1776;
+    AOT_Thread_execution_state_offset = 1816;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 544;
 static constexpr dart::compiler::target::word
@@ -20623,14 +20500,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 784;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1752;
+    AOT_Thread_global_object_pool_offset = 1792;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1808;
+    AOT_Thread_exit_through_ffi_offset = 1848;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1880;
+    1920;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -20687,11 +20564,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 728;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1760;
+    1800;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1768;
+    AOT_Thread_saved_shadow_call_stack_offset = 1808;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1784;
+    AOT_Thread_safepoint_state_offset = 1824;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 520;
 static constexpr dart::compiler::target::word
@@ -20713,35 +20590,33 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_await_entry_point_offset = 1664;
+    AOT_Thread_suspend_state_await_entry_point_offset = 1704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_entry_point_offset = 1656;
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1696;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_entry_point_offset = 1672;
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1680;
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1688;
+    AOT_Thread_suspend_state_init_async_star_entry_point_offset = 1728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1696;
+    AOT_Thread_suspend_state_yield_async_star_entry_point_offset = 1736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1704;
+    AOT_Thread_suspend_state_return_async_star_entry_point_offset = 1744;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1712;
+    AOT_Thread_suspend_state_init_sync_star_entry_point_offset = 1752;
 static constexpr dart::compiler::target::word
     AOT_Thread_suspend_state_suspend_sync_star_at_start_entry_point_offset =
-        1720;
+        1760;
 static constexpr dart::compiler::target::word
-    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1728;
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1768;
 static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
     32;
 static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_int64_runtime_arg_offset = 184;
-static constexpr dart::compiler::target::word
-    AOT_Thread_unboxed_double_runtime_arg_offset = 192;
+    AOT_Thread_unboxed_runtime_arg_offset = 184;
 static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_entry_point_offset = 568;
@@ -20749,16 +20624,16 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1792;
-static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1800;
-static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
     1832;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1840;
+static constexpr dart::compiler::target::word
+    AOT_Thread_callback_stack_return_offset = 1840;
+static constexpr dart::compiler::target::word AOT_Thread_next_task_id_offset =
+    1872;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1880;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 688;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1848;
+    1888;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -20773,12 +20648,8 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    40;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Finalizer_type_arguments_offset = 48;
 static constexpr dart::compiler::target::word AOT_Finalizer_callback_offset =
@@ -20805,25 +20676,21 @@
     8;
 static constexpr dart::compiler::target::word
     AOT_NativeFinalizer_callback_offset = 40;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 64;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 48;
+    AOT_FunctionType_named_parameter_names_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_nullability_offset = 71;
+    AOT_FunctionType_packed_parameter_counts_offset = 72;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_parameter_counts_offset = 64;
+    AOT_FunctionType_packed_type_parameter_counts_offset = 76;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_type_parameter_counts_offset = 68;
+    AOT_FunctionType_parameter_types_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 40;
+    AOT_FunctionType_type_parameters_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 24;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 40;
+    AOT_TypeParameter_parameterized_class_id_offset = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    43;
-static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 45;
+    51;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -20841,10 +20708,8 @@
 static constexpr dart::compiler::target::word
     AOT_TypeParameters_defaults_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    32;
-static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    44;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+    40;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -20872,11 +20737,11 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,   -1,   -1, -1, -1, 1512, 1520, 1528, -1,   -1,   1536,
-        1544, 1552, -1, -1, -1, 1560, 1568, 1576, 1584, 1592, 1600,
-        1608, 1616, -1, -1, -1, -1,   1624, 1632, 1640, 1648};
+        -1,   -1,   -1, -1, -1, 1552, 1560, 1568, -1,   -1,   1576,
+        1584, 1592, -1, -1, -1, 1600, 1608, 1616, 1624, 1632, 1640,
+        1648, 1656, -1, -1, -1, -1,   1664, 1672, 1680, 1688};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
-    24;
+    32;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
 static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
@@ -20911,7 +20776,7 @@
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 80;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    72;
+    80;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 32;
@@ -20951,6 +20816,7 @@
 static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_RecordType_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
 static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
@@ -20967,10 +20833,10 @@
     AOT_TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
-    48;
+    56;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
     40;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     24;
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index d98cb26..a023962b 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -46,13 +46,14 @@
 #define COMMON_OFFSETS_LIST(FIELD, ARRAY, SIZEOF, ARRAY_SIZEOF,                \
                             PAYLOAD_SIZEOF, RANGE, CONSTANT)                   \
   ARRAY(Array, element_offset)                                                 \
-  NOT_IN_PRODUCT(ARRAY(ClassTable, ClassOffsetFor))                            \
+  NOT_IN_PRODUCT(ARRAY(ClassTable, AllocationTracingStateSlotOffsetFor))       \
   ARRAY(Code, element_offset)                                                  \
   ARRAY(Context, variable_offset)                                              \
   ARRAY(ContextScope, element_offset)                                          \
   ARRAY(ExceptionHandlers, element_offset)                                     \
   ARRAY(ObjectPool, element_offset)                                            \
   ARRAY(OneByteString, element_offset)                                         \
+  ARRAY(Record, field_offset)                                                  \
   ARRAY(TypeArguments, type_at_offset)                                         \
   ARRAY(TwoByteString, element_offset)                                         \
   ARRAY_SIZEOF(Array, InstanceSize, element_offset)                            \
@@ -62,6 +63,7 @@
   ARRAY_SIZEOF(ExceptionHandlers, InstanceSize, element_offset)                \
   ARRAY_SIZEOF(ObjectPool, InstanceSize, element_offset)                       \
   ARRAY_SIZEOF(OneByteString, InstanceSize, element_offset)                    \
+  ARRAY_SIZEOF(Record, InstanceSize, field_offset)                             \
   ARRAY_SIZEOF(TypeArguments, InstanceSize, type_at_offset)                    \
   ARRAY_SIZEOF(TwoByteString, InstanceSize, element_offset)                    \
   CONSTANT(Array, kMaxElements)                                                \
@@ -73,7 +75,7 @@
   CONSTANT(Instructions, kPolymorphicEntryOffsetAOT)                           \
   CONSTANT(Instructions, kBarePayloadAlignment)                                \
   CONSTANT(Instructions, kNonBarePayloadAlignment)                             \
-  CONSTANT(OldPage, kBytesPerCardLog2)                                         \
+  CONSTANT(Page, kBytesPerCardLog2)                                            \
   CONSTANT(NativeEntry, kNumCallWrapperArguments)                              \
   CONSTANT(String, kMaxElements)                                               \
   CONSTANT(SubtypeTestCache, kFunctionTypeArguments)                           \
@@ -86,6 +88,7 @@
   CONSTANT(SubtypeTestCache, kTestEntryLength)                                 \
   CONSTANT(SubtypeTestCache, kTestResult)                                      \
   CONSTANT(TypeArguments, kMaxElements)                                        \
+  FIELD(AbstractType, flags_offset)                                            \
   FIELD(AbstractType, type_test_stub_entry_point_offset)                       \
   FIELD(ArgumentsDescriptor, count_offset)                                     \
   FIELD(ArgumentsDescriptor, size_offset)                                      \
@@ -103,7 +106,7 @@
   FIELD(Class, num_type_arguments_offset)                                      \
   FIELD(Class, super_type_offset)                                              \
   FIELD(Class, host_type_arguments_field_offset_in_words_offset)               \
-  NOT_IN_PRODUCT(FIELD(SharedClassTable, class_heap_stats_table_offset))       \
+  NOT_IN_PRODUCT(FIELD(ClassTable, allocation_tracing_state_table_offset))     \
   FIELD(Closure, context_offset)                                               \
   FIELD(Closure, delayed_type_arguments_offset)                                \
   FIELD(Closure, function_offset)                                              \
@@ -138,7 +141,7 @@
   FIELD(GrowableObjectArray, data_offset)                                      \
   FIELD(GrowableObjectArray, length_offset)                                    \
   FIELD(GrowableObjectArray, type_arguments_offset)                            \
-  FIELD(OldPage, card_table_offset)                                            \
+  FIELD(Page, card_table_offset)                                               \
   FIELD(CallSiteData, arguments_descriptor_offset)                             \
   FIELD(ICData, NumArgsTestedMask)                                             \
   FIELD(ICData, NumArgsTestedShift)                                            \
@@ -152,7 +155,7 @@
   NOT_IN_PRODUCT(FIELD(Isolate, has_resumption_breakpoints_offset))            \
   FIELD(Isolate, ic_miss_code_offset)                                          \
   FIELD(IsolateGroup, object_store_offset)                                     \
-  FIELD(IsolateGroup, shared_class_table_offset)                               \
+  FIELD(IsolateGroup, class_table_offset)                                      \
   FIELD(IsolateGroup, cached_class_table_table_offset)                         \
   NOT_IN_PRODUCT(FIELD(Isolate, single_step_offset))                           \
   FIELD(Isolate, user_tag_offset)                                              \
@@ -190,6 +193,8 @@
   FIELD(OneByteString, data_offset)                                            \
   FIELD(PointerBase, data_offset)                                              \
   FIELD(Pointer, type_arguments_offset)                                        \
+  FIELD(Record, num_fields_offset)                                             \
+  FIELD(Record, field_names_offset)                                            \
   FIELD(SingleTargetCache, entry_point_offset)                                 \
   FIELD(SingleTargetCache, lower_limit_offset)                                 \
   FIELD(SingleTargetCache, target_offset)                                      \
@@ -312,8 +317,7 @@
   FIELD(Thread, top_exit_frame_info_offset)                                    \
   FIELD(Thread, top_offset)                                                    \
   FIELD(Thread, top_resource_offset)                                           \
-  FIELD(Thread, unboxed_int64_runtime_arg_offset)                              \
-  FIELD(Thread, unboxed_double_runtime_arg_offset)                             \
+  FIELD(Thread, unboxed_runtime_arg_offset)                                    \
   FIELD(Thread, vm_tag_offset)                                                 \
   FIELD(Thread, write_barrier_entry_point_offset)                              \
   FIELD(Thread, write_barrier_mask_offset)                                     \
@@ -333,9 +337,6 @@
   FIELD(TwoByteString, data_offset)                                            \
   FIELD(Type, arguments_offset)                                                \
   FIELD(Type, hash_offset)                                                     \
-  FIELD(Type, type_class_id_offset)                                            \
-  FIELD(Type, type_state_offset)                                               \
-  FIELD(Type, nullability_offset)                                              \
   FIELD(Finalizer, type_arguments_offset)                                      \
   FIELD(Finalizer, callback_offset)                                            \
   FIELD(FinalizerBase, all_entries_offset)                                     \
@@ -351,14 +352,12 @@
   FIELD(NativeFinalizer, callback_offset)                                      \
   FIELD(FunctionType, hash_offset)                                             \
   FIELD(FunctionType, named_parameter_names_offset)                            \
-  FIELD(FunctionType, nullability_offset)                                      \
   FIELD(FunctionType, packed_parameter_counts_offset)                          \
   FIELD(FunctionType, packed_type_parameter_counts_offset)                     \
   FIELD(FunctionType, parameter_types_offset)                                  \
   FIELD(FunctionType, type_parameters_offset)                                  \
   FIELD(TypeParameter, parameterized_class_id_offset)                          \
   FIELD(TypeParameter, index_offset)                                           \
-  FIELD(TypeParameter, nullability_offset)                                     \
   FIELD(TypeArguments, instantiations_offset)                                  \
   FIELD(TypeArguments, length_offset)                                          \
   FIELD(TypeArguments, nullability_offset)                                     \
@@ -368,7 +367,6 @@
   FIELD(TypeParameters, bounds_offset)                                         \
   FIELD(TypeParameters, defaults_offset)                                       \
   FIELD(TypeParameter, bound_offset)                                           \
-  FIELD(TypeParameter, flags_offset)                                           \
   FIELD(TypeRef, type_offset)                                                  \
   FIELD(TypedDataBase, length_offset)                                          \
   FIELD(TypedDataView, typed_data_offset)                                      \
@@ -446,6 +444,7 @@
   SIZEOF(PcDescriptors, HeaderSize, UntaggedPcDescriptors)                     \
   SIZEOF(Pointer, InstanceSize, UntaggedPointer)                               \
   SIZEOF(ReceivePort, InstanceSize, UntaggedReceivePort)                       \
+  SIZEOF(RecordType, InstanceSize, UntaggedRecordType)                         \
   SIZEOF(RegExp, InstanceSize, UntaggedRegExp)                                 \
   SIZEOF(Script, InstanceSize, UntaggedScript)                                 \
   SIZEOF(SendPort, InstanceSize, UntaggedSendPort)                             \
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index a4c1c5e..992bd37 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -312,49 +312,27 @@
   __ LoadClassId(InstantiateTypeABI::kScratchReg,
                  InstantiateTypeABI::kResultTypeReg);
 
-  // The loaded value from the TAV can be [Type], [FunctionType] or [TypeRef].
+  // Handle/unwrap TypeRefs in runtime.
+  __ CompareImmediate(InstantiateTypeABI::kScratchReg, kTypeRefCid);
+  __ BranchIf(EQUAL, &runtime_call);
 
-  // Handle [Type]s.
-  __ CompareImmediate(InstantiateTypeABI::kScratchReg, kTypeCid);
-  __ BranchIf(NOT_EQUAL, &type_parameter_value_is_not_type);
   switch (nullability) {
     case Nullability::kNonNullable:
       __ Ret();
       break;
     case Nullability::kNullable:
-      __ CompareTypeNullabilityWith(
+      __ CompareAbstractTypeNullabilityWith(
           InstantiateTypeABI::kResultTypeReg,
-          static_cast<int8_t>(Nullability::kNullable));
+          static_cast<int8_t>(Nullability::kNullable),
+          InstantiateTypeABI::kScratchReg);
       __ BranchIf(NOT_EQUAL, &runtime_call);
       __ Ret();
       break;
     case Nullability::kLegacy:
-      __ CompareTypeNullabilityWith(
+      __ CompareAbstractTypeNullabilityWith(
           InstantiateTypeABI::kResultTypeReg,
-          static_cast<int8_t>(Nullability::kNonNullable));
-      __ BranchIf(EQUAL, &runtime_call);
-      __ Ret();
-  }
-
-  // Handle [FunctionType]s.
-  __ Bind(&type_parameter_value_is_not_type);
-  __ CompareImmediate(InstantiateTypeABI::kScratchReg, kFunctionTypeCid);
-  __ BranchIf(NOT_EQUAL, &runtime_call);
-  switch (nullability) {
-    case Nullability::kNonNullable:
-      __ Ret();
-      break;
-    case Nullability::kNullable:
-      __ CompareFunctionTypeNullabilityWith(
-          InstantiateTypeABI::kResultTypeReg,
-          static_cast<int8_t>(Nullability::kNullable));
-      __ BranchIf(NOT_EQUAL, &runtime_call);
-      __ Ret();
-      break;
-    case Nullability::kLegacy:
-      __ CompareFunctionTypeNullabilityWith(
-          InstantiateTypeABI::kResultTypeReg,
-          static_cast<int8_t>(Nullability::kNonNullable));
+          static_cast<int8_t>(Nullability::kNonNullable),
+          InstantiateTypeABI::kScratchReg);
       __ BranchIf(EQUAL, &runtime_call);
       __ Ret();
   }
@@ -519,8 +497,9 @@
   __ BranchIf(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
   if (null_safety) {
     // Instance type isn't a top type if non-nullable in null safe mode.
-    __ CompareTypeNullabilityWith(
-        scratch1_reg, static_cast<int8_t>(Nullability::kNonNullable));
+    __ CompareAbstractTypeNullabilityWith(
+        scratch1_reg, static_cast<int8_t>(Nullability::kNonNullable),
+        scratch2_reg);
     __ BranchIf(EQUAL, &done, compiler::Assembler::kNearJump);
   }
   __ Bind(&is_top_type);
@@ -618,8 +597,9 @@
     compiler::Label is_not_type;
     __ CompareClassId(kCurrentTypeReg, kTypeCid, kScratchReg);
     __ BranchIf(NOT_EQUAL, &is_not_type, compiler::Assembler::kNearJump);
-    __ CompareTypeNullabilityWith(
-        kCurrentTypeReg, static_cast<int8_t>(Nullability::kNonNullable));
+    __ CompareAbstractTypeNullabilityWith(
+        kCurrentTypeReg, static_cast<int8_t>(Nullability::kNonNullable),
+        kScratchReg);
     __ BranchIf(NOT_EQUAL, &is_assignable);
     // FutureOr is a special case because it may have the non-nullable bit set,
     // but FutureOr<T> functions as the union of T and Future<T>, so it must be
@@ -643,11 +623,9 @@
     __ Bind(&is_not_type);
     // Null is assignable to a type parameter only if it is nullable or if the
     // instantiation is nullable.
-    __ LoadFieldFromOffset(
-        kScratchReg, kCurrentTypeReg,
-        compiler::target::TypeParameter::nullability_offset(), kByte);
-    __ CompareImmediate(kScratchReg,
-                        static_cast<int8_t>(Nullability::kNonNullable));
+    __ CompareAbstractTypeNullabilityWith(
+        kCurrentTypeReg, static_cast<int8_t>(Nullability::kNonNullable),
+        kScratchReg);
     __ BranchIf(NOT_EQUAL, &is_assignable);
 
     // Don't set kScratchReg in here as on IA32, that's the function TAV reg.
@@ -869,7 +847,7 @@
   __ CompareObject(TypeTestABI::kSubtypeTestCacheReg, NullObject());
   __ BranchIf(EQUAL, &call_runtime, Assembler::kNearJump);
 
-  // If this is not a [Type] object, we'll go to the runtime.
+  // If this is not a [Type] object, we'll use wider SubtypeTestCache.
   Label is_simple_case, is_complex_case;
   __ LoadClassId(TypeTestABI::kScratchReg, TypeTestABI::kDstTypeReg);
   __ CompareImmediate(TypeTestABI::kScratchReg, kTypeCid);
@@ -877,10 +855,15 @@
 
   // Check whether this [Type] is instantiated/uninstantiated.
   __ LoadFieldFromOffset(TypeTestABI::kScratchReg, TypeTestABI::kDstTypeReg,
-                         target::Type::type_state_offset(), kByte);
+                         target::AbstractType::flags_offset(), kByte);
+  __ AndImmediate(
+      TypeTestABI::kScratchReg,
+      Utils::NBitMask<int32_t>(target::UntaggedAbstractType::kTypeStateBits)
+          << target::UntaggedAbstractType::kTypeStateShift);
   __ CompareImmediate(
       TypeTestABI::kScratchReg,
-      target::UntaggedAbstractType::kTypeStateFinalizedInstantiated);
+      target::UntaggedAbstractType::kTypeStateFinalizedInstantiated
+          << target::UntaggedAbstractType::kTypeStateShift);
   __ BranchIf(NOT_EQUAL, &is_complex_case, Assembler::kNearJump);
 
   // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
@@ -1061,6 +1044,118 @@
 #endif  // defined(TARGET_ARCH_IA32)
 }
 
+void StubCodeCompiler::GenerateAllocateRecordStub(Assembler* assembler) {
+  const Register result_reg = AllocateRecordABI::kResultReg;
+  const Register num_fields_reg = AllocateRecordABI::kNumFieldsReg;
+  const Register field_names_reg = AllocateRecordABI::kFieldNamesReg;
+  const Register temp_reg = AllocateRecordABI::kTemp1Reg;
+  const Register new_top_reg = AllocateRecordABI::kTemp2Reg;
+  Label slow_case;
+
+  // Check for allocation tracing.
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kRecordCid, &slow_case, temp_reg));
+
+  // Compute the rounded instance size.
+  const intptr_t fixed_size_plus_alignment_padding =
+      (target::Record::field_offset(0) +
+       target::ObjectAlignment::kObjectAlignment - 1);
+  __ AddScaled(temp_reg, num_fields_reg, TIMES_COMPRESSED_WORD_SIZE,
+               fixed_size_plus_alignment_padding);
+  __ AndImmediate(temp_reg, -target::ObjectAlignment::kObjectAlignment);
+
+  // Now allocate the object.
+  __ LoadFromOffset(result_reg, Address(THR, target::Thread::top_offset()));
+  __ MoveRegister(new_top_reg, temp_reg);
+  __ AddRegisters(new_top_reg, result_reg);
+  // Check if the allocation fits into the remaining space.
+  __ CompareWithMemoryValue(new_top_reg,
+                            Address(THR, target::Thread::end_offset()));
+  __ BranchIf(UNSIGNED_GREATER_EQUAL, &slow_case);
+
+  // Successfully allocated the object, now update top to point to
+  // next object start and initialize the object.
+  __ StoreToOffset(new_top_reg, Address(THR, target::Thread::top_offset()));
+  __ AddImmediate(result_reg, kHeapObjectTag);
+
+  // Calculate the size tag.
+  {
+    Label size_tag_overflow, done;
+    __ CompareImmediate(temp_reg, target::UntaggedObject::kSizeTagMaxSizeTag);
+    __ BranchIf(UNSIGNED_GREATER, &size_tag_overflow, Assembler::kNearJump);
+    __ LslImmediate(temp_reg,
+                    target::UntaggedObject::kTagBitsSizeTagPos -
+                        target::ObjectAlignment::kObjectAlignmentLog2);
+    __ Jump(&done, Assembler::kNearJump);
+
+    __ Bind(&size_tag_overflow);
+    // Set overflow size tag value.
+    __ LoadImmediate(temp_reg, 0);
+
+    __ Bind(&done);
+    uword tags = target::MakeTagWordForNewSpaceObject(kRecordCid, 0);
+    __ OrImmediate(temp_reg, tags);
+    __ StoreToOffset(
+        temp_reg,
+        FieldAddress(result_reg, target::Object::tags_offset()));  // Tags.
+  }
+
+  __ StoreToOffset(
+      num_fields_reg,
+      FieldAddress(result_reg, target::Record::num_fields_offset()),
+      kFourBytes);
+
+  __ StoreCompressedIntoObjectNoBarrier(
+      result_reg,
+      FieldAddress(result_reg, target::Record::field_names_offset()),
+      field_names_reg);
+
+  // Initialize the remaining words of the object.
+  {
+    const Register field_reg = field_names_reg;
+#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_RISCV32) ||              \
+    defined(TARGET_ARCH_RISCV64)
+    const Register null_reg = NULL_REG;
+#else
+    const Register null_reg = temp_reg;
+    __ LoadObject(null_reg, NullObject());
+#endif
+
+    Label loop, done;
+    __ AddImmediate(field_reg, result_reg, target::Record::field_offset(0));
+    __ CompareRegisters(field_reg, new_top_reg);
+    __ BranchIf(UNSIGNED_GREATER_EQUAL, &done, Assembler::kNearJump);
+
+    __ Bind(&loop);
+    for (intptr_t offset = 0; offset < target::kObjectAlignment;
+         offset += target::kCompressedWordSize) {
+      __ StoreCompressedIntoObjectNoBarrier(
+          result_reg, FieldAddress(field_reg, offset), null_reg);
+    }
+    // Safe to only check every kObjectAlignment bytes instead of each word.
+    ASSERT(kAllocationRedZoneSize >= target::kObjectAlignment);
+    __ AddImmediate(field_reg, target::kObjectAlignment);
+    __ CompareRegisters(field_reg, new_top_reg);
+    __ BranchIf(UNSIGNED_LESS, &loop, Assembler::kNearJump);
+    __ Bind(&done);
+  }
+
+  __ Ret();
+
+  __ Bind(&slow_case);
+
+  __ EnterStubFrame();
+  __ PushObject(NullObject());  // Space on the stack for the return value.
+  __ SmiTag(num_fields_reg);
+  __ PushRegistersInOrder({num_fields_reg, field_names_reg});
+  __ CallRuntime(kAllocateRecordRuntimeEntry, 2);
+  __ Drop(2);
+  __ PopRegister(AllocateRecordABI::kResultReg);
+
+  EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
 // The UnhandledException class lives in the VM isolate, so it cannot cache
 // an allocation stub for itself. Instead, we cache it in the stub code list.
 void StubCodeCompiler::GenerateAllocateUnhandledExceptionStub(
@@ -1244,13 +1339,17 @@
 
 #undef EMIT_BOX_ALLOCATION
 
-void StubCodeCompiler::GenerateBoxDoubleStub(Assembler* assembler) {
+static void GenerateBoxFpuValueStub(Assembler* assembler,
+                                    const dart::Class& cls,
+                                    const RuntimeEntry& runtime_entry,
+                                    void (Assembler::*store_value)(FpuRegister,
+                                                                   Register,
+                                                                   int32_t)) {
   Label call_runtime;
   if (!FLAG_use_slow_path && FLAG_inline_alloc) {
-    __ TryAllocate(compiler::DoubleClass(), &call_runtime,
-                   compiler::Assembler::kFarJump, BoxDoubleStubABI::kResultReg,
-                   BoxDoubleStubABI::kTempReg);
-    __ StoreUnboxedDouble(
+    __ TryAllocate(cls, &call_runtime, compiler::Assembler::kFarJump,
+                   BoxDoubleStubABI::kResultReg, BoxDoubleStubABI::kTempReg);
+    (assembler->*store_value)(
         BoxDoubleStubABI::kValueReg, BoxDoubleStubABI::kResultReg,
         compiler::target::Double::value_offset() - kHeapObjectTag);
     __ Ret();
@@ -1258,18 +1357,44 @@
   __ Bind(&call_runtime);
   __ EnterStubFrame();
   __ PushObject(NullObject()); /* Make room for result. */
-  __ StoreUnboxedDouble(BoxDoubleStubABI::kValueReg, THR,
-                        target::Thread::unboxed_double_runtime_arg_offset());
-  __ CallRuntime(kBoxDoubleRuntimeEntry, 0);
+  (assembler->*store_value)(BoxDoubleStubABI::kValueReg, THR,
+                            target::Thread::unboxed_runtime_arg_offset());
+  __ CallRuntime(runtime_entry, 0);
   __ PopRegister(BoxDoubleStubABI::kResultReg);
   __ LeaveStubFrame();
   __ Ret();
 }
 
+void StubCodeCompiler::GenerateBoxDoubleStub(Assembler* assembler) {
+  GenerateBoxFpuValueStub(assembler, compiler::DoubleClass(),
+                          kBoxDoubleRuntimeEntry,
+                          &Assembler::StoreUnboxedDouble);
+}
+
+void StubCodeCompiler::GenerateBoxFloat32x4Stub(Assembler* assembler) {
+#if !defined(TARGET_ARCH_RISCV32) && !defined(TARGET_ARCH_RISCV64)
+  GenerateBoxFpuValueStub(assembler, compiler::Float32x4Class(),
+                          kBoxFloat32x4RuntimeEntry,
+                          &Assembler::StoreUnboxedSimd128);
+#else
+  __ Stop("Not supported on RISC-V.");
+#endif
+}
+
+void StubCodeCompiler::GenerateBoxFloat64x2Stub(Assembler* assembler) {
+#if !defined(TARGET_ARCH_RISCV32) && !defined(TARGET_ARCH_RISCV64)
+  GenerateBoxFpuValueStub(assembler, compiler::Float64x2Class(),
+                          kBoxFloat64x2RuntimeEntry,
+                          &Assembler::StoreUnboxedSimd128);
+#else
+  __ Stop("Not supported on RISC-V.");
+#endif
+}
+
 void StubCodeCompiler::GenerateDoubleToIntegerStub(Assembler* assembler) {
   __ EnterStubFrame();
   __ StoreUnboxedDouble(DoubleToIntegerStubABI::kInputReg, THR,
-                        target::Thread::unboxed_double_runtime_arg_offset());
+                        target::Thread::unboxed_runtime_arg_offset());
   __ PushObject(NullObject()); /* Make room for result. */
   __ PushRegister(DoubleToIntegerStubABI::kRecognizedKindReg);
   __ CallRuntime(kDoubleToIntegerRuntimeEntry, 1);
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index e50effc..7e26f2c 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -1719,20 +1719,20 @@
 
     // Get card table.
     __ Bind(&remember_card);
-    __ AndImmediate(TMP, R1, target::kOldPageMask);  // OldPage.
+    __ AndImmediate(TMP, R1, target::kPageMask);  // Page.
     __ ldr(TMP,
-           Address(TMP, target::OldPage::card_table_offset()));  // Card table.
+           Address(TMP, target::Page::card_table_offset()));  // Card table.
     __ cmp(TMP, Operand(0));
     __ b(&remember_card_slow, EQ);
 
     // Dirty the card.
-    __ AndImmediate(TMP, R1, target::kOldPageMask);  // OldPage.
+    __ AndImmediate(TMP, R1, target::kPageMask);     // Page.
     __ sub(R9, R9, Operand(TMP));                    // Offset in page.
     __ ldr(TMP,
-           Address(TMP, target::OldPage::card_table_offset()));  // Card table.
+           Address(TMP, target::Page::card_table_offset()));  // Card table.
     __ add(TMP, TMP,
            Operand(R9, LSR,
-                   target::OldPage::kBytesPerCardLog2));  // Card address.
+                   target::Page::kBytesPerCardLog2));  // Card address.
     __ strb(R1,
             Address(TMP, 0));  // Low byte of R0 is non-zero from object tag.
     __ Ret();
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 12f53ac..1658a12 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -1807,10 +1807,8 @@
     Label slow_case;
 
     // Load num. variable (int32) in the existing context.
-    __ ldr(
-        R1,
-        FieldAddress(R5, target::Context::num_variables_offset(), kFourBytes),
-        kFourBytes);
+    __ ldr(R1, FieldAddress(R5, target::Context::num_variables_offset()),
+           kFourBytes);
 
     GenerateAllocateContextSpaceStub(assembler, &slow_case);
 
@@ -2026,19 +2024,19 @@
 
     // Get card table.
     __ Bind(&remember_card);
-    __ AndImmediate(TMP, R1, target::kOldPageMask);  // OldPage.
+    __ AndImmediate(TMP, R1, target::kPageMask);  // Page.
     __ ldr(TMP,
-           Address(TMP, target::OldPage::card_table_offset()));  // Card table.
+           Address(TMP, target::Page::card_table_offset()));  // Card table.
     __ cbz(&remember_card_slow, TMP);
 
     // Dirty the card.
-    __ AndImmediate(TMP, R1, target::kOldPageMask);  // OldPage.
+    __ AndImmediate(TMP, R1, target::kPageMask);     // Page.
     __ sub(R25, R25, Operand(TMP));                  // Offset in page.
     __ ldr(TMP,
-           Address(TMP, target::OldPage::card_table_offset()));  // Card table.
+           Address(TMP, target::Page::card_table_offset()));  // Card table.
     __ add(TMP, TMP,
            Operand(R25, LSR,
-                   target::OldPage::kBytesPerCardLog2));  // Card address.
+                   target::Page::kBytesPerCardLog2));  // Card address.
     __ str(R1, Address(TMP, 0),
            kUnsignedByte);  // Low byte of R1 is non-zero from object tag.
     __ ret();
@@ -3055,31 +3053,26 @@
   // Closure handling.
   {
     __ Comment("Closure");
-    __ LoadCompressed(
-        STCInternalRegs::kInstanceCidOrSignatureReg,
-        FieldAddress(TypeTestABI::kInstanceReg,
-                     target::Closure::function_offset(), kObjectBytes));
-    __ LoadCompressed(
-        STCInternalRegs::kInstanceCidOrSignatureReg,
-        FieldAddress(STCInternalRegs::kInstanceCidOrSignatureReg,
-                     target::Function::signature_offset(), kObjectBytes));
+    __ LoadCompressed(STCInternalRegs::kInstanceCidOrSignatureReg,
+                      FieldAddress(TypeTestABI::kInstanceReg,
+                                   target::Closure::function_offset()));
+    __ LoadCompressed(STCInternalRegs::kInstanceCidOrSignatureReg,
+                      FieldAddress(STCInternalRegs::kInstanceCidOrSignatureReg,
+                                   target::Function::signature_offset()));
     if (n >= 3) {
       __ LoadCompressed(
           STCInternalRegs::kInstanceInstantiatorTypeArgumentsReg,
           FieldAddress(TypeTestABI::kInstanceReg,
-                       target::Closure::instantiator_type_arguments_offset(),
-                       kObjectBytes));
+                       target::Closure::instantiator_type_arguments_offset()));
       if (n >= 7) {
         __ LoadCompressed(
             STCInternalRegs::kInstanceParentFunctionTypeArgumentsReg,
             FieldAddress(TypeTestABI::kInstanceReg,
-                         target::Closure::function_type_arguments_offset(),
-                         kObjectBytes));
+                         target::Closure::function_type_arguments_offset()));
         __ LoadCompressed(
             STCInternalRegs::kInstanceDelayedFunctionTypeArgumentsReg,
             FieldAddress(TypeTestABI::kInstanceReg,
-                         target::Closure::delayed_type_arguments_offset(),
-                         kObjectBytes));
+                         target::Closure::delayed_type_arguments_offset()));
       }
     }
     __ b(&loop);
@@ -3103,7 +3096,7 @@
       __ add(kScratchReg, TypeTestABI::kInstanceReg,
              Operand(kScratchReg, LSL, kCompressedWordSizeLog2));
       __ LoadCompressed(STCInternalRegs::kInstanceInstantiatorTypeArgumentsReg,
-                        FieldAddress(kScratchReg, 0, kObjectBytes));
+                        FieldAddress(kScratchReg, 0));
       __ Bind(&has_no_type_arguments);
       __ Comment("No type arguments");
 
@@ -3126,8 +3119,7 @@
       kScratchReg,
       Address(kCacheArrayReg,
               target::kCompressedWordSize *
-                  target::SubtypeTestCache::kInstanceCidOrSignature,
-              Address::Offset, kObjectBytes));
+                  target::SubtypeTestCache::kInstanceCidOrSignature));
   __ CompareObjectRegisters(kScratchReg, kNullReg);
   __ b(&done, EQ);
   __ CompareObjectRegisters(kScratchReg,
@@ -3139,16 +3131,14 @@
     __ LoadCompressed(kScratchReg,
                       Address(kCacheArrayReg,
                               target::kCompressedWordSize *
-                                  target::SubtypeTestCache::kDestinationType,
-                              Address::Offset, kObjectBytes));
+                                  target::SubtypeTestCache::kDestinationType));
     __ cmp(kScratchReg, Operand(TypeTestABI::kDstTypeReg));
     __ b(&next_iteration, NE);
     __ LoadCompressed(
         kScratchReg,
         Address(kCacheArrayReg,
                 target::kCompressedWordSize *
-                    target::SubtypeTestCache::kInstanceTypeArguments,
-                Address::Offset, kObjectBytes));
+                    target::SubtypeTestCache::kInstanceTypeArguments));
     __ cmp(kScratchReg,
            Operand(STCInternalRegs::kInstanceInstantiatorTypeArgumentsReg));
     if (n == 3) {
@@ -3159,16 +3149,14 @@
           kScratchReg,
           Address(kCacheArrayReg,
                   target::kCompressedWordSize *
-                      target::SubtypeTestCache::kInstantiatorTypeArguments,
-                  Address::Offset, kObjectBytes));
+                      target::SubtypeTestCache::kInstantiatorTypeArguments));
       __ cmp(kScratchReg, Operand(TypeTestABI::kInstantiatorTypeArgumentsReg));
       __ b(&next_iteration, NE);
       __ LoadCompressed(
           kScratchReg,
           Address(kCacheArrayReg,
                   target::kCompressedWordSize *
-                      target::SubtypeTestCache::kFunctionTypeArguments,
-                  Address::Offset, kObjectBytes));
+                      target::SubtypeTestCache::kFunctionTypeArguments));
       __ cmp(kScratchReg, Operand(TypeTestABI::kFunctionTypeArgumentsReg));
       if (n == 5) {
         __ b(&found, EQ);
@@ -3176,23 +3164,22 @@
         ASSERT(n == 7);
         __ b(&next_iteration, NE);
 
-        __ LoadCompressed(kScratchReg,
-                          Address(kCacheArrayReg,
-                                  target::kCompressedWordSize *
-                                      target::SubtypeTestCache::
-                                          kInstanceParentFunctionTypeArguments,
-                                  Address::Offset, kObjectBytes));
+        __ LoadCompressed(
+            kScratchReg, Address(kCacheArrayReg,
+                                 target::kCompressedWordSize *
+                                     target::SubtypeTestCache::
+                                         kInstanceParentFunctionTypeArguments));
         __ cmp(
             kScratchReg,
             Operand(STCInternalRegs::kInstanceParentFunctionTypeArgumentsReg));
         __ b(&next_iteration, NE);
 
-        __ LoadCompressed(kScratchReg,
-                          Address(kCacheArrayReg,
-                                  target::kCompressedWordSize *
-                                      target::SubtypeTestCache::
-                                          kInstanceDelayedFunctionTypeArguments,
-                                  Address::Offset, kObjectBytes));
+        __ LoadCompressed(
+            kScratchReg,
+            Address(kCacheArrayReg,
+                    target::kCompressedWordSize *
+                        target::SubtypeTestCache::
+                            kInstanceDelayedFunctionTypeArguments));
         __ cmp(
             kScratchReg,
             Operand(STCInternalRegs::kInstanceDelayedFunctionTypeArgumentsReg));
@@ -3209,11 +3196,10 @@
 
   __ Bind(&found);
   __ Comment("Found");
-  __ LoadCompressed(TypeTestABI::kSubtypeTestCacheResultReg,
-                    Address(kCacheArrayReg,
-                            target::kCompressedWordSize *
-                                target::SubtypeTestCache::kTestResult,
-                            Address::Offset, kObjectBytes));
+  __ LoadCompressed(
+      TypeTestABI::kSubtypeTestCacheResultReg,
+      Address(kCacheArrayReg, target::kCompressedWordSize *
+                                  target::SubtypeTestCache::kTestResult));
   __ Bind(&done);
   __ Comment("Done");
   __ ret();
@@ -3512,9 +3498,8 @@
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
-  __ LoadCompressed(
-      FUNCTION_REG,
-      FieldAddress(TMP, base + target::kCompressedWordSize, kObjectBytes));
+  __ LoadCompressed(FUNCTION_REG,
+                    FieldAddress(TMP, base + target::kCompressedWordSize));
   __ ldr(R1,
          FieldAddress(FUNCTION_REG, target::Function::entry_point_offset()));
   __ ldr(ARGS_DESC_REG,
@@ -3577,14 +3562,12 @@
   if (FLAG_precompiled_mode) {
     const intptr_t entry_offset =
         target::ICData::EntryPointIndexFor(1) * target::kCompressedWordSize;
-    __ LoadCompressed(R1,
-                      Address(R8, entry_offset, Address::Offset, kObjectBytes));
+    __ LoadCompressed(R1, Address(R8, entry_offset));
     __ ldr(R1, FieldAddress(R1, target::Function::entry_point_offset()));
   } else {
     const intptr_t code_offset =
         target::ICData::CodeIndexFor(1) * target::kCompressedWordSize;
-    __ LoadCompressed(CODE_REG,
-                      Address(R8, code_offset, Address::Offset, kObjectBytes));
+    __ LoadCompressed(CODE_REG, Address(R8, code_offset));
     __ ldr(R1, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
   }
   __ br(R1);
@@ -3657,13 +3640,9 @@
 void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
   Label miss;
   __ LoadClassIdMayBeSmi(R1, R0);
-  __ ldr(R2,
-         FieldAddress(R5, target::SingleTargetCache::lower_limit_offset(),
-                      kTwoBytes),
+  __ ldr(R2, FieldAddress(R5, target::SingleTargetCache::lower_limit_offset()),
          kUnsignedTwoBytes);
-  __ ldr(R3,
-         FieldAddress(R5, target::SingleTargetCache::upper_limit_offset(),
-                      kTwoBytes),
+  __ ldr(R3, FieldAddress(R5, target::SingleTargetCache::upper_limit_offset()),
          kUnsignedTwoBytes);
 
   __ cmp(R1, Operand(R2));
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index d1ffea3..cb0b674 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -1454,17 +1454,17 @@
     // Get card table.
     __ Bind(&remember_card);
     __ movl(EAX, EDX);                              // Object.
-    __ andl(EAX, Immediate(target::kOldPageMask));  // OldPage.
-    __ cmpl(Address(EAX, target::OldPage::card_table_offset()), Immediate(0));
+    __ andl(EAX, Immediate(target::kPageMask));     // Page.
+    __ cmpl(Address(EAX, target::Page::card_table_offset()), Immediate(0));
     __ j(EQUAL, &remember_card_slow, Assembler::kNearJump);
 
     // Dirty the card.
     __ subl(EDI, EAX);  // Offset in page.
     __ movl(EAX,
-            Address(EAX, target::OldPage::card_table_offset()));  // Card table.
+            Address(EAX, target::Page::card_table_offset()));  // Card table.
     __ shrl(
         EDI,
-        Immediate(target::OldPage::kBytesPerCardLog2));  // Index in card table.
+        Immediate(target::Page::kBytesPerCardLog2));  // Index in card table.
     __ movb(Address(EAX, EDI, TIMES_1, 0), Immediate(1));
     __ popl(ECX);
     __ popl(EAX);
diff --git a/runtime/vm/compiler/stub_code_compiler_riscv.cc b/runtime/vm/compiler/stub_code_compiler_riscv.cc
index d281e7b..57add7e 100644
--- a/runtime/vm/compiler/stub_code_compiler_riscv.cc
+++ b/runtime/vm/compiler/stub_code_compiler_riscv.cc
@@ -1842,17 +1842,15 @@
 
     // Get card table.
     __ Bind(&remember_card);
-    __ AndImmediate(TMP, A0, target::kOldPageMask);  // OldPage.
-    __ lx(TMP,
-          Address(TMP, target::OldPage::card_table_offset()));  // Card table.
+    __ AndImmediate(TMP, A0, target::kPageMask);                  // Page.
+    __ lx(TMP, Address(TMP, target::Page::card_table_offset()));  // Card table.
     __ beqz(TMP, &remember_card_slow);
 
     // Dirty the card.
-    __ AndImmediate(TMP, A0, target::kOldPageMask);  // OldPage.
+    __ AndImmediate(TMP, A0, target::kPageMask);     // Page.
     __ sub(A6, A6, TMP);                             // Offset in page.
-    __ lx(TMP,
-          Address(TMP, target::OldPage::card_table_offset()));  // Card table.
-    __ srli(A6, A6, target::OldPage::kBytesPerCardLog2);
+    __ lx(TMP, Address(TMP, target::Page::card_table_offset()));  // Card table.
+    __ srli(A6, A6, target::Page::kBytesPerCardLog2);
     __ add(TMP, TMP, A6);        // Card address.
     __ sb(A0, Address(TMP, 0));  // Low byte of A0 is non-zero from object tag.
     __ ret();
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 26dba7f..c2cb5e1 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -1928,17 +1928,17 @@
     // Get card table.
     __ Bind(&remember_card);
     __ movq(TMP, RDX);                              // Object.
-    __ andq(TMP, Immediate(target::kOldPageMask));  // OldPage.
-    __ cmpq(Address(TMP, target::OldPage::card_table_offset()), Immediate(0));
+    __ andq(TMP, Immediate(target::kPageMask));     // Page.
+    __ cmpq(Address(TMP, target::Page::card_table_offset()), Immediate(0));
     __ j(EQUAL, &remember_card_slow, Assembler::kNearJump);
 
     // Dirty the card.
     __ subq(R13, TMP);  // Offset in page.
     __ movq(TMP,
-            Address(TMP, target::OldPage::card_table_offset()));  // Card table.
+            Address(TMP, target::Page::card_table_offset()));  // Card table.
     __ shrq(
         R13,
-        Immediate(target::OldPage::kBytesPerCardLog2));  // Index in card table.
+        Immediate(target::Page::kBytesPerCardLog2));  // Index in card table.
     __ movb(Address(TMP, R13, TIMES_1, 0), Immediate(1));
     __ ret();
 
diff --git a/runtime/vm/compiler/write_barrier_elimination.cc b/runtime/vm/compiler/write_barrier_elimination.cc
index 89fcb74..5b8d6b8 100644
--- a/runtime/vm/compiler/write_barrier_elimination.cc
+++ b/runtime/vm/compiler/write_barrier_elimination.cc
@@ -359,8 +359,8 @@
 
   switch (slot.kind()) {
     case Slot::Kind::kCapturedVariable:  // Context
-      return true;
-    case Slot::Kind::kDartField:  // Instance
+    case Slot::Kind::kDartField:         // Instance
+    case Slot::Kind::kRecordField:       // Instance
       return true;
 
 #define FOR_EACH_NATIVE_SLOT(class, underlying_type, field, __, ___)           \
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 77ff089..7a28be8 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -514,6 +514,15 @@
   static const Register kTypeArgumentsReg = R1;
 };
 
+// ABI for AllocateRecordStub.
+struct AllocateRecordABI {
+  static const Register kResultReg = AllocateObjectABI::kResultReg;
+  static const Register kNumFieldsReg = R2;
+  static const Register kFieldNamesReg = R1;
+  static const Register kTemp1Reg = R3;
+  static const Register kTemp2Reg = R4;
+};
+
 // ABI for AllocateTypedDataArrayStub.
 struct AllocateTypedDataArrayABI {
   static const Register kResultReg = AllocateObjectABI::kResultReg;
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index e3cbcbc..766aca1 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -348,6 +348,15 @@
   static const Register kTypeArgumentsReg = R1;
 };
 
+// ABI for AllocateRecordStub.
+struct AllocateRecordABI {
+  static const Register kResultReg = AllocateObjectABI::kResultReg;
+  static const Register kNumFieldsReg = R2;
+  static const Register kFieldNamesReg = R1;
+  static const Register kTemp1Reg = R3;
+  static const Register kTemp2Reg = R4;
+};
+
 // ABI for AllocateTypedDataArrayStub.
 struct AllocateTypedDataArrayABI {
   static const Register kResultReg = AllocateObjectABI::kResultReg;
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index b3a0259..3da47f9 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -243,6 +243,15 @@
   static const Register kTypeArgumentsReg = ECX;
 };
 
+// ABI for AllocateRecordStub.
+struct AllocateRecordABI {
+  static const Register kResultReg = AllocateObjectABI::kResultReg;
+  static const Register kNumFieldsReg = EDX;
+  static const Register kFieldNamesReg = ECX;
+  static const Register kTemp1Reg = EBX;
+  static const Register kTemp2Reg = EDI;
+};
+
 // ABI for AllocateTypedDataArrayStub.
 struct AllocateTypedDataArrayABI {
   static const Register kResultReg = AllocateObjectABI::kResultReg;
diff --git a/runtime/vm/constants_riscv.h b/runtime/vm/constants_riscv.h
index 070f495..01604b8 100644
--- a/runtime/vm/constants_riscv.h
+++ b/runtime/vm/constants_riscv.h
@@ -357,6 +357,15 @@
   static constexpr Register kTypeArgumentsReg = T1;
 };
 
+// ABI for AllocateRecordStub.
+struct AllocateRecordABI {
+  static const Register kResultReg = AllocateObjectABI::kResultReg;
+  static const Register kNumFieldsReg = T2;
+  static const Register kFieldNamesReg = T1;
+  static const Register kTemp1Reg = T3;
+  static const Register kTemp2Reg = T4;
+};
+
 // ABI for AllocateTypedDataArrayStub.
 struct AllocateTypedDataArrayABI {
   static constexpr Register kResultReg = AllocateObjectABI::kResultReg;
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 531e21f..1111d60 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -319,6 +319,15 @@
   static const Register kTypeArgumentsReg = RBX;
 };
 
+// ABI for AllocateRecordStub.
+struct AllocateRecordABI {
+  static const Register kResultReg = AllocateObjectABI::kResultReg;
+  static const Register kNumFieldsReg = R10;
+  static const Register kFieldNamesReg = RBX;
+  static const Register kTemp1Reg = RDX;
+  static const Register kTemp2Reg = RCX;
+};
+
 // ABI for AllocateTypedDataArrayStub.
 struct AllocateTypedDataArrayABI {
   static const Register kResultReg = AllocateObjectABI::kResultReg;
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 672c042..a0e900a8 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -93,48 +93,45 @@
   DISALLOW_COPY_AND_ASSIGN(ReadOnlyHandles);
 };
 
-class DartInitializationState {
+class DartInitializationState : public AllStatic {
  public:
-  uint8_t kUnInitialized = 0;
-  uint8_t kInitializing = 1;
-  uint8_t kInitialized = 2;
-  uint8_t kCleaningup = 3;
-
-  DartInitializationState() : state_(0), in_use_count_(0) {}
-  ~DartInitializationState() {}
-
-  bool SetInitializing() {
+  static bool SetInitializing() {
     ASSERT(in_use_count_.load() == 0);
-    return state_.compare_exchange_strong(kUnInitialized, kInitializing);
+    uint8_t expected = kUnInitialized;
+    return state_.compare_exchange_strong(expected, kInitializing);
   }
 
-  void ResetInitializing() {
+  static void ResetInitializing() {
     ASSERT(in_use_count_.load() == 0);
-    bool result = state_.compare_exchange_strong(kInitializing, kUnInitialized);
+    uint8_t expected = kInitializing;
+    bool result = state_.compare_exchange_strong(expected, kUnInitialized);
     ASSERT(result);
   }
 
-  void SetInitialized() {
+  static void SetInitialized() {
     ASSERT(in_use_count_.load() == 0);
-    bool result = state_.compare_exchange_strong(kInitializing, kInitialized);
+    uint8_t expected = kInitializing;
+    bool result = state_.compare_exchange_strong(expected, kInitialized);
     ASSERT(result);
   }
 
-  bool IsInitialized() const { return state_.load() == kInitialized; }
+  static bool IsInitialized() { return state_.load() == kInitialized; }
 
-  bool SetCleaningup() {
-    return state_.compare_exchange_strong(kInitialized, kCleaningup);
+  static bool SetCleaningup() {
+    uint8_t expected = kInitialized;
+    return state_.compare_exchange_strong(expected, kCleaningup);
   }
 
-  void SetUnInitialized() {
+  static void SetUnInitialized() {
     while (in_use_count_.load() > 0) {
       OS::Sleep(1);  // Sleep for 1 millis waiting for it to not be in use.
     }
-    bool result = state_.compare_exchange_strong(kCleaningup, kUnInitialized);
+    uint8_t expected = kCleaningup;
+    bool result = state_.compare_exchange_strong(expected, kUnInitialized);
     ASSERT(result);
   }
 
-  bool SetInUse() {
+  static bool SetInUse() {
     if (state_.load() != kInitialized) {
       return false;
     }
@@ -142,17 +139,23 @@
     return true;
   }
 
-  void ResetInUse() {
+  static void ResetInUse() {
     uint8_t value = state_.load();
     ASSERT((value == kInitialized) || (value == kCleaningup));
     in_use_count_ -= 1;
   }
 
  private:
-  std::atomic<uint8_t> state_;
-  std::atomic<uint64_t> in_use_count_;
+  static constexpr uint8_t kUnInitialized = 0;
+  static constexpr uint8_t kInitializing = 1;
+  static constexpr uint8_t kInitialized = 2;
+  static constexpr uint8_t kCleaningup = 3;
+
+  static std::atomic<uint8_t> state_;
+  static std::atomic<uint64_t> in_use_count_;
 };
-static DartInitializationState init_state_;
+std::atomic<uint8_t> DartInitializationState::state_ = {kUnInitialized};
+std::atomic<uint64_t> DartInitializationState::in_use_count_ = {0};
 
 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
 static void CheckOffsets() {
@@ -323,7 +326,7 @@
   Api::Init();
   NativeSymbolResolver::Init();
   NOT_IN_PRODUCT(Profiler::Init());
-  SemiSpace::Init();
+  Page::Init();
   NOT_IN_PRODUCT(Metric::Init());
   StoreBuffer::Init();
   MarkingStack::Init();
@@ -518,7 +521,7 @@
 }
 
 char* Dart::Init(const Dart_InitializeParams* params) {
-  if (!init_state_.SetInitializing()) {
+  if (!DartInitializationState::SetInitializing()) {
     return Utils::StrDup(
         "Bad VM initialization state, "
         "already initialized or "
@@ -526,10 +529,10 @@
   }
   char* retval = DartInit(params);
   if (retval != NULL) {
-    init_state_.ResetInitializing();
+    DartInitializationState::ResetInitializing();
     return retval;
   }
-  init_state_.SetInitialized();
+  DartInitializationState::SetInitialized();
   return NULL;
 }
 
@@ -622,7 +625,7 @@
 
 char* Dart::Cleanup() {
   ASSERT(Isolate::Current() == NULL);
-  if (!init_state_.SetCleaningup()) {
+  if (!DartInitializationState::SetCleaningup()) {
     return Utils::StrDup("VM already terminated.");
   }
   ASSERT(vm_isolate_ != NULL);
@@ -714,7 +717,7 @@
     OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting thread pool\n",
                  UptimeMillis());
   }
-  init_state_.SetUnInitialized();
+  DartInitializationState::SetUnInitialized();
   thread_pool_->Shutdown();
   delete thread_pool_;
   thread_pool_ = NULL;
@@ -770,7 +773,7 @@
   MarkingStack::Cleanup();
   StoreBuffer::Cleanup();
   Object::Cleanup();
-  SemiSpace::Cleanup();
+  Page::Cleanup();
   StubCode::Cleanup();
 #if defined(SUPPORT_TIMELINE)
   if (FLAG_trace_shutdown) {
@@ -812,15 +815,15 @@
 }
 
 bool Dart::IsInitialized() {
-  return init_state_.IsInitialized();
+  return DartInitializationState::IsInitialized();
 }
 
 bool Dart::SetActiveApiCall() {
-  return init_state_.SetInUse();
+  return DartInitializationState::SetInUse();
 }
 
 void Dart::ResetActiveApiCall() {
-  init_state_.ResetInUse();
+  DartInitializationState::ResetInUse();
 }
 
 Isolate* Dart::CreateIsolate(const char* name_prefix,
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 6efa997..600f3f0 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1036,7 +1036,9 @@
       FinalizablePersistentHandle::New(thread->isolate_group(), ref, peer,
                                        callback, external_allocation_size,
                                        /*auto_delete=*/false);
-  return finalizable_ref->ApiWeakPersistentHandle();
+  return finalizable_ref == nullptr
+             ? nullptr
+             : finalizable_ref->ApiWeakPersistentHandle();
 }
 
 static Dart_WeakPersistentHandle AllocateWeakPersistentHandle(
@@ -1070,7 +1072,8 @@
       FinalizablePersistentHandle::New(thread->isolate_group(), ref, peer,
                                        callback, external_allocation_size,
                                        /*auto_delete=*/true);
-  return finalizable_ref->ApiFinalizableHandle();
+  return finalizable_ref == nullptr ? nullptr
+                                    : finalizable_ref->ApiFinalizableHandle();
 }
 
 static Dart_FinalizableHandle AllocateFinalizableHandle(
@@ -1817,7 +1820,7 @@
 
 DART_EXPORT void Dart_NotifyLowMemory() {
   API_TIMELINE_BEGIN_END(Thread::Current());
-  SemiSpace::ClearCache();
+  Page::ClearCache();
   Zone::ClearCache();
 
   // For each isolate's global variables, we might also clear:
@@ -6421,6 +6424,13 @@
 #endif
 }
 
+DART_EXPORT void Dart_SetTimelineRecorderCallback(
+    Dart_TimelineRecorderCallback callback) {
+#if defined(SUPPORT_TIMELINE)
+  Timeline::set_callback(callback);
+#endif
+}
+
 DART_EXPORT void Dart_SetThreadName(const char* name) {
   OSThread* thread = OSThread::Current();
   if (thread == NULL) {
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 0ba1eb1..945e53a 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -8385,7 +8385,7 @@
   EXPECT_EQ(Dart_TypedData_kUint8, message->value.as_typed_data.type);
   EXPECT_EQ(10, message->value.as_typed_data.length);
   EXPECT_EQ(42, message->value.as_typed_data.values[0]);
-  free(message->value.as_typed_data.values);
+  free(const_cast<uint8_t*>(message->value.as_typed_data.values));
 }
 
 static void NewNativePort_Transferrable2(Dart_Port dest_port_id,
@@ -8399,7 +8399,7 @@
   EXPECT_EQ(Dart_TypedData_kUint8, cobj->value.as_typed_data.type);
   EXPECT_EQ(10, cobj->value.as_typed_data.length);
   EXPECT_EQ(42, cobj->value.as_typed_data.values[0]);
-  free(cobj->value.as_typed_data.values);
+  free(const_cast<uint8_t*>(cobj->value.as_typed_data.values));
 }
 
 TEST_CASE(DartAPI_NativePortPostTransferrableTypedData) {
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index f3f9775..21529e7 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -6,13 +6,13 @@
 #define RUNTIME_VM_DART_API_STATE_H_
 
 #include "include/dart_api.h"
-
 #include "platform/utils.h"
 #include "vm/bitfield.h"
 #include "vm/dart_api_impl.h"
 #include "vm/flags.h"
 #include "vm/growable_array.h"
 #include "vm/handles.h"
+#include "vm/handles_impl.h"
 #include "vm/heap/weak_table.h"
 #include "vm/object.h"
 #include "vm/os.h"
@@ -21,8 +21,6 @@
 #include "vm/thread_pool.h"
 #include "vm/visitor.h"
 
-#include "vm/handles_impl.h"
-
 namespace dart {
 
 // Implementation of Zone support for very fast allocation of small chunks
@@ -223,14 +221,19 @@
     return ExternalSizeInWordsBits::decode(external_data_) * kWordSize;
   }
 
-  void SetExternalSize(intptr_t size, IsolateGroup* isolate_group) {
-    ASSERT(size >= 0);
+  bool SetExternalSize(intptr_t size, IsolateGroup* isolate_group) {
+    // This method only behaves correctly when external_size() has not been
+    // previously modified.
+    ASSERT(external_size() == 0);
+    if (size < 0 || (size >> kWordSizeLog2) > kMaxAddrSpaceInWords) {
+      return false;
+    }
     set_external_size(size);
     if (SpaceForExternal() == Heap::kNew) {
       SetExternalNewSpaceBit();
     }
-    isolate_group->heap()->AllocatedExternal(external_size(),
-                                             SpaceForExternal());
+    return isolate_group->heap()->AllocatedExternal(external_size(),
+                                                    SpaceForExternal());
   }
   void UpdateExternalSize(intptr_t size, IsolateGroup* isolate_group) {
     ASSERT(size >= 0);
@@ -803,14 +806,17 @@
     intptr_t external_size,
     bool auto_delete) {
   ApiState* state = isolate_group->api_state();
-  ASSERT(state != NULL);
+  ASSERT(state != nullptr);
   FinalizablePersistentHandle* ref = state->AllocateWeakPersistentHandle();
   ref->set_ptr(object);
   ref->set_peer(peer);
   ref->set_callback(callback);
   ref->set_auto_delete(auto_delete);
   // This may trigger GC, so it must be called last.
-  ref->SetExternalSize(external_size, isolate_group);
+  if (!(ref->SetExternalSize(external_size, isolate_group))) {
+    state->FreeWeakPersistentHandle(ref);
+    return nullptr;
+  }
   return ref;
 }
 
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 818a051..1f55ec8 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1640,7 +1640,7 @@
   // before deoptimizing the world.
   SafepointWriteRwLocker ml(thread, isolate_group->program_lock());
   for (intptr_t i = 1; i < num_classes + num_tlc_classes; i++) {
-    const classid_t cid =
+    const intptr_t cid =
         i < num_classes ? i : ClassTable::CidFromTopLevelIndex(i - num_classes);
     if (class_table.HasValidClassAt(cid)) {
       cls = class_table.At(cid);
@@ -2536,7 +2536,7 @@
     const intptr_t num_classes = class_table.NumCids();
     const intptr_t num_tlc_classes = class_table.NumTopLevelCids();
     for (intptr_t i = 1; i < num_classes + num_tlc_classes; i++) {
-      const classid_t cid =
+      const intptr_t cid =
           i < num_classes ? i
                           : ClassTable::CidFromTopLevelIndex(i - num_classes);
       if (class_table.HasValidClassAt(cid)) {
@@ -2659,7 +2659,7 @@
     const intptr_t num_classes = class_table.NumCids();
     const intptr_t num_tlc_classes = class_table.NumTopLevelCids();
     for (intptr_t i = 1; i < num_classes + num_tlc_classes; i++) {
-      const classid_t cid =
+      const intptr_t cid =
           i < num_classes ? i
                           : ClassTable::CidFromTopLevelIndex(i - num_classes);
       if (!class_table.HasValidClassAt(cid)) {
diff --git a/runtime/vm/dispatch_table.cc b/runtime/vm/dispatch_table.cc
index 7aa3eca..8ec4661 100644
--- a/runtime/vm/dispatch_table.cc
+++ b/runtime/vm/dispatch_table.cc
@@ -8,54 +8,8 @@
 
 namespace dart {
 
-intptr_t DispatchTable::OriginElement() {
-#if defined(TARGET_ARCH_X64)
-  // Max negative byte offset / 8
-  return 16;
-#elif defined(TARGET_ARCH_ARM)
-  // Max negative load offset / 4
-  return 1023;
-#elif defined(TARGET_ARCH_ARM64)
-  // Max consecutive sub immediate value
-  return 4096;
-#elif defined(TARGET_ARCH_RISCV32)
-  // Max consecutive sub immediate value
-  return 2048 / 4;
-#elif defined(TARGET_ARCH_RISCV64)
-  // Max consecutive sub immediate value
-  return 2048 / 8;
-#else
-  // No AOT on IA32
-  UNREACHABLE();
-  return 0;
-#endif
-}
-
-intptr_t DispatchTable::LargestSmallOffset() {
-#if defined(TARGET_ARCH_X64)
-  // Origin + Max positive byte offset / 8
-  return 31;
-#elif defined(TARGET_ARCH_ARM)
-  // Origin + Max positive load offset / 4
-  return 2046;
-#elif defined(TARGET_ARCH_ARM64)
-  // Origin + Max consecutive add immediate value
-  return 8192;
-#elif defined(TARGET_ARCH_RISCV32)
-  // Origin + Max consecutive add immediate value
-  return 4096 / 4;
-#elif defined(TARGET_ARCH_RISCV64)
-  // Origin + Max consecutive add immediate value
-  return 4096 / 8;
-#else
-  // No AOT on IA32
-  UNREACHABLE();
-  return 0;
-#endif
-}
-
 const uword* DispatchTable::ArrayOrigin() const {
-  return &array_.get()[OriginElement()];
+  return &array_.get()[kOriginElement];
 }
 
 }  // namespace dart
diff --git a/runtime/vm/dispatch_table.h b/runtime/vm/dispatch_table.h
index 8d02cdf..6ba4369 100644
--- a/runtime/vm/dispatch_table.h
+++ b/runtime/vm/dispatch_table.h
@@ -20,8 +20,45 @@
 
   // The element of the dispatch table array to which the dispatch table
   // register points.
-  static intptr_t OriginElement();
-  static intptr_t LargestSmallOffset();
+#if defined(TARGET_ARCH_X64)
+  // Max negative byte offset / 8
+  static constexpr intptr_t kOriginElement = 16;
+#elif defined(TARGET_ARCH_ARM)
+  // Max negative load offset / 4
+  static constexpr intptr_t kOriginElement = 1023;
+#elif defined(TARGET_ARCH_ARM64)
+  // Max consecutive sub immediate value
+  static constexpr intptr_t kOriginElement = 4096;
+#elif defined(TARGET_ARCH_RISCV32)
+  // Max consecutive sub immediate value
+  static constexpr intptr_t kOriginElement = 2048 / 4;
+#elif defined(TARGET_ARCH_RISCV64)
+  // Max consecutive sub immediate value
+  static constexpr intptr_t kOriginElement = 2048 / 8;
+#else
+  static constexpr intptr_t kOriginElement = 0;
+#endif
+
+#if defined(TARGET_ARCH_X64)
+  // Origin + Max positive byte offset / 8
+  static constexpr intptr_t kLargestSmallOffset = 31;
+#elif defined(TARGET_ARCH_ARM)
+  // Origin + Max positive load offset / 4
+  static constexpr intptr_t kLargestSmallOffset = 2046;
+#elif defined(TARGET_ARCH_ARM64)
+  // Origin + Max consecutive add immediate value
+  static constexpr intptr_t kLargestSmallOffset = 8192;
+#elif defined(TARGET_ARCH_RISCV32)
+  // Origin + Max consecutive add immediate value
+  static constexpr intptr_t kLargestSmallOffset = 4096 / 4;
+#elif defined(TARGET_ARCH_RISCV64)
+  // Origin + Max consecutive add immediate value
+  static constexpr intptr_t kLargestSmallOffset = 4096 / 8;
+#else
+  // No AOT on IA32
+  static constexpr intptr_t kLargestSmallOffset = 0;
+#endif
+
   // Dispatch table array pointer to put into the dispatch table register.
   const uword* ArrayOrigin() const;
 
diff --git a/runtime/vm/dwarf.cc b/runtime/vm/dwarf.cc
index 25c5792..5cf3c16 100644
--- a/runtime/vm/dwarf.cc
+++ b/runtime/vm/dwarf.cc
@@ -551,11 +551,11 @@
   // Associates the given file, line, and column information for the instruction
   // at the pc_offset into the instructions payload of the Code object with the
   // symbol asm_name. Returns whether any changes were made to the stream.
-  bool AddRow(intptr_t file,
-              intptr_t line,
-              intptr_t column,
-              const char* asm_name,
-              intptr_t pc_offset) {
+  DART_WARN_UNUSED_RESULT bool AddRow(intptr_t file,
+                                      intptr_t line,
+                                      intptr_t column,
+                                      const char* asm_name,
+                                      intptr_t pc_offset) {
     ASSERT_EQUAL(end_sequence_, false);
     bool source_info_changed = false;
     // Note that files are 1-indexed.
@@ -675,8 +675,8 @@
     auto& comments = code.comments();
     for (intptr_t i = 0, len = comments.Length(); i < len;) {
       intptr_t current_pc_offset = comments.PCOffsetAt(i);
-      writer->AddRow(comments_file_index, current_line,
-                     DwarfPosition::kNoColumn, asm_name, current_pc_offset);
+      writer->EmitRow(comments_file_index, current_line,
+                      DwarfPosition::kNoColumn, asm_name, current_pc_offset);
       while (i < len && current_pc_offset == comments.PCOffsetAt(i)) {
         comments_buffer.AddString(comments.CommentAt(i));
         comments_buffer.AddChar('\n');
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index fa58e02..60be32a 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -88,6 +88,8 @@
   DISASSEMBLE_FLAGS(P, R, C, D)                                                \
   P(abort_on_oom, bool, false,                                                 \
     "Abort if memory allocation fails - use only with --old-gen-heap-size")    \
+  P(add_readonly_data_symbols, bool, false,                                    \
+    "Add static symbols for objects in snapshot read-only data")               \
   C(async_debugger, false, false, bool, true,                                  \
     "Debugger support async functions.")                                       \
   P(background_compilation, bool, kDartUseBackgroundCompilation,               \
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index ac91f20..80b830e 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -44,7 +44,11 @@
 typedef uintptr_t compressed_uword;
 typedef intptr_t compressed_word;
 #endif
-const int kMaxAddrSpaceMB = (kWordSize <= 4) ? 4096 : kMaxInt;
+// 32-bit: 2^32 addresses => kMaxAddrSpaceMB = 2^(32 - MBLog2) = 2^12 MB
+// 64-bit: 2^48 addresses => kMaxAddrSpaceMB = 2^(48 - MBLog2) = 2^28 MB
+const intptr_t kMaxAddrSpaceMB = (kWordSize <= 4) ? 4096 : 268435456;
+const intptr_t kMaxAddrSpaceInWords = kMaxAddrSpaceMB >> kWordSizeLog2
+                                                             << MBLog2;
 
 // Number of bytes per BigInt digit.
 const intptr_t kBytesPerBigIntDigit = 4;
@@ -52,7 +56,7 @@
 // The default old gen heap size in MB, where 0 -- unlimited.
 // 32-bit: OS limit is 2 or 3 GB
 // 64-bit: Linux's limit is
-//   sysctl vm.max_map_count (default 2^16) * 512 KB OldPages = 32 GB
+//   sysctl vm.max_map_count (default 2^16) * 512 KB Pages = 32 GB
 // Set the VM limit below the OS limit to increase the likelihood of failing
 // gracefully with a Dart OutOfMemory exception instead of SIGABORT.
 const intptr_t kDefaultMaxOldGenHeapSize = (kWordSize <= 4) ? 1536 : 30720;
@@ -109,8 +113,9 @@
 #define NOT_IN_PRECOMPILED_RUNTIME(code) code
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-#if !defined(PRODUCT) || defined(DART_HOST_OS_FUCHSIA) ||                      \
-    defined(DART_TARGET_OS_FUCHSIA) || defined(DART_TARGET_OS_ANDROID)
+#if defined(DART_ENABLE_TIMELINE) || !defined(PRODUCT) ||                      \
+    defined(DART_HOST_OS_FUCHSIA) || defined(DART_TARGET_OS_FUCHSIA) ||        \
+    defined(DART_TARGET_OS_ANDROID)
 #define SUPPORT_TIMELINE 1
 #endif
 
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index 9afb2d7..7a3ca54 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -19,11 +19,11 @@
             false,
             "Force compaction to move every movable object");
 
-// Each OldPage is divided into blocks of size kBlockSize. Each object belongs
+// Each Page is divided into blocks of size kBlockSize. Each object belongs
 // to the block containing its header word (so up to kBlockSize +
 // kAllocatablePageSize - 2 * kObjectAlignment bytes belong to the same block).
 // During compaction, all live objects in the same block will slide such that
-// they all end up on the same OldPage, and all gaps within the block will be
+// they all end up on the same Page, and all gaps within the block will be
 // closed. During sliding, a bitvector is computed that indictates which
 // allocation units are live, so the new address of any object in the block can
 // be found by adding the number of live allocation units before the object to
@@ -95,7 +95,7 @@
   uword Lookup(uword old_addr) { return BlockFor(old_addr)->Lookup(old_addr); }
 
   ForwardingBlock* BlockFor(uword old_addr) {
-    intptr_t page_offset = old_addr & ~kOldPageMask;
+    intptr_t page_offset = old_addr & ~kPageMask;
     intptr_t block_number = page_offset / kBlockSize;
     ASSERT(block_number >= 0);
     ASSERT(block_number <= kBlocksPerPage);
@@ -109,17 +109,17 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(ForwardingPage);
 };
 
-void OldPage::AllocateForwardingPage() {
+void Page::AllocateForwardingPage() {
   ASSERT(forwarding_page_ == NULL);
   ASSERT((object_start() + sizeof(ForwardingPage)) < object_end());
   ASSERT(Utils::IsAligned(sizeof(ForwardingPage), kObjectAlignment));
-  object_end_ -= sizeof(ForwardingPage);
-  forwarding_page_ = reinterpret_cast<ForwardingPage*>(object_end_);
+  top_ -= sizeof(ForwardingPage);
+  forwarding_page_ = reinterpret_cast<ForwardingPage*>(top_);
 }
 
 struct Partition {
-  OldPage* head;
-  OldPage* tail;
+  Page* head;
+  Page* tail;
 };
 
 class CompactorTask : public ThreadPool::Task {
@@ -150,8 +150,8 @@
   void RunEnteredIsolateGroup();
 
  private:
-  void PlanPage(OldPage* page);
-  void SlidePage(OldPage* page);
+  void PlanPage(Page* page);
+  void SlidePage(Page* page);
   uword PlanBlock(uword first_object, ForwardingPage* forwarding_page);
   uword SlideBlock(uword first_object, ForwardingPage* forwarding_page);
   void PlanMoveToContiguousSize(intptr_t size);
@@ -165,7 +165,7 @@
   intptr_t num_tasks_;
   Partition* partitions_;
   FreeList* freelist_;
-  OldPage* free_page_;
+  Page* free_page_;
   uword free_current_;
   uword free_end_;
 
@@ -178,15 +178,13 @@
 // time, keeping blocks from spanning page boundaries (see ForwardingBlock).
 // Free space at the end of a page that is too small for the next block is
 // added to the freelist.
-void GCCompactor::Compact(OldPage* pages,
-                          FreeList* freelist,
-                          Mutex* pages_lock) {
+void GCCompactor::Compact(Page* pages, FreeList* freelist, Mutex* pages_lock) {
   SetupImagePageBoundaries();
 
   // Divide the heap.
   // TODO(30978): Try to divide based on live bytes or with work stealing.
   intptr_t num_pages = 0;
-  for (OldPage* page = pages; page != NULL; page = page->next()) {
+  for (Page* page = pages; page != NULL; page = page->next()) {
     num_pages++;
   }
 
@@ -202,8 +200,8 @@
     const intptr_t pages_per_task = num_pages / num_tasks;
     intptr_t task_index = 0;
     intptr_t page_index = 0;
-    OldPage* page = pages;
-    OldPage* prev = NULL;
+    Page* page = pages;
+    Page* prev = NULL;
     while (task_index < num_tasks) {
       if (page_index % pages_per_task == 0) {
         partitions[task_index].head = page;
@@ -231,8 +229,8 @@
          task_index++) {
       const intptr_t pages_per_task = num_pages / num_tasks;
       for (intptr_t j = 0; j < pages_per_task; j++) {
-        OldPage* page = heap_->old_space()->AllocatePage(OldPage::kData,
-                                                         /* link */ false);
+        Page* page = heap_->old_space()->AllocatePage(Page::kData,
+                                                      /* link */ false);
 
         if (page == nullptr) {
           oom = true;
@@ -333,12 +331,12 @@
 
     // Free empty pages.
     for (intptr_t task_index = 0; task_index < num_tasks; task_index++) {
-      OldPage* page = partitions[task_index].tail->next();
+      Page* page = partitions[task_index].tail->next();
       while (page != NULL) {
-        OldPage* next = page->next();
+        Page* next = page->next();
         heap_->old_space()->IncreaseCapacityInWordsLocked(
             -(page->memory_->size() >> kWordSizeLog2));
-        page->Deallocate();
+        page->Deallocate(/*can_use_cache*/ true);
         page = next;
       }
     }
@@ -385,12 +383,12 @@
       if (planning_task >= num_tasks_) break;
 
       TIMELINE_FUNCTION_GC_DURATION(thread, "Plan");
-      OldPage* head = partitions_[planning_task].head;
+      Page* head = partitions_[planning_task].head;
       free_page_ = head;
       free_current_ = head->object_start();
       free_end_ = head->object_end();
 
-      for (OldPage* page = head; page != NULL; page = page->next()) {
+      for (Page* page = head; page != NULL; page = page->next()) {
         PlanPage(page);
       }
     }
@@ -402,12 +400,12 @@
       if (sliding_task >= num_tasks_) break;
 
       TIMELINE_FUNCTION_GC_DURATION(thread, "Slide");
-      OldPage* head = partitions_[sliding_task].head;
+      Page* head = partitions_[sliding_task].head;
       free_page_ = head;
       free_current_ = head->object_start();
       free_end_ = head->object_end();
 
-      for (OldPage* page = head; page != NULL; page = page->next()) {
+      for (Page* page = head; page != NULL; page = page->next()) {
         SlidePage(page);
       }
 
@@ -431,7 +429,7 @@
       switch (forwarding_task) {
         case 0: {
           TIMELINE_FUNCTION_GC_DURATION(thread, "ForwardLargePages");
-          for (OldPage* large_page =
+          for (Page* large_page =
                    isolate_group_->heap()->old_space()->large_pages_;
                large_page != NULL; large_page = large_page->next()) {
             large_page->VisitObjectPointers(compactor_);
@@ -479,7 +477,7 @@
   }
 }
 
-void CompactorTask::PlanPage(OldPage* page) {
+void CompactorTask::PlanPage(Page* page) {
   uword current = page->object_start();
   uword end = page->object_end();
 
@@ -491,7 +489,7 @@
   }
 }
 
-void CompactorTask::SlidePage(OldPage* page) {
+void CompactorTask::SlidePage(Page* page) {
   uword current = page->object_start();
   uword end = page->object_end();
 
@@ -552,7 +550,7 @@
         // to a new page.  But if we exactly hit the end of the previous page
         // then free_current could be at the start of the next page, so we
         // subtract 1.
-        ASSERT(OldPage::Of(free_current_ - 1) != OldPage::Of(new_addr));
+        ASSERT(Page::Of(free_current_ - 1) != Page::Of(new_addr));
         intptr_t free_remaining = free_end_ - free_current_;
         // Add any leftover at the end of a page to the free list.
         if (free_remaining > 0) {
@@ -593,7 +591,7 @@
 
 void CompactorTask::PlanMoveToContiguousSize(intptr_t size) {
   // Move the free cursor to ensure 'size' bytes of contiguous space.
-  ASSERT(size <= kOldPageSize);
+  ASSERT(size <= kPageSize);
 
   // Check if the current free page has enough space.
   intptr_t free_remaining = free_end_ - free_current_;
@@ -611,7 +609,7 @@
 void GCCompactor::SetupImagePageBoundaries() {
   MallocGrowableArray<ImagePageRange> ranges(4);
 
-  OldPage* image_page =
+  Page* image_page =
       Dart::vm_isolate_group()->heap()->old_space()->image_pages_;
   while (image_page != NULL) {
     ImagePageRange range = {image_page->object_start(),
@@ -656,7 +654,7 @@
     }
   }
 
-  OldPage* page = OldPage::Of(old_target);
+  Page* page = Page::Of(old_target);
   ForwardingPage* forwarding_page = page->forwarding_page();
   if (forwarding_page == NULL) {
     return;  // Not moved (VM isolate, large page, code page).
@@ -692,7 +690,7 @@
     }
   }
 
-  OldPage* page = OldPage::Of(old_target);
+  Page* page = Page::Of(old_target);
   ForwardingPage* forwarding_page = page->forwarding_page();
   if (forwarding_page == NULL) {
     return;  // Not moved (VM isolate, large page, code page).
diff --git a/runtime/vm/heap/compactor.h b/runtime/vm/heap/compactor.h
index cff7736..7b65ccd 100644
--- a/runtime/vm/heap/compactor.h
+++ b/runtime/vm/heap/compactor.h
@@ -17,7 +17,7 @@
 // Forward declarations.
 class FreeList;
 class Heap;
-class OldPage;
+class Page;
 
 // Implements a sliding compactor.
 class GCCompactor : public ValueObject,
@@ -30,7 +30,7 @@
         heap_(heap) {}
   ~GCCompactor() { free(image_page_ranges_); }
 
-  void Compact(OldPage* pages, FreeList* freelist, Mutex* mutex);
+  void Compact(Page* pages, FreeList* freelist, Mutex* mutex);
 
  private:
   friend class CompactorTask;
diff --git a/runtime/vm/heap/freelist.h b/runtime/vm/heap/freelist.h
index 8040f5f..7f2700e 100644
--- a/runtime/vm/heap/freelist.h
+++ b/runtime/vm/heap/freelist.h
@@ -133,7 +133,7 @@
     return result;
   }
 
-  // Ensures OldPage::VisitObjects can successful walk over a partially
+  // Ensures Page::VisitObjects can successful walk over a partially
   // allocated bump region.
   void MakeIterable() {
     if (top_ < end_) {
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 8704c82..ecbb141 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -88,10 +88,10 @@
 
   // It is possible a GC doesn't clear enough space.
   // In that case, we must fall through and allocate into old space.
-  return AllocateOld(thread, size, OldPage::kData);
+  return AllocateOld(thread, size, Page::kData);
 }
 
-uword Heap::AllocateOld(Thread* thread, intptr_t size, OldPage::PageType type) {
+uword Heap::AllocateOld(Thread* thread, intptr_t size, Page::PageType type) {
   ASSERT(thread->no_safepoint_scope_depth() == 0);
   if (!thread->force_growth()) {
     CollectForDebugging(thread);
@@ -107,7 +107,7 @@
     }
     // All GC tasks finished without allocating successfully. Collect both
     // generations.
-    CollectMostGarbage(GCReason::kOldSpace, /*compact=*/ false);
+    CollectMostGarbage(GCReason::kOldSpace, /*compact=*/false);
     addr = old_space_.TryAllocate(size, type);
     if (addr != 0) {
       return addr;
@@ -124,7 +124,7 @@
       return addr;
     }
     // Before throwing an out-of-memory error try a synchronous GC.
-    CollectAllGarbage(GCReason::kOldSpace, /*compact=*/ true);
+    CollectAllGarbage(GCReason::kOldSpace, /*compact=*/true);
     WaitForSweeperTasks(thread);
   }
   uword addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
@@ -146,12 +146,16 @@
   return 0;
 }
 
-void Heap::AllocatedExternal(intptr_t size, Space space) {
+bool Heap::AllocatedExternal(intptr_t size, Space space) {
   if (space == kNew) {
-    new_space_.AllocatedExternal(size);
+    if (!new_space_.AllocatedExternal(size)) {
+      return false;
+    }
   } else {
     ASSERT(space == kOld);
-    old_space_.AllocatedExternal(size);
+    if (!old_space_.AllocatedExternal(size)) {
+      return false;
+    }
   }
 
   Thread* thread = Thread::Current();
@@ -160,6 +164,7 @@
   } else {
     // Check delayed until Dart_TypedDataRelease/~ForceGrowthScope.
   }
+  return true;
 }
 
 void Heap::FreedExternal(intptr_t size, Space space) {
@@ -216,7 +221,7 @@
 }
 
 bool Heap::CodeContains(uword addr) const {
-  return old_space_.Contains(addr, OldPage::kExecutable);
+  return old_space_.Contains(addr, Page::kExecutable);
 }
 
 bool Heap::DataContains(uword addr) const {
@@ -341,14 +346,14 @@
 
 InstructionsPtr Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const {
   // Only executable pages can have RawInstructions objects.
-  ObjectPtr raw_obj = old_space_.FindObject(visitor, OldPage::kExecutable);
+  ObjectPtr raw_obj = old_space_.FindObject(visitor, Page::kExecutable);
   ASSERT((raw_obj == Object::null()) ||
          (raw_obj->GetClassId() == kInstructionsCid));
   return static_cast<InstructionsPtr>(raw_obj);
 }
 
 ObjectPtr Heap::FindOldObject(FindObjectVisitor* visitor) const {
-  return old_space_.FindObject(visitor, OldPage::kData);
+  return old_space_.FindObject(visitor, Page::kData);
 }
 
 ObjectPtr Heap::FindNewObject(FindObjectVisitor* visitor) {
@@ -427,7 +432,7 @@
   }
 
   if (OS::GetCurrentMonotonicMicros() < deadline) {
-    SemiSpace::ClearCache();
+    Page::ClearCache();
   }
 }
 
@@ -704,19 +709,6 @@
   isolate_group->set_heap(std::move(heap));
 }
 
-const char* Heap::RegionName(Space space) {
-  switch (space) {
-    case kNew:
-      return "dart-newspace";
-    case kOld:
-      return "dart-oldspace";
-    case kCode:
-      return "dart-codespace";
-    default:
-      UNREACHABLE();
-  }
-}
-
 void Heap::AddRegionsToObjectSet(ObjectSet* set) const {
   new_space_.AddRegionsToObjectSet(set);
   old_space_.AddRegionsToObjectSet(set);
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index 9c1286f..a5f65eb 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -65,21 +65,23 @@
       case kNew:
         // Do not attempt to allocate very large objects in new space.
         if (!IsAllocatableInNewSpace(size)) {
-          return AllocateOld(thread, size, OldPage::kData);
+          return AllocateOld(thread, size, Page::kData);
         }
         return AllocateNew(thread, size);
       case kOld:
-        return AllocateOld(thread, size, OldPage::kData);
+        return AllocateOld(thread, size, Page::kData);
       case kCode:
-        return AllocateOld(thread, size, OldPage::kExecutable);
+        return AllocateOld(thread, size, Page::kExecutable);
       default:
         UNREACHABLE();
     }
     return 0;
   }
 
-  // Track external data.
-  void AllocatedExternal(intptr_t size, Space space);
+  // Tracks an external allocation. Returns false without tracking the
+  // allocation if it will make the total external size exceed
+  // kMaxAddrSpaceInWords.
+  bool AllocatedExternal(intptr_t size, Space space);
   void FreedExternal(intptr_t size, Space space);
   // Move external size from new to old space. Does not by itself trigger GC.
   void PromotedExternal(intptr_t size);
@@ -148,9 +150,6 @@
                    intptr_t max_new_gen_words,
                    intptr_t max_old_gen_words);
 
-  // Returns a suitable name for a VM region in the heap.
-  static const char* RegionName(Space space);
-
   // Verify that all pointers in the heap point to the heap.
   bool Verify(MarkExpectation mark_expectation = kForbidMarked);
 
@@ -322,7 +321,7 @@
        intptr_t max_old_gen_words);
 
   uword AllocateNew(Thread* thread, intptr_t size);
-  uword AllocateOld(Thread* thread, intptr_t size, OldPage::PageType type);
+  uword AllocateOld(Thread* thread, intptr_t size, Page::PageType type);
 
   // Visit all pointers. Caller must ensure concurrent sweeper is not running,
   // and the visitor must not allocate.
diff --git a/runtime/vm/heap/heap_sources.gni b/runtime/vm/heap/heap_sources.gni
index a8e8d99..39a2ec9 100644
--- a/runtime/vm/heap/heap_sources.gni
+++ b/runtime/vm/heap/heap_sources.gni
@@ -17,6 +17,8 @@
   "heap.h",
   "marker.cc",
   "marker.h",
+  "page.cc",
+  "page.h",
   "pages.cc",
   "pages.h",
   "pointer_block.cc",
diff --git a/runtime/vm/heap/heap_test.cc b/runtime/vm/heap/heap_test.cc
index 51a139b..a428876 100644
--- a/runtime/vm/heap/heap_test.cc
+++ b/runtime/vm/heap/heap_test.cc
@@ -674,6 +674,76 @@
               heap->new_space()->ExternalInWords() * kWordSize);
   }
 }
+
+ISOLATE_UNIT_TEST_CASE(ExternalSizeLimit) {
+  // This test checks that the tracked total size of external data never exceeds
+  // the amount of memory on the system. To accomplish this, the test performs
+  // five calls to FinalizablePersistentHandle::New(), all supplying a size
+  // argument that is barely (16 bytes) less than a quarter of kMaxAddrSpaceMB.
+  // So, we expect the first four calls to succeed, and the fifth one to return
+  // nullptr.
+
+  auto isolate_group = thread->isolate_group();
+  Heap* heap = isolate_group->heap();
+
+  // We declare an array of only length 1 here to get around the limit of
+  // ExternalTypedData::MaxElements(kExternalTypedDataUint8ArrayCid). Below, we
+  // pretend that the length is longer when calling
+  // FinalizablePersistentHandle::New(), which is what updates the external size
+  // tracker.
+  const intptr_t data_length = 1;
+  uint8_t data[data_length] = {0};
+  const ExternalTypedData& external_typed_data_1 =
+      ExternalTypedData::Handle(ExternalTypedData::New(
+          kExternalTypedDataUint8ArrayCid, data, data_length, Heap::kOld));
+  const ExternalTypedData& external_typed_data_2 =
+      ExternalTypedData::Handle(ExternalTypedData::New(
+          kExternalTypedDataUint8ArrayCid, data, data_length, Heap::kOld));
+  const ExternalTypedData& external_typed_data_3 =
+      ExternalTypedData::Handle(ExternalTypedData::New(
+          kExternalTypedDataUint8ArrayCid, data, data_length, Heap::kOld));
+  const ExternalTypedData& external_typed_data_4 =
+      ExternalTypedData::Handle(ExternalTypedData::New(
+          kExternalTypedDataUint8ArrayCid, data, data_length, Heap::kOld));
+  const ExternalTypedData& external_typed_data_5 =
+      ExternalTypedData::Handle(ExternalTypedData::New(
+          kExternalTypedDataUint8ArrayCid, data, data_length, Heap::kOld));
+
+  // A size that is less than a quarter of kMaxAddrSpaceMB is used because it
+  // needs to be less than or equal to std::numeric_limits<intptr_t>::max().
+  const intptr_t external_allocation_size =
+      (intptr_t{kMaxAddrSpaceMB / 4} << MBLog2) - 16;
+  EXPECT_NOTNULL(FinalizablePersistentHandle::New(
+      isolate_group, external_typed_data_1, nullptr, NoopFinalizer,
+      external_allocation_size,
+      /*auto_delete=*/true));
+  EXPECT_LT(heap->old_space()->ExternalInWords(), kMaxAddrSpaceInWords);
+
+  EXPECT_NOTNULL(FinalizablePersistentHandle::New(
+      isolate_group, external_typed_data_2, nullptr, NoopFinalizer,
+      external_allocation_size,
+      /*auto_delete=*/true));
+  EXPECT_LT(heap->old_space()->ExternalInWords(), kMaxAddrSpaceInWords);
+
+  EXPECT_NOTNULL(FinalizablePersistentHandle::New(
+      isolate_group, external_typed_data_3, nullptr, NoopFinalizer,
+      external_allocation_size,
+      /*auto_delete=*/true));
+  EXPECT_LT(heap->old_space()->ExternalInWords(), kMaxAddrSpaceInWords);
+
+  EXPECT_NOTNULL(FinalizablePersistentHandle::New(
+      isolate_group, external_typed_data_4, nullptr, NoopFinalizer,
+      external_allocation_size,
+      /*auto_delete=*/true));
+  EXPECT_LT(heap->old_space()->ExternalInWords(), kMaxAddrSpaceInWords);
+
+  EXPECT_NULLPTR(FinalizablePersistentHandle::New(
+      isolate_group, external_typed_data_5, nullptr, NoopFinalizer,
+      external_allocation_size,
+      /*auto_delete=*/true));
+  // Check that the external size is indeed protected from overflowing.
+  EXPECT_LT(heap->old_space()->ExternalInWords(), kMaxAddrSpaceInWords);
+}
 #endif  // !defined(PRODUCT)
 
 ISOLATE_UNIT_TEST_CASE(ArrayTruncationRaces) {
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 29bf3ed..4515324 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -376,7 +376,7 @@
   static bool TryAcquireMarkBit(ObjectPtr raw_obj) {
     if (FLAG_write_protect_code && raw_obj->IsInstructions()) {
       // A non-writable alias mapping may exist for instruction pages.
-      raw_obj = OldPage::ToWritable(raw_obj);
+      raw_obj = Page::ToWritable(raw_obj);
     }
     if (!sync) {
       raw_obj->untag()->SetMarkBitUnsynchronized();
@@ -460,7 +460,7 @@
  public:
   explicit MarkingWeakVisitor(Thread* thread)
       : HandleVisitor(thread),
-        class_table_(thread->isolate_group()->shared_class_table()) {}
+        class_table_(thread->isolate_group()->class_table()) {}
 
   void VisitHandle(uword addr) {
     FinalizablePersistentHandle* handle =
@@ -472,7 +472,7 @@
   }
 
  private:
-  SharedClassTable* class_table_;
+  ClassTable* class_table_;
 
   DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor);
 };
@@ -495,7 +495,7 @@
   root_slices_finished_ = 0;
   root_slices_count_ = kNumFixedRootSlices;
   new_page_ = heap_->new_space()->head();
-  for (NewPage* p = new_page_; p != nullptr; p = p->next()) {
+  for (Page* p = new_page_; p != nullptr; p = p->next()) {
     root_slices_count_++;
   }
 
@@ -518,7 +518,7 @@
         break;
       }
       default: {
-        NewPage* page;
+        Page* page;
         {
           MonitorLocker ml(&root_slices_monitor_);
           page = new_page_;
diff --git a/runtime/vm/heap/marker.h b/runtime/vm/heap/marker.h
index 6cc2653..2888017 100644
--- a/runtime/vm/heap/marker.h
+++ b/runtime/vm/heap/marker.h
@@ -20,7 +20,7 @@
 class PageSpace;
 template <bool sync>
 class MarkingVisitorBase;
-class NewPage;
+class Page;
 class Thread;
 
 // The class GCMarker is used to mark reachable old generation objects as part
@@ -73,7 +73,7 @@
   GCLinkedLists global_list_;
   MarkingVisitorBase<true>** visitors_;
 
-  NewPage* new_page_;
+  Page* new_page_;
   Monitor root_slices_monitor_;
   RelaxedAtomic<intptr_t> root_slices_started_;
   intptr_t root_slices_finished_;
diff --git a/runtime/vm/heap/page.cc b/runtime/vm/heap/page.cc
new file mode 100644
index 0000000..a2eba82
--- /dev/null
+++ b/runtime/vm/heap/page.cc
@@ -0,0 +1,286 @@
+// Copyright (c) 2022, 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 "vm/heap/page.h"
+
+#include "platform/assert.h"
+#include "platform/leak_sanitizer.h"
+#include "vm/dart.h"
+#include "vm/heap/become.h"
+#include "vm/heap/compactor.h"
+#include "vm/heap/marker.h"
+#include "vm/heap/safepoint.h"
+#include "vm/heap/sweeper.h"
+#include "vm/lockers.h"
+#include "vm/log.h"
+#include "vm/object.h"
+#include "vm/object_set.h"
+#include "vm/os_thread.h"
+#include "vm/virtual_memory.h"
+
+namespace dart {
+
+// This cache needs to be at least as big as FLAG_new_gen_semi_max_size or
+// munmap will noticably impact performance.
+static constexpr intptr_t kPageCacheCapacity = 8 * kWordSize;
+static Mutex* page_cache_mutex = nullptr;
+static VirtualMemory* page_cache[kPageCacheCapacity] = {nullptr};
+static intptr_t page_cache_size = 0;
+
+void Page::Init() {
+  ASSERT(page_cache_mutex == nullptr);
+  page_cache_mutex = new Mutex(NOT_IN_PRODUCT("page_cache_mutex"));
+}
+
+void Page::ClearCache() {
+  MutexLocker ml(page_cache_mutex);
+  ASSERT(page_cache_size >= 0);
+  ASSERT(page_cache_size <= kPageCacheCapacity);
+  while (page_cache_size > 0) {
+    delete page_cache[--page_cache_size];
+  }
+}
+
+void Page::Cleanup() {
+  ClearCache();
+  delete page_cache_mutex;
+  page_cache_mutex = nullptr;
+}
+
+intptr_t Page::CachedSize() {
+  MutexLocker ml(page_cache_mutex);
+  return page_cache_size * kPageSize;
+}
+
+Page* Page::Allocate(intptr_t size, PageType type, bool can_use_cache) {
+  const bool executable = type == kExecutable;
+  const bool compressed = !executable;
+  const char* name = executable ? "dart-code" : "dart-heap";
+
+  VirtualMemory* memory = nullptr;
+  if (can_use_cache) {
+    // We don't automatically use the cache based on size and type because a
+    // large page that happens to be the same size as a regular page can't
+    // use the cache. Large pages are expected to be zeroed on allocation but
+    // cached pages are dirty.
+    ASSERT(size == kPageSize);
+    ASSERT(!executable);
+    MutexLocker ml(page_cache_mutex);
+    ASSERT(page_cache_size >= 0);
+    ASSERT(page_cache_size <= kPageCacheCapacity);
+    if (page_cache_size > 0) {
+      memory = page_cache[--page_cache_size];
+    }
+  }
+  if (memory == nullptr) {
+    memory = VirtualMemory::AllocateAligned(size, kPageSize, executable,
+                                            compressed, name);
+  }
+  if (memory == nullptr) {
+    return nullptr;  // Out of memory.
+  }
+
+  if (type == kNew) {
+#if defined(DEBUG)
+    memset(memory->address(), Heap::kZapByte, size);
+#endif
+    // Initialized by generated code.
+    MSAN_UNPOISON(memory->address(), size);
+  } else {
+    // We don't zap old-gen because we rely on implicit zero-initialization
+    // of large typed data arrays.
+  }
+
+  Page* result = reinterpret_cast<Page*>(memory->address());
+  ASSERT(result != NULL);
+  result->type_ = type;
+  result->memory_ = memory;
+  result->next_ = nullptr;
+  result->forwarding_page_ = nullptr;
+  result->card_table_ = nullptr;
+  result->progress_bar_ = 0;
+  result->owner_ = nullptr;
+  result->top_ = 0;
+  result->end_ = 0;
+  result->survivor_end_ = 0;
+  result->resolved_top_ = 0;
+
+  if (type == kNew) {
+    uword top = result->object_start();
+    uword end =
+        memory->end() - kNewObjectAlignmentOffset - kAllocationRedZoneSize;
+    result->top_ = top;
+    result->end_ = end;
+    result->survivor_end_ = top;
+    result->resolved_top_ = top;
+  }
+
+  LSAN_REGISTER_ROOT_REGION(result, sizeof(*result));
+
+  return result;
+}
+
+void Page::Deallocate(bool can_use_cache) {
+  if (is_image_page()) {
+    delete memory_;
+    // For a heap page from a snapshot, the Page object lives in the malloc
+    // heap rather than the page itself.
+    free(this);
+    return;
+  }
+
+  free(card_table_);
+
+  LSAN_UNREGISTER_ROOT_REGION(this, sizeof(*this));
+
+  VirtualMemory* memory = memory_;
+  if (can_use_cache) {
+    ASSERT(memory->size() == kPageSize);
+    ASSERT(type_ != kExecutable);
+    MutexLocker ml(page_cache_mutex);
+    ASSERT(page_cache_size >= 0);
+    ASSERT(page_cache_size <= kPageCacheCapacity);
+    if (page_cache_size < kPageCacheCapacity) {
+      intptr_t size = memory->size();
+#if defined(DEBUG)
+      if (type_ == kNew) {
+        memset(memory->address(), Heap::kZapByte, size);
+      } else {
+        // We don't zap old-gen because we rely on implicit zero-initialization
+        // of large typed data arrays.
+      }
+#endif
+      MSAN_POISON(memory->address(), size);
+      page_cache[page_cache_size++] = memory;
+      memory = nullptr;
+    }
+  }
+  delete memory;
+}
+
+void Page::VisitObjects(ObjectVisitor* visitor) const {
+  ASSERT(Thread::Current()->IsAtSafepoint());
+  NoSafepointScope no_safepoint;
+  uword obj_addr = object_start();
+  uword end_addr = object_end();
+  while (obj_addr < end_addr) {
+    ObjectPtr raw_obj = UntaggedObject::FromAddr(obj_addr);
+    visitor->VisitObject(raw_obj);
+    obj_addr += raw_obj->untag()->HeapSize();
+  }
+  ASSERT(obj_addr == end_addr);
+}
+
+void Page::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
+  ASSERT(Thread::Current()->IsAtSafepoint() ||
+         (Thread::Current()->task_kind() == Thread::kCompactorTask) ||
+         (Thread::Current()->task_kind() == Thread::kMarkerTask));
+  NoSafepointScope no_safepoint;
+  uword obj_addr = object_start();
+  uword end_addr = object_end();
+  while (obj_addr < end_addr) {
+    ObjectPtr raw_obj = UntaggedObject::FromAddr(obj_addr);
+    obj_addr += raw_obj->untag()->VisitPointers(visitor);
+  }
+  ASSERT(obj_addr == end_addr);
+}
+
+void Page::VisitRememberedCards(ObjectPointerVisitor* visitor) {
+  ASSERT(Thread::Current()->IsAtSafepoint() ||
+         (Thread::Current()->task_kind() == Thread::kScavengerTask));
+  NoSafepointScope no_safepoint;
+
+  if (card_table_ == NULL) {
+    return;
+  }
+
+  ArrayPtr obj =
+      static_cast<ArrayPtr>(UntaggedObject::FromAddr(object_start()));
+  ASSERT(obj->IsArray());
+  ASSERT(obj->untag()->IsCardRemembered());
+  CompressedObjectPtr* obj_from = obj->untag()->from();
+  CompressedObjectPtr* obj_to =
+      obj->untag()->to(Smi::Value(obj->untag()->length()));
+  uword heap_base = obj.heap_base();
+
+  const intptr_t size = card_table_size();
+  for (;;) {
+    intptr_t i = progress_bar_.fetch_add(1);
+    if (i >= size) break;
+
+    if (card_table_[i] != 0) {
+      CompressedObjectPtr* card_from =
+          reinterpret_cast<CompressedObjectPtr*>(this) +
+          (i << kSlotsPerCardLog2);
+      CompressedObjectPtr* card_to =
+          reinterpret_cast<CompressedObjectPtr*>(card_from) +
+          (1 << kSlotsPerCardLog2) - 1;
+      // Minus 1 because to is inclusive.
+
+      if (card_from < obj_from) {
+        // First card overlaps with header.
+        card_from = obj_from;
+      }
+      if (card_to > obj_to) {
+        // Last card(s) may extend past the object. Array truncation can make
+        // this happen for more than one card.
+        card_to = obj_to;
+      }
+
+      visitor->VisitCompressedPointers(heap_base, card_from, card_to);
+
+      bool has_new_target = false;
+      for (CompressedObjectPtr* slot = card_from; slot <= card_to; slot++) {
+        if ((*slot)->IsNewObjectMayBeSmi()) {
+          has_new_target = true;
+          break;
+        }
+      }
+
+      if (!has_new_target) {
+        card_table_[i] = 0;
+      }
+    }
+  }
+}
+
+void Page::ResetProgressBar() {
+  progress_bar_ = 0;
+}
+
+ObjectPtr Page::FindObject(FindObjectVisitor* visitor) const {
+  uword obj_addr = object_start();
+  uword end_addr = object_end();
+  if (visitor->VisitRange(obj_addr, end_addr)) {
+    while (obj_addr < end_addr) {
+      ObjectPtr raw_obj = UntaggedObject::FromAddr(obj_addr);
+      uword next_obj_addr = obj_addr + raw_obj->untag()->HeapSize();
+      if (visitor->VisitRange(obj_addr, next_obj_addr) &&
+          raw_obj->untag()->FindObject(visitor)) {
+        return raw_obj;  // Found object, return it.
+      }
+      obj_addr = next_obj_addr;
+    }
+    ASSERT(obj_addr == end_addr);
+  }
+  return Object::null();
+}
+
+void Page::WriteProtect(bool read_only) {
+  ASSERT(!is_image_page());
+
+  VirtualMemory::Protection prot;
+  if (read_only) {
+    if ((type_ == kExecutable) && (memory_->AliasOffset() == 0)) {
+      prot = VirtualMemory::kReadExecute;
+    } else {
+      prot = VirtualMemory::kReadOnly;
+    }
+  } else {
+    prot = VirtualMemory::kReadWrite;
+  }
+  memory_->Protect(prot);
+}
+
+}  // namespace dart
diff --git a/runtime/vm/heap/page.h b/runtime/vm/heap/page.h
new file mode 100644
index 0000000..5aba1ae
--- /dev/null
+++ b/runtime/vm/heap/page.h
@@ -0,0 +1,340 @@
+// Copyright (c) 2022, 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.
+
+#ifndef RUNTIME_VM_HEAP_PAGE_H_
+#define RUNTIME_VM_HEAP_PAGE_H_
+
+#include "platform/atomic.h"
+#include "vm/globals.h"
+#include "vm/heap/spaces.h"
+#include "vm/pointer_tagging.h"
+#include "vm/raw_object.h"
+#include "vm/virtual_memory.h"
+
+namespace dart {
+
+class ForwardingPage;
+class ObjectVisitor;
+class ObjectPointerVisitor;
+class FindObjectVisitor;
+class Thread;
+
+// Pages are allocated with kPageSize alignment so that the Page of any object
+// can be computed by masking the object with kPageMask. This does not apply to
+// image pages, whose address is choosen by the system loader rather than the
+// Dart VM.
+static constexpr intptr_t kPageSize = 512 * KB;
+static constexpr intptr_t kPageSizeInWords = kPageSize / kWordSize;
+static constexpr intptr_t kPageMask = ~(kPageSize - 1);
+
+// See ForwardingBlock and CountingBlock.
+static constexpr intptr_t kBitVectorWordsPerBlock = 1;
+static constexpr intptr_t kBlockSize =
+    kObjectAlignment * kBitsPerWord * kBitVectorWordsPerBlock;
+static constexpr intptr_t kBlockMask = ~(kBlockSize - 1);
+static constexpr intptr_t kBlocksPerPage = kPageSize / kBlockSize;
+
+// Simplify initialization in allocation stubs by ensuring it is safe
+// to overshoot the object end by up to kAllocationRedZoneSize. (Just as the
+// stack red zone allows one to overshoot the stack pointer.)
+static constexpr intptr_t kAllocationRedZoneSize = kObjectAlignment;
+
+// A Page is the granuitary at which the Dart heap allocates memory from the OS.
+// Pages are usually of size kPageSize, except large objects are allocated on
+// their own Page sized to the object.
+//
+// +----------------------+  <- start
+// | struct Page (header) |
+// +----------------------+
+// | alignment gap        |
+// +----------------------+  <- object_start
+// | objects              |
+// | ...                  |
+// | ...                  |
+// +----------------------+  <- object_end / top_
+// | available            |
+// +----------------------+  <- end_
+// | red zone or          |
+// | forwarding table     |
+// +----------------------+  <- memory_->end()
+class Page {
+ public:
+  static void Init();
+  static void ClearCache();
+  static intptr_t CachedSize();
+  static void Cleanup();
+
+  enum PageType : uword { kExecutable = 0, kData, kNew };
+
+  Page* next() const { return next_; }
+  void set_next(Page* next) { next_ = next; }
+
+  uword start() const { return memory_->start(); }
+  uword end() const { return memory_->end(); }
+  bool Contains(uword addr) const { return memory_->Contains(addr); }
+  intptr_t AliasOffset() const { return memory_->AliasOffset(); }
+
+  uword object_start() const {
+    return type_ == kNew ? new_object_start() : old_object_start();
+  }
+  uword old_object_start() const {
+    return memory_->start() + OldObjectStartOffset();
+  }
+  uword new_object_start() const {
+    return memory_->start() + NewObjectStartOffset();
+  }
+  uword object_end() const {
+    if (owner_ != NULL) return owner_->top();
+    return top_;
+  }
+  intptr_t used() const { return object_end() - object_start(); }
+
+  ForwardingPage* forwarding_page() const { return forwarding_page_; }
+  void AllocateForwardingPage();
+
+  PageType type() const { return type_; }
+
+  bool is_image_page() const { return !memory_->vm_owns_region(); }
+
+  void VisitObjects(ObjectVisitor* visitor) const;
+  void VisitObjectPointers(ObjectPointerVisitor* visitor) const;
+
+  ObjectPtr FindObject(FindObjectVisitor* visitor) const;
+
+  void WriteProtect(bool read_only);
+
+  static intptr_t OldObjectStartOffset() {
+    return Utils::RoundUp(sizeof(Page) - kOldObjectAlignmentOffset,
+                          kObjectStartAlignment) +
+           kOldObjectAlignmentOffset;
+  }
+  static intptr_t NewObjectStartOffset() {
+    // Note weaker alignment because the bool/null offset tricks don't apply to
+    // new-space.
+    return Utils::RoundUp(sizeof(Page) - kNewObjectAlignmentOffset,
+                          kObjectAlignment) +
+           kNewObjectAlignmentOffset;
+  }
+
+  // Warning: This does not work for objects on image pages because image pages
+  // are not aligned. However, it works for objects on large pages, because
+  // only one object is allocated per large page.
+  static Page* Of(ObjectPtr obj) {
+    ASSERT(obj->IsHeapObject());
+    return reinterpret_cast<Page*>(static_cast<uword>(obj) & kPageMask);
+  }
+
+  // Warning: This does not work for addresses on image pages or on large pages.
+  static Page* Of(uword addr) {
+    return reinterpret_cast<Page*>(addr & kPageMask);
+  }
+
+  // Warning: This does not work for objects on image pages.
+  static ObjectPtr ToExecutable(ObjectPtr obj) {
+    Page* page = Of(obj);
+    VirtualMemory* memory = page->memory_;
+    const intptr_t alias_offset = memory->AliasOffset();
+    if (alias_offset == 0) {
+      return obj;  // Not aliased.
+    }
+    uword addr = UntaggedObject::ToAddr(obj);
+    if (memory->Contains(addr)) {
+      return UntaggedObject::FromAddr(addr + alias_offset);
+    }
+    // obj is executable.
+    ASSERT(memory->ContainsAlias(addr));
+    return obj;
+  }
+
+  // Warning: This does not work for objects on image pages.
+  static ObjectPtr ToWritable(ObjectPtr obj) {
+    Page* page = Of(obj);
+    VirtualMemory* memory = page->memory_;
+    const intptr_t alias_offset = memory->AliasOffset();
+    if (alias_offset == 0) {
+      return obj;  // Not aliased.
+    }
+    uword addr = UntaggedObject::ToAddr(obj);
+    if (memory->ContainsAlias(addr)) {
+      return UntaggedObject::FromAddr(addr - alias_offset);
+    }
+    // obj is writable.
+    ASSERT(memory->Contains(addr));
+    return obj;
+  }
+
+  // 1 card = 128 slots.
+  static const intptr_t kSlotsPerCardLog2 = 7;
+  static const intptr_t kBytesPerCardLog2 =
+      kCompressedWordSizeLog2 + kSlotsPerCardLog2;
+
+  intptr_t card_table_size() const {
+    return memory_->size() >> kBytesPerCardLog2;
+  }
+
+  static intptr_t card_table_offset() { return OFFSET_OF(Page, card_table_); }
+
+  void RememberCard(ObjectPtr const* slot) {
+    ASSERT(Contains(reinterpret_cast<uword>(slot)));
+    if (card_table_ == NULL) {
+      card_table_ = reinterpret_cast<uint8_t*>(
+          calloc(card_table_size(), sizeof(uint8_t)));
+    }
+    intptr_t offset =
+        reinterpret_cast<uword>(slot) - reinterpret_cast<uword>(this);
+    intptr_t index = offset >> kBytesPerCardLog2;
+    ASSERT((index >= 0) && (index < card_table_size()));
+    card_table_[index] = 1;
+  }
+  bool IsCardRemembered(ObjectPtr const* slot) {
+    ASSERT(Contains(reinterpret_cast<uword>(slot)));
+    if (card_table_ == NULL) {
+      return false;
+    }
+    intptr_t offset =
+        reinterpret_cast<uword>(slot) - reinterpret_cast<uword>(this);
+    intptr_t index = offset >> kBytesPerCardLog2;
+    ASSERT((index >= 0) && (index < card_table_size()));
+    return card_table_[index] != 0;
+  }
+#if defined(DART_COMPRESSED_POINTERS)
+  void RememberCard(CompressedObjectPtr const* slot) {
+    ASSERT(Contains(reinterpret_cast<uword>(slot)));
+    if (card_table_ == NULL) {
+      card_table_ = reinterpret_cast<uint8_t*>(
+          calloc(card_table_size(), sizeof(uint8_t)));
+    }
+    intptr_t offset =
+        reinterpret_cast<uword>(slot) - reinterpret_cast<uword>(this);
+    intptr_t index = offset >> kBytesPerCardLog2;
+    ASSERT((index >= 0) && (index < card_table_size()));
+    card_table_[index] = 1;
+  }
+  bool IsCardRemembered(CompressedObjectPtr const* slot) {
+    ASSERT(Contains(reinterpret_cast<uword>(slot)));
+    if (card_table_ == NULL) {
+      return false;
+    }
+    intptr_t offset =
+        reinterpret_cast<uword>(slot) - reinterpret_cast<uword>(this);
+    intptr_t index = offset >> kBytesPerCardLog2;
+    ASSERT((index >= 0) && (index < card_table_size()));
+    return card_table_[index] != 0;
+  }
+#endif
+  void VisitRememberedCards(ObjectPointerVisitor* visitor);
+  void ResetProgressBar();
+
+  Thread* owner() const {
+    return owner_;
+  }
+
+  // Remember the limit to which objects have been copied.
+  void RecordSurvivors() {
+    survivor_end_ = object_end();
+  }
+
+  // Move survivor end to the end of the to_ space, making all surviving
+  // objects candidates for promotion next time.
+  void EarlyTenure() {
+    survivor_end_ = end_;
+  }
+
+  uword promo_candidate_words() const {
+    return (survivor_end_ - object_start()) / kWordSize;
+  }
+
+  void Acquire(Thread* thread) {
+    ASSERT(owner_ == nullptr);
+    owner_ = thread;
+    thread->set_top(top_);
+    thread->set_end(end_);
+  }
+  void Release(Thread* thread) {
+    ASSERT(owner_ == thread);
+    owner_ = nullptr;
+    top_ = thread->top();
+    thread->set_top(0);
+    thread->set_end(0);
+  }
+  void Release() {
+    if (owner_ != nullptr) {
+      Release(owner_);
+    }
+  }
+
+  uword TryAllocateGC(intptr_t size) {
+    ASSERT(owner_ == nullptr);
+    uword result = top_;
+    uword new_top = result + size;
+    if (LIKELY(new_top <= end_)) {
+      top_ = new_top;
+      return result;
+    }
+    return 0;
+  }
+
+  void Unallocate(uword addr, intptr_t size) {
+    ASSERT((addr + size) == top_);
+    top_ -= size;
+  }
+
+  bool IsSurvivor(uword raw_addr) const {
+    return raw_addr < survivor_end_;
+  }
+  bool IsResolved() const {
+    return top_ == resolved_top_;
+  }
+
+ private:
+  void set_object_end(uword value) {
+    ASSERT((value & kObjectAlignmentMask) == kOldObjectAlignmentOffset);
+    top_ = value;
+  }
+
+  // Returns NULL on OOM.
+  static Page* Allocate(intptr_t size, PageType type, bool can_use_cache);
+
+  // Deallocate the virtual memory backing this page. The page pointer to this
+  // page becomes immediately inaccessible.
+  void Deallocate(bool can_use_cache);
+
+  PageType type_;
+  VirtualMemory* memory_;
+  Page* next_;
+  ForwardingPage* forwarding_page_;
+  uint8_t* card_table_;  // Remembered set, not marking.
+  RelaxedAtomic<intptr_t> progress_bar_;
+
+  // The thread using this page for allocation, otherwise NULL.
+  Thread* owner_;
+
+  // The address of the next allocation. If owner is non-NULL, this value is
+  // stale and the current value is at owner->top_. Called "NEXT" in the
+  // original Cheney paper.
+  uword top_;
+
+  // The address after the last allocatable byte in this page.
+  uword end_;
+
+  // Objects below this address have survived a scavenge.
+  uword survivor_end_;
+
+  // A pointer to the first unprocessed object. Resolution completes when this
+  // value meets the allocation top. Called "SCAN" in the original Cheney paper.
+  uword resolved_top_;
+
+  template <bool>
+  friend class ScavengerVisitorBase;
+  friend class SemiSpace;
+  friend class PageSpace;
+  friend class GCCompactor;
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Page);
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_HEAP_PAGE_H_
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 11fca3d..a928109 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -43,180 +43,6 @@
             "Print free list statistics after a GC");
 DEFINE_FLAG(bool, log_growth, false, "Log PageSpace growth policy decisions.");
 
-OldPage* OldPage::Allocate(intptr_t size_in_words,
-                           PageType type,
-                           const char* name) {
-  const bool executable = type == kExecutable;
-  const bool compressed = !executable;
-
-  VirtualMemory* memory = VirtualMemory::AllocateAligned(
-      size_in_words << kWordSizeLog2, kOldPageSize, executable, compressed,
-      name);
-  if (memory == NULL) {
-    return NULL;
-  }
-
-  OldPage* result = reinterpret_cast<OldPage*>(memory->address());
-  ASSERT(result != NULL);
-  result->memory_ = memory;
-  result->next_ = NULL;
-  result->used_in_bytes_ = 0;
-  result->forwarding_page_ = NULL;
-  result->card_table_ = NULL;
-  result->progress_bar_ = 0;
-  result->type_ = type;
-
-  LSAN_REGISTER_ROOT_REGION(result, sizeof(*result));
-
-  return result;
-}
-
-void OldPage::Deallocate() {
-  if (card_table_ != NULL) {
-    free(card_table_);
-    card_table_ = NULL;
-  }
-
-  bool image_page = is_image_page();
-
-  if (!image_page) {
-    LSAN_UNREGISTER_ROOT_REGION(this, sizeof(*this));
-  }
-
-  // For a regular heap pages, the memory for this object will become
-  // unavailable after the delete below.
-  delete memory_;
-
-  // For a heap page from a snapshot, the OldPage object lives in the malloc
-  // heap rather than the page itself.
-  if (image_page) {
-    free(this);
-  }
-}
-
-void OldPage::VisitObjects(ObjectVisitor* visitor) const {
-  ASSERT(Thread::Current()->IsAtSafepoint());
-  NoSafepointScope no_safepoint;
-  uword obj_addr = object_start();
-  uword end_addr = object_end();
-  while (obj_addr < end_addr) {
-    ObjectPtr raw_obj = UntaggedObject::FromAddr(obj_addr);
-    visitor->VisitObject(raw_obj);
-    obj_addr += raw_obj->untag()->HeapSize();
-  }
-  ASSERT(obj_addr == end_addr);
-}
-
-void OldPage::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
-  ASSERT(Thread::Current()->IsAtSafepoint() ||
-         (Thread::Current()->task_kind() == Thread::kCompactorTask));
-  NoSafepointScope no_safepoint;
-  uword obj_addr = object_start();
-  uword end_addr = object_end();
-  while (obj_addr < end_addr) {
-    ObjectPtr raw_obj = UntaggedObject::FromAddr(obj_addr);
-    obj_addr += raw_obj->untag()->VisitPointers(visitor);
-  }
-  ASSERT(obj_addr == end_addr);
-}
-
-void OldPage::VisitRememberedCards(ObjectPointerVisitor* visitor) {
-  ASSERT(Thread::Current()->IsAtSafepoint() ||
-         (Thread::Current()->task_kind() == Thread::kScavengerTask));
-  NoSafepointScope no_safepoint;
-
-  if (card_table_ == NULL) {
-    return;
-  }
-
-  ArrayPtr obj =
-      static_cast<ArrayPtr>(UntaggedObject::FromAddr(object_start()));
-  ASSERT(obj->IsArray());
-  ASSERT(obj->untag()->IsCardRemembered());
-  CompressedObjectPtr* obj_from = obj->untag()->from();
-  CompressedObjectPtr* obj_to =
-      obj->untag()->to(Smi::Value(obj->untag()->length()));
-  uword heap_base = obj.heap_base();
-
-  const intptr_t size = card_table_size();
-  for (;;) {
-    intptr_t i = progress_bar_.fetch_add(1);
-    if (i >= size) break;
-
-    if (card_table_[i] != 0) {
-      CompressedObjectPtr* card_from =
-          reinterpret_cast<CompressedObjectPtr*>(this) +
-          (i << kSlotsPerCardLog2);
-      CompressedObjectPtr* card_to =
-          reinterpret_cast<CompressedObjectPtr*>(card_from) +
-          (1 << kSlotsPerCardLog2) - 1;
-      // Minus 1 because to is inclusive.
-
-      if (card_from < obj_from) {
-        // First card overlaps with header.
-        card_from = obj_from;
-      }
-      if (card_to > obj_to) {
-        // Last card(s) may extend past the object. Array truncation can make
-        // this happen for more than one card.
-        card_to = obj_to;
-      }
-
-      visitor->VisitCompressedPointers(heap_base, card_from, card_to);
-
-      bool has_new_target = false;
-      for (CompressedObjectPtr* slot = card_from; slot <= card_to; slot++) {
-        if ((*slot)->IsNewObjectMayBeSmi()) {
-          has_new_target = true;
-          break;
-        }
-      }
-
-      if (!has_new_target) {
-        card_table_[i] = 0;
-      }
-    }
-  }
-}
-
-void OldPage::ResetProgressBar() {
-  progress_bar_ = 0;
-}
-
-ObjectPtr OldPage::FindObject(FindObjectVisitor* visitor) const {
-  uword obj_addr = object_start();
-  uword end_addr = object_end();
-  if (visitor->VisitRange(obj_addr, end_addr)) {
-    while (obj_addr < end_addr) {
-      ObjectPtr raw_obj = UntaggedObject::FromAddr(obj_addr);
-      uword next_obj_addr = obj_addr + raw_obj->untag()->HeapSize();
-      if (visitor->VisitRange(obj_addr, next_obj_addr) &&
-          raw_obj->untag()->FindObject(visitor)) {
-        return raw_obj;  // Found object, return it.
-      }
-      obj_addr = next_obj_addr;
-    }
-    ASSERT(obj_addr == end_addr);
-  }
-  return Object::null();
-}
-
-void OldPage::WriteProtect(bool read_only) {
-  ASSERT(!is_image_page());
-
-  VirtualMemory::Protection prot;
-  if (read_only) {
-    if ((type_ == kExecutable) && (memory_->AliasOffset() == 0)) {
-      prot = VirtualMemory::kReadExecute;
-    } else {
-      prot = VirtualMemory::kReadOnly;
-    }
-  } else {
-    prot = VirtualMemory::kReadWrite;
-  }
-  memory_->Protect(prot);
-}
-
 // The initial estimate of how many words we can mark per microsecond (usage
 // before / mark-sweep time). This is a conservative value observed running
 // Flutter on a Nexus 4. After the first mark-sweep, we instead use a value
@@ -266,21 +92,21 @@
       ml.Wait();
     }
   }
-  FreePages(pages_);
-  FreePages(exec_pages_);
-  FreePages(large_pages_);
-  FreePages(image_pages_);
+  FreePages(pages_, /*can_use_cache*/ true);
+  FreePages(exec_pages_, /*can_use_cache*/ false);
+  FreePages(large_pages_, /*can_use_cache*/ false);
+  FreePages(image_pages_, /*can_use_cache*/ false);
   ASSERT(marker_ == NULL);
   delete[] freelists_;
 }
 
 intptr_t PageSpace::LargePageSizeInWordsFor(intptr_t size) {
-  intptr_t page_size = Utils::RoundUp(size + OldPage::ObjectStartOffset(),
+  intptr_t page_size = Utils::RoundUp(size + Page::OldObjectStartOffset(),
                                       VirtualMemory::PageSize());
   return page_size >> kWordSizeLog2;
 }
 
-void PageSpace::AddPageLocked(OldPage* page) {
+void PageSpace::AddPageLocked(Page* page) {
   if (pages_ == nullptr) {
     pages_ = page;
   } else {
@@ -289,7 +115,7 @@
   pages_tail_ = page;
 }
 
-void PageSpace::AddLargePageLocked(OldPage* page) {
+void PageSpace::AddLargePageLocked(Page* page) {
   if (large_pages_ == nullptr) {
     large_pages_ = page;
   } else {
@@ -298,7 +124,7 @@
   large_pages_tail_ = page;
 }
 
-void PageSpace::AddExecPageLocked(OldPage* page) {
+void PageSpace::AddExecPageLocked(Page* page) {
   if (exec_pages_ == nullptr) {
     exec_pages_ = page;
   } else {
@@ -313,7 +139,7 @@
   exec_pages_tail_ = page;
 }
 
-void PageSpace::RemovePageLocked(OldPage* page, OldPage* previous_page) {
+void PageSpace::RemovePageLocked(Page* page, Page* previous_page) {
   if (previous_page != NULL) {
     previous_page->set_next(page->next());
   } else {
@@ -324,7 +150,7 @@
   }
 }
 
-void PageSpace::RemoveLargePageLocked(OldPage* page, OldPage* previous_page) {
+void PageSpace::RemoveLargePageLocked(Page* page, Page* previous_page) {
   if (previous_page != NULL) {
     previous_page->set_next(page->next());
   } else {
@@ -335,7 +161,7 @@
   }
 }
 
-void PageSpace::RemoveExecPageLocked(OldPage* page, OldPage* previous_page) {
+void PageSpace::RemoveExecPageLocked(Page* page, Page* previous_page) {
   if (previous_page != NULL) {
     previous_page->set_next(page->next());
   } else {
@@ -346,20 +172,19 @@
   }
 }
 
-OldPage* PageSpace::AllocatePage(OldPage::PageType type, bool link) {
+Page* PageSpace::AllocatePage(Page::PageType type, bool link) {
   {
     MutexLocker ml(&pages_lock_);
-    if (!CanIncreaseCapacityInWordsLocked(kOldPageSizeInWords)) {
+    if (!CanIncreaseCapacityInWordsLocked(kPageSizeInWords)) {
       return nullptr;
     }
-    IncreaseCapacityInWordsLocked(kOldPageSizeInWords);
+    IncreaseCapacityInWordsLocked(kPageSizeInWords);
   }
-  const bool is_exec = (type == OldPage::kExecutable);
-  const char* name = Heap::RegionName(is_exec ? Heap::kCode : Heap::kOld);
-  OldPage* page = OldPage::Allocate(kOldPageSizeInWords, type, name);
+  const bool is_exec = (type == Page::kExecutable);
+  Page* page = Page::Allocate(kPageSize, type, /*can_use_cache*/ !is_exec);
   if (page == nullptr) {
     RELEASE_ASSERT(!FLAG_abort_on_oom);
-    IncreaseCapacityInWords(-kOldPageSizeInWords);
+    IncreaseCapacityInWords(-kPageSizeInWords);
     return nullptr;
   }
 
@@ -373,14 +198,14 @@
   }
 
   page->set_object_end(page->memory_->end());
-  if ((type != OldPage::kExecutable) && (heap_ != nullptr) &&
+  if ((type != Page::kExecutable) && (heap_ != nullptr) &&
       (!heap_->is_vm_isolate())) {
     page->AllocateForwardingPage();
   }
   return page;
 }
 
-OldPage* PageSpace::AllocateLargePage(intptr_t size, OldPage::PageType type) {
+Page* PageSpace::AllocateLargePage(intptr_t size, Page::PageType type) {
   const intptr_t page_size_in_words = LargePageSizeInWordsFor(size);
   {
     MutexLocker ml(&pages_lock_);
@@ -389,9 +214,9 @@
     }
     IncreaseCapacityInWordsLocked(page_size_in_words);
   }
-  const bool is_exec = (type == OldPage::kExecutable);
-  const char* name = Heap::RegionName(is_exec ? Heap::kCode : Heap::kOld);
-  OldPage* page = OldPage::Allocate(page_size_in_words, type, name);
+  const bool is_exec = (type == Page::kExecutable);
+  Page* page = Page::Allocate(page_size_in_words << kWordSizeLog2, type,
+                              /*can_use_cache*/ false);
 
   MutexLocker ml(&pages_lock_);
   if (page == nullptr) {
@@ -415,7 +240,7 @@
   return page;
 }
 
-void PageSpace::TruncateLargePage(OldPage* page,
+void PageSpace::TruncateLargePage(Page* page,
                                   intptr_t new_object_size_in_bytes) {
   const intptr_t old_object_size_in_bytes =
       page->object_end() - page->object_start();
@@ -431,8 +256,8 @@
   }
 }
 
-void PageSpace::FreePage(OldPage* page, OldPage* previous_page) {
-  bool is_exec = (page->type() == OldPage::kExecutable);
+void PageSpace::FreePage(Page* page, Page* previous_page) {
+  bool is_exec = (page->type() == Page::kExecutable);
   {
     MutexLocker ml(&pages_lock_);
     IncreaseCapacityInWordsLocked(-(page->memory_->size() >> kWordSizeLog2));
@@ -442,30 +267,29 @@
       RemovePageLocked(page, previous_page);
     }
   }
-  // TODO(iposva): Consider adding to a pool of empty pages.
-  page->Deallocate();
+  page->Deallocate(/*can_use_cache*/ !is_exec);
 }
 
-void PageSpace::FreeLargePage(OldPage* page, OldPage* previous_page) {
-  ASSERT(page->type() != OldPage::kExecutable);
+void PageSpace::FreeLargePage(Page* page, Page* previous_page) {
+  ASSERT(page->type() != Page::kExecutable);
   MutexLocker ml(&pages_lock_);
   IncreaseCapacityInWordsLocked(-(page->memory_->size() >> kWordSizeLog2));
   RemoveLargePageLocked(page, previous_page);
-  page->Deallocate();
+  page->Deallocate(/*can_use_cache*/ false);
 }
 
-void PageSpace::FreePages(OldPage* pages) {
-  OldPage* page = pages;
+void PageSpace::FreePages(Page* pages, bool can_use_cache) {
+  Page* page = pages;
   while (page != NULL) {
-    OldPage* next = page->next();
-    page->Deallocate();
+    Page* next = page->next();
+    page->Deallocate(can_use_cache);
     page = next;
   }
 }
 
 uword PageSpace::TryAllocateInFreshPage(intptr_t size,
                                         FreeList* freelist,
-                                        OldPage::PageType type,
+                                        Page::PageType type,
                                         GrowthPolicy growth_policy,
                                         bool is_locked) {
   ASSERT(Heap::IsAllocatableViaFreeLists(size));
@@ -474,7 +298,7 @@
     ASSERT(!Thread::Current()->force_growth());
     if (heap_ != nullptr) {  // Some unit tests.
       heap_->CheckConcurrentMarking(Thread::Current(), GCReason::kOldSpace,
-                                    kOldPageSize);
+                                    kPageSize);
     }
   }
 
@@ -482,10 +306,10 @@
   SpaceUsage after_allocation = GetCurrentUsage();
   after_allocation.used_in_words += size >> kWordSizeLog2;
   // Can we grow by one page?
-  after_allocation.capacity_in_words += kOldPageSizeInWords;
+  after_allocation.capacity_in_words += kPageSizeInWords;
   if (growth_policy == kForceGrowth ||
       !page_space_controller_.ReachedHardThreshold(after_allocation)) {
-    OldPage* page = AllocatePage(type);
+    Page* page = AllocatePage(type);
     if (page == NULL) {
       return 0;
     }
@@ -508,7 +332,7 @@
 }
 
 uword PageSpace::TryAllocateInFreshLargePage(intptr_t size,
-                                             OldPage::PageType type,
+                                             Page::PageType type,
                                              GrowthPolicy growth_policy) {
   ASSERT(!Heap::IsAllocatableViaFreeLists(size));
 
@@ -532,7 +356,7 @@
   after_allocation.capacity_in_words += page_size_in_words;
   if (growth_policy == kForceGrowth ||
       !page_space_controller_.ReachedHardThreshold(after_allocation)) {
-    OldPage* page = AllocateLargePage(size, type);
+    Page* page = AllocateLargePage(size, type);
     if (page != NULL) {
       result = page->object_start();
       // Note: usage_.capacity_in_words is increased by AllocateLargePage.
@@ -544,7 +368,7 @@
 
 uword PageSpace::TryAllocateInternal(intptr_t size,
                                      FreeList* freelist,
-                                     OldPage::PageType type,
+                                     Page::PageType type,
                                      GrowthPolicy growth_policy,
                                      bool is_protected,
                                      bool is_locked) {
@@ -586,7 +410,7 @@
  public:
   explicit BasePageIterator(const PageSpace* space) : space_(space) {}
 
-  OldPage* page() const { return page_; }
+  Page* page() const { return page_; }
 
   bool Done() const { return page_ == NULL; }
 
@@ -630,7 +454,7 @@
 
   const PageSpace* space_ = nullptr;
   List list_;
-  OldPage* page_ = nullptr;
+  Page* page_ = nullptr;
 };
 
 // Provides unsafe access to all pages. Assumes pages are walkable.
@@ -665,7 +489,7 @@
     space_->MakeIterable();
     page_ = space_->exec_pages_;
   }
-  OldPage* page() const { return page_; }
+  Page* page() const { return page_; }
   bool Done() const { return page_ == NULL; }
   void Advance() {
     ASSERT(!Done());
@@ -676,7 +500,7 @@
   const PageSpace* space_;
   MutexLocker ml_;
   NoSafepointScope no_safepoint;
-  OldPage* page_;
+  Page* page_;
 };
 
 void PageSpace::MakeIterable() const {
@@ -740,8 +564,8 @@
   return false;
 }
 
-bool PageSpace::Contains(uword addr, OldPage::PageType type) const {
-  if (type == OldPage::kExecutable) {
+bool PageSpace::Contains(uword addr, Page::PageType type) const {
+  if (type == Page::kExecutable) {
     // Fast path executable pages.
     for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) {
       if (it.page()->Contains(addr)) {
@@ -760,8 +584,7 @@
 
 bool PageSpace::DataContains(uword addr) const {
   for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
-    if ((it.page()->type() != OldPage::kExecutable) &&
-        it.page()->Contains(addr)) {
+    if ((it.page()->type() != Page::kExecutable) && it.page()->Contains(addr)) {
       return true;
     }
   }
@@ -818,9 +641,9 @@
   // Large pages may be added concurrently due to promotion in another scavenge
   // worker, so terminate the traversal when we hit the tail we saw while
   // holding the pages lock, instead of at NULL, otherwise we are racing when we
-  // read OldPage::next_ and OldPage::remembered_cards_.
-  OldPage* page;
-  OldPage* tail;
+  // read Page::next_ and Page::remembered_cards_.
+  Page* page;
+  Page* tail;
   {
     MutexLocker ml(&pages_lock_);
     page = large_pages_;
@@ -834,14 +657,14 @@
 }
 
 void PageSpace::ResetProgressBars() const {
-  for (OldPage* page = large_pages_; page != NULL; page = page->next()) {
+  for (Page* page = large_pages_; page != NULL; page = page->next()) {
     page->ResetProgressBar();
   }
 }
 
 ObjectPtr PageSpace::FindObject(FindObjectVisitor* visitor,
-                                OldPage::PageType type) const {
-  if (type == OldPage::kExecutable) {
+                                Page::PageType type) const {
+  if (type == Page::kExecutable) {
     // Fast path executable pages.
     for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) {
       ObjectPtr obj = it.page()->FindObject(visitor);
@@ -920,7 +743,7 @@
   heap_map.AddProperty("freeClassId", static_cast<intptr_t>(kFreeListElement));
   heap_map.AddProperty("unitSizeBytes",
                        static_cast<intptr_t>(kObjectAlignment));
-  heap_map.AddProperty("pageSizeBytes", kOldPageSizeInWords * kWordSize);
+  heap_map.AddProperty("pageSizeBytes", kPageSizeInWords * kWordSize);
   {
     JSONObject class_list(&heap_map, "classList");
     isolate_group->class_table()->PrintToJSONObject(&class_list);
@@ -933,7 +756,7 @@
     MutexLocker ml(&pages_lock_);
     MakeIterable();
     JSONArray all_pages(&heap_map, "pages");
-    for (OldPage* page = pages_; page != NULL; page = page->next()) {
+    for (Page* page = pages_; page != NULL; page = page->next()) {
       JSONObject page_container(&all_pages);
       page_container.AddPropertyF("objectStart", "0x%" Px "",
                                   page->object_start());
@@ -941,7 +764,7 @@
       HeapMapAsJSONVisitor printer(&page_map);
       page->VisitObjects(&printer);
     }
-    for (OldPage* page = exec_pages_; page != NULL; page = page->next()) {
+    for (Page* page = exec_pages_; page != NULL; page = page->next()) {
       JSONObject page_container(&all_pages);
       page_container.AddPropertyF("objectStart", "0x%" Px "",
                                   page->object_start());
@@ -958,15 +781,15 @@
     MutexLocker ml(&pages_lock_);
     NoSafepointScope no_safepoint;
     // No need to go through all of the data pages first.
-    OldPage* page = exec_pages_;
+    Page* page = exec_pages_;
     while (page != NULL) {
-      ASSERT(page->type() == OldPage::kExecutable);
+      ASSERT(page->type() == Page::kExecutable);
       page->WriteProtect(read_only);
       page = page->next();
     }
     page = large_pages_;
     while (page != NULL) {
-      if (page->type() == OldPage::kExecutable) {
+      if (page->type() == Page::kExecutable) {
         page->WriteProtect(read_only);
       }
       page = page->next();
@@ -1009,7 +832,7 @@
   // Discount two pages to account for the newest data and code pages, whose
   // partial use doesn't indicate fragmentation.
   const intptr_t excess_in_words =
-      usage_.capacity_in_words - usage_.used_in_words - 2 * kOldPageSizeInWords;
+      usage_.capacity_in_words - usage_.used_in_words - 2 * kPageSizeInWords;
   const double excess_ratio = static_cast<double>(excess_in_words) /
                               static_cast<double>(usage_.capacity_in_words);
   const bool fragmented = excess_ratio > 0.05;
@@ -1073,7 +896,7 @@
   uword addr = reinterpret_cast<uword>(oom_reservation_);
   intptr_t size = oom_reservation_->HeapSize();
   oom_reservation_ = nullptr;
-  freelists_[OldPage::kData].Free(addr, size);
+  freelists_[Page::kData].Free(addr, size);
 }
 
 bool PageSpace::MarkReservation() {
@@ -1089,7 +912,7 @@
 
 void PageSpace::TryReserveForOOM() {
   if (oom_reservation_ == nullptr) {
-    uword addr = TryAllocate(kOOMReservationSize, OldPage::kData,
+    uword addr = TryAllocate(kOOMReservationSize, Page::kData,
                              kForceGrowth /* Don't re-enter GC */);
     if (addr != 0) {
       oom_reservation_ = FreeListElement::AsElement(addr, kOOMReservationSize);
@@ -1164,7 +987,7 @@
   const int64_t start = OS::GetCurrentMonotonicMicros();
 
   // Perform various cleanup that relies on no tasks interfering.
-  isolate_group->shared_class_table()->FreeOldTables();
+  isolate_group->class_table_allocator()->FreePending();
   isolate_group->ForEachIsolate(
       [&](Isolate* isolate) { isolate->field_table()->FreeOldTables(); },
       /*at_safepoint=*/true);
@@ -1229,12 +1052,12 @@
     // code protection.
     TIMELINE_FUNCTION_GC_DURATION(thread, "SweepExecutable");
     GCSweeper sweeper;
-    OldPage* prev_page = NULL;
-    OldPage* page = exec_pages_;
-    FreeList* freelist = &freelists_[OldPage::kExecutable];
+    Page* prev_page = NULL;
+    Page* page = exec_pages_;
+    FreeList* freelist = &freelists_[Page::kExecutable];
     MutexLocker ml(freelist->mutex());
     while (page != NULL) {
-      OldPage* next_page = page->next();
+      Page* next_page = page->next();
       bool page_in_use = sweeper.SweepPage(page, freelist, true /*is_locked*/);
       if (page_in_use) {
         prev_page = page;
@@ -1313,17 +1136,17 @@
   GCSweeper sweeper;
   MutexLocker ml(&pages_lock_);
   while (sweep_large_ != nullptr) {
-    OldPage* page = sweep_large_;
+    Page* page = sweep_large_;
     sweep_large_ = page->next();
     page->set_next(nullptr);
-    ASSERT(page->type() == OldPage::kData);
+    ASSERT(page->type() == Page::kData);
 
     ml.Unlock();
     intptr_t words_to_end = sweeper.SweepLargePage(page);
     intptr_t size;
     if (words_to_end == 0) {
       size = page->memory_->size();
-      page->Deallocate();
+      page->Deallocate(/*can_use_cache*/ false);
       ml.Lock();
       IncreaseCapacityInWordsLocked(-(size >> kWordSizeLog2));
     } else {
@@ -1349,10 +1172,10 @@
 
   MutexLocker ml(&pages_lock_);
   while (sweep_regular_ != nullptr) {
-    OldPage* page = sweep_regular_;
+    Page* page = sweep_regular_;
     sweep_regular_ = page->next();
     page->set_next(nullptr);
-    ASSERT(page->type() == OldPage::kData);
+    ASSERT(page->type() == Page::kData);
 
     ml.Unlock();
     // Cycle through the shards round-robin so that free space is roughly
@@ -1363,7 +1186,7 @@
     intptr_t size;
     if (!page_in_use) {
       size = page->memory_->size();
-      page->Deallocate();
+      page->Deallocate(/*can_use_cache*/ true);
     }
     ml.Lock();
 
@@ -1389,7 +1212,7 @@
 void PageSpace::Compact(Thread* thread) {
   thread->isolate_group()->set_compaction_in_progress(true);
   GCCompactor compactor(thread, heap_);
-  compactor.Compact(pages_, &freelists_[OldPage::kData], &pages_lock_);
+  compactor.Compact(pages_, &freelists_[Page::kData], &pages_lock_);
   thread->isolate_group()->set_compaction_in_progress(false);
 
   if (FLAG_verify_after_gc) {
@@ -1415,8 +1238,8 @@
       // side-effect of populating the freelist with a large block. The next
       // bump allocation request will have a chance to consume that block.
       // TODO(koda): Could take freelist lock just once instead of twice.
-      return TryAllocateInFreshPage(size, freelist, OldPage::kData,
-                                    kForceGrowth, true /* is_locked*/);
+      return TryAllocateInFreshPage(size, freelist, Page::kData, kForceGrowth,
+                                    true /* is_locked*/);
     }
     intptr_t block_size = block->HeapSize();
     if (remaining > 0) {
@@ -1462,30 +1285,29 @@
 }
 
 void PageSpace::SetupImagePage(void* pointer, uword size, bool is_executable) {
-  // Setup a OldPage so precompiled Instructions can be traversed.
-  // Instructions are contiguous at [pointer, pointer + size). OldPage
+  // Setup a Page so precompiled Instructions can be traversed.
+  // Instructions are contiguous at [pointer, pointer + size). Page
   // expects to find objects at [memory->start() + ObjectStartOffset,
   // memory->end()).
-  uword offset = OldPage::ObjectStartOffset();
+  uword offset = Page::OldObjectStartOffset();
   pointer = reinterpret_cast<void*>(reinterpret_cast<uword>(pointer) - offset);
   ASSERT(Utils::IsAligned(pointer, kObjectAlignment));
   size += offset;
 
   VirtualMemory* memory = VirtualMemory::ForImagePage(pointer, size);
   ASSERT(memory != NULL);
-  OldPage* page = reinterpret_cast<OldPage*>(malloc(sizeof(OldPage)));
+  Page* page = reinterpret_cast<Page*>(malloc(sizeof(Page)));
+  page->type_ = is_executable ? Page::kExecutable : Page::kData;
   page->memory_ = memory;
-  page->next_ = NULL;
-  page->object_end_ = memory->end();
-  page->used_in_bytes_ = page->object_end_ - page->object_start();
-  page->forwarding_page_ = NULL;
-  page->card_table_ = NULL;
+  page->next_ = nullptr;
+  page->forwarding_page_ = nullptr;
+  page->card_table_ = nullptr;
   page->progress_bar_ = 0;
-  if (is_executable) {
-    page->type_ = OldPage::kExecutable;
-  } else {
-    page->type_ = OldPage::kData;
-  }
+  page->owner_ = nullptr;
+  page->top_ = memory->end();
+  page->end_ = memory->end();
+  page->survivor_end_ = 0;
+  page->resolved_top_ = 0;
 
   MutexLocker ml(&pages_lock_);
   page->next_ = image_pages_;
@@ -1494,7 +1316,7 @@
 
 bool PageSpace::IsObjectFromImagePages(dart::ObjectPtr object) {
   uword object_addr = UntaggedObject::ToAddr(object);
-  OldPage* image_page = image_pages_;
+  Page* image_page = image_pages_;
   while (image_page != nullptr) {
     if (image_page->Contains(object_addr)) {
       return true;
@@ -1585,7 +1407,7 @@
         (static_cast<intptr_t>(after.CombinedUsedInWords() /
                                desired_utilization_) -
          (after.CombinedUsedInWords())) /
-        kOldPageSizeInWords;
+        kPageSizeInWords;
     if (garbage_ratio == 0) {
       // No garbage in the previous cycle so it would be hard to compute a
       // grow_heap size based on estimated garbage so we use growth ratio
@@ -1600,8 +1422,8 @@
       intptr_t local_grow_heap = 0;
       while (min < max) {
         local_grow_heap = (max + min) / 2;
-        const intptr_t limit = after.CombinedUsedInWords() +
-                               (local_grow_heap * kOldPageSizeInWords);
+        const intptr_t limit =
+            after.CombinedUsedInWords() + (local_grow_heap * kPageSizeInWords);
         const intptr_t allocated_before_next_gc =
             limit - (after.CombinedUsedInWords());
         const double estimated_garbage = k * allocated_before_next_gc;
@@ -1630,7 +1452,7 @@
     ASSERT(grow_heap >= 0);
     // Fraction of asymptote used.
     double f = static_cast<double>(after.CombinedUsedInWords() +
-                                   (kOldPageSizeInWords * grow_heap)) /
+                                   (kPageSizeInWords * grow_heap)) /
                static_cast<double>(max_capacity_in_words);
     ASSERT(f >= 0.0);
     // Increase weight at the high end.
@@ -1641,7 +1463,7 @@
     // Discount growth more the closer we get to the desired asymptote.
     grow_heap = static_cast<intptr_t>(grow_heap * f);
     // Minimum growth step after reaching the asymptote.
-    intptr_t min_step = (2 * MB) / kOldPageSize;
+    intptr_t min_step = (2 * MB) / kPageSize;
     grow_heap = Utils::Maximum(min_step, grow_heap);
   }
 
@@ -1658,7 +1480,7 @@
     growth_in_pages = (static_cast<intptr_t>(after.CombinedUsedInWords() /
                                              desired_utilization_) -
                        (after.CombinedUsedInWords())) /
-                      kOldPageSizeInWords;
+                      kPageSizeInWords;
   }
 
   // Apply growth cap.
@@ -1674,7 +1496,7 @@
                                        const char* reason) {
   // Save final threshold compared before growing.
   intptr_t threshold =
-      after.CombinedUsedInWords() + (kOldPageSizeInWords * growth_in_pages);
+      after.CombinedUsedInWords() + (kPageSizeInWords * growth_in_pages);
 
 #if defined(TARGET_ARCH_IA32)
   bool concurrent_mark = false;
@@ -1691,7 +1513,7 @@
 
   // Set a tight idle threshold.
   idle_gc_threshold_in_words_ =
-      after.CombinedUsedInWords() + (2 * kOldPageSizeInWords);
+      after.CombinedUsedInWords() + (2 * kPageSizeInWords);
 
 #if defined(SUPPORT_TIMELINE)
   Thread* thread = Thread::Current();
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index 36e8ab2..406cded 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -8,6 +8,7 @@
 #include "platform/atomic.h"
 #include "vm/globals.h"
 #include "vm/heap/freelist.h"
+#include "vm/heap/page.h"
 #include "vm/heap/spaces.h"
 #include "vm/lockers.h"
 #include "vm/ring_buffer.h"
@@ -26,196 +27,6 @@
 class ForwardingPage;
 class GCMarker;
 
-static constexpr intptr_t kOldPageSize = 512 * KB;
-static constexpr intptr_t kOldPageSizeInWords = kOldPageSize / kWordSize;
-static constexpr intptr_t kOldPageMask = ~(kOldPageSize - 1);
-
-static constexpr intptr_t kBitVectorWordsPerBlock = 1;
-static constexpr intptr_t kBlockSize =
-    kObjectAlignment * kBitsPerWord * kBitVectorWordsPerBlock;
-static constexpr intptr_t kBlockMask = ~(kBlockSize - 1);
-static constexpr intptr_t kBlocksPerPage = kOldPageSize / kBlockSize;
-
-// A page containing old generation objects.
-class OldPage {
- public:
-  enum PageType { kExecutable = 0, kData };
-
-  OldPage* next() const { return next_; }
-  void set_next(OldPage* next) { next_ = next; }
-
-  bool Contains(uword addr) const { return memory_->Contains(addr); }
-  intptr_t AliasOffset() const { return memory_->AliasOffset(); }
-
-  uword object_start() const { return memory_->start() + ObjectStartOffset(); }
-  uword object_end() const { return object_end_; }
-  uword used_in_bytes() const { return used_in_bytes_; }
-  void set_used_in_bytes(uword value) {
-    ASSERT(Utils::IsAligned(value, kObjectAlignment));
-    used_in_bytes_ = value;
-  }
-
-  ForwardingPage* forwarding_page() const { return forwarding_page_; }
-  void AllocateForwardingPage();
-
-  PageType type() const { return type_; }
-
-  bool is_image_page() const { return !memory_->vm_owns_region(); }
-
-  void VisitObjects(ObjectVisitor* visitor) const;
-  void VisitObjectPointers(ObjectPointerVisitor* visitor) const;
-
-  ObjectPtr FindObject(FindObjectVisitor* visitor) const;
-
-  void WriteProtect(bool read_only);
-
-  static intptr_t ObjectStartOffset() {
-    return Utils::RoundUp(sizeof(OldPage), kMaxObjectAlignment);
-  }
-
-  // Warning: This does not work for objects on image pages because image pages
-  // are not aligned. However, it works for objects on large pages, because
-  // only one object is allocated per large page.
-  static OldPage* Of(ObjectPtr obj) {
-    ASSERT(obj->IsHeapObject());
-    ASSERT(obj->IsOldObject());
-    return reinterpret_cast<OldPage*>(static_cast<uword>(obj) & kOldPageMask);
-  }
-
-  // Warning: This does not work for addresses on image pages or on large pages.
-  static OldPage* Of(uword addr) {
-    return reinterpret_cast<OldPage*>(addr & kOldPageMask);
-  }
-
-  // Warning: This does not work for objects on image pages.
-  static ObjectPtr ToExecutable(ObjectPtr obj) {
-    OldPage* page = Of(obj);
-    VirtualMemory* memory = page->memory_;
-    const intptr_t alias_offset = memory->AliasOffset();
-    if (alias_offset == 0) {
-      return obj;  // Not aliased.
-    }
-    uword addr = UntaggedObject::ToAddr(obj);
-    if (memory->Contains(addr)) {
-      return UntaggedObject::FromAddr(addr + alias_offset);
-    }
-    // obj is executable.
-    ASSERT(memory->ContainsAlias(addr));
-    return obj;
-  }
-
-  // Warning: This does not work for objects on image pages.
-  static ObjectPtr ToWritable(ObjectPtr obj) {
-    OldPage* page = Of(obj);
-    VirtualMemory* memory = page->memory_;
-    const intptr_t alias_offset = memory->AliasOffset();
-    if (alias_offset == 0) {
-      return obj;  // Not aliased.
-    }
-    uword addr = UntaggedObject::ToAddr(obj);
-    if (memory->ContainsAlias(addr)) {
-      return UntaggedObject::FromAddr(addr - alias_offset);
-    }
-    // obj is writable.
-    ASSERT(memory->Contains(addr));
-    return obj;
-  }
-
-  // 1 card = 128 slots.
-  static const intptr_t kSlotsPerCardLog2 = 7;
-  static const intptr_t kBytesPerCardLog2 =
-      kCompressedWordSizeLog2 + kSlotsPerCardLog2;
-
-  intptr_t card_table_size() const {
-    return memory_->size() >> kBytesPerCardLog2;
-  }
-
-  static intptr_t card_table_offset() {
-    return OFFSET_OF(OldPage, card_table_);
-  }
-
-  void RememberCard(ObjectPtr const* slot) {
-    ASSERT(Contains(reinterpret_cast<uword>(slot)));
-    if (card_table_ == NULL) {
-      card_table_ = reinterpret_cast<uint8_t*>(
-          calloc(card_table_size(), sizeof(uint8_t)));
-    }
-    intptr_t offset =
-        reinterpret_cast<uword>(slot) - reinterpret_cast<uword>(this);
-    intptr_t index = offset >> kBytesPerCardLog2;
-    ASSERT((index >= 0) && (index < card_table_size()));
-    card_table_[index] = 1;
-  }
-  bool IsCardRemembered(ObjectPtr const* slot) {
-    ASSERT(Contains(reinterpret_cast<uword>(slot)));
-    if (card_table_ == NULL) {
-      return false;
-    }
-    intptr_t offset =
-        reinterpret_cast<uword>(slot) - reinterpret_cast<uword>(this);
-    intptr_t index = offset >> kBytesPerCardLog2;
-    ASSERT((index >= 0) && (index < card_table_size()));
-    return card_table_[index] != 0;
-  }
-#if defined(DART_COMPRESSED_POINTERS)
-  void RememberCard(CompressedObjectPtr const* slot) {
-    ASSERT(Contains(reinterpret_cast<uword>(slot)));
-    if (card_table_ == NULL) {
-      card_table_ = reinterpret_cast<uint8_t*>(
-          calloc(card_table_size(), sizeof(uint8_t)));
-    }
-    intptr_t offset =
-        reinterpret_cast<uword>(slot) - reinterpret_cast<uword>(this);
-    intptr_t index = offset >> kBytesPerCardLog2;
-    ASSERT((index >= 0) && (index < card_table_size()));
-    card_table_[index] = 1;
-  }
-  bool IsCardRemembered(CompressedObjectPtr const* slot) {
-    ASSERT(Contains(reinterpret_cast<uword>(slot)));
-    if (card_table_ == NULL) {
-      return false;
-    }
-    intptr_t offset =
-        reinterpret_cast<uword>(slot) - reinterpret_cast<uword>(this);
-    intptr_t index = offset >> kBytesPerCardLog2;
-    ASSERT((index >= 0) && (index < card_table_size()));
-    return card_table_[index] != 0;
-  }
-#endif
-  void VisitRememberedCards(ObjectPointerVisitor* visitor);
-  void ResetProgressBar();
-
- private:
-  void set_object_end(uword value) {
-    ASSERT((value & kObjectAlignmentMask) == kOldObjectAlignmentOffset);
-    object_end_ = value;
-  }
-
-  // Returns NULL on OOM.
-  static OldPage* Allocate(intptr_t size_in_words,
-                           PageType type,
-                           const char* name);
-
-  // Deallocate the virtual memory backing this page. The page pointer to this
-  // page becomes immediately inaccessible.
-  void Deallocate();
-
-  VirtualMemory* memory_;
-  OldPage* next_;
-  uword object_end_;
-  uword used_in_bytes_;
-  ForwardingPage* forwarding_page_;
-  uint8_t* card_table_;  // Remembered set, not marking.
-  RelaxedAtomic<intptr_t> progress_bar_;
-  PageType type_;
-
-  friend class PageSpace;
-  friend class GCCompactor;
-
-  DISALLOW_ALLOCATION();
-  DISALLOW_IMPLICIT_CONSTRUCTORS(OldPage);
-};
-
 // The history holds the timing information of the last garbage collection
 // runs.
 class PageSpaceGarbageCollectionHistory {
@@ -328,10 +139,9 @@
   ~PageSpace();
 
   uword TryAllocate(intptr_t size,
-                    OldPage::PageType type = OldPage::kData,
+                    Page::PageType type = Page::kData,
                     GrowthPolicy growth_policy = kControlGrowth) {
-    bool is_protected =
-        (type == OldPage::kExecutable) && FLAG_write_protect_code;
+    bool is_protected = (type == Page::kExecutable) && FLAG_write_protect_code;
     bool is_locked = false;
     return TryAllocateInternal(size, &freelists_[type], type, growth_policy,
                                is_protected, is_locked);
@@ -381,7 +191,7 @@
   int64_t ImageInWords() const {
     int64_t size = 0;
     MutexLocker ml(&pages_lock_);
-    for (OldPage* page = image_pages_; page != nullptr; page = page->next()) {
+    for (Page* page = image_pages_; page != nullptr; page = page->next()) {
       size += page->memory_->size();
     }
     return size >> kWordSizeLog2;
@@ -389,7 +199,7 @@
 
   bool Contains(uword addr) const;
   bool ContainsUnsafe(uword addr) const;
-  bool Contains(uword addr, OldPage::PageType type) const;
+  bool Contains(uword addr, Page::PageType type) const;
   bool DataContains(uword addr) const;
   bool IsValidAddress(uword addr) const { return Contains(addr); }
 
@@ -401,8 +211,7 @@
   void VisitRememberedCards(ObjectPointerVisitor* visitor) const;
   void ResetProgressBars() const;
 
-  ObjectPtr FindObject(FindObjectVisitor* visitor,
-                       OldPage::PageType type) const;
+  ObjectPtr FindObject(FindObjectVisitor* visitor, Page::PageType type) const;
 
   // Collect the garbage in the page space using mark-sweep or mark-compact.
   void CollectGarbage(Thread* thread, bool compact, bool finalize);
@@ -438,10 +247,19 @@
     allocated_black_in_words_.fetch_add(size >> kWordSizeLog2);
   }
 
-  void AllocatedExternal(intptr_t size) {
+  // Tracks an external allocation by incrementing the old space's total
+  // external size tracker. Returns false without incrementing the tracker if
+  // this allocation will make it exceed kMaxAddrSpaceInWords.
+  bool AllocatedExternal(intptr_t size) {
     ASSERT(size >= 0);
     intptr_t size_in_words = size >> kWordSizeLog2;
-    usage_.external_in_words += size_in_words;
+    intptr_t next_external_in_words = usage_.external_in_words + size_in_words;
+    if (next_external_in_words < 0 ||
+        next_external_in_words > kMaxAddrSpaceInWords) {
+      return false;
+    }
+    usage_.external_in_words = next_external_in_words;
+    return true;
   }
   void FreedExternal(intptr_t size) {
     ASSERT(size >= 0);
@@ -451,7 +269,7 @@
 
   // Bulk data allocation.
   FreeList* DataFreeList(intptr_t i = 0) {
-    return &freelists_[OldPage::kData + i];
+    return &freelists_[Page::kData + i];
   }
   void AcquireLock(FreeList* freelist);
   void ReleaseLock(FreeList* freelist);
@@ -461,7 +279,7 @@
                               GrowthPolicy growth_policy) {
     bool is_protected = false;
     bool is_locked = true;
-    return TryAllocateInternal(size, freelist, OldPage::kData, growth_policy,
+    return TryAllocateInternal(size, freelist, Page::kData, growth_policy,
                                is_protected, is_locked);
   }
 
@@ -481,7 +299,7 @@
 
   // Attempt to allocate from bump block rather than normal freelist.
   uword TryAllocateDataBumpLocked(intptr_t size) {
-    return TryAllocateDataBumpLocked(&freelists_[OldPage::kData], size);
+    return TryAllocateDataBumpLocked(&freelists_[Page::kData], size);
   }
   uword TryAllocateDataBumpLocked(FreeList* freelist, intptr_t size);
   DART_FORCE_INLINE
@@ -523,36 +341,36 @@
 
   uword TryAllocateInternal(intptr_t size,
                             FreeList* freelist,
-                            OldPage::PageType type,
+                            Page::PageType type,
                             GrowthPolicy growth_policy,
                             bool is_protected,
                             bool is_locked);
   uword TryAllocateInFreshPage(intptr_t size,
                                FreeList* freelist,
-                               OldPage::PageType type,
+                               Page::PageType type,
                                GrowthPolicy growth_policy,
                                bool is_locked);
   uword TryAllocateInFreshLargePage(intptr_t size,
-                                    OldPage::PageType type,
+                                    Page::PageType type,
                                     GrowthPolicy growth_policy);
 
   // Makes bump block walkable; do not call concurrently with mutator.
   void MakeIterable() const;
 
-  void AddPageLocked(OldPage* page);
-  void AddLargePageLocked(OldPage* page);
-  void AddExecPageLocked(OldPage* page);
-  void RemovePageLocked(OldPage* page, OldPage* previous_page);
-  void RemoveLargePageLocked(OldPage* page, OldPage* previous_page);
-  void RemoveExecPageLocked(OldPage* page, OldPage* previous_page);
+  void AddPageLocked(Page* page);
+  void AddLargePageLocked(Page* page);
+  void AddExecPageLocked(Page* page);
+  void RemovePageLocked(Page* page, Page* previous_page);
+  void RemoveLargePageLocked(Page* page, Page* previous_page);
+  void RemoveExecPageLocked(Page* page, Page* previous_page);
 
-  OldPage* AllocatePage(OldPage::PageType type, bool link = true);
-  OldPage* AllocateLargePage(intptr_t size, OldPage::PageType type);
+  Page* AllocatePage(Page::PageType type, bool link = true);
+  Page* AllocateLargePage(intptr_t size, Page::PageType type);
 
-  void TruncateLargePage(OldPage* page, intptr_t new_object_size_in_bytes);
-  void FreePage(OldPage* page, OldPage* previous_page);
-  void FreeLargePage(OldPage* page, OldPage* previous_page);
-  void FreePages(OldPage* pages);
+  void TruncateLargePage(Page* page, intptr_t new_object_size_in_bytes);
+  void FreePage(Page* page, Page* previous_page);
+  void FreeLargePage(Page* page, Page* previous_page);
+  void FreePages(Page* pages, bool can_use_cache);
 
   void CollectGarbageHelper(Thread* thread, bool compact, bool finalize);
   void SweepLarge();
@@ -575,9 +393,9 @@
 
   Heap* const heap_;
 
-  // One list for executable pages at freelists_[OldPage::kExecutable].
+  // One list for executable pages at freelists_[Page::kExecutable].
   // FLAG_scavenger_tasks count of lists for data pages starting at
-  // freelists_[OldPage::kData]. The sweeper inserts into the data page
+  // freelists_[Page::kData]. The sweeper inserts into the data page
   // freelists round-robin. The scavenger workers each use one of the data
   // page freelists without locking.
   const intptr_t num_freelists_;
@@ -587,15 +405,15 @@
 
   // Use ExclusivePageIterator for safe access to these.
   mutable Mutex pages_lock_;
-  OldPage* pages_ = nullptr;
-  OldPage* pages_tail_ = nullptr;
-  OldPage* exec_pages_ = nullptr;
-  OldPage* exec_pages_tail_ = nullptr;
-  OldPage* large_pages_ = nullptr;
-  OldPage* large_pages_tail_ = nullptr;
-  OldPage* image_pages_ = nullptr;
-  OldPage* sweep_regular_ = nullptr;
-  OldPage* sweep_large_ = nullptr;
+  Page* pages_ = nullptr;
+  Page* pages_tail_ = nullptr;
+  Page* exec_pages_ = nullptr;
+  Page* exec_pages_tail_ = nullptr;
+  Page* large_pages_ = nullptr;
+  Page* large_pages_tail_ = nullptr;
+  Page* image_pages_ = nullptr;
+  Page* sweep_regular_ = nullptr;
+  Page* sweep_large_ = nullptr;
 
   // Various sizes being tracked for this generation.
   intptr_t max_capacity_in_words_;
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index 6b9d191..860825a 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -237,7 +237,7 @@
     ASSERT((obj == nullptr) || obj->IsOldObject());
     visiting_old_object_ = obj;
     if (obj != nullptr) {
-      // Card update happens in OldPage::VisitRememberedCards.
+      // Card update happens in Page::VisitRememberedCards.
       ASSERT(!obj->untag()->IsCardRemembered());
     }
   }
@@ -300,7 +300,7 @@
     if (!scavenger_->abort_) {
       ASSERT(!HasWork());
 
-      for (NewPage* page = head_; page != nullptr; page = page->next()) {
+      for (Page* page = head_; page != nullptr; page = page->next()) {
         ASSERT(page->IsResolved());
         page->RecordSurvivors();
       }
@@ -320,8 +320,12 @@
     delayed_.Release();
   }
 
-  NewPage* head() const { return head_; }
-  NewPage* tail() const { return tail_; }
+  Page* head() const {
+    return head_;
+  }
+  Page* tail() const {
+    return tail_;
+  }
 
   static bool ForwardOrSetNullIfCollected(uword heap_base,
                                           CompressedObjectPtr* ptr_address);
@@ -403,7 +407,7 @@
       intptr_t size = raw_obj->untag()->HeapSize(header);
       uword new_addr = 0;
       // Check whether object should be promoted.
-      if (!NewPage::Of(raw_obj)->IsSurvivor(raw_addr)) {
+      if (!Page::Of(raw_obj)->IsSurvivor(raw_addr)) {
         // Not a survivor of a previous scavenge. Just copy the object into the
         // to space.
         new_addr = TryAllocateCopy(size);
@@ -542,9 +546,9 @@
   PromotionWorkList promoted_list_;
   GCLinkedLists delayed_;
 
-  NewPage* head_ = nullptr;
-  NewPage* tail_ = nullptr;  // Allocating from here.
-  NewPage* scan_ = nullptr;  // Resolving from here.
+  Page* head_ = nullptr;
+  Page* tail_ = nullptr;  // Allocating from here.
+  Page* scan_ = nullptr;  // Resolving from here.
 
   template <typename GCVisitorType>
   friend void MournFinalized(GCVisitorType* visitor);
@@ -560,7 +564,7 @@
   ScavengerWeakVisitor(Thread* thread, Scavenger* scavenger)
       : HandleVisitor(thread),
         scavenger_(scavenger),
-        class_table_(thread->isolate_group()->shared_class_table()) {
+        class_table_(thread->isolate_group()->class_table()) {
     ASSERT(scavenger->heap_->isolate_group() == thread->isolate_group());
   }
 
@@ -577,7 +581,7 @@
 
  private:
   Scavenger* scavenger_;
-  SharedClassTable* class_table_;
+  ClassTable* class_table_;
 
   DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor);
 };
@@ -674,121 +678,23 @@
     : max_capacity_in_words_(max_capacity_in_words), head_(nullptr) {}
 
 SemiSpace::~SemiSpace() {
-  NewPage* page = head_;
+  Page* page = head_;
   while (page != nullptr) {
-    NewPage* next = page->next();
-    page->Deallocate();
+    Page* next = page->next();
+    page->Deallocate(/*can_use_cache*/ true);
     page = next;
   }
 }
 
-// TODO(rmacnak): Unify this with old-space pages, and possibly zone segments.
-// This cache needs to be at least as big as FLAG_new_gen_semi_max_size or
-// munmap will noticably impact performance.
-static constexpr intptr_t kPageCacheCapacity = 8 * kWordSize;
-static Mutex* page_cache_mutex = nullptr;
-static VirtualMemory* page_cache[kPageCacheCapacity] = {nullptr};
-static intptr_t page_cache_size = 0;
-
-void SemiSpace::Init() {
-  ASSERT(page_cache_mutex == nullptr);
-  page_cache_mutex = new Mutex(NOT_IN_PRODUCT("page_cache_mutex"));
-}
-
-void SemiSpace::ClearCache() {
-  MutexLocker ml(page_cache_mutex);
-  ASSERT(page_cache_size >= 0);
-  ASSERT(page_cache_size <= kPageCacheCapacity);
-  while (page_cache_size > 0) {
-    delete page_cache[--page_cache_size];
-  }
-}
-
-void SemiSpace::Cleanup() {
-  ClearCache();
-  delete page_cache_mutex;
-  page_cache_mutex = nullptr;
-}
-
-intptr_t SemiSpace::CachedSize() {
-  MutexLocker ml(page_cache_mutex);
-  return page_cache_size * kNewPageSize;
-}
-
-NewPage* NewPage::Allocate() {
-  const intptr_t size = kNewPageSize;
-  VirtualMemory* memory = nullptr;
-  {
-    MutexLocker ml(page_cache_mutex);
-    ASSERT(page_cache_size >= 0);
-    ASSERT(page_cache_size <= kPageCacheCapacity);
-    if (page_cache_size > 0) {
-      memory = page_cache[--page_cache_size];
-    }
-  }
-  if (memory == nullptr) {
-    const intptr_t alignment = kNewPageSize;
-    const bool is_executable = false;
-    const bool compressed = true;
-    const char* const name = Heap::RegionName(Heap::kNew);
-    memory = VirtualMemory::AllocateAligned(size, alignment, is_executable,
-                                            compressed, name);
-  }
-  if (memory == nullptr) {
-    return nullptr;  // Out of memory.
-  }
-
-#if defined(DEBUG)
-  memset(memory->address(), Heap::kZapByte, size);
-#endif
-  // Initialized by generated code.
-  MSAN_UNPOISON(memory->address(), size);
-
-  NewPage* result = reinterpret_cast<NewPage*>(memory->address());
-  result->memory_ = memory;
-  result->next_ = nullptr;
-  result->owner_ = nullptr;
-  uword top = result->object_start();
-  result->top_ = top;
-  result->end_ = memory->end() - kNewObjectAlignmentOffset;
-  result->survivor_end_ = top;
-  result->resolved_top_ = top;
-
-  LSAN_REGISTER_ROOT_REGION(result, sizeof(*result));
-
-  return result;
-}
-
-void NewPage::Deallocate() {
-  LSAN_UNREGISTER_ROOT_REGION(this, sizeof(*this));
-
-  VirtualMemory* memory = memory_;
-  {
-    MutexLocker ml(page_cache_mutex);
-    ASSERT(page_cache_size >= 0);
-    ASSERT(page_cache_size <= kPageCacheCapacity);
-    if (page_cache_size < kPageCacheCapacity) {
-      intptr_t size = memory->size();
-#if defined(DEBUG)
-      memset(memory->address(), Heap::kZapByte, size);
-#endif
-      MSAN_POISON(memory->address(), size);
-      page_cache[page_cache_size++] = memory;
-      memory = nullptr;
-    }
-  }
-  delete memory;
-}
-
-NewPage* SemiSpace::TryAllocatePageLocked(bool link) {
+Page* SemiSpace::TryAllocatePageLocked(bool link) {
   if (capacity_in_words_ >= max_capacity_in_words_) {
     return nullptr;  // Full.
   }
-  NewPage* page = NewPage::Allocate();
+  Page* page = Page::Allocate(kPageSize, Page::kNew, /*can_use_cache*/ true);
   if (page == nullptr) {
     return nullptr;  // Out of memory;
   }
-  capacity_in_words_ += kNewPageSizeInWords;
+  capacity_in_words_ += kPageSizeInWords;
   if (link) {
     if (head_ == nullptr) {
       head_ = tail_ = page;
@@ -801,19 +707,19 @@
 }
 
 bool SemiSpace::Contains(uword addr) const {
-  for (NewPage* page = head_; page != nullptr; page = page->next()) {
+  for (Page* page = head_; page != nullptr; page = page->next()) {
     if (page->Contains(addr)) return true;
   }
   return false;
 }
 
 void SemiSpace::WriteProtect(bool read_only) {
-  for (NewPage* page = head_; page != nullptr; page = page->next()) {
+  for (Page* page = head_; page != nullptr; page = page->next()) {
     page->WriteProtect(read_only);
   }
 }
 
-void SemiSpace::AddList(NewPage* head, NewPage* tail) {
+void SemiSpace::AddList(Page* head, Page* tail) {
   if (head == nullptr) {
     return;
   }
@@ -868,7 +774,7 @@
                                    GCReason reason) const {
   bool grow = false;
   if (2 * heap_->isolate_group()->MutatorCount() >
-      (old_size_in_words / kNewPageSizeInWords)) {
+      (old_size_in_words / kPageSizeInWords)) {
     // Not enough TLABs to give two to each mutator.
     grow = true;
   }
@@ -957,7 +863,7 @@
       ObjectPtr raw_obj = *ptr;
       if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) {
         if (is_card_remembered_) {
-          if (!OldPage::Of(visiting_)->IsCardRemembered(ptr)) {
+          if (!Page::Of(visiting_)->IsCardRemembered(ptr)) {
             FATAL3(
                 "Old object %#" Px " references new object %#" Px
                 ", but the "
@@ -988,7 +894,7 @@
       ObjectPtr raw_obj = ptr->Decompress(heap_base);
       if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) {
         if (is_card_remembered_) {
-          if (!OldPage::Of(visiting_)->IsCardRemembered(ptr)) {
+          if (!Page::Of(visiting_)->IsCardRemembered(ptr)) {
             FATAL3(
                 "Old object %#" Px " references new object %#" Px
                 ", but the "
@@ -1322,9 +1228,6 @@
     return false;
   }
   uword raw_addr = UntaggedObject::ToAddr(raw_obj);
-  if (to_->Contains(raw_addr)) {
-    return false;
-  }
   uword header = *reinterpret_cast<uword*>(raw_addr);
   if (IsForwarding(header)) {
     *p = ForwardedObj(header);
@@ -1350,7 +1253,7 @@
     }
     scan_->resolved_top_ = resolved_top;
 
-    NewPage* next = scan_->next();
+    Page* next = scan_->next();
     if (next == nullptr) {
       // Don't update scan_. More objects may yet be copied to this TLAB.
       return;
@@ -1633,7 +1536,7 @@
   ASSERT(Thread::Current()->IsAtSafepoint() ||
          (Thread::Current()->task_kind() == Thread::kMarkerTask) ||
          (Thread::Current()->task_kind() == Thread::kCompactorTask));
-  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+  for (Page* page = to_->head(); page != nullptr; page = page->next()) {
     page->VisitObjectPointers(visitor);
   }
 }
@@ -1641,20 +1544,20 @@
 void Scavenger::VisitObjects(ObjectVisitor* visitor) const {
   ASSERT(Thread::Current()->IsAtSafepoint() ||
          (Thread::Current()->task_kind() == Thread::kMarkerTask));
-  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+  for (Page* page = to_->head(); page != nullptr; page = page->next()) {
     page->VisitObjects(visitor);
   }
 }
 
 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const {
-  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+  for (Page* page = to_->head(); page != nullptr; page = page->next()) {
     set->AddRegion(page->start(), page->end());
   }
 }
 
 ObjectPtr Scavenger::FindObject(FindObjectVisitor* visitor) {
   ASSERT(!scavenging_);
-  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+  for (Page* page = to_->head(); page != nullptr; page = page->next()) {
     uword cur = page->object_start();
     if (!visitor->VisitRange(cur, page->object_end())) continue;
     while (cur < page->object_end()) {
@@ -1681,20 +1584,21 @@
 
   if (can_safepoint && !thread->force_growth()) {
     ASSERT(thread->no_safepoint_scope_depth() == 0);
-    heap_->CheckConcurrentMarking(thread, GCReason::kNewSpace, kNewPageSize);
+    heap_->CheckConcurrentMarking(thread, GCReason::kNewSpace, kPageSize);
   }
 
   MutexLocker ml(&space_lock_);
-  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+  for (Page* page = to_->head(); page != nullptr; page = page->next()) {
     if (page->owner() != nullptr) continue;
-    intptr_t available = page->end() - page->object_end();
+    intptr_t available =
+        (page->end() - kAllocationRedZoneSize) - page->object_end();
     if (available >= min_size) {
       page->Acquire(thread);
       return;
     }
   }
 
-  NewPage* page = to_->TryAllocatePageLocked(true);
+  Page* page = to_->TryAllocatePageLocked(true);
   if (page == nullptr) {
     return;
   }
@@ -1716,7 +1620,7 @@
 
 void Scavenger::AbandonRemainingTLAB(Thread* thread) {
   if (thread->top() == 0) return;
-  NewPage* page = NewPage::Of(thread->top() - 1);
+  Page* page = Page::Of(thread->top() - 1);
   {
     MutexLocker ml(&space_lock_);
     page->Release(thread);
@@ -1726,7 +1630,7 @@
 
 template <bool parallel>
 uword ScavengerVisitorBase<parallel>::TryAllocateCopySlow(intptr_t size) {
-  NewPage* page;
+  Page* page;
   {
     MutexLocker ml(&scavenger_->space_lock_);
     page = scavenger_->to_->TryAllocatePageLocked(false);
@@ -1774,7 +1678,7 @@
   intptr_t abandoned_bytes = 0;  // TODO(rmacnak): Count fragmentation?
   SpaceUsage usage_before = GetCurrentUsage();
   intptr_t promo_candidate_words = 0;
-  for (NewPage* page = to_->head(); page != nullptr; page = page->next()) {
+  for (Page* page = to_->head(); page != nullptr; page = page->next()) {
     page->Release();
     if (early_tenure_) {
       page->EarlyTenure();
@@ -1920,7 +1824,7 @@
   };
 
   ReverseFromForwardingVisitor visitor;
-  for (NewPage* page = (*from)->head(); page != nullptr; page = page->next()) {
+  for (Page* page = (*from)->head(); page != nullptr; page = page->next()) {
     page->VisitObjects(&visitor);
   }
 
diff --git a/runtime/vm/heap/scavenger.h b/runtime/vm/heap/scavenger.h
index 43eac30..a54680d 100644
--- a/runtime/vm/heap/scavenger.h
+++ b/runtime/vm/heap/scavenger.h
@@ -11,6 +11,7 @@
 #include "vm/dart.h"
 #include "vm/flags.h"
 #include "vm/globals.h"
+#include "vm/heap/page.h"
 #include "vm/heap/spaces.h"
 #include "vm/isolate.h"
 #include "vm/lockers.h"
@@ -29,166 +30,19 @@
 template <bool parallel>
 class ScavengerVisitorBase;
 
-static constexpr intptr_t kNewPageSize = 512 * KB;
-static constexpr intptr_t kNewPageSizeInWords = kNewPageSize / kWordSize;
-static constexpr intptr_t kNewPageMask = ~(kNewPageSize - 1);
-
-// Simplify initialization in allocation stubs by ensuring it is safe
-// to overshoot the object end by up to kAllocationRedZoneSize. (Just as the
-// stack red zone allows one to overshoot the stack pointer.)
-static constexpr intptr_t kAllocationRedZoneSize = kObjectAlignment;
-
-// A page containing new generation objects.
-class NewPage {
- public:
-  static NewPage* Allocate();
-  void Deallocate();
-
-  uword start() const { return memory_->start(); }
-  uword end() const { return memory_->end() - kAllocationRedZoneSize; }
-  bool Contains(uword addr) const { return memory_->Contains(addr); }
-  void WriteProtect(bool read_only) {
-    memory_->Protect(read_only ? VirtualMemory::kReadOnly
-                               : VirtualMemory::kReadWrite);
-  }
-
-  NewPage* next() const { return next_; }
-  void set_next(NewPage* next) { next_ = next; }
-
-  Thread* owner() const { return owner_; }
-
-  uword object_start() const { return start() + ObjectStartOffset(); }
-  uword object_end() const { return owner_ != nullptr ? owner_->top() : top_; }
-  intptr_t used() const { return object_end() - object_start(); }
-  void VisitObjects(ObjectVisitor* visitor) const {
-    uword addr = object_start();
-    uword end = object_end();
-    while (addr < end) {
-      ObjectPtr obj = UntaggedObject::FromAddr(addr);
-      visitor->VisitObject(obj);
-      addr += obj->untag()->HeapSize();
-    }
-  }
-  void VisitObjectPointers(ObjectPointerVisitor* visitor) const {
-    uword addr = object_start();
-    uword end = object_end();
-    while (addr < end) {
-      ObjectPtr obj = UntaggedObject::FromAddr(addr);
-      intptr_t size = obj->untag()->VisitPointers(visitor);
-      addr += size;
-    }
-  }
-
-  static intptr_t ObjectStartOffset() {
-    return Utils::RoundUp(sizeof(NewPage), kObjectAlignment) +
-           kNewObjectAlignmentOffset;
-  }
-
-  static NewPage* Of(ObjectPtr obj) {
-    ASSERT(obj->IsHeapObject());
-    ASSERT(obj->IsNewObject());
-    return Of(static_cast<uword>(obj));
-  }
-  static NewPage* Of(uword addr) {
-    return reinterpret_cast<NewPage*>(addr & kNewPageMask);
-  }
-
-  // Remember the limit to which objects have been copied.
-  void RecordSurvivors() { survivor_end_ = object_end(); }
-
-  // Move survivor end to the end of the to_ space, making all surviving
-  // objects candidates for promotion next time.
-  void EarlyTenure() { survivor_end_ = end_; }
-
-  uword promo_candidate_words() const {
-    return (survivor_end_ - object_start()) / kWordSize;
-  }
-
-  void Acquire(Thread* thread) {
-    ASSERT(owner_ == nullptr);
-    owner_ = thread;
-    thread->set_top(top_);
-    thread->set_end(end_);
-  }
-  void Release(Thread* thread) {
-    ASSERT(owner_ == thread);
-    owner_ = nullptr;
-    top_ = thread->top();
-    thread->set_top(0);
-    thread->set_end(0);
-  }
-  void Release() {
-    if (owner_ != nullptr) {
-      Release(owner_);
-    }
-  }
-
-  uword TryAllocateGC(intptr_t size) {
-    ASSERT(owner_ == nullptr);
-    uword result = top_;
-    uword new_top = result + size;
-    if (LIKELY(new_top <= end_)) {
-      top_ = new_top;
-      return result;
-    }
-    return 0;
-  }
-
-  void Unallocate(uword addr, intptr_t size) {
-    ASSERT((addr + size) == top_);
-    top_ -= size;
-  }
-
-  bool IsSurvivor(uword raw_addr) const { return raw_addr < survivor_end_; }
-  bool IsResolved() const { return top_ == resolved_top_; }
-
- private:
-  VirtualMemory* memory_;
-  NewPage* next_;
-
-  // The thread using this page for allocation, otherwise NULL.
-  Thread* owner_;
-
-  // The address of the next allocation. If owner is non-NULL, this value is
-  // stale and the current value is at owner->top_. Called "NEXT" in the
-  // original Cheney paper.
-  uword top_;
-
-  // The address after the last allocatable byte in this page.
-  uword end_;
-
-  // Objects below this address have survived a scavenge.
-  uword survivor_end_;
-
-  // A pointer to the first unprocessed object. Resolution completes when this
-  // value meets the allocation top. Called "SCAN" in the original Cheney paper.
-  uword resolved_top_;
-
-  template <bool>
-  friend class ScavengerVisitorBase;
-
-  DISALLOW_ALLOCATION();
-  DISALLOW_IMPLICIT_CONSTRUCTORS(NewPage);
-};
-
 class SemiSpace {
  public:
-  static void Init();
-  static void ClearCache();
-  static void Cleanup();
-  static intptr_t CachedSize();
-
   explicit SemiSpace(intptr_t max_capacity_in_words);
   ~SemiSpace();
 
-  NewPage* TryAllocatePageLocked(bool link);
+  Page* TryAllocatePageLocked(bool link);
 
   bool Contains(uword addr) const;
   void WriteProtect(bool read_only);
 
   intptr_t used_in_words() const {
     intptr_t size = 0;
-    for (const NewPage* p = head_; p != nullptr; p = p->next()) {
+    for (const Page* p = head_; p != nullptr; p = p->next()) {
       size += p->used();
     }
     return size >> kWordSizeLog2;
@@ -196,9 +50,9 @@
   intptr_t capacity_in_words() const { return capacity_in_words_; }
   intptr_t max_capacity_in_words() const { return max_capacity_in_words_; }
 
-  NewPage* head() const { return head_; }
+  Page* head() const { return head_; }
 
-  void AddList(NewPage* head, NewPage* tail);
+  void AddList(Page* head, Page* tail);
 
  private:
   // Size of NewPages in this semi-space.
@@ -207,8 +61,8 @@
   // Size of NewPages before we trigger a scavenge.
   intptr_t max_capacity_in_words_;
 
-  NewPage* head_ = nullptr;
-  NewPage* tail_ = nullptr;
+  Page* head_ = nullptr;
+  Page* tail_ = nullptr;
 };
 
 // Statistics for a particular scavenge.
@@ -335,10 +189,20 @@
   void PrintToJSONObject(JSONObject* object) const;
 #endif  // !PRODUCT
 
-  void AllocatedExternal(intptr_t size) {
+  // Tracks an external allocation by incrementing the new space's total
+  // external size tracker. Returns false without incrementing the tracker if
+  // this allocation will make it exceed kMaxAddrSpaceInWords.
+  bool AllocatedExternal(intptr_t size) {
     ASSERT(size >= 0);
+    intptr_t next_external_size_in_words =
+        (external_size_ >> kWordSizeLog2) + (size >> kWordSizeLog2);
+    if (next_external_size_in_words < 0 ||
+        next_external_size_in_words > kMaxAddrSpaceInWords) {
+      return false;
+    }
     external_size_ += size;
     ASSERT(external_size_ >= 0);
+    return true;
   }
   void FreedExternal(intptr_t size) {
     ASSERT(size >= 0);
@@ -362,7 +226,9 @@
     return max_pool_size > 0 ? max_pool_size : 1;
   }
 
-  NewPage* head() const { return to_->head(); }
+  Page* head() const {
+    return to_->head();
+  }
 
  private:
   // Ids for time and data records in Heap::GCStats.
diff --git a/runtime/vm/heap/sweeper.cc b/runtime/vm/heap/sweeper.cc
index 11900bb..faf54b8 100644
--- a/runtime/vm/heap/sweeper.cc
+++ b/runtime/vm/heap/sweeper.cc
@@ -15,20 +15,20 @@
 
 namespace dart {
 
-bool GCSweeper::SweepPage(OldPage* page, FreeList* freelist, bool locked) {
+bool GCSweeper::SweepPage(Page* page, FreeList* freelist, bool locked) {
   ASSERT(!page->is_image_page());
 
   // Keep track whether this page is still in use.
   intptr_t used_in_bytes = 0;
 
-  bool is_executable = (page->type() == OldPage::kExecutable);
+  bool is_executable = (page->type() == Page::kExecutable);
   uword start = page->object_start();
   uword end = page->object_end();
   uword current = start;
 
   while (current < end) {
     ObjectPtr raw_obj = UntaggedObject::FromAddr(current);
-    ASSERT(OldPage::Of(raw_obj) == page);
+    ASSERT(Page::Of(raw_obj) == page);
     // These acquire operations balance release operations in array
     // truncaton, ensuring the writes creating the filler object are ordered
     // before the writes inserting the filler object into the freelist.
@@ -76,16 +76,15 @@
   }
   ASSERT(current == end);
 
-  page->set_used_in_bytes(used_in_bytes);
   return used_in_bytes != 0;  // In use.
 }
 
-intptr_t GCSweeper::SweepLargePage(OldPage* page) {
+intptr_t GCSweeper::SweepLargePage(Page* page) {
   ASSERT(!page->is_image_page());
 
   intptr_t words_to_end = 0;
   ObjectPtr raw_obj = UntaggedObject::FromAddr(page->object_start());
-  ASSERT(OldPage::Of(raw_obj) == page);
+  ASSERT(Page::Of(raw_obj) == page);
   if (raw_obj->untag()->IsMarked()) {
     raw_obj->untag()->ClearMarkBit();
     words_to_end = (raw_obj->untag()->HeapSize() >> kWordSizeLog2);
diff --git a/runtime/vm/heap/sweeper.h b/runtime/vm/heap/sweeper.h
index 8b781d4..99e22e2 100644
--- a/runtime/vm/heap/sweeper.h
+++ b/runtime/vm/heap/sweeper.h
@@ -12,7 +12,7 @@
 // Forward declarations.
 class FreeList;
 class Heap;
-class OldPage;
+class Page;
 class IsolateGroup;
 class PageSpace;
 
@@ -28,11 +28,11 @@
   // pre-locked is indicated by the locked parameter.
   // Returns true if the page is in use. Freelist is untouched if page is not
   // in use.
-  bool SweepPage(OldPage* page, FreeList* freelist, bool locked);
+  bool SweepPage(Page* page, FreeList* freelist, bool locked);
 
   // Returns the number of words from page->object_start() to the end of the
   // last marked object.
-  intptr_t SweepLargePage(OldPage* page);
+  intptr_t SweepLargePage(Page* page);
 
   // Sweep the large and regular sized data pages.
   static void SweepConcurrent(IsolateGroup* isolate_group);
diff --git a/runtime/vm/heap/verifier.cc b/runtime/vm/heap/verifier.cc
index 1a726dd..148c901 100644
--- a/runtime/vm/heap/verifier.cc
+++ b/runtime/vm/heap/verifier.cc
@@ -50,7 +50,7 @@
     if (raw_obj->IsHeapObject()) {
       if (!allocated_set_->Contains(raw_obj)) {
         if (raw_obj->IsInstructions() &&
-            allocated_set_->Contains(OldPage::ToWritable(raw_obj))) {
+            allocated_set_->Contains(Page::ToWritable(raw_obj))) {
           continue;
         }
         uword raw_addr = UntaggedObject::ToAddr(raw_obj);
@@ -68,7 +68,7 @@
     if (raw_obj->IsHeapObject()) {
       if (!allocated_set_->Contains(raw_obj)) {
         if (raw_obj->IsInstructions() &&
-            allocated_set_->Contains(OldPage::ToWritable(raw_obj))) {
+            allocated_set_->Contains(Page::ToWritable(raw_obj))) {
           continue;
         }
         uword raw_addr = UntaggedObject::ToAddr(raw_obj);
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 8115931..01cd7af 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -179,6 +179,9 @@
       next_text_offset_(0),
       objects_(),
       instructions_(),
+#if defined(DART_PRECOMPILER)
+      namer_(t->zone()),
+#endif
       image_type_(TagObjectTypeAsReadOnly(zone_, "Image")),
       instructions_section_type_(
           TagObjectTypeAsReadOnly(zone_, "InstructionsSection")),
@@ -286,11 +289,20 @@
   }
 }
 
+#if defined(SNAPSHOT_BACKTRACE)
+uint32_t ImageWriter::GetDataOffsetFor(ObjectPtr raw_object,
+                                       ObjectPtr raw_parent) {
+#else
 uint32_t ImageWriter::GetDataOffsetFor(ObjectPtr raw_object) {
+#endif
   const intptr_t snap_size = SizeInSnapshot(raw_object);
   const intptr_t offset = next_data_offset_;
   next_data_offset_ += snap_size;
+#if defined(SNAPSHOT_BACKTRACE)
+  objects_.Add(ObjectData(raw_object, raw_parent));
+#else
   objects_.Add(ObjectData(raw_object));
+#endif
   return offset;
 }
 
@@ -455,8 +467,11 @@
     heap->SetObjectId(data.insns_->ptr(), 0);
   }
   for (auto& data : objects_) {
-    if (data.is_object) {
+    if (data.is_object()) {
       data.obj = &Object::Handle(zone_, data.raw_obj);
+#if defined(SNAPSHOT_BACKTRACE)
+      data.parent = &Object::Handle(zone_, data.raw_parent);
+#endif
     }
   }
 
@@ -464,11 +479,14 @@
   // to string objects. String is used for simplicity as a bit container,
   // can't use TypedData because it has an internal pointer (data_) field.
   for (auto& data : objects_) {
-    if (!data.is_object) {
+    if (!data.is_object()) {
       const auto bytes = data.bytes;
       data.obj = &Object::Handle(
           zone_, OneByteString::New(bytes.buf, bytes.length, Heap::kOld));
-      data.is_object = true;
+#if defined(SNAPSHOT_BACKTRACE)
+      data.parent = &Object::null_object();
+#endif
+      data.set_is_object(true);
       String::Cast(*data.obj).Hash();
       free(bytes.buf);
     }
@@ -489,13 +507,8 @@
 }
 
 void ImageWriter::WriteROData(NonStreamingWriteStream* stream, bool vm) {
-#if defined(DART_PRECOMPILER)
-  const intptr_t start_position = stream->Position();
-#endif
-  stream->Align(ImageWriter::kRODataAlignment);
-
+  ASSERT(Utils::IsAligned(stream->Position(), kRODataAlignment));
   // Heap page starts here.
-
   intptr_t section_start = stream->Position();
 
   stream->WriteWord(next_data_offset_);  // Data length.
@@ -505,20 +518,20 @@
   ASSERT_EQUAL(stream->Position() - section_start, Image::kHeaderSize);
 #if defined(DART_PRECOMPILER)
   if (profile_writer_ != nullptr) {
-    const intptr_t end_position = stream->Position();
+    // Attribute the Image header to the artificial root.
     profile_writer_->AttributeBytesTo(
-        V8SnapshotProfileWriter::kArtificialRootId,
-        end_position - start_position);
+        V8SnapshotProfileWriter::kArtificialRootId, Image::kHeaderSize);
   }
 #endif
 
   // Heap page objects start here.
 
   for (auto entry : objects_) {
-    ASSERT(entry.is_object);
+    ASSERT(entry.is_object());
     const Object& obj = *entry.obj;
 #if defined(DART_PRECOMPILER)
     AutoTraceImage(obj, section_start, stream);
+    const char* object_name = namer_.SnapshotNameFor(entry);
 #endif
     auto const object_start = stream->Position();
 
@@ -568,6 +581,9 @@
     }
     stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
     ASSERT_EQUAL(stream->Position() - object_start, SizeInSnapshot(obj));
+#if defined(DART_PRECOMPILER)
+    AddDataSymbol(object_name, object_start, stream->Position() - object_start);
+#endif
   }
 }
 
@@ -669,7 +685,9 @@
   const bool bare_instruction_payloads = FLAG_precompiled_mode;
 
   // Start snapshot at page boundary.
-  if (!EnterSection(ProgramSection::Text, vm, ImageWriter::kTextAlignment)) {
+  intptr_t alignment_padding = 0;
+  if (!EnterSection(ProgramSection::Text, vm, ImageWriter::kTextAlignment,
+                    &alignment_padding)) {
     return;
   }
 
@@ -682,7 +700,7 @@
 #endif
 
   // This head also provides the gap to make the instructions snapshot
-  // look like a OldPage.
+  // look like a Page.
   const intptr_t image_size = Utils::RoundUp(
       next_text_offset_, compiler::target::ObjectAlignment::kObjectAlignment);
   text_offset += WriteTargetWord(image_size);
@@ -704,7 +722,8 @@
   if (profile_writer_ != nullptr) {
     profile_writer_->SetObjectTypeAndName(parent_id, image_type_,
                                           instructions_symbol);
-    profile_writer_->AttributeBytesTo(parent_id, Image::kHeaderSize);
+    profile_writer_->AttributeBytesTo(
+        parent_id, ImageWriter::kTextAlignment + alignment_padding);
     profile_writer_->AddRoot(parent_id);
   }
 
@@ -772,7 +791,6 @@
 
 #if defined(DART_PRECOMPILER)
   PcDescriptors& descriptors = PcDescriptors::Handle(zone_);
-  SnapshotTextObjectNamer namer(zone_);
 #endif
 
   ASSERT(offset_space_ != IdSpace::kSnapshot);
@@ -782,10 +800,7 @@
     ASSERT_EQUAL(data.text_offset_, text_offset);
 
 #if defined(DART_PRECOMPILER)
-    // We won't add trampolines as symbols, so their name need not be unique
-    // across different WriteText() calls.
-    const char* object_name = namer.SnapshotNameFor(
-        is_trampoline ? i : unique_symbol_counter_++, data);
+    const char* object_name = namer_.SnapshotNameFor(data);
 
     if (profile_writer_ != nullptr) {
       const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
@@ -1104,9 +1119,15 @@
   if (debug_elf_ != nullptr) {
     debug_elf_->Finalize();
   }
+
+#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
+    defined(DART_TARGET_OS_FUCHSIA)
+  // Non-executable stack.
+  assembly_stream_->WriteString(".section .note.GNU-stack,\"\"\n");
+#endif
 }
 
-static void AddAssemblerIdentifier(ZoneTextBuffer* printer, const char* label) {
+static void AddAssemblerIdentifier(BaseTextBuffer* printer, const char* label) {
   ASSERT(label[0] != '.');
   if (label[0] == 'L' && printer->length() == 0) {
     // Assembler treats labels starting with `L` as local which can cause
@@ -1159,47 +1180,89 @@
   }
 }
 
-const char* SnapshotTextObjectNamer::SnapshotNameFor(intptr_t code_index,
-                                                     const Code& code) {
-  ASSERT(!code.IsNull());
-  owner_ = code.owner();
-  if (owner_.IsNull()) {
-    insns_ = code.instructions();
-    const char* name = StubCode::NameOfStub(insns_.EntryPoint());
-    ASSERT(name != nullptr);
-    return OS::SCreate(zone_, "Stub_%s", name);
-  }
-  // The weak reference to the Code's owner should never have been removed via
-  // an intermediate serialization, since WSRs are only introduced during
-  // precompilation.
-  owner_ = WeakSerializationReference::Unwrap(owner_);
-  ASSERT(!owner_.IsNull());
-  ZoneTextBuffer printer(zone_);
-  if (owner_.IsClass()) {
-    const char* name = Class::Cast(owner_).ScrubbedNameCString();
-    printer.AddString("AllocationStub_");
-    AddAssemblerIdentifier(&printer, name);
-  } else if (owner_.IsAbstractType()) {
-    const char* name = namer_.StubNameForType(AbstractType::Cast(owner_));
-    printer.AddString(name);
-  } else if (owner_.IsFunction()) {
-    const char* name = Function::Cast(owner_).QualifiedScrubbedNameCString();
-    AddAssemblerIdentifier(&printer, name);
+void ImageWriter::SnapshotTextObjectNamer::AddNonUniqueNameFor(
+    BaseTextBuffer* buffer,
+    const Object& object) {
+  if (object.IsCode()) {
+    const Code& code = Code::Cast(object);
+    owner_ = WeakSerializationReference::Unwrap(code.owner());
+    if (owner_.IsNull()) {
+      buffer->AddString("Stub_");
+      insns_ = code.instructions();
+      const char* name = StubCode::NameOfStub(insns_.EntryPoint());
+      ASSERT(name != nullptr);
+      buffer->AddString(name);
+    } else {
+      if (owner_.IsClass()) {
+        buffer->AddString("AllocationStub_");
+      } else if (!owner_.IsAbstractType() && !owner_.IsFunction()) {
+        // Double-check that we didn't get an invalid owner for the Code object.
+        UNREACHABLE();
+      }
+      AddNonUniqueNameFor(buffer, owner_);
+    }
+  } else if (object.IsClass()) {
+    const char* name = Class::Cast(object).ScrubbedNameCString();
+    AddAssemblerIdentifier(buffer, name);
+  } else if (object.IsAbstractType()) {
+    namer_.WriteStubNameForTypeTo(buffer, AbstractType::Cast(object));
+  } else if (object.IsFunction()) {
+    const char* name = Function::Cast(object).QualifiedScrubbedNameCString();
+    AddAssemblerIdentifier(buffer, name);
+  } else if (object.IsCompressedStackMaps()) {
+    buffer->AddString("CompressedStackMaps");
+  } else if (object.IsPcDescriptors()) {
+    buffer->AddString("PcDescriptors");
+  } else if (object.IsCodeSourceMap()) {
+    buffer->AddString("CodeSourceMap");
+  } else if (object.IsString()) {
+    const String& str = String::Cast(object);
+    if (str.IsOneByteString()) {
+      buffer->AddString("OneByteString");
+    } else if (str.IsTwoByteString()) {
+      buffer->AddString("TwoByteString");
+    }
   } else {
     UNREACHABLE();
   }
+}
 
-  printer.Printf("_%" Pd, code_index);
+const char* ImageWriter::SnapshotTextObjectNamer::SnapshotNameFor(
+    const InstructionsData& data) {
+  ZoneTextBuffer printer(zone_);
+  if (data.trampoline_bytes != nullptr) {
+    printer.AddString("Trampoline");
+  } else {
+    AddNonUniqueNameFor(&printer, *data.code_);
+  }
+  printer.Printf("_%" Pd, nonce_++);
   return printer.buffer();
 }
 
-const char* SnapshotTextObjectNamer::SnapshotNameFor(
-    intptr_t index,
-    const ImageWriter::InstructionsData& data) {
-  if (data.trampoline_bytes != nullptr) {
-    return OS::SCreate(zone_, "Trampoline_%" Pd "", index);
+const char* ImageWriter::SnapshotTextObjectNamer::SnapshotNameFor(
+    const ObjectData& data) {
+  ASSERT(data.is_object());
+  ZoneTextBuffer printer(zone_);
+  if (data.is_original_object()) {
+    const Object& obj = *data.obj;
+    AddNonUniqueNameFor(&printer, obj);
+#if defined(SNAPSHOT_BACKTRACE)
+    // It's less useful knowing the parent of a String than other read-only
+    // data objects, and this avoids us having to handle other classes
+    // in AddNonUniqueNameFor.
+    if (!obj.IsString()) {
+      const Object& parent = *data.parent;
+      if (!parent.IsNull()) {
+        printer.AddString("_");
+        AddNonUniqueNameFor(&printer, parent);
+      }
+    }
+#endif
+  } else {
+    printer.AddString("RawBytes");
   }
-  return SnapshotNameFor(index, *data.code_);
+  printer.Printf("_%" Pd, nonce_++);
+  return printer.buffer();
 }
 
 void AssemblyImageWriter::WriteBss(bool vm) {
@@ -1215,17 +1278,52 @@
 
 void AssemblyImageWriter::WriteROData(NonStreamingWriteStream* clustered_stream,
                                       bool vm) {
-  ImageWriter::WriteROData(clustered_stream, vm);
   if (!EnterSection(ProgramSection::Data, vm, ImageWriter::kRODataAlignment)) {
     return;
   }
-  WriteBytes(clustered_stream->buffer(), clustered_stream->bytes_written());
-  ExitSection(ProgramSection::Data, vm, clustered_stream->bytes_written());
+  // The clustered stream already has some data on it from the serializer, so
+  // make sure that the read-only objects start at the appropriate alignment
+  // within the stream, as we'll write the entire clustered stream to the
+  // assembly output (which was aligned in EnterSection).
+  const intptr_t start_position = clustered_stream->Position();
+  clustered_stream->Align(ImageWriter::kRODataAlignment);
+  if (profile_writer_ != nullptr) {
+    // Attribute any padding needed to the artificial root.
+    const intptr_t padding = clustered_stream->Position() - start_position;
+    profile_writer_->AttributeBytesTo(
+        V8SnapshotProfileWriter::kArtificialRootId, padding);
+  }
+  // First write the read-only data objects to the clustered stream.
+  ImageWriter::WriteROData(clustered_stream, vm);
+  // Next, write the bytes of the clustered stream (along with any symbols
+  // if appropriate) to the assembly output.
+  const uint8_t* bytes = clustered_stream->buffer();
+  const intptr_t len = clustered_stream->bytes_written();
+  intptr_t last_position = 0;
+  for (const auto& symbol : *current_symbols_) {
+    WriteBytes(bytes + last_position, symbol.offset - last_position);
+    assembly_stream_->Printf("%s:\n", symbol.name);
+#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
+    defined(DART_TARGET_OS_FUCHSIA)
+    // Output size and type of the read-only data symbol to the assembly stream.
+    assembly_stream_->Printf(".size %s, %zu\n", symbol.name, symbol.size);
+    assembly_stream_->Printf(".type %s, %%object\n", symbol.name);
+#elif defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
+    // MachO symbol tables don't include the size of the symbol, so don't bother
+    // printing it to the assembly output.
+#else
+    UNIMPLEMENTED();
+#endif
+    last_position = symbol.offset;
+  }
+  WriteBytes(bytes + last_position, len - last_position);
+  ExitSection(ProgramSection::Data, vm, len);
 }
 
 bool AssemblyImageWriter::EnterSection(ProgramSection section,
                                        bool vm,
-                                       intptr_t alignment) {
+                                       intptr_t alignment,
+                                       intptr_t* alignment_padding) {
   ASSERT(FLAG_precompiled_mode);
   ASSERT(current_section_symbol_ == nullptr);
   ASSERT(current_symbols_ == nullptr);
@@ -1240,10 +1338,14 @@
       global_symbol = true;
       break;
     case ProgramSection::Data:
-      if (debug_elf_ != nullptr) {
-        current_symbols_ =
-            new (zone_) ZoneGrowableArray<Elf::SymbolData>(zone_, 0);
-      }
+      // We create a SymbolData array even if there is no debug_elf_ because we
+      // may be writing RO data symbols, and RO data is written in two steps:
+      // 1. Serializing the read-only data objects to the clustered stream
+      // 2. Writing the bytes of the clustered stream to the assembly output.
+      // Thus, we'll need to interleave the symbols with the cluster bytes
+      // during step 2.
+      current_symbols_ =
+          new (zone_) ZoneGrowableArray<Elf::SymbolData>(zone_, 0);
 #if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
     defined(DART_TARGET_OS_FUCHSIA)
       assembly_stream_->WriteString(".section .rodata\n");
@@ -1265,7 +1367,10 @@
   if (global_symbol) {
     assembly_stream_->Printf(".globl %s\n", current_section_symbol_);
   }
-  Align(alignment);
+  intptr_t padding = Align(alignment);
+  if (alignment_padding != nullptr) {
+    *alignment_padding = padding;
+  }
   assembly_stream_->Printf("%s:\n", current_section_symbol_);
   return true;
 }
@@ -1298,6 +1403,17 @@
   // We should still be in the same section as the last EnterSection.
   ASSERT(current_section_symbol_ != nullptr);
   ASSERT_EQUAL(strcmp(SectionSymbol(name, vm), current_section_symbol_), 0);
+#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
+    defined(DART_TARGET_OS_FUCHSIA)
+  // Output the size of the section symbol to the assembly stream.
+  assembly_stream_->Printf(".size %s, %zu\n", current_section_symbol_, size);
+  assembly_stream_->Printf(".type %s, %%object\n", current_section_symbol_);
+#elif defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
+  // MachO symbol tables don't include the size of the symbol, so don't bother
+  // printing it to the assembly output.
+#else
+  UNIMPLEMENTED();
+#endif
   // We need to generate a text segment of the appropriate size in the ELF
   // for two reasons:
   //
@@ -1379,6 +1495,24 @@
     debug_elf_->dwarf()->AddCode(code, symbol);
   }
   assembly_stream_->Printf("%s:\n", symbol);
+#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
+    defined(DART_TARGET_OS_FUCHSIA)
+  // Output the size of the code symbol to the assembly stream.
+  assembly_stream_->Printf(".size %s, %zu\n", symbol, code.Size());
+  assembly_stream_->Printf(".type %s, %%function\n", symbol);
+#elif defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
+  // MachO symbol tables don't include the size of the symbol, so don't bother
+  // printing it to the assembly output.
+#else
+  UNIMPLEMENTED();
+#endif
+}
+
+void AssemblyImageWriter::AddDataSymbol(const char* symbol,
+                                        intptr_t offset,
+                                        size_t size) {
+  if (!FLAG_add_readonly_data_symbols) return;
+  current_symbols_->Add({symbol, elf::STT_OBJECT, offset, size});
 }
 
 void AssemblyImageWriter::FrameUnwindPrologue() {
@@ -1504,23 +1638,34 @@
 
 void BlobImageWriter::WriteROData(NonStreamingWriteStream* clustered_stream,
                                   bool vm) {
-  ImageWriter::WriteROData(clustered_stream, vm);
-  current_section_stream_ = clustered_stream;
+#if defined(DART_PRECOMPILER)
+  const intptr_t start_position = clustered_stream->Position();
+#endif
+  current_section_stream_ = ASSERT_NOTNULL(clustered_stream);
   if (!EnterSection(ProgramSection::Data, vm, ImageWriter::kRODataAlignment)) {
     return;
   }
+#if defined(DART_PRECOMPILER)
+  if (profile_writer_ != nullptr) {
+    // Attribute any padding needed to the artificial root.
+    const intptr_t padding = clustered_stream->Position() - start_position;
+    profile_writer_->AttributeBytesTo(
+        V8SnapshotProfileWriter::kArtificialRootId, padding);
+  }
+#endif
+  ImageWriter::WriteROData(clustered_stream, vm);
   ExitSection(ProgramSection::Data, vm, clustered_stream->bytes_written());
 }
 
 bool BlobImageWriter::EnterSection(ProgramSection section,
                                    bool vm,
-                                   intptr_t alignment) {
+                                   intptr_t alignment,
+                                   intptr_t* alignment_padding) {
 #if defined(DART_PRECOMPILER)
   ASSERT_EQUAL(elf_ != nullptr, FLAG_precompiled_mode);
   ASSERT(current_relocations_ == nullptr);
   ASSERT(current_symbols_ == nullptr);
 #endif
-  // For now, we set current_section_stream_ in ::WriteData.
   ASSERT(section == ProgramSection::Data || current_section_stream_ == nullptr);
   ASSERT(current_section_symbol_ == nullptr);
   switch (section) {
@@ -1535,6 +1680,8 @@
 #endif
       break;
     case ProgramSection::Data:
+      // The stream to use is passed into WriteROData and set there.
+      ASSERT(current_section_stream_ != nullptr);
 #if defined(DART_PRECOMPILER)
       current_relocations_ =
           new (zone_) ZoneGrowableArray<Elf::Relocation>(zone_, 0);
@@ -1552,7 +1699,10 @@
       return false;
   }
   current_section_symbol_ = SectionSymbol(section, vm);
-  current_section_stream_->Align(alignment);
+  intptr_t padding = current_section_stream_->Align(alignment);
+  if (alignment_padding != nullptr) {
+    *alignment_padding = padding;
+  }
   return true;
 }
 
@@ -1614,6 +1764,13 @@
     debug_elf_->dwarf()->AddCode(code, symbol);
   }
 }
+
+void BlobImageWriter::AddDataSymbol(const char* symbol,
+                                    intptr_t offset,
+                                    size_t size) {
+  if (!FLAG_add_readonly_data_symbols) return;
+  current_symbols_->Add({symbol, elf::STT_OBJECT, offset, size});
+}
 #endif  // defined(DART_PRECOMPILER)
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
@@ -1623,8 +1780,8 @@
       instructions_image_(ASSERT_NOTNULL(instructions_image)) {}
 
 ApiErrorPtr ImageReader::VerifyAlignment() const {
-  if (!Utils::IsAligned(data_image_, kObjectAlignment) ||
-      !Utils::IsAligned(instructions_image_, kMaxObjectAlignment)) {
+  if (!Utils::IsAligned(data_image_, kObjectStartAlignment) ||
+      !Utils::IsAligned(instructions_image_, kObjectStartAlignment)) {
     return ApiError::New(
         String::Handle(String::New("Snapshot is misaligned", Heap::kOld)),
         Heap::kOld);
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index 730b861..abbcabf 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -22,6 +22,10 @@
 #include "vm/type_testing_stubs.h"
 #include "vm/v8_snapshot_writer.h"
 
+#if defined(DEBUG)
+#define SNAPSHOT_BACKTRACE
+#endif
+
 namespace dart {
 
 // Forward declarations.
@@ -40,7 +44,7 @@
       : raw_memory_(raw_memory),
         snapshot_size_(FieldValue(raw_memory, HeaderField::ImageSize)),
         extra_info_(ExtraInfo(raw_memory_, snapshot_size_)) {
-    ASSERT(Utils::IsAligned(raw_memory, kMaxObjectAlignment));
+    ASSERT(Utils::IsAligned(raw_memory, kObjectStartAlignment));
   }
 
   // Even though an Image is read-only memory, we must return a void* here.
@@ -113,12 +117,12 @@
   //
   // Note: Image::kHeaderSize is _not_ an architecture-dependent constant,
   // and so there is no compiler::target::Image::kHeaderSize.
-  static constexpr intptr_t kHeaderSize = kMaxObjectAlignment;
+  static constexpr intptr_t kHeaderSize = kObjectStartAlignment;
   // Explicitly double-checking kHeaderSize is never changed. Increasing the
   // Image header size would mean objects would not start at a place expected
-  // by parts of the VM (like the GC) that use Image pages as HeapPages.
-  static_assert(kHeaderSize == kMaxObjectAlignment,
-                "Image page cannot be used as HeapPage");
+  // by parts of the VM (like the GC) that use Image pages as Pages.
+  static_assert(kHeaderSize == kObjectStartAlignment,
+                "Image page cannot be used as Page");
   // Make sure that the number of fields in the Image header fit both on the
   // host and target architectures.
   static_assert(kHeaderFields * kWordSize <= kHeaderSize,
@@ -239,10 +243,10 @@
   // BSS sections contain word-sized data.
   static constexpr intptr_t kBssAlignment = compiler::target::kWordSize;
   // ROData sections contain objects wrapped in an Image object.
-  static constexpr intptr_t kRODataAlignment = kMaxObjectAlignment;
+  static constexpr intptr_t kRODataAlignment = kObjectStartAlignment;
   // Text sections contain objects (even in bare instructions mode) wrapped
   // in an Image object.
-  static constexpr intptr_t kTextAlignment = kMaxObjectAlignment;
+  static constexpr intptr_t kTextAlignment = kObjectStartAlignment;
 
   void ResetOffsets() {
     next_data_offset_ = Image::kHeaderSize;
@@ -270,7 +274,11 @@
            offset_space_ == IdSpace::kIsolateText;
   }
   int32_t GetTextOffsetFor(InstructionsPtr instructions, CodePtr code);
+#if defined(SNAPSHOT_BACKTRACE)
+  uint32_t GetDataOffsetFor(ObjectPtr raw_object, ObjectPtr raw_parent);
+#else
   uint32_t GetDataOffsetFor(ObjectPtr raw_object);
+#endif
 
   uint32_t AddBytesToData(uint8_t* bytes, intptr_t length);
 
@@ -356,10 +364,27 @@
   };
 
   struct ObjectData {
-    explicit ObjectData(ObjectPtr raw_obj)
-        : raw_obj(raw_obj), is_object(true) {}
+#if defined(SNAPSHOT_BACKTRACE)
+    explicit ObjectData(ObjectPtr raw_obj, ObjectPtr raw_parent)
+        : raw_obj(raw_obj),
+          raw_parent(raw_parent),
+          flags(IsObjectField::encode(true) |
+                IsOriginalObjectField::encode(true)) {}
     ObjectData(uint8_t* buf, intptr_t length)
-        : bytes({buf, length}), is_object(false) {}
+        : bytes({buf, length}),
+          raw_parent(Object::null()),
+          flags(IsObjectField::encode(false) |
+                IsOriginalObjectField::encode(false)) {}
+#else
+    explicit ObjectData(ObjectPtr raw_obj)
+        : raw_obj(raw_obj),
+          flags(IsObjectField::encode(true) |
+                IsOriginalObjectField::encode(true)) {}
+    ObjectData(uint8_t* buf, intptr_t length)
+        : bytes({buf, length}),
+          flags(IsObjectField::encode(false) |
+                IsOriginalObjectField::encode(false)) {}
+#endif
 
     union {
       struct {
@@ -369,7 +394,28 @@
       ObjectPtr raw_obj;
       const Object* obj;
     };
-    bool is_object;
+#if defined(SNAPSHOT_BACKTRACE)
+    union {
+      ObjectPtr raw_parent;
+      const Object* parent;
+    };
+#endif
+    uint8_t flags;
+
+    bool is_object() const {
+      return IsObjectField::decode(flags);
+    }
+    bool is_original_object() const {
+      return IsOriginalObjectField::decode(flags);
+    }
+
+    void set_is_object(bool value) {
+      flags = IsObjectField::update(value, flags);
+    }
+
+    using IsObjectField = BitField<uint8_t, bool, 0, 1>;
+    using IsOriginalObjectField =
+        BitField<uint8_t, bool, IsObjectField::kNextBit, 1>;
   };
 
   // Methods abstracting out the particulars of the underlying concrete writer.
@@ -379,7 +425,8 @@
   // this section should not be written.
   virtual bool EnterSection(ProgramSection name,
                             bool vm,
-                            intptr_t alignment) = 0;
+                            intptr_t alignment,
+                            intptr_t* alignment_padding = nullptr) = 0;
   // Marks the exit from a particular ProgramSection, allowing subclasses to
   // do any post-writing work.
   virtual void ExitSection(ProgramSection name, bool vm, intptr_t size) = 0;
@@ -415,6 +462,10 @@
   virtual void AddCodeSymbol(const Code& code,
                              const char* symbol,
                              intptr_t section_offset) = 0;
+  // Creates a static symbol for a read-only data object when appropriate.
+  virtual void AddDataSymbol(const char* symbol,
+                             intptr_t section_offset,
+                             size_t size) = 0;
 
   // Overloaded convenience versions of the above virtual methods.
 
@@ -442,6 +493,47 @@
   GrowableArray<ObjectData> objects_;
   GrowableArray<InstructionsData> instructions_;
 
+#if defined(DART_PRECOMPILER)
+  class SnapshotTextObjectNamer : ValueObject {
+   public:
+    explicit SnapshotTextObjectNamer(Zone* zone)
+        : zone_(ASSERT_NOTNULL(zone)),
+          owner_(Object::Handle(zone)),
+          string_(String::Handle(zone)),
+          insns_(Instructions::Handle(zone)),
+          store_(IsolateGroup::Current()->object_store()) {}
+
+    const char* StubNameForType(const AbstractType& type) const;
+
+    // Returns a unique assembly-safe name for text data to use in symbols.
+    // Assumes that code in the InstructionsData has been allocated a handle.
+    const char* SnapshotNameFor(const InstructionsData& data);
+    // Returns a unique assembly-safe name for read-only data to use in symbols.
+    // Assumes that the ObjectData has already been converted to object handles.
+    const char* SnapshotNameFor(const ObjectData& data);
+
+   private:
+    // Returns a unique assembly-safe name for the given code or read-only
+    // data object for use in symbols.
+    const char* SnapshotNameFor(const Object& object);
+    // Adds a non-unique assembly-safe name for the given object to the given
+    // buffer.
+    void AddNonUniqueNameFor(BaseTextBuffer* buffer, const Object& object);
+
+    Zone* const zone_;
+    Object& owner_;
+    String& string_;
+    Instructions& insns_;
+    ObjectStore* const store_;
+    TypeTestingStubNamer namer_;
+    intptr_t nonce_ = 0;
+
+    DISALLOW_COPY_AND_ASSIGN(SnapshotTextObjectNamer);
+  };
+
+  SnapshotTextObjectNamer namer_;
+#endif
+
   IdSpace offset_space_ = IdSpace::kSnapshot;
   V8SnapshotProfileWriter* profile_writer_ = nullptr;
   const char* const image_type_;
@@ -449,12 +541,8 @@
   const char* const instructions_type_;
   const char* const trampoline_type_;
 
-  // Used to make sure Code symbols are unique across text sections.
-  intptr_t unique_symbol_counter_ = 0;
-
   template <class T>
   friend class TraceImageObjectScope;
-  friend class SnapshotTextObjectNamer;  // For InstructionsData.
 
  private:
   static intptr_t SizeInSnapshotForBytes(intptr_t length);
@@ -503,32 +591,6 @@
   DISALLOW_COPY_AND_ASSIGN(TraceImageObjectScope);
 };
 
-class SnapshotTextObjectNamer : ValueObject {
- public:
-  explicit SnapshotTextObjectNamer(Zone* zone)
-      : zone_(ASSERT_NOTNULL(zone)),
-        owner_(Object::Handle(zone)),
-        string_(String::Handle(zone)),
-        insns_(Instructions::Handle(zone)),
-        store_(IsolateGroup::Current()->object_store()) {}
-
-  const char* StubNameForType(const AbstractType& type) const;
-
-  const char* SnapshotNameFor(intptr_t code_index, const Code& code);
-  const char* SnapshotNameFor(intptr_t index,
-                              const ImageWriter::InstructionsData& data);
-
- private:
-  Zone* const zone_;
-  Object& owner_;
-  String& string_;
-  Instructions& insns_;
-  ObjectStore* const store_;
-  TypeTestingStubNamer namer_;
-
-  DISALLOW_COPY_AND_ASSIGN(SnapshotTextObjectNamer);
-};
-
 class AssemblyImageWriter : public ImageWriter {
  public:
   AssemblyImageWriter(Thread* thread,
@@ -543,7 +605,8 @@
 
   virtual bool EnterSection(ProgramSection section,
                             bool vm,
-                            intptr_t alignment);
+                            intptr_t alignment,
+                            intptr_t* alignment_padding = nullptr);
   virtual void ExitSection(ProgramSection name, bool vm, intptr_t size);
   virtual intptr_t WriteTargetWord(word value);
   virtual intptr_t WriteBytes(const void* bytes, intptr_t size);
@@ -563,6 +626,7 @@
   virtual void AddCodeSymbol(const Code& code,
                              const char* symbol,
                              intptr_t offset);
+  virtual void AddDataSymbol(const char* symbol, intptr_t offset, size_t size);
 
   BaseWriteStream* const assembly_stream_;
   Dwarf* const assembly_dwarf_;
@@ -571,8 +635,8 @@
   // Used in Relocation to output "(.)" for relocations involving the current
   // section position and creating local symbols in AddCodeSymbol.
   const char* current_section_symbol_ = nullptr;
-  // Used for creating local symbols for code objects in the debugging info,
-  // if separately written.
+  // Used for creating local symbols for code and data objects in the
+  // debugging info, if separately written.
   ZoneGrowableArray<Elf::SymbolData>* current_symbols_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(AssemblyImageWriter);
@@ -593,7 +657,8 @@
 
   virtual bool EnterSection(ProgramSection section,
                             bool vm,
-                            intptr_t alignment);
+                            intptr_t alignment,
+                            intptr_t* alignment_padding = nullptr);
   virtual void ExitSection(ProgramSection name, bool vm, intptr_t size);
   virtual intptr_t WriteTargetWord(word value);
   virtual intptr_t WriteBytes(const void* bytes, intptr_t size);
@@ -616,6 +681,7 @@
   virtual void AddCodeSymbol(const Code& code,
                              const char* symbol,
                              intptr_t offset);
+  virtual void AddDataSymbol(const char* symbol, intptr_t offset, size_t size);
 
   // Set on section entrance to a new array containing the relocations for the
   // current section.
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index f3dcdf4..49f6de9 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -329,10 +329,10 @@
                            void* embedder_data,
                            ObjectStore* object_store,
                            Dart_IsolateFlags api_flags)
-    : shared_class_table_(new SharedClassTable()),
-      class_table_(new ClassTable(shared_class_table_.get())),
-      cached_class_table_table_(class_table_->table()),
+    : class_table_(nullptr),
+      cached_class_table_table_(nullptr),
       object_store_(object_store),
+      class_table_allocator_(),
       embedder_data_(embedder_data),
       thread_pool_(),
       isolates_lock_(new SafepointRwLock()),
@@ -401,6 +401,9 @@
     WriteRwLocker wl(ThreadState::Current(), isolate_groups_rwlock_);
     id_ = isolate_group_random_->NextUInt64();
   }
+  heap_walk_class_table_ = class_table_ =
+      new ClassTable(&class_table_allocator_);
+  cached_class_table_table_.store(class_table_->table());
 }
 
 IsolateGroup::IsolateGroup(std::shared_ptr<IsolateGroupSource> source,
@@ -424,6 +427,11 @@
     delete[] obfuscation_map_;
   }
 
+  class_table_allocator_.Free(class_table_);
+  if (heap_walk_class_table_ != class_table_) {
+    class_table_allocator_.Free(heap_walk_class_table_);
+  }
+
 #if !defined(PRODUCT)
   delete debugger_;
   debugger_ = nullptr;
@@ -461,7 +469,7 @@
   }
 }
 
-bool IsolateGroup::UnregisterIsolateDecrementCount(Isolate* isolate) {
+bool IsolateGroup::UnregisterIsolateDecrementCount() {
   SafepointWriteRwLocker ml(Thread::Current(), isolates_lock_.get());
   isolate_count_--;
   return isolate_count_ == 0;
@@ -1731,6 +1739,7 @@
       spawn_count_monitor_(),
       handler_info_cache_(),
       catch_entry_moves_cache_(),
+      wake_pause_event_handler_count_(0),
       loaded_prefixes_set_storage_(nullptr) {
   FlagsCopyFrom(api_flags);
   SetErrorsFatal(true);
@@ -2039,9 +2048,9 @@
 
   ASSERT(!IsReloading());
 
-  auto shared_class_table = IsolateGroup::Current()->shared_class_table();
+  auto class_table = IsolateGroup::Current()->class_table();
   std::shared_ptr<IsolateGroupReloadContext> group_reload_context(
-      new IsolateGroupReloadContext(this, shared_class_table, js));
+      new IsolateGroupReloadContext(this, class_table, js));
   group_reload_context_ = group_reload_context;
 
   SetHasAttemptedReload(true);
@@ -2068,9 +2077,9 @@
 
   ASSERT(!IsReloading());
 
-  auto shared_class_table = IsolateGroup::Current()->shared_class_table();
+  auto class_table = IsolateGroup::Current()->class_table();
   std::shared_ptr<IsolateGroupReloadContext> group_reload_context(
-      new IsolateGroupReloadContext(this, shared_class_table, js));
+      new IsolateGroupReloadContext(this, class_table, js));
   group_reload_context_ = group_reload_context;
 
   SetHasAttemptedReload(true);
@@ -2087,7 +2096,6 @@
 }
 
 void IsolateGroup::DeleteReloadContext() {
-  // Another thread may be in the middle of GetClassForHeapWalkAt.
   GcSafepointOperationScope safepoint_scope(Thread::Current());
   group_reload_context_.reset();
 
@@ -2698,8 +2706,7 @@
     }
   }
 
-  const bool shutdown_group =
-      isolate_group->UnregisterIsolateDecrementCount(isolate);
+  const bool shutdown_group = isolate_group->UnregisterIsolateDecrementCount();
   if (shutdown_group) {
     KernelIsolate::NotifyAboutIsolateGroupShutdown(isolate_group);
 
@@ -2965,10 +2972,10 @@
 }
 
 void IsolateGroup::VisitSharedPointers(ObjectPointerVisitor* visitor) {
-  // if class table is shared, it's stored on isolate group
-  if (class_table() != nullptr) {
-    // Visit objects in the class table.
-    class_table()->VisitObjectPointers(visitor);
+  // Visit objects in the class table.
+  class_table()->VisitObjectPointers(visitor);
+  if (heap_walk_class_table() != class_table()) {
+    heap_walk_class_table()->VisitObjectPointers(visitor);
   }
   api_state()->VisitObjectPointersUnlocked(visitor);
   // Visit objects in the object store.
@@ -3054,34 +3061,6 @@
                  /*at_safepoint=*/true);
 }
 
-ClassPtr IsolateGroup::GetClassForHeapWalkAt(intptr_t cid) {
-  ClassPtr raw_class = nullptr;
-#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-  if (IsReloading()) {
-    raw_class = program_reload_context()->GetClassForHeapWalkAt(cid);
-  } else {
-    raw_class = class_table()->At(cid);
-  }
-#else
-  raw_class = class_table()->At(cid);
-#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-  ASSERT(raw_class != nullptr);
-  ASSERT(remapping_cids() || raw_class->untag()->id_ == cid);
-  return raw_class;
-}
-
-intptr_t IsolateGroup::GetClassSizeForHeapWalkAt(intptr_t cid) {
-#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-  if (IsReloading()) {
-    return group_reload_context_->GetClassSizeForHeapWalkAt(cid);
-  } else {
-    return shared_class_table()->SizeAt(cid);
-  }
-#else
-  return shared_class_table()->SizeAt(cid);
-#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-}
-
 #if !defined(PRODUCT)
 ObjectIdRing* Isolate::EnsureObjectIdRing() {
   if (object_id_ring_ == nullptr) {
@@ -3503,6 +3482,20 @@
   Isolate* iso = reinterpret_cast<Isolate*>(isolate);
   MonitorLocker ml(iso->pause_loop_monitor_);
   ml.Notify();
+
+  Dart_MessageNotifyCallback current_notify_callback =
+      iso->message_notify_callback();
+  // It is possible that WakePauseEventHandler was replaced by original callback
+  // while waiting for pause_loop_monitor_. In that case PauseEventHandler
+  // is no longer running and the original callback needs to be invoked instead
+  // of incrementing wake_pause_event_handler_count_.
+  if (current_notify_callback != Isolate::WakePauseEventHandler) {
+    if (current_notify_callback != nullptr) {
+      current_notify_callback(isolate);
+    }
+  } else {
+    ++iso->wake_pause_event_handler_count_;
+  }
 }
 
 void Isolate::PauseEventHandler() {
@@ -3518,6 +3511,7 @@
   MonitorLocker ml(pause_loop_monitor_, false);
 
   Dart_MessageNotifyCallback saved_notify_callback = message_notify_callback();
+  ASSERT(wake_pause_event_handler_count_ == 0);
   set_message_notify_callback(Isolate::WakePauseEventHandler);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -3531,7 +3525,6 @@
                                               ->start_time_micros();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
   bool resume = false;
-  bool handle_non_service_messages = false;
   while (true) {
     // Handle all available vm service messages, up to a resume
     // request.
@@ -3542,8 +3535,6 @@
     }
     if (resume) {
       break;
-    } else {
-      handle_non_service_messages = true;
     }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -3567,8 +3558,13 @@
   // message notify callback to check for unhandled messages. Otherwise, events
   // may be left unhandled until the next event comes in. See
   // https://github.com/dart-lang/sdk/issues/37312.
-  if ((saved_notify_callback != nullptr) && handle_non_service_messages) {
-    saved_notify_callback(Api::CastIsolate(this));
+  if (saved_notify_callback != nullptr) {
+    while (wake_pause_event_handler_count_ > 0) {
+      saved_notify_callback(Api::CastIsolate(this));
+      --wake_pause_event_handler_count_;
+    }
+  } else {
+    wake_pause_event_handler_count_ = 0;
   }
   set_message_notify_callback(saved_notify_callback);
   Dart_ExitScope();
@@ -3850,4 +3846,26 @@
   }
 }
 
+#if !defined(PRODUCT)
+void IsolateGroup::CloneClassTableForReload() {
+  RELEASE_ASSERT(class_table_ == heap_walk_class_table_);
+  class_table_ = class_table_->Clone();
+  set_cached_class_table_table(nullptr);
+}
+
+void IsolateGroup::RestoreOriginalClassTable() {
+  RELEASE_ASSERT(class_table_ != heap_walk_class_table_);
+  class_table_allocator_.Free(class_table_);
+  class_table_ = heap_walk_class_table_;
+  set_cached_class_table_table(class_table_->table());
+}
+
+void IsolateGroup::DropOriginalClassTable() {
+  RELEASE_ASSERT(class_table_ != heap_walk_class_table_);
+  class_table_allocator_.Free(heap_walk_class_table_);
+  heap_walk_class_table_ = class_table_;
+  set_cached_class_table_table(class_table_->table());
+}
+#endif
+
 }  // namespace dart
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 472b79f..5b19f0b 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -57,6 +57,7 @@
 class HandleVisitor;
 class Heap;
 class ICData;
+class IsolateGroupReloadContext;
 class IsolateObjectStore;
 class IsolateProfilerData;
 class ProgramReloadContext;
@@ -335,7 +336,7 @@
   void UnregisterIsolate(Isolate* isolate);
   // Returns `true` if this was the last isolate and the caller is responsible
   // for deleting the isolate group.
-  bool UnregisterIsolateDecrementCount(Isolate* isolate);
+  bool UnregisterIsolateDecrementCount();
 
   bool ContainsOnlyOneIsolate();
 
@@ -393,13 +394,13 @@
     dispatch_table_snapshot_size_ = size;
   }
 
-  SharedClassTable* shared_class_table() const {
-    return shared_class_table_.get();
+  ClassTableAllocator* class_table_allocator() {
+    return &class_table_allocator_;
   }
 
-  static intptr_t shared_class_table_offset() {
-    COMPILE_ASSERT(sizeof(IsolateGroup::shared_class_table_) == kWordSize);
-    return OFFSET_OF(IsolateGroup, shared_class_table_);
+  static intptr_t class_table_offset() {
+    COMPILE_ASSERT(sizeof(IsolateGroup::class_table_) == kWordSize);
+    return OFFSET_OF(IsolateGroup, class_table_);
   }
 
   ClassPtr* cached_class_table_table() {
@@ -520,8 +521,27 @@
   }
 #endif  // defined(PRODUCT)
 
+  // Class table for the program loaded into this isolate group.
+  //
+  // This table is modified by kernel loading.
+  ClassTable* class_table() const {
+    return class_table_;
+  }
+
+  // Class table used for heap walks by GC visitors. Usually it
+  // is the same table as one in |class_table_|, except when in the
+  // middle of the reload.
+  //
+  // See comment for |ClassTable| class for more details.
+  ClassTable* heap_walk_class_table() const {
+    return heap_walk_class_table_;
+  }
+
+  void CloneClassTableForReload();
+  void RestoreOriginalClassTable();
+  void DropOriginalClassTable();
+
   StoreBuffer* store_buffer() const { return store_buffer_.get(); }
-  ClassTable* class_table() const { return class_table_.get(); }
   ObjectStore* object_store() const { return object_store_.get(); }
   Mutex* symbols_mutex() { return &symbols_mutex_; }
   Mutex* type_canonicalization_mutex() { return &type_canonicalization_mutex_; }
@@ -595,8 +615,6 @@
     deferred_load_handler_ = handler;
   }
 
-  intptr_t GetClassSizeForHeapWalkAt(intptr_t cid);
-
   // Prepares all threads in an isolate for Garbage Collection.
   void ReleaseStoreBuffers();
   void EnableIncrementalBarrier(MarkingStack* marking_stack,
@@ -695,9 +713,6 @@
   bool CanReload() { return false; }
 #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 
-  // Prefers old classes when we are in the middle of a reload.
-  ClassPtr GetClassForHeapWalkAt(intptr_t cid);
-
   bool IsReloading() const {
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
     return group_reload_context_ != nullptr;
@@ -823,12 +838,14 @@
   void set_heap(std::unique_ptr<Heap> value);
 
   // Accessed from generated code.
-  std::unique_ptr<SharedClassTable> shared_class_table_;
-  std::unique_ptr<ClassTable> class_table_;
+  ClassTable* class_table_;
   AcqRelAtomic<ClassPtr*> cached_class_table_table_;
   std::unique_ptr<ObjectStore> object_store_;
   // End accessed from generated code.
 
+  ClassTableAllocator class_table_allocator_;
+  ClassTable* heap_walk_class_table_;
+
   const char** obfuscation_map_ = nullptr;
 
   bool is_vm_isolate_heap_ = false;
@@ -1712,6 +1729,8 @@
 
   std::unique_ptr<VirtualMemory> regexp_backtracking_stack_cache_ = nullptr;
 
+  intptr_t wake_pause_event_handler_count_;
+
   static Dart_IsolateGroupCreateCallback create_group_callback_;
   static Dart_InitializeIsolateCallback initialize_callback_;
   static Dart_IsolateShutdownCallback shutdown_callback_;
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index f40c12b..16c32c3 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -97,11 +97,11 @@
 
 InstanceMorpher* InstanceMorpher::CreateFromClassDescriptors(
     Zone* zone,
-    SharedClassTable* shared_class_table,
+    ClassTable* class_table,
     const Class& from,
     const Class& to) {
-  auto mapping = new (zone) ZoneGrowableArray<intptr_t>();
-  auto new_fields_offsets = new (zone) ZoneGrowableArray<intptr_t>();
+  auto mapping = new (zone) FieldMappingArray();
+  auto new_fields_offsets = new (zone) FieldOffsetArray();
 
   if (from.NumTypeArguments() > 0) {
     // Add copying of the optional type argument field.
@@ -109,20 +109,27 @@
     ASSERT(from_offset != Class::kNoTypeArguments);
     intptr_t to_offset = to.host_type_arguments_field_offset();
     ASSERT(to_offset != Class::kNoTypeArguments);
-    mapping->Add(from_offset);
-    mapping->Add(to_offset);
+    mapping->Add({from_offset, kIllegalCid});
+    mapping->Add({to_offset, kIllegalCid});
   }
 
   // Add copying of the instance fields if matching by name.
   // Note: currently the type of the fields are ignored.
-  const Array& from_fields =
-      Array::Handle(from.OffsetToFieldMap(true /* original classes */));
+  const Array& from_fields = Array::Handle(
+      from.OffsetToFieldMap(IsolateGroup::Current()->heap_walk_class_table()));
   const Array& to_fields = Array::Handle(to.OffsetToFieldMap());
   Field& from_field = Field::Handle();
   Field& to_field = Field::Handle();
   String& from_name = String::Handle();
   String& to_name = String::Handle();
 
+  auto ensure_boxed_and_guarded = [&](const Field& field) {
+    field.set_needs_load_guard(true);
+    if (field.is_unboxed()) {
+      to.MarkFieldBoxedDuringReload(class_table, field);
+    }
+  };
+
   // Scan across all the fields in the new class definition.
   for (intptr_t i = 0; i < to_fields.Length(); i++) {
     if (to_fields.At(i) == Field::null()) {
@@ -146,36 +153,77 @@
       ASSERT(from_field.is_instance());
       from_name = from_field.name();
       if (from_name.Equals(to_name)) {
+        intptr_t from_box_cid = kIllegalCid;
+        intptr_t to_box_cid = kIllegalCid;
+
+        // Check if either of the fields are unboxed.
+        if ((from_field.is_unboxed() && from_field.type() != to_field.type()) ||
+            (from_field.is_unboxed() != to_field.is_unboxed())) {
+          // For simplicity we just migrate to boxed fields if such
+          // situation occurs.
+          ensure_boxed_and_guarded(to_field);
+        }
+
+        if (from_field.is_unboxed()) {
+          const auto field_cid = from_field.guarded_cid();
+          switch (field_cid) {
+            case kDoubleCid:
+            case kFloat32x4Cid:
+            case kFloat64x2Cid:
+              from_box_cid = field_cid;
+              break;
+            default:
+              from_box_cid = kIntegerCid;
+              break;
+          }
+        }
+
+        if (to_field.is_unboxed()) {
+          const auto field_cid = to_field.guarded_cid();
+          switch (field_cid) {
+            case kDoubleCid:
+            case kFloat32x4Cid:
+            case kFloat64x2Cid:
+              to_box_cid = field_cid;
+              break;
+            default:
+              to_box_cid = kIntegerCid;
+              break;
+          }
+        }
+
+        // Field can't become unboxed if it was boxed.
+        ASSERT(from_box_cid != kIllegalCid || to_box_cid == kIllegalCid);
+
         // Success
-        mapping->Add(from_field.HostOffset());
-        mapping->Add(to_field.HostOffset());
+        mapping->Add({from_field.HostOffset(), from_box_cid});
+        mapping->Add({to_field.HostOffset(), to_box_cid});
+
         // Field did exist in old class deifnition.
         new_field = false;
+        break;
       }
     }
 
     if (new_field) {
-      const Field& field = Field::Handle(to_field.ptr());
-      field.set_needs_load_guard(true);
-      field.set_is_unboxing_candidate_unsafe(false);
-      new_fields_offsets->Add(field.HostOffset());
+      ensure_boxed_and_guarded(to_field);
+      new_fields_offsets->Add(to_field.HostOffset());
     }
   }
 
   ASSERT(from.id() == to.id());
-  return new (zone) InstanceMorpher(zone, to.id(), shared_class_table, mapping,
-                                    new_fields_offsets);
+  return new (zone)
+      InstanceMorpher(zone, to.id(), class_table, mapping, new_fields_offsets);
 }
 
-InstanceMorpher::InstanceMorpher(
-    Zone* zone,
-    classid_t cid,
-    SharedClassTable* shared_class_table,
-    ZoneGrowableArray<intptr_t>* mapping,
-    ZoneGrowableArray<intptr_t>* new_fields_offsets)
+InstanceMorpher::InstanceMorpher(Zone* zone,
+                                 classid_t cid,
+                                 ClassTable* class_table,
+                                 FieldMappingArray* mapping,
+                                 FieldOffsetArray* new_fields_offsets)
     : zone_(zone),
       cid_(cid),
-      shared_class_table_(shared_class_table),
+      class_table_(class_table),
       mapping_(mapping),
       new_fields_offsets_(new_fields_offsets),
       before_(zone, 16) {}
@@ -212,7 +260,7 @@
     // objects to old space.
     const bool is_canonical = before.IsCanonical();
     const Heap::Space space = is_canonical ? Heap::kOld : Heap::kNew;
-    after = Instance::NewFromCidAndSize(shared_class_table_, cid_, space);
+    after = Instance::NewFromCidAndSize(class_table_, cid_, space);
 
     // We preserve the canonical bit of the object, since this object is present
     // in the class's constants.
@@ -226,16 +274,77 @@
 
     // Morph the context from [before] to [after] using mapping_.
     for (intptr_t i = 0; i < mapping_->length(); i += 2) {
-      intptr_t from_offset = mapping_->At(i);
-      intptr_t to_offset = mapping_->At(i + 1);
-      ASSERT(from_offset > 0);
-      ASSERT(to_offset > 0);
-      value = before.RawGetFieldAtOffset(from_offset);
-      after.RawSetFieldAtOffset(to_offset, value);
+      const auto& from = mapping_->At(i);
+      const auto& to = mapping_->At(i + 1);
+      ASSERT(from.offset > 0);
+      ASSERT(to.offset > 0);
+      if (from.box_cid == kIllegalCid) {
+        // Boxed to boxed field migration.
+        ASSERT(to.box_cid == kIllegalCid);
+        value = before.RawGetFieldAtOffset(from.offset);
+        after.RawSetFieldAtOffset(to.offset, value);
+      } else if (to.box_cid == kIllegalCid) {
+        // Unboxed to boxed field migration.
+        switch (from.box_cid) {
+          case kDoubleCid: {
+            const auto unboxed_value =
+                before.RawGetUnboxedFieldAtOffset<double>(from.offset);
+            value = Double::New(unboxed_value);
+            break;
+          }
+          case kFloat32x4Cid: {
+            const auto unboxed_value =
+                before.RawGetUnboxedFieldAtOffset<simd128_value_t>(from.offset);
+            value = Float32x4::New(unboxed_value);
+            break;
+          }
+          case kFloat64x2Cid: {
+            const auto unboxed_value =
+                before.RawGetUnboxedFieldAtOffset<simd128_value_t>(from.offset);
+            value = Float64x2::New(unboxed_value);
+            break;
+          }
+          case kIntegerCid: {
+            const auto unboxed_value =
+                before.RawGetUnboxedFieldAtOffset<int64_t>(from.offset);
+            value = Integer::New(unboxed_value);
+            break;
+          }
+        }
+        if (is_canonical) {
+          value = Instance::Cast(value).Canonicalize(Thread::Current());
+        }
+        after.RawSetFieldAtOffset(to.offset, value);
+      } else {
+        // Unboxed to unboxed field migration.
+        ASSERT(to.box_cid == from.box_cid);
+        switch (from.box_cid) {
+          case kDoubleCid: {
+            const auto unboxed_value =
+                before.RawGetUnboxedFieldAtOffset<double>(from.offset);
+            after.RawSetUnboxedFieldAtOffset<double>(to.offset, unboxed_value);
+            break;
+          }
+          case kFloat32x4Cid:
+          case kFloat64x2Cid: {
+            const auto unboxed_value =
+                before.RawGetUnboxedFieldAtOffset<simd128_value_t>(from.offset);
+            after.RawSetUnboxedFieldAtOffset<simd128_value_t>(to.offset,
+                                                              unboxed_value);
+            break;
+          }
+          case kIntegerCid: {
+            const auto unboxed_value =
+                before.RawGetUnboxedFieldAtOffset<int64_t>(from.offset);
+            after.RawSetUnboxedFieldAtOffset<int64_t>(to.offset, unboxed_value);
+            break;
+          }
+        }
+      }
     }
 
     for (intptr_t i = 0; i < new_fields_offsets_->length(); i++) {
-      const intptr_t field_offset = new_fields_offsets_->At(i);
+      const auto& field_offset = new_fields_offsets_->At(i);
       after.RawSetFieldAtOffset(field_offset, Object::sentinel());
     }
 
@@ -248,11 +357,33 @@
   }
 }
 
+static const char* BoxCidToCString(intptr_t box_cid) {
+  switch (box_cid) {
+    case kDoubleCid:
+      return "double";
+    case kFloat32x4Cid:
+      return "float32x4";
+    case kFloat64x2Cid:
+      return "float64x2";
+    case kIntegerCid:
+      return "int64";
+  }
+  return "?";
+}
+
 void InstanceMorpher::Dump() const {
   LogBlock blocker;
   THR_Print("Morphing objects with cid: %d via this mapping: ", cid_);
   for (int i = 0; i < mapping_->length(); i += 2) {
-    THR_Print(" %" Pd "->%" Pd, mapping_->At(i), mapping_->At(i + 1));
+    const auto& from = mapping_->At(i);
+    const auto& to = mapping_->At(i + 1);
+    THR_Print(" %" Pd "->%" Pd "", from.offset, to.offset);
+    THR_Print(" (%" Pd " -> %" Pd ")", from.box_cid, to.box_cid);
+    if (to.box_cid == kIllegalCid && from.box_cid != kIllegalCid) {
+      THR_Print("[box %s]", BoxCidToCString(from.box_cid));
+    } else if (to.box_cid != kIllegalCid) {
+      THR_Print("[%s]", BoxCidToCString(from.box_cid));
+    }
   }
   THR_Print("\n");
 }
@@ -264,9 +395,17 @@
   jsobj.AddProperty("instanceCount", before_.length());
   JSONArray map(&jsobj, "fieldOffsetMappings");
   for (int i = 0; i < mapping_->length(); i += 2) {
+    const auto& from = mapping_->At(i);
+    const auto& to = mapping_->At(i + 1);
+
     JSONArray pair(&map);
-    pair.AddValue(mapping_->At(i));
-    pair.AddValue(mapping_->At(i + 1));
+    pair.AddValue(from.offset);
+    pair.AddValue(to.offset);
+    if (to.box_cid == kIllegalCid && from.box_cid != kIllegalCid) {
+      pair.AddValueF("box %s", BoxCidToCString(from.box_cid));
+    } else if (to.box_cid != kIllegalCid) {
+      pair.AddValueF("%s", BoxCidToCString(from.box_cid));
+    }
   }
 }
 
@@ -402,15 +541,14 @@
 
 IsolateGroupReloadContext::IsolateGroupReloadContext(
     IsolateGroup* isolate_group,
-    SharedClassTable* shared_class_table,
+    ClassTable* class_table,
     JSONStream* js)
     : zone_(Thread::Current()->zone()),
       isolate_group_(isolate_group),
-      shared_class_table_(shared_class_table),
+      class_table_(class_table),
       start_time_micros_(OS::GetCurrentMonotonicMicros()),
       reload_timestamp_(OS::GetCurrentTimeMillis()),
       js_(js),
-      saved_size_table_(nullptr),
       instance_morphers_(zone_, 0),
       reasons_to_cancel_reload_(zone_, 0),
       instance_morpher_by_cid_(zone_),
@@ -425,8 +563,6 @@
     : zone_(Thread::Current()->zone()),
       group_reload_context_(group_reload_context),
       isolate_group_(isolate_group),
-      saved_class_table_(nullptr),
-      saved_tlc_class_table_(nullptr),
       old_classes_set_storage_(Array::null()),
       class_map_storage_(Array::null()),
       removed_class_set_storage_(Array::null()),
@@ -442,8 +578,7 @@
 
 ProgramReloadContext::~ProgramReloadContext() {
   ASSERT(zone_ == Thread::Current()->zone());
-  ASSERT(saved_class_table_.load(std::memory_order_relaxed) == nullptr);
-  ASSERT(saved_tlc_class_table_.load(std::memory_order_relaxed) == nullptr);
+  ASSERT(IG->class_table() == IG->heap_walk_class_table());
 }
 
 void IsolateGroupReloadContext::ReportError(const Error& error) {
@@ -671,10 +806,9 @@
     heap->CollectAllGarbage(GCReason::kDebugging, /*compact=*/ true);
   }
 
-  // Copy the size table for isolate group & class tables for each isolate.
+  // Clone the class table.
   {
     TIMELINE_SCOPE(CheckpointClasses);
-    CheckpointSharedClassTable();
     IG->program_reload_context()->CheckpointClasses();
   }
 
@@ -699,7 +833,6 @@
     const auto& error = Error::Cast(result);
     AddReasonForCancelling(new Aborted(Z, error));
 
-    DiscardSavedClassTable(/*is_rollback=*/true);
     IG->program_reload_context()->ReloadPhase4Rollback();
     CommonFinalizeTail(num_old_libs_);
   } else {
@@ -730,7 +863,8 @@
       isolate_group_->program_reload_context()->ReloadPhase4CommitPrepare();
       bool discard_class_tables = true;
       if (HasInstanceMorphers()) {
-        // Find all objects that need to be morphed (reallocated to a new size).
+        // Find all objects that need to be morphed (reallocated to a new
+        // layout).
         ObjectLocator locator(this);
         {
           HeapIterationScope iteration(Thread::Current());
@@ -747,11 +881,11 @@
         if (count > 0) {
           TIMELINE_SCOPE(MorphInstances);
 
-          // While we are reallocating instances to their new size, the heap
-          // will contain a mix of instances with the old and new sizes that
+          // While we are reallocating instances to their new layout, the heap
+          // will contain a mix of instances with the old and new layouts that
           // have the same cid. This makes the heap unwalkable until the
           // "become" operation below replaces all the instances of the old
-          // size with forwarding corpses. Force heap growth to prevent size
+          // layout with forwarding corpses. Force heap growth to prevent layout
           // confusion during this period.
           ForceGrowthScope force_growth(thread);
           // The HeapIterationScope above ensures no other GC tasks can be
@@ -761,17 +895,15 @@
           MorphInstancesPhase1Allocate(&locator, IG->become());
           {
             // Apply the new class table before "become". Become will replace
-            // all the instances of the old size with forwarding corpses, then
+            // all the instances of the old layout with forwarding corpses, then
             // perform a heap walk to fix references to the forwarding corpses.
             // During this heap walk, it will encounter instances of the new
-            // size, so it requires the new class table.
+            // layout, so it requires the new class table.
             ASSERT(HasNoTasks(heap));
 
             // We accepted the hot-reload and morphed instances. So now we can
             // commit to the changed class table and deleted the saved one.
-            DiscardSavedClassTable(/*is_rollback=*/false);
-            IG->program_reload_context()->DiscardSavedClassTable(
-                /*is_rollback=*/false);
+            IG->DropOriginalClassTable();
           }
           MorphInstancesPhase2Become(IG->become());
 
@@ -784,17 +916,31 @@
           heap->CollectAllGarbage(GCReason::kDebugging, /*compact=*/ true);
         }
       }
+      if (FLAG_identity_reload) {
+        if (!discard_class_tables) {
+          TIR_Print("Identity reload failed! Some instances were morphed\n");
+        }
+        if (IG->heap_walk_class_table()->NumCids() !=
+            IG->class_table()->NumCids()) {
+          TIR_Print("Identity reload failed! B#C=%" Pd " A#C=%" Pd "\n",
+                    IG->heap_walk_class_table()->NumCids(),
+                    IG->class_table()->NumCids());
+        }
+        if (IG->heap_walk_class_table()->NumTopLevelCids() !=
+            IG->class_table()->NumTopLevelCids()) {
+          TIR_Print("Identity reload failed! B#TLC=%" Pd " A#TLC=%" Pd "\n",
+                    IG->heap_walk_class_table()->NumTopLevelCids(),
+                    IG->class_table()->NumTopLevelCids());
+        }
+      }
       if (discard_class_tables) {
-        DiscardSavedClassTable(/*is_rollback=*/false);
-        IG->program_reload_context()->DiscardSavedClassTable(
-            /*is_rollback=*/false);
+        IG->DropOriginalClassTable();
       }
       isolate_group_->program_reload_context()->ReloadPhase4CommitFinish();
       TIR_Print("---- DONE COMMIT\n");
       isolate_group_->set_last_reload_timestamp(reload_timestamp_);
     } else {
       TIR_Print("---- ROLLING BACK");
-      DiscardSavedClassTable(/*is_rollback=*/true);
       isolate_group_->program_reload_context()->ReloadPhase4Rollback();
     }
 
@@ -1066,7 +1212,7 @@
 }
 
 void ProgramReloadContext::ReloadPhase4Rollback() {
-  RollbackClasses();
+  IG->RestoreOriginalClassTable();
   RollbackLibraries();
 }
 
@@ -1209,64 +1355,33 @@
   // TODO(rmacnak): Also call LibraryPrefix::InvalidateDependentCode.
 }
 
-void IsolateGroupReloadContext::CheckpointSharedClassTable() {
-  // Copy the size table for isolate group.
-  intptr_t* saved_size_table = nullptr;
-  shared_class_table_->CopyBeforeHotReload(&saved_size_table, &saved_num_cids_);
-
-  Thread* thread = Thread::Current();
-  {
-    NoSafepointScope no_safepoint_scope(thread);
-
-    // The saved_size_table_ will now become source of truth for GC.
-    saved_size_table_.store(saved_size_table, std::memory_order_release);
-  }
-
-  // But the concurrent sweeper may still be reading from the old table.
-  thread->heap()->WaitForSweeperTasks(thread);
-
-  // Now we can clear the old table. This satisfies asserts during class
-  // registration and encourages fast failure if we use the wrong table
-  // for GC during reload, but isn't strictly needed for correctness.
-  shared_class_table_->ResetBeforeHotReload();
-}
-
 void ProgramReloadContext::CheckpointClasses() {
   TIR_Print("---- CHECKPOINTING CLASSES\n");
-  // Checkpoint classes before a reload. We need to copy the following:
-  // 1) The size of the class table.
-  // 2) The class table itself.
+  // Checkpoint classes before a reload.
+
+  // Before this operation class table which is used for heap scanning and
+  // the class table used for program loading are the same. After this step
+  // they will become different until reload is commited (or rolled back).
+  //
+  // Note that because GC is always reading from heap_walk_class_table and
+  // we are not changing that, there is no reason to wait for sweeping
+  // threads or marking to complete.
+  RELEASE_ASSERT(IG->class_table() == IG->heap_walk_class_table());
+
+  IG->CloneClassTableForReload();
+
+  // IG->class_table() is now the clone of heap_walk_class_table.
+  RELEASE_ASSERT(IG->class_table() != IG->heap_walk_class_table());
+
+  ClassTable* class_table = IG->class_table();
+
   // For efficiency, we build a set of classes before the reload. This set
   // is used to pair new classes with old classes.
-
-  // Copy the class table for isolate.
-  ClassTable* class_table = IG->class_table();
-  ClassPtr* saved_class_table = nullptr;
-  ClassPtr* saved_tlc_class_table = nullptr;
-  class_table->CopyBeforeHotReload(&saved_class_table, &saved_tlc_class_table,
-                                   &saved_num_cids_, &saved_num_tlc_cids_);
-
-  // Copy classes into saved_class_table_ first. Make sure there are no
-  // safepoints until saved_class_table_ is filled up and saved so class raw
-  // pointers in saved_class_table_ are properly visited by GC.
-  {
-    NoSafepointScope no_safepoint_scope(Thread::Current());
-
-    // The saved_class_table_ is now source of truth for GC.
-    saved_class_table_.store(saved_class_table, std::memory_order_release);
-    saved_tlc_class_table_.store(saved_tlc_class_table,
-                                 std::memory_order_release);
-
-    // We can therefore wipe out all of the old entries (if that table is used
-    // for GC during the hot-reload we have a bug).
-    class_table->ResetBeforeHotReload();
-  }
-
   // Add classes to the set. Set is stored in the Array, so adding an element
   // may allocate Dart object on the heap and trigger GC.
   Class& cls = Class::Handle();
   UnorderedHashSet<ClassMapTraits> old_classes_set(old_classes_set_storage_);
-  for (intptr_t i = 0; i < saved_num_cids_; i++) {
+  for (intptr_t i = 0; i < class_table->NumCids(); i++) {
     if (class_table->IsValidIndex(i) && class_table->HasValidClassAt(i)) {
       if (i != kFreeListElement && i != kForwardingCorpse) {
         cls = class_table->At(i);
@@ -1275,7 +1390,7 @@
       }
     }
   }
-  for (intptr_t i = 0; i < saved_num_tlc_cids_; i++) {
+  for (intptr_t i = 0; i < class_table->NumTopLevelCids(); i++) {
     const intptr_t cid = ClassTable::CidFromTopLevelIndex(i);
     if (class_table->IsValidIndex(cid) && class_table->HasValidClassAt(cid)) {
       cls = class_table->At(cid);
@@ -1284,7 +1399,8 @@
     }
   }
   old_classes_set_storage_ = old_classes_set.Release().ptr();
-  TIR_Print("---- System had %" Pd " classes\n", saved_num_cids_);
+  TIR_Print("---- System had %" Pd " classes\n",
+            class_table->NumCids() + class_table->NumTopLevelCids());
 }
 
 Dart_FileModifiedCallback IsolateGroupReloadContext::file_modified_callback_ =
@@ -1429,14 +1545,6 @@
   object_store()->set_root_library(Library::Handle());
 }
 
-void ProgramReloadContext::RollbackClasses() {
-  TIR_Print("---- ROLLING BACK CLASS TABLE\n");
-  ASSERT((saved_num_cids_ + saved_num_tlc_cids_) > 0);
-  ASSERT(saved_class_table_.load(std::memory_order_relaxed) != nullptr);
-  ASSERT(saved_tlc_class_table_.load(std::memory_order_relaxed) != nullptr);
-
-  DiscardSavedClassTable(/*is_rollback=*/true);
-}
 
 void ProgramReloadContext::RollbackLibraries() {
   TIR_Print("---- ROLLING BACK LIBRARY CHANGES\n");
@@ -1618,14 +1726,6 @@
 #endif
 
   if (FLAG_identity_reload) {
-    if (saved_num_cids_ != IG->class_table()->NumCids()) {
-      TIR_Print("Identity reload failed! B#C=%" Pd " A#C=%" Pd "\n",
-                saved_num_cids_, IG->class_table()->NumCids());
-    }
-    if (saved_num_tlc_cids_ != IG->class_table()->NumTopLevelCids()) {
-      TIR_Print("Identity reload failed! B#TLC=%" Pd " A#TLC=%" Pd "\n",
-                saved_num_tlc_cids_, IG->class_table()->NumTopLevelCids());
-    }
     const auto& saved_libs = GrowableObjectArray::Handle(saved_libraries_);
     const GrowableObjectArray& libs =
         GrowableObjectArray::Handle(IG->object_store()->libraries());
@@ -1704,8 +1804,8 @@
   ASSERT(HasInstanceMorphers());
 
   become->Forward();
-  // The heap now contains only instances with the new size. Ordinary GC is safe
-  // again.
+  // The heap now contains only instances with the new layout.
+  // Ordinary GC is safe again.
 }
 
 void IsolateGroupReloadContext::ForEachIsolate(
@@ -1755,60 +1855,6 @@
   }
 }
 
-ClassPtr ProgramReloadContext::GetClassForHeapWalkAt(intptr_t cid) {
-  ClassPtr* class_table = nullptr;
-  intptr_t index = -1;
-  if (ClassTable::IsTopLevelCid(cid)) {
-    class_table = saved_tlc_class_table_.load(std::memory_order_acquire);
-    index = ClassTable::IndexFromTopLevelCid(cid);
-    ASSERT(index < saved_num_tlc_cids_);
-  } else {
-    class_table = saved_class_table_.load(std::memory_order_acquire);
-    index = cid;
-    ASSERT(cid > 0 && cid < saved_num_cids_);
-  }
-  if (class_table != nullptr) {
-    return class_table[index];
-  }
-  return IG->class_table()->At(cid);
-}
-
-intptr_t IsolateGroupReloadContext::GetClassSizeForHeapWalkAt(classid_t cid) {
-  if (ClassTable::IsTopLevelCid(cid)) {
-    return 0;
-  }
-  intptr_t* size_table = saved_size_table_.load(std::memory_order_acquire);
-  if (size_table != nullptr) {
-    ASSERT(cid < saved_num_cids_);
-    return size_table[cid];
-  } else {
-    return shared_class_table_->SizeAt(cid);
-  }
-}
-
-void ProgramReloadContext::DiscardSavedClassTable(bool is_rollback) {
-  ClassPtr* local_saved_class_table =
-      saved_class_table_.load(std::memory_order_relaxed);
-  ClassPtr* local_saved_tlc_class_table =
-      saved_tlc_class_table_.load(std::memory_order_relaxed);
-  {
-    auto thread = Thread::Current();
-    SafepointWriteRwLocker sl(thread, thread->isolate_group()->program_lock());
-    IG->class_table()->ResetAfterHotReload(
-        local_saved_class_table, local_saved_tlc_class_table, saved_num_cids_,
-        saved_num_tlc_cids_, is_rollback);
-  }
-  saved_class_table_.store(nullptr, std::memory_order_release);
-  saved_tlc_class_table_.store(nullptr, std::memory_order_release);
-}
-
-void IsolateGroupReloadContext::DiscardSavedClassTable(bool is_rollback) {
-  intptr_t* local_saved_size_table = saved_size_table_;
-  shared_class_table_->ResetAfterHotReload(local_saved_size_table,
-                                           saved_num_cids_, is_rollback);
-  saved_size_table_.store(nullptr, std::memory_order_release);
-}
-
 void IsolateGroupReloadContext::VisitObjectPointers(
     ObjectPointerVisitor* visitor) {
   visitor->VisitPointers(from(), to());
@@ -1816,20 +1862,6 @@
 
 void ProgramReloadContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   visitor->VisitPointers(from(), to());
-
-  ClassPtr* saved_class_table =
-      saved_class_table_.load(std::memory_order_relaxed);
-  if (saved_class_table != NULL) {
-    auto class_table = reinterpret_cast<ObjectPtr*>(&(saved_class_table[0]));
-    visitor->VisitPointers(class_table, saved_num_cids_);
-  }
-  ClassPtr* saved_tlc_class_table =
-      saved_tlc_class_table_.load(std::memory_order_relaxed);
-  if (saved_tlc_class_table != NULL) {
-    auto class_table =
-        reinterpret_cast<ObjectPtr*>(&(saved_tlc_class_table[0]));
-    visitor->VisitPointers(class_table, saved_num_tlc_cids_);
-  }
 }
 
 ObjectStore* ProgramReloadContext::object_store() {
@@ -2177,6 +2209,10 @@
     if (field.needs_load_guard()) {
       return;  // Already guarding.
     }
+    if (field.is_unboxed()) {
+      // Unboxed fields are guaranteed to match.
+      return;
+    }
     value_ = instance.GetField(field);
     if (value_.ptr() == Object::sentinel().ptr()) {
       if (field.is_late()) {
@@ -2270,11 +2306,17 @@
         ASSERT(!FLAG_identity_reload || instance_.IsNull());
         field.set_needs_load_guard(true);
       } else {
-        cache_.AddCheck(instance_cid_or_signature_, type_,
-                        instance_type_arguments_, instantiator_type_arguments_,
-                        function_type_arguments_,
-                        parent_function_type_arguments_,
-                        delayed_function_type_arguments_, Bool::True());
+        // Do not add record instances to cache as they don't have a valid
+        // key (type of a record depends on types of all its fields).
+        // TODO(dartbug.com/49719): consider testing each record field using
+        // SubtypeTestCache.
+        if (cid != kRecordCid) {
+          cache_.AddCheck(
+              instance_cid_or_signature_, type_, instance_type_arguments_,
+              instantiator_type_arguments_, function_type_arguments_,
+              parent_function_type_arguments_, delayed_function_type_arguments_,
+              Bool::True());
+        }
       }
     }
   }
diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h
index 07978e4..07361e0 100644
--- a/runtime/vm/isolate_reload.h
+++ b/runtime/vm/isolate_reload.h
@@ -52,21 +52,28 @@
 class Script;
 class UpdateClassesVisitor;
 
+struct FieldMapping {
+  intptr_t offset;
+  intptr_t box_cid;  // kIllegalCid if field is boxed
+};
+
+using FieldMappingArray = ZoneGrowableArray<FieldMapping>;
+using FieldOffsetArray = ZoneGrowableArray<intptr_t>;
+
 class InstanceMorpher : public ZoneAllocated {
  public:
   // Creates a new [InstanceMorpher] based on the [from]/[to] class
   // descriptions.
-  static InstanceMorpher* CreateFromClassDescriptors(
-      Zone* zone,
-      SharedClassTable* shared_class_table,
-      const Class& from,
-      const Class& to);
+  static InstanceMorpher* CreateFromClassDescriptors(Zone* zone,
+                                                     ClassTable* class_table,
+                                                     const Class& from,
+                                                     const Class& to);
 
   InstanceMorpher(Zone* zone,
                   classid_t cid,
-                  SharedClassTable* shared_class_table,
-                  ZoneGrowableArray<intptr_t>* mapping,
-                  ZoneGrowableArray<intptr_t>* new_fields_offsets);
+                  ClassTable* class_table,
+                  FieldMappingArray* mapping,
+                  FieldOffsetArray* new_fields_offsets);
   virtual ~InstanceMorpher() {}
 
   // Adds an object to be morphed.
@@ -87,9 +94,9 @@
  private:
   Zone* zone_;
   classid_t cid_;
-  SharedClassTable* shared_class_table_;
-  ZoneGrowableArray<intptr_t>* mapping_;
-  ZoneGrowableArray<intptr_t>* new_fields_offsets_;
+  ClassTable* class_table_;
+  FieldMappingArray* mapping_;
+  FieldOffsetArray* new_fields_offsets_;
 
   GrowableArray<const Instance*> before_;
 };
@@ -130,7 +137,7 @@
 class IsolateGroupReloadContext {
  public:
   IsolateGroupReloadContext(IsolateGroup* isolate,
-                            SharedClassTable* shared_class_table,
+                            ClassTable* class_table,
                             JSONStream* js);
   ~IsolateGroupReloadContext();
 
@@ -144,10 +151,6 @@
   // All zone allocated objects must be allocated from this zone.
   Zone* zone() const { return zone_; }
 
-  bool UseSavedSizeTableForGC() const {
-    return saved_size_table_.load(std::memory_order_relaxed) != nullptr;
-  }
-
   IsolateGroup* isolate_group() const { return isolate_group_; }
   bool reload_aborted() const { return HasReasonsForCancelling(); }
   bool reload_skipped() const { return reload_skipped_; }
@@ -163,9 +166,6 @@
   }
 
  private:
-  intptr_t GetClassSizeForHeapWalkAt(classid_t cid);
-  void DiscardSavedClassTable(bool is_rollback);
-
   // Tells whether there are reasons for cancelling the reload.
   bool HasReasonsForCancelling() const {
     return !reasons_to_cancel_reload_.is_empty();
@@ -209,8 +209,6 @@
                            const char* packages_url);
   bool ScriptModifiedSince(const Script& script, int64_t since);
 
-  void CheckpointSharedClassTable();
-
   void MorphInstancesPhase1Allocate(ObjectLocator* locator, Become* become);
   void MorphInstancesPhase2Become(Become* become);
 
@@ -220,7 +218,7 @@
   Zone* zone_;
 
   IsolateGroup* isolate_group_;
-  SharedClassTable* shared_class_table_;
+  ClassTable* class_table_;
 
   int64_t start_time_micros_ = -1;
   int64_t reload_timestamp_ = -1;
@@ -229,8 +227,6 @@
   JSONStream* js_;
   intptr_t num_old_libs_ = -1;
 
-  intptr_t saved_num_cids_ = -1;
-  std::atomic<intptr_t*> saved_size_table_;
   intptr_t num_received_libs_ = -1;
   intptr_t bytes_received_libs_ = -1;
   intptr_t num_received_classes_ = -1;
@@ -283,8 +279,7 @@
   friend class ObjectLocator;
   friend class ReasonForCancelling;
   friend class ProgramReloadContext;
-  friend class IsolateGroup;  // GetClassSizeForHeapWalkAt
-  friend class UntaggedObject;  // GetClassSizeForHeapWalkAt
+  friend class IsolateGroup;
 
   static Dart_FileModifiedCallback file_modified_callback_;
 };
@@ -309,10 +304,6 @@
  private:
   bool IsDirty(const Library& lib);
 
-  // Prefers old classes when we are in the middle of a reload.
-  ClassPtr GetClassForHeapWalkAt(intptr_t cid);
-  void DiscardSavedClassTable(bool is_rollback);
-
   void RegisterClass(const Class& new_cls);
 
   // Finds the library private key for |replacement_or_new| or return null
@@ -338,7 +329,6 @@
 
   void CheckpointLibraries();
 
-  void RollbackClasses();
   void RollbackLibraries();
 
 #ifdef DEBUG
@@ -373,10 +363,6 @@
   Zone* zone_;
   std::shared_ptr<IsolateGroupReloadContext> group_reload_context_;
   IsolateGroup* isolate_group_;
-  intptr_t saved_num_cids_ = -1;
-  intptr_t saved_num_tlc_cids_ = -1;
-  std::atomic<ClassPtr*> saved_class_table_;
-  std::atomic<ClassPtr*> saved_tlc_class_table_;
   MallocGrowableArray<LibraryInfo> library_infos_;
 
   ClassPtr OldClassOrNull(const Class& replacement_or_new);
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index 0aacc35..72bed37 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -4205,21 +4205,45 @@
   }
 }
 
-TEST_CASE(IsolateReload_ExistingFieldChangesType) {
+static void TestReloadWithFieldChange(const char* prefix,
+                                      const char* suffix,
+                                      const char* verify,
+                                      const char* from_type,
+                                      const char* from_init,
+                                      const char* to_type,
+                                      const char* to_init) {
   const char* late_tag = TestCase::LateTag();
   // clang-format off
   auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr,
                                                      R"(
+    import 'dart:typed_data';
+
+    void doubleEq(double got, double expected) {
+      if (got != expected) throw 'expected $expected got $got';
+    }
+
+    void float32x4Eq(Float32x4 got, Float32x4 expected) {
+      if (got.equal(expected).signMask != 0xf) throw 'expected $expected got $got';
+    }
+
     class Foo {
-      int x = 42;
+      %s
+      %s x = %s;
+      %s
     }
     %s Foo value;
     main() {
       value = Foo();
+      %s
       return 'Okay';
     }
   )",
-  late_tag), std::free);
+  prefix,
+  from_type,
+  from_init,
+  suffix,
+  late_tag,
+  verify), std::free);
   // clang-format on
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
@@ -4228,28 +4252,92 @@
 
   // clang-format off
   auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
+    import 'dart:typed_data';
+
+    void doubleEq(double got, double expected) {
+      if (got != expected) throw 'expected $expected got $got';
+    }
+
+    void float32x4Eq(Float32x4 got, Float32x4 expected) {
+      if (got.equal(expected).signMask != 0xf) throw 'expected $expected got $got';
+    }
+
     class Foo {
-      double x = 42.0;
+      %s
+      %s x = %s;
+      %s
     }
     %s Foo value;
     main() {
       try {
+        %s
         return value.x.toString();
       } catch (e) {
         return e.toString();
       }
     }
-  )",
-  late_tag), std::free);
+  )", prefix, to_type, to_init, suffix,
+  late_tag, verify), std::free);
   // clang-format on
 
   lib = TestCase::ReloadTestScript(kReloadScript.get());
   EXPECT_VALID(lib);
   EXPECT_STREQ(
-      "type 'int' is not a subtype of type 'double' of 'function result'",
+      OS::SCreate(
+          Thread::Current()->zone(),
+          "type '%s' is not a subtype of type '%s' of 'function result'",
+          from_type, to_type),
       SimpleInvokeStr(lib, "main"));
 }
 
+TEST_CASE(IsolateReload_ExistingFieldChangesType) {
+  TestReloadWithFieldChange(/*prefix=*/"", /*suffix=*/"", /*verify=*/"",
+                            /*from_type=*/"int", /*from_init=*/"42",
+                            /*to_type=*/"double", /*to_init=*/"42.0");
+}
+
+TEST_CASE(IsolateReload_ExistingFieldChangesTypeWithOtherUnboxedFields) {
+  TestReloadWithFieldChange(
+      /*prefix=*/"double a = 1.5;",
+      /*suffix=*/"Float32x4 b = Float32x4(1.0, 2.0, 3.0, 4.0);", /*verify=*/
+      "doubleEq(value.a, 1.5); float32x4Eq(value.b, Float32x4(1.0, 2.0, 3.0, "
+      "4.0));",
+      /*from_type=*/"int", /*from_init=*/"42", /*to_type=*/"double",
+      /*to_init=*/"42.0");
+}
+
+TEST_CASE(IsolateReload_ExistingFieldUnboxedToBoxed) {
+  TestReloadWithFieldChange(
+      /*prefix=*/"double a = 1.5;",
+      /*suffix=*/"Float32x4 b = Float32x4(1.0, 2.0, 3.0, 4.0);", /*verify=*/
+      "doubleEq(value.a, 1.5); float32x4Eq(value.b, Float32x4(1.0, 2.0, 3.0, "
+      "4.0));",
+      /*from_type=*/"double", /*from_init=*/"42.0", /*to_type=*/"String",
+      /*to_init=*/"'42'");
+}
+
+TEST_CASE(IsolateReload_ExistingFieldBoxedToUnboxed) {
+  // Note: underlying field will not actually be unboxed.
+  TestReloadWithFieldChange(
+      /*prefix=*/"double a = 1.5;",
+      /*suffix=*/"Float32x4 b = Float32x4(1.0, 2.0, 3.0, 4.0);", /*verify=*/
+      "doubleEq(value.a, 1.5); float32x4Eq(value.b, Float32x4(1.0, 2.0, 3.0, "
+      "4.0));",
+      /*from_type=*/"String", /*from_init=*/"'42.0'", /*to_type=*/"double",
+      /*to_init=*/"42.0");
+}
+
+TEST_CASE(IsolateReload_ExistingFieldUnboxedToUnboxed) {
+  // Note: underlying field will not actually be unboxed.
+  TestReloadWithFieldChange(
+      /*prefix=*/"double a = 1.5;",
+      /*suffix=*/"Float32x4 b = Float32x4(1.0, 2.0, 3.0, 4.0);", /*verify=*/
+      "doubleEq(value.a, 1.5); float32x4Eq(value.b, Float32x4(1.0, 2.0, 3.0, "
+      "4.0));",
+      /*from_type=*/"double", /*from_init=*/"42.0", /*to_type=*/"Float32x4",
+      /*to_init=*/"Float32x4(1.0, 2.0, 3.0, 4.0)");
+}
+
 TEST_CASE(IsolateReload_ExistingStaticFieldChangesType) {
   const char* kScript = R"(
     int value = init();
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 6efcbf6..3347661 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -125,9 +125,6 @@
   V(AsyncForInStatement, 80)                                                   \
   V(AssertBlock, 81)                                                           \
   V(TypedefType, 87)                                                           \
-  V(NeverType, 98)                                                             \
-  V(IntersectionType, 99)                                                      \
-  V(RecordType, 100)                                                           \
   V(InvalidType, 90)                                                           \
   V(DynamicType, 91)                                                           \
   V(VoidType, 92)                                                              \
@@ -136,6 +133,9 @@
   V(TypeParameterType, 95)                                                     \
   V(SimpleInterfaceType, 96)                                                   \
   V(SimpleFunctionType, 97)                                                    \
+  V(NeverType, 98)                                                             \
+  V(IntersectionType, 99)                                                      \
+  V(RecordType, 100)                                                           \
   V(ConstantExpression, 106)                                                   \
   V(InstanceGet, 118)                                                          \
   V(InstanceSet, 119)                                                          \
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 0ffba9b..f91e60a 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -377,7 +377,7 @@
       source_code->value.as_typed_data.type = Dart_TypedData_kUint8;
       source_code->value.as_typed_data.length = strlen(source_files[i].source);
       source_code->value.as_typed_data.values =
-          reinterpret_cast<uint8_t*>(const_cast<char*>(source_files[i].source));
+          reinterpret_cast<const uint8_t*>(source_files[i].source);
     } else {
       source_code->type = Dart_CObject_kNull;
     }
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 67834c1..1fdb5bd 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -869,17 +869,15 @@
   field.set_is_nullable(type.IsNullable());
   field.set_guarded_list_length(Field::kNoFixedLength);
   if (FLAG_precompiled_mode) {
-    field.set_is_unboxing_candidate(
-        !field.is_late() && !field.is_static() &&
-        ((field.guarded_cid() == kDoubleCid &&
-          FlowGraphCompiler::SupportsUnboxedDoubles()) ||
-         (field.guarded_cid() == kFloat32x4Cid &&
-          FlowGraphCompiler::SupportsUnboxedSimd128()) ||
-         (field.guarded_cid() == kFloat64x2Cid &&
-          FlowGraphCompiler::SupportsUnboxedSimd128()) ||
-         type.IsInt()) &&
-        !field.is_nullable());
-    field.set_is_non_nullable_integer(!field.is_nullable() && type.IsInt());
+    field.set_is_unboxed(!field.is_late() && !field.is_static() &&
+                         !field.is_nullable() &&
+                         ((field.guarded_cid() == kDoubleCid &&
+                           FlowGraphCompiler::SupportsUnboxedDoubles()) ||
+                          (field.guarded_cid() == kFloat32x4Cid &&
+                           FlowGraphCompiler::SupportsUnboxedSimd128()) ||
+                          (field.guarded_cid() == kFloat64x2Cid &&
+                           FlowGraphCompiler::SupportsUnboxedSimd128()) ||
+                          type.IsInt()));
   }
 }
 
@@ -1177,11 +1175,10 @@
     field_helper.ReadUntilExcluding(FieldHelper::kEnd);
 
     {
-      // GenerateFieldAccessors reads (some of) the initializer.
       AlternativeReadingScope alt(&helper_.reader_, field_initializer_offset);
-      static_field_value_ =
-          GenerateFieldAccessors(toplevel_class, field, &field_helper);
+      static_field_value_ = ReadInitialFieldValue(field, &field_helper);
     }
+    GenerateFieldAccessors(toplevel_class, field, &field_helper);
     IG->RegisterStaticField(field, static_field_value_);
 
     if ((FLAG_enable_mirrors || has_pragma_annotation) &&
@@ -1560,11 +1557,10 @@
       field_helper.ReadUntilExcluding(FieldHelper::kEnd);
 
       {
-        // GenerateFieldAccessors reads (some of) the initializer.
         AlternativeReadingScope alt(&helper_.reader_, field_initializer_offset);
-        static_field_value_ =
-            GenerateFieldAccessors(klass, field, &field_helper);
+        static_field_value_ = ReadInitialFieldValue(field, &field_helper);
       }
+      GenerateFieldAccessors(klass, field, &field_helper);
       if (field.is_static()) {
         IG->RegisterStaticField(field, static_field_value_);
       }
@@ -2179,9 +2175,8 @@
   return script.ptr();
 }
 
-ObjectPtr KernelLoader::GenerateFieldAccessors(const Class& klass,
-                                               const Field& field,
-                                               FieldHelper* field_helper) {
+ObjectPtr KernelLoader::ReadInitialFieldValue(const Field& field,
+                                              FieldHelper* field_helper) {
   const Tag tag = helper_.PeekTag();
   const bool has_initializer = (tag == kSomething);
 
@@ -2193,14 +2188,7 @@
       if (field_helper->IsStatic()) {
         return converter.SimpleValue().ptr();
       } else {
-        // Note: optimizer relies on DoubleInitialized bit in its field-unboxing
-        // heuristics. See JitCallSpecializer::VisitStoreField for more
-        // details.
         field.RecordStore(converter.SimpleValue());
-        if (!converter.SimpleValue().IsNull() &&
-            converter.SimpleValue().IsDouble()) {
-          field.set_is_double_initialized(true);
-        }
       }
     }
   }
@@ -2208,45 +2196,64 @@
   if (field_helper->IsStatic()) {
     if (!has_initializer && !field_helper->IsLate()) {
       // Static fields without an initializer are implicitly initialized to
-      // null. We do not need a getter.
+      // null.
       return Instance::null();
     }
   }
   ASSERT(field.NeedsGetter());
 
-  const String& getter_name =
-      H.DartGetterName(field_helper->canonical_name_getter_);
+  // If static, we do need a getter that evaluates the initializer if necessary.
+  return field_helper->IsStatic() ? Object::sentinel().ptr() : Object::null();
+}
+
+void KernelLoader::GenerateFieldAccessors(const Class& klass,
+                                          const Field& field,
+                                          FieldHelper* field_helper) {
+  const bool needs_getter = field.NeedsGetter();
+  const bool needs_setter = field.NeedsSetter();
+
+  if (!needs_getter && !needs_setter) {
+    return;
+  }
+
   const Object& script_class =
       ClassForScriptAt(klass, field_helper->source_uri_index_);
-  const FunctionType& signature = FunctionType::Handle(Z, FunctionType::New());
-  Function& getter = Function::ZoneHandle(
-      Z,
-      Function::New(
-          signature, getter_name,
-          field_helper->IsStatic() ? UntaggedFunction::kImplicitStaticGetter
-                                   : UntaggedFunction::kImplicitGetter,
-          field_helper->IsStatic(),
-          // The functions created by the parser have is_const for static fields
-          // that are const (not just final) and they have is_const for
-          // non-static fields that are final.
-          field_helper->IsStatic() ? field_helper->IsConst()
-                                   : field_helper->IsFinal(),
-          false,  // is_abstract
-          false,  // is_external
-          false,  // is_native
-          script_class, field_helper->position_));
-  functions_.Add(&getter);
-  getter.set_end_token_pos(field_helper->end_position_);
-  getter.set_kernel_offset(field.kernel_offset());
   const AbstractType& field_type = AbstractType::Handle(Z, field.type());
-  signature.set_result_type(field_type);
-  getter.set_is_debuggable(false);
-  getter.set_accessor_field(field);
-  getter.set_is_extension_member(field.is_extension_member());
-  H.SetupFieldAccessorFunction(klass, getter, field_type);
-  T.SetupUnboxingInfoMetadataForFieldAccessors(getter, library_kernel_offset_);
 
-  if (field.NeedsSetter()) {
+  if (needs_getter) {
+    const String& getter_name =
+        H.DartGetterName(field_helper->canonical_name_getter_);
+    const FunctionType& signature =
+        FunctionType::Handle(Z, FunctionType::New());
+    Function& getter = Function::ZoneHandle(
+        Z,
+        Function::New(
+            signature, getter_name,
+            field_helper->IsStatic() ? UntaggedFunction::kImplicitStaticGetter
+                                     : UntaggedFunction::kImplicitGetter,
+            field_helper->IsStatic(),
+            // The functions created by the parser have is_const for static
+            // fields that are const (not just final) and they have is_const
+            // for non-static fields that are final.
+            field_helper->IsStatic() ? field_helper->IsConst()
+                                     : field_helper->IsFinal(),
+            false,  // is_abstract
+            false,  // is_external
+            false,  // is_native
+            script_class, field_helper->position_));
+    functions_.Add(&getter);
+    getter.set_end_token_pos(field_helper->end_position_);
+    getter.set_kernel_offset(field.kernel_offset());
+    signature.set_result_type(field_type);
+    getter.set_is_debuggable(false);
+    getter.set_accessor_field(field);
+    getter.set_is_extension_member(field.is_extension_member());
+    H.SetupFieldAccessorFunction(klass, getter, field_type);
+    T.SetupUnboxingInfoMetadataForFieldAccessors(getter,
+                                                 library_kernel_offset_);
+  }
+
+  if (needs_setter) {
     // Only static fields can be const.
     ASSERT(!field_helper->IsConst());
     const String& setter_name =
@@ -2273,9 +2280,6 @@
     T.SetupUnboxingInfoMetadataForFieldAccessors(setter,
                                                  library_kernel_offset_);
   }
-
-  // If static, we do need a getter that evaluates the initializer if necessary.
-  return field_helper->IsStatic() ? Object::sentinel().ptr() : Object::null();
 }
 
 LibraryPtr KernelLoader::LookupLibraryOrNull(NameIndex library) {
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index 5654ca9..af10b3b 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -318,11 +318,14 @@
     return kernel_program_info_.ScriptAt(source_uri_index);
   }
 
-  // Returns the initial field value for a static function (if applicable).
-  ObjectPtr GenerateFieldAccessors(const Class& klass,
-                                   const Field& field,
-                                   FieldHelper* field_helper);
-  bool FieldNeedsSetter(FieldHelper* field_helper);
+  // Reads field initializer and returns the initial field value.
+  ObjectPtr ReadInitialFieldValue(const Field& field,
+                                  FieldHelper* field_helper);
+
+  // Generates field getter and setter functions.
+  void GenerateFieldAccessors(const Class& klass,
+                              const Field& field,
+                              FieldHelper* field_helper);
 
   void LoadLibraryImportsAndExports(Library* library,
                                     const Class& toplevel_class);
diff --git a/runtime/vm/malloc_hooks_test.cc b/runtime/vm/malloc_hooks_test.cc
index d04ab64..63c04b9 100644
--- a/runtime/vm/malloc_hooks_test.cc
+++ b/runtime/vm/malloc_hooks_test.cc
@@ -112,6 +112,11 @@
   EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes());
 }
 
+DART_NOINLINE
+static void* IgnoreUseAfterFree(void* x) {
+  return x;
+}
+
 VM_UNIT_TEST_CASE(StackTraceMallocHookSimpleTest) {
   EnableMallocHooksAndStacksScope scope;
 
@@ -119,8 +124,9 @@
   Sample* sample = MallocHooks::GetSample(var);
   EXPECT(sample != NULL);
 
+  void* lookup_var = IgnoreUseAfterFree(var);
   free(var);
-  sample = MallocHooks::GetSample(var);
+  sample = MallocHooks::GetSample(lookup_var);
   EXPECT(sample == NULL);
 }
 
diff --git a/runtime/vm/message.h b/runtime/vm/message.h
index 46064a9..31bdb4a 100644
--- a/runtime/vm/message.h
+++ b/runtime/vm/message.h
@@ -21,9 +21,6 @@
 
 class JSONStream;
 class PersistentHandle;
-class OldPage;
-class WeakTable;
-class FreeList;
 
 class Message {
  public:
diff --git a/runtime/vm/message_snapshot.cc b/runtime/vm/message_snapshot.cc
index 936ec2a..389d347 100644
--- a/runtime/vm/message_snapshot.cc
+++ b/runtime/vm/message_snapshot.cc
@@ -822,17 +822,13 @@
     objects_.Add(instance);
 
     const intptr_t next_field_offset = next_field_offset_;
-#if defined(DART_PRECOMPILED_RUNTIME)
     const auto unboxed_fields_bitmap =
-        s->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(cid_);
-#endif
+        s->isolate_group()->class_table()->GetUnboxedFieldsMapAt(cid_);
     for (intptr_t offset = Instance::NextFieldOffset();
          offset < next_field_offset; offset += kCompressedWordSize) {
-#if defined(DART_PRECOMPILED_RUNTIME)
       if (unboxed_fields_bitmap.Get(offset / kCompressedWordSize)) {
         continue;
       }
-#endif
       s->Push(reinterpret_cast<CompressedObjectPtr*>(
                   reinterpret_cast<uword>(instance->untag()) + offset)
                   ->Decompress(instance->untag()->heap_base()));
@@ -856,13 +852,10 @@
       Instance* instance = objects_[i];
 
       const intptr_t next_field_offset = next_field_offset_;
-#if defined(DART_PRECOMPILED_RUNTIME)
       const auto unboxed_fields_bitmap =
-          s->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(cid_);
-#endif
+          s->isolate_group()->class_table()->GetUnboxedFieldsMapAt(cid_);
       for (intptr_t offset = Instance::NextFieldOffset();
            offset < next_field_offset; offset += kCompressedWordSize) {
-#if defined(DART_PRECOMPILED_RUNTIME)
         if (unboxed_fields_bitmap.Get(offset / kCompressedWordSize)) {
           // Writes 32 bits of the unboxed value at a time
           const uword value = *reinterpret_cast<compressed_uword*>(
@@ -870,7 +863,6 @@
           s->WriteWordWith32BitWrites(value);
           continue;
         }
-#endif
         s->WriteRef(reinterpret_cast<CompressedObjectPtr*>(
                         reinterpret_cast<uword>(instance->untag()) + offset)
                         ->Decompress(instance->untag()->heap_base()));
@@ -905,11 +897,9 @@
 
   void ReadEdges(MessageDeserializer* d) {
     const intptr_t next_field_offset = cls_.host_next_field_offset();
-#if defined(DART_PRECOMPILED_RUNTIME)
     const auto unboxed_fields_bitmap =
-        d->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(
-            cls_.id());
-#else
+        d->isolate_group()->class_table()->GetUnboxedFieldsMapAt(cls_.id());
+#if !defined(DART_PRECOMPILED_RUNTIME)
     const intptr_t type_argument_field_offset =
         cls_.host_type_arguments_field_offset();
     const bool use_field_guards = d->isolate_group()->use_field_guards();
@@ -923,7 +913,6 @@
       instance ^= d->Ref(id);
       for (intptr_t offset = Instance::NextFieldOffset();
            offset < next_field_offset; offset += kCompressedWordSize) {
-#if defined(DART_PRECOMPILED_RUNTIME)
         if (unboxed_fields_bitmap.Get(offset / kCompressedWordSize)) {
           compressed_uword* p = reinterpret_cast<compressed_uword*>(
               reinterpret_cast<uword>(instance.untag()) + offset);
@@ -931,7 +920,6 @@
           *p = d->ReadWordWith32BitReads();
           continue;
         }
-#endif
         value = d->ReadRef();
         instance.SetFieldAtOffset(offset, value);
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -1611,8 +1599,7 @@
       s->AssignRef(data);
       intptr_t length = data->value.as_external_typed_data.length;
       s->WriteUnsigned(length);
-      uint8_t* cdata =
-          reinterpret_cast<uint8_t*>(data->value.as_typed_data.values);
+      const uint8_t* cdata = data->value.as_typed_data.values;
       s->WriteBytes(cdata, length * element_size);
     }
   }
@@ -1701,8 +1688,7 @@
       if (length == 0) {
         data->value.as_typed_data.values = NULL;
       } else {
-        data->value.as_typed_data.values =
-            const_cast<uint8_t*>(d->CurrentBufferAddress());
+        data->value.as_typed_data.values = d->CurrentBufferAddress();
         d->Advance(length * element_size);
       }
       d->AssignRef(data);
@@ -1931,6 +1917,11 @@
   const intptr_t cid_;
 };
 
+enum TypedDataViewFormat {
+  kTypedDataViewFromC,
+  kTypedDataViewFromDart,
+};
+
 class TypedDataViewMessageSerializationCluster
     : public MessageSerializationCluster {
  public:
@@ -1953,6 +1944,7 @@
   void WriteNodes(MessageSerializer* s) {
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
+    s->Write<TypedDataViewFormat>(kTypedDataViewFromDart);
     for (intptr_t i = 0; i < count; i++) {
       TypedDataView* view = objects_[i];
       s->AssignRef(view);
@@ -1969,6 +1961,31 @@
     }
   }
 
+  void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {
+    ASSERT(object->type == Dart_CObject_kUnmodifiableExternalTypedData);
+    objects_.Add(reinterpret_cast<TypedDataView*>(object));
+  }
+
+  void WriteNodesApi(ApiMessageSerializer* s) {
+    intptr_t element_size = TypedDataView::ElementSizeInBytes(cid_);
+
+    intptr_t count = objects_.length();
+    s->WriteUnsigned(count);
+    s->Write<TypedDataViewFormat>(kTypedDataViewFromC);
+    for (intptr_t i = 0; i < count; i++) {
+      Dart_CObject* data = reinterpret_cast<Dart_CObject*>(objects_[i]);
+      s->AssignRef(data);
+
+      intptr_t length = data->value.as_external_typed_data.length;
+      s->WriteUnsigned(length);
+
+      s->finalizable_data()->Put(length * element_size,
+                                 data->value.as_external_typed_data.data,
+                                 data->value.as_external_typed_data.peer,
+                                 data->value.as_external_typed_data.callback);
+    }
+  }
+
  private:
   GrowableArray<TypedDataView*> objects_;
 };
@@ -1982,12 +1999,39 @@
 
   void ReadNodes(MessageDeserializer* d) {
     const intptr_t count = d->ReadUnsigned();
-    for (intptr_t i = 0; i < count; i++) {
-      d->AssignRef(TypedDataView::New(cid_));
+    format_ = d->Read<TypedDataViewFormat>();
+    if (format_ == kTypedDataViewFromC) {
+      intptr_t view_cid = cid_;
+      ASSERT(IsUnmodifiableTypedDataViewClassId(view_cid));
+      intptr_t backing_cid = cid_ - kTypedDataCidRemainderUnmodifiable +
+                             kTypedDataCidRemainderExternal;
+      ASSERT(IsExternalTypedDataClassId(backing_cid));
+      intptr_t element_size =
+          ExternalTypedData::ElementSizeInBytes(backing_cid);
+      ExternalTypedData& data = ExternalTypedData::Handle(d->zone());
+      TypedDataView& view = TypedDataView::Handle(d->zone());
+      for (intptr_t i = 0; i < count; i++) {
+        intptr_t length = d->ReadUnsigned();
+        FinalizableData finalizable_data = d->finalizable_data()->Take();
+        data = ExternalTypedData::New(
+            backing_cid, reinterpret_cast<uint8_t*>(finalizable_data.data),
+            length);
+        data.SetImmutable();  // Can pass by reference.
+        intptr_t external_size = length * element_size;
+        data.AddFinalizer(finalizable_data.peer, finalizable_data.callback,
+                          external_size);
+        view = TypedDataView::New(view_cid, data, 0, length);
+        d->AssignRef(data.ptr());
+      }
+    } else {
+      for (intptr_t i = 0; i < count; i++) {
+        d->AssignRef(TypedDataView::New(cid_));
+      }
     }
   }
 
   void ReadEdges(MessageDeserializer* d) {
+    if (format_ == kTypedDataViewFromC) return;
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d->Ref(id));
       view->untag()->set_length(static_cast<SmiPtr>(d->ReadRef()));
@@ -1998,6 +2042,7 @@
   }
 
   ObjectPtr PostLoad(MessageDeserializer* d) {
+    if (format_ == kTypedDataViewFromC) return nullptr;
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d->Ref(id));
       view->untag()->RecomputeDataField();
@@ -2013,13 +2058,75 @@
 
   void ReadNodesApi(ApiMessageDeserializer* d) {
     intptr_t count = d->ReadUnsigned();
-    for (intptr_t i = 0; i < count; i++) {
-      Dart_CTypedDataView* view = d->zone()->Alloc<Dart_CTypedDataView>(1);
-      d->AssignRef(view);
+    format_ = d->Read<TypedDataViewFormat>();
+    if (format_ == kTypedDataViewFromC) {
+      Dart_TypedData_Type type;
+      switch (cid_) {
+        case kUnmodifiableTypedDataInt8ArrayViewCid:
+          type = Dart_TypedData_kInt8;
+          break;
+        case kUnmodifiableTypedDataUint8ArrayViewCid:
+          type = Dart_TypedData_kUint8;
+          break;
+        case kUnmodifiableTypedDataUint8ClampedArrayViewCid:
+          type = Dart_TypedData_kUint8Clamped;
+          break;
+        case kUnmodifiableTypedDataInt16ArrayViewCid:
+          type = Dart_TypedData_kInt16;
+          break;
+        case kUnmodifiableTypedDataUint16ArrayViewCid:
+          type = Dart_TypedData_kUint16;
+          break;
+        case kUnmodifiableTypedDataInt32ArrayViewCid:
+          type = Dart_TypedData_kInt32;
+          break;
+        case kUnmodifiableTypedDataUint32ArrayViewCid:
+          type = Dart_TypedData_kUint32;
+          break;
+        case kUnmodifiableTypedDataInt64ArrayViewCid:
+          type = Dart_TypedData_kInt64;
+          break;
+        case kUnmodifiableTypedDataUint64ArrayViewCid:
+          type = Dart_TypedData_kUint64;
+          break;
+        case kUnmodifiableTypedDataFloat32ArrayViewCid:
+          type = Dart_TypedData_kFloat32;
+          break;
+        case kUnmodifiableTypedDataFloat64ArrayViewCid:
+          type = Dart_TypedData_kFloat64;
+          break;
+        case kUnmodifiableTypedDataInt32x4ArrayViewCid:
+          type = Dart_TypedData_kInt32x4;
+          break;
+        case kUnmodifiableTypedDataFloat32x4ArrayViewCid:
+          type = Dart_TypedData_kFloat32x4;
+          break;
+        case kUnmodifiableTypedDataFloat64x2ArrayViewCid:
+          type = Dart_TypedData_kFloat64x2;
+          break;
+        default:
+          UNREACHABLE();
+      }
+
+      Dart_CObject* data =
+          d->Allocate(Dart_CObject_kUnmodifiableExternalTypedData);
+      intptr_t length = d->ReadUnsigned();
+      FinalizableData finalizable_data = d->finalizable_data()->Get();
+      data->value.as_typed_data.type = type;
+      data->value.as_typed_data.length = length;
+      data->value.as_typed_data.values =
+          reinterpret_cast<uint8_t*>(finalizable_data.data);
+      d->AssignRef(data);
+    } else {
+      for (intptr_t i = 0; i < count; i++) {
+        Dart_CTypedDataView* view = d->zone()->Alloc<Dart_CTypedDataView>(1);
+        d->AssignRef(view);
+      }
     }
   }
 
   void ReadEdgesApi(ApiMessageDeserializer* d) {
+    if (format_ == kTypedDataViewFromC) return;
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       Dart_CTypedDataView* view = static_cast<Dart_CTypedDataView*>(d->Ref(id));
       view->length = d->ReadRef();
@@ -2029,6 +2136,7 @@
   }
 
   void PostLoadApi(ApiMessageDeserializer* d) {
+    if (format_ == kTypedDataViewFromC) return;
     Dart_TypedData_Type type;
     switch (cid_) {
       case kTypedDataInt8ArrayViewCid:
@@ -2094,6 +2202,7 @@
 
  private:
   const intptr_t cid_;
+  TypedDataViewFormat format_;
 };
 
 class TransferableTypedDataMessageSerializationCluster
@@ -2183,7 +2292,7 @@
       data->value.as_typed_data.type = Dart_TypedData_kUint8;
       FinalizableData finalizable_data = d->finalizable_data()->Get();
       data->value.as_typed_data.values =
-          reinterpret_cast<uint8_t*>(finalizable_data.data);
+          reinterpret_cast<const uint8_t*>(finalizable_data.data);
       d->AssignRef(data);
     }
   }
@@ -3260,6 +3369,10 @@
     ILLEGAL(SuspendState)
     ILLEGAL(UserTag)
 
+    // TODO(dartbug.com/49719): allow sending records as long as their
+    // elements are objects that can be sent.
+    ILLEGAL(RecordType)
+
     // From "dart:ffi" we handle only Pointer/DynamicLibrary specially, since
     // those are the only non-abstract classes (so we avoid checking more cids
     // here that cannot happen in reality)
@@ -3428,6 +3541,62 @@
         }
       }
       break;
+    case Dart_CObject_kUnmodifiableExternalTypedData:
+      switch (object->value.as_external_typed_data.type) {
+        case Dart_TypedData_kInt8:
+          cid = kUnmodifiableTypedDataInt8ArrayViewCid;
+          break;
+        case Dart_TypedData_kUint8:
+          cid = kUnmodifiableTypedDataUint8ArrayViewCid;
+          break;
+        case Dart_TypedData_kUint8Clamped:
+          cid = kUnmodifiableTypedDataUint8ClampedArrayViewCid;
+          break;
+        case Dart_TypedData_kInt16:
+          cid = kUnmodifiableTypedDataInt16ArrayViewCid;
+          break;
+        case Dart_TypedData_kUint16:
+          cid = kUnmodifiableTypedDataUint16ArrayViewCid;
+          break;
+        case Dart_TypedData_kInt32:
+          cid = kUnmodifiableTypedDataInt32ArrayViewCid;
+          break;
+        case Dart_TypedData_kUint32:
+          cid = kUnmodifiableTypedDataUint32ArrayViewCid;
+          break;
+        case Dart_TypedData_kInt64:
+          cid = kUnmodifiableTypedDataInt64ArrayViewCid;
+          break;
+        case Dart_TypedData_kUint64:
+          cid = kUnmodifiableTypedDataUint64ArrayViewCid;
+          break;
+        case Dart_TypedData_kFloat32:
+          cid = kUnmodifiableTypedDataFloat32ArrayViewCid;
+          break;
+        case Dart_TypedData_kFloat64:
+          cid = kUnmodifiableTypedDataFloat64ArrayViewCid;
+          break;
+        case Dart_TypedData_kInt32x4:
+          cid = kUnmodifiableTypedDataInt32x4ArrayViewCid;
+          break;
+        case Dart_TypedData_kFloat32x4:
+          cid = kUnmodifiableTypedDataFloat32x4ArrayViewCid;
+          break;
+        case Dart_TypedData_kFloat64x2:
+          cid = kUnmodifiableTypedDataFloat64x2ArrayViewCid;
+          break;
+        default:
+          return Fail("invalid TypedData type");
+      }
+      {
+        intptr_t len = object->value.as_typed_data.length;
+        if (len < 0 || len > TypedData::MaxElements(
+                                 cid - kTypedDataCidRemainderUnmodifiable +
+                                 kTypedDataCidRemainderInternal)) {
+          return Fail("invalid typeddata length");
+        }
+      }
+      break;
     case Dart_CObject_kSendPort:
       cid = kSendPortCid;
       break;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index cb4ea64..97fb9d4 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -733,6 +733,7 @@
   *null_instance_ = Instance::null();
   *null_function_ = Function::null();
   *null_function_type_ = FunctionType::null();
+  *null_record_type_ = RecordType::null();
   *null_type_arguments_ = TypeArguments::null();
   *empty_type_arguments_ = TypeArguments::null();
   *null_abstract_type_ = AbstractType::null();
@@ -1160,6 +1161,11 @@
   cls.set_is_declaration_loaded();
   cls.set_is_type_finalized();
 
+  cls = Class::New<RecordType, RTN::RecordType>(isolate_group);
+  cls.set_is_allocate_finalized();
+  cls.set_is_declaration_loaded();
+  cls.set_is_type_finalized();
+
   cls = dynamic_class_;
   *dynamic_type_ =
       Type::New(cls, Object::null_type_arguments(), Nullability::kNullable);
@@ -1241,6 +1247,8 @@
   ASSERT(null_function_->IsFunction());
   ASSERT(!null_function_type_->IsSmi());
   ASSERT(null_function_type_->IsFunctionType());
+  ASSERT(!null_record_type_->IsSmi());
+  ASSERT(null_record_type_->IsRecordType());
   ASSERT(!null_type_arguments_->IsSmi());
   ASSERT(null_type_arguments_->IsTypeArguments());
   ASSERT(!null_compressed_stackmaps_->IsSmi());
@@ -1740,6 +1748,12 @@
         kInitialCanonicalFunctionTypeSize, Heap::kOld);
     object_store->set_canonical_function_types(array);
 
+    // Initialize hash set for canonical record types.
+    const intptr_t kInitialCanonicalRecordTypeSize = 16;
+    array = HashTables::New<CanonicalRecordTypeSet>(
+        kInitialCanonicalRecordTypeSize, Heap::kOld);
+    object_store->set_canonical_record_types(array);
+
     // Initialize hash set for canonical type parameters.
     const intptr_t kInitialCanonicalTypeParameterSize = 4;
     array = HashTables::New<CanonicalTypeParameterSet>(
@@ -1757,6 +1771,8 @@
         Class::Handle(zone, Class::New<Type, RTN::Type>(isolate_group));
     const Class& function_type_cls = Class::Handle(
         zone, Class::New<FunctionType, RTN::FunctionType>(isolate_group));
+    const Class& record_type_cls = Class::Handle(
+        zone, Class::New<RecordType, RTN::RecordType>(isolate_group));
     const Class& type_ref_cls =
         Class::Handle(zone, Class::New<TypeRef, RTN::TypeRef>(isolate_group));
     const Class& type_parameter_cls = Class::Handle(
@@ -1940,6 +1956,9 @@
     RegisterPrivateClass(function_type_cls, Symbols::_FunctionType(), core_lib);
     pending_classes.Add(function_type_cls);
 
+    RegisterPrivateClass(record_type_cls, Symbols::_RecordType(), core_lib);
+    pending_classes.Add(record_type_cls);
+
     RegisterPrivateClass(type_ref_cls, Symbols::_TypeRef(), core_lib);
     pending_classes.Add(type_ref_cls);
 
@@ -1973,6 +1992,10 @@
     RegisterPrivateClass(cls, Symbols::_Closure(), core_lib);
     pending_classes.Add(cls);
 
+    cls = Class::New<Record, RTN::Record>(isolate_group);
+    RegisterPrivateClass(cls, Symbols::_Record(), core_lib);
+    pending_classes.Add(cls);
+
     cls = Class::New<WeakProperty, RTN::WeakProperty>(isolate_group);
     object_store->set_weak_property_class(cls);
     RegisterPrivateClass(cls, Symbols::_WeakProperty(), core_lib);
@@ -2472,6 +2495,7 @@
     cls = Class::New<LibraryPrefix, RTN::LibraryPrefix>(isolate_group);
     cls = Class::New<Type, RTN::Type>(isolate_group);
     cls = Class::New<FunctionType, RTN::FunctionType>(isolate_group);
+    cls = Class::New<RecordType, RTN::RecordType>(isolate_group);
     cls = Class::New<TypeRef, RTN::TypeRef>(isolate_group);
     cls = Class::New<TypeParameter, RTN::TypeParameter>(isolate_group);
 
@@ -2565,6 +2589,8 @@
     cls = Class::New<Closure, RTN::Closure>(isolate_group);
     object_store->set_closure_class(cls);
 
+    cls = Class::New<Record, RTN::Record>(isolate_group);
+
     cls = Class::NewStringClass(kOneByteStringCid, isolate_group);
     object_store->set_one_byte_string_class(cls);
 
@@ -2703,6 +2729,8 @@
   tags = UntaggedObject::OldAndNotMarkedBit::update(is_old, tags);
   tags = UntaggedObject::OldAndNotRememberedBit::update(is_old, tags);
   tags = UntaggedObject::NewBit::update(!is_old, tags);
+  tags = UntaggedObject::ImmutableBit::update(
+      IsUnmodifiableTypedDataViewClassId(class_id), tags);
 #if defined(HASH_IN_OBJECT_HEADER)
   tags = UntaggedObject::HashTag::update(0, tags);
 #endif
@@ -2766,8 +2794,8 @@
     heap->old_space()->AllocateBlack(size);
   }
 #ifndef PRODUCT
-  auto class_table = thread->isolate_group()->shared_class_table();
-  if (class_table->TraceAllocationFor(cls_id)) {
+  auto class_table = thread->isolate_group()->class_table();
+  if (class_table->ShouldTraceAllocationFor(cls_id)) {
     uint32_t hash =
         HeapSnapshotWriter::GetHeapSnapshotIdentityHash(thread, raw_obj);
     Profiler::SampleAllocation(thread, cls_id, hash);
@@ -3085,7 +3113,8 @@
   set_invocation_dispatcher_cache(Object::empty_array());
 }
 
-ArrayPtr Class::OffsetToFieldMap(bool original_classes) const {
+ArrayPtr Class::OffsetToFieldMap(
+    ClassTable* class_table /* = nullptr */) const {
   ASSERT(is_finalized());
   if (untag()->offset_in_words_to_field<std::memory_order_acquire>() ==
       Array::null()) {
@@ -3104,7 +3133,7 @@
           array.SetAt(f.HostOffset() >> kCompressedWordSizeLog2, f);
         }
       }
-      cls = cls.SuperClass(original_classes);
+      cls = cls.SuperClass(class_table);
     }
     untag()->set_offset_in_words_to_field<std::memory_order_release>(
         array.ptr());
@@ -3492,24 +3521,23 @@
   return type_params.defaults();
 }
 
-ClassPtr Class::SuperClass(bool original_classes) const {
+ClassPtr Class::SuperClass(ClassTable* class_table /* = nullptr */) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
-  auto isolate_group = thread->isolate_group();
+  if (class_table == nullptr) {
+    class_table = thread->isolate_group()->class_table();
+  }
+
   if (super_type() == AbstractType::null()) {
     if (id() == kTypeArgumentsCid) {
       // Pretend TypeArguments objects are Dart instances.
-      return isolate_group->class_table()->At(kInstanceCid);
+      return class_table->At(kInstanceCid);
     }
     return Class::null();
   }
   const AbstractType& sup_type = AbstractType::Handle(zone, super_type());
   const intptr_t type_class_id = sup_type.type_class_id();
-  if (original_classes) {
-    return isolate_group->GetClassForHeapWalkAt(type_class_id);
-  } else {
-    return isolate_group->class_table()->At(type_class_id);
-  }
+  return class_table->At(type_class_id);
 }
 
 void Class::set_super_type(const AbstractType& value) const {
@@ -3532,6 +3560,19 @@
   return type_param.ptr();
 }
 
+intptr_t Class::UnboxedFieldSizeInBytesByCid(intptr_t cid) {
+  switch (cid) {
+    case kDoubleCid:
+      return sizeof(UntaggedDouble::value_);
+    case kFloat32x4Cid:
+      return sizeof(UntaggedFloat32x4::value_);
+    case kFloat64x2Cid:
+      return sizeof(UntaggedFloat64x2::value_);
+    default:
+      return sizeof(UntaggedMint::value_);
+  }
+}
+
 UnboxedFieldBitmap Class::CalculateFieldOffsets() const {
   Array& flds = Array::Handle(fields());
   const Class& super = Class::Handle(SuperClass());
@@ -3559,11 +3600,8 @@
     ASSERT(num_native_fields() == 0);
     set_num_native_fields(super.num_native_fields());
 
-    if (FLAG_precompiled_mode) {
-      host_bitmap =
-          IsolateGroup::Current()->shared_class_table()->GetUnboxedFieldsMapAt(
-              super.id());
-    }
+    host_bitmap = IsolateGroup::Current()->class_table()->GetUnboxedFieldsMapAt(
+        super.id());
   }
   // If the super class is parameterized, use the same type_arguments field,
   // otherwise, if this class is the first in the super chain to be
@@ -3595,27 +3633,9 @@
       ASSERT(field.TargetOffset() == 0);
       field.SetOffset(host_offset, target_offset);
 
-      if (FLAG_precompiled_mode && field.is_unboxing_candidate()) {
-        intptr_t field_size;
-        switch (field.guarded_cid()) {
-          case kDoubleCid:
-            field_size = sizeof(UntaggedDouble::value_);
-            break;
-          case kFloat32x4Cid:
-            field_size = sizeof(UntaggedFloat32x4::value_);
-            break;
-          case kFloat64x2Cid:
-            field_size = sizeof(UntaggedFloat64x2::value_);
-            break;
-          default:
-            if (field.is_non_nullable_integer()) {
-              field_size = sizeof(UntaggedMint::value_);
-            } else {
-              UNREACHABLE();
-              field_size = 0;
-            }
-            break;
-        }
+      if (field.is_unboxed()) {
+        const intptr_t field_size =
+            UnboxedFieldSizeInBytesByCid(field.guarded_cid());
 
         const intptr_t host_num_words = field_size / kCompressedWordSize;
         const intptr_t host_next_offset = host_offset + field_size;
@@ -3641,7 +3661,7 @@
           target_offset = target_next_offset;
         } else {
           // Make the field boxed
-          field.set_is_unboxing_candidate(false);
+          field.set_is_unboxed(false);
           host_offset += kCompressedWordSize;
           target_offset += compiler::target::kCompressedWordSize;
         }
@@ -3654,7 +3674,6 @@
   set_instance_size(RoundedAllocationSize(host_offset),
                     compiler::target::RoundedAllocationSize(target_offset));
   set_next_field_offset(host_offset, target_offset);
-
   return host_bitmap;
 }
 
@@ -4127,10 +4146,7 @@
         // Unless class is top-level, which don't get instantiated,
         // sets the new size in the class table.
         isolate_group->class_table()->UpdateClassSize(id(), ptr());
-      }
-      if (FLAG_precompiled_mode && !ClassTable::IsTopLevelCid(id())) {
-        isolate_group->shared_class_table()->SetUnboxedFieldsMapAt(id(),
-                                                                   host_bitmap);
+        isolate_group->class_table()->SetUnboxedFieldsMapAt(id(), host_bitmap);
       }
     }
   }
@@ -4243,8 +4259,8 @@
 
 bool Class::TraceAllocation(IsolateGroup* isolate_group) const {
 #ifndef PRODUCT
-  auto class_table = isolate_group->shared_class_table();
-  return class_table->TraceAllocationFor(id());
+  auto class_table = isolate_group->class_table();
+  return class_table->ShouldTraceAllocationFor(id());
 #else
   return false;
 #endif
@@ -4255,7 +4271,7 @@
   auto isolate_group = IsolateGroup::Current();
   const bool changed = trace_allocation != this->TraceAllocation(isolate_group);
   if (changed) {
-    auto class_table = isolate_group->shared_class_table();
+    auto class_table = isolate_group->class_table();
     class_table->SetTraceAllocationFor(id(), trace_allocation);
     DisableAllocationStub();
   }
@@ -8288,6 +8304,7 @@
     case MethodRecognizer::kFfiAsExternalTypedDataFloat:
     case MethodRecognizer::kFfiAsExternalTypedDataDouble:
     case MethodRecognizer::kGetNativeField:
+    case MethodRecognizer::kRecord_numFields:
     case MethodRecognizer::kUtf8DecoderScan:
     // Prevent the GC from running so that the operation is atomic from
     // a GC point of view. Always double check implementation in
@@ -10537,20 +10554,15 @@
   result.set_packed_type_parameter_counts(0);
   result.set_named_parameter_names(Object::empty_array());
   result.SetNumParentTypeArguments(num_parent_type_arguments);
-  result.set_nullability(nullability);
   result.SetHash(0);
-  result.StoreNonPointer(&result.untag()->type_state_,
-                         UntaggedType::kAllocated);
+  result.set_flags(0);
+  result.set_nullability(nullability);
+  result.set_type_state(UntaggedAbstractType::kAllocated);
   result.InitializeTypeTestingStubNonAtomic(
       Code::Handle(Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
   return result.ptr();
 }
 
-void FunctionType::set_type_state(uint8_t state) const {
-  ASSERT(state <= UntaggedFunctionType::kFinalizedUninstantiated);
-  StoreNonPointer(&untag()->type_state_, state);
-}
-
 const char* FunctionType::ToUserVisibleCString() const {
   Zone* zone = Thread::Current()->zone();
   ZoneTextBuffer printer(zone);
@@ -10644,43 +10656,6 @@
   }
 }
 
-const Object* Field::CloneForUnboxed(const Object& value) const {
-  if (is_unboxing_candidate() && !is_nullable()) {
-    switch (guarded_cid()) {
-      case kDoubleCid:
-      case kFloat32x4Cid:
-      case kFloat64x2Cid:
-        return &Object::Handle(Object::Clone(value, Heap::kNew));
-      default:
-        // Not a supported unboxed field type.
-        return &value;
-    }
-  }
-  return &value;
-}
-
-void Field::DisableFieldUnboxing() const {
-  ASSERT(!IsOriginal());
-  const Field& original = Field::Handle(Original());
-  if (!original.is_unboxing_candidate()) {
-    return;
-  }
-  auto thread = Thread::Current();
-  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
-  if (!original.is_unboxing_candidate()) {
-    return;
-  }
-
-  // Ensures that to-be-disabled existing code won't continue running as we
-  // update field properties as it might write into now boxed field thinking
-  // it still holds unboxed(reusable box) value.
-  thread->isolate_group()->RunWithStoppedMutators([&]() {
-    original.set_is_unboxing_candidate(false);
-    set_is_unboxing_candidate(false);
-    original.DeoptimizeDependentCode();
-  });
-}
-
 intptr_t Field::guarded_cid() const {
 #if defined(DEBUG)
   // This assertion ensures that the cid seen by the background compiler is
@@ -10908,19 +10883,14 @@
   result.set_is_const(is_const);
   result.set_is_reflectable(is_reflectable);
   result.set_is_late(is_late);
-  result.set_is_double_initialized_unsafe(false);
   result.set_owner(owner);
   result.set_token_pos(token_pos);
   result.set_end_token_pos(end_token_pos);
   result.set_has_nontrivial_initializer_unsafe(false);
   result.set_has_initializer_unsafe(false);
-  if (FLAG_precompiled_mode) {
-    // May be updated by KernelLoader::ReadInferredType
-    result.set_is_unboxing_candidate_unsafe(false);
-  } else {
-    result.set_is_unboxing_candidate_unsafe(!is_final && !is_late &&
-                                            !is_static);
-  }
+  // We will make unboxing decision once we read static type or
+  // in KernelLoader::ReadInferredType.
+  result.set_is_unboxed_unsafe(false);
   result.set_initializer_changed_after_initialization(false);
   NOT_IN_PRECOMPILED(result.set_kernel_offset(0));
   result.set_has_pragma(false);
@@ -10966,6 +10936,9 @@
   InitializeNew(result, name, is_static, is_final, is_const, is_reflectable,
                 is_late, owner, token_pos, end_token_pos);
   result.SetFieldTypeSafe(type);
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  compiler::target::UnboxFieldIfSupported(result, type);
+#endif
   return result.ptr();
 }
 
@@ -11052,25 +11025,36 @@
 }
 
 bool Field::NeedsSetter() const {
-  // Late fields always need a setter, unless they're static and non-final, or
-  // final with an initializer.
-  if (is_late()) {
-    if (is_static() && !is_final()) {
-      return false;
+  // According to the Dart language specification, final fields don't have
+  // a setter, except late final fields without initializer.
+  if (is_final()) {
+    // Late final fields without initializer always need a setter to check
+    // if they are already initialized.
+    if (is_late() && !has_initializer()) {
+      return true;
     }
-    if (is_final() && has_initializer()) {
-      return false;
-    }
-    return true;
-  }
-
-  // Non-late static fields never need a setter.
-  if (is_static()) {
     return false;
   }
 
-  // Otherwise, the field only needs a setter if it isn't final.
-  return !is_final();
+  // Instance non-final fields always need a setter.
+  if (!is_static()) {
+    return true;
+  }
+
+  // Setter is needed to make null assertions.
+  if (FLAG_null_assertions) {
+    Thread* thread = Thread::Current();
+    IsolateGroup* isolate_group = thread->isolate_group();
+    if (!isolate_group->null_safety() && isolate_group->asserts()) {
+      if (AbstractType::Handle(thread->zone(), type()).NeedsNullAssertion()) {
+        return true;
+      }
+    }
+  }
+
+  // Othwerwise, setters for static fields can be omitted
+  // and fields can be accessed directly.
+  return false;
 }
 
 bool Field::NeedsGetter() const {
@@ -11211,7 +11195,7 @@
          (untag()->is_nullable_ == other.untag()->is_nullable_) &&
          (untag()->guarded_list_length() ==
           other.untag()->guarded_list_length()) &&
-         (is_unboxing_candidate() == other.is_unboxing_candidate()) &&
+         (is_unboxed() == other.is_unboxed()) &&
          (static_type_exactness_state().Encode() ==
           other.static_type_exactness_state().Encode());
 }
@@ -11981,10 +11965,10 @@
 }
 
 void Field::ForceDynamicGuardedCidAndLength() const {
-  // Assume nothing about this field.
-  set_is_unboxing_candidate(false);
-  set_guarded_cid(kDynamicCid);
-  set_is_nullable(true);
+  if (!is_unboxed()) {
+    set_guarded_cid(kDynamicCid);
+    set_is_nullable(true);
+  }
   set_guarded_list_length(Field::kNoFixedLength);
   set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
   if (static_type_exactness_state().IsTracking()) {
@@ -17499,7 +17483,7 @@
     if (FLAG_write_protect_code) {
       uword address = UntaggedObject::ToAddr(instrs.ptr());
       // Check if a dual mapping exists.
-      instrs = Instructions::RawCast(OldPage::ToExecutable(instrs.ptr()));
+      instrs = Instructions::RawCast(Page::ToExecutable(instrs.ptr()));
       uword exec_address = UntaggedObject::ToAddr(instrs.ptr());
       const bool use_dual_mapping = exec_address != address;
       ASSERT(use_dual_mapping == FLAG_dual_map_code);
@@ -17756,8 +17740,8 @@
 bool Code::IsTypeTestStubCode() const {
   auto const cid = OwnerClassId();
   return cid == kAbstractTypeCid || cid == kTypeCid ||
-         cid == kFunctionTypeCid || cid == kTypeRefCid ||
-         cid == kTypeParameterCid;
+         cid == kFunctionTypeCid || cid == kRecordTypeCid ||
+         cid == kTypeRefCid || cid == kTypeParameterCid;
 }
 
 bool Code::IsFunctionCode() const {
@@ -18394,6 +18378,7 @@
              ->isolate_group()
              ->subtype_test_cache_mutex()
              ->IsOwnedByCurrentThread());
+  ASSERT(Smi::New(kRecordCid) != instance_class_id_or_signature.ptr());
 
   intptr_t old_num = NumberOfChecks();
   Array& data = Array::Handle(cache());
@@ -19382,7 +19367,7 @@
     Instance& instance = Instance::Handle(zone);
 
     const auto unboxed_fields_bitmap =
-        thread->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(
+        thread->isolate_group()->class_table()->GetUnboxedFieldsMapAt(
             GetClassId());
 
     for (intptr_t offset = Instance::NextFieldOffset();
@@ -19453,8 +19438,7 @@
     const intptr_t instance_size = SizeFromClass();
     ASSERT(instance_size != 0);
     const auto unboxed_fields_bitmap =
-        thread->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(
-            class_id);
+        thread->isolate_group()->class_table()->GetUnboxedFieldsMapAt(class_id);
     for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size;
          offset += kCompressedWordSize) {
       if (unboxed_fields_bitmap.Get(offset / kCompressedWordSize)) {
@@ -19524,7 +19508,7 @@
 #endif  // DEBUG
 
 ObjectPtr Instance::GetField(const Field& field) const {
-  if (FLAG_precompiled_mode && field.is_unboxing_candidate()) {
+  if (field.is_unboxed()) {
     switch (field.guarded_cid()) {
       case kDoubleCid:
         return Double::New(*reinterpret_cast<double_t*>(FieldAddr(field)));
@@ -19535,12 +19519,7 @@
         return Float64x2::New(
             *reinterpret_cast<simd128_value_t*>(FieldAddr(field)));
       default:
-        if (field.is_non_nullable_integer()) {
-          return Integer::New(*reinterpret_cast<int64_t*>(FieldAddr(field)));
-        } else {
-          UNREACHABLE();
-          return nullptr;
-        }
+        return Integer::New(*reinterpret_cast<int64_t*>(FieldAddr(field)));
     }
   } else {
     return FieldAddr(field)->Decompress(untag()->heap_base());
@@ -19548,7 +19527,7 @@
 }
 
 void Instance::SetField(const Field& field, const Object& value) const {
-  if (FLAG_precompiled_mode && field.is_unboxing_candidate()) {
+  if (field.is_unboxed()) {
     switch (field.guarded_cid()) {
       case kDoubleCid:
         StoreNonPointer(reinterpret_cast<double_t*>(FieldAddr(field)),
@@ -19563,18 +19542,13 @@
                         Float64x2::Cast(value).value());
         break;
       default:
-        if (field.is_non_nullable_integer()) {
-          StoreNonPointer(reinterpret_cast<int64_t*>(FieldAddr(field)),
-                          Integer::Cast(value).AsInt64Value());
-        } else {
-          UNREACHABLE();
-        }
+        StoreNonPointer(reinterpret_cast<int64_t*>(FieldAddr(field)),
+                        Integer::Cast(value).AsInt64Value());
         break;
     }
   } else {
     field.RecordStore(value);
-    const Object* stored_value = field.CloneForUnboxed(value);
-    StoreCompressedPointer(FieldAddr(field), stored_value->ptr());
+    StoreCompressedPointer(FieldAddr(field), value.ptr());
   }
 }
 
@@ -19593,13 +19567,21 @@
   }
   if (cls.IsClosureClass()) {
     FunctionType& signature = FunctionType::Handle(
-        Closure::Cast(*this).GetInstantiatedSignature(zone));
+        zone, Closure::Cast(*this).GetInstantiatedSignature(zone));
     if (!signature.IsFinalized()) {
       signature.SetIsFinalized();
     }
     signature ^= signature.Canonicalize(thread, nullptr);
     return signature.ptr();
   }
+  if (IsRecord()) {
+    ASSERT(cls.IsRecordClass());
+    auto& record_type =
+        RecordType::Handle(zone, Record::Cast(*this).GetRecordType());
+    ASSERT(record_type.IsFinalized());
+    ASSERT(record_type.IsCanonical());
+    return record_type.ptr();
+  }
   Type& type = Type::Handle(zone);
   if (!cls.IsGeneric()) {
     type = cls.DeclarationType();
@@ -19816,6 +19798,52 @@
         Closure::Cast(*this).GetInstantiatedSignature(zone));
     return sig.IsSubtypeOf(FunctionType::Cast(instantiated_other), Heap::kOld);
   }
+  if (cls.IsRecordClass()) {
+    if (other.IsDartRecordType() || other.IsObjectType()) {
+      return true;
+    }
+    AbstractType& instantiated_other = AbstractType::Handle(zone, other.ptr());
+    if (!other.IsInstantiated()) {
+      instantiated_other = other.InstantiateFrom(
+          other_instantiator_type_arguments, other_function_type_arguments,
+          kAllFree, Heap::kOld);
+      if (instantiated_other.IsTypeRef()) {
+        instantiated_other = TypeRef::Cast(instantiated_other).type();
+      }
+      if (instantiated_other.IsTopTypeForSubtyping() ||
+          instantiated_other.IsObjectType() ||
+          instantiated_other.IsDartRecordType()) {
+        return true;
+      }
+    }
+    if (RuntimeTypeIsSubtypeOfFutureOr(zone, instantiated_other)) {
+      return true;
+    }
+    if (!instantiated_other.IsRecordType()) {
+      return false;
+    }
+    const Record& record = Record::Cast(*this);
+    const RecordType& record_type = RecordType::Cast(instantiated_other);
+    const intptr_t num_fields = record.num_fields();
+    ASSERT(Array::Handle(record.field_names()).IsCanonical());
+    ASSERT(Array::Handle(record_type.field_names()).IsCanonical());
+    if ((num_fields != record_type.NumFields()) ||
+        (record.field_names() != record_type.field_names())) {
+      return false;
+    }
+    Instance& field_value = Instance::Handle(zone);
+    AbstractType& field_type = AbstractType::Handle(zone);
+    for (intptr_t i = 0; i < num_fields; ++i) {
+      field_value ^= record.FieldAt(i);
+      field_type = record_type.FieldTypeAt(i);
+      if (!field_value.RuntimeTypeIsSubtypeOf(field_type,
+                                              Object::null_type_arguments(),
+                                              Object::null_type_arguments())) {
+        return false;
+      }
+    }
+    return true;
+  }
   TypeArguments& type_arguments = TypeArguments::Handle(zone);
   if (cls.NumTypeArguments() > 0) {
     type_arguments = GetTypeArguments();
@@ -19988,10 +20016,10 @@
   return static_cast<InstancePtr>(raw);
 }
 
-InstancePtr Instance::NewFromCidAndSize(SharedClassTable* shared_class_table,
+InstancePtr Instance::NewFromCidAndSize(ClassTable* class_table,
                                         classid_t cid,
                                         Heap::Space heap) {
-  const intptr_t instance_size = shared_class_table->SizeAt(cid);
+  const intptr_t instance_size = class_table->SizeAt(cid);
   ASSERT(instance_size > 0);
   ObjectPtr raw = Object::Allocate(cid, instance_size, heap,
                                    Instance::ContainsCompressedPointers());
@@ -20050,6 +20078,8 @@
       return OneByteString::data_offset();
     case kTwoByteStringCid:
       return TwoByteString::data_offset();
+    case kRecordCid:
+      return Record::field_offset(0);
     default:
       UNIMPLEMENTED();
       return Array::data_offset();
@@ -20098,12 +20128,6 @@
   UNREACHABLE();
 }
 
-Nullability AbstractType::nullability() const {
-  // AbstractType is an abstract class.
-  UNREACHABLE();
-  return Nullability::kNullable;
-}
-
 bool AbstractType::IsStrictlyNonNullable() const {
   // Null can be assigned to legacy and nullable types.
   if (!IsNonNullable()) {
@@ -20164,6 +20188,9 @@
   if (IsFunctionType()) {
     return FunctionType::Cast(*this).ToNullability(result_nullability, space);
   }
+  if (IsRecordType()) {
+    return RecordType::Cast(*this).ToNullability(result_nullability, space);
+  }
   if (IsTypeParameter()) {
     return TypeParameter::Cast(*this).ToNullability(result_nullability, space);
   }
@@ -20221,26 +20248,32 @@
   return false;
 }
 
-bool AbstractType::IsFinalized() const {
-  // AbstractType is an abstract class.
-  UNREACHABLE();
-  return false;
-}
-
 void AbstractType::SetIsFinalized() const {
-  // AbstractType is an abstract class.
-  UNREACHABLE();
-}
-
-bool AbstractType::IsBeingFinalized() const {
-  // AbstractType is an abstract class.
-  UNREACHABLE();
-  return false;
+  ASSERT(!IsFinalized());
+  set_type_state(IsInstantiated()
+                     ? UntaggedAbstractType::kFinalizedInstantiated
+                     : UntaggedAbstractType::kFinalizedUninstantiated);
 }
 
 void AbstractType::SetIsBeingFinalized() const {
-  // AbstractType is an abstract class.
-  UNREACHABLE();
+  ASSERT(!IsFinalized() && !IsBeingFinalized());
+  set_type_state(UntaggedAbstractType::kBeingFinalized);
+}
+
+void AbstractType::set_flags(uint32_t value) const {
+  StoreNonPointer(&untag()->flags_, value);
+}
+
+void AbstractType::set_type_state(UntaggedAbstractType::TypeState value) const {
+  ASSERT(!IsCanonical());
+  set_flags(
+      UntaggedAbstractType::TypeStateBits::update(value, untag()->flags_));
+}
+
+void AbstractType::set_nullability(Nullability value) const {
+  ASSERT(!IsCanonical());
+  set_flags(UntaggedAbstractType::NullabilityBits::update(
+      static_cast<uint8_t>(value), untag()->flags_));
 }
 
 bool AbstractType::IsEquivalent(const Instance& other,
@@ -20251,6 +20284,35 @@
   return false;
 }
 
+bool AbstractType::IsNullabilityEquivalent(Thread* thread,
+                                           const AbstractType& other_type,
+                                           TypeEquality kind) const {
+  Nullability this_type_nullability = nullability();
+  Nullability other_type_nullability = other_type.nullability();
+  if (kind == TypeEquality::kInSubtypeTest) {
+    if (thread->isolate_group()->use_strict_null_safety_checks() &&
+        this_type_nullability == Nullability::kNullable &&
+        other_type_nullability == Nullability::kNonNullable) {
+      return false;
+    }
+  } else {
+    if (kind == TypeEquality::kSyntactical) {
+      if (this_type_nullability == Nullability::kLegacy) {
+        this_type_nullability = Nullability::kNonNullable;
+      }
+      if (other_type_nullability == Nullability::kLegacy) {
+        other_type_nullability = Nullability::kNonNullable;
+      }
+    } else {
+      ASSERT(kind == TypeEquality::kCanonical);
+    }
+    if (this_type_nullability != other_type_nullability) {
+      return false;
+    }
+  }
+  return true;
+}
+
 bool AbstractType::IsRecursive(TrailPtr trail) const {
   // AbstractType is an abstract class.
   UNREACHABLE();
@@ -20468,6 +20530,10 @@
     }
     return;
   }
+  if (IsRecordType()) {
+    RecordType::Cast(*this).Print(name_visibility, printer);
+    return;
+  }
   const TypeArguments& args = TypeArguments::Handle(zone, arguments());
   const intptr_t num_args = args.IsNull() ? 0 : args.Length();
   intptr_t first_type_param_index;
@@ -20508,7 +20574,7 @@
 }
 
 StringPtr AbstractType::ClassName() const {
-  ASSERT(!IsFunctionType());
+  ASSERT(!IsFunctionType() && !IsRecordType());
   return Class::Handle(type_class()).Name();
 }
 
@@ -20612,6 +20678,11 @@
   return (type_class_id() == kClosureCid);
 }
 
+bool AbstractType::IsDartRecordType() const {
+  // TODO(dartbug.com/49719): should check for Record, not _Record class.
+  return HasTypeClass() && type_class_id() == kRecordCid;
+}
+
 bool AbstractType::IsFfiPointerType() const {
   return HasTypeClass() && type_class_id() == kPointerCid;
 }
@@ -20641,6 +20712,24 @@
   return type_arg.ptr();
 }
 
+bool AbstractType::NeedsNullAssertion() const {
+  if (!IsNonNullable()) {
+    return false;
+  }
+  if (IsTypeRef()) {
+    return AbstractType::Handle(TypeRef::Cast(*this).type())
+        .NeedsNullAssertion();
+  }
+  if (IsTypeParameter()) {
+    return AbstractType::Handle(TypeParameter::Cast(*this).bound())
+        .NeedsNullAssertion();
+  }
+  if (IsFutureOrType()) {
+    return AbstractType::Handle(UnwrapFutureOr()).NeedsNullAssertion();
+  }
+  return true;
+}
+
 bool AbstractType::IsSubtypeOf(const AbstractType& other,
                                Heap::Space space,
                                TrailPtr trail) const {
@@ -20757,6 +20846,32 @@
     // fall through to class-based type tests.
     return false;
   }
+  // Record types cannot be handled by Class::IsSubtypeOf().
+  if (IsRecordType()) {
+    if (other.IsObjectType() || other.IsDartRecordType()) {
+      return !isolate_group->use_strict_null_safety_checks() || !IsNullable() ||
+             !other.IsNonNullable();
+    }
+    if (other.IsRecordType()) {
+      // Check for two record types.
+      if (isolate_group->use_strict_null_safety_checks() && IsNullable() &&
+          other.IsNonNullable()) {
+        return false;
+      }
+      return RecordType::Cast(*this).IsSubtypeOf(RecordType::Cast(other),
+                                                 space);
+    }
+    // Apply additional subtyping rules if 'other' is 'FutureOr'.
+    if (IsSubtypeOfFutureOr(zone, other, space, trail)) {
+      return true;
+    }
+    // All possible supertypes for record type have been checked.
+    return false;
+  } else if (other.IsRecordType()) {
+    // RecordTypes can only be subtyped by other RecordTypes, so don't
+    // fall through to class-based type tests.
+    return false;
+  }
   const Class& type_cls = Class::Handle(zone, type_class());
   return Class::IsSubtypeOf(type_cls, TypeArguments::Handle(zone, arguments()),
                             nullability(), other, space, trail);
@@ -20768,9 +20883,9 @@
                                        TrailPtr trail) const {
   if (other.IsFutureOrType()) {
     // This function is only called with a receiver that is either a function
-    // type or an uninstantiated type parameter, therefore, it cannot be of
-    // class Future and we can spare the check.
-    ASSERT(IsFunctionType() || IsTypeParameter());
+    // type, record type, or an uninstantiated type parameter.
+    // Therefore, it cannot be of class Future and we can spare the check.
+    ASSERT(IsFunctionType() || IsRecordType() || IsTypeParameter());
     const TypeArguments& other_type_arguments =
         TypeArguments::Handle(zone, other.arguments());
     const AbstractType& other_type_arg =
@@ -20946,34 +21061,6 @@
   return type.ptr();
 }
 
-void Type::SetIsFinalized() const {
-  ASSERT(!IsFinalized());
-  if (IsInstantiated()) {
-    set_type_state(UntaggedType::kFinalizedInstantiated);
-  } else {
-    set_type_state(UntaggedType::kFinalizedUninstantiated);
-  }
-}
-
-void FunctionType::SetIsFinalized() const {
-  ASSERT(!IsFinalized());
-  if (IsInstantiated()) {
-    set_type_state(UntaggedFunctionType::kFinalizedInstantiated);
-  } else {
-    set_type_state(UntaggedFunctionType::kFinalizedUninstantiated);
-  }
-}
-
-void Type::SetIsBeingFinalized() const {
-  ASSERT(!IsFinalized() && !IsBeingFinalized());
-  set_type_state(UntaggedType::kBeingFinalized);
-}
-
-void FunctionType::SetIsBeingFinalized() const {
-  ASSERT(!IsFinalized() && !IsBeingFinalized());
-  set_type_state(UntaggedFunctionType::kBeingFinalized);
-}
-
 TypePtr Type::ToNullability(Nullability value, Heap::Space space) const {
   if (nullability() == value) {
     return ptr();
@@ -21031,7 +21118,7 @@
 }
 
 classid_t Type::type_class_id() const {
-  return untag()->type_class_id_;
+  return untag()->type_class_id();
 }
 
 ClassPtr Type::type_class() const {
@@ -21041,11 +21128,11 @@
 bool Type::IsInstantiated(Genericity genericity,
                           intptr_t num_free_fun_type_params,
                           TrailPtr trail) const {
-  if (untag()->type_state_ == UntaggedType::kFinalizedInstantiated) {
+  if (type_state() == UntaggedType::kFinalizedInstantiated) {
     return true;
   }
   if ((genericity == kAny) && (num_free_fun_type_params == kAllFree) &&
-      (untag()->type_state_ == UntaggedType::kFinalizedUninstantiated)) {
+      (type_state() == UntaggedType::kFinalizedUninstantiated)) {
     return false;
   }
   if (arguments() == TypeArguments::null()) {
@@ -21107,6 +21194,23 @@
   return instantiated_type.NormalizeFutureOrType(space);
 }
 
+// Certain built-in classes are treated as syntactically equivalent.
+static classid_t NormalizeClassIdForSyntacticalTypeEquality(classid_t cid) {
+  if (IsIntegerClassId(cid)) {
+    return Type::Handle(Type::IntType()).type_class_id();
+  } else if (IsStringClassId(cid)) {
+    return Type::Handle(Type::StringType()).type_class_id();
+  } else if (cid == kDoubleCid) {
+    return Type::Handle(Type::Double()).type_class_id();
+  } else if (IsTypeClassId(cid)) {
+    return Type::Handle(Type::DartTypeType()).type_class_id();
+  } else if (IsArrayClassId(cid)) {
+    return Class::Handle(IsolateGroup::Current()->object_store()->list_class())
+        .id();
+  }
+  return cid;
+}
+
 bool Type::IsEquivalent(const Instance& other,
                         TypeEquality kind,
                         TrailPtr trail) const {
@@ -21125,37 +21229,22 @@
     return false;
   }
   const Type& other_type = Type::Cast(other);
-  if (type_class_id() != other_type.type_class_id()) {
+  const classid_t type_cid = type_class_id();
+  const classid_t other_type_cid = other_type.type_class_id();
+  if (type_cid != other_type_cid) {
+    if ((kind != TypeEquality::kSyntactical) ||
+        (NormalizeClassIdForSyntacticalTypeEquality(type_cid) !=
+         NormalizeClassIdForSyntacticalTypeEquality(other_type_cid))) {
+      return false;
+    }
+  }
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  if (!IsNullabilityEquivalent(thread, other_type, kind)) {
     return false;
   }
-  Nullability this_type_nullability = nullability();
-  Nullability other_type_nullability = other_type.nullability();
-  Thread* thread = Thread::Current();
-  auto isolate_group = thread->isolate_group();
-  Zone* zone = thread->zone();
-  if (kind == TypeEquality::kInSubtypeTest) {
-    if (isolate_group->use_strict_null_safety_checks() &&
-        this_type_nullability == Nullability::kNullable &&
-        other_type_nullability == Nullability::kNonNullable) {
-      return false;
-    }
-  } else {
-    if (kind == TypeEquality::kSyntactical) {
-      if (this_type_nullability == Nullability::kLegacy) {
-        this_type_nullability = Nullability::kNonNullable;
-      }
-      if (other_type_nullability == Nullability::kLegacy) {
-        other_type_nullability = Nullability::kNonNullable;
-      }
-    } else {
-      ASSERT(kind == TypeEquality::kCanonical);
-      ASSERT(IsFinalized() && other_type.IsFinalized());
-    }
-    if (this_type_nullability != other_type_nullability) {
-      return false;
-    }
-  }
   if (!IsFinalized() || !other_type.IsFinalized()) {
+    ASSERT(kind != TypeEquality::kCanonical);
     return false;  // Too early to decide if equal.
   }
   if (arguments() == other_type.arguments()) {
@@ -21232,34 +21321,13 @@
     // Different number of type parameters or parameters.
     return false;
   }
-  Nullability this_type_nullability = nullability();
-  Nullability other_type_nullability = other_type.nullability();
   Thread* thread = Thread::Current();
-  auto isolate_group = thread->isolate_group();
   Zone* zone = thread->zone();
-  if (kind == TypeEquality::kInSubtypeTest) {
-    if (isolate_group->null_safety() &&
-        this_type_nullability == Nullability::kNullable &&
-        other_type_nullability == Nullability::kNonNullable) {
-      return false;
-    }
-  } else {
-    if (kind == TypeEquality::kSyntactical) {
-      if (this_type_nullability == Nullability::kLegacy) {
-        this_type_nullability = Nullability::kNonNullable;
-      }
-      if (other_type_nullability == Nullability::kLegacy) {
-        other_type_nullability = Nullability::kNonNullable;
-      }
-    } else {
-      ASSERT(kind == TypeEquality::kCanonical);
-      ASSERT(IsFinalized() && other_type.IsFinalized());
-    }
-    if (this_type_nullability != other_type_nullability) {
-      return false;
-    }
+  if (!IsNullabilityEquivalent(thread, other_type, kind)) {
+    return false;
   }
   if (!IsFinalized() || !other_type.IsFinalized()) {
+    ASSERT(kind != TypeEquality::kCanonical);
     return false;  // Too early to decide if equal.
   }
   // Equal function types must have equal signature types and equal optional
@@ -21622,12 +21690,12 @@
                   Heap::Space space) {
   Zone* Z = Thread::Current()->zone();
   const Type& result = Type::Handle(Z, Type::New(space));
-  result.set_type_class(clazz);
   result.set_arguments(arguments);
   result.SetHash(0);
-  result.StoreNonPointer(&result.untag()->type_state_,
-                         UntaggedType::kAllocated);
+  result.set_flags(0);
   result.set_nullability(nullability);
+  result.set_type_state(UntaggedAbstractType::kAllocated);
+  result.set_type_class(clazz);
 
   result.InitializeTypeTestingStubNonAtomic(
       Code::Handle(Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
@@ -21635,19 +21703,13 @@
 }
 
 void Type::set_type_class_id(intptr_t id) const {
-  COMPILE_ASSERT(
-      std::is_unsigned<decltype(UntaggedType::type_class_id_)>::value);
-  ASSERT(Utils::IsUint(sizeof(untag()->type_class_id_) * kBitsPerByte, id));
+  COMPILE_ASSERT(std::is_unsigned<ClassIdTagType>::value);
+  ASSERT(Utils::IsUint(sizeof(ClassIdTagType) * kBitsPerByte, id));
   // We should never need a Type object for a top-level class.
   ASSERT(!ClassTable::IsTopLevelCid(id));
   ASSERT(id != kIllegalCid);
   ASSERT(!IsInternalOnlyClassId(id));
-  StoreNonPointer(&untag()->type_class_id_, id);
-}
-
-void Type::set_type_state(uint8_t state) const {
-  ASSERT(state <= UntaggedType::kFinalizedUninstantiated);
-  StoreNonPointer(&untag()->type_state_, state);
+  untag()->set_type_class_id(id);
 }
 
 const char* Type::ToCString() const {
@@ -21963,6 +22025,12 @@
 
 void TypeRef::set_type(const AbstractType& value) const {
   ASSERT(!value.IsTypeRef());
+  if (value.IsNull()) {
+    ASSERT(!IsFinalized());
+  } else {
+    set_type_state(value.type_state());
+    set_nullability(value.nullability());
+  }
   untag()->set_type(value.ptr());
 }
 
@@ -21979,7 +22047,11 @@
   AbstractType& ref_type = AbstractType::Handle(type());
   ASSERT(!ref_type.IsNull());
   ref_type = ref_type.Canonicalize(thread, trail);
-  set_type(ref_type);
+  {
+    SafepointMutexLocker ml(
+        thread->isolate_group()->type_canonicalization_mutex());
+    set_type(ref_type);
+  }
   return ptr();
 }
 
@@ -22064,23 +22136,6 @@
   return printer.buffer();
 }
 
-void TypeParameter::SetIsFinalized() const {
-  ASSERT(!IsFinalized());
-  set_flags(UntaggedTypeParameter::FinalizedBit::update(
-      true, UntaggedTypeParameter::BeingFinalizedBit::update(false,
-                                                             untag()->flags_)));
-}
-
-void TypeParameter::SetIsBeingFinalized() const {
-  ASSERT(!IsFinalized());
-  set_flags(
-      UntaggedTypeParameter::BeingFinalizedBit::update(true, untag()->flags_));
-}
-
-void TypeParameter::set_nullability(Nullability value) const {
-  StoreNonPointer(&untag()->nullability_, static_cast<uint8_t>(value));
-}
-
 TypeParameterPtr TypeParameter::ToNullability(Nullability value,
                                               Heap::Space space) const {
   if (nullability() == value) {
@@ -22196,31 +22251,7 @@
       return false;
     }
   }
-  // Compare nullability.
-  Nullability this_type_param_nullability = nullability();
-  Nullability other_type_param_nullability = other_type_param.nullability();
-  if (kind == TypeEquality::kInSubtypeTest) {
-    if (IsolateGroup::Current()->use_strict_null_safety_checks() &&
-        (this_type_param_nullability == Nullability::kNullable) &&
-        (other_type_param_nullability == Nullability::kNonNullable)) {
-      return false;
-    }
-  } else {
-    if (kind == TypeEquality::kSyntactical) {
-      if (this_type_param_nullability == Nullability::kLegacy) {
-        this_type_param_nullability = Nullability::kNonNullable;
-      }
-      if (other_type_param_nullability == Nullability::kLegacy) {
-        other_type_param_nullability = Nullability::kNonNullable;
-      }
-    } else {
-      ASSERT(kind == TypeEquality::kCanonical);
-    }
-    if (this_type_param_nullability != other_type_param_nullability) {
-      return false;
-    }
-  }
-  return true;
+  return IsNullabilityEquivalent(Thread::Current(), other_type_param, kind);
 }
 
 bool TypeParameter::IsRecursive(TrailPtr trail) const {
@@ -22462,19 +22493,16 @@
   result.set_base(base);
   result.set_index(index);
   result.set_bound(bound);
+  result.SetHash(0);
   result.set_flags(0);
   result.set_nullability(nullability);
-  result.SetHash(0);
+  result.set_type_state(UntaggedAbstractType::kAllocated);
 
   result.InitializeTypeTestingStubNonAtomic(
       Code::Handle(Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
   return result.ptr();
 }
 
-void TypeParameter::set_flags(uint8_t flags) const {
-  StoreNonPointer(&untag()->flags_, flags);
-}
-
 const char* TypeParameter::CanonicalNameCString(bool is_class_type_parameter,
                                                 intptr_t base,
                                                 intptr_t index) {
@@ -23788,10 +23816,13 @@
                                                  void* peer,
                                                  Dart_HandleFinalizer callback,
                                                  intptr_t external_size) {
-  ASSERT(callback != NULL);
-  return FinalizablePersistentHandle::New(IsolateGroup::Current(), referent,
-                                          peer, callback, external_size,
-                                          /*auto_delete=*/true);
+  ASSERT(callback != nullptr);
+  FinalizablePersistentHandle* finalizable_ref =
+      FinalizablePersistentHandle::New(IsolateGroup::Current(), referent, peer,
+                                       callback, external_size,
+                                       /*auto_delete=*/true);
+  ASSERT(finalizable_ref != nullptr);
+  return finalizable_ref;
 }
 
 StringPtr String::Transform(int32_t (*mapping)(int32_t ch),
@@ -25420,7 +25451,7 @@
 
   if (perform_eager_msan_initialization_check) {
     // Once the TypedData is created, Dart might read this memory. Check for
-    // intialization at construction to make it easier to track the source.
+    // initialization at construction to make it easier to track the source.
     MSAN_CHECK_INITIALIZED(data, len);
   }
 
@@ -25642,10 +25673,12 @@
   }
   // Set up finalizer so it frees allocated memory if handle is
   // garbage-collected.
-  peer->set_handle(
+  FinalizablePersistentHandle* finalizable_ref =
       FinalizablePersistentHandle::New(thread->isolate_group(), result, peer,
                                        &TransferableTypedDataFinalizer, length,
-                                       /*auto_delete=*/true));
+                                       /*auto_delete=*/true);
+  ASSERT(finalizable_ref != nullptr);
+  peer->set_handle(finalizable_ref);
 
   return result.ptr();
 }
@@ -26844,6 +26877,14 @@
   table.Release();
 }
 
+void DumpRecordTypeTable(Isolate* isolate) {
+  OS::PrintErr("canonical record types:\n");
+  CanonicalRecordTypeSet table(
+      isolate->group()->object_store()->canonical_record_types());
+  table.Dump();
+  table.Release();
+}
+
 void DumpTypeParameterTable(Isolate* isolate) {
   OS::PrintErr("canonical type parameters (cloned from declarations):\n");
   CanonicalTypeParameterSet table(
@@ -27057,4 +27098,560 @@
   }
 }
 
+AbstractTypePtr RecordType::FieldTypeAt(intptr_t index) const {
+  const Array& field_types = Array::Handle(untag()->field_types());
+  return AbstractType::RawCast(field_types.At(index));
+}
+
+void RecordType::SetFieldTypeAt(intptr_t index,
+                                const AbstractType& value) const {
+  ASSERT(!value.IsNull());
+  const Array& field_types = Array::Handle(untag()->field_types());
+  field_types.SetAt(index, value);
+}
+
+void RecordType::set_field_types(const Array& value) const {
+  ASSERT(!value.IsNull() && (value.Length() > 0));
+  untag()->set_field_types(value.ptr());
+}
+
+StringPtr RecordType::FieldNameAt(intptr_t index) const {
+  const Array& field_names = Array::Handle(untag()->field_names());
+  return String::RawCast(field_names.At(index));
+}
+
+void RecordType::SetFieldNameAt(intptr_t index, const String& value) const {
+  ASSERT(!value.IsNull());
+  ASSERT(value.IsSymbol());
+  const Array& field_names = Array::Handle(untag()->field_names());
+  field_names.SetAt(index, value);
+}
+
+void RecordType::set_field_names(const Array& value) const {
+  ASSERT(value.ptr() == Object::empty_array().ptr() || value.Length() > 0);
+  untag()->set_field_names(value.ptr());
+}
+
+void RecordType::Print(NameVisibility name_visibility,
+                       BaseTextBuffer* printer) const {
+  if (IsNull()) {
+    printer->AddString("null");
+    return;
+  }
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  AbstractType& type = AbstractType::Handle(zone);
+  String& name = String::Handle(zone);
+  const intptr_t num_fields = NumFields();
+  const intptr_t num_positional_fields = NumPositionalFields();
+  printer->AddString("(");
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    if (i != 0) {
+      printer->AddString(", ");
+    }
+    if (i == num_positional_fields) {
+      printer->AddString("{");
+    }
+    type = FieldTypeAt(i);
+    type.PrintName(name_visibility, printer);
+    if (i >= num_positional_fields) {
+      printer->AddString(" ");
+      name = FieldNameAt(i - num_positional_fields);
+      printer->AddString(name.ToCString());
+    }
+  }
+  if (num_positional_fields < num_fields) {
+    printer->AddString("}");
+  }
+  printer->AddString(")");
+  printer->AddString(NullabilitySuffix(name_visibility));
+}
+
+const char* RecordType::ToCString() const {
+  Zone* zone = Thread::Current()->zone();
+  ZoneTextBuffer printer(zone);
+  Print(kInternalName, &printer);
+  return printer.buffer();
+}
+
+bool RecordType::IsInstantiated(Genericity genericity,
+                                intptr_t num_free_fun_type_params,
+                                TrailPtr trail) const {
+  AbstractType& type = AbstractType::Handle();
+  const intptr_t num_fields = NumFields();
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    type = FieldTypeAt(i);
+    if (!type.IsInstantiated(genericity, num_free_fun_type_params, trail)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+RecordTypePtr RecordType::New(Heap::Space space) {
+  ObjectPtr raw =
+      Object::Allocate(RecordType::kClassId, RecordType::InstanceSize(), space,
+                       RecordType::ContainsCompressedPointers());
+  return static_cast<RecordTypePtr>(raw);
+}
+
+RecordTypePtr RecordType::New(const Array& field_types,
+                              const Array& field_names,
+                              Nullability nullability,
+                              Heap::Space space) {
+  Zone* Z = Thread::Current()->zone();
+  const RecordType& result = RecordType::Handle(Z, RecordType::New(space));
+  result.set_field_types(field_types);
+  result.set_field_names(field_names);
+  result.SetHash(0);
+  result.set_flags(0);
+  result.set_nullability(nullability);
+  result.set_type_state(UntaggedAbstractType::kAllocated);
+  result.InitializeTypeTestingStubNonAtomic(
+      Code::Handle(Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
+  return result.ptr();
+}
+
+RecordTypePtr RecordType::ToNullability(Nullability value,
+                                        Heap::Space space) const {
+  if (nullability() == value) {
+    return ptr();
+  }
+  // Clone record type and set new nullability.
+  RecordType& type = RecordType::Handle();
+  // Always cloning in old space and removing space parameter would not satisfy
+  // currently existing requests for type instantiation in new space.
+  type ^= Object::Clone(*this, space);
+  type.set_nullability(value);
+  type.SetHash(0);
+  type.InitializeTypeTestingStubNonAtomic(
+      Code::Handle(TypeTestingStubGenerator::DefaultCodeForType(type)));
+  if (IsCanonical()) {
+    // Object::Clone does not clone canonical bit.
+    ASSERT(!type.IsCanonical());
+    type ^= type.Canonicalize(Thread::Current(), nullptr);
+  }
+  return type.ptr();
+}
+
+bool RecordType::IsEquivalent(const Instance& other,
+                              TypeEquality kind,
+                              TrailPtr trail) const {
+  ASSERT(!IsNull());
+  if (ptr() == other.ptr()) {
+    return true;
+  }
+  if (other.IsTypeRef()) {
+    // Unfold right hand type. Divergence is controlled by left hand type.
+    const AbstractType& other_ref_type =
+        AbstractType::Handle(TypeRef::Cast(other).type());
+    ASSERT(!other_ref_type.IsTypeRef());
+    return IsEquivalent(other_ref_type, kind, trail);
+  }
+  if (!other.IsRecordType()) {
+    return false;
+  }
+  const RecordType& other_type = RecordType::Cast(other);
+  if ((NumFields() != other_type.NumFields()) ||
+      (NumNamedFields() != other_type.NumNamedFields())) {
+    // Different number of positional or named fields.
+    return false;
+  }
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  if (!IsNullabilityEquivalent(thread, other_type, kind)) {
+    return false;
+  }
+  // Equal record types must have equal field types and names.
+  AbstractType& field_type = Type::Handle(zone);
+  AbstractType& other_field_type = Type::Handle(zone);
+  const intptr_t num_fields = NumFields();
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    field_type = FieldTypeAt(i);
+    other_field_type = other_type.FieldTypeAt(i);
+    if (!field_type.IsEquivalent(other_field_type, kind, trail)) {
+      return false;
+    }
+  }
+  if (field_names() != other_type.field_names()) {
+    const intptr_t num_named_fields = NumNamedFields();
+    for (intptr_t i = 0; i < num_named_fields; ++i) {
+      if (FieldNameAt(i) != other_type.FieldNameAt(i)) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+uword RecordType::ComputeHash() const {
+  ASSERT(IsFinalized());
+  uint32_t result = 0;
+  // A legacy type should have the same hash as its non-nullable version to be
+  // consistent with the definition of type equality in Dart code.
+  Nullability type_nullability = nullability();
+  if (type_nullability == Nullability::kLegacy) {
+    type_nullability = Nullability::kNonNullable;
+  }
+  result = CombineHashes(result, static_cast<uint32_t>(type_nullability));
+  AbstractType& type = AbstractType::Handle();
+  const intptr_t num_fields = NumFields();
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    type = FieldTypeAt(i);
+    result = CombineHashes(result, type.Hash());
+  }
+  const intptr_t num_named_fields = NumNamedFields();
+  if (num_named_fields > 0) {
+    String& field_name = String::Handle();
+    for (intptr_t i = 0; i < num_named_fields; ++i) {
+      field_name = FieldNameAt(i);
+      result = CombineHashes(result, field_name.Hash());
+    }
+  }
+  result = FinalizeHash(result, kHashBits);
+  SetHash(result);
+  return result;
+}
+
+bool RecordType::IsRecursive(TrailPtr trail) const {
+  AbstractType& type = AbstractType::Handle();
+  const intptr_t num_fields = NumFields();
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    type = FieldTypeAt(i);
+    if (type.IsRecursive(trail)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool RecordType::RequireConstCanonicalTypeErasure(Zone* zone,
+                                                  TrailPtr trail) const {
+  if (IsNonNullable()) {
+    return true;
+  }
+  if (IsLegacy()) {
+    return false;
+  }
+  AbstractType& type = AbstractType::Handle();
+  const intptr_t num_fields = NumFields();
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    type = FieldTypeAt(i);
+    if (type.RequireConstCanonicalTypeErasure(zone, trail)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+AbstractTypePtr RecordType::Canonicalize(Thread* thread, TrailPtr trail) const {
+  ASSERT(IsFinalized());
+  Zone* zone = thread->zone();
+  AbstractType& type = AbstractType::Handle(zone);
+  if (IsCanonical()) {
+#ifdef DEBUG
+    // Verify that all fields are allocated in old space and are canonical.
+    ASSERT(Array::Handle(zone, field_types()).IsOld());
+    ASSERT(Array::Handle(zone, field_names()).IsOld());
+    const intptr_t num_fields = NumFields();
+    for (intptr_t i = 0; i < num_fields; ++i) {
+      type = FieldTypeAt(i);
+      ASSERT(type.IsOld());
+      ASSERT(type.IsCanonical());
+    }
+#endif
+    return ptr();
+  }
+  auto isolate_group = thread->isolate_group();
+  ObjectStore* object_store = isolate_group->object_store();
+  RecordType& rec = RecordType::Handle(zone);
+  {
+    SafepointMutexLocker ml(isolate_group->type_canonicalization_mutex());
+    CanonicalRecordTypeSet table(zone, object_store->canonical_record_types());
+    rec ^= table.GetOrNull(CanonicalRecordTypeKey(*this));
+    ASSERT(object_store->canonical_record_types() == table.Release().ptr());
+  }
+  if (rec.IsNull()) {
+    ASSERT(Array::Handle(zone, field_types()).IsOld());
+    ASSERT(Array::Handle(zone, field_names()).IsOld());
+    const intptr_t num_fields = NumFields();
+    for (intptr_t i = 0; i < num_fields; ++i) {
+      type = FieldTypeAt(i);
+      if (!type.IsCanonical()) {
+        type = type.Canonicalize(thread, trail);
+        SetFieldTypeAt(i, type);
+        SetHash(0);
+      }
+    }
+    if (IsCanonical()) {
+      // Canonicalizing fields types canonicalized this record as a
+      // side effect.
+      ASSERT(IsRecursive());
+      return this->ptr();
+    }
+    // Check to see if the record type got added to canonical table as part
+    // of the canonicalization of its signature types.
+    SafepointMutexLocker ml(isolate_group->type_canonicalization_mutex());
+    CanonicalRecordTypeSet table(zone, object_store->canonical_record_types());
+    rec ^= table.GetOrNull(CanonicalRecordTypeKey(*this));
+    if (rec.IsNull()) {
+      // Add this record type into the canonical table of record types.
+      if (this->IsNew()) {
+        rec ^= Object::Clone(*this, Heap::kOld);
+      } else {
+        rec = this->ptr();
+      }
+      ASSERT(rec.IsOld());
+      rec.SetCanonical();  // Mark object as being canonical.
+      bool present = table.Insert(rec);
+      ASSERT(!present);
+    }
+    object_store->set_canonical_record_types(table.Release());
+  }
+  return rec.ptr();
+}
+
+#if defined(DEBUG)
+bool RecordType::CheckIsCanonical(Thread* thread) const {
+  Zone* zone = thread->zone();
+  auto isolate_group = thread->isolate_group();
+  RecordType& type = RecordType::Handle(zone);
+  ObjectStore* object_store = isolate_group->object_store();
+  {
+    ASSERT(thread->isolate_group()
+               ->constant_canonicalization_mutex()
+               ->IsOwnedByCurrentThread());
+    CanonicalRecordTypeSet table(zone, object_store->canonical_record_types());
+    type ^= table.GetOrNull(CanonicalRecordTypeKey(*this));
+    object_store->set_canonical_record_types(table.Release());
+  }
+  return ptr() == type.ptr();
+}
+#endif  // DEBUG
+
+void RecordType::EnumerateURIs(URIs* uris) const {
+  AbstractType& type = AbstractType::Handle();
+  const intptr_t num_fields = NumFields();
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    type = FieldTypeAt(i);
+    type.EnumerateURIs(uris);
+  }
+}
+
+AbstractTypePtr RecordType::InstantiateFrom(
+    const TypeArguments& instantiator_type_arguments,
+    const TypeArguments& function_type_arguments,
+    intptr_t num_free_fun_type_params,
+    Heap::Space space,
+    TrailPtr trail) const {
+  ASSERT(IsFinalized() || IsBeingFinalized());
+  Zone* zone = Thread::Current()->zone();
+
+  const intptr_t num_fields = NumFields();
+  const Array& old_field_types = Array::Handle(zone, field_types());
+  const Array& new_field_types =
+      Array::Handle(zone, Array::New(num_fields, space));
+  AbstractType& type = AbstractType::Handle(zone);
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    type ^= old_field_types.At(i);
+    if (!type.IsInstantiated()) {
+      type = type.InstantiateFrom(instantiator_type_arguments,
+                                  function_type_arguments,
+                                  num_free_fun_type_params, space, trail);
+      // A returned null type indicates a failed instantiation in dead code that
+      // must be propagated up to the caller, the optimizing compiler.
+      if (type.IsNull()) {
+        return RecordType::null();
+      }
+    }
+    new_field_types.SetAt(i, type);
+  }
+
+  const auto& rec = RecordType::Handle(
+      zone, RecordType::New(new_field_types, Array::Handle(zone, field_names()),
+                            nullability(), space));
+
+  if (IsFinalized()) {
+    rec.SetIsFinalized();
+  } else {
+    if (IsBeingFinalized()) {
+      rec.SetIsBeingFinalized();
+    }
+  }
+
+  // Canonicalization is not part of instantiation.
+  return rec.ptr();
+}
+
+bool RecordType::IsSubtypeOf(const RecordType& other, Heap::Space space) const {
+  if (ptr() == other.ptr()) {
+    return true;
+  }
+  ASSERT(IsFinalized());
+  ASSERT(other.IsFinalized());
+  const intptr_t num_fields = NumFields();
+  if ((num_fields != other.NumFields()) ||
+      (field_names() != other.field_names())) {
+    // Different number of fields or different named fields.
+    return false;
+  }
+  Thread* const thread = Thread::Current();
+  if (!IsNullabilityEquivalent(thread, other, TypeEquality::kInSubtypeTest)) {
+    return false;
+  }
+  // Check subtyping of record field types.
+  Zone* const zone = thread->zone();
+  AbstractType& field_type = Type::Handle(zone);
+  AbstractType& other_field_type = Type::Handle(zone);
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    field_type = FieldTypeAt(i);
+    other_field_type = other.FieldTypeAt(i);
+    if (!field_type.IsSubtypeOf(other_field_type, space)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+intptr_t Record::NumNamedFields() const {
+  return Array::LengthOf(field_names());
+}
+
+intptr_t Record::NumPositionalFields() const {
+  return num_fields() - NumNamedFields();
+}
+
+void Record::set_num_fields(intptr_t num_fields) const {
+  ASSERT(num_fields >= 0);
+  StoreNonPointer(&untag()->num_fields_, num_fields);
+}
+
+void Record::set_field_names(const Array& field_names) const {
+  ASSERT(!field_names.IsNull());
+  ASSERT(field_names.IsCanonical());
+  ASSERT(field_names.ptr() == Object::empty_array().ptr() ||
+         field_names.Length() > 0);
+  untag()->set_field_names(field_names.ptr());
+}
+
+RecordPtr Record::New(intptr_t num_fields,
+                      const Array& field_names,
+                      Heap::Space space) {
+  ASSERT(num_fields >= 0);
+  Record& result = Record::Handle();
+  {
+    ObjectPtr raw =
+        Object::Allocate(Record::kClassId, Record::InstanceSize(num_fields),
+                         space, Record::ContainsCompressedPointers());
+    NoSafepointScope no_safepoint;
+    result ^= raw;
+    result.set_num_fields(num_fields);
+  }
+  result.set_field_names(field_names);
+  return result.ptr();
+}
+
+const char* Record::ToCString() const {
+  if (IsNull()) {
+    return "Record: null";
+  }
+  Zone* zone = Thread::Current()->zone();
+  ZoneTextBuffer printer(zone);
+  const intptr_t num_fields = this->num_fields();
+  const intptr_t num_positional_fields = NumPositionalFields();
+  const Array& field_names = Array::Handle(zone, this->field_names());
+  Object& obj = Object::Handle(zone);
+  printer.AddString("Record (");
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    if (i != 0) {
+      printer.AddString(", ");
+    }
+    if (i >= num_positional_fields) {
+      obj = field_names.At(i - num_positional_fields);
+      printer.AddString(obj.ToCString());
+      printer.AddString(": ");
+    }
+    obj = FieldAt(i);
+    printer.AddString(obj.ToCString());
+  }
+  printer.AddString(")");
+  return printer.buffer();
+}
+
+bool Record::CanonicalizeEquals(const Instance& other) const {
+  if (this->ptr() == other.ptr()) {
+    return true;
+  }
+
+  if (!other.IsRecord() || other.IsNull()) {
+    return false;
+  }
+
+  const Record& other_rec = Record::Cast(other);
+
+  const intptr_t num_fields = this->num_fields();
+  if (num_fields != other_rec.num_fields()) {
+    return false;
+  }
+
+  if (field_names() != other_rec.field_names()) {
+    return false;
+  }
+
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    if (this->FieldAt(i) != other_rec.FieldAt(i)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+uint32_t Record::CanonicalizeHash() const {
+  Thread* thread = Thread::Current();
+  uint32_t hash = thread->heap()->GetCanonicalHash(ptr());
+  if (hash != 0) {
+    return hash;
+  }
+  const intptr_t num_fields = this->num_fields();
+  hash = num_fields;
+  Instance& element = Instance::Handle(field_names());
+  hash = CombineHashes(hash, element.CanonicalizeHash());
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    element ^= FieldAt(i);
+    hash = CombineHashes(hash, element.CanonicalizeHash());
+  }
+  hash = FinalizeHash(hash, kHashBits);
+  thread->heap()->SetCanonicalHash(ptr(), hash);
+  return hash;
+}
+
+void Record::CanonicalizeFieldsLocked(Thread* thread) const {
+  Zone* zone = thread->zone();
+  Instance& obj = Instance::Handle(zone);
+  const intptr_t num_fields = this->num_fields();
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    obj ^= FieldAt(i);
+    obj = obj.CanonicalizeLocked(thread);
+    SetFieldAt(i, obj);
+  }
+}
+
+RecordTypePtr Record::GetRecordType() const {
+  Zone* const zone = Thread::Current()->zone();
+  const intptr_t num_fields = this->num_fields();
+  const Array& field_types =
+      Array::Handle(zone, Array::New(num_fields, Heap::kOld));
+  Instance& obj = Instance::Handle(zone);
+  AbstractType& type = AbstractType::Handle(zone);
+  for (intptr_t i = 0; i < num_fields; ++i) {
+    obj ^= FieldAt(i);
+    type = obj.GetType(Heap::kNew);
+    field_types.SetAt(i, type);
+  }
+  const Array& field_names = Array::Handle(zone, this->field_names());
+  type = RecordType::New(field_types, field_names, Nullability::kNonNullable);
+  type = ClassFinalizer::FinalizeType(type);
+  return RecordType::Cast(type).ptr();
+}
+
 }  // namespace dart
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 6612a30..a3ab391 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -439,6 +439,7 @@
   V(Instance, null_instance)                                                   \
   V(Function, null_function)                                                   \
   V(FunctionType, null_function_type)                                          \
+  V(RecordType, null_record_type)                                              \
   V(TypeArguments, null_type_arguments)                                        \
   V(CompressedStackMaps, null_compressed_stackmaps)                            \
   V(TypeArguments, empty_type_arguments)                                       \
@@ -633,7 +634,7 @@
   };
 
  protected:
-  friend ObjectPtr AllocateObject(intptr_t, intptr_t);
+  friend ObjectPtr AllocateObject(intptr_t, intptr_t, intptr_t);
 
   // Used for extracting the C++ vtable during bringup.
   Object() : ptr_(null_) {}
@@ -1302,10 +1303,10 @@
   }
 
   // Asserts that the class of the super type has been resolved.
-  // |original_classes| only has an effect when reloading. If true and we
-  // are reloading, it will prefer the original classes to the replacement
-  // classes.
-  ClassPtr SuperClass(bool original_classes = false) const;
+  // If |class_table| is provided it will be used to resolve class id to the
+  // actual class object, instead of using current class table on the isolate
+  // group.
+  ClassPtr SuperClass(ClassTable* class_table = nullptr) const;
 
   // Interfaces is an array of Types.
   ArrayPtr interfaces() const {
@@ -1443,6 +1444,11 @@
     return GetClassId(cls) == kClosureCid;
   }
 
+  // Check if this class represents the 'Record' class.
+  bool IsRecordClass() const {
+    return id() == kRecordCid;
+  }
+
   static bool IsInFullSnapshot(ClassPtr cls) {
     NoSafepointScope no_safepoint;
     return UntaggedLibrary::InFullSnapshotBit::decode(
@@ -1491,10 +1497,9 @@
 
   // Returns an array of all instance fields of this class and its superclasses
   // indexed by offset in words.
-  // |original_classes| only has an effect when reloading. If true and we
-  // are reloading, it will prefer the original classes to the replacement
-  // classes.
-  ArrayPtr OffsetToFieldMap(bool original_classes = false) const;
+  // If |class_table| is provided it will be used to resolve super classes by
+  // class id, instead of the current class_table stored in the isolate.
+  ArrayPtr OffsetToFieldMap(ClassTable* class_table = nullptr) const;
 
   // Returns true if non-static fields are defined.
   bool HasInstanceFields() const;
@@ -1826,6 +1831,10 @@
 #endif  // defined(DART_PRECOMPILER)
   }
 
+  static intptr_t UnboxedFieldSizeInBytesByCid(intptr_t cid);
+  void MarkFieldBoxedDuringReload(ClassTable* class_table,
+                                  const Field& field) const;
+
  private:
   TypePtr declaration_type() const {
     return untag()->declaration_type<std::memory_order_acquire>();
@@ -1840,7 +1849,8 @@
                              ProgramReloadContext* context) const;
 
   // Tells whether instances need morphing for reload.
-  bool RequiresInstanceMorphing(const Class& replacement) const;
+  bool RequiresInstanceMorphing(ClassTable* class_table,
+                                const Class& replacement) const;
 
   template <class FakeInstance, class TargetFakeInstance>
   static ClassPtr NewCommon(intptr_t index);
@@ -4049,9 +4059,6 @@
     return !untag()->owner()->IsField();
   }
 
-  // Mark previously unboxed field boxed. Only operates on clones, updates
-  // original as well as this clone.
-  void DisableFieldUnboxing() const;
   // Returns a field cloned from 'this'. 'this' is set as the
   // original field of result.
   FieldPtr CloneFromOriginal() const;
@@ -4083,22 +4090,6 @@
     // TODO(36097): Once concurrent access is possible ensure updates are safe.
     set_kind_bits(ReflectableBit::update(value, untag()->kind_bits_));
   }
-  bool is_double_initialized() const {
-    return DoubleInitializedBit::decode(kind_bits());
-  }
-  // Called in parser after allocating field, immutable property otherwise.
-  // Marks fields that are initialized with a simple double constant.
-  void set_is_double_initialized_unsafe(bool value) const {
-    ASSERT(IsOriginal());
-    // TODO(36097): Once concurrent access is possible ensure updates are safe.
-    set_kind_bits(DoubleInitializedBit::update(value, untag()->kind_bits_));
-  }
-
-  void set_is_double_initialized(bool value) const {
-    DEBUG_ASSERT(
-        IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
-    set_is_double_initialized_unsafe(value);
-  }
 
   bool initializer_changed_after_initialization() const {
     return InitializerChangedAfterInitializatonBit::decode(kind_bits());
@@ -4263,17 +4254,6 @@
     return has_initializer() && !has_nontrivial_initializer();
   }
 
-  bool is_non_nullable_integer() const {
-    return IsNonNullableIntBit::decode(kind_bits());
-  }
-
-  void set_is_non_nullable_integer(bool is_non_nullable_integer) const {
-    ASSERT(Thread::Current()->IsMutatorThread());
-    // TODO(36097): Once concurrent access is possible ensure updates are safe.
-    set_kind_bits(IsNonNullableIntBit::update(is_non_nullable_integer,
-                                              untag()->kind_bits_));
-  }
-
   StaticTypeExactnessState static_type_exactness_state() const {
     return StaticTypeExactnessState::Decode(
         LoadNonPointer<int8_t, std::memory_order_relaxed>(
@@ -4353,22 +4333,20 @@
 
   const char* GuardedPropertiesAsCString() const;
 
-  intptr_t UnboxedFieldCid() const { return guarded_cid(); }
-
-  bool is_unboxing_candidate() const {
-    return UnboxingCandidateBit::decode(kind_bits());
+  bool is_unboxed() const {
+    return UnboxedBit::decode(kind_bits());
   }
 
-  // Default 'true', set to false once optimizing compiler determines it should
-  // be boxed.
-  void set_is_unboxing_candidate_unsafe(bool b) const {
-    set_kind_bits(UnboxingCandidateBit::update(b, untag()->kind_bits_));
+  // Field unboxing decisions are based either on static types (JIT) or
+  // inferred types (AOT). See the callers of this function.
+  void set_is_unboxed_unsafe(bool b) const {
+    set_kind_bits(UnboxedBit::update(b, untag()->kind_bits_));
   }
 
-  void set_is_unboxing_candidate(bool b) const {
+  void set_is_unboxed(bool b) const {
     DEBUG_ASSERT(
         IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
-    set_is_unboxing_candidate_unsafe(b);
+    set_is_unboxed_unsafe(b);
   }
 
   enum {
@@ -4483,10 +4461,6 @@
   void set_type_test_cache(const SubtypeTestCache& cache) const;
 #endif
 
-  // Unboxed fields require exclusive ownership of the box.
-  // Ensure this by cloning the box if necessary.
-  const Object* CloneForUnboxed(const Object& value) const;
-
  private:
   static void InitializeNew(const Field& result,
                             const String& name,
@@ -4505,9 +4479,8 @@
     kStaticBit,
     kFinalBit,
     kHasNontrivialInitializerBit,
-    kUnboxingCandidateBit,
+    kUnboxedBit,
     kReflectableBit,
-    kDoubleInitializedBit,
     kInitializerChangedAfterInitializatonBit,
     kHasPragmaBit,
     kCovariantBit,
@@ -4516,18 +4489,14 @@
     kIsExtensionMemberBit,
     kNeedsLoadGuardBit,
     kHasInitializerBit,
-    kIsNonNullableIntBit,
   };
   class ConstBit : public BitField<uint16_t, bool, kConstBit, 1> {};
   class StaticBit : public BitField<uint16_t, bool, kStaticBit, 1> {};
   class FinalBit : public BitField<uint16_t, bool, kFinalBit, 1> {};
   class HasNontrivialInitializerBit
       : public BitField<uint16_t, bool, kHasNontrivialInitializerBit, 1> {};
-  class UnboxingCandidateBit
-      : public BitField<uint16_t, bool, kUnboxingCandidateBit, 1> {};
+  class UnboxedBit : public BitField<uint16_t, bool, kUnboxedBit, 1> {};
   class ReflectableBit : public BitField<uint16_t, bool, kReflectableBit, 1> {};
-  class DoubleInitializedBit
-      : public BitField<uint16_t, bool, kDoubleInitializedBit, 1> {};
   class InitializerChangedAfterInitializatonBit
       : public BitField<uint16_t,
                         bool,
@@ -4544,8 +4513,6 @@
       : public BitField<uint16_t, bool, kNeedsLoadGuardBit, 1> {};
   class HasInitializerBit
       : public BitField<uint16_t, bool, kHasInitializerBit, 1> {};
-  class IsNonNullableIntBit
-      : public BitField<uint16_t, bool, kIsNonNullableIntBit, 1> {};
 
   // Force this field's guard to be dynamic and deoptimize dependent code.
   void ForceDynamicGuardedCidAndLength() const;
@@ -5483,7 +5450,7 @@
 
   static const intptr_t kMaxElements =
       (kMaxInt32 - (sizeof(UntaggedInstructions) + sizeof(UntaggedObject) +
-                    (2 * kMaxObjectAlignment)));
+                    (2 * kObjectStartAlignment)));
 
   // Currently, we align bare instruction payloads on 4 byte boundaries.
   //
@@ -7765,7 +7732,20 @@
     StoreCompressedPointer(RawFieldAddrAtOffset(offset), value.ptr());
   }
 
-  static InstancePtr NewFromCidAndSize(SharedClassTable* shared_class_table,
+  template <typename T>
+  T* RawUnboxedFieldAddrAtOffset(intptr_t offset) const {
+    return reinterpret_cast<T*>(raw_value() - kHeapObjectTag + offset);
+  }
+  template <typename T>
+  T RawGetUnboxedFieldAtOffset(intptr_t offset) const {
+    return *RawUnboxedFieldAddrAtOffset<T>(offset);
+  }
+  template <typename T>
+  void RawSetUnboxedFieldAtOffset(intptr_t offset, const T& value) const {
+    *RawUnboxedFieldAddrAtOffset<T>(offset) = value;
+  }
+
+  static InstancePtr NewFromCidAndSize(ClassTable* class_table,
                                        classid_t cid,
                                        Heap::Space heap = Heap::kNew);
 
@@ -8185,12 +8165,25 @@
 // Subclasses of AbstractType are Type and TypeParameter.
 class AbstractType : public Instance {
  public:
-  virtual bool IsFinalized() const;
-  virtual void SetIsFinalized() const;
-  virtual bool IsBeingFinalized() const;
-  virtual void SetIsBeingFinalized() const;
+  static intptr_t flags_offset() {
+    return OFFSET_OF(UntaggedAbstractType, flags_);
+  }
 
-  virtual Nullability nullability() const;
+  bool IsFinalized() const {
+    const auto state = type_state();
+    return (state == UntaggedAbstractType::kFinalizedInstantiated) ||
+           (state == UntaggedAbstractType::kFinalizedUninstantiated);
+  }
+  void SetIsFinalized() const;
+  bool IsBeingFinalized() const {
+    return type_state() == UntaggedAbstractType::kBeingFinalized;
+  }
+  void SetIsBeingFinalized() const;
+
+  Nullability nullability() const {
+    return static_cast<Nullability>(
+        UntaggedAbstractType::NullabilityBits::decode(untag()->flags_));
+  }
   // Returns true if type has '?' nullability suffix, or it is a
   // built-in type which is always nullable (Null, dynamic or void).
   bool IsNullable() const { return nullability() == Nullability::kNullable; }
@@ -8396,6 +8389,9 @@
   // Check if this type represents the Dart '_Closure' type.
   bool IsDartClosureType() const;
 
+  // Check if this type represents the Dart 'Record' type.
+  bool IsDartRecordType() const;
+
   // Check if this type represents the 'Pointer' type from "dart:ffi".
   bool IsFfiPointerType() const;
 
@@ -8406,6 +8402,10 @@
   // Returns unmodified type if this type is not a 'FutureOr' type.
   AbstractTypePtr UnwrapFutureOr() const;
 
+  // Returns true if parameter of this type might need a
+  // null assertion (if null assertions are enabled).
+  bool NeedsNullAssertion() const;
+
   // Returns true if catching this type will catch all exceptions.
   // Exception objects are guaranteed to be non-nullable, so
   // non-nullable Object is also a catch-all type.
@@ -8471,45 +8471,37 @@
                            TrailPtr trail = nullptr) const;
 
  protected:
+  bool IsNullabilityEquivalent(Thread* thread,
+                               const AbstractType& other_type,
+                               TypeEquality kind) const;
+
+  UntaggedAbstractType::TypeState type_state() const {
+    return static_cast<UntaggedAbstractType::TypeState>(
+        UntaggedAbstractType::TypeStateBits::decode(untag()->flags_));
+  }
+  void set_flags(uint32_t value) const;
+  void set_type_state(UntaggedAbstractType::TypeState value) const;
+  void set_nullability(Nullability value) const;
+
   HEAP_OBJECT_IMPLEMENTATION(AbstractType, Instance);
   friend class Class;
   friend class Function;
   friend class TypeArguments;
+  friend class TypeRef;
 };
 
 // A Type consists of a class, possibly parameterized with type
 // arguments. Example: C<T1, T2>.
 class Type : public AbstractType {
  public:
-  static intptr_t type_class_id_offset() {
-    return OFFSET_OF(UntaggedType, type_class_id_);
-  }
   static intptr_t arguments_offset() {
     return OFFSET_OF(UntaggedType, arguments_);
   }
-  static intptr_t type_state_offset() {
-    return OFFSET_OF(UntaggedType, type_state_);
-  }
   static intptr_t hash_offset() { return OFFSET_OF(UntaggedType, hash_); }
-  static intptr_t nullability_offset() {
-    return OFFSET_OF(UntaggedType, nullability_);
-  }
-  virtual bool IsFinalized() const {
-    return (untag()->type_state_ == UntaggedType::kFinalizedInstantiated) ||
-           (untag()->type_state_ == UntaggedType::kFinalizedUninstantiated);
-  }
-  virtual void SetIsFinalized() const;
-  virtual bool IsBeingFinalized() const {
-    return untag()->type_state_ == UntaggedType::kBeingFinalized;
-  }
-  virtual void SetIsBeingFinalized() const;
   virtual bool HasTypeClass() const {
     ASSERT(type_class_id() != kIllegalCid);
     return true;
   }
-  virtual Nullability nullability() const {
-    return static_cast<Nullability>(untag()->nullability_);
-  }
   TypePtr ToNullability(Nullability value, Heap::Space space) const;
   virtual classid_t type_class_id() const;
   virtual ClassPtr type_class() const;
@@ -8625,11 +8617,6 @@
   // in ClassIdTagType. This allows us to guard against that case, instead of
   // silently truncating the cid.
   void set_type_class_id(intptr_t id) const;
-  void set_type_state(uint8_t state) const;
-  void set_nullability(Nullability value) const {
-    ASSERT(!IsCanonical());
-    StoreNonPointer(&untag()->nullability_, static_cast<uint8_t>(value));
-  }
 
   static TypePtr New(Heap::Space space = Heap::kOld);
 
@@ -8657,28 +8644,10 @@
   using PackedNumOptionalParameters =
       UntaggedFunctionType::PackedNumOptionalParameters;
 
-  static intptr_t type_state_offset() {
-    return OFFSET_OF(UntaggedFunctionType, type_state_);
-  }
   static intptr_t hash_offset() {
     return OFFSET_OF(UntaggedFunctionType, hash_);
   }
-  static intptr_t nullability_offset() {
-    return OFFSET_OF(UntaggedFunctionType, nullability_);
-  }
-  virtual bool IsFinalized() const {
-    return (untag()->type_state_ == UntaggedType::kFinalizedInstantiated) ||
-           (untag()->type_state_ == UntaggedType::kFinalizedUninstantiated);
-  }
-  virtual void SetIsFinalized() const;
-  virtual bool IsBeingFinalized() const {
-    return untag()->type_state_ == UntaggedType::kBeingFinalized;
-  }
-  virtual void SetIsBeingFinalized() const;
   virtual bool HasTypeClass() const { return false; }
-  virtual Nullability nullability() const {
-    return static_cast<Nullability>(untag()->nullability_);
-  }
   FunctionTypePtr ToNullability(Nullability value, Heap::Space space) const;
   virtual classid_t type_class_id() const { return kIllegalCid; }
   virtual bool IsInstantiated(Genericity genericity = kAny,
@@ -8928,12 +8897,6 @@
  private:
   void SetHash(intptr_t value) const;
 
-  void set_type_state(uint8_t state) const;
-  void set_nullability(Nullability value) const {
-    ASSERT(!IsCanonical());
-    StoreNonPointer(&untag()->nullability_, static_cast<uint8_t>(value));
-  }
-
   static FunctionTypePtr New(Heap::Space space);
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(FunctionType, AbstractType);
@@ -8942,6 +8905,88 @@
   friend class Function;
 };
 
+// A RecordType represents the type of a record. It describes
+// number of named and positional fields, field types and
+// names of the named fields.
+class RecordType : public AbstractType {
+ public:
+  static intptr_t hash_offset() { return OFFSET_OF(UntaggedRecordType, hash_); }
+  virtual bool HasTypeClass() const { return false; }
+  RecordTypePtr ToNullability(Nullability value, Heap::Space space) const;
+  virtual classid_t type_class_id() const { return kIllegalCid; }
+  virtual bool IsInstantiated(Genericity genericity = kAny,
+                              intptr_t num_free_fun_type_params = kAllFree,
+                              TrailPtr trail = nullptr) const;
+  virtual bool IsEquivalent(const Instance& other,
+                            TypeEquality kind,
+                            TrailPtr trail = nullptr) const;
+  virtual bool IsRecursive(TrailPtr trail = nullptr) const;
+  virtual bool RequireConstCanonicalTypeErasure(Zone* zone,
+                                                TrailPtr trail = nullptr) const;
+
+  virtual AbstractTypePtr InstantiateFrom(
+      const TypeArguments& instantiator_type_arguments,
+      const TypeArguments& function_type_arguments,
+      intptr_t num_free_fun_type_params,
+      Heap::Space space,
+      TrailPtr trail = nullptr) const;
+  virtual AbstractTypePtr Canonicalize(Thread* thread, TrailPtr trail) const;
+#if defined(DEBUG)
+  // Check if type is canonical.
+  virtual bool CheckIsCanonical(Thread* thread) const;
+#endif  // DEBUG
+  virtual void EnumerateURIs(URIs* uris) const;
+
+  virtual uword Hash() const;
+  uword ComputeHash() const;
+
+  bool IsSubtypeOf(const RecordType& other, Heap::Space space) const;
+
+  ArrayPtr field_types() const {
+    return untag()->field_types();
+  }
+
+  AbstractTypePtr FieldTypeAt(intptr_t index) const;
+  void SetFieldTypeAt(intptr_t index, const AbstractType& value) const;
+
+  // Names of the named fields, sorted.
+  ArrayPtr field_names() const {
+    return untag()->field_names();
+  }
+
+  StringPtr FieldNameAt(intptr_t index) const;
+  void SetFieldNameAt(intptr_t index, const String& value) const;
+
+  intptr_t NumFields() const;
+  intptr_t NumNamedFields() const;
+  intptr_t NumPositionalFields() const;
+
+  void Print(NameVisibility name_visibility, BaseTextBuffer* printer) const;
+
+  static intptr_t InstanceSize() {
+    return RoundedAllocationSize(sizeof(UntaggedRecordType));
+  }
+
+  static RecordTypePtr New(const Array& field_types,
+                           const Array& field_names,
+                           Nullability nullability = Nullability::kLegacy,
+                           Heap::Space space = Heap::kOld);
+
+ private:
+  void SetHash(intptr_t value) const;
+
+  void set_field_types(const Array& value) const;
+  void set_field_names(const Array& value) const;
+
+  static RecordTypePtr New(Heap::Space space);
+
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(RecordType, AbstractType);
+  friend class Class;
+  friend class ClassFinalizer;
+  friend class ClearTypeHashVisitor;
+  friend class Record;
+};
+
 // A TypeRef is used to break cycles in the representation of recursive types.
 // Its only field is the recursive AbstractType it refers to, which can
 // temporarily be null during finalization.
@@ -8950,19 +8995,6 @@
  public:
   static intptr_t type_offset() { return OFFSET_OF(UntaggedTypeRef, type_); }
 
-  virtual bool IsFinalized() const {
-    const AbstractType& ref_type = AbstractType::Handle(type());
-    return !ref_type.IsNull() && ref_type.IsFinalized();
-  }
-  virtual bool IsBeingFinalized() const {
-    const AbstractType& ref_type = AbstractType::Handle(type());
-    return ref_type.IsNull() || ref_type.IsBeingFinalized();
-  }
-  virtual Nullability nullability() const {
-    const AbstractType& ref_type = AbstractType::Handle(type());
-    ASSERT(!ref_type.IsNull());
-    return ref_type.nullability();
-  }
   virtual bool HasTypeClass() const {
     return (type() != AbstractType::null()) &&
            AbstractType::Handle(type()).HasTypeClass();
@@ -9027,23 +9059,6 @@
 // to the ObjectType.
 class TypeParameter : public AbstractType {
  public:
-  virtual bool IsFinalized() const {
-    return UntaggedTypeParameter::FinalizedBit::decode(untag()->flags_);
-  }
-  virtual void SetIsFinalized() const;
-  virtual bool IsBeingFinalized() const {
-    return UntaggedTypeParameter::BeingFinalizedBit::decode(untag()->flags_);
-  }
-  virtual void SetIsBeingFinalized() const;
-  static intptr_t flags_offset() {
-    return OFFSET_OF(UntaggedTypeParameter, flags_);
-  }
-  static intptr_t nullability_offset() {
-    return OFFSET_OF(UntaggedTypeParameter, nullability_);
-  }
-  virtual Nullability nullability() const {
-    return static_cast<Nullability>(untag()->nullability_);
-  }
   TypeParameterPtr ToNullability(Nullability value, Heap::Space space) const;
   virtual bool HasTypeClass() const { return false; }
   virtual classid_t type_class_id() const { return kIllegalCid; }
@@ -9136,8 +9151,6 @@
 
   void set_parameterized_class(const Class& value) const;
   void set_name(const String& value) const;
-  void set_flags(uint8_t flags) const;
-  void set_nullability(Nullability value) const;
 
   static TypeParameterPtr New();
 
@@ -9323,6 +9336,7 @@
 
   int64_t value() const { return untag()->value_; }
   static intptr_t value_offset() { return OFFSET_OF(UntaggedMint, value_); }
+  static int64_t Value(MintPtr mint) { return mint->untag()->value_; }
 
   virtual bool IsZero() const { return value() == 0; }
   virtual bool IsNegative() const { return value() < 0; }
@@ -9363,6 +9377,7 @@
 class Double : public Number {
  public:
   double value() const { return untag()->value_; }
+  static double Value(DoublePtr dbl) { return dbl->untag()->value_; }
 
   bool BitwiseEqualsToDouble(double value) const;
   virtual bool OperatorEquals(const Instance& other) const;
@@ -10708,6 +10723,76 @@
   friend class Class;
 };
 
+class Record : public Instance {
+ public:
+  intptr_t num_fields() const { return NumFields(ptr()); }
+  static intptr_t NumFields(RecordPtr ptr) { return ptr->untag()->num_fields_; }
+  static intptr_t num_fields_offset() {
+    return OFFSET_OF(UntaggedRecord, num_fields_);
+  }
+
+  intptr_t NumNamedFields() const;
+  intptr_t NumPositionalFields() const;
+
+  ArrayPtr field_names() const { return untag()->field_names(); }
+  static intptr_t field_names_offset() {
+    return OFFSET_OF(UntaggedRecord, field_names_);
+  }
+
+  ObjectPtr FieldAt(intptr_t field_index) const {
+    return untag()->field(field_index);
+  }
+  void SetFieldAt(intptr_t field_index, const Object& value) const {
+    untag()->set_field(field_index, value.ptr());
+  }
+
+  static const intptr_t kBytesPerElement = kCompressedWordSize;
+  static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
+
+  struct ArrayTraits {
+    static intptr_t elements_start_offset() { return sizeof(UntaggedRecord); }
+    static constexpr intptr_t kElementSize = kBytesPerElement;
+  };
+
+  static intptr_t field_offset(intptr_t index) {
+    return OFFSET_OF_RETURNED_VALUE(UntaggedRecord, data) +
+           kBytesPerElement * index;
+  }
+
+  static intptr_t InstanceSize() {
+    ASSERT(sizeof(UntaggedRecord) ==
+           OFFSET_OF_RETURNED_VALUE(UntaggedRecord, data));
+    return 0;
+  }
+
+  static intptr_t InstanceSize(intptr_t num_fields) {
+    return RoundedAllocationSize(sizeof(UntaggedRecord) +
+                                 (num_fields * kBytesPerElement));
+  }
+
+  static RecordPtr New(intptr_t num_fields,
+                       const Array& field_names,
+                       Heap::Space space = Heap::kNew);
+
+  virtual bool CanonicalizeEquals(const Instance& other) const;
+  virtual uint32_t CanonicalizeHash() const;
+  virtual void CanonicalizeFieldsLocked(Thread* thread) const;
+
+  // Returns RecordType representing runtime type of this record instance.
+  // It is not created eagerly when record instance is allocated because
+  // it depends on runtime types of values if its fields, which can be
+  // quite expensive to query.
+  RecordTypePtr GetRecordType() const;
+
+ private:
+  void set_num_fields(intptr_t num_fields) const;
+  void set_field_names(const Array& field_names) const;
+
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(Record, Instance);
+  friend class Class;
+  friend class Object;
+};
+
 class PointerBase : public Instance {
  public:
   static intptr_t data_offset() {
@@ -12593,6 +12678,33 @@
   untag()->set_hash(Smi::New(value));
 }
 
+inline uword RecordType::Hash() const {
+  ASSERT(IsFinalized());
+  intptr_t result = Smi::Value(untag()->hash());
+  if (result != 0) {
+    return result;
+  }
+  return ComputeHash();
+}
+
+inline void RecordType::SetHash(intptr_t value) const {
+  // This is only safe because we create a new Smi, which does not cause
+  // heap allocation.
+  untag()->set_hash(Smi::New(value));
+}
+
+inline intptr_t RecordType::NumFields() const {
+  return Array::LengthOf(field_types());
+}
+
+inline intptr_t RecordType::NumNamedFields() const {
+  return Array::LengthOf(field_names());
+}
+
+inline intptr_t RecordType::NumPositionalFields() const {
+  return NumFields() - NumNamedFields();
+}
+
 inline uword TypeParameter::Hash() const {
   ASSERT(IsFinalized() || IsBeingFinalized());  // Bound may not be finalized.
   intptr_t result = Smi::Value(untag()->hash());
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index 5074cb5..33824c1 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -100,12 +100,10 @@
               // If the field is unboxed, we don't know the size of it (may be
               // multiple words) - but that doesn't matter because
               //   a) we will process instances using the slots we collect
-              //     (instead of regular GC visitor
+              //     (instead of regular GC visitor);
               //   b) we will not write the value of the field and instead treat
               //     it like a dummy reference to 0 (like we do with Smis).
-              const bool kIsUnboxedField =
-                  FLAG_precompiled_mode && field.is_unboxing_candidate();
-              slots->Add(ObjectSlot(field.HostOffset(), !kIsUnboxedField,
+              slots->Add(ObjectSlot(field.HostOffset(), !field.is_unboxed(),
                                     name.ToCString()));
             }
           }
@@ -708,7 +706,7 @@
   return visitor.length();
 }
 
-// Each OldPage is divided into blocks of size kBlockSize. Each object belongs
+// Each Page is divided into blocks of size kBlockSize. Each object belongs
 // to the block containing its header word.
 // When generating a heap snapshot, we assign objects sequential ids in heap
 // iteration order. A bitvector is computed that indicates the number of objects
@@ -765,7 +763,7 @@
   }
 
   CountingBlock* BlockFor(uword addr) {
-    intptr_t page_offset = addr & ~kOldPageMask;
+    intptr_t page_offset = addr & ~kPageMask;
     intptr_t block_number = page_offset / kBlockSize;
     ASSERT(block_number >= 0);
     ASSERT(block_number <= kBlocksPerPage);
@@ -818,7 +816,7 @@
     image_page_ranges_[i].size = 0;
   }
   intptr_t next_offset = 0;
-  OldPage* image_page =
+  Page* image_page =
       Dart::vm_isolate_group()->heap()->old_space()->image_pages_;
   while (image_page != NULL) {
     RELEASE_ASSERT(next_offset <= kMaxImagePages);
@@ -838,7 +836,7 @@
     next_offset++;
   }
 
-  OldPage* page = isolate_group()->heap()->old_space()->pages_;
+  Page* page = isolate_group()->heap()->old_space()->pages_;
   while (page != NULL) {
     page->forwarding_page();
     CountingPage* counting_page =
@@ -862,7 +860,7 @@
 CountingPage* HeapSnapshotWriter::FindCountingPage(ObjectPtr obj) const {
   if (obj->IsOldObject() && !OnImagePage(obj)) {
     // On a regular or large page.
-    OldPage* page = OldPage::Of(obj);
+    Page* page = Page::Of(obj);
     return reinterpret_cast<CountingPage*>(page->forwarding_page());
   }
 
@@ -890,7 +888,7 @@
 
   if (FLAG_write_protect_code && obj->IsInstructions() && !OnImagePage(obj)) {
     // A non-writable alias mapping may exist for instruction pages.
-    obj = OldPage::ToWritable(obj);
+    obj = Page::ToWritable(obj);
   }
 
   CountingPage* counting_page = FindCountingPage(obj);
diff --git a/runtime/vm/object_graph_copy.cc b/runtime/vm/object_graph_copy.cc
index 78daab15f..41d6bfc 100644
--- a/runtime/vm/object_graph_copy.cc
+++ b/runtime/vm/object_graph_copy.cc
@@ -67,6 +67,7 @@
   V(PcDescriptors)                                                             \
   V(Pointer)                                                                   \
   V(ReceivePort)                                                               \
+  V(RecordType)                                                                \
   V(RegExp)                                                                    \
   V(Script)                                                                    \
   V(Sentinel)                                                                  \
@@ -262,13 +263,18 @@
 }
 
 DART_FORCE_INLINE
-ObjectPtr AllocateObject(intptr_t cid, intptr_t size) {
+ObjectPtr AllocateObject(intptr_t cid,
+                         intptr_t size,
+                         intptr_t allocated_bytes) {
 #if defined(DART_COMPRESSED_POINTERS)
   const bool compressed = true;
 #else
   const bool compressed = false;
 #endif
-  return Object::Allocate(cid, size, Heap::kNew, compressed);
+  const intptr_t kLargeMessageThreshold = 16 * MB;
+  const Heap::Space space =
+      allocated_bytes > kLargeMessageThreshold ? Heap::kOld : Heap::kNew;
+  return Object::Allocate(cid, size, space, compressed);
 }
 
 DART_FORCE_INLINE
@@ -288,6 +294,9 @@
   } else if (IsTypedDataClassId(cid)) {
     static_cast<UntaggedTypedDataBase*>(to.untag())->length_ =
         static_cast<UntaggedTypedDataBase*>(from.untag())->length_;
+  } else if (cid == kRecordCid) {
+    static_cast<UntaggedRecord*>(to.untag())->num_fields_ =
+        static_cast<UntaggedRecord*>(from.untag())->num_fields_;
   }
 }
 
@@ -359,14 +368,199 @@
   delete static_cast<TransferableTypedDataPeer*>(peer);
 }
 
-class ForwardMapBase {
+class SlowFromTo {
  public:
-  explicit ForwardMapBase(Thread* thread)
-      : thread_(thread), zone_(thread->zone()), isolate_(thread->isolate()) {}
+  explicit SlowFromTo(const GrowableObjectArray& storage) : storage_(storage) {}
 
- protected:
-  friend class ObjectGraphCopier;
+  ObjectPtr At(intptr_t index) { return storage_.At(index); }
+  void Add(const Object& key, const Object& value) {
+    storage_.Add(key);
+    storage_.Add(value);
+  }
+  intptr_t Length() { return storage_.Length(); }
 
+ private:
+  const GrowableObjectArray& storage_;
+};
+
+class FastFromTo {
+ public:
+  explicit FastFromTo(GrowableArray<ObjectPtr>& storage) : storage_(storage) {}
+
+  ObjectPtr At(intptr_t index) { return storage_.At(index); }
+  void Add(ObjectPtr key, ObjectPtr value) {
+    intptr_t i = storage_.length();
+    storage_.Resize(i + 2);
+    storage_[i + 0] = key;
+    storage_[i + 1] = value;
+  }
+  intptr_t Length() { return storage_.length(); }
+
+ private:
+  GrowableArray<ObjectPtr>& storage_;
+};
+
+static ObjectPtr Ptr(ObjectPtr obj) {
+  return obj;
+}
+static ObjectPtr Ptr(const Object& obj) {
+  return obj.ptr();
+}
+
+#if defined(HASH_IN_OBJECT_HEADER)
+class IdentityMap {
+ public:
+  explicit IdentityMap(Thread* thread) : thread_(thread) {
+    hash_table_used_ = 0;
+    hash_table_capacity_ = 32;
+    hash_table_ = reinterpret_cast<uint32_t*>(
+        malloc(hash_table_capacity_ * sizeof(uint32_t)));
+    memset(hash_table_, 0, hash_table_capacity_ * sizeof(uint32_t));
+  }
+  ~IdentityMap() { free(hash_table_); }
+
+  template <typename S, typename T>
+  DART_FORCE_INLINE ObjectPtr ForwardedObject(const S& object, T from_to) {
+    intptr_t mask = hash_table_capacity_ - 1;
+    intptr_t probe = GetHeaderHash(Ptr(object)) & mask;
+    for (;;) {
+      intptr_t index = hash_table_[probe];
+      if (index == 0) {
+        return Marker();
+      }
+      if (from_to.At(index) == Ptr(object)) {
+        return from_to.At(index + 1);
+      }
+      probe = (probe + 1) & mask;
+    }
+  }
+
+  template <typename S, typename T>
+  DART_FORCE_INLINE void Insert(const S& from,
+                                const S& to,
+                                T from_to,
+                                bool check_for_safepoint) {
+    ASSERT(ForwardedObject(from, from_to) == Marker());
+    const auto id = from_to.Length();
+    from_to.Add(from, to);  // Must occur before rehashing.
+    intptr_t mask = hash_table_capacity_ - 1;
+    intptr_t probe = GetHeaderHash(Ptr(from)) & mask;
+    for (;;) {
+      intptr_t index = hash_table_[probe];
+      if (index == 0) {
+        hash_table_[probe] = id;
+        break;
+      }
+      probe = (probe + 1) & mask;
+    }
+    hash_table_used_++;
+    if (hash_table_used_ * 2 > hash_table_capacity_) {
+      Rehash(hash_table_capacity_ * 2, from_to, check_for_safepoint);
+    }
+  }
+
+ private:
+  DART_FORCE_INLINE
+  uint32_t GetHeaderHash(ObjectPtr object) {
+    uint32_t hash = Object::GetCachedHash(object);
+    if (hash == 0) {
+      switch (object->GetClassId()) {
+        case kMintCid:
+          hash = Mint::Value(static_cast<MintPtr>(object));
+          // Don't write back: doesn't agree with dart:core's identityHash.
+          break;
+        case kDoubleCid:
+          hash =
+              bit_cast<uint64_t>(Double::Value(static_cast<DoublePtr>(object)));
+          // Don't write back: doesn't agree with dart:core's identityHash.
+          break;
+        case kOneByteStringCid:
+        case kTwoByteStringCid:
+        case kExternalOneByteStringCid:
+        case kExternalTwoByteStringCid:
+          hash = String::Hash(static_cast<StringPtr>(object));
+          hash = Object::SetCachedHashIfNotSet(object, hash);
+          break;
+        default:
+          do {
+            hash = thread_->random()->NextUInt32();
+          } while (hash == 0 || !Smi::IsValid(hash));
+          hash = Object::SetCachedHashIfNotSet(object, hash);
+          break;
+      }
+    }
+    return hash;
+  }
+
+  template <typename T>
+  void Rehash(intptr_t new_capacity, T from_to, bool check_for_safepoint) {
+    hash_table_capacity_ = new_capacity;
+    hash_table_used_ = 0;
+    free(hash_table_);
+    hash_table_ = reinterpret_cast<uint32_t*>(
+        malloc(hash_table_capacity_ * sizeof(uint32_t)));
+    for (intptr_t i = 0; i < hash_table_capacity_; i++) {
+      hash_table_[i] = 0;
+      if (check_for_safepoint && (((i + 1) % KB) == 0)) {
+        thread_->CheckForSafepoint();
+      }
+    }
+    for (intptr_t id = 2; id < from_to.Length(); id += 2) {
+      ObjectPtr obj = from_to.At(id);
+      intptr_t mask = hash_table_capacity_ - 1;
+      intptr_t probe = GetHeaderHash(obj) & mask;
+      for (;;) {
+        if (hash_table_[probe] == 0) {
+          hash_table_[probe] = id;
+          hash_table_used_++;
+          break;
+        }
+        probe = (probe + 1) & mask;
+      }
+      if (check_for_safepoint && (((id + 2) % KB) == 0)) {
+        thread_->CheckForSafepoint();
+      }
+    }
+  }
+
+  Thread* thread_;
+  uint32_t* hash_table_;
+  uint32_t hash_table_capacity_;
+  uint32_t hash_table_used_;
+};
+#else   // defined(HASH_IN_OBJECT_HEADER)
+class IdentityMap {
+ public:
+  explicit IdentityMap(Thread* thread) : isolate_(thread->isolate()) {
+    isolate_->set_forward_table_new(new WeakTable());
+    isolate_->set_forward_table_old(new WeakTable());
+  }
+  ~IdentityMap() {
+    isolate_->set_forward_table_new(nullptr);
+    isolate_->set_forward_table_old(nullptr);
+  }
+
+  template <typename S, typename T>
+  DART_FORCE_INLINE ObjectPtr ForwardedObject(const S& object, T from_to) {
+    const intptr_t id = GetObjectId(Ptr(object));
+    if (id == 0) return Marker();
+    return from_to.At(id + 1);
+  }
+
+  template <typename S, typename T>
+  DART_FORCE_INLINE void Insert(const S& from,
+                                const S& to,
+                                T from_to,
+                                bool check_for_safepoint) {
+    ASSERT(ForwardedObject(from, from_to) == Marker());
+    const auto id = from_to.Length();
+    // May take >100ms and cannot yield to safepoints.
+    SetObjectId(Ptr(from), id);
+    from_to.Add(from, to);
+  }
+
+ private:
+  DART_FORCE_INLINE
   intptr_t GetObjectId(ObjectPtr object) {
     if (object->IsNewObject()) {
       return isolate_->forward_table_new()->GetValueExclusive(object);
@@ -374,6 +568,8 @@
       return isolate_->forward_table_old()->GetValueExclusive(object);
     }
   }
+
+  DART_FORCE_INLINE
   void SetObjectId(ObjectPtr object, intptr_t id) {
     if (object->IsNewObject()) {
       isolate_->forward_table_new()->SetValueExclusive(object, id);
@@ -382,6 +578,18 @@
     }
   }
 
+  Isolate* isolate_;
+};
+#endif  // defined(HASH_IN_OBJECT_HEADER)
+
+class ForwardMapBase {
+ public:
+  explicit ForwardMapBase(Thread* thread)
+      : thread_(thread), zone_(thread->zone()) {}
+
+ protected:
+  friend class ObjectGraphCopier;
+
   void FinalizeTransferable(const TransferableTypedData& from,
                             const TransferableTypedData& to) {
     // Get the old peer.
@@ -396,9 +604,12 @@
 
     // Move the handle itself to the new object.
     fpeer->handle()->EnsureFreedExternal(thread_->isolate_group());
-    tpeer->set_handle(FinalizablePersistentHandle::New(
-        thread_->isolate_group(), to, tpeer, FreeTransferablePeer, length,
-        /*auto_delete=*/true));
+    FinalizablePersistentHandle* finalizable_ref =
+        FinalizablePersistentHandle::New(thread_->isolate_group(), to, tpeer,
+                                         FreeTransferablePeer, length,
+                                         /*auto_delete=*/true);
+    ASSERT(finalizable_ref != nullptr);
+    tpeer->set_handle(finalizable_ref);
     fpeer->ClearData();
   }
 
@@ -408,7 +619,6 @@
 
   Thread* thread_;
   Zone* zone_;
-  Isolate* isolate_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ForwardMapBase);
@@ -416,8 +626,9 @@
 
 class FastForwardMap : public ForwardMapBase {
  public:
-  explicit FastForwardMap(Thread* thread)
+  explicit FastForwardMap(Thread* thread, IdentityMap* map)
       : ForwardMapBase(thread),
+        map_(map),
         raw_from_to_(thread->zone(), 20),
         raw_transferables_from_to_(thread->zone(), 0),
         raw_objects_to_rehash_(thread->zone(), 0),
@@ -429,19 +640,12 @@
   }
 
   ObjectPtr ForwardedObject(ObjectPtr object) {
-    const intptr_t id = GetObjectId(object);
-    if (id == 0) return Marker();
-    return raw_from_to_[id + 1];
+    return map_->ForwardedObject(object, FastFromTo(raw_from_to_));
   }
 
   void Insert(ObjectPtr from, ObjectPtr to, intptr_t size) {
-    ASSERT(ForwardedObject(from) == Marker());
-    ASSERT(raw_from_to_.length() == raw_from_to_.length());
-    const auto id = raw_from_to_.length();
-    SetObjectId(from, id);
-    raw_from_to_.Resize(id + 2);
-    raw_from_to_[id] = from;
-    raw_from_to_[id + 1] = to;
+    map_->Insert(from, to, FastFromTo(raw_from_to_),
+                 /*check_for_safepoint*/ false);
     allocated_bytes += size;
   }
 
@@ -465,6 +669,7 @@
   friend class FastObjectCopy;
   friend class ObjectGraphCopier;
 
+  IdentityMap* map_;
   GrowableArray<ObjectPtr> raw_from_to_;
   GrowableArray<TransferableTypedDataPtr> raw_transferables_from_to_;
   GrowableArray<ExternalTypedDataPtr> raw_external_typed_data_to_;
@@ -480,8 +685,9 @@
 
 class SlowForwardMap : public ForwardMapBase {
  public:
-  explicit SlowForwardMap(Thread* thread)
+  explicit SlowForwardMap(Thread* thread, IdentityMap* map)
       : ForwardMapBase(thread),
+        map_(map),
         from_to_transition_(thread->zone(), 2),
         from_to_(GrowableObjectArray::Handle(thread->zone(),
                                              GrowableObjectArray::New(2))),
@@ -495,17 +701,11 @@
   }
 
   ObjectPtr ForwardedObject(ObjectPtr object) {
-    const intptr_t id = GetObjectId(object);
-    if (id == 0) return Marker();
-    return from_to_.At(id + 1);
+    return map_->ForwardedObject(object, SlowFromTo(from_to_));
   }
-
   void Insert(const Object& from, const Object& to, intptr_t size) {
-    ASSERT(ForwardedObject(from.ptr()) == Marker());
-    const auto id = from_to_.Length();
-    SetObjectId(from.ptr(), id);
-    from_to_.Add(from);
-    from_to_.Add(to);
+    map_->Insert(from, to, SlowFromTo(from_to_),
+                 /* check_for_safepoint */ true);
     allocated_bytes += size;
   }
 
@@ -549,8 +749,10 @@
 
  private:
   friend class SlowObjectCopy;
+  friend class SlowObjectCopyBase;
   friend class ObjectGraphCopier;
 
+  IdentityMap* map_;
   GrowableArray<const PassiveObject*> from_to_transition_;
   GrowableObjectArray& from_to_;
   GrowableArray<const TransferableTypedData*> transferables_from_to_;
@@ -707,8 +909,8 @@
  public:
   using Types = PtrTypes;
 
-  explicit FastObjectCopyBase(Thread* thread)
-      : ObjectCopyBase(thread), fast_forward_map_(thread) {}
+  FastObjectCopyBase(Thread* thread, IdentityMap* map)
+      : ObjectCopyBase(thread), fast_forward_map_(thread, map) {}
 
  protected:
   DART_FORCE_INLINE
@@ -874,8 +1076,8 @@
  public:
   using Types = HandleTypes;
 
-  explicit SlowObjectCopyBase(Thread* thread)
-      : ObjectCopyBase(thread), slow_forward_map_(thread) {}
+  explicit SlowObjectCopyBase(Thread* thread, IdentityMap* map)
+      : ObjectCopyBase(thread), slow_forward_map_(thread, map) {}
 
  protected:
   DART_FORCE_INLINE
@@ -1008,9 +1210,9 @@
     if (size == 0) {
       size = from.ptr().untag()->HeapSize();
     }
-    to_ = AllocateObject(cid, size);
+    to_ = AllocateObject(cid, size, slow_forward_map_.allocated_bytes);
     UpdateLengthField(cid, from.ptr(), to_.ptr());
-    slow_forward_map_.Insert(from, to_, size);  // SAFEPOINT
+    slow_forward_map_.Insert(from, to_, size);
     ObjectPtr to = to_.ptr();
     if (cid == kArrayCid && !Heap::IsAllocatableInNewSpace(size)) {
       to.untag()->SetCardRememberedBitUnsynchronized();
@@ -1102,13 +1304,13 @@
  public:
   using Types = typename Base::Types;
 
-  explicit ObjectCopy(Thread* thread) : Base(thread) {}
+  ObjectCopy(Thread* thread, IdentityMap* map) : Base(thread, map) {}
 
   void CopyPredefinedInstance(typename Types::Object from,
                               typename Types::Object to,
                               intptr_t cid) {
     if (IsImplicitFieldClassId(cid)) {
-      CopyUserdefinedInstance(from, to);
+      CopyUserdefinedInstanceWithoutUnboxedFields(from, to);
       return;
     }
     switch (cid) {
@@ -1171,21 +1373,18 @@
     FATAL1("Unexpected object: %s\n", obj.ToCString());
   }
 
-#if defined(DART_PRECOMPILED_RUNTIME)
-  void CopyUserdefinedInstanceAOT(typename Types::Object from,
-                                  typename Types::Object to,
-                                  UnboxedFieldBitmap bitmap) {
+  void CopyUserdefinedInstance(typename Types::Object from,
+                               typename Types::Object to,
+                               UnboxedFieldBitmap bitmap) {
     const intptr_t instance_size = UntagObject(from)->HeapSize();
     Base::ForwardCompressedPointers(from, to, kWordSize, instance_size, bitmap);
   }
-#endif
 
-  void CopyUserdefinedInstance(typename Types::Object from,
-                               typename Types::Object to) {
+  void CopyUserdefinedInstanceWithoutUnboxedFields(typename Types::Object from,
+                                                   typename Types::Object to) {
     const intptr_t instance_size = UntagObject(from)->HeapSize();
     Base::ForwardCompressedPointers(from, to, kWordSize, instance_size);
   }
-
   void CopyClosure(typename Types::Closure from, typename Types::Closure to) {
     Base::StoreCompressedPointers(
         from, to, OFFSET_OF(UntaggedClosure, instantiator_type_arguments_),
@@ -1236,6 +1435,16 @@
         from, to, OFFSET_OF(UntaggedGrowableObjectArray, data_));
   }
 
+  void CopyRecord(typename Types::Record from, typename Types::Record to) {
+    const intptr_t num_fields = Record::NumFields(Types::GetRecordPtr(from));
+    UntagRecord(to)->num_fields_ = UntagRecord(from)->num_fields_;
+    Base::ForwardCompressedPointer(from, to,
+                                   OFFSET_OF(UntaggedRecord, field_names_));
+    Base::ForwardCompressedPointers(
+        from, to, Record::field_offset(0),
+        Record::field_offset(0) + Record::kBytesPerElement * num_fields);
+  }
+
   template <intptr_t one_for_set_two_for_map, typename T>
   void CopyLinkedHashBase(T from,
                           T to,
@@ -1510,7 +1719,7 @@
 
 class FastObjectCopy : public ObjectCopy<FastObjectCopyBase> {
  public:
-  explicit FastObjectCopy(Thread* thread) : ObjectCopy(thread) {}
+  FastObjectCopy(Thread* thread, IdentityMap* map) : ObjectCopy(thread, map) {}
   ~FastObjectCopy() {}
 
   ObjectPtr TryCopyGraphFast(ObjectPtr root) {
@@ -1664,14 +1873,9 @@
       CopyPredefinedInstance(from, to, cid);
       return;
     }
-#if defined(DART_PRECOMPILED_RUNTIME)
-    const auto bitmap =
-        class_table_->shared_class_table()->GetUnboxedFieldsMapAt(cid);
-    CopyUserdefinedInstanceAOT(Instance::RawCast(from), Instance::RawCast(to),
-                               bitmap);
-#else
-    CopyUserdefinedInstance(Instance::RawCast(from), Instance::RawCast(to));
-#endif
+    const auto bitmap = class_table_->GetUnboxedFieldsMapAt(cid);
+    CopyUserdefinedInstance(Instance::RawCast(from), Instance::RawCast(to),
+                            bitmap);
     if (cid == expando_cid_) {
       EnqueueExpandoToRehash(to);
     }
@@ -1683,8 +1887,8 @@
 
 class SlowObjectCopy : public ObjectCopy<SlowObjectCopyBase> {
  public:
-  explicit SlowObjectCopy(Thread* thread)
-      : ObjectCopy(thread),
+  SlowObjectCopy(Thread* thread, IdentityMap* map)
+      : ObjectCopy(thread, map),
         objects_to_rehash_(Array::Handle(thread->zone())),
         expandos_to_rehash_(Array::Handle(thread->zone())) {}
   ~SlowObjectCopy() {}
@@ -1799,13 +2003,8 @@
       CopyPredefinedInstance(from, to, cid);
       return;
     }
-#if defined(DART_PRECOMPILED_RUNTIME)
-    const auto bitmap =
-        class_table_->shared_class_table()->GetUnboxedFieldsMapAt(cid);
-    CopyUserdefinedInstanceAOT(from, to, bitmap);
-#else
-    CopyUserdefinedInstance(from, to);
-#endif
+    const auto bitmap = class_table_->GetUnboxedFieldsMapAt(cid);
+    CopyUserdefinedInstance(from, to, bitmap);
     if (cid == expando_cid_) {
       EnqueueExpandoToRehash(to);
     }
@@ -1821,15 +2020,9 @@
       : StackResource(thread),
         thread_(thread),
         zone_(thread->zone()),
-        fast_object_copy_(thread_),
-        slow_object_copy_(thread_) {
-    thread_->isolate()->set_forward_table_new(new WeakTable());
-    thread_->isolate()->set_forward_table_old(new WeakTable());
-  }
-  ~ObjectGraphCopier() {
-    thread_->isolate()->set_forward_table_new(nullptr);
-    thread_->isolate()->set_forward_table_old(nullptr);
-  }
+        map_(thread),
+        fast_object_copy_(thread_, &map_),
+        slow_object_copy_(thread_, &map_) {}
 
   // Result will be
   //   [
@@ -2080,6 +2273,7 @@
 
   Thread* thread_;
   Zone* zone_;
+  IdentityMap map_;
   FastObjectCopy fast_object_copy_;
   SlowObjectCopy slow_object_copy_;
   intptr_t copied_objects_ = 0;
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index d939b4a..7c5ee68 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -220,12 +220,6 @@
             field.set_field_id_unsafe(old_field.field_id());
           }
           reload_context->AddStaticFieldMapping(old_field, field);
-        } else {
-          if (old_field.needs_load_guard()) {
-            ASSERT(!old_field.is_unboxing_candidate());
-            field.set_needs_load_guard(true);
-            field.set_is_unboxing_candidate_unsafe(false);
-          }
         }
       }
     }
@@ -688,8 +682,8 @@
 
     // Consts can't lose fields.
     bool field_removed = false;
-    const Array& old_fields =
-        Array::Handle(OffsetToFieldMap(true /* original classes */));
+    const Array& old_fields = Array::Handle(
+        OffsetToFieldMap(IsolateGroup::Current()->heap_walk_class_table()));
     const Array& new_fields = Array::Handle(replacement.OffsetToFieldMap());
     if (new_fields.Length() < old_fields.Length()) {
       field_removed = true;
@@ -745,11 +739,37 @@
             id(), replacement.id());
 }
 
-bool Class::RequiresInstanceMorphing(const Class& replacement) const {
+void Class::MarkFieldBoxedDuringReload(ClassTable* class_table,
+                                       const Field& field) const {
+  if (!field.is_unboxed()) {
+    return;
+  }
+
+  field.set_is_unboxed_unsafe(false);
+
+  // Make sure to update the bitmap used for scanning.
+  auto unboxed_fields_map = class_table->GetUnboxedFieldsMapAt(id());
+  const auto start_index = field.HostOffset() >> kCompressedWordSizeLog2;
+  const auto end_index =
+      start_index + (Class::UnboxedFieldSizeInBytesByCid(field.guarded_cid()) >>
+                     kCompressedWordSizeLog2);
+  ASSERT(unboxed_fields_map.Get(start_index));
+  for (intptr_t i = start_index; i < end_index; i++) {
+    unboxed_fields_map.Clear(i);
+  }
+  class_table->SetUnboxedFieldsMapAt(id(), unboxed_fields_map);
+}
+
+bool Class::RequiresInstanceMorphing(ClassTable* class_table,
+                                     const Class& replacement) const {
   // Get the field maps for both classes. These field maps walk the class
   // hierarchy.
+  auto isolate_group = IsolateGroup::Current();
+
+  // heap_walk_class_table is the original class table before it was
+  // updated by reloading sources.
   const Array& fields =
-      Array::Handle(OffsetToFieldMap(true /* original classes */));
+      Array::Handle(OffsetToFieldMap(isolate_group->heap_walk_class_table()));
   const Array& replacement_fields =
       Array::Handle(replacement.OffsetToFieldMap());
 
@@ -779,6 +799,22 @@
     field_name = field.name();
     replacement_field_name = replacement_field.name();
     if (!field_name.Equals(replacement_field_name)) return true;
+    if (field.is_unboxed() && !replacement_field.is_unboxed()) {
+      return true;
+    }
+    if (field.is_unboxed() && (field.type() != replacement_field.type())) {
+      return true;
+    }
+    if (!field.is_unboxed() && replacement_field.is_unboxed()) {
+      // No actual morphing is required in this case but we need to mark
+      // the field unboxed.
+      replacement.MarkFieldBoxedDuringReload(class_table, replacement_field);
+    }
+    if (field.needs_load_guard()) {
+      ASSERT(!field.is_unboxed());
+      ASSERT(!replacement_field.is_unboxed());
+      replacement_field.set_needs_load_guard(true);
+    }
   }
   return false;
 }
@@ -788,21 +824,20 @@
   // Make sure the declaration types argument count matches for the two classes.
   // ex. class A<int,B> {} cannot be replace with class A<B> {}.
   auto group_context = context->group_reload_context();
-  auto shared_class_table =
-      group_context->isolate_group()->shared_class_table();
+  auto class_table = group_context->isolate_group()->class_table();
   if (NumTypeArguments() != replacement.NumTypeArguments()) {
     group_context->AddReasonForCancelling(
         new (context->zone())
             TypeParametersChanged(context->zone(), *this, replacement));
     return false;
   }
-  if (RequiresInstanceMorphing(replacement)) {
+  if (RequiresInstanceMorphing(class_table, replacement)) {
     ASSERT(id() == replacement.id());
     const classid_t cid = id();
     // We unconditionally create an instance morpher. As a side effect of
-    // building the morpher, we will mark all new fields as late.
+    // building the morpher, we will mark all new fields as guarded on load.
     auto instance_morpher = InstanceMorpher::CreateFromClassDescriptors(
-        context->zone(), shared_class_table, *this, replacement);
+        context->zone(), class_table, *this, replacement);
     group_context->EnsureHasInstanceMorpherFor(cid, instance_morpher);
   }
   return true;
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 41da4b4..de767c9 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -1240,6 +1240,31 @@
   }
 }
 
+void RecordType::PrintJSONImpl(JSONStream* stream, bool ref) const {
+  JSONObject jsobj(stream);
+  PrintSharedInstanceJSON(&jsobj, ref);
+  jsobj.AddProperty("kind", "_RecordType");
+
+  {
+    JSONArray arr(&jsobj, "fields");
+    const intptr_t num_fields = NumFields();
+    const intptr_t num_positional_fields = NumPositionalFields();
+    AbstractType& type = AbstractType::Handle();
+    String& name = String::Handle();
+    for (intptr_t i = 0; i < num_fields; ++i) {
+      JSONObject field(&arr);
+      type = FieldTypeAt(i);
+      field.AddProperty("type", type);
+      if (i >= num_positional_fields) {
+        name = FieldNameAt(i - num_positional_fields);
+        field.AddProperty("name", name.ToCString());
+      } else {
+        field.AddProperty("pos", i);
+      }
+    }
+  }
+}
+
 void TypeRef::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   PrintSharedInstanceJSON(&jsobj, ref);
@@ -1619,6 +1644,46 @@
   Instance::PrintJSONImpl(stream, ref);
 }
 
+void Record::PrintJSONImpl(JSONStream* stream, bool ref) const {
+  JSONObject jsobj(stream);
+  PrintSharedInstanceJSON(&jsobj, ref);
+  jsobj.AddProperty("kind", "_Record");
+  jsobj.AddProperty("numFields", num_fields());
+  jsobj.AddServiceId(*this);
+  if (ref) {
+    return;
+  }
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(num_fields(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < num_fields()) {
+    jsobj.AddProperty("count", count);
+  }
+  intptr_t limit = offset + count;
+  ASSERT(limit <= num_fields());
+  {
+    JSONArray jsarr(&jsobj, "fields");
+    Object& obj = Object::Handle();
+    String& name = String::Handle();
+    const intptr_t num_positional_fields = NumPositionalFields();
+    const Array& field_names = Array::Handle(this->field_names());
+    for (intptr_t index = offset; index < limit; ++index) {
+      JSONObject field(&jsarr);
+      obj = FieldAt(index);
+      field.AddProperty("value", obj);
+      if (index >= num_positional_fields) {
+        name ^= field_names.At(index - num_positional_fields);
+        field.AddProperty("name", name);
+      } else {
+        field.AddProperty("pos", index);
+      }
+    }
+  }
+}
+
 void StackTrace::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   PrintSharedInstanceJSON(&jsobj, ref);
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 396d2e4..26bf965 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -135,6 +135,7 @@
   ARW_AR(Array, symbol_table)                                                  \
   RW(Array, canonical_types)                                                   \
   RW(Array, canonical_function_types)                                          \
+  RW(Array, canonical_record_types)                                            \
   RW(Array, canonical_type_parameters)                                         \
   RW(Array, canonical_type_arguments)                                          \
   RW(Library, async_library)                                                   \
@@ -234,6 +235,7 @@
   RW(Code, allocate_growable_array_stub)                                       \
   RW(Code, allocate_object_stub)                                               \
   RW(Code, allocate_object_parametrized_stub)                                  \
+  RW(Code, allocate_record_stub)                                               \
   RW(Code, allocate_unhandled_exception_stub)                                  \
   RW(Code, clone_context_stub)                                                 \
   RW(Code, write_barrier_wrappers_stub)                                        \
@@ -325,6 +327,7 @@
   DO(allocate_growable_array_stub, AllocateGrowableArray)                      \
   DO(allocate_object_stub, AllocateObject)                                     \
   DO(allocate_object_parametrized_stub, AllocateObjectParameterized)           \
+  DO(allocate_record_stub, AllocateRecord)                                     \
   DO(allocate_unhandled_exception_stub, AllocateUnhandledException)            \
   DO(clone_context_stub, CloneContext)                                         \
   DO(call_closure_no_such_method_stub, CallClosureNoSuchMethod)                \
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 3cc7a2b..5ced93d 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2759,7 +2759,7 @@
       Object::Handle(DartEntry::InvokeFunction(function, Array::empty_array()));
   EXPECT_EQ(1, Smi::Cast(result).Value());
   // Switch to the writeable but non-executable view of the instructions.
-  instructions ^= OldPage::ToWritable(instructions.ptr());
+  instructions ^= Page::ToWritable(instructions.ptr());
   payload_start = instructions.PayloadStart();
   EXPECT_EQ(instructions.ptr(), Instructions::FromPayloadStart(payload_start));
   // Hook up Code and Instructions objects.
diff --git a/runtime/vm/pointer_tagging.h b/runtime/vm/pointer_tagging.h
index 90dd053..6838506 100644
--- a/runtime/vm/pointer_tagging.h
+++ b/runtime/vm/pointer_tagging.h
@@ -71,9 +71,10 @@
 static constexpr intptr_t kFalseOffsetFromNull =
     HostObjectAlignment::kFalseOffsetFromNull;
 
-// The largest value of kObjectAlignment across all configurations.
-static constexpr intptr_t kMaxObjectAlignment = 16;
-COMPILE_ASSERT(kMaxObjectAlignment >= kObjectAlignment);
+static constexpr intptr_t kObjectStartAlignment = 64;
+COMPILE_ASSERT(kObjectStartAlignment >= kObjectAlignment);
+COMPILE_ASSERT(kObjectStartAlignment >= 2 * kBoolValueMask);
+COMPILE_ASSERT(kObjectStartAlignment >= 2 * kBoolVsNullMask);
 
 // On all targets heap pointers are tagged by set least significant bit.
 //
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 39cf824..4c26e8d 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -69,11 +69,11 @@
     }
   }
   const intptr_t class_id = ClassIdTag::decode(tags);
-  if (!isolate_group->shared_class_table()->IsValidIndex(class_id)) {
+  if (!isolate_group->class_table()->IsValidIndex(class_id)) {
     FATAL1("Invalid class id encountered %" Pd "\n", class_id);
   }
   if (class_id == kNullCid &&
-      isolate_group->shared_class_table()->HasValidClassAt(class_id)) {
+      isolate_group->class_table()->HasValidClassAt(class_id)) {
     // Null class not yet initialized; skip.
     return;
   }
@@ -158,6 +158,12 @@
       instance_size = ObjectPool::InstanceSize(len);
       break;
     }
+    case kRecordCid: {
+      const RecordPtr raw_record = static_cast<const RecordPtr>(this);
+      intptr_t num_fields = raw_record->untag()->num_fields_;
+      instance_size = Record::InstanceSize(num_fields);
+      break;
+    }
 #define SIZE_FROM_CLASS(clazz) case kTypedData##clazz##Cid:
       CLASS_LIST_TYPED_DATA(SIZE_FROM_CLASS) {
         const TypedDataPtr raw_obj = static_cast<const TypedDataPtr>(this);
@@ -241,24 +247,15 @@
       // TODO(koda): Add Size(ClassTable*) interface to allow caching in loops.
       auto isolate_group = IsolateGroup::Current();
 #if defined(DEBUG)
-#if !defined(DART_PRECOMPILED_RUNTIME)
-      auto reload_context = isolate_group->reload_context();
-      const bool use_saved_class_table =
-          reload_context != nullptr ? reload_context->UseSavedSizeTableForGC()
-                                    : false;
-#else
-      const bool use_saved_class_table = false;
-#endif
-
-      auto class_table = isolate_group->shared_class_table();
-      ASSERT(use_saved_class_table || class_table->SizeAt(class_id) > 0);
+      auto class_table = isolate_group->heap_walk_class_table();
+      ASSERT(class_table->SizeAt(class_id) > 0);
       if (!class_table->IsValidIndex(class_id) ||
-          (!class_table->HasValidClassAt(class_id) && !use_saved_class_table)) {
+          !class_table->HasValidClassAt(class_id)) {
         FATAL3("Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?",
                class_id, this, static_cast<uint32_t>(tags));
       }
 #endif  // DEBUG
-      instance_size = isolate_group->GetClassSizeForHeapWalkAt(class_id);
+      instance_size = isolate_group->heap_walk_class_table()->SizeAt(class_id);
     }
   }
   ASSERT(instance_size != 0);
@@ -386,7 +383,8 @@
   }
 
   // N.B.: Not using the heap size!
-  uword next_field_offset = isolate_group->GetClassForHeapWalkAt(class_id)
+  uword next_field_offset = visitor->class_table()
+                                ->At(class_id)
                                 ->untag()
                                 ->host_next_field_offset_in_words_
                             << kCompressedWordSizeLog2;
@@ -397,9 +395,8 @@
   const auto first = reinterpret_cast<CompressedObjectPtr*>(from);
   const auto last = reinterpret_cast<CompressedObjectPtr*>(to);
 
-#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
   const auto unboxed_fields_bitmap =
-      visitor->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
+      visitor->class_table()->GetUnboxedFieldsMapAt(class_id);
 
   if (!unboxed_fields_bitmap.IsEmpty()) {
     intptr_t bit = sizeof(UntaggedObject) / kCompressedWordSize;
@@ -411,9 +408,6 @@
   } else {
     visitor->VisitCompressedPointers(heap_base(), first, last);
   }
-#else
-  visitor->VisitCompressedPointers(heap_base(), first, last);
-#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
 }
 
 bool UntaggedObject::FindObject(FindObjectVisitor* visitor) {
@@ -537,6 +531,7 @@
 COMPRESSED_VISITOR(WeakSerializationReference)
 COMPRESSED_VISITOR(Type)
 COMPRESSED_VISITOR(FunctionType)
+COMPRESSED_VISITOR(RecordType)
 COMPRESSED_VISITOR(TypeRef)
 COMPRESSED_VISITOR(TypeParameter)
 COMPRESSED_VISITOR(Function)
@@ -582,6 +577,7 @@
     TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *
         Smi::Value(raw_obj->untag()->length()))
 VARIABLE_COMPRESSED_VISITOR(ContextScope, raw_obj->untag()->num_variables_)
+VARIABLE_COMPRESSED_VISITOR(Record, raw_obj->untag()->num_fields_)
 NULL_VISITOR(Sentinel)
 REGULAR_VISITOR(InstructionsTable)
 NULL_VISITOR(Mint)
@@ -732,8 +728,7 @@
   uword tags = raw_obj->untag()->tags_;
   intptr_t instance_size = SizeTag::decode(tags);
   if (instance_size == 0) {
-    instance_size = visitor->isolate_group()->GetClassSizeForHeapWalkAt(
-        raw_obj->GetClassId());
+    instance_size = visitor->class_table()->SizeAt(raw_obj->GetClassId());
   }
 
   // Calculate the first and last raw object pointer fields.
@@ -765,12 +760,12 @@
 }
 
 void UntaggedObject::RememberCard(ObjectPtr const* slot) {
-  OldPage::Of(static_cast<ObjectPtr>(this))->RememberCard(slot);
+  Page::Of(static_cast<ObjectPtr>(this))->RememberCard(slot);
 }
 
 #if defined(DART_COMPRESSED_POINTERS)
 void UntaggedObject::RememberCard(CompressedObjectPtr const* slot) {
-  OldPage::Of(static_cast<ObjectPtr>(this))->RememberCard(slot);
+  Page::Of(static_cast<ObjectPtr>(this))->RememberCard(slot);
 }
 #endif
 
@@ -782,7 +777,7 @@
   ObjectPtr object = static_cast<ObjectPtr>(object_in);
   ASSERT(object->IsOldObject());
   ASSERT(object->untag()->IsCardRemembered());
-  OldPage::Of(object)->RememberCard(slot);
+  Page::Of(object)->RememberCard(slot);
 }
 END_LEAF_RUNTIME_ENTRY
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index ac1f257..adcd0c3 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -416,9 +416,8 @@
     const auto first = reinterpret_cast<CompressedObjectPtr*>(from);
     const auto last = reinterpret_cast<CompressedObjectPtr*>(to);
 
-#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
     const auto unboxed_fields_bitmap =
-        visitor->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
+        visitor->class_table()->GetUnboxedFieldsMapAt(class_id);
 
     if (!unboxed_fields_bitmap.IsEmpty()) {
       intptr_t bit = sizeof(UntaggedObject) / kCompressedWordSize;
@@ -430,10 +429,6 @@
     } else {
       visitor->VisitCompressedPointers(heap_base(), first, last);
     }
-#else
-    // Call visitor function virtually
-    visitor->VisitCompressedPointers(heap_base(), first, last);
-#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
 
     return instance_size;
   }
@@ -454,9 +449,8 @@
     const auto first = reinterpret_cast<CompressedObjectPtr*>(from);
     const auto last = reinterpret_cast<CompressedObjectPtr*>(to);
 
-#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
     const auto unboxed_fields_bitmap =
-        visitor->shared_class_table()->GetUnboxedFieldsMapAt(class_id);
+        visitor->class_table()->GetUnboxedFieldsMapAt(class_id);
 
     if (!unboxed_fields_bitmap.IsEmpty()) {
       intptr_t bit = sizeof(UntaggedObject) / kCompressedWordSize;
@@ -468,10 +462,6 @@
     } else {
       visitor->V::VisitCompressedPointers(heap_base(), first, last);
     }
-#else
-    // Call visitor function non-virtually
-    visitor->V::VisitCompressedPointers(heap_base(), first, last);
-#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
 
     return instance_size;
   }
@@ -2617,26 +2607,29 @@
 };
 
 class UntaggedAbstractType : public UntaggedInstance {
+ protected:
+  // Accessed from generated code.
+  std::atomic<uword> type_test_stub_entry_point_;
+  // Accessed from generated code.
+  uint32_t flags_;
+  COMPRESSED_POINTER_FIELD(CodePtr, type_test_stub)
+  VISIT_FROM(type_test_stub)
+
  public:
   enum TypeState {
     kAllocated,                // Initial state.
     kBeingFinalized,           // In the process of being finalized.
     kFinalizedInstantiated,    // Instantiated type ready for use.
     kFinalizedUninstantiated,  // Uninstantiated type ready for use.
-    // Adjust kTypeStateBitSize if more are added.
   };
 
- protected:
-  static constexpr intptr_t kTypeStateBitSize = 2;
-  COMPILE_ASSERT(sizeof(std::atomic<word>) == sizeof(word));
+  using NullabilityBits = BitField<decltype(flags_), uint8_t, 0, 2>;
+  static constexpr intptr_t kNullabilityMask = NullabilityBits::mask();
 
-  // Accessed from generated code.
-  std::atomic<uword> type_test_stub_entry_point_;
-#if defined(DART_COMPRESSED_POINTERS)
-  uint32_t padding_;  // Makes Windows and Posix agree on layout.
-#endif
-  COMPRESSED_POINTER_FIELD(CodePtr, type_test_stub)
-  VISIT_FROM(type_test_stub)
+  static constexpr intptr_t kTypeStateShift = NullabilityBits::kNextBit;
+  static constexpr intptr_t kTypeStateBits = 2;
+  using TypeStateBits =
+      BitField<decltype(flags_), uint8_t, kTypeStateShift, kTypeStateBits>;
 
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(AbstractType);
@@ -2646,18 +2639,29 @@
 };
 
 class UntaggedType : public UntaggedAbstractType {
+ public:
+  static constexpr intptr_t kTypeClassIdShift = TypeStateBits::kNextBit;
+  using TypeClassIdBits = BitField<decltype(flags_),
+                                   ClassIdTagType,
+                                   kTypeClassIdShift,
+                                   sizeof(ClassIdTagType) * kBitsPerByte>;
+
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Type);
 
   COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, arguments)
   COMPRESSED_POINTER_FIELD(SmiPtr, hash)
   VISIT_TO(hash)
-  ClassIdTagType type_class_id_;
-  uint8_t type_state_;
-  uint8_t nullability_;
 
   CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
+  ClassIdTagType type_class_id() const {
+    return TypeClassIdBits::decode(flags_);
+  }
+  void set_type_class_id(ClassIdTagType value) {
+    flags_ = TypeClassIdBits::update(value, flags_);
+  }
+
   friend class compiler::target::UntaggedType;
   friend class CidRewriteVisitor;
   friend class UntaggedTypeArguments;
@@ -2675,8 +2679,6 @@
   VISIT_TO(hash)
   AtomicBitFieldContainer<uint32_t> packed_parameter_counts_;
   AtomicBitFieldContainer<uint16_t> packed_type_parameter_counts_;
-  uint8_t type_state_;
-  uint8_t nullability_;
 
   // The bit fields are public for use in kernel_to_il.cc.
  public:
@@ -2718,6 +2720,18 @@
   friend class Function;
 };
 
+class UntaggedRecordType : public UntaggedAbstractType {
+ private:
+  RAW_HEAP_OBJECT_IMPLEMENTATION(RecordType);
+
+  COMPRESSED_POINTER_FIELD(ArrayPtr, field_types)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, field_names);
+  COMPRESSED_POINTER_FIELD(SmiPtr, hash)
+  VISIT_TO(hash)
+
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+};
+
 class UntaggedTypeRef : public UntaggedAbstractType {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeRef);
@@ -2738,14 +2752,6 @@
   ClassIdTagType parameterized_class_id_;  // Or kFunctionCid for function tp.
   uint8_t base_;   // Number of enclosing function type parameters.
   uint8_t index_;  // Keep size in sync with BuildTypeParameterTypeTestStub.
-  uint8_t flags_;
-  uint8_t nullability_;
-
- public:
-  using BeingFinalizedBit = BitField<decltype(flags_), bool, 0, 1>;
-  using FinalizedBit =
-      BitField<decltype(flags_), bool, BeingFinalizedBit::kNextBit, 1>;
-  static constexpr intptr_t kFlagsBitSize = FinalizedBit::kNextBit;
 
  private:
   CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
@@ -3102,7 +3108,7 @@
   friend class ReversePc;
   template <typename Table, bool kAllCanonicalObjectsAreIncludedIntoSet>
   friend class CanonicalSetDeserializationCluster;
-  friend class OldPage;
+  friend class Page;
   friend class FastObjectCopy;  // For initializing fields.
   friend void UpdateLengthField(intptr_t, ObjectPtr, ObjectPtr);  // length_
 };
@@ -3209,6 +3215,19 @@
 };
 COMPILE_ASSERT(sizeof(UntaggedFloat64x2) == 24);
 
+class UntaggedRecord : public UntaggedInstance {
+  RAW_HEAP_OBJECT_IMPLEMENTATION(Record);
+
+  int32_t num_fields_;
+  COMPRESSED_POINTER_FIELD(ArrayPtr, field_names)
+  VISIT_FROM(field_names)
+  // Variable length data follows here.
+  COMPRESSED_VARIABLE_POINTER_FIELDS(ObjectPtr, field, data)
+
+  friend void UpdateLengthField(intptr_t, ObjectPtr,
+                                ObjectPtr);  // num_fields_
+};
+
 // Define an aliases for intptr_t.
 #if defined(ARCH_IS_32_BIT)
 #define kIntPtrCid kTypedDataInt32ArrayCid
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index b35eb19..ef68911 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -135,7 +135,6 @@
   F(TypeArguments, nullability_)                                               \
   F(AbstractType, type_test_stub_)                                             \
   F(Type, type_test_stub_)                                                     \
-  F(Type, type_class_id_)                                                      \
   F(Type, arguments_)                                                          \
   F(Type, hash_)                                                               \
   F(FunctionType, type_test_stub_)                                             \
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index caeae9b..b9b3909 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -4,6 +4,7 @@
 
 #include "vm/runtime_entry.h"
 
+#include "platform/memory_sanitizer.h"
 #include "platform/thread_sanitizer.h"
 #include "vm/code_descriptors.h"
 #include "vm/code_patcher.h"
@@ -385,6 +386,16 @@
   arguments.SetReturn(Object::Handle(zone, Double::New(val)));
 }
 
+DEFINE_RUNTIME_ENTRY_NO_LAZY_DEOPT(BoxFloat32x4, 0) {
+  const auto val = thread->unboxed_simd128_runtime_arg();
+  arguments.SetReturn(Object::Handle(zone, Float32x4::New(val)));
+}
+
+DEFINE_RUNTIME_ENTRY_NO_LAZY_DEOPT(BoxFloat64x2, 0) {
+  const auto val = thread->unboxed_simd128_runtime_arg();
+  arguments.SetReturn(Object::Handle(zone, Float64x2::New(val)));
+}
+
 DEFINE_RUNTIME_ENTRY_NO_LAZY_DEOPT(AllocateMint, 0) {
   if (FLAG_shared_slow_path_triggers_gc) {
     isolate->group()->heap()->CollectAllGarbage(GCReason::kDebugging);
@@ -709,6 +720,19 @@
   arguments.SetReturn(cloned_ctx);
 }
 
+// Allocate a new record instance.
+// Arg0: number of fields.
+// Arg1: field names.
+// Return value: newly allocated record.
+DEFINE_RUNTIME_ENTRY(AllocateRecord, 2) {
+  const Smi& num_fields = Smi::CheckedHandle(zone, arguments.ArgAt(0));
+  const auto& field_names = Array::CheckedHandle(zone, arguments.ArgAt(1));
+  const Record& record =
+      Record::Handle(zone, Record::New(num_fields.Value(), field_names,
+                                       SpaceForRuntimeAllocation()));
+  arguments.SetReturn(record);
+}
+
 // Allocate a SuspendState object.
 // Arg0: frame size.
 // Arg1: existing SuspendState object or function data.
@@ -835,6 +859,16 @@
   ASSERT(destination_type.IsCanonical());
   ASSERT(instantiator_type_arguments.IsCanonical());
   ASSERT(function_type_arguments.IsCanonical());
+  if (instance.IsRecord()) {
+    // Do not add record instances to cache as they don't have a valid
+    // key (type of a record depends on types of all its fields).
+    // TODO(dartbug.com/49719): consider testing each record field using
+    // SubtypeTestCache.
+    if (FLAG_trace_type_checks) {
+      THR_Print("Not updating subtype test cache for the record instance.\n");
+    }
+    return;
+  }
   Class& instance_class = Class::Handle(zone);
   if (instance.IsSmi()) {
     instance_class = Smi::Class();
@@ -3868,6 +3902,15 @@
     false /* is_float */,
     reinterpret_cast<RuntimeFunction>(&DLRT_AllocateHandle));
 
+#if defined(USING_MEMORY_SANITIZER)
+#define MSAN_UNPOISON_RANGE reinterpret_cast<RuntimeFunction>(&__msan_unpoison)
+#define MSAN_UNPOISON_PARAM                                                    \
+  reinterpret_cast<RuntimeFunction>(&__msan_unpoison_param)
+#else
+#define MSAN_UNPOISON_RANGE nullptr
+#define MSAN_UNPOISON_PARAM nullptr
+#endif
+
 #if defined(USING_THREAD_SANITIZER)
 #define TSAN_ACQUIRE reinterpret_cast<RuntimeFunction>(&__tsan_acquire)
 #define TSAN_RELEASE reinterpret_cast<RuntimeFunction>(&__tsan_release)
@@ -3876,6 +3919,19 @@
 #define TSAN_RELEASE nullptr
 #endif
 
+// These runtime entries are defined even when not using MSAN / TSAN to keep
+// offsets on Thread consistent.
+
+DEFINE_RAW_LEAF_RUNTIME_ENTRY(MsanUnpoison,
+                              /*argument_count=*/2,
+                              /*is_float=*/false,
+                              MSAN_UNPOISON_RANGE);
+
+DEFINE_RAW_LEAF_RUNTIME_ENTRY(MsanUnpoisonParam,
+                              /*argument_count=*/1,
+                              /*is_float=*/false,
+                              MSAN_UNPOISON_PARAM);
+
 DEFINE_RAW_LEAF_RUNTIME_ENTRY(TsanLoadAcquire,
                               /*argument_count=*/1,
                               /*is_float=*/false,
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index 93b4a06..5f94bf8 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -18,8 +18,11 @@
   V(AllocateClosure)                                                           \
   V(AllocateContext)                                                           \
   V(AllocateObject)                                                            \
+  V(AllocateRecord)                                                            \
   V(AllocateSuspendState)                                                      \
   V(BoxDouble)                                                                 \
+  V(BoxFloat32x4)                                                              \
+  V(BoxFloat64x2)                                                              \
   V(BreakpointRuntimeHandler)                                                  \
   V(SingleStepHandler)                                                         \
   V(CloneContext)                                                              \
@@ -104,8 +107,10 @@
   V(ApiLocalScope*, EnterHandleScope, Thread*)                                 \
   V(void, ExitHandleScope, Thread*)                                            \
   V(LocalHandle*, AllocateHandle, ApiLocalScope*)                              \
-  V(void, TsanLoadAcquire, uword /* address */)                                \
-  V(void, TsanStoreRelease, uword /* address */)
+  V(void, MsanUnpoison, void*, size_t)                                         \
+  V(void, MsanUnpoisonParam, size_t)                                           \
+  V(void, TsanLoadAcquire, void*)                                              \
+  V(void, TsanStoreRelease, void*)
 
 }  // namespace dart
 
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 8a6b868..27a350e 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2869,6 +2869,11 @@
     output.Add(instance);
     return;
   }
+  if (type.IsRecordType()) {
+    // _Record class is not useful for the CFE. We use null instead.
+    output.Add(instance);
+    return;
+  }
   if (type.IsDynamicType()) {
     // Dynamic is weird in that it seems to have a class with no name and a
     // library called something like '7189777121420'. We use null instead.
@@ -3397,7 +3402,7 @@
                         bool include_implementors) {
   Thread* thread = Thread::Current();
   HANDLESCOPE(thread);
-  SharedClassTable* table = thread->isolate()->group()->shared_class_table();
+  ClassTable* table = thread->isolate()->group()->class_table();
   GrowableArray<const Class*> worklist;
   table->SetCollectInstancesFor(root.id(), true);
   worklist.Add(&root);
@@ -3437,7 +3442,7 @@
 }
 
 static void UnmarkClasses() {
-  SharedClassTable* table = IsolateGroup::Current()->shared_class_table();
+  ClassTable* table = IsolateGroup::Current()->class_table();
   for (intptr_t i = 1; i < table->NumCids(); i++) {
     table->SetCollectInstancesFor(i, false);
   }
@@ -3447,7 +3452,7 @@
  public:
   GetInstancesVisitor(ZoneGrowableHandlePtrArray<Object>* storage,
                       intptr_t limit)
-      : table_(IsolateGroup::Current()->shared_class_table()),
+      : table_(IsolateGroup::Current()->class_table()),
         storage_(storage),
         limit_(limit),
         count_(0) {}
@@ -3469,7 +3474,7 @@
   intptr_t count() const { return count_; }
 
  private:
-  SharedClassTable* const table_;
+  ClassTable* const table_;
   ZoneGrowableHandlePtrArray<Object>* storage_;
   const intptr_t limit_;
   intptr_t count_;
@@ -4587,10 +4592,8 @@
       // [anon:dart-*] - as labelled (Android)
       if ((strcmp(property, "Rss:") == 0) && (size != 0) &&
           (strcmp(path, "(deleted)") != 0) && (strcmp(path, "[heap]") != 0) &&
-          (strcmp(path, "") != 0) &&
-          (strcmp(path, "[anon:dart-newspace]") != 0) &&
-          (strcmp(path, "[anon:dart-oldspace]") != 0) &&
-          (strcmp(path, "[anon:dart-codespace]") != 0) &&
+          (strcmp(path, "") != 0) && (strcmp(path, "[anon:dart-heap]") != 0) &&
+          (strcmp(path, "[anon:dart-code]") != 0) &&
           (strcmp(path, "[anon:dart-profiler]") != 0) &&
           (strcmp(path, "[anon:dart-timeline]") != 0) &&
           (strcmp(path, "[anon:dart-zone]") != 0)) {
@@ -4675,9 +4678,9 @@
 
       {
         JSONObject semi(&vm_children);
-        semi.AddProperty("name", "SemiSpace Cache");
+        semi.AddProperty("name", "Page Cache");
         semi.AddProperty("description", "Cached heap regions");
-        intptr_t size = SemiSpace::CachedSize();
+        intptr_t size = Page::CachedSize();
         vm_size += size;
         semi.AddProperty64("size", size);
         JSONArray(&semi, "children");
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 63d61a8..351c52f 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -83,7 +83,7 @@
     if (!IncludesCode(kind())) {
       return NULL;
     }
-    uword offset = Utils::RoundUp(length(), kMaxObjectAlignment);
+    uword offset = Utils::RoundUp(length(), kObjectStartAlignment);
     return Addr() + offset;
   }
 
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 31747a0..54b00cb 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -523,6 +523,16 @@
   ExpectEncodeFail(scope.zone(), &root);
 }
 
+TEST_CASE(FailSerializeLargeUnmodifiableExternalTypedData) {
+  Dart_CObject root;
+  root.type = Dart_CObject_kUnmodifiableExternalTypedData;
+  root.value.as_external_typed_data.type = Dart_TypedData_kUint8;
+  root.value.as_external_typed_data.length =
+      ExternalTypedData::MaxElements(kExternalTypedDataUint8ArrayCid) + 1;
+  ApiNativeScope scope;
+  ExpectEncodeFail(scope.zone(), &root);
+}
+
 ISOLATE_UNIT_TEST_CASE(SerializeEmptyArray) {
   // Write snapshot with object content.
   const int kArrayLength = 0;
@@ -613,6 +623,27 @@
     }                                                                          \
   }
 
+#define TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(darttype, ctype)                \
+  {                                                                            \
+    StackZone zone(thread);                                                    \
+    ctype data[] = {0, 11, 22, 33, 44, 55, 66, 77};                            \
+    intptr_t length = ARRAY_SIZE(data);                                        \
+    ExternalTypedData& array = ExternalTypedData::Handle(                      \
+        ExternalTypedData::New(kExternalTypedData##darttype##ArrayCid,         \
+                               reinterpret_cast<uint8_t*>(data), length));     \
+    TypedDataView& view = TypedDataView::Handle(TypedDataView::New(            \
+        kUnmodifiableTypedData##darttype##ArrayViewCid, array, 0, length));    \
+    intptr_t scale = array.ElementSizeInBytes();                               \
+    std::unique_ptr<Message> message = WriteMessage(                           \
+        /* same_group */ false, view, ILLEGAL_PORT, Message::kNormalPriority); \
+    TypedDataView& serialized_view = TypedDataView::Handle();                  \
+    serialized_view ^= ReadMessage(thread, message.get());                     \
+    for (int i = 0; i < length; i++) {                                         \
+      EXPECT_EQ(static_cast<ctype>(data[i]),                                   \
+                serialized_view.Get##darttype(i* scale));                      \
+    }                                                                          \
+  }
+
 ISOLATE_UNIT_TEST_CASE(SerializeTypedArray) {
   TEST_TYPED_ARRAY(Int8, int8_t);
   TEST_TYPED_ARRAY(Uint8, uint8_t);
@@ -639,6 +670,19 @@
   TEST_EXTERNAL_TYPED_ARRAY(Float64, double);
 }
 
+ISOLATE_UNIT_TEST_CASE(SerializeUnmodifiableExternalTypedArray) {
+  TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(Int8, int8_t);
+  TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(Uint8, uint8_t);
+  TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(Int16, int16_t);
+  TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(Uint16, uint16_t);
+  TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(Int32, int32_t);
+  TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(Uint32, uint32_t);
+  TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(Int64, int64_t);
+  TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(Uint64, uint64_t);
+  TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(Float32, float);
+  TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(Float64, double);
+}
+
 ISOLATE_UNIT_TEST_CASE(SerializeEmptyByteArray) {
   // Write snapshot with object content.
   const int kTypedDataLength = 0;
@@ -1864,6 +1908,11 @@
   Dart_ShutdownIsolate();
 }
 
+static void MallocFinalizer(void* isolate_callback_data, void* peer) {
+  free(peer);
+}
+static void NoopFinalizer(void* isolate_callback_data, void* peer) {}
+
 VM_UNIT_TEST_CASE(PostCObject) {
   // Create a native port for posting from C to Dart
   TestIsolateScope __test_isolate__;
@@ -1884,7 +1933,7 @@
       "      }\n"
       "    }\n"
       "    messageCount++;\n"
-      "    if (messageCount == 10) throw new Exception(exception);\n"
+      "    if (messageCount == 13) throw new Exception(exception);\n"
       "  };\n"
       "  return sendPort;\n"
       "}\n";
@@ -1950,11 +1999,41 @@
   }
   EXPECT(Dart_PostCObject(port_id, array));
 
+  object.type = Dart_CObject_kTypedData;
+  object.value.as_typed_data.type = Dart_TypedData_kUint8;
+  uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+  object.value.as_typed_data.length = ARRAY_SIZE(data);
+  object.value.as_typed_data.values = data;
+  EXPECT(Dart_PostCObject(port_id, &object));
+
+  object.type = Dart_CObject_kExternalTypedData;
+  object.value.as_typed_data.type = Dart_TypedData_kUint8;
+  uint8_t* external_data = reinterpret_cast<uint8_t*>(malloc(sizeof(data)));
+  memmove(external_data, data, sizeof(data));
+  object.value.as_external_typed_data.length = ARRAY_SIZE(data);
+  object.value.as_external_typed_data.data = external_data;
+  object.value.as_external_typed_data.peer = external_data;
+  object.value.as_external_typed_data.callback = MallocFinalizer;
+  EXPECT(Dart_PostCObject(port_id, &object));
+
+  object.type = Dart_CObject_kUnmodifiableExternalTypedData;
+  object.value.as_typed_data.type = Dart_TypedData_kUint8;
+  static const uint8_t unmodifiable_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+  object.value.as_external_typed_data.length = ARRAY_SIZE(unmodifiable_data);
+  object.value.as_external_typed_data.data =
+      const_cast<uint8_t*>(unmodifiable_data);
+  object.value.as_external_typed_data.peer = nullptr;
+  object.value.as_external_typed_data.callback = NoopFinalizer;
+  EXPECT(Dart_PostCObject(port_id, &object));
+
   result = Dart_RunLoop();
   EXPECT(Dart_IsError(result));
   EXPECT(Dart_ErrorHasException(result));
-  EXPECT_SUBSTRING("Exception: nulltruefalse123456æøå3.14[]100123456789\n",
-                   Dart_GetError(result));
+  EXPECT_SUBSTRING(
+      "Exception: "
+      "nulltruefalse123456æøå3.14[]"
+      "100123456789901234567890123456789012345678\n",
+      Dart_GetError(result));
 
   Dart_ExitScope();
 }
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index b78960a..6101ae4 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -192,8 +192,28 @@
   return false;
 }
 
-intptr_t SourceReport::GetScriptIndex(const Script& script,
-                                      bool bypass_filters) {
+bool SourceReport::ShouldFiltersIncludeUrl(const String& url) {
+  String& filter = String::Handle(zone());
+  const intptr_t num_filters = library_filters_.Length();
+  for (intptr_t i = 0; i < num_filters; ++i) {
+    filter ^= library_filters_.At(i);
+    if (url.StartsWith(filter)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool SourceReport::ShouldFiltersIncludeScript(const Script& script) {
+  if (library_filters_.IsNull()) return true;
+  String& url = String::Handle(zone(), script.url());
+  if (ShouldFiltersIncludeUrl(url)) return true;
+  const Library& lib = Library::Handle(zone(), script.FindLibrary());
+  url ^= lib.url();
+  return ShouldFiltersIncludeUrl(url);
+}
+
+intptr_t SourceReport::GetScriptIndex(const Script& script) {
   ScriptTableEntry wrapper;
   const String& url = String::Handle(zone(), script.url());
   wrapper.key = &url;
@@ -202,14 +222,15 @@
   if (pair != NULL) {
     return pair->index;
   }
-  if (!library_filters_.IsNull() && !bypass_filters) {
-    return -1;
-  }
   ScriptTableEntry* tmp = new ScriptTableEntry();
   tmp->key = &url;
-  tmp->index = next_script_index_++;
   tmp->script = wrapper.script;
-  script_table_entries_.Add(tmp);
+  if (ShouldFiltersIncludeScript(script)) {
+    tmp->index = next_script_index_++;
+    script_table_entries_.Add(tmp);
+  } else {
+    tmp->index = -1;
+  }
   script_table_.Insert(tmp);
   ASSERT(script_table_entries_.length() == next_script_index_);
 #if defined(DEBUG)
@@ -660,19 +681,6 @@
   });
 }
 
-bool SourceReport::LibraryMatchesFilters(const Library& lib) {
-  const String& url = String::Handle(zone(), lib.url());
-  String& filter = String::Handle(zone());
-  const intptr_t num_filters = library_filters_.Length();
-  for (intptr_t i = 0; i < num_filters; ++i) {
-    filter ^= library_filters_.At(i);
-    if (url.StartsWith(filter)) {
-      return true;
-    }
-  }
-  return false;
-}
-
 void SourceReport::PrintJSON(JSONStream* js,
                              const Script& script,
                              TokenPosition start_pos,
@@ -687,24 +695,8 @@
     const GrowableObjectArray& libs = GrowableObjectArray::Handle(
         zone(), thread()->isolate_group()->object_store()->libraries());
 
-    Library& lib = Library::Handle(zone());
-    if (!library_filters_.IsNull()) {
-      // If we have library filters, pre-fill GetScriptIndex with all the
-      // scripts from the libraries that pass the filters. Later calls to
-      // GetScriptIndex will ignore any scripts that are missing.
-      for (intptr_t i = 0; i < libs.Length(); i++) {
-        lib ^= libs.At(i);
-        if (LibraryMatchesFilters(lib)) {
-          Script& script = Script::Handle(zone());
-          const Array& scripts = Array::Handle(zone(), lib.LoadedScripts());
-          for (intptr_t j = 0; j < scripts.Length(); j++) {
-            script ^= scripts.At(j);
-            GetScriptIndex(script, true /* bypass_filters */);
-          }
-        }
-      }
-    }
     // We only visit the libraries which actually load the specified script.
+    Library& lib = Library::Handle(zone());
     for (intptr_t i = 0; i < libs.Length(); i++) {
       lib ^= libs.At(i);
       if (script.IsNull() || ScriptIsLoadedByLibrary(script, lib)) {
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index 4b75b45..0904aee 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -76,11 +76,12 @@
   bool ShouldSkipFunction(const Function& func);
   bool ShouldSkipField(const Field& field);
   bool ShouldCoverageSkipCallSite(const ICData* ic_data);
-  intptr_t GetScriptIndex(const Script& script, bool bypass_filters = false);
+  intptr_t GetScriptIndex(const Script& script);
   bool ScriptIsLoadedByLibrary(const Script& script, const Library& lib);
   intptr_t GetTokenPosOrLine(const Script& script,
                              const TokenPosition& token_pos);
-  bool LibraryMatchesFilters(const Library& lib);
+  bool ShouldFiltersIncludeScript(const Script& script);
+  bool ShouldFiltersIncludeUrl(const String& url);
 
   void PrintCallSitesData(JSONObject* jsobj,
                           const Function& func,
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index be40522..916fd1f 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -192,6 +192,8 @@
       return object_store->allocate_int32x4_stub();
     case kClosureCid:
       return object_store->allocate_closure_stub();
+    case kRecordCid:
+      return object_store->allocate_record_stub();
   }
   Code& stub = Code::Handle(zone, cls.allocation_stub());
   if (stub.IsNull()) {
diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h
index 6b0223d..bd9b83e 100644
--- a/runtime/vm/stub_code_list.h
+++ b/runtime/vm/stub_code_list.h
@@ -56,8 +56,11 @@
   V(AllocateObject)                                                            \
   V(AllocateObjectParameterized)                                               \
   V(AllocateObjectSlow)                                                        \
+  V(AllocateRecord)                                                            \
   V(AllocateUnhandledException)                                                \
   V(BoxDouble)                                                                 \
+  V(BoxFloat32x4)                                                              \
+  V(BoxFloat64x2)                                                              \
   V(CloneContext)                                                              \
   V(CallToRuntime)                                                             \
   V(LazyCompile)                                                               \
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 271cc64..1c6df55 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -341,7 +341,7 @@
   V(_GrowableListLiteralFactory, "_GrowableList._literal")                     \
   V(_GrowableListWithData, "_GrowableList._withData")                          \
   V(_ImmutableLinkedHashMap, "_InternalImmutableLinkedHashMap")                \
-  V(_ImmutableLinkedHashSet, "_CompactImmutableLinkedHashSet")                 \
+  V(_ImmutableLinkedHashSet, "_InternalImmutableLinkedHashSet")                \
   V(_ImmutableList, "_ImmutableList")                                          \
   V(_Int16ArrayFactory, "Int16List.")                                          \
   V(_Int16ArrayView, "_Int16ArrayView")                                        \
@@ -365,7 +365,7 @@
   V(_LibraryMirror, "_LibraryMirror")                                          \
   V(_LibraryPrefix, "_LibraryPrefix")                                          \
   V(_LinkedHashMap, "_InternalLinkedHashMap")                                  \
-  V(_LinkedHashSet, "_CompactLinkedHashSet")                                   \
+  V(_LinkedHashSet, "_InternalLinkedHashSet")                                  \
   V(_List, "_List")                                                            \
   V(_ListFactory, "_List.")                                                    \
   V(_ListFilledFactory, "_List.filled")                                        \
@@ -376,6 +376,8 @@
   V(_ParameterMirror, "_ParameterMirror")                                      \
   V(_Random, "_Random")                                                        \
   V(_RawReceivePortImpl, "_RawReceivePortImpl")                                \
+  V(_Record, "_Record")                                                        \
+  V(_RecordType, "_RecordType")                                                \
   V(_RegExp, "_RegExp")                                                        \
   V(_SendPortImpl, "_SendPortImpl")                                            \
   V(_Smi, "_Smi")                                                              \
diff --git a/runtime/vm/tagged_pointer.h b/runtime/vm/tagged_pointer.h
index 8a74276..cfbfda7 100644
--- a/runtime/vm/tagged_pointer.h
+++ b/runtime/vm/tagged_pointer.h
@@ -388,6 +388,7 @@
 DEFINE_TAGGED_POINTER(AbstractType, Instance)
 DEFINE_TAGGED_POINTER(Type, AbstractType)
 DEFINE_TAGGED_POINTER(FunctionType, AbstractType)
+DEFINE_TAGGED_POINTER(RecordType, AbstractType)
 DEFINE_TAGGED_POINTER(TypeRef, AbstractType)
 DEFINE_TAGGED_POINTER(TypeParameter, AbstractType)
 DEFINE_TAGGED_POINTER(Closure, Instance)
@@ -399,6 +400,7 @@
 DEFINE_TAGGED_POINTER(String, Instance)
 DEFINE_TAGGED_POINTER(OneByteString, String)
 DEFINE_TAGGED_POINTER(TwoByteString, String)
+DEFINE_TAGGED_POINTER(Record, Instance)
 DEFINE_TAGGED_POINTER(PointerBase, Instance)
 DEFINE_TAGGED_POINTER(TypedDataBase, PointerBase)
 DEFINE_TAGGED_POINTER(TypedData, TypedDataBase)
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 1bc5236..5b81cc2 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -77,8 +77,6 @@
       store_buffer_block_(nullptr),
       marking_stack_block_(nullptr),
       vm_tag_(0),
-      unboxed_int64_runtime_arg_(0),
-      unboxed_double_runtime_arg_(0.0),
       active_exception_(Object::null()),
       active_stacktrace_(Object::null()),
       global_object_pool_(ObjectPool::null()),
@@ -149,6 +147,8 @@
 #else
   next_task_id_ = Random::GlobalNextUInt64();
 #endif
+
+  memset(&unboxed_runtime_arg_, 0, sizeof(simd128_value_t));
 }
 
 static const double double_nan_constant = NAN;
@@ -648,10 +648,12 @@
     StackFrameIterator frames_iterator(top_exit_frame_info(), validation_policy,
                                        this, cross_thread_policy);
     StackFrame* frame = frames_iterator.NextFrame();
+    visitor->set_gc_root_type("frame");
     while (frame != nullptr) {
       frame->VisitObjectPointers(visitor);
       frame = frames_iterator.NextFrame();
     }
+    visitor->clear_gc_root_type();
   } else {
     // We are not on the mutator thread.
     RELEASE_ASSERT(top_exit_frame_info() == 0);
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 405d405..6a07342 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -776,22 +776,25 @@
   static intptr_t vm_tag_offset() { return OFFSET_OF(Thread, vm_tag_); }
 
   int64_t unboxed_int64_runtime_arg() const {
-    return unboxed_int64_runtime_arg_;
+    return unboxed_runtime_arg_.int64_storage[0];
   }
   void set_unboxed_int64_runtime_arg(int64_t value) {
-    unboxed_int64_runtime_arg_ = value;
-  }
-  static intptr_t unboxed_int64_runtime_arg_offset() {
-    return OFFSET_OF(Thread, unboxed_int64_runtime_arg_);
+    unboxed_runtime_arg_.int64_storage[0] = value;
   }
   double unboxed_double_runtime_arg() const {
-    return unboxed_double_runtime_arg_;
+    return unboxed_runtime_arg_.double_storage[0];
   }
   void set_unboxed_double_runtime_arg(double value) {
-    unboxed_double_runtime_arg_ = value;
+    unboxed_runtime_arg_.double_storage[0] = value;
   }
-  static intptr_t unboxed_double_runtime_arg_offset() {
-    return OFFSET_OF(Thread, unboxed_double_runtime_arg_);
+  simd128_value_t unboxed_simd128_runtime_arg() const {
+    return unboxed_runtime_arg_;
+  }
+  void set_unboxed_simd128_runtime_arg(simd128_value_t value) {
+    unboxed_runtime_arg_ = value;
+  }
+  static intptr_t unboxed_runtime_arg_offset() {
+    return OFFSET_OF(Thread, unboxed_runtime_arg_);
   }
 
   static intptr_t global_object_pool_offset() {
@@ -1176,8 +1179,7 @@
   // values from generated code to runtime.
   // TODO(dartbug.com/33549): Clean this up when unboxed values
   // could be passed as arguments.
-  ALIGN8 int64_t unboxed_int64_runtime_arg_;
-  ALIGN8 double unboxed_double_runtime_arg_;
+  ALIGN8 simd128_value_t unboxed_runtime_arg_;
 
 // State that is cached in the TLS for fast access in generated code.
 #define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value)      \
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index f5140c6..3d2177a 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -24,6 +24,15 @@
 
 namespace dart {
 
+#if defined(PRODUCT)
+#define DEFAULT_TIMELINE_RECORDER "none"
+#define SUPPORTED_TIMELINE_RECORDERS "systrace, file, callback"
+#else
+#define DEFAULT_TIMELINE_RECORDER "ring"
+#define SUPPORTED_TIMELINE_RECORDERS                                           \
+  "ring, endless, startup, systrace, file, callback"
+#endif
+
 DEFINE_FLAG(bool, complete_timeline, false, "Record the complete timeline");
 DEFINE_FLAG(bool, startup_timeline, false, "Record the startup timeline");
 DEFINE_FLAG(
@@ -45,9 +54,9 @@
             "Debugger, Embedder, GC, Isolate, and VM.");
 DEFINE_FLAG(charp,
             timeline_recorder,
-            "ring",
+            DEFAULT_TIMELINE_RECORDER,
             "Select the timeline recorder used. "
-            "Valid values: ring, endless, startup, and systrace.")
+            "Valid values: none, " SUPPORTED_TIMELINE_RECORDERS)
 
 // Implementation notes:
 //
@@ -94,56 +103,81 @@
 std::atomic<bool> RecorderLock::shutdown_lock_ = {false};
 std::atomic<intptr_t> RecorderLock::outstanding_event_writes_ = {0};
 
+static TimelineEventRecorder* CreateDefaultTimelineRecorder() {
+#if defined(PRODUCT)
+  return new TimelineEventNopRecorder();
+#else
+  return new TimelineEventRingRecorder();
+#endif
+}
+
 static TimelineEventRecorder* CreateTimelineRecorder() {
   // Some flags require that we use the endless recorder.
-  const bool use_endless_recorder =
-      (FLAG_timeline_dir != NULL) || FLAG_complete_timeline;
 
-  const bool use_startup_recorder = FLAG_startup_timeline;
-  const bool use_systrace_recorder = FLAG_systrace_timeline;
-  const char* flag = FLAG_timeline_recorder;
+  const char* flag =
+      FLAG_timeline_recorder != nullptr ? FLAG_timeline_recorder : "";
 
-  if (use_systrace_recorder || (flag != NULL)) {
-    if (use_systrace_recorder || (strcmp("systrace", flag) == 0)) {
+  if (FLAG_systrace_timeline) {
+    flag = "systrace";
+  } else if (FLAG_timeline_dir != nullptr || FLAG_complete_timeline) {
+    flag = "endless";
+  } else if (FLAG_startup_timeline) {
+    flag = "startup";
+  }
+
+  if (strcmp("none", flag) == 0) {
+    return new TimelineEventNopRecorder();
+  }
+
+  // Systrace recorder.
+  if (strcmp("systrace", flag) == 0) {
 #if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
-      return new TimelineEventSystraceRecorder();
+    return new TimelineEventSystraceRecorder();
 #elif defined(DART_HOST_OS_MACOS)
-      if (__builtin_available(iOS 12.0, macOS 10.14, *)) {
-        return new TimelineEventMacosRecorder();
-      }
+    if (__builtin_available(iOS 12.0, macOS 10.14, *)) {
+      return new TimelineEventMacosRecorder();
+    }
 #elif defined(DART_HOST_OS_FUCHSIA)
-      return new TimelineEventFuchsiaRecorder();
+    return new TimelineEventFuchsiaRecorder();
 #else
-      OS::PrintErr(
-          "Warning: The systrace timeline recorder is equivalent to the"
-          "ring recorder on this platform.");
-      return new TimelineEventRingRecorder();
+    // Not supported. A warning will be emitted below.
 #endif
-    }
   }
 
-  if (use_endless_recorder || (flag != NULL)) {
-    if (use_endless_recorder || (strcmp("endless", flag) == 0)) {
-      return new TimelineEventEndlessRecorder();
-    }
+  if (Utils::StrStartsWith(flag, "file") &&
+      (flag[4] == '\0' || flag[4] == ':' || flag[4] == '=')) {
+    const char* filename = flag[4] == '\0' ? "dart-timeline.json" : &flag[5];
+    return new TimelineEventFileRecorder(filename);
   }
 
-  if (use_startup_recorder || (flag != NULL)) {
-    if (use_startup_recorder || (strcmp("startup", flag) == 0)) {
-      return new TimelineEventStartupRecorder();
-    }
+  if (strcmp("callback", flag) == 0) {
+    return new TimelineEventEmbedderCallbackRecorder();
   }
 
-  if (strcmp("file", flag) == 0) {
-    return new TimelineEventFileRecorder("dart-timeline.json");
-  }
-  if (Utils::StrStartsWith(flag, "file:") ||
-      Utils::StrStartsWith(flag, "file=")) {
-    return new TimelineEventFileRecorder(&flag[5]);
+#if !defined(PRODUCT)
+  // Recorders below do nothing useful in PRODUCT mode. You can't extract
+  // information available in them without vm-service.
+  if (strcmp("endless", flag) == 0) {
+    return new TimelineEventEndlessRecorder();
   }
 
-  // Always fall back to the ring recorder.
-  return new TimelineEventRingRecorder();
+  if (strcmp("startup", flag) == 0) {
+    return new TimelineEventStartupRecorder();
+  }
+
+  if (strcmp("ring", flag) == 0) {
+    return new TimelineEventRingRecorder();
+  }
+#endif
+
+  if (strlen(flag) > 0 && strcmp(flag, DEFAULT_TIMELINE_RECORDER) != 0) {
+    OS::PrintErr(
+        "Warning: requested %s timeline recorder which is not supported, "
+        "defaulting to " DEFAULT_TIMELINE_RECORDER " recorder\n",
+        flag);
+  }
+
+  return CreateDefaultTimelineRecorder();
 }
 
 // Returns a caller freed array of stream names in FLAG_timeline_streams.
@@ -206,6 +240,7 @@
   stream_##name##_.set_enabled(HasStream(enabled_streams_, #name));
   TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT)
 #undef TIMELINE_STREAM_FLAG_DEFAULT
+  RecorderLock::Init();
 }
 
 void Timeline::Cleanup() {
@@ -399,6 +434,7 @@
 }
 
 TimelineEventRecorder* Timeline::recorder_ = NULL;
+Dart_TimelineRecorderCallback Timeline::callback_ = NULL;
 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL;
 bool Timeline::recorder_discards_clock_values_ = false;
 
@@ -417,8 +453,8 @@
       label_(NULL),
       stream_(NULL),
       thread_(OSThread::kInvalidThreadId),
-      isolate_id_(ILLEGAL_PORT),
-      isolate_group_id_(0) {}
+      isolate_id_(ILLEGAL_ISOLATE_ID),
+      isolate_group_id_(ILLEGAL_ISOLATE_GROUP_ID) {}
 
 TimelineEvent::~TimelineEvent() {
   Reset();
@@ -698,13 +734,13 @@
   if (pre_serialized_args()) {
     ASSERT(arguments_.length() == 1);
     writer->AppendSerializedObject("args", arguments_[0].value);
-    if (isolate_id_ != ILLEGAL_PORT) {
+    if (HasIsolateId()) {
       writer->UncloseObject();
       writer->PrintfProperty("isolateId", ISOLATE_SERVICE_ID_FORMAT_STRING,
                              static_cast<int64_t>(isolate_id_));
       writer->CloseObject();
     }
-    if (isolate_group_id_ != 0) {
+    if (HasIsolateGroupId()) {
       writer->UncloseObject();
       writer->PrintfProperty("isolateGroupId",
                              ISOLATE_GROUP_SERVICE_ID_FORMAT_STRING,
@@ -719,11 +755,11 @@
       const TimelineEventArgument& arg = arguments_[i];
       writer->PrintProperty(arg.name, arg.value);
     }
-    if (isolate_id_ != ILLEGAL_PORT) {
+    if (HasIsolateId()) {
       writer->PrintfProperty("isolateId", ISOLATE_SERVICE_ID_FORMAT_STRING,
                              static_cast<int64_t>(isolate_id_));
     }
-    if (isolate_group_id_ != 0) {
+    if (HasIsolateGroupId()) {
       writer->PrintfProperty("isolateGroupId",
                              ISOLATE_GROUP_SERVICE_ID_FORMAT_STRING,
                              isolate_group_id_);
@@ -773,6 +809,36 @@
   return thread_timestamp1_ - thread_timestamp0_;
 }
 
+bool TimelineEvent::HasIsolateId() const {
+  return isolate_id_ != ILLEGAL_ISOLATE_ID;
+}
+
+bool TimelineEvent::HasIsolateGroupId() const {
+  return isolate_group_id_ != ILLEGAL_ISOLATE_GROUP_ID;
+}
+
+const char* TimelineEvent::GetFormattedIsolateId() const {
+  ASSERT(HasIsolateId());
+  intptr_t formatted_isolate_id_len =
+      Utils::SNPrint(nullptr, 0, ISOLATE_SERVICE_ID_FORMAT_STRING, isolate_id_);
+  char* formatted_isolate_id =
+      reinterpret_cast<char*>(malloc(formatted_isolate_id_len + 1));
+  Utils::SNPrint(formatted_isolate_id, formatted_isolate_id_len + 1,
+                 ISOLATE_SERVICE_ID_FORMAT_STRING, isolate_id_);
+  return formatted_isolate_id;
+}
+
+const char* TimelineEvent::GetFormattedIsolateGroupId() const {
+  ASSERT(HasIsolateGroupId());
+  intptr_t formatted_isolate_group_id_len = Utils::SNPrint(
+      nullptr, 0, ISOLATE_GROUP_SERVICE_ID_FORMAT_STRING, isolate_group_id_);
+  char* formatted_isolate_group_id =
+      reinterpret_cast<char*>(malloc(formatted_isolate_group_id_len + 1));
+  Utils::SNPrint(formatted_isolate_group_id, formatted_isolate_group_id_len + 1,
+                 ISOLATE_GROUP_SERVICE_ID_FORMAT_STRING, isolate_group_id_);
+  return formatted_isolate_group_id;
+}
+
 TimelineStream::TimelineStream(const char* name,
                                const char* fuchsia_name,
                                bool has_static_labels,
@@ -1326,6 +1392,71 @@
   delete event;
 }
 
+void TimelineEventEmbedderCallbackRecorder::OnEvent(TimelineEvent* event) {
+  Dart_TimelineRecorderCallback callback = Timeline::callback();
+  if (callback == NULL) {
+    return;
+  }
+
+  Dart_TimelineRecorderEvent recorder_event;
+  recorder_event.version = DART_TIMELINE_RECORDER_CURRENT_VERSION;
+  switch (event->event_type()) {
+    case TimelineEvent::kBegin:
+      recorder_event.type = Dart_Timeline_Event_Begin;
+      break;
+    case TimelineEvent::kEnd:
+      recorder_event.type = Dart_Timeline_Event_End;
+      break;
+    case TimelineEvent::kInstant:
+      recorder_event.type = Dart_Timeline_Event_Instant;
+      break;
+    case TimelineEvent::kDuration:
+      recorder_event.type = Dart_Timeline_Event_Duration;
+      break;
+    case TimelineEvent::kAsyncBegin:
+      recorder_event.type = Dart_Timeline_Event_Async_Begin;
+      break;
+    case TimelineEvent::kAsyncEnd:
+      recorder_event.type = Dart_Timeline_Event_Async_End;
+      break;
+    case TimelineEvent::kAsyncInstant:
+      recorder_event.type = Dart_Timeline_Event_Async_Instant;
+      break;
+    case TimelineEvent::kCounter:
+      recorder_event.type = Dart_Timeline_Event_Counter;
+      break;
+    case TimelineEvent::kFlowBegin:
+      recorder_event.type = Dart_Timeline_Event_Flow_Begin;
+      break;
+    case TimelineEvent::kFlowStep:
+      recorder_event.type = Dart_Timeline_Event_Flow_Step;
+      break;
+    case TimelineEvent::kFlowEnd:
+      recorder_event.type = Dart_Timeline_Event_Flow_End;
+      break;
+    default:
+      // Type not expressible as Dart_Timeline_Event_Type: drop event.
+      return;
+  }
+  recorder_event.timestamp0 = event->timestamp0();
+  recorder_event.timestamp1_or_async_id = event->timestamp1();
+  recorder_event.isolate = event->isolate_id();
+  recorder_event.isolate_group = event->isolate_group_id();
+  recorder_event.label = event->label();
+  recorder_event.stream = event->stream()->name();
+  recorder_event.argument_count = event->GetNumArguments();
+  recorder_event.arguments =
+      reinterpret_cast<Dart_TimelineRecorderEvent_Argument*>(
+          event->arguments());
+
+  NoActiveIsolateScope no_active_isolate_scope;
+  callback(&recorder_event);
+}
+
+void TimelineEventNopRecorder::OnEvent(TimelineEvent* event) {
+  // Do nothing.
+}
+
 TimelineEventPlatformRecorder::TimelineEventPlatformRecorder() {}
 
 TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {}
@@ -1680,81 +1811,48 @@
 #endif
 }
 
-void DartTimelineEventHelpers::ReportTaskEvent(Thread* thread,
-                                               TimelineEvent* event,
+void DartTimelineEventHelpers::ReportTaskEvent(TimelineEvent* event,
                                                int64_t id,
-                                               const char* phase,
-                                               const char* category,
+                                               intptr_t type,
                                                char* name,
                                                char* args) {
-  ASSERT(phase != NULL);
-  ASSERT((phase[0] == 'n') || (phase[0] == 'b') || (phase[0] == 'e') ||
-         (phase[0] == 'B') || (phase[0] == 'E'));
-  ASSERT(phase[1] == '\0');
   const int64_t start = OS::GetCurrentMonotonicMicrosForTimeline();
   const int64_t start_cpu = OS::GetCurrentThreadCPUMicrosForTimeline();
-  switch (phase[0]) {
-    case 'n':
+  switch (static_cast<TimelineEvent::EventType>(type)) {
+    case TimelineEvent::kAsyncInstant:
       event->AsyncInstant(name, id, start);
       break;
-    case 'b':
+    case TimelineEvent::kAsyncBegin:
       event->AsyncBegin(name, id, start);
       break;
-    case 'e':
+    case TimelineEvent::kAsyncEnd:
       event->AsyncEnd(name, id, start);
       break;
-    case 'B':
+    case TimelineEvent::kBegin:
       event->Begin(name, id, start, start_cpu);
       break;
-    case 'E':
+    case TimelineEvent::kEnd:
       event->End(name, id, start, start_cpu);
       break;
-    default:
-      UNREACHABLE();
-  }
-  event->set_owns_label(true);
-  event->CompleteWithPreSerializedArgs(args);
-}
-
-void DartTimelineEventHelpers::ReportFlowEvent(Thread* thread,
-                                               TimelineEvent* event,
-                                               const char* category,
-                                               char* name,
-                                               int64_t type,
-                                               int64_t flow_id,
-                                               char* args) {
-  const int64_t start = OS::GetCurrentMonotonicMicrosForTimeline();
-  TimelineEvent::EventType event_type =
-      static_cast<TimelineEvent::EventType>(type);
-  switch (event_type) {
     case TimelineEvent::kFlowBegin:
-      event->FlowBegin(name, flow_id, start);
+      event->FlowBegin(name, id, start);
       break;
     case TimelineEvent::kFlowStep:
-      event->FlowStep(name, flow_id, start);
+      event->FlowStep(name, id, start);
       break;
     case TimelineEvent::kFlowEnd:
-      event->FlowEnd(name, flow_id, start);
+      event->FlowEnd(name, id, start);
+      break;
+    case TimelineEvent::kInstant:
+      event->Instant(name, start);
       break;
     default:
       UNREACHABLE();
-      break;
   }
   event->set_owns_label(true);
   event->CompleteWithPreSerializedArgs(args);
 }
 
-void DartTimelineEventHelpers::ReportInstantEvent(Thread* thread,
-                                                  TimelineEvent* event,
-                                                  const char* category,
-                                                  char* name,
-                                                  char* args) {
-  const int64_t start = OS::GetCurrentMonotonicMicrosForTimeline();
-  event->Instant(name, start);
-  event->set_owns_label(true);
-  event->CompleteWithPreSerializedArgs(args);
-}
-
 }  // namespace dart
 
 #endif  // defined(SUPPORT_TIMELINE)
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 2d06a1e..5c409a8 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -130,6 +130,11 @@
 
 class RecorderLock : public AllStatic {
  public:
+  static void Init() {
+    outstanding_event_writes_.store(0);
+    shutdown_lock_.store(false, std::memory_order_release);
+  }
+
   static void EnterLock() {
     outstanding_event_writes_.fetch_add(1, std::memory_order_acquire);
   }
@@ -188,6 +193,11 @@
     recorder_discards_clock_values_ = value;
   }
 
+  static Dart_TimelineRecorderCallback callback() { return callback_; }
+  static void set_callback(Dart_TimelineRecorderCallback callback) {
+    callback_ = callback;
+  }
+
   // Reclaim all |TimelineEventBlocks|s that are cached by threads.
   static void ReclaimCachedBlocksFromThreads();
 
@@ -218,6 +228,7 @@
   static void ReclaimCachedBlocksFromThreadsUnsafe();
 
   static TimelineEventRecorder* recorder_;
+  static Dart_TimelineRecorderCallback callback_;
   static MallocGrowableArray<char*>* enabled_streams_;
   static bool recorder_discards_clock_values_;
 
@@ -280,20 +291,21 @@
 class TimelineEvent {
  public:
   // Keep in sync with StateBits below.
+  // Keep in sync with constants in sdk/lib/developer/timeline.dart.
   enum EventType {
-    kNone,
-    kBegin,
-    kEnd,
-    kDuration,
-    kInstant,
-    kAsyncBegin,
-    kAsyncInstant,
-    kAsyncEnd,
-    kCounter,
-    kFlowBegin,
-    kFlowStep,
-    kFlowEnd,
-    kMetadata,
+    kNone = 0,
+    kBegin = 1,
+    kEnd = 2,
+    kDuration = 3,
+    kInstant = 4,
+    kAsyncBegin = 5,
+    kAsyncInstant = 6,
+    kAsyncEnd = 7,
+    kCounter = 8,
+    kFlowBegin = 9,
+    kFlowStep = 10,
+    kFlowEnd = 11,
+    kMetadata = 12,
     kNumEventTypes,
   };
 
@@ -389,6 +401,8 @@
 
   EventType event_type() const { return EventTypeField::decode(state_); }
 
+  TimelineStream* stream() const { return stream_; }
+
   bool IsFinishedDuration() const {
     return (event_type() == kDuration) && (timestamp1_ > timestamp0_);
   }
@@ -408,6 +422,14 @@
     return timestamp1_;
   }
 
+  int64_t timestamp0() const { return timestamp0_; }
+  int64_t timestamp1() const { return timestamp1_; }
+
+  bool HasIsolateId() const;
+  bool HasIsolateGroupId() const;
+  const char* GetFormattedIsolateId() const;
+  const char* GetFormattedIsolateGroupId() const;
+
   // The lowest time value stored in this event.
   int64_t LowTime() const;
   // The highest time value stored in this event.
@@ -916,6 +938,9 @@
   virtual void OnEvent(TimelineEvent* event) = 0;
 
   const char* name() const { return CALLBACK_RECORDER_NAME; }
+  intptr_t Size() {
+    return 0;
+  }
 
  protected:
   TimelineEventBlock* GetNewBlockLocked() { return NULL; }
@@ -925,6 +950,26 @@
   void CompleteEvent(TimelineEvent* event);
 };
 
+// A recorder that forwards completed events to the callback provided by
+// Dart_SetTimelineRecorderCallback.
+class TimelineEventEmbedderCallbackRecorder
+    : public TimelineEventCallbackRecorder {
+ public:
+  TimelineEventEmbedderCallbackRecorder() {}
+  virtual ~TimelineEventEmbedderCallbackRecorder() {}
+
+  virtual void OnEvent(TimelineEvent* event);
+};
+
+// A recorder that does nothing.
+class TimelineEventNopRecorder : public TimelineEventCallbackRecorder {
+ public:
+  TimelineEventNopRecorder() {}
+  virtual ~TimelineEventNopRecorder() {}
+
+  virtual void OnEvent(TimelineEvent* event);
+};
+
 // A recorder that stores events in chains of blocks of events.
 // NOTE: This recorder will continue to allocate blocks until it exhausts
 // memory.
@@ -1067,27 +1112,11 @@
 
 class DartTimelineEventHelpers : public AllStatic {
  public:
-  static void ReportTaskEvent(Thread* thread,
-                              TimelineEvent* event,
+  static void ReportTaskEvent(TimelineEvent* event,
                               int64_t id,
-                              const char* phase,
-                              const char* category,
+                              intptr_t type,
                               char* name,
                               char* args);
-
-  static void ReportFlowEvent(Thread* thread,
-                              TimelineEvent* event,
-                              const char* category,
-                              char* name,
-                              int64_t type,
-                              int64_t flow_id,
-                              char* args);
-
-  static void ReportInstantEvent(Thread* thread,
-                                 TimelineEvent* event,
-                                 const char* category,
-                                 char* name,
-                                 char* args);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/timeline_test.cc b/runtime/vm/timeline_test.cc
index 09d226b..ee3ff18 100644
--- a/runtime/vm/timeline_test.cc
+++ b/runtime/vm/timeline_test.cc
@@ -279,8 +279,6 @@
 
   intptr_t CountFor(TimelineEvent::EventType type) { return counts_[type]; }
 
-  intptr_t Size() { return -1; }
-
  private:
   intptr_t counts_[TimelineEvent::kNumEventTypes];
 };
@@ -377,4 +375,94 @@
 
 #endif  // !PRODUCT
 
+#if defined(SUPPORT_TIMELINE)
+
+static Dart_Port expected_isolate;
+static Dart_IsolateGroupId expected_isolate_group;
+static bool saw_begin;
+static bool saw_end;
+
+static void TestTimelineRecorderCallback(Dart_TimelineRecorderEvent* event) {
+  EXPECT_EQ(DART_TIMELINE_RECORDER_CURRENT_VERSION, event->version);
+
+  if ((event->type == Dart_Timeline_Event_Begin) &&
+      (strcmp(event->label, "TestEvent") == 0)) {
+    saw_begin = true;
+    EXPECT_NE(0, event->timestamp0);
+    EXPECT_EQ(expected_isolate, event->isolate);
+    EXPECT_EQ(expected_isolate_group, event->isolate_group);
+    EXPECT_STREQ("Dart", event->stream);
+    EXPECT_EQ(1, event->argument_count);
+    EXPECT_STREQ("Dart Arguments", event->arguments[0].name);
+    EXPECT_STREQ("{\"key\":\"value\"}", event->arguments[0].value);
+  }
+
+  if ((event->type == Dart_Timeline_Event_End) &&
+      (strcmp(event->label, "TestEvent") == 0)) {
+    saw_end = true;
+    EXPECT_NE(0, event->timestamp0);
+    EXPECT_EQ(expected_isolate, event->isolate);
+    EXPECT_EQ(expected_isolate_group, event->isolate_group);
+    EXPECT_STREQ("Dart", event->stream);
+    EXPECT_EQ(1, event->argument_count);
+    EXPECT_STREQ("Dart Arguments", event->arguments[0].name);
+    EXPECT_STREQ("{\"key\":\"value\"}", event->arguments[0].value);
+  }
+}
+
+UNIT_TEST_CASE(DartAPI_SetTimelineRecorderCallback) {
+  int argc = TesterState::argc + 2;
+  const char** argv = new const char*[argc];
+  for (intptr_t i = 0; i < argc - 2; i++) {
+    argv[i] = TesterState::argv[i];
+  }
+  argv[argc - 2] = "--timeline_recorder=callback";
+  argv[argc - 1] = "--timeline_streams=Dart";
+
+  Dart_SetTimelineRecorderCallback(TestTimelineRecorderCallback);
+
+  EXPECT(Dart_SetVMFlags(argc, argv) == NULL);
+  Dart_InitializeParams params;
+  memset(&params, 0, sizeof(Dart_InitializeParams));
+  params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
+  params.vm_snapshot_data = TesterState::vm_snapshot_data;
+  params.create_group = TesterState::create_callback;
+  params.shutdown_isolate = TesterState::shutdown_callback;
+  params.cleanup_group = TesterState::group_cleanup_callback;
+  params.start_kernel_isolate = true;
+
+  EXPECT(Dart_Initialize(&params) == NULL);
+  {
+    TestIsolateScope scope;
+    const char* kScriptChars =
+        "import 'dart:developer';\n"
+        "main() {\n"
+        "  Timeline.startSync('TestEvent', arguments: {'key':'value'});\n"
+        "  Timeline.finishSync();\n"
+        "}\n";
+    Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+    EXPECT_VALID(lib);
+
+    expected_isolate = Dart_GetMainPortId();
+    EXPECT_NE(ILLEGAL_PORT, expected_isolate);
+    expected_isolate_group = Dart_CurrentIsolateGroupId();
+    EXPECT_NE(ILLEGAL_PORT, expected_isolate_group);
+    saw_begin = false;
+    saw_end = false;
+
+    Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+    EXPECT_VALID(result);
+
+    EXPECT(saw_begin);
+    EXPECT(saw_end);
+  }
+  EXPECT(Dart_Cleanup() == NULL);
+
+  Dart_SetTimelineRecorderCallback(NULL);
+
+  delete[] argv;
+}
+
+#endif  // defined(SUPPORT_TIMELINE)
+
 }  // namespace dart
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index aa79b1d..52aeef3 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -14,6 +14,7 @@
 #include "vm/stub_code.h"
 #include "vm/timeline.h"
 #include "vm/type_testing_stubs.h"
+#include "vm/zone_text_buffer.h"
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/compiler/backend/flow_graph_compiler.h"
@@ -32,57 +33,60 @@
 
 const char* TypeTestingStubNamer::StubNameForType(
     const AbstractType& type) const {
-  Zone* Z = Thread::Current()->zone();
-  return OS::SCreate(Z, "TypeTestingStub_%s", StringifyType(type));
+  ZoneTextBuffer buffer(Thread::Current()->zone());
+  WriteStubNameForTypeTo(&buffer, type);
+  return buffer.buffer();
 }
 
-const char* TypeTestingStubNamer::StringifyType(
+void TypeTestingStubNamer::WriteStubNameForTypeTo(
+    BaseTextBuffer* buffer,
     const AbstractType& type) const {
+  buffer->AddString("TypeTestingStub_");
+  StringifyTypeTo(buffer, type);
+}
+
+void TypeTestingStubNamer::StringifyTypeTo(BaseTextBuffer* buffer,
+                                           const AbstractType& type) const {
   NoSafepointScope no_safepoint;
-  Zone* Z = Thread::Current()->zone();
   if (type.IsType()) {
     const intptr_t cid = Type::Cast(type).type_class_id();
     ClassTable* class_table = IsolateGroup::Current()->class_table();
     klass_ = class_table->At(cid);
     ASSERT(!klass_.IsNull());
 
-    const char* curl = "";
     lib_ = klass_.library();
     if (!lib_.IsNull()) {
       string_ = lib_.url();
-      curl = OS::SCreate(Z, "%s_", string_.ToCString());
+      buffer->AddString(string_.ToCString());
     } else {
-      static std::atomic<intptr_t> counter = 0;
-      curl = OS::SCreate(Z, "nolib%" Pd "_", counter++);
+      buffer->Printf("nolib%" Pd "_", nonce_++);
     }
 
-    const char* concatenated = AssemblerSafeName(
-        OS::SCreate(Z, "%s_%s", curl, klass_.ScrubbedNameCString()));
+    buffer->AddString("_");
+    buffer->AddString(klass_.ScrubbedNameCString());
 
     const intptr_t type_parameters = klass_.NumTypeParameters();
-    auto& type_arguments = TypeArguments::Handle();
-    if (type.arguments() != TypeArguments::null() && type_parameters > 0) {
+    auto& type_arguments = TypeArguments::Handle(type.arguments());
+    if (!type_arguments.IsNull() && type_parameters > 0) {
       type_arguments = type.arguments();
       ASSERT(type_arguments.Length() >= type_parameters);
       const intptr_t length = type_arguments.Length();
       for (intptr_t i = 0; i < type_parameters; ++i) {
         type_ = type_arguments.TypeAt(length - type_parameters + i);
-        concatenated =
-            OS::SCreate(Z, "%s__%s", concatenated, StringifyType(type_));
+        buffer->AddString("__");
+        StringifyTypeTo(buffer, type_);
       }
     }
-
-    return concatenated;
   } else if (type.IsTypeParameter()) {
-    return AssemblerSafeName(
-        OS::SCreate(Z, "%s", TypeParameter::Cast(type).CanonicalNameCString()));
+    buffer->AddString(TypeParameter::Cast(type).CanonicalNameCString());
   } else {
-    return AssemblerSafeName(OS::SCreate(Z, "%s", type.ToCString()));
+    buffer->AddString(type.ToCString());
   }
+  MakeNameAssemblerSafe(buffer);
 }
 
-const char* TypeTestingStubNamer::AssemblerSafeName(char* cname) {
-  char* cursor = cname;
+void TypeTestingStubNamer::MakeNameAssemblerSafe(BaseTextBuffer* buffer) {
+  char* cursor = buffer->buffer();
   while (*cursor != '\0') {
     char c = *cursor;
     if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
@@ -91,7 +95,6 @@
     }
     cursor++;
   }
-  return cname;
 }
 
 CodePtr TypeTestingStubGenerator::DefaultCodeForType(
@@ -126,7 +129,7 @@
     }
   }
 
-  if (type.IsFunctionType()) {
+  if (type.IsFunctionType() || type.IsRecordType()) {
     const bool nullable = Instance::NullIsAssignableTo(type);
     return nullable ? StubCode::DefaultNullableTypeTest().ptr()
                     : StubCode::DefaultTypeTest().ptr();
@@ -969,43 +972,24 @@
   return !type_argument_checks.is_empty();
 }
 
-// Unwraps TypeRefs, jumping to the appropriate label for the unwrapped type
-// if that label is not nullptr and otherwise falling through.
+// Unwraps TypeRef in [type_reg] and loads class id of the unwrapped type to
+// [class_id_reg].
 //
-// [type_reg] must contain an AbstractTypePtr, and [scratch] must be distinct
-// from [type_reg]. Clobbers [type_reg] with the unwrapped type.
-static void UnwrapAbstractType(compiler::Assembler* assembler,
-                               Register type_reg,
-                               Register scratch,
-                               compiler::Label* is_type = nullptr,
-                               compiler::Label* is_function_type = nullptr,
-                               compiler::Label* is_type_parameter = nullptr) {
-  ASSERT(scratch != type_reg);
-  compiler::Label cid_checks, fall_through;
+// [type_reg] must contain an AbstractType. Unwrapped TypeRef is written
+// back to [type_reg]. [class_id_reg] must be distinct from [type_reg].
+static void UnwrapTypeRefAndLoadClassId(compiler::Assembler* assembler,
+                                        Register type_reg,
+                                        Register class_id_reg) {
+  ASSERT(class_id_reg != type_reg);
+  compiler::Label done;
   // TypeRefs never wrap other TypeRefs, so we only need to unwrap once.
-  __ LoadClassId(scratch, type_reg);
-  __ CompareImmediate(scratch, kTypeRefCid);
-  __ BranchIf(NOT_EQUAL, &cid_checks, compiler::Assembler::kNearJump);
+  __ LoadClassId(class_id_reg, type_reg);
+  __ CompareImmediate(class_id_reg, kTypeRefCid);
+  __ BranchIf(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
   __ LoadCompressedFieldFromOffset(type_reg, type_reg,
                                    compiler::target::TypeRef::type_offset());
-  // Only load the class id of the unwrapped type if it will be checked below.
-  if (is_type != nullptr || is_function_type != nullptr ||
-      is_type_parameter != nullptr) {
-    __ LoadClassId(scratch, type_reg);
-  }
-  __ Bind(&cid_checks);
-  if (is_type != nullptr) {
-    __ CompareImmediate(scratch, kTypeCid);
-    __ BranchIf(EQUAL, is_type);
-  }
-  if (is_function_type != nullptr) {
-    __ CompareImmediate(scratch, kFunctionTypeCid);
-    __ BranchIf(EQUAL, is_function_type);
-  }
-  if (is_type_parameter != nullptr) {
-    __ CompareImmediate(scratch, kTypeParameterCid);
-    __ BranchIf(EQUAL, is_type_parameter);
-  }
+  __ LoadClassId(class_id_reg, type_reg);
+  __ Bind(&done);
 }
 
 void TypeTestingStubGenerator::BuildOptimizedTypeParameterArgumentValueCheck(
@@ -1049,9 +1033,10 @@
 
   __ Comment("Checking instantiated type parameter for possible top types");
   compiler::Label check_subtype_type_class_ids;
-  UnwrapAbstractType(assembler, TTSInternalRegs::kSuperTypeArgumentReg,
-                     TTSInternalRegs::kScratchReg, /*is_type=*/nullptr,
-                     &check_subtype_type_class_ids);
+  UnwrapTypeRefAndLoadClassId(assembler, TTSInternalRegs::kSuperTypeArgumentReg,
+                              TTSInternalRegs::kScratchReg);
+  __ CompareImmediate(TTSInternalRegs::kScratchReg, kTypeCid);
+  __ BranchIf(NOT_EQUAL, &check_subtype_type_class_ids);
   __ LoadTypeClassId(TTSInternalRegs::kScratchReg,
                      TTSInternalRegs::kSuperTypeArgumentReg);
   __ CompareImmediate(TTSInternalRegs::kScratchReg, kDynamicCid);
@@ -1062,22 +1047,16 @@
   if (strict_null_safety) {
     __ BranchIf(NOT_EQUAL, &check_subtype_type_class_ids);
     // If non-nullable Object, then the subtype must be legacy or non-nullable.
-    __ CompareTypeNullabilityWith(
+    __ CompareAbstractTypeNullabilityWith(
         TTSInternalRegs::kSuperTypeArgumentReg,
-        static_cast<int8_t>(Nullability::kNonNullable));
+        static_cast<int8_t>(Nullability::kNonNullable),
+        TTSInternalRegs::kScratchReg);
     __ BranchIf(NOT_EQUAL, &is_subtype);
     __ Comment("Checking for legacy or non-nullable instance type argument");
-    compiler::Label subtype_is_type;
-    UnwrapAbstractType(assembler, TTSInternalRegs::kSubTypeArgumentReg,
-                       TTSInternalRegs::kScratchReg, &subtype_is_type);
-    __ CompareFunctionTypeNullabilityWith(
+    __ CompareAbstractTypeNullabilityWith(
         TTSInternalRegs::kSubTypeArgumentReg,
-        static_cast<int8_t>(Nullability::kNullable));
-    __ BranchIf(EQUAL, check_failed);
-    __ Jump(&is_subtype);
-    __ Bind(&subtype_is_type);
-    __ CompareTypeNullabilityWith(TTSInternalRegs::kSubTypeArgumentReg,
-                                  static_cast<int8_t>(Nullability::kNullable));
+        static_cast<int8_t>(Nullability::kNullable),
+        TTSInternalRegs::kScratchReg);
     __ BranchIf(EQUAL, check_failed);
     __ Jump(&is_subtype);
   } else {
@@ -1087,9 +1066,10 @@
   __ Bind(&check_subtype_type_class_ids);
   __ Comment("Checking instance type argument for possible bottom types");
   // Nothing else to check for non-Types, so fall back to the slow stub.
-  UnwrapAbstractType(assembler, TTSInternalRegs::kSubTypeArgumentReg,
-                     TTSInternalRegs::kScratchReg, /*is_type=*/nullptr,
-                     check_failed);
+  UnwrapTypeRefAndLoadClassId(assembler, TTSInternalRegs::kSubTypeArgumentReg,
+                              TTSInternalRegs::kScratchReg);
+  __ CompareImmediate(TTSInternalRegs::kScratchReg, kTypeCid);
+  __ BranchIf(NOT_EQUAL, check_failed);
   __ LoadTypeClassId(TTSInternalRegs::kScratchReg,
                      TTSInternalRegs::kSubTypeArgumentReg);
   __ CompareImmediate(TTSInternalRegs::kScratchReg, kNeverCid);
@@ -1100,18 +1080,10 @@
   if (strict_null_safety) {
     // Only nullable or legacy types can be a supertype of Null.
     __ Comment("Checking for legacy or nullable instantiated type parameter");
-    compiler::Label supertype_is_type;
-    UnwrapAbstractType(assembler, TTSInternalRegs::kSuperTypeArgumentReg,
-                       TTSInternalRegs::kScratchReg, &supertype_is_type);
-    __ CompareFunctionTypeNullabilityWith(
+    __ CompareAbstractTypeNullabilityWith(
         TTSInternalRegs::kSuperTypeArgumentReg,
-        static_cast<int8_t>(Nullability::kNonNullable));
-    __ BranchIf(EQUAL, check_failed);
-    __ Jump(&is_subtype, compiler::Assembler::kNearJump);
-    __ Bind(&supertype_is_type);
-    __ CompareTypeNullabilityWith(
-        TTSInternalRegs::kSuperTypeArgumentReg,
-        static_cast<int8_t>(Nullability::kNonNullable));
+        static_cast<int8_t>(Nullability::kNonNullable),
+        TTSInternalRegs::kScratchReg);
     __ BranchIf(EQUAL, check_failed);
   }
 
@@ -1143,43 +1115,54 @@
     __ Comment("%s", buffer.buffer());
   }
 
-  compiler::Label is_subtype, check_subtype_cid, sub_is_function_type,
-      sub_is_type;
+  compiler::Label is_subtype, sub_is_type;
   __ LoadCompressedFieldFromOffset(
       TTSInternalRegs::kSubTypeArgumentReg,
       TTSInternalRegs::kInstanceTypeArgumentsReg,
       compiler::target::TypeArguments::type_at_offset(
           type_param_value_offset_i));
-  __ Bind(&check_subtype_cid);
-  UnwrapAbstractType(assembler, TTSInternalRegs::kSubTypeArgumentReg,
-                     TTSInternalRegs::kScratchReg, &sub_is_type);
-  __ Comment("Checks for FunctionType");
-  __ EnsureHasClassIdInDEBUG(kFunctionTypeCid,
-                             TTSInternalRegs::kSubTypeArgumentReg,
-                             TTSInternalRegs::kScratchReg);
-  if (type.IsObjectType() || type.IsDartFunctionType()) {
+  UnwrapTypeRefAndLoadClassId(assembler, TTSInternalRegs::kSubTypeArgumentReg,
+                              TTSInternalRegs::kScratchReg);
+  if (type.IsObjectType() || type.IsDartFunctionType() ||
+      type.IsDartRecordType()) {
+    __ CompareImmediate(TTSInternalRegs::kScratchReg, kTypeCid);
+    __ BranchIf(EQUAL, &sub_is_type);
+    if (type.IsDartFunctionType()) {
+      __ Comment("Checks for Function type");
+      __ CompareImmediate(TTSInternalRegs::kScratchReg, kFunctionTypeCid);
+      __ BranchIf(NOT_EQUAL, check_failed);
+    } else if (type.IsDartRecordType()) {
+      __ Comment("Checks for Record type");
+      __ CompareImmediate(TTSInternalRegs::kScratchReg, kRecordTypeCid);
+      __ BranchIf(NOT_EQUAL, check_failed);
+    } else {
+      __ Comment("Checks for Object type");
+    }
     if (strict_null_safety && type.IsNonNullable()) {
       // Nullable types cannot be a subtype of a non-nullable type.
-      __ CompareFunctionTypeNullabilityWith(
+      __ CompareAbstractTypeNullabilityWith(
           TTSInternalRegs::kSubTypeArgumentReg,
-          compiler::target::Nullability::kNullable);
+          static_cast<int8_t>(Nullability::kNullable),
+          TTSInternalRegs::kScratchReg);
       __ BranchIf(EQUAL, check_failed);
     }
-    // No further checks needed for non-nullable Object or Function.
+    // No further checks needed for non-nullable Object, Function or Record.
     __ Jump(&is_subtype, compiler::Assembler::kNearJump);
   } else {
-    // _Closure <: Function, and T <: Function for any FunctionType T, but
-    // T </: _Closure, so we _don't_ want to fall back to cid tests. Instead,
+    // Don't fall back to cid tests for record and function types. Instead,
     // just let the STC/runtime handle any possible false negatives here.
-    __ Jump(check_failed);
+    __ CompareImmediate(TTSInternalRegs::kScratchReg, kTypeCid);
+    __ BranchIf(NOT_EQUAL, check_failed);
   }
 
   __ Comment("Checks for Type");
   __ Bind(&sub_is_type);
   if (strict_null_safety && type.IsNonNullable()) {
     // Nullable types cannot be a subtype of a non-nullable type in strict mode.
-    __ CompareTypeNullabilityWith(TTSInternalRegs::kSubTypeArgumentReg,
-                                  compiler::target::Nullability::kNullable);
+    __ CompareAbstractTypeNullabilityWith(
+        TTSInternalRegs::kSubTypeArgumentReg,
+        static_cast<int8_t>(Nullability::kNullable),
+        TTSInternalRegs::kScratchReg);
     __ BranchIf(EQUAL, check_failed);
     // Fall through to bottom type checks.
   }
@@ -1367,6 +1350,10 @@
     // No support for function types yet.
     UNREACHABLE();
     return nullptr;
+  } else if (type.IsRecordType()) {
+    // No support for record types yet.
+    UNREACHABLE();
+    return nullptr;
   } else if (type.IsTypeRef()) {
     // No support for recursive types.
     UNREACHABLE();
diff --git a/runtime/vm/type_testing_stubs.h b/runtime/vm/type_testing_stubs.h
index 7807bc1..6bd8b50 100644
--- a/runtime/vm/type_testing_stubs.h
+++ b/runtime/vm/type_testing_stubs.h
@@ -24,15 +24,19 @@
   //
   // (only during dart_boostrap).
   const char* StubNameForType(const AbstractType& type) const;
+  void WriteStubNameForTypeTo(BaseTextBuffer* buffer,
+                              const AbstractType& type) const;
 
  private:
-  const char* StringifyType(const AbstractType& type) const;
-  static const char* AssemblerSafeName(char* cname);
+  void StringifyTypeTo(BaseTextBuffer* buffer, const AbstractType& type) const;
+  // Converts the contents of the buffer to an assembly-safe name.
+  static void MakeNameAssemblerSafe(BaseTextBuffer* buffer);
 
   Library& lib_;
   Class& klass_;
   AbstractType& type_;
   String& string_;
+  mutable intptr_t nonce_ = 0;
 };
 
 class TypeTestingStubGenerator {
@@ -210,6 +214,9 @@
     } else if (type.IsFunctionType()) {
       // No support for function types yet.
       return false;
+    } else if (type.IsRecordType()) {
+      // No support for record types yet.
+      return false;
     } else if (type.IsTypeRef()) {
       // No support for recursive types.
       return false;
diff --git a/runtime/vm/virtual_memory_compressed.cc b/runtime/vm/virtual_memory_compressed.cc
index 7706ea4..7a09940 100644
--- a/runtime/vm/virtual_memory_compressed.cc
+++ b/runtime/vm/virtual_memory_compressed.cc
@@ -41,7 +41,7 @@
   memset(pages_, 0, kCompressedHeapBitmapSize);
   ASSERT(size > 0);
   ASSERT(size <= kCompressedHeapSize);
-  for (intptr_t page_id = size / kCompressedHeapPageSize;
+  for (intptr_t page_id = size / kCompressedPageSize;
        page_id < kCompressedHeapNumPages; page_id++) {
     SetPageUsed(page_id);
   }
@@ -50,8 +50,8 @@
   ASSERT(base_ != 0);
   ASSERT(size_ != 0);
   ASSERT(size_ <= kCompressedHeapSize);
-  ASSERT(Utils::IsAligned(base_, kCompressedHeapPageSize));
-  ASSERT(Utils::IsAligned(size_, kCompressedHeapPageSize));
+  ASSERT(Utils::IsAligned(base_, kCompressedPageSize));
+  ASSERT(Utils::IsAligned(size_, kCompressedPageSize));
   // base_ is not necessarily 4GB-aligned, because on some systems we can't make
   // a large enough reservation to guarantee it. Instead, we have only the
   // weaker property that all addresses in [base_, base_ + size_) have the same
@@ -78,11 +78,10 @@
 MemoryRegion VirtualMemoryCompressedHeap::Allocate(intptr_t size,
                                                    intptr_t alignment) {
   ASSERT(alignment <= kCompressedHeapAlignment);
-  const intptr_t allocated_size = Utils::RoundUp(size, kCompressedHeapPageSize);
-  uword pages = allocated_size / kCompressedHeapPageSize;
-  uword page_alignment = alignment > kCompressedHeapPageSize
-                             ? alignment / kCompressedHeapPageSize
-                             : 1;
+  const intptr_t allocated_size = Utils::RoundUp(size, kCompressedPageSize);
+  uword pages = allocated_size / kCompressedPageSize;
+  uword page_alignment =
+      alignment > kCompressedPageSize ? alignment / kCompressedPageSize : 1;
   MutexLocker ml(mutex_);
 
   // Find a gap with enough empty pages, using the bitmap. Note that reading
@@ -105,7 +104,7 @@
 
   // Make sure we're not trying to allocate past the end of the heap.
   uword end = page_id + pages;
-  if (end > kCompressedHeapSize / kCompressedHeapPageSize) {
+  if (end > kCompressedHeapSize / kCompressedPageSize) {
     return MemoryRegion();
   }
 
@@ -120,19 +119,19 @@
     ++minimum_free_page_id_;
   }
 
-  uword address = base_ + page_id * kCompressedHeapPageSize;
-  ASSERT(Utils::IsAligned(address, kCompressedHeapPageSize));
+  uword address = base_ + page_id * kCompressedPageSize;
+  ASSERT(Utils::IsAligned(address, kCompressedPageSize));
   return MemoryRegion(reinterpret_cast<void*>(address), allocated_size);
 }
 
 void VirtualMemoryCompressedHeap::Free(void* address, intptr_t size) {
   uword start = reinterpret_cast<uword>(address);
-  ASSERT(Utils::IsAligned(start, kCompressedHeapPageSize));
-  ASSERT(Utils::IsAligned(size, kCompressedHeapPageSize));
+  ASSERT(Utils::IsAligned(start, kCompressedPageSize));
+  ASSERT(Utils::IsAligned(size, kCompressedPageSize));
   MutexLocker ml(mutex_);
   ASSERT(start >= base_);
-  uword page_id = (start - base_) / kCompressedHeapPageSize;
-  uword end = page_id + size / kCompressedHeapPageSize;
+  uword page_id = (start - base_) / kCompressedPageSize;
+  uword end = page_id + size / kCompressedPageSize;
   for (uword i = page_id; i < end; ++i) {
     ClearPageUsed(i);
   }
diff --git a/runtime/vm/virtual_memory_compressed.h b/runtime/vm/virtual_memory_compressed.h
index bf6fb4c..dbe80c1 100644
--- a/runtime/vm/virtual_memory_compressed.h
+++ b/runtime/vm/virtual_memory_compressed.h
@@ -14,9 +14,9 @@
 #if defined(DART_COMPRESSED_POINTERS)
 static constexpr intptr_t kCompressedHeapSize = 4 * GB;
 static constexpr intptr_t kCompressedHeapAlignment = 4 * GB;
-static constexpr intptr_t kCompressedHeapPageSize = kOldPageSize;
+static constexpr intptr_t kCompressedPageSize = kPageSize;
 static constexpr intptr_t kCompressedHeapNumPages =
-    kCompressedHeapSize / kOldPageSize;
+    kCompressedHeapSize / kPageSize;
 static constexpr intptr_t kCompressedHeapBitmapSize =
     kCompressedHeapNumPages / 8;
 
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index 72235ff..21f6f79 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -133,10 +133,10 @@
   // not cross a 4GB boundary. The subregion itself is not necessarily
   // 4GB-aligned.
   for (size_t allocated_size = kCompressedHeapSize + kCompressedHeapAlignment;
-       allocated_size >= kCompressedHeapPageSize; allocated_size >>= 1) {
+       allocated_size >= kCompressedPageSize; allocated_size >>= 1) {
     void* address = GenericMapAligned(
-        nullptr, PROT_NONE, allocated_size, kCompressedHeapPageSize,
-        allocated_size + kCompressedHeapPageSize,
+        nullptr, PROT_NONE, allocated_size, kCompressedPageSize,
+        allocated_size + kCompressedPageSize,
         MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE);
     if (address == nullptr) continue;
 
@@ -177,7 +177,7 @@
   // Also detect for missing support of memfd_create syscall.
   if (FLAG_dual_map_code) {
     intptr_t size = PageSize();
-    intptr_t alignment = kOldPageSize;
+    intptr_t alignment = kPageSize;
     bool executable = true;
     bool compressed = false;
     VirtualMemory* vm =
@@ -206,7 +206,7 @@
     int count = fscanf(fp, "%zu", &max_map_count);
     fclose(fp);
     if (count == 1) {
-      size_t max_heap_pages = FLAG_old_gen_heap_size * MB / kOldPageSize;
+      size_t max_heap_pages = FLAG_old_gen_heap_size * MB / kPageSize;
       if (max_map_count < max_heap_pages) {
         OS::PrintErr(
             "warning: vm.max_map_count (%zu) is not large enough to support "
diff --git a/runtime/vm/virtual_memory_test.cc b/runtime/vm/virtual_memory_test.cc
index c343961..083c906 100644
--- a/runtime/vm/virtual_memory_test.cc
+++ b/runtime/vm/virtual_memory_test.cc
@@ -52,7 +52,7 @@
 }
 
 VM_UNIT_TEST_CASE(AllocateAlignedVirtualMemory) {
-  intptr_t kHeapPageSize = kOldPageSize;
+  intptr_t kHeapPageSize = kPageSize;
   intptr_t kVirtualPageSize = 4096;
 
   intptr_t kIterations = kHeapPageSize / kVirtualPageSize;
diff --git a/runtime/vm/visitor.cc b/runtime/vm/visitor.cc
index 145dd06..37806bb 100644
--- a/runtime/vm/visitor.cc
+++ b/runtime/vm/visitor.cc
@@ -11,6 +11,6 @@
 ObjectPointerVisitor::ObjectPointerVisitor(IsolateGroup* isolate_group)
     : isolate_group_(isolate_group),
       gc_root_type_("unknown"),
-      shared_class_table_(isolate_group->shared_class_table()) {}
+      class_table_(isolate_group->heap_walk_class_table()) {}
 
 }  // namespace dart
diff --git a/runtime/vm/visitor.h b/runtime/vm/visitor.h
index 2ed6547..5aafc64 100644
--- a/runtime/vm/visitor.h
+++ b/runtime/vm/visitor.h
@@ -60,9 +60,7 @@
   // Otherwise trace field values through isolate's field_table.
   virtual bool trace_values_through_fields() const { return false; }
 
-  const SharedClassTable* shared_class_table() const {
-    return shared_class_table_;
-  }
+  const ClassTable* class_table() const { return class_table_; }
 
   // Returns true if pointers of the given SuspendState object can be visited.
   // Compactor overrides this method in order to postpone visiting SuspendState
@@ -76,7 +74,7 @@
  private:
   IsolateGroup* isolate_group_;
   const char* gc_root_type_;
-  SharedClassTable* shared_class_table_;
+  ClassTable* class_table_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectPointerVisitor);
 };
diff --git a/runtime/vm/zone.h b/runtime/vm/zone.h
index d5abb3b..c38cc45 100644
--- a/runtime/vm/zone.h
+++ b/runtime/vm/zone.h
@@ -310,9 +310,8 @@
           reinterpret_cast<uword>(old_data) + (new_len * kElementSize);
       // ...and there is sufficient space.
       if (new_end <= limit_) {
-        ASSERT(new_len >= old_len);
         position_ = Utils::RoundUp(new_end, kAlignment);
-        size_ += (new_end - old_end);
+        size_ += static_cast<intptr_t>(new_len - old_len);
         return old_data;
       }
     }
diff --git a/runtime/vm/zone_test.cc b/runtime/vm/zone_test.cc
index 9231cda..13ca394 100644
--- a/runtime/vm/zone_test.cc
+++ b/runtime/vm/zone_test.cc
@@ -111,6 +111,28 @@
   Dart_ShutdownIsolate();
 }
 
+VM_UNIT_TEST_CASE(ZoneRealloc) {
+  TestCase::CreateTestIsolate();
+  Thread* thread = Thread::Current();
+  {
+    TransitionNativeToVM transition(thread);
+    StackZone stack_zone(thread);
+    auto zone = thread->zone();
+
+    const intptr_t kOldLen = 32;
+    const intptr_t kNewLen = 16;
+    const intptr_t kNewLen2 = 16;
+
+    auto data_old = zone->Alloc<uint8_t>(kOldLen);
+    auto data_new = zone->Realloc<uint8_t>(data_old, kOldLen, kNewLen);
+    RELEASE_ASSERT(data_old == data_new);
+
+    auto data_new2 = zone->Realloc<uint8_t>(data_old, kNewLen, kNewLen2);
+    RELEASE_ASSERT(data_old == data_new2);
+  }
+  Dart_ShutdownIsolate();
+}
+
 VM_UNIT_TEST_CASE(ZoneAllocated) {
 #if defined(DEBUG)
   FLAG_trace_zones = true;
diff --git a/samples-dev/swarm/README b/samples-dev/swarm/README
deleted file mode 100644
index 7403a92..0000000
--- a/samples-dev/swarm/README
+++ /dev/null
@@ -1,31 +0,0 @@
-Copyright (c) 2011, 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.
-
-A sample news reader application.
-
-Running in the Editor with demo data (demo only, no feeds):
-
-1. open the Dart Editor
-
-2. from the menu, click File / Open Folder and load this directory
-
-3. click the green run button
-
-4. alternatively, to run as javascript:
-  - compile (under the Tools / Generate JavaScript menu option)
-  - load the same url shown in Dartium in step 3 in any other browser
-
-Running in Dartium from the file system (demo only, no feeds):
-
-1. run the Dartium Chrome binary from the command line with the following flag: --allow-file-access-from-files
-
-2. navigate to the swarm.html file in this directory
-
-Running from App Engine (TODO: these are stale instructions):
-
-1. To run on App Engine, install the App Engine SDK for your platform, then
-  $ easy_install --upgrade google-api-python-client per http://code.google.com/p/google-api-python-client/wiki/Installation
-  $ cd samples/swarm/appengine
-  $ enable-app-engine-project . per http://code.google.com/p/google-api-python-client/wiki/GoogleAppEngine
-  Start the App Engine dev server and browse to /swarm-js.html
diff --git a/samples-dev/swarm/analysis_options.yaml b/samples-dev/swarm/analysis_options.yaml
deleted file mode 100644
index 79113c2..0000000
--- a/samples-dev/swarm/analysis_options.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-include: package:lints/recommended.yaml
-
-analyzer:
-  exclude: [build/**]
-  language:
-
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index feaa042..275380e 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -5,7 +5,11 @@
 library dart._http;
 
 import 'dart:_internal'
-    show Since, valueOfNonNullableParamWithDefault, HttpStatus;
+    show
+        checkNotNullable,
+        Since,
+        valueOfNonNullableParamWithDefault,
+        HttpStatus;
 import 'dart:async';
 import 'dart:collection'
     show
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index e1c0d5c..5e3c48f 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -2678,6 +2678,30 @@
     }
   }
 
+  bool _isValidToken(String token) {
+    checkNotNullable(token, "token");
+    // from https://www.rfc-editor.org/rfc/rfc2616#page-15
+    //
+    // CTL            = <any US-ASCII control character
+    //                  (octets 0 - 31) and DEL (127)>
+    // separators     = "(" | ")" | "<" | ">" | "@"
+    //                | "," | ";" | ":" | "\" | <">
+    //                | "/" | "[" | "]" | "?" | "="
+    //                | "{" | "}" | SP | HT
+    // token          = 1*<any CHAR except CTLs or separators>
+    const _validChars = r"                                "
+        r" ! #$%&'  *+ -. 0123456789      "
+        r" ABCDEFGHIJKLMNOPQRSTUVWXYZ   ^_"
+        r"`abcdefghijklmnopqrstuvwxyz | ~ ";
+    for (int codeUnit in token.codeUnits) {
+      if (codeUnit >= _validChars.length ||
+          _validChars.codeUnitAt(codeUnit) == 0x20) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   Future<_HttpClientRequest> _openUrl(String method, Uri uri) {
     if (_closing) {
       throw StateError("Client is closed");
@@ -2686,9 +2710,11 @@
     // Ignore any fragments on the request URI.
     uri = uri.removeFragment();
 
-    if (method == null) {
-      throw ArgumentError(method);
+    // from https://www.rfc-editor.org/rfc/rfc2616#page-35
+    if (!_isValidToken(method)) {
+      throw ArgumentError.value(method, "method");
     }
+
     if (method != "CONNECT") {
       if (uri.host.isEmpty) {
         throw ArgumentError("No host specified in URI $uri");
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart
index a8f6c4e..a345e1c 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart
@@ -146,24 +146,13 @@
 int _clockValue = 0;
 
 @patch
-void _reportFlowEvent(
-    String category, String name, int type, int id, String argumentsAsJson) {
-  // TODO.
-}
-
-@patch
-void _reportInstantEvent(String category, String name, String argumentsAsJson) {
-  // TODO.
-}
-
-@patch
 int _getNextTaskId() {
   return 0;
 }
 
 @patch
-void _reportTaskEvent(int taskId, String phase, String category, String name,
-    String argumentsAsJson) {
+void _reportTaskEvent(
+    int taskId, int type, String name, String argumentsAsJson) {
   // TODO.
 }
 
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
index d68ddb7..31ba7d7 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
@@ -123,6 +123,11 @@
   }
 
   @patch
+  static List<dynamic> _createPipe(_Namespace namespace) {
+    throw UnsupportedError("File._createPipe");
+  }
+
+  @patch
   static _linkTarget(_Namespace namespace, Uint8List rawPath) {
     throw UnsupportedError("File._linkTarget");
   }
@@ -541,6 +546,16 @@
   factory ResourceHandle.fromStdout(Stdout stdout) {
     throw UnsupportedError("ResourceHandle.fromStdout constructor");
   }
+
+  @patch
+  factory ResourceHandle.fromReadPipe(ReadPipe pipe) {
+    throw UnsupportedError("ResourceHandle.fromReadPipe constructor");
+  }
+
+  @patch
+  factory ResourceHandle.fromWritePipe(WritePipe pipe) {
+    throw UnsupportedError("ResourceHandle.fromWritePipe constructor");
+  }
 }
 
 @patch
@@ -753,7 +768,7 @@
 @patch
 class _IOService {
   @patch
-  static Future _dispatch(int request, List data) {
+  static Future<Object?> _dispatch(int request, List data) {
     throw UnsupportedError("_IOService._dispatch");
   }
 }
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
index f028cb7..c942721 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
@@ -65,7 +65,7 @@
     'A null value was passed into a non-nullable parameter: $variableName.';
 
 // Run-time null safety assertion per:
-// https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion
+// https://github.com/dart-lang/language/blob/master/accepted/2.12/nnbd/feature-specification.md#automatic-debug-assertion-insertion
 nullFailed(String? fileUri, int? line, int? column, String? variable) {
   if (_nonNullAsserts) {
     throw AssertionErrorImpl(_nullFailedMessage(variable), fileUri, line,
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index 5f8f5af..7d19ca4 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -647,6 +647,9 @@
           JS('', 'throw #', value.value);
         } else {
           assert(state == _IterationMarker.YIELD_STAR);
+          // Casting to avoid the `.iterator` dynamic call would impact the
+          // performance of yield*.
+          // ignore: avoid_dynamic_calls
           Iterator<T> inner = value.value.iterator;
           if (inner is _SyncStarIterator) {
             // The test needs to be 'is _SyncStarIterator<T>' for promotion to
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 442c3cf..2f5de16 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -63,8 +63,7 @@
 
   @patch
   dynamic noSuchMethod(Invocation invocation) {
-    throw new NoSuchMethodError(this, invocation.memberName,
-        invocation.positionalArguments, invocation.namedArguments);
+    throw new NoSuchMethodError.withInvocation(this, invocation);
   }
 
   @patch
@@ -703,13 +702,19 @@
   @patch
   factory NoSuchMethodError.withInvocation(
           Object? receiver, Invocation invocation) =>
-      NoSuchMethodError(receiver, invocation.memberName,
+      NoSuchMethodError._(receiver, invocation.memberName,
           invocation.positionalArguments, invocation.namedArguments);
 
   @patch
   NoSuchMethodError(Object? receiver, Symbol memberName,
       List? positionalArguments, Map<Symbol, dynamic>? namedArguments,
       [List? existingArgumentNames = null])
+      : this._(receiver, memberName, positionalArguments, namedArguments,
+            existingArgumentNames);
+
+  NoSuchMethodError._(Object? receiver, Symbol memberName,
+      List? positionalArguments, Map<Symbol, dynamic>? namedArguments,
+      [List? existingArgumentNames = null])
       : _receiver = receiver,
         _memberName = memberName,
         _arguments = positionalArguments,
@@ -848,7 +853,7 @@
 // Called from kernel generated code.
 _genericNoSuchMethod(receiver, memberName, positionalArguments, namedArguments,
     existingArguments) {
-  return new NoSuchMethodError(
+  return new NoSuchMethodError._(
       receiver, memberName, positionalArguments, namedArguments);
 }
 
@@ -859,7 +864,7 @@
   //
   //     No constructor '$memberName' declared in class '$receiver'.
 
-  return new NoSuchMethodError(
+  return new NoSuchMethodError._(
       receiver, memberName, positionalArguments, namedArguments);
 }
 
@@ -867,7 +872,7 @@
 _unresolvedStaticGetterError(receiver, memberName, positionalArguments,
     namedArguments, existingArguments) {
   // TODO(sra): Generate customized message.
-  return new NoSuchMethodError(
+  return new NoSuchMethodError._(
       receiver, memberName, positionalArguments, namedArguments);
 }
 
@@ -875,7 +880,7 @@
 _unresolvedStaticSetterError(receiver, memberName, positionalArguments,
     namedArguments, existingArguments) {
   // TODO(sra): Generate customized message.
-  return new NoSuchMethodError(
+  return new NoSuchMethodError._(
       receiver, memberName, positionalArguments, namedArguments);
 }
 
@@ -883,7 +888,7 @@
 _unresolvedStaticMethodError(receiver, memberName, positionalArguments,
     namedArguments, existingArguments) {
   // TODO(sra): Generate customized message.
-  return new NoSuchMethodError(
+  return new NoSuchMethodError._(
       receiver, memberName, positionalArguments, namedArguments);
 }
 
@@ -891,7 +896,7 @@
 _unresolvedTopLevelGetterError(receiver, memberName, positionalArguments,
     namedArguments, existingArguments) {
   // TODO(sra): Generate customized message.
-  return new NoSuchMethodError(
+  return new NoSuchMethodError._(
       receiver, memberName, positionalArguments, namedArguments);
 }
 
@@ -899,7 +904,7 @@
 _unresolvedTopLevelSetterError(receiver, memberName, positionalArguments,
     namedArguments, existingArguments) {
   // TODO(sra): Generate customized message.
-  return new NoSuchMethodError(
+  return new NoSuchMethodError._(
       receiver, memberName, positionalArguments, namedArguments);
 }
 
@@ -907,7 +912,7 @@
 _unresolvedTopLevelMethodError(receiver, memberName, positionalArguments,
     namedArguments, existingArguments) {
   // TODO(sra): Generate customized message.
-  return new NoSuchMethodError(
+  return new NoSuchMethodError._(
       receiver, memberName, positionalArguments, namedArguments);
 }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
index d8439cc..5f2698d 100644
--- a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
@@ -69,24 +69,13 @@
 int _clockValue = 0;
 
 @patch
-void _reportFlowEvent(
-    String category, String name, int type, int id, String argumentsAsJson) {
-  // TODO.
-}
-
-@patch
-void _reportInstantEvent(String category, String name, String argumentsAsJson) {
-  // TODO.
-}
-
-@patch
 int _getNextTaskId() {
   return 0;
 }
 
 @patch
-void _reportTaskEvent(int taskId, String phase, String category, String name,
-    String argumentsAsJson) {
+void _reportTaskEvent(
+    int taskId, int type, String name, String argumentsAsJson) {
   // TODO.
 }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index f94f379..e7a6375 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -123,6 +123,11 @@
   }
 
   @patch
+  static List<dynamic> _createPipe(_Namespace namespace) {
+    throw UnsupportedError("File._createPipe");
+  }
+
+  @patch
   static _linkTarget(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("File._linkTarget");
   }
@@ -541,6 +546,16 @@
   factory ResourceHandle.fromStdout(Stdout stdout) {
     throw UnsupportedError("ResourceHandle.fromStdout constructor");
   }
+
+  @patch
+  factory ResourceHandle.fromReadPipe(ReadPipe pipe) {
+    throw UnsupportedError("ResourceHandle.fromReadPipe constructor");
+  }
+
+  @patch
+  factory ResourceHandle.fromWritePipe(WritePipe pipe) {
+    throw UnsupportedError("ResourceHandle.fromWritePipe constructor");
+  }
 }
 
 @patch
diff --git a/sdk/lib/_internal/js_runtime/lib/js_patch.dart b/sdk/lib/_internal/js_runtime/lib/js_patch.dart
index 2568376..e5f614d 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_patch.dart
@@ -328,6 +328,9 @@
   @patch
   E removeAt(int index) {
     _checkIndex(index);
+    // Avoid optimizing. Static type of [callMethod] is dynamic which makes
+    // indexing dynamic.
+    // ignore: avoid_dynamic_calls
     return callMethod('splice', [index, 1])[0];
   }
 
diff --git a/sdk/lib/_internal/js_shared/lib/rti.dart b/sdk/lib/_internal/js_shared/lib/rti.dart
index 8708600..bc6e334 100644
--- a/sdk/lib/_internal/js_shared/lib/rti.dart
+++ b/sdk/lib/_internal/js_shared/lib/rti.dart
@@ -2249,7 +2249,7 @@
 ///     binding(interface("Map", [num,dynamic]), [int, bool])
 ///             0                 3   4           1    2
 ///
-/// Any environment can be reconstructed via a recipe. The above enviroment for
+/// Any environment can be reconstructed via a recipe. The above environment for
 /// method `cast` can be constructed as the ground term
 /// `Map<num,dynamic><int,bool>`, or (somewhat pointlessly) reconstructed via
 /// `0<1,2>` or `Map<3,4><1,2>`. The ability to construct an environment
diff --git a/sdk/lib/_internal/vm/bin/file_patch.dart b/sdk/lib/_internal/vm/bin/file_patch.dart
index a5ac789..db8f000 100644
--- a/sdk/lib/_internal/vm/bin/file_patch.dart
+++ b/sdk/lib/_internal/vm/bin/file_patch.dart
@@ -18,6 +18,9 @@
   external static _createLink(
       _Namespace namespace, Uint8List rawPath, String target);
   @patch
+  @pragma("vm:external-name", "File_CreatePipe")
+  external static List<dynamic> _createPipe(_Namespace namespace);
+  @patch
   @pragma("vm:external-name", "File_LinkTarget")
   external static _linkTarget(_Namespace namespace, Uint8List rawPath);
   @patch
diff --git a/sdk/lib/_internal/vm/bin/io_service_patch.dart b/sdk/lib/_internal/vm/bin/io_service_patch.dart
index cbaf99c..c185f6c 100644
--- a/sdk/lib/_internal/vm/bin/io_service_patch.dart
+++ b/sdk/lib/_internal/vm/bin/io_service_patch.dart
@@ -53,7 +53,7 @@
   static int _id = 0;
 
   @patch
-  static Future _dispatch(int request, List data) {
+  static Future<Object?> _dispatch(int request, List data) {
     int id;
     do {
       id = _getNextId();
diff --git a/sdk/lib/_internal/vm/bin/process_patch.dart b/sdk/lib/_internal/vm/bin/process_patch.dart
index 5033077..7d5b18c 100644
--- a/sdk/lib/_internal/vm/bin/process_patch.dart
+++ b/sdk/lib/_internal/vm/bin/process_patch.dart
@@ -215,7 +215,7 @@
 // implicit constructor.
 class _ProcessImplNativeWrapper extends NativeFieldWrapperClass1 {}
 
-class _ProcessImpl extends _ProcessImplNativeWrapper implements Process {
+class _ProcessImpl extends _ProcessImplNativeWrapper implements _Process {
   static bool connectedResourceHandler = false;
 
   _ProcessImpl(
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index eaf072a..ea232c2 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -506,9 +506,13 @@
         throw createError(response, "Failed host lookup: '$host'");
       }
       return [
-        for (var result in response.skip(1))
-          _InternetAddress(InternetAddressType._from(result[0]), result[1],
-              host, result[2], result[3])
+        for (List<Object?> result in (response as List).skip(1))
+          _InternetAddress(
+              InternetAddressType._from(result[0] as int),
+              result[1] as String,
+              host,
+              result[2] as Uint8List,
+              result[3] as int)
       ];
     });
   }
@@ -530,7 +534,7 @@
       if (isErrorResponse(response)) {
         throw createError(response, "Failed reverse host lookup", addr);
       } else {
-        return (addr as _InternetAddress)._cloneWithNewHost(response);
+        return addr._cloneWithNewHost(response as String);
       }
     });
   }
@@ -544,16 +548,19 @@
       if (isErrorResponse(response)) {
         throw createError(response, "Failed listing interfaces");
       } else {
-        var map = response.skip(1).fold(new Map<String, NetworkInterface>(),
-            (map, result) {
-          var type = InternetAddressType._from(result[0]);
-          var name = result[3];
-          var index = result[4];
-          var address = _InternetAddress(type, result[1], "", result[2]);
+        var map = (response as List)
+            .skip(1)
+            .fold(new Map<String, NetworkInterface>(), (map, result) {
+          List<Object?> resultList = result as List<Object?>;
+          var type = InternetAddressType._from(resultList[0] as int);
+          var name = resultList[3] as String;
+          var index = resultList[4] as int;
+          var address = _InternetAddress(
+              type, resultList[1] as String, "", resultList[2] as Uint8List);
           if (!includeLinkLocal && address.isLinkLocal) return map;
           if (!includeLoopback && address.isLoopback) return map;
           map.putIfAbsent(name, () => new _NetworkInterface(name, index));
-          map[name].addresses.add(address);
+          (map[name] as _NetworkInterface).addresses.add(address);
           return map;
         });
         return map.values.toList();
@@ -749,7 +756,8 @@
                 "Address family not supported by protocol family, "
                 // ...and then add some details.
                 "sourceAddress.type must be ${InternetAddressType.unix} but was "
-                "${source.type}", address: address);
+                "${source.type}",
+                address: address);
           }
           connectionResult = socket.nativeCreateUnixDomainBindConnect(
               address.address, source.address, _Namespace._namespace);
@@ -1541,23 +1549,23 @@
   static createError(error, String message,
       [InternetAddress? address, int? port]) {
     if (error is OSError) {
-      return new SocketException(message,
+      return SocketException(message,
           osError: error, address: address, port: port);
     } else if (error is List) {
       assert(isErrorResponse(error));
       switch (error[0]) {
         case _illegalArgumentResponse:
-          return new ArgumentError();
+          return ArgumentError();
         case _osErrorResponse:
-          return new SocketException(message,
-              osError: new OSError(error[2], error[1]),
+          return SocketException(message,
+              osError: OSError(error[2], error[1]),
               address: address,
               port: port);
         default:
-          return new Exception("Unknown error");
+          return AssertionError("Unknown error");
       }
     } else {
-      return new SocketException(message, address: address, port: port);
+      return SocketException(message, address: address, port: port);
     }
   }
 
@@ -2585,23 +2593,49 @@
   factory ResourceHandle.fromStdout(Stdout stdout) {
     return _ResourceHandleImpl(stdout._fd);
   }
+
+  factory ResourceHandle.fromReadPipe(ReadPipe pipe) {
+    _ReadPipe rp = pipe as _ReadPipe;
+    return ResourceHandle.fromFile(rp._openedFile!);
+  }
+
+  factory ResourceHandle.fromWritePipe(WritePipe pipe) {
+    _WritePipe wp = pipe as _WritePipe;
+    return ResourceHandle.fromFile(wp._file);
+  }
 }
 
 @pragma("vm:entry-point")
 class _ResourceHandleImpl implements ResourceHandle {
+  bool _toMethodCalled = false;
+
   @pragma("vm:entry-point")
   int _handle; // file descriptor on linux
   @pragma("vm:entry-point")
   _ResourceHandleImpl(this._handle);
 
-  @pragma("vm:external-name", "ResourceHandleImpl_toFile")
-  external RandomAccessFile toFile();
-  @pragma("vm:external-name", "ResourceHandleImpl_toSocket")
-  external Socket toSocket();
-  @pragma("vm:external-name", "ResourceHandleImpl_toRawSocket")
-  external List<dynamic> _toRawSocket();
+  RandomAccessFile toFile() {
+    if (_toMethodCalled) {
+      throw StateError('Resource handle has already been used.');
+    }
+    _toMethodCalled = true;
+    return _toFile();
+  }
+
+  RawDatagramSocket toRawDatagramSocket() {
+    if (_toMethodCalled) {
+      throw StateError('Resource handle has already been used.');
+    }
+    _toMethodCalled = true;
+    return _toRawDatagramSocket();
+  }
 
   RawSocket toRawSocket() {
+    if (_toMethodCalled) {
+      throw StateError('Resource handle has already been used.');
+    }
+    _toMethodCalled = true;
+
     List<dynamic> list = _toRawSocket();
     InternetAddressType type = InternetAddressType._from(list[0] as int);
     String hostname = list[1] as String;
@@ -2615,8 +2649,30 @@
     return _RawSocket(nativeSocket);
   }
 
+  Socket toSocket() {
+    if (_toMethodCalled) {
+      throw StateError('Resource handle has already been used.');
+    }
+    _toMethodCalled = true;
+    return _toSocket();
+  }
+
+  _ReadPipe toReadPipe() {
+    return _ReadPipe(toFile());
+  }
+
+  _WritePipe toWritePipe() {
+    return _WritePipe(toFile());
+  }
+
+  @pragma("vm:external-name", "ResourceHandleImpl_toFile")
+  external RandomAccessFile _toFile();
+  @pragma("vm:external-name", "ResourceHandleImpl_toSocket")
+  external Socket _toSocket();
+  @pragma("vm:external-name", "ResourceHandleImpl_toRawSocket")
+  external List<dynamic> _toRawSocket();
   @pragma("vm:external-name", "ResourceHandleImpl_toRawDatagramSocket")
-  external RawDatagramSocket toRawDatagramSocket();
+  external RawDatagramSocket _toRawDatagramSocket();
 
   @pragma("vm:entry-point")
   static final _ResourceHandleImpl _sentinel = _ResourceHandleImpl(-1);
diff --git a/sdk/lib/_internal/vm/lib/bigint_patch.dart b/sdk/lib/_internal/vm/lib/bigint_patch.dart
index affdfeb..79482eb 100644
--- a/sdk/lib/_internal/vm/lib/bigint_patch.dart
+++ b/sdk/lib/_internal/vm/lib/bigint_patch.dart
@@ -4,10 +4,6 @@
 
 // part of dart.core;
 
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
 /*
  * Copyright (c) 2003-2005  Tom Wu
  * Copyright (c) 2012 Adam Singer (adam@solvr.io)
diff --git a/sdk/lib/_internal/vm/lib/compact_hash.dart b/sdk/lib/_internal/vm/lib/compact_hash.dart
index 16d85b2..b5566c6 100644
--- a/sdk/lib/_internal/vm/lib/compact_hash.dart
+++ b/sdk/lib/_internal/vm/lib/compact_hash.dart
@@ -18,20 +18,15 @@
 
 // Common interface for [_HashFieldBase] and [_HashVMBase].
 abstract class _HashAbstractBase {
-  Uint32List get _index;
-  void set _index(Uint32List value);
+  abstract Uint32List _index;
 
-  int get _hashMask;
-  void set _hashMask(int value);
+  abstract int _hashMask;
 
-  List get _data;
-  void set _data(List value);
+  abstract List<Object?> _data;
 
-  int get _usedData;
-  void set _usedData(int value);
+  abstract int _usedData;
 
-  int get _deletedKeys;
-  void set _deletedKeys(int value);
+  abstract int _deletedKeys;
 }
 
 abstract class _HashAbstractImmutableBase extends _HashAbstractBase {
@@ -55,7 +50,7 @@
   // Fixed-length list of keys (set) or key/value at even/odd indices (map).
   //
   // Can be either a mutable or immutable list.
-  List _data = _uninitializedData;
+  List<Object?> _data = _uninitializedData;
 
   // Length of _data that is used (i.e., keys + values for a map).
   int _usedData = 0;
@@ -95,11 +90,11 @@
   @pragma("vm:exact-result-type", "dart:core#_List")
   @pragma("vm:prefer-inline")
   @pragma("vm:external-name", "LinkedHashBase_getData")
-  external List get _data;
+  external List<Object?> get _data;
   @pragma("vm:recognized", "other")
   @pragma("vm:prefer-inline")
   @pragma("vm:external-name", "LinkedHashBase_setData")
-  external void set _data(List value);
+  external void set _data(List<Object?> value);
 
   @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
@@ -129,7 +124,7 @@
   @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", "dart:core#_ImmutableList")
   @pragma("vm:prefer-inline")
-  List get _data native "ImmutableLinkedHashBase_getData";
+  List<Object?> get _data native "ImmutableLinkedHashBase_getData";
 
   // The index is nullable rather than not nullable.
   @pragma("vm:recognized", "other")
@@ -195,16 +190,16 @@
   static int _nextProbe(int i, int sizeMask) => (i + 1) & sizeMask;
 
   // A self-loop is used to mark a deleted key or value.
-  static bool _isDeleted(List data, Object? keyOrValue) =>
+  static bool _isDeleted(List<Object?> data, Object? keyOrValue) =>
       identical(keyOrValue, data);
-  static void _setDeletedAt(List data, int d) {
+  static void _setDeletedAt(List<Object?> data, int d) {
     data[d] = data;
   }
 
   // Concurrent modification detection relies on this checksum monotonically
   // increasing between reallocations of _data.
   int get _checkSum => _usedData + _deletedKeys;
-  bool _isModifiedSince(List oldData, int oldCheckSum) =>
+  bool _isModifiedSince(List<Object?> oldData, int oldCheckSum) =>
       !identical(_data, oldData) || (_checkSum != oldCheckSum);
 
   int get length;
@@ -224,7 +219,7 @@
     assert(!identical(other._data, _uninitializedData));
     _index = Uint32List.fromList(other._index);
     _hashMask = other._hashMask;
-    _data = List.of(other._data, growable: false);
+    _data = List<Object?>.of(other._data, growable: false);
     _usedData = other._usedData;
     _deletedKeys = other._deletedKeys;
     return true;
@@ -232,24 +227,24 @@
 }
 
 abstract class _EqualsAndHashCode {
-  int _hashCode(e);
-  bool _equals(e1, e2);
+  int _hashCode(Object? e);
+  bool _equals(Object? e1, Object? e2);
 }
 
 mixin _OperatorEqualsAndHashCode implements _EqualsAndHashCode {
-  int _hashCode(e) => e.hashCode;
-  bool _equals(e1, e2) => e1 == e2;
+  int _hashCode(Object? e) => e.hashCode;
+  bool _equals(Object? e1, Object? e2) => e1 == e2;
 }
 
 mixin _IdenticalAndIdentityHashCode implements _EqualsAndHashCode {
-  int _hashCode(e) => identityHashCode(e);
-  bool _equals(e1, e2) => identical(e1, e2);
+  int _hashCode(Object? e) => identityHashCode(e);
+  bool _equals(Object? e1, Object? e2) => identical(e1, e2);
 }
 
 mixin _OperatorEqualsAndCanonicalHashCode implements _EqualsAndHashCode {
   static final int cidSymbol = ClassID.getID(#a);
 
-  int _hashCode(e) {
+  int _hashCode(Object? e) {
     final int cid = ClassID.getID(e);
     if (cid < ClassID.numPredefinedCids || cid == cidSymbol) {
       return e.hashCode;
@@ -257,15 +252,17 @@
     return identityHashCode(e);
   }
 
-  bool _equals(e1, e2) => e1 == e2;
+  bool _equals(Object? e1, Object? e2) => e1 == e2;
 }
 
-mixin _CustomEqualsAndHashCode implements _EqualsAndHashCode {
-  dynamic get _hasher;
-  dynamic get _equality;
+mixin _CustomEqualsAndHashCode<K> implements _EqualsAndHashCode {
+  int Function(K) get _hasher;
+  bool Function(K, K) get _equality;
 
-  int _hashCode(e) => _hasher(e);
-  bool _equals(e1, e2) => _equality(e1, e2);
+  // For backwards compatibility, we must allow any key here that is accepted
+  // dynamically by the [_hasher] and [_equality] functions.
+  int _hashCode(Object? e) => (_hasher as Function)(e);
+  bool _equals(Object? e1, Object? e2) => (_equality as Function)(e1, e2);
 }
 
 final _uninitializedIndex = new Uint32List(_HashBase._UNINITIALIZED_INDEX_SIZE);
@@ -344,7 +341,7 @@
     assert(_hashMask == hashMask);
 
     for (int j = 0; j < _usedData; j += 2) {
-      final key = _data[j];
+      final key = _data[j] as K;
 
       final fullHash = _hashCode(key);
       final hashPattern = _HashBase._hashPattern(fullHash, hashMask, size);
@@ -366,9 +363,9 @@
   }
 
   Iterable<K> get keys =>
-      new _CompactIterableImmutable<K>(this, _data, _usedData, -2, 2);
+      _CompactIterableImmutable<K>(this, _data, _usedData, -2, 2);
   Iterable<V> get values =>
-      new _CompactIterableImmutable<V>(this, _data, _usedData, -1, 2);
+      _CompactIterableImmutable<V>(this, _data, _usedData, -1, 2);
 }
 
 // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
@@ -410,7 +407,7 @@
     }
   }
 
-  // Allocate new _index and _data, and optionally copy existing contents.
+  // Allocate _index and _data, and optionally copy existing contents.
   void _init(int size, int hashMask, List? oldData, int oldUsed) {
     if (size < _HashBase._INITIAL_INDEX_SIZE) {
       size = _HashBase._INITIAL_INDEX_SIZE;
@@ -446,7 +443,7 @@
     for (int i = 0; i < tmpUsed; i += 2) {
       final key = _data[i];
       if (!_HashBase._isDeleted(_data, key)) {
-        this[key] = _data[i + 1];
+        this[key as K] = _data[i + 1] as V;
       }
     }
   }
@@ -519,7 +516,7 @@
     final int d =
         _findValueOrInsertPoint(key, fullHash, hashPattern, size, _index);
     if (d > 0) {
-      return _data[d];
+      return _data[d] as V;
     }
     // 'ifAbsent' is allowed to modify the map.
     List oldData = _data;
@@ -550,7 +547,7 @@
           if (_equals(key, _data[d])) {
             _index[i] = _HashBase._DELETED_PAIR;
             _HashBase._setDeletedAt(_data, d);
-            V value = _data[d + 1];
+            V value = _data[d + 1] as V;
             _HashBase._setDeletedAt(_data, d + 1);
             ++_deletedKeys;
             return value;
@@ -621,10 +618,8 @@
     }
   }
 
-  Iterable<K> get keys =>
-      new _CompactIterable<K>(this, _data, _usedData, -2, 2);
-  Iterable<V> get values =>
-      new _CompactIterable<V>(this, _data, _usedData, -1, 2);
+  Iterable<K> get keys => _CompactIterable<K>(this, _data, _usedData, -2, 2);
+  Iterable<V> get values => _CompactIterable<V>(this, _data, _usedData, -1, 2);
 }
 
 class _CompactLinkedIdentityHashMap<K, V> extends _HashFieldBase
@@ -649,12 +644,12 @@
     with
         MapMixin<K, V>,
         _HashBase,
-        _CustomEqualsAndHashCode,
+        _CustomEqualsAndHashCode<K>,
         _LinkedHashMapMixin<K, V>
     implements LinkedHashMap<K, V> {
-  final dynamic _equality;
-  final dynamic _hasher;
-  final dynamic _validKey;
+  final bool Function(K, K) _equality;
+  final int Function(K) _hasher;
+  final bool Function(Object?) _validKey;
 
   bool containsKey(Object? o) => _validKey(o) ? super.containsKey(o) : false;
   V? operator [](Object? o) => _validKey(o) ? super[o] : null;
@@ -663,8 +658,9 @@
   @pragma("wasm:entry-point")
   void operator []=(K key, V value);
 
-  _CompactLinkedCustomHashMap(this._equality, this._hasher, validKey)
-      : _validKey = (validKey != null) ? validKey : new _TypeTest<K>().test;
+  _CompactLinkedCustomHashMap(
+      this._equality, this._hasher, bool Function(Object?)? validKey)
+      : _validKey = validKey ?? _TypeTest<K>().test;
 }
 
 // Iterates through _data[_offset + _step], _data[_offset + 2*_step], ...
@@ -681,7 +677,7 @@
       this._table, this._data, this._len, this._offset, this._step);
 
   Iterator<E> get iterator =>
-      new _CompactIterator<E>(_table, _data, _len, _offset, _step);
+      _CompactIterator<E>(_table, _data, _len, _offset, _step);
 
   int get length => _table.length;
   bool get isEmpty => length == 0;
@@ -737,7 +733,7 @@
       this._table, this._data, this._len, this._offset, this._step);
 
   Iterator<E> get iterator =>
-      new _CompactIteratorImmutable<E>(_table, _data, _len, _offset, _step);
+      _CompactIteratorImmutable<E>(_table, _data, _len, _offset, _step);
 
   int get length => _table.length;
   bool get isEmpty => length == 0;
@@ -928,7 +924,7 @@
   }
 
   Iterator<E> get iterator =>
-      new _CompactIterator<E>(this, _data, _usedData, -1, 1);
+      _CompactIterator<E>(this, _data, _usedData, -1, 1);
 
   // This method is called by [_rehashObjects] (see above).
   void _regenerateIndex() {
@@ -943,14 +939,14 @@
 
 // Set implementation, analogous to _InternalLinkedHashMap.
 @pragma('vm:entry-point')
-class _CompactLinkedHashSet<E> extends _HashVMBase
+class _InternalLinkedHashSet<E> extends _HashVMBase
     with
         SetMixin<E>,
         _HashBase,
         _OperatorEqualsAndHashCode,
         _LinkedHashSetMixin<E>
     implements LinkedHashSet<E> {
-  _CompactLinkedHashSet() {
+  _InternalLinkedHashSet() {
     _index = _uninitializedIndex;
     _hashMask = _HashBase._UNINITIALIZED_HASH_MASK;
     _data = _uninitializedData;
@@ -960,16 +956,16 @@
 
   Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newEmpty);
 
-  static Set<R> _newEmpty<R>() => new _CompactLinkedHashSet<R>();
+  static Set<R> _newEmpty<R>() => _InternalLinkedHashSet<R>();
 
   // Returns a set of the same type, although this
   // is not required by the spec. (For instance, always using an identity set
   // would be technically correct, albeit surprising.)
-  Set<E> toSet() => new _CompactLinkedHashSet<E>()..addAll(this);
+  Set<E> toSet() => _InternalLinkedHashSet<E>()..addAll(this);
 
   void addAll(Iterable<E> other) {
-    if (other is _CompactLinkedHashSet) {
-      final otherBase = other as _CompactLinkedHashSet;
+    if (other is _InternalLinkedHashSet) {
+      final otherBase = other as _InternalLinkedHashSet;
       // If this set is empty we might be able to block-copy from [other].
       if (isEmpty && _quickCopy(otherBase)) return;
       // TODO(48143): Pre-grow capacity if it will reduce rehashing.
@@ -979,7 +975,7 @@
 }
 
 @pragma("vm:entry-point")
-class _CompactImmutableLinkedHashSet<E> extends _HashVMImmutableBase
+class _InternalImmutableLinkedHashSet<E> extends _HashVMImmutableBase
     with
         SetMixin<E>,
         _HashBase,
@@ -988,9 +984,16 @@
         _UnmodifiableSetMixin<E>,
         _ImmutableLinkedHashSetMixin<E>
     implements LinkedHashSet<E> {
-  factory _CompactImmutableLinkedHashSet._uninstantiable() {
+  factory _InternalImmutableLinkedHashSet._uninstantiable() {
     throw new UnsupportedError("ImmutableSet can only be allocated by the VM");
   }
+
+  Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newEmpty);
+
+  static Set<R> _newEmpty<R>() => _InternalLinkedHashSet<R>();
+
+  // Returns a mutable set.
+  Set<E> toSet() => _InternalLinkedHashSet<E>()..addAll(this);
 }
 
 mixin _ImmutableLinkedHashSetMixin<E>
@@ -1050,15 +1053,8 @@
     _index = index;
   }
 
-  Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newEmpty);
-
-  static Set<R> _newEmpty<R>() => new _CompactLinkedHashSet<R>();
-
-  // Returns a mutable set.
-  Set<E> toSet() => new _CompactLinkedHashSet<E>()..addAll(this);
-
   Iterator<E> get iterator =>
-      new _CompactIteratorImmutable<E>(this, _data, _usedData, -1, 1);
+      _CompactIteratorImmutable<E>(this, _data, _usedData, -1, 1);
 }
 
 class _CompactLinkedIdentityHashSet<E> extends _HashFieldBase
@@ -1068,17 +1064,16 @@
         _IdenticalAndIdentityHashCode,
         _LinkedHashSetMixin<E>
     implements LinkedHashSet<E> {
-  Set<E> toSet() => new _CompactLinkedIdentityHashSet<E>()..addAll(this);
+  Set<E> toSet() => _CompactLinkedIdentityHashSet<E>()..addAll(this);
 
-  static Set<R> _newEmpty<R>() => new _CompactLinkedIdentityHashSet<R>();
+  static Set<R> _newEmpty<R>() => _CompactLinkedIdentityHashSet<R>();
 
   Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newEmpty);
 
   void addAll(Iterable<E> other) {
-    if (other is _CompactLinkedIdentityHashSet) {
-      final otherBase = other as _CompactLinkedIdentityHashSet;
+    if (other is _CompactLinkedIdentityHashSet<E>) {
       // If this set is empty we might be able to block-copy from [other].
-      if (isEmpty && _quickCopy(otherBase)) return;
+      if (isEmpty && _quickCopy(other)) return;
       // TODO(48143): Pre-grow capacity if it will reduce rehashing.
     }
     super.addAll(other);
@@ -1089,12 +1084,12 @@
     with
         SetMixin<E>,
         _HashBase,
-        _CustomEqualsAndHashCode,
+        _CustomEqualsAndHashCode<E>,
         _LinkedHashSetMixin<E>
     implements LinkedHashSet<E> {
-  final dynamic _equality;
-  final dynamic _hasher;
-  final dynamic _validKey;
+  final bool Function(E, E) _equality;
+  final int Function(E) _hasher;
+  final bool Function(Object?) _validKey;
 
   bool contains(Object? o) => _validKey(o) ? super.contains(o) : false;
   E? lookup(Object? o) => _validKey(o) ? super.lookup(o) : null;
@@ -1103,11 +1098,12 @@
   @pragma("wasm:entry-point")
   bool add(E key);
 
-  _CompactLinkedCustomHashSet(this._equality, this._hasher, validKey)
-      : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
+  _CompactLinkedCustomHashSet(
+      this._equality, this._hasher, bool Function(Object?)? validKey)
+      : _validKey = validKey ?? _TypeTest<E>().test;
 
   Set<R> cast<R>() => Set.castFrom<E, R>(this);
   Set<E> toSet() =>
-      new _CompactLinkedCustomHashSet<E>(_equality, _hasher, _validKey)
+      _CompactLinkedCustomHashSet<E>(_equality, _hasher, _validKey)
         ..addAll(this);
 }
diff --git a/sdk/lib/_internal/vm/lib/core_patch.dart b/sdk/lib/_internal/vm/lib/core_patch.dart
index c7ad0af..674993e 100644
--- a/sdk/lib/_internal/vm/lib/core_patch.dart
+++ b/sdk/lib/_internal/vm/lib/core_patch.dart
@@ -27,6 +27,7 @@
         Lists,
         POWERS_OF_TEN,
         SubListIterable,
+        SystemHash,
         UnmodifiableListMixin,
         has63BitSmis,
         makeFixedListUnmodifiable,
diff --git a/sdk/lib/_internal/vm/lib/hash_factories.dart b/sdk/lib/_internal/vm/lib/hash_factories.dart
index 01558af..59bdb0f 100644
--- a/sdk/lib/_internal/vm/lib/hash_factories.dart
+++ b/sdk/lib/_internal/vm/lib/hash_factories.dart
@@ -46,7 +46,7 @@
     if (isValidKey == null) {
       if (hashCode == null) {
         if (equals == null) {
-          return new _CompactLinkedHashSet<E>();
+          return new _InternalLinkedHashSet<E>();
         }
         hashCode = _defaultHashCode;
       } else {
diff --git a/sdk/lib/_internal/vm/lib/object_patch.dart b/sdk/lib/_internal/vm/lib/object_patch.dart
index d0398a2..5468b68 100644
--- a/sdk/lib/_internal/vm/lib/object_patch.dart
+++ b/sdk/lib/_internal/vm/lib/object_patch.dart
@@ -83,3 +83,92 @@
 @pragma("vm:entry-point", "call")
 dynamic _objectNoSuchMethod(Object? obj, Invocation invocation) =>
     obj.noSuchMethod(invocation);
+
+// Base class for record instances.
+// TODO(dartbug.com/49719): create a separate patch file for this class.
+@pragma("vm:entry-point")
+class _Record {
+  factory _Record._uninstantiable() {
+    throw "Unreachable";
+  }
+
+  // Do not inline to avoid mixing _fieldAt with
+  // record field accesses.
+  @pragma("vm:never-inline")
+  bool operator ==(Object other) {
+    if (identical(this, other)) {
+      return true;
+    }
+
+    if (other is! _Record) {
+      return false;
+    }
+
+    _Record otherRec = unsafeCast<_Record>(other);
+    final int numFields = _numFields;
+    if (numFields != otherRec._numFields ||
+        !identical(_fieldNames, otherRec._fieldNames)) {
+      return false;
+    }
+
+    for (int i = 0; i < numFields; ++i) {
+      if (_fieldAt(i) != otherRec._fieldAt(i)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  // Do not inline to avoid mixing _fieldAt with
+  // record field accesses.
+  @pragma("vm:never-inline")
+  int get hashCode {
+    final int numFields = _numFields;
+    int hash = numFields;
+    hash = SystemHash.combine(hash, identityHashCode(_fieldNames));
+    for (int i = 0; i < numFields; ++i) {
+      hash = SystemHash.combine(hash, _fieldAt(i).hashCode);
+    }
+    return SystemHash.finish(hash);
+  }
+
+  // Do not inline to avoid mixing _fieldAt with
+  // record field accesses.
+  @pragma("vm:never-inline")
+  String toString() {
+    StringBuffer buffer = StringBuffer("(");
+    final int numFields = _numFields;
+    final _List fieldNames = _fieldNames;
+    final int numPositionalFields = numFields - fieldNames.length;
+    for (int i = 0; i < numFields; ++i) {
+      if (i != 0) {
+        buffer.write(", ");
+      }
+      if (i >= numPositionalFields) {
+        buffer.write(unsafeCast<String>(fieldNames[i - numPositionalFields]));
+        buffer.write(": ");
+      }
+      buffer.write(_fieldAt(i).toString());
+    }
+    buffer.write(")");
+    return buffer.toString();
+  }
+
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  external int get _numFields;
+
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  external _List get _fieldNames;
+
+  // Currently compiler does not take into account aliasing
+  // between access to record fields via _fieldAt and
+  // via record.foo / record.$n.
+  // So this method should only be used in methods
+  // which only access record fields with _fieldAt and
+  // annotated with @pragma("vm:never-inline").
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  external Object? _fieldAt(int index);
+}
diff --git a/sdk/lib/_internal/vm/lib/timeline.dart b/sdk/lib/_internal/vm/lib/timeline.dart
index d65d975..f013753 100644
--- a/sdk/lib/_internal/vm/lib/timeline.dart
+++ b/sdk/lib/_internal/vm/lib/timeline.dart
@@ -18,15 +18,5 @@
 
 @patch
 @pragma("vm:external-name", "Timeline_reportTaskEvent")
-external void _reportTaskEvent(int taskId, String phase, String category,
-    String name, String argumentsAsJson);
-
-@patch
-@pragma("vm:external-name", "Timeline_reportFlowEvent")
-external void _reportFlowEvent(
-    String category, String name, int type, int id, String argumentsAsJson);
-
-@patch
-@pragma("vm:external-name", "Timeline_reportInstantEvent")
-external void _reportInstantEvent(
-    String category, String name, String argumentsAsJson);
+external void _reportTaskEvent(
+    int taskId, int type, String name, String argumentsAsJson);
diff --git a/sdk/lib/_internal/vm/lib/type_patch.dart b/sdk/lib/_internal/vm/lib/type_patch.dart
index 6a0a21b..66cffa6 100644
--- a/sdk/lib/_internal/vm/lib/type_patch.dart
+++ b/sdk/lib/_internal/vm/lib/type_patch.dart
@@ -6,13 +6,21 @@
 
 // These Dart classes correspond to the VM internal implementation classes.
 
-// Equivalent of AbstractTypeLayout.
 abstract class _AbstractType implements Type {
   @pragma("vm:external-name", "AbstractType_toString")
   external String toString();
+
+  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
+  @pragma("vm:external-name", "AbstractType_getHashCode")
+  external int get hashCode;
+
+  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:exact-result-type", bool)
+  @pragma("vm:external-name", "AbstractType_equality")
+  external bool operator ==(other);
 }
 
-// Equivalent of TypeLayout.
 @pragma("vm:entry-point")
 class _Type extends _AbstractType {
   factory _Type._uninstantiable() {
@@ -30,25 +38,20 @@
   external bool operator ==(other);
 }
 
-// Equivalent of FunctionTypeLayout.
 @pragma("vm:entry-point")
 class _FunctionType extends _AbstractType {
   factory _FunctionType._uninstantiable() {
     throw "Unreachable";
   }
-
-  @pragma("vm:recognized", "asm-intrinsic")
-  @pragma("vm:exact-result-type", "dart:core#_Smi")
-  @pragma("vm:external-name", "FunctionType_getHashCode")
-  external int get hashCode;
-
-  @pragma("vm:recognized", "asm-intrinsic")
-  @pragma("vm:exact-result-type", bool)
-  @pragma("vm:external-name", "FunctionType_equality")
-  external bool operator ==(other);
 }
 
-// Equivalent of TypeRefLayout.
+@pragma("vm:entry-point")
+class _RecordType extends _AbstractType {
+  factory _RecordType._uninstantiable() {
+    throw "Unreachable";
+  }
+}
+
 @pragma("vm:entry-point")
 class _TypeRef extends _AbstractType {
   factory _TypeRef._uninstantiable() {
@@ -56,7 +59,6 @@
   }
 }
 
-// Equivalent of TypeParameterLayout.
 @pragma("vm:entry-point")
 class _TypeParameter extends _AbstractType {
   factory _TypeParameter._uninstantiable() {
diff --git a/sdk/lib/_internal/wasm/lib/async_patch.dart b/sdk/lib/_internal/wasm/lib/async_patch.dart
index e9ed97e..b9e3dfb 100644
--- a/sdk/lib/_internal/wasm/lib/async_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/async_patch.dart
@@ -53,20 +53,18 @@
 import 'dart:wasm';
 
 @pragma("wasm:entry-point")
-Future<T> _asyncHelper<T>(WasmEqRef args) {
+Future<T> _asyncHelper<T>(WasmDataRef args) {
   Completer<T> completer = Completer();
   _callAsyncBridge(args, completer);
   return completer.future;
 }
 
 @pragma("wasm:import", "dart2wasm.callAsyncBridge")
-external void _callAsyncBridge(WasmEqRef args, Completer<Object?> completer);
+external void _callAsyncBridge(WasmDataRef args, Completer<Object?> completer);
 
 @pragma("wasm:export", "\$asyncBridge")
 WasmAnyRef? _asyncBridge(
-    WasmExternRef? stack, WasmExternRef? argsRef, WasmExternRef? completerRef) {
-  WasmDataRef args = unsafeCastOpaque(argsRef!.internalize());
-  Completer<Object?> completer = unsafeCastOpaque(completerRef!.internalize());
+    WasmExternRef? stack, WasmDataRef args, Completer<Object?> completer) {
   try {
     Object? result = _asyncBridge2(args, stack);
     completer.complete(result);
@@ -87,9 +85,7 @@
 @pragma("wasm:entry-point")
 Object? _awaitHelper(Object? operand, WasmExternRef? stack) {
   if (operand is! Future) return operand;
-  WasmExternRef futureRef = WasmAnyRef.fromObject(operand).externalize();
-  Object? result =
-      unsafeCastOpaque(_futurePromise(stack, futureRef).internalize());
+  Object? result = _futurePromise(stack, operand);
   if (result is _FutureError) {
     // TODO(askesc): Combine stack traces
     throw result.exception;
@@ -98,11 +94,10 @@
 }
 
 @pragma("wasm:import", "dart2wasm.futurePromise")
-external WasmExternRef? _futurePromise(
-    WasmExternRef? stack, WasmExternRef? future);
+external Object? _futurePromise(WasmExternRef? stack, Future<Object?> future);
 
 @pragma("wasm:export", "\$awaitCallback")
-void _awaitCallback(Future<Object?> future, WasmAnyRef resolve) {
+void _awaitCallback(Future<Object?> future, WasmExternRef? resolve) {
   future.then((value) {
     _callResolve(resolve, value);
   }, onError: (exception, stackTrace) {
@@ -111,4 +106,4 @@
 }
 
 @pragma("wasm:import", "dart2wasm.callResolve")
-external void _callResolve(WasmAnyRef resolve, Object? result);
+external void _callResolve(WasmExternRef? resolve, Object? result);
diff --git a/sdk/lib/_internal/wasm/lib/developer.dart b/sdk/lib/_internal/wasm/lib/developer.dart
index e93f2b4..15384c2 100644
--- a/sdk/lib/_internal/wasm/lib/developer.dart
+++ b/sdk/lib/_internal/wasm/lib/developer.dart
@@ -52,13 +52,5 @@
 int _getNextTaskId() => 0;
 
 @patch
-void _reportTaskEvent(int taskId, String phase, String category, String name,
-    String argumentsAsJson) {}
-
-@patch
-void _reportFlowEvent(
-    String category, String name, int type, int id, String argumentsAsJson) {}
-
-@patch
-void _reportInstantEvent(
-    String category, String name, String argumentsAsJson) {}
+void _reportTaskEvent(
+    int taskId, int type, String name, String argumentsAsJson) {}
diff --git a/sdk/lib/_internal/wasm/lib/errors_patch.dart b/sdk/lib/_internal/wasm/lib/errors_patch.dart
index f1542bd..10d8751 100644
--- a/sdk/lib/_internal/wasm/lib/errors_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/errors_patch.dart
@@ -158,3 +158,10 @@
 
   toString() => "Error: field '$_name' is already initialized.";
 }
+
+@patch
+class StateError {
+  static _throwNew(String msg) {
+    throw new StateError(msg);
+  }
+}
diff --git a/sdk/lib/_internal/wasm/lib/hash_factories.dart b/sdk/lib/_internal/wasm/lib/hash_factories.dart
index c0f6160..8c9d6ab 100644
--- a/sdk/lib/_internal/wasm/lib/hash_factories.dart
+++ b/sdk/lib/_internal/wasm/lib/hash_factories.dart
@@ -89,4 +89,11 @@
     throw new UnsupportedError(
         "Immutable sets can only be instantiated via constants");
   }
+
+  Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newEmpty);
+
+  static Set<R> _newEmpty<R>() => LinkedHashSet<R>._default();
+
+  // Returns a mutable set.
+  Set<E> toSet() => LinkedHashSet<E>._default()..addAll(this);
 }
diff --git a/sdk/lib/_internal/wasm/lib/internal_patch.dart b/sdk/lib/_internal/wasm/lib/internal_patch.dart
index a2fd239..64b97c2 100644
--- a/sdk/lib/_internal/wasm/lib/internal_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/internal_patch.dart
@@ -4,6 +4,10 @@
 
 import "dart:typed_data" show Uint8List;
 
+// Compilation to Wasm is always fully null safe.
+@patch
+bool typeAcceptsNull<T>() => null is T;
+
 /// The returned string is a [_OneByteString] with uninitialized content.
 external String allocateOneByteString(int length);
 
diff --git a/sdk/lib/_internal/wasm/lib/io_patch.dart b/sdk/lib/_internal/wasm/lib/io_patch.dart
index 98697a1..1042190 100644
--- a/sdk/lib/_internal/wasm/lib/io_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/io_patch.dart
@@ -122,6 +122,11 @@
   }
 
   @patch
+  static List<dynamic> _createPipe(_Namespace namespace) {
+    throw UnsupportedError("File._createPipe");
+  }
+
+  @patch
   static _linkTarget(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("File._linkTarget");
   }
@@ -540,6 +545,16 @@
   factory ResourceHandle.fromStdout(Stdout stdout) {
     throw UnsupportedError("ResourceHandle.fromStdout constructor");
   }
+
+  @patch
+  factory ResourceHandle.fromReadPipe(ReadPipe pipe) {
+    throw UnsupportedError("ResourceHandle.fromReadPipe constructor");
+  }
+
+  @patch
+  factory ResourceHandle.fromWritePipe(WritePipe pipe) {
+    throw UnsupportedError("ResourceHandle.fromWritePipe constructor");
+  }
 }
 
 @patch
@@ -752,7 +767,7 @@
 @patch
 class _IOService {
   @patch
-  static Future _dispatch(int request, List data) {
+  static Future<Object?> _dispatch(int request, List data) {
     throw new UnsupportedError("_IOService._dispatch");
   }
 }
diff --git a/sdk/lib/_internal/wasm/lib/isolate_patch.dart b/sdk/lib/_internal/wasm/lib/isolate_patch.dart
new file mode 100644
index 0000000..9decf7e
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/isolate_patch.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2022, 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:_internal" show patch;
+
+import "dart:async" show Future, Stream;
+
+import "dart:typed_data" show TypedData;
+
+@patch
+class Isolate {
+  @patch
+  String? get debugName {
+    throw UnsupportedError("Isolate.debugName");
+  }
+
+  @patch
+  static Isolate get current {
+    throw UnsupportedError("Isolate.current");
+  }
+
+  @patch
+  static Future<Uri?> get packageConfig {
+    throw UnsupportedError("Isolate.packageConfig");
+  }
+
+  @patch
+  static Future<Uri?> resolvePackageUri(Uri packageUri) {
+    throw UnsupportedError("Isolate.resolvePackageUri");
+  }
+
+  @patch
+  static Future<Isolate> spawn<T>(void entryPoint(T message), T message,
+      {bool paused = false,
+      bool errorsAreFatal = true,
+      SendPort? onExit,
+      SendPort? onError,
+      String? debugName}) {
+    throw UnsupportedError("Isolate.spawn");
+  }
+
+  @patch
+  static Future<Isolate> spawnUri(Uri uri, List<String> args, var message,
+      {bool paused = false,
+      SendPort? onExit,
+      SendPort? onError,
+      bool errorsAreFatal = true,
+      bool? checked,
+      Map<String, String>? environment,
+      Uri? packageRoot,
+      Uri? packageConfig,
+      bool automaticPackageResolution = false,
+      String? debugName}) {
+    throw UnsupportedError("Isolate.spawnUri");
+  }
+
+  @patch
+  void _pause(Capability resumeCapability) {
+    throw UnsupportedError("Isolate._pause");
+  }
+
+  @patch
+  void resume(Capability resumeCapability) {
+    throw UnsupportedError("Isolate.resume");
+  }
+
+  @patch
+  void addOnExitListener(SendPort responsePort, {Object? response}) {
+    throw UnsupportedError("Isolate.addOnExitListener");
+  }
+
+  @patch
+  void removeOnExitListener(SendPort responsePort) {
+    throw UnsupportedError("Isolate.removeOnExitListener");
+  }
+
+  @patch
+  void setErrorsFatal(bool errorsAreFatal) {
+    throw UnsupportedError("Isolate.setErrorsFatal");
+  }
+
+  @patch
+  void kill({int priority = beforeNextEvent}) {
+    throw UnsupportedError("Isolate.kill");
+  }
+
+  @patch
+  void ping(SendPort responsePort,
+      {Object? response, int priority = immediate}) {
+    throw UnsupportedError("Isolate.ping");
+  }
+
+  @patch
+  void addErrorListener(SendPort port) {
+    throw UnsupportedError("Isolate.addErrorListener");
+  }
+
+  @patch
+  void removeErrorListener(SendPort port) {
+    throw UnsupportedError("Isolate.removeErrorListener");
+  }
+
+  @patch
+  static Never exit([SendPort? finalMessagePort, Object? message]) {
+    throw UnsupportedError("Isolate.exit");
+  }
+}
+
+@patch
+abstract class ReceivePort implements Stream<dynamic> {
+  @patch
+  factory ReceivePort([String debugName = '']) {
+    throw UnsupportedError("ReceivePort");
+  }
+
+  @patch
+  factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
+    throw UnsupportedError("ReceivePort.fromRawReceivePort");
+  }
+}
+
+@patch
+abstract class RawReceivePort {
+  @patch
+  factory RawReceivePort([Function? handler, String debugName = '']) {
+    throw UnsupportedError("RawReceivePort");
+  }
+}
+
+@patch
+abstract class TransferableTypedData {
+  @patch
+  factory TransferableTypedData.fromList(List<TypedData> list) {
+    throw UnsupportedError("TransferableTypedData.fromList");
+  }
+}
diff --git a/sdk/lib/_internal/wasm/lib/js_helper.dart b/sdk/lib/_internal/wasm/lib/js_helper.dart
index 59f9c41..9a43631 100644
--- a/sdk/lib/_internal/wasm/lib/js_helper.dart
+++ b/sdk/lib/_internal/wasm/lib/js_helper.dart
@@ -14,73 +14,77 @@
 
 /// [JSValue] is the root of the JS interop object hierarchy.
 class JSValue {
-  final WasmAnyRef _ref;
+  final WasmExternRef _ref;
 
   JSValue(this._ref);
 
   // Currently we always explictly box JS ref's in [JSValue] objects. In the
   // future, we will want to leave these values unboxed when possible, even when
   // they are nullable.
-  static JSValue? box(WasmAnyRef? ref) =>
+  static JSValue? box(WasmExternRef? ref) =>
       isDartNull(ref) ? null : JSValue(ref!);
 
-  WasmAnyRef toAnyRef() => _ref;
+  @override
+  bool operator ==(Object that) =>
+      that is JSValue && areEqualInJS(_ref, that._ref);
+
+  WasmExternRef toExternRef() => _ref;
   String toString() => jsStringToDartString(_ref);
   List<Object?> toObjectList() => toDartList(_ref);
   Object toObject() => jsObjectToDartObject(_ref);
 }
 
 extension DoubleToJS on double {
-  WasmAnyRef toAnyRef() => toJSNumber(this);
-  JSValue toJS() => JSValue(toAnyRef());
+  WasmExternRef toExternRef() => toJSNumber(this)!;
+  JSValue toJS() => JSValue(toExternRef());
 }
 
 extension StringToJS on String {
-  WasmAnyRef toAnyRef() => jsStringFromDartString(this);
-  JSValue toJS() => JSValue(toAnyRef());
+  WasmExternRef toExternRef() => jsStringFromDartString(this)!;
+  JSValue toJS() => JSValue(toExternRef());
 }
 
 extension ListOfObjectToJS on List<Object?> {
-  WasmAnyRef toAnyRef() => jsArrayFromDartList(this);
-  JSValue toJS() => JSValue(toAnyRef());
+  WasmExternRef toExternRef() => jsArrayFromDartList(this)!;
+  JSValue toJS() => JSValue(toExternRef());
 }
 
 extension ObjectToJS on Object {
-  WasmAnyRef toAnyRef() => jsObjectFromDartObject(this);
-  JSValue toJS() => JSValue(toAnyRef());
+  WasmExternRef toExternRef() => jsObjectFromDartObject(this);
+  JSValue toJS() => JSValue(toExternRef());
 }
 
 // For now both `null` and `undefined` in JS map to `null` in Dart.
-bool isDartNull(WasmAnyRef? ref) => ref == null || isJSUndefined(ref);
+bool isDartNull(WasmExternRef? ref) => ref == null || isJSUndefined(ref);
 
 /// A [JSArray] is a wrapper for a native JSArray.
 class JSArray extends JSValue {
-  JSArray(WasmAnyRef ref) : super(ref);
+  JSArray(WasmExternRef ref) : super(ref);
 
-  static JSArray? box(WasmAnyRef? ref) =>
+  static JSArray? box(WasmExternRef? ref) =>
       isDartNull(ref) ? null : JSArray(ref!);
 
-  JSValue? pop() =>
-      JSValue.box(callMethodVarArgsRaw(_ref, 'pop'.toAnyRef(), [].toAnyRef()));
+  JSValue? pop() => JSValue.box(
+      callMethodVarArgsRaw(_ref, 'pop'.toExternRef(), [].toExternRef()));
   JSValue? operator [](int index) =>
       JSValue.box(getPropertyRaw(_ref, intToJSNumber(index)));
   void operator []=(int index, JSValue? value) =>
-      setPropertyRaw(_ref, intToJSNumber(index), value?.toAnyRef());
+      setPropertyRaw(_ref, intToJSNumber(index), value?.toExternRef());
   int get length =>
-      toDartNumber(getPropertyRaw(_ref, 'length'.toAnyRef())!).floor();
+      toDartNumber(getPropertyRaw(_ref, 'length'.toExternRef())!).floor();
 }
 
 /// A [JSObject] is a wrapper for any JS object literal.
 class JSObject extends JSValue {
-  JSObject(WasmAnyRef ref) : super(ref);
+  JSObject(WasmExternRef ref) : super(ref);
 
-  static JSObject? box(WasmAnyRef? ref) =>
+  static JSObject? box(WasmExternRef? ref) =>
       isDartNull(ref) ? null : JSObject(ref!);
 
   JSValue? operator [](String key) =>
-      JSValue.box(getPropertyRaw(_ref, key.toAnyRef()));
+      JSValue.box(getPropertyRaw(_ref, key.toExternRef()));
   void operator []=(String key, JSValue? value) =>
-      setPropertyRaw(_ref, key.toAnyRef(), value?.toAnyRef());
+      setPropertyRaw(_ref, key.toExternRef(), value?.toExternRef());
 }
 
 class JSArrayIteratorAdapter<T> extends Iterator<T> {
@@ -99,7 +103,7 @@
   }
 
   @override
-  T get current => dartifyRaw(array[index]?.toAnyRef()) as T;
+  T get current => dartifyRaw(array[index]?.toExternRef()) as T;
 }
 
 /// [JSArrayIterableAdapter] lazily adapts a [JSArray] to Dart's [Iterable]
@@ -117,188 +121,200 @@
 }
 
 // Convert to double to avoid converting to [BigInt] in the case of int64.
-WasmAnyRef intToJSNumber(int i) => toJSNumber(i.toDouble());
+WasmExternRef intToJSNumber(int i) => toJSNumber(i.toDouble())!;
 
-WasmAnyRef? getConstructorString(String constructor) =>
-    getPropertyRaw(globalThisRaw(), constructor.toAnyRef());
+WasmExternRef? getConstructorString(String constructor) =>
+    getPropertyRaw(globalThisRaw(), constructor.toExternRef());
 
-Object jsObjectToDartObject(WasmAnyRef ref) => unsafeCastOpaque<Object>(ref);
+Object jsObjectToDartObject(WasmExternRef? ref) =>
+    unsafeCastOpaque<Object>(ref.internalize());
 
-WasmAnyRef jsObjectFromDartObject(Object object) =>
-    unsafeCastOpaque<WasmAnyRef>(object);
+WasmExternRef jsObjectFromDartObject(Object object) =>
+    unsafeCastOpaque<WasmAnyRef>(object).externalize();
 
 @pragma("wasm:import", "dart2wasm.isJSUndefined")
-external bool isJSUndefined(WasmAnyRef? o);
+external bool isJSUndefined(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSBoolean")
-external bool isJSBoolean(WasmAnyRef? o);
+external bool isJSBoolean(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSNumber")
-external bool isJSNumber(WasmAnyRef? o);
+external bool isJSNumber(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSBigInt")
-external bool isJSBigInt(WasmAnyRef? o);
+external bool isJSBigInt(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSString")
-external bool isJSString(WasmAnyRef? o);
+external bool isJSString(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSSymbol")
-external bool isJSSymbol(WasmAnyRef? o);
+external bool isJSSymbol(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSFunction")
-external bool isJSFunction(WasmAnyRef? o);
+external bool isJSFunction(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSInt8Array")
-external bool isJSInt8Array(WasmAnyRef object);
+external bool isJSInt8Array(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSUint8Array")
-external bool isJSUint8Array(WasmAnyRef object);
+external bool isJSUint8Array(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSUint8ClampedArray")
-external bool isJSUint8ClampedArray(WasmAnyRef object);
+external bool isJSUint8ClampedArray(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSInt16Array")
-external bool isJSInt16Array(WasmAnyRef object);
+external bool isJSInt16Array(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSUint16Array")
-external bool isJSUint16Array(WasmAnyRef object);
+external bool isJSUint16Array(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSInt32Array")
-external bool isJSInt32Array(WasmAnyRef object);
+external bool isJSInt32Array(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSUint32Array")
-external bool isJSUint32Array(WasmAnyRef object);
+external bool isJSUint32Array(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSFloat32Array")
-external bool isJSFloat32Array(WasmAnyRef object);
+external bool isJSFloat32Array(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSFloat64Array")
-external bool isJSFloat64Array(WasmAnyRef object);
+external bool isJSFloat64Array(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSArrayBuffer")
-external bool isJSArrayBuffer(WasmAnyRef object);
+external bool isJSArrayBuffer(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSDataView")
-external bool isJSDataView(WasmAnyRef object);
+external bool isJSDataView(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.isJSArray")
-external bool isJSArray(WasmAnyRef? o);
+external bool isJSArray(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSWrappedDartFunction")
-external bool isJSWrappedDartFunction(WasmAnyRef? o);
+external bool isJSWrappedDartFunction(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSObject")
-external bool isJSObject(WasmAnyRef? o);
+external bool isJSObject(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSSimpleObject")
-external bool isJSSimpleObject(WasmAnyRef? o);
+external bool isJSSimpleObject(WasmExternRef? o);
 
 @pragma("wasm:import", "dart2wasm.isJSRegExp")
-external bool isJSRegExp(WasmAnyRef object);
+external bool isJSRegExp(WasmExternRef? object);
+
+@pragma("wasm:import", "dart2wasm.areEqualInJS")
+external bool areEqualInJS(WasmExternRef? l, WasmExternRef? r);
 
 // The JS runtime will run helpful conversion routines between refs and bool /
 // double. In the longer term hopefully we can find a way to avoid the round
 // trip.
 @pragma("wasm:import", "dart2wasm.roundtrip")
-external double toDartNumber(WasmAnyRef ref);
+external double toDartNumber(WasmExternRef? ref);
 
 @pragma("wasm:import", "dart2wasm.roundtrip")
-external WasmAnyRef toJSNumber(double d);
+external WasmExternRef? toJSNumber(double d);
 
 @pragma("wasm:import", "dart2wasm.roundtrip")
-external bool toDartBool(WasmAnyRef ref);
+external bool toDartBool(WasmExternRef? ref);
 
 @pragma("wasm:import", "dart2wasm.toJSBoolean")
-external WasmAnyRef toJSBoolean(bool b);
+external WasmExternRef? toJSBoolean(bool b);
 
 @pragma("wasm:import", "dart2wasm.objectLength")
-external double objectLength(WasmAnyRef ref);
+external double objectLength(WasmExternRef? ref);
 
 @pragma("wasm:import", "dart2wasm.objectReadIndex")
-external WasmAnyRef? objectReadIndex(WasmAnyRef ref, int index);
+external WasmExternRef? objectReadIndex(WasmExternRef? ref, int index);
 
 @pragma("wasm:import", "dart2wasm.unwrapJSWrappedDartFunction")
-external Object? unwrapJSWrappedDartFunction(WasmAnyRef f);
+external Object? unwrapJSWrappedDartFunction(WasmExternRef? f);
 
 @pragma("wasm:import", "dart2wasm.int8ArrayFromDartInt8List")
-external WasmAnyRef jsInt8ArrayFromDartInt8List(Int8List list);
+external WasmExternRef? jsInt8ArrayFromDartInt8List(Int8List list);
 
 @pragma("wasm:import", "dart2wasm.uint8ArrayFromDartUint8List")
-external WasmAnyRef jsUint8ArrayFromDartUint8List(Uint8List list);
+external WasmExternRef? jsUint8ArrayFromDartUint8List(Uint8List list);
 
 @pragma("wasm:import", "dart2wasm.uint8ClampedArrayFromDartUint8ClampedList")
-external WasmAnyRef jsUint8ClampedArrayFromDartUint8ClampedList(
+external WasmExternRef? jsUint8ClampedArrayFromDartUint8ClampedList(
     Uint8ClampedList list);
 
 @pragma("wasm:import", "dart2wasm.int16ArrayFromDartInt16List")
-external WasmAnyRef jsInt16ArrayFromDartInt16List(Int16List list);
+external WasmExternRef? jsInt16ArrayFromDartInt16List(Int16List list);
 
 @pragma("wasm:import", "dart2wasm.uint16ArrayFromDartUint16List")
-external WasmAnyRef jsUint16ArrayFromDartUint16List(Uint16List list);
+external WasmExternRef? jsUint16ArrayFromDartUint16List(Uint16List list);
 
 @pragma("wasm:import", "dart2wasm.int32ArrayFromDartInt32List")
-external WasmAnyRef jsInt32ArrayFromDartInt32List(Int32List list);
+external WasmExternRef? jsInt32ArrayFromDartInt32List(Int32List list);
 
 @pragma("wasm:import", "dart2wasm.uint32ArrayFromDartUint32List")
-external WasmAnyRef jsUint32ArrayFromDartUint32List(Uint32List list);
+external WasmExternRef? jsUint32ArrayFromDartUint32List(Uint32List list);
 
 @pragma("wasm:import", "dart2wasm.float32ArrayFromDartFloat32List")
-external WasmAnyRef jsFloat32ArrayFromDartFloat32List(Float32List list);
+external WasmExternRef? jsFloat32ArrayFromDartFloat32List(Float32List list);
 
 @pragma("wasm:import", "dart2wasm.float64ArrayFromDartFloat64List")
-external WasmAnyRef jsFloat64ArrayFromDartFloat64List(Float64List list);
+external WasmExternRef? jsFloat64ArrayFromDartFloat64List(Float64List list);
 
 @pragma("wasm:import", "dart2wasm.dataViewFromDartByteData")
-external WasmAnyRef jsDataViewFromDartByteData(
+external WasmExternRef? jsDataViewFromDartByteData(
     ByteData data, double byteLength);
 
 @pragma("wasm:import", "dart2wasm.arrayFromDartList")
-external WasmAnyRef jsArrayFromDartList(List<Object?> list);
+external WasmExternRef? jsArrayFromDartList(List<Object?> list);
 
 @pragma("wasm:import", "dart2wasm.stringFromDartString")
-external WasmAnyRef jsStringFromDartString(String string);
+external WasmExternRef? jsStringFromDartString(String string);
 
 @pragma("wasm:import", "dart2wasm.stringToDartString")
-external String jsStringToDartString(WasmAnyRef string);
+external String jsStringToDartString(WasmExternRef? string);
 
 @pragma("wasm:import", "dart2wasm.eval")
-external void evalRaw(WasmAnyRef code);
+external void evalRaw(WasmExternRef? code);
 
 @pragma("wasm:import", "dart2wasm.newObject")
-external WasmAnyRef newObjectRaw();
+external WasmExternRef? newObjectRaw();
 
 @pragma("wasm:import", "dart2wasm.newArray")
-external WasmAnyRef newArrayRaw();
+external WasmExternRef? newArrayRaw();
 
 @pragma("wasm:import", "dart2wasm.globalThis")
-external WasmAnyRef globalThisRaw();
+external WasmExternRef? globalThisRaw();
 
 @pragma("wasm:import", "dart2wasm.callConstructorVarArgs")
-external WasmAnyRef callConstructorVarArgsRaw(WasmAnyRef o, WasmAnyRef args);
+external WasmExternRef? callConstructorVarArgsRaw(
+    WasmExternRef? o, WasmExternRef? args);
 
 @pragma("wasm:import", "dart2wasm.safeCallConstructorVarArgs")
-external WasmAnyRef safeCallConstructorVarArgsRaw(
-    WasmAnyRef o, WasmAnyRef args);
+external WasmExternRef? safeCallConstructorVarArgsRaw(
+    WasmExternRef? o, WasmExternRef? args);
 
 @pragma("wasm:import", "dart2wasm.hasProperty")
-external bool hasPropertyRaw(WasmAnyRef o, WasmAnyRef name);
+external bool hasPropertyRaw(WasmExternRef? o, WasmExternRef? name);
 
 @pragma("wasm:import", "dart2wasm.getProperty")
-external WasmAnyRef? getPropertyRaw(WasmAnyRef o, WasmAnyRef name);
+external WasmExternRef? getPropertyRaw(WasmExternRef? o, WasmExternRef? name);
 
 @pragma("wasm:import", "dart2wasm.setProperty")
-external WasmAnyRef? setPropertyRaw(
-    WasmAnyRef o, WasmAnyRef name, WasmAnyRef? value);
+external WasmExternRef? setPropertyRaw(
+    WasmExternRef? o, WasmExternRef? name, WasmExternRef? value);
 
 @pragma("wasm:import", "dart2wasm.callMethodVarArgs")
-external WasmAnyRef? callMethodVarArgsRaw(
-    WasmAnyRef o, WasmAnyRef method, WasmAnyRef? args);
+external WasmExternRef? callMethodVarArgsRaw(
+    WasmExternRef? o, WasmExternRef? method, WasmExternRef? args);
 
 @pragma("wasm:import", "dart2wasm.stringify")
-external String stringify(WasmAnyRef? object);
+external String stringify(WasmExternRef? object);
 
 @pragma("wasm:import", "dart2wasm.objectKeys")
-external WasmAnyRef objectKeysRaw(WasmAnyRef? o);
+external WasmExternRef? objectKeysRaw(WasmExternRef? o);
+
+@pragma("wasm:import", "dart2wasm.promiseThen")
+external void promiseThen(WasmExternRef? promise, WasmExternRef? successFunc,
+    WasmExternRef? failureFunc);
+
+@pragma("wasm:import", "dart2wasm.instanceofTrampoline")
+external bool instanceofRaw(WasmExternRef? object, WasmExternRef? type);
 
 // Currently, `allowInterop` returns a Function type. This is unfortunate for
 // Dart2wasm because it means arbitrary Dart functions can flow to JS util
@@ -308,14 +324,14 @@
 // NOTE: We are not currently replacing functions returned from JS.
 Map<Function, JSValue> functionToJSWrapper = {};
 
-WasmAnyRef jsArrayBufferFromDartByteBuffer(ByteBuffer buffer) {
+WasmExternRef? jsArrayBufferFromDartByteBuffer(ByteBuffer buffer) {
   ByteData byteData = ByteData.view(buffer);
-  WasmAnyRef dataView =
+  WasmExternRef? dataView =
       jsDataViewFromDartByteData(byteData, byteData.lengthInBytes.toDouble());
-  return getPropertyRaw(dataView, 'buffer'.toAnyRef())!;
+  return getPropertyRaw(dataView, 'buffer'.toExternRef());
 }
 
-WasmAnyRef? jsifyRaw(Object? object) {
+WasmExternRef? jsifyRaw(Object? object) {
   if (object == null) {
     return null;
   } else if (object is bool) {
@@ -323,9 +339,9 @@
   } else if (object is Function) {
     assert(functionToJSWrapper.containsKey(object),
         'Must call `allowInterop` on functions before they flow to JS');
-    return functionToJSWrapper[object]?.toAnyRef();
+    return functionToJSWrapper[object]?.toExternRef();
   } else if (object is JSValue) {
-    return object.toAnyRef();
+    return object.toExternRef();
   } else if (object is String) {
     return jsStringFromDartString(object);
   } else if (object is Int8List) {
@@ -359,13 +375,15 @@
   }
 }
 
+bool isWasmGCStruct(WasmExternRef ref) => ref.internalize().isObject;
+
 /// TODO(joshualitt): We shouldn't need this, but otherwise we seem to get a
 /// cast error for certain oddball types(I think undefined, but need to dig
 /// deeper).
 @pragma("wasm:export", "\$dartifyRaw")
-Object? dartifyExported(WasmAnyRef? ref) => dartifyRaw(ref);
+Object? dartifyExported(WasmExternRef? ref) => dartifyRaw(ref);
 
-Object? dartifyRaw(WasmAnyRef? ref) {
+Object? dartifyRaw(WasmExternRef? ref) {
   if (ref == null) {
     return null;
   } else if (isJSUndefined(ref)) {
@@ -403,124 +421,124 @@
     return toDartList(ref);
   } else if (isJSWrappedDartFunction(ref)) {
     return unwrapJSWrappedDartFunction(ref);
-  } else if (isJSObject(ref) ||
-      // TODO(joshualitt): We may want to create proxy types for some of these
-      // cases.
-      isJSBigInt(ref) ||
-      isJSSymbol(ref) ||
-      isJSFunction(ref)) {
-    return JSValue(ref);
-  } else {
+  } else if (isWasmGCStruct(ref)) {
     return jsObjectToDartObject(ref);
+  } else {
+    return JSValue(ref);
   }
 }
 
-Int8List toDartInt8List(WasmAnyRef ref) =>
+Int8List toDartInt8List(WasmExternRef? ref) =>
     jsIntTypedArrayToDartIntTypedData(ref, (size) => Int8List(size))
         as Int8List;
 
-Uint8List toDartUint8List(WasmAnyRef ref) =>
+Uint8List toDartUint8List(WasmExternRef? ref) =>
     jsIntTypedArrayToDartIntTypedData(ref, (size) => Uint8List(size))
         as Uint8List;
 
-Uint8ClampedList toDartUint8ClampedList(WasmAnyRef ref) =>
+Uint8ClampedList toDartUint8ClampedList(WasmExternRef? ref) =>
     jsIntTypedArrayToDartIntTypedData(ref, (size) => Uint8ClampedList(size))
         as Uint8ClampedList;
 
-Int16List toDartInt16List(WasmAnyRef ref) =>
+Int16List toDartInt16List(WasmExternRef? ref) =>
     jsIntTypedArrayToDartIntTypedData(ref, (size) => Int16List(size))
         as Int16List;
 
-Uint16List toDartUint16List(WasmAnyRef ref) =>
+Uint16List toDartUint16List(WasmExternRef? ref) =>
     jsIntTypedArrayToDartIntTypedData(ref, (size) => Uint16List(size))
         as Uint16List;
 
-Int32List toDartInt32List(WasmAnyRef ref) =>
+Int32List toDartInt32List(WasmExternRef? ref) =>
     jsIntTypedArrayToDartIntTypedData(ref, (size) => Int32List(size))
         as Int32List;
 
-Uint32List toDartUint32List(WasmAnyRef ref) =>
+Uint32List toDartUint32List(WasmExternRef? ref) =>
     jsIntTypedArrayToDartIntTypedData(ref, (size) => Uint32List(size))
         as Uint32List;
 
-Float32List toDartFloat32List(WasmAnyRef ref) =>
+Float32List toDartFloat32List(WasmExternRef? ref) =>
     jsFloatTypedArrayToDartFloatTypedData(ref, (size) => Float32List(size))
         as Float32List;
 
-Float64List toDartFloat64List(WasmAnyRef ref) =>
+Float64List toDartFloat64List(WasmExternRef? ref) =>
     jsFloatTypedArrayToDartFloatTypedData(ref, (size) => Float64List(size))
         as Float64List;
 
-ByteBuffer toDartByteBuffer(WasmAnyRef ref) =>
+ByteBuffer toDartByteBuffer(WasmExternRef? ref) =>
     toDartByteData(callConstructorVarArgsRaw(
-            getConstructorString('DataView')!, [JSValue(ref)].toAnyRef()))
+            getConstructorString('DataView'), [JSValue.box(ref)].toExternRef()))
         .buffer;
 
-ByteData toDartByteData(WasmAnyRef ref) {
+ByteData toDartByteData(WasmExternRef? ref) {
   int length =
-      toDartNumber(getPropertyRaw(ref, 'byteLength'.toAnyRef())!).toInt();
+      toDartNumber(getPropertyRaw(ref, 'byteLength'.toExternRef())).toInt();
   ByteData data = ByteData(length);
   for (int i = 0; i < length; i++) {
     data.setUint8(
         i,
         toDartNumber(callMethodVarArgsRaw(
-                ref, 'getUint8'.toAnyRef(), [i].toAnyRef())!)
+                ref, 'getUint8'.toExternRef(), [i].toExternRef()))
             .toInt());
   }
   return data;
 }
 
 List<double> jsFloatTypedArrayToDartFloatTypedData(
-    WasmAnyRef ref, List<double> makeTypedData(int size)) {
+    WasmExternRef? ref, List<double> makeTypedData(int size)) {
   int length = objectLength(ref).toInt();
   List<double> list = makeTypedData(length);
   for (int i = 0; i < length; i++) {
-    list[i] = toDartNumber(objectReadIndex(ref, i)!);
+    list[i] = toDartNumber(objectReadIndex(ref, i));
   }
   return list;
 }
 
 List<int> jsIntTypedArrayToDartIntTypedData(
-    WasmAnyRef ref, List<int> makeTypedData(int size)) {
+    WasmExternRef? ref, List<int> makeTypedData(int size)) {
   int length = objectLength(ref).toInt();
   List<int> list = makeTypedData(length);
   for (int i = 0; i < length; i++) {
-    list[i] = toDartNumber(objectReadIndex(ref, i)!).toInt();
+    list[i] = toDartNumber(objectReadIndex(ref, i)).toInt();
   }
   return list;
 }
 
-List<Object?> toDartList(WasmAnyRef ref) => List<Object?>.generate(
+List<Object?> toDartList(WasmExternRef? ref) => List<Object?>.generate(
     objectLength(ref).round(), (int n) => dartifyRaw(objectReadIndex(ref, n)));
 
 @pragma("wasm:import", "dart2wasm.wrapDartFunction")
-external WasmAnyRef _wrapDartFunctionRaw(
-    WasmAnyRef dartFunction, WasmAnyRef trampolineName);
+external WasmExternRef? _wrapDartFunctionRaw(WasmExternRef? dartFunction,
+    WasmExternRef? trampolineName, WasmExternRef? argCount);
 
-F _wrapDartFunction<F extends Function>(F f, String trampolineName) {
+F _wrapDartFunction<F extends Function>(
+    F f, String trampolineName, int argCount) {
   if (functionToJSWrapper.containsKey(f)) {
     return f;
   }
   JSValue wrappedFunction = JSValue(_wrapDartFunctionRaw(
-      f.toJS().toAnyRef(), trampolineName.toJS().toAnyRef()));
+      f.toJS().toExternRef(),
+      trampolineName.toJS().toExternRef(),
+      argCount.toDouble().toJS().toExternRef())!);
   functionToJSWrapper[f] = wrappedFunction;
   return f;
 }
 
 /// Returns the JS constructor object for a given [String].
-WasmAnyRef getConstructorRaw(String name) =>
-    getPropertyRaw(globalThisRaw(), name.toAnyRef())!;
+WasmExternRef? getConstructorRaw(String name) =>
+    getPropertyRaw(globalThisRaw(), name.toExternRef());
 
 /// Equivalent to `Object.keys(object)`.
 JSArray objectKeys(JSValue object) => JSArray(callMethodVarArgsRaw(
-    getConstructorRaw('Object'), 'keys'.toAnyRef(), [object].toAnyRef())!);
+    getConstructorRaw('Object'),
+    'keys'.toExternRef(),
+    [object].toExternRef())!);
 
 /// Methods used by the wasm runtime.
 @pragma("wasm:export", "\$listLength")
 double _listLength(List list) => list.length.toDouble();
 
 @pragma("wasm:export", "\$listRead")
-WasmAnyRef? _listRead(List<Object?> list, double index) =>
+WasmExternRef? _listRead(List<Object?> list, double index) =>
     jsifyRaw(list[index.toInt()]);
 
 @pragma("wasm:export", "\$byteDataGetUint8")
diff --git a/sdk/lib/_internal/wasm/lib/js_patch.dart b/sdk/lib/_internal/wasm/lib/js_patch.dart
index 0445321..373b067 100644
--- a/sdk/lib/_internal/wasm/lib/js_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/js_patch.dart
@@ -12,109 +12,111 @@
 import 'dart:wasm';
 
 @patch
-JsObject get context => throw UnimplementedError;
+JsObject get context => throw UnimplementedError();
 
 @patch
 class JsObject {
   // No argument empty constructor to support inheritance.
   JsObject._() {
-    throw UnimplementedError;
+    throw UnimplementedError();
   }
 
   @patch
   factory JsObject(JsFunction constructor, [List? arguments]) =>
-      throw UnimplementedError;
+      throw UnimplementedError();
 
   @patch
-  factory JsObject.fromBrowserObject(Object object) => throw UnimplementedError;
+  factory JsObject.fromBrowserObject(Object object) =>
+      throw UnimplementedError();
 
   @patch
-  factory JsObject.jsify(Object object) => throw UnimplementedError;
+  factory JsObject.jsify(Object object) => throw UnimplementedError();
 
   @patch
-  dynamic operator [](Object property) => throw UnimplementedError;
+  dynamic operator [](Object property) => throw UnimplementedError();
 
   @patch
-  void operator []=(Object property, Object? value) => throw UnimplementedError;
+  void operator []=(Object property, Object? value) =>
+      throw UnimplementedError();
 
   @patch
-  bool operator ==(Object other) => throw UnimplementedError;
+  bool operator ==(Object other) => throw UnimplementedError();
 
   @patch
-  bool hasProperty(Object property) => throw UnimplementedError;
+  bool hasProperty(Object property) => throw UnimplementedError();
 
   @patch
-  void deleteProperty(Object property) => throw UnimplementedError;
+  void deleteProperty(Object property) => throw UnimplementedError();
 
   @patch
-  bool instanceof(JsFunction type) => throw UnimplementedError;
+  bool instanceof(JsFunction type) => throw UnimplementedError();
 
   @patch
-  String toString() => throw UnimplementedError;
+  String toString() => throw UnimplementedError();
 
   @patch
-  dynamic callMethod(Object method, [List? args]) => throw UnimplementedError;
+  dynamic callMethod(Object method, [List? args]) => throw UnimplementedError();
 }
 
 @patch
 class JsFunction extends JsObject {
   @patch
-  factory JsFunction.withThis(Function f) => throw UnimplementedError;
+  factory JsFunction.withThis(Function f) => throw UnimplementedError();
 
   @patch
-  dynamic apply(List args, {thisArg}) => throw UnimplementedError;
+  dynamic apply(List args, {thisArg}) => throw UnimplementedError();
 }
 
 @patch
 class JsArray<E> extends JsObject with ListMixin<E> {
   @patch
-  factory JsArray() => throw UnimplementedError;
+  factory JsArray() => throw UnimplementedError();
 
   @patch
-  factory JsArray.from(Iterable<E> other) => throw UnimplementedError;
+  factory JsArray.from(Iterable<E> other) => throw UnimplementedError();
 
   @patch
-  E operator [](Object index) => throw UnimplementedError;
+  E operator [](Object index) => throw UnimplementedError();
 
   @patch
-  void operator []=(Object index, E value) => throw UnimplementedError;
+  void operator []=(Object index, E value) => throw UnimplementedError();
 
   @patch
-  int get length => throw UnimplementedError;
+  int get length => throw UnimplementedError();
 
   @patch
-  void set length(int length) => throw UnimplementedError;
+  void set length(int length) => throw UnimplementedError();
 
   @patch
-  void add(E value) => throw UnimplementedError;
+  void add(E value) => throw UnimplementedError();
 
   @patch
-  void addAll(Iterable<E> iterable) => throw UnimplementedError;
+  void addAll(Iterable<E> iterable) => throw UnimplementedError();
 
   @patch
-  void insert(int index, E element) => throw UnimplementedError;
+  void insert(int index, E element) => throw UnimplementedError();
 
   @patch
-  E removeAt(int index) => throw UnimplementedError;
+  E removeAt(int index) => throw UnimplementedError();
 
   @patch
-  E removeLast() => throw UnimplementedError;
+  E removeLast() => throw UnimplementedError();
 
   @patch
-  void removeRange(int start, int end) => throw UnimplementedError;
+  void removeRange(int start, int end) => throw UnimplementedError();
 
   @patch
   void setRange(int start, int end, Iterable<E> iterable,
           [int skipCount = 0]) =>
-      throw UnimplementedError;
+      throw UnimplementedError();
 
   @patch
-  void sort([int compare(E a, E b)?]) => throw UnimplementedError;
+  void sort([int compare(E a, E b)?]) => throw UnimplementedError();
 }
 
 /// This will be lowered to a a call to `_wrapDartCallback`.
 @patch
-F allowInterop<F extends Function>(F f) => throw UnimplementedError;
+F allowInterop<F extends Function>(F f) => throw UnimplementedError();
 
 @patch
-Function allowInteropCaptureThis(Function f) => throw UnimplementedError;
+Function allowInteropCaptureThis(Function f) => throw UnimplementedError();
diff --git a/sdk/lib/_internal/wasm/lib/js_util_patch.dart b/sdk/lib/_internal/wasm/lib/js_util_patch.dart
index eb59f4a..84ab1fb 100644
--- a/sdk/lib/_internal/wasm/lib/js_util_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/js_util_patch.dart
@@ -4,8 +4,10 @@
 
 library dart.js_util;
 
+import "dart:_js_annotations" as js;
 import "dart:_internal";
 import "dart:_js_helper";
+import "dart:async" show Completer, FutureOr;
 import "dart:collection";
 import "dart:typed_data";
 import "dart:wasm";
@@ -45,8 +47,8 @@
       convertedObjects[o] = convertedMap;
       for (final key in o.keys) {
         JSValue convertedKey = convert(key) as JSValue;
-        setPropertyRaw(convertedMap.toAnyRef(), convertedKey.toAnyRef(),
-            (convert(o[key]) as JSValue).toAnyRef());
+        setPropertyRaw(convertedMap.toExternRef(), convertedKey.toExternRef(),
+            (convert(o[key]) as JSValue).toExternRef());
       }
       return convertedMap;
     } else if (o is Iterable) {
@@ -66,37 +68,37 @@
 }
 
 @patch
-Object get globalThis => JSValue(globalThisRaw());
+Object get globalThis => JSValue(globalThisRaw()!);
 
 @patch
-T newObject<T>() => JSValue(newObjectRaw()) as T;
+T newObject<T>() => JSValue(newObjectRaw()!) as T;
 
-JSValue _newArray() => JSValue(newArrayRaw());
+JSValue _newArray() => JSValue(newArrayRaw()!);
 
 @patch
 bool hasProperty(Object o, String name) =>
-    hasPropertyRaw(jsifyRaw(o)!, name.toJS().toAnyRef());
+    hasPropertyRaw(jsifyRaw(o)!, name.toJS().toExternRef());
 
 @patch
 T getProperty<T>(Object o, String name) =>
-    dartifyRaw(getPropertyRaw(jsifyRaw(o)!, name.toJS().toAnyRef())) as T;
+    dartifyRaw(getPropertyRaw(jsifyRaw(o)!, name.toJS().toExternRef())) as T;
 
 @patch
-T setProperty<T>(Object o, String name, T? value) => dartifyRaw(
-    setPropertyRaw(jsifyRaw(o)!, name.toJS().toAnyRef(), jsifyRaw(value))) as T;
+T setProperty<T>(Object o, String name, T? value) => dartifyRaw(setPropertyRaw(
+    jsifyRaw(o)!, name.toJS().toExternRef(), jsifyRaw(value))) as T;
 
 @patch
 T callMethod<T>(Object o, String method, List<Object?> args) =>
-    dartifyRaw(callMethodVarArgsRaw(
-        jsifyRaw(o)!, method.toJS().toAnyRef(), args.toJS().toAnyRef())) as T;
+    dartifyRaw(callMethodVarArgsRaw(jsifyRaw(o)!, method.toJS().toExternRef(),
+        args.toJS().toExternRef())) as T;
 
 @patch
-bool instanceof(Object? o, Object type) => throw 'unimplemented';
+bool instanceof(Object? o, Object type) =>
+    instanceofRaw(jsifyRaw(o), jsifyRaw(type));
 
 @patch
-T callConstructor<T>(Object o, List<Object?> args) =>
-    dartifyRaw(callConstructorVarArgsRaw(jsifyRaw(o)!, args.toJS().toAnyRef()))!
-        as T;
+T callConstructor<T>(Object o, List<Object?> args) => dartifyRaw(
+    callConstructorVarArgsRaw(jsifyRaw(o)!, args.toJS().toExternRef()))! as T;
 
 @patch
 T add<T>(Object? first, Object? second) => throw 'unimplemented';
@@ -141,8 +143,32 @@
 @patch
 bool lessThanOrEqual<T>(Object? first, Object? second) => throw 'unimplemented';
 
+typedef _PromiseSuccessFunc = void Function(Object? value);
+typedef _PromiseFailureFunc = void Function(Object? error);
+
 @patch
-Future<T> promiseToFuture<T>(Object jsPromise) => throw 'unimplemented';
+Future<T> promiseToFuture<T>(Object jsPromise) {
+  Completer<T> completer = Completer<T>();
+
+  final success = js.allowInterop<_PromiseSuccessFunc>((r) {
+    return completer.complete(r as FutureOr<T>?);
+  });
+  final error = js.allowInterop<_PromiseFailureFunc>((e) {
+    // Note that `completeError` expects a non-nullable error regardless of
+    // whether null-safety is enabled, so a `NullRejectionException` is always
+    // provided if the error is `null` or `undefined`.
+    // TODO(joshualitt): At this point `undefined` has been replaced with `null`
+    // so we cannot tell them apart. In the future we should reify `undefined`
+    // in Dart.
+    if (e == null) {
+      return completer.completeError(NullRejectionException._(false));
+    }
+    return completer.completeError(e);
+  });
+
+  promiseThen(jsifyRaw(jsPromise)!, jsifyRaw(success)!, jsifyRaw(error)!);
+  return completer.future;
+}
 
 @patch
 Object? objectGetPrototypeOf(Object? object) => throw 'unimplemented';
@@ -166,7 +192,7 @@
       return o;
     }
 
-    WasmAnyRef ref = o.toAnyRef();
+    WasmExternRef ref = o.toExternRef();
     if (isJSBoolean(ref) ||
         isJSNumber(ref) ||
         isJSString(ref) ||
@@ -199,7 +225,7 @@
         Object? key = keys[i];
         if (key != null) {
           dartMap[key] = convert(
-              JSValue.box(getPropertyRaw(ref, (key as String).toAnyRef())));
+              JSValue.box(getPropertyRaw(ref, (key as String).toExternRef())));
         }
       }
       return dartMap;
diff --git a/sdk/lib/_internal/wasm/lib/object_patch.dart b/sdk/lib/_internal/wasm/lib/object_patch.dart
index 5844697..c60a3d7 100644
--- a/sdk/lib/_internal/wasm/lib/object_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/object_patch.dart
@@ -11,6 +11,8 @@
 external _Type _getInterfaceTypeRuntimeType(
     Object object, List<Type> typeArguments);
 
+external _Type _getFunctionTypeRuntimeType(Object object);
+
 @patch
 class Object {
   @patch
@@ -47,7 +49,13 @@
   external Type get runtimeType;
 
   @pragma("wasm:entry-point")
-  _Type get _runtimeType => _getInterfaceTypeRuntimeType(this, _typeArguments);
+  _Type get _runtimeType {
+    if (ClassID.getID(this) == ClassID.cid_Function) {
+      return _getFunctionTypeRuntimeType(this);
+    } else {
+      return _getInterfaceTypeRuntimeType(this, _typeArguments);
+    }
+  }
 
   @patch
   String toString() => _toString(this);
diff --git a/sdk/lib/_internal/wasm/lib/regexp_helper.dart b/sdk/lib/_internal/wasm/lib/regexp_helper.dart
index 569b792..4fe90fd 100644
--- a/sdk/lib/_internal/wasm/lib/regexp_helper.dart
+++ b/sdk/lib/_internal/wasm/lib/regexp_helper.dart
@@ -15,39 +15,39 @@
 external String quoteStringForRegExp(String string);
 
 class JSNativeMatch extends JSArray {
-  JSNativeMatch(WasmAnyRef ref) : super(ref);
+  JSNativeMatch(WasmExternRef ref) : super(ref);
 
-  static JSNativeMatch? box(WasmAnyRef? ref) =>
+  static JSNativeMatch? box(WasmExternRef? ref) =>
       isDartNull(ref) ? null : JSNativeMatch(ref!);
 
   String get input => jsStringToDartString(
-      getPropertyRaw(this.toAnyRef(), 'input'.toAnyRef())!);
+      getPropertyRaw(this.toExternRef(), 'input'.toExternRef())!);
   int get index =>
-      toDartNumber(getPropertyRaw(this.toAnyRef(), 'index'.toAnyRef())!)
+      toDartNumber(getPropertyRaw(this.toExternRef(), 'index'.toExternRef())!)
           .floor();
   JSObject? get groups =>
-      JSObject.box(getPropertyRaw(this.toAnyRef(), 'groups'.toAnyRef()));
+      JSObject.box(getPropertyRaw(this.toExternRef(), 'groups'.toExternRef()));
 }
 
 class JSNativeRegExp extends JSValue {
-  JSNativeRegExp(WasmAnyRef ref) : super(ref);
+  JSNativeRegExp(WasmExternRef ref) : super(ref);
 
   JSNativeMatch? exec(String string) => JSNativeMatch.box(callMethodVarArgsRaw(
-      this.toAnyRef(), 'exec'.toAnyRef(), [string].toAnyRef()));
+      this.toExternRef(), 'exec'.toExternRef(), [string].toExternRef()));
   bool test(String string) => toDartBool(callMethodVarArgsRaw(
-      this.toAnyRef(), 'test'.toAnyRef(), [string].toAnyRef())!);
+      this.toExternRef(), 'test'.toExternRef(), [string].toExternRef())!);
   String get flags => jsStringToDartString(
-      getPropertyRaw(this.toAnyRef(), 'flags'.toAnyRef())!);
-  bool get multiline =>
-      toDartBool(getPropertyRaw(this.toAnyRef(), 'multiline'.toAnyRef())!);
-  bool get ignoreCase =>
-      toDartBool(getPropertyRaw(this.toAnyRef(), 'ignoreCase'.toAnyRef())!);
+      getPropertyRaw(this.toExternRef(), 'flags'.toExternRef())!);
+  bool get multiline => toDartBool(
+      getPropertyRaw(this.toExternRef(), 'multiline'.toExternRef())!);
+  bool get ignoreCase => toDartBool(
+      getPropertyRaw(this.toExternRef(), 'ignoreCase'.toExternRef())!);
   bool get unicode =>
-      toDartBool(getPropertyRaw(this.toAnyRef(), 'unicode'.toAnyRef())!);
+      toDartBool(getPropertyRaw(this.toExternRef(), 'unicode'.toExternRef())!);
   bool get dotAll =>
-      toDartBool(getPropertyRaw(this.toAnyRef(), 'dotAll'.toAnyRef())!);
+      toDartBool(getPropertyRaw(this.toExternRef(), 'dotAll'.toExternRef())!);
   set lastIndex(int start) => setPropertyRaw(
-      this.toAnyRef(), 'lastIndex'.toAnyRef(), intToJSNumber(start));
+      this.toExternRef(), 'lastIndex'.toExternRef(), intToJSNumber(start));
 }
 
 class JSSyntaxRegExp implements RegExp {
@@ -99,9 +99,9 @@
     String modifiers = '$m$i$u$s$g';
     // The call to create the regexp is wrapped in a try catch so we can
     // reformat the exception if need be.
-    WasmAnyRef result = safeCallConstructorVarArgsRaw(
-        getConstructorRaw('RegExp'), [source, modifiers].toAnyRef());
-    if (isJSRegExp(result)) return JSNativeRegExp(result);
+    WasmExternRef? result = safeCallConstructorVarArgsRaw(
+        getConstructorRaw('RegExp'), [source, modifiers].toExternRef());
+    if (isJSRegExp(result)) return JSNativeRegExp(result!);
     // The returned value is the stringified JavaScript exception. Turn it into
     // a Dart exception.
     String errorMessage = jsStringToDartString(result);
@@ -194,7 +194,7 @@
     if (groups != null) {
       JSValue? result = groups[name];
       if (result != null ||
-          hasPropertyRaw(groups.toAnyRef(), name.toAnyRef())) {
+          hasPropertyRaw(groups.toExternRef(), name.toExternRef())) {
         return result?.toString();
       }
     }
diff --git a/sdk/lib/_internal/wasm/lib/stopwatch_patch.dart b/sdk/lib/_internal/wasm/lib/stopwatch_patch.dart
index b20f9eb..7265cff 100644
--- a/sdk/lib/_internal/wasm/lib/stopwatch_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/stopwatch_patch.dart
@@ -4,7 +4,7 @@
 
 // part of "core_patch.dart";
 
-@pragma("wasm:import", "performance.now")
+@pragma("wasm:import", "dart2wasm.performanceNow")
 external double _performanceNow();
 
 @patch
diff --git a/sdk/lib/_internal/wasm/lib/type.dart b/sdk/lib/_internal/wasm/lib/type.dart
index 8df02e3..aeb9d23 100644
--- a/sdk/lib/_internal/wasm/lib/type.dart
+++ b/sdk/lib/_internal/wasm/lib/type.dart
@@ -659,12 +659,6 @@
       return true;
     }
 
-    // TODO(joshualitt): This is not correct, but it is necessary until we fully
-    // implement RTI for FunctionTypes.
-    if (isFunctionType(s) && (t.isFunction || t.isGenericFunction)) {
-      return true;
-    }
-
     // Positional Function Types + Named Function Types:
     if (s.isGenericFunction && t.isGenericFunction) {
       // TODO(joshualitt): Implement case.
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index f83386d..bfdb082 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -842,7 +842,7 @@
   ///
   /// This method is equivalent to:
   /// ```dart
-  /// Future<T> whenComplete(action() {
+  /// Future<T> whenComplete(action()) {
   ///   return this.then((v) {
   ///     var f2 = action();
   ///     if (f2 is Future) return f2.then((_) => v);
@@ -880,37 +880,72 @@
   /// If the future never completes, the stream will not produce any events.
   Stream<T> asStream();
 
-  /// Time-out the future computation after [timeLimit] has passed.
+  /// Stop waiting for this future after [timeLimit] has passed.
   ///
-  /// Returns a new future that completes with the same value as this future,
-  /// if this future completes in time.
+  /// Creates a new _timeout future_ that completes
+  /// with the same result as this future, the _source future_,
+  /// *if* the source future completes in time.
   ///
-  /// If this future does not complete before `timeLimit` has passed,
-  /// the [onTimeout] action is executed instead, and its result (whether it
-  /// returns or throws) is used as the result of the returned future.
+  /// If the source future does not complete before [timeLimit] has passed,
+  /// the [onTimeout] action is executed,
+  /// and its result (whether it returns or throws)
+  /// is used as the result of the timeout future.
   /// The [onTimeout] function must return a [T] or a `Future<T>`.
+  /// If [onTimeout] returns a future, the _alternative result future_,
+  /// the eventual result of the alternative result future is used
+  /// to complete the timeout future,
+  /// even if the source future completes
+  /// before the alternative result future.
+  /// It only matters that the source future did not complete in time.
   ///
   /// If `onTimeout` is omitted, a timeout will cause the returned future to
   /// complete with a [TimeoutException].
   ///
-  /// Example:
+  /// In either case, the source future can still complete normally
+  /// at a later time.
+  /// It just won't be used as the result of the timeout future
+  /// unless it completes within the time bound.
+  ///
+  /// Examples:
   /// ```dart
   /// void main() async {
-  ///   var result = await waitTask()
-  ///       .timeout(const Duration(seconds: 10));
-  ///   print(result); // 'completed'
+  ///   var result =
+  ///       await waitTask("completed").timeout(const Duration(seconds: 10));
+  ///   print(result); // Prints "completed" after 5 seconds.
   ///
-  ///   result = await waitTask()
-  ///       .timeout(const Duration(seconds: 1), onTimeout: () => 'timeout');
-  ///   print(result); // 'timeout'
+  ///   result = await waitTask("completed")
+  ///       .timeout(const Duration(seconds: 1), onTimeout: () => "timeout");
+  ///   print(result); // Prints "timeout" after 1 second.
   ///
-  ///   result = await waitTask()
-  ///       .timeout(const Duration(seconds: 2)); // Throws.
+  ///   result = await waitTask("first").timeout(const Duration(seconds: 2),
+  ///       onTimeout: () => waitTask("second"));
+  ///   // Prints "second" after 7 seconds.
+  ///
+  ///   try {
+  ///     await waitTask("completed").timeout(const Duration(seconds: 2));
+  ///   } on TimeoutException {
+  ///     print("throws"); // Prints "throws" after 2 seconds.
+  ///   }
+  ///
+  ///   var printFuture = waitPrint();
+  ///   await printFuture.timeout(const Duration(seconds: 2), onTimeout: () {
+  ///     print("timeout");
+  ///   });
+  ///   // Prints "timeout" after 2 seconds.
+  ///   await printFuture;
+  ///   // Prints "printed" after additional 3 seconds.
   /// }
   ///
-  /// Future<String> waitTask() async {
+  /// // Returns [string] after five seconds.
+  /// Future<String> waitTask(String string) async {
   ///   await Future.delayed(const Duration(seconds: 5));
-  ///   return 'completed';
+  ///   return string;
+  /// }
+  ///
+  /// // Prints "printed" after five seconds.
+  /// Future<void> waitPrint() async {
+  ///   await Future.delayed(const Duration(seconds: 5));
+  ///   print("printed");
   /// }
   /// ```
   Future<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()?});
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index bdb1a01..e0d15c6 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -489,7 +489,6 @@
   external factory NoSuchMethodError.withInvocation(
       Object? receiver, Invocation invocation);
 
-  // Deprecated constructor to be removed after dart2js updates to the above.
   /// Create a [NoSuchMethodError] corresponding to a failed method call.
   ///
   /// The [receiver] is the receiver of the method call.
diff --git a/sdk/lib/core/function.dart b/sdk/lib/core/function.dart
index ea2d614..608b542 100644
--- a/sdk/lib/core/function.dart
+++ b/sdk/lib/core/function.dart
@@ -4,19 +4,112 @@
 
 part of dart.core;
 
-/// The base class for all function types.
+/// The supertype of all function types.
 ///
-/// The run-time type of a function object is subtype of a function type,
+/// The run-time type of a function object is a function type,
 /// and as such, a subtype of [Function].
+///
+/// The `Function` type does not carry information about the
+/// parameter signatures or return type of a function.
+/// To express a more precise function type, use the function type syntax,
+/// which is the `Function` keyword followed by a parameter list,
+/// or a type argument list and a parameter list, and which can also have
+/// an optional return type.
+///
+/// The function type syntax mirrors the definition of a function,
+/// with the function name replaced by the word "Function".
+///
+/// Example:
+/// ```dart
+/// String numberToString(int n) => "$n";
+/// String Function(int n) fun = numberToString; // Type annotation
+/// assert(fun is String Function(int)); // Type check.
+/// List<String Function(int)> functions = [fun]; // Type argument.
+/// ```
+/// The type `String Function(int)` is the type of a function
+/// that takes one positional `int` argument and returns a `String`.
+///
+/// Example with generic function type:
+/// ```dart
+/// T id<T>(T value) => value;
+/// X Function<X>(X) anotherId = id; // Parameter name may be omitted.
+/// int Function(int) intId = id<int>;
+/// ```
+///
+/// A function type can be used anywhere a type is allowed,
+/// and is often used for functions taking other functions, "callbacks",
+/// as arguments.
+///
+/// ```dart
+/// void doSomething(String Function(int) callback) {
+///   print(callback(1));
+/// }
+/// ```
+///
+/// A function type has all the members declared by [Object],
+/// since function types are subtypes of [Object].
+///
+/// A function type also has a `call` method with a signature
+/// that has the same function type as the function type itself.
+/// Calling the `call` method behaves just as calling the function.
+/// This is mainly used to conditionally call a nullable function value.
+/// ```dart
+/// String Function(int) fun = (n) => "$n";
+/// String Function(int) fun2 = fun.call; // Valid.
+/// print(fun2.call(1)); // Prints "1".
+///
+/// String Function(int)? maybeFun = Random().nextBool() ? fun : null;
+/// print(maybeFun?.call(1)); // Prints "1" or "null".
+/// ```
+///
+/// The [Function] type has a number of special features which are not visible
+/// in this `class` declaration.
+///
+/// The `Function` type itself allows any function to be assigned to it,
+/// since it is a supertype of any function type,
+/// but does not say how the function can be called.
+///
+/// However, a value with the static type `Function` *can* still be called
+/// like a function.
+/// ```dart
+/// Function f = (int x) => "$x";
+/// print(f(1)); // Prints "1".
+///
+/// f("not", "one", "int"); // Throws! No static warning.
+/// ```
+/// Such an invocation is a *dynamic* invocation,
+/// precisely as if the function value had been statically typed as [dynamic],
+/// and is precisely as unsafe as any other dynamic invocation.
+/// Checks will be performed at run-time to ensure that the argument
+/// list matches the function's parameters, and if not the call will
+/// fail with an [Error].
+/// There is no static type checking for such a call, any argument list
+/// is accepted and checked at runtime.
+///
+/// Like every function type has a `call` method with its own function type,
+/// the the `Function` type has a special `call` member
+/// which acts as if it is a method with a function type of `Function`
+/// (which is not a method signature which can be expression in normal
+/// Dart code).
+/// ```dart
+/// Function fun = (int x) => "$x";
+///
+/// var fun2 = f.call; // Inferred type of `fun2` is `Function`.
+///
+/// print(fun2.call(1)); // Prints "1";
+///
+/// Function? maybeFun = Random().nextBool() ? fun : null;
+/// print(maybeFun?.call(1)); // Prints "1" or "null".
+/// ```
 abstract class Function {
   /// Dynamically call [function] with the specified arguments.
   ///
-  /// Acts the same as calling function with positional arguments
-  /// corresponding to the elements of [positionalArguments] and
-  /// named arguments corresponding to the elements of [namedArguments].
+  /// Acts the same as dynamically calling [function] with
+  /// positional arguments corresponding to the elements of [positionalArguments]
+  /// and named arguments corresponding to the elements of [namedArguments].
   ///
-  /// This includes giving the same errors if [function] isn't callable or
-  /// if it expects different parameters.
+  /// This includes giving the same errors if [function]
+  /// expects different parameters.
   ///
   /// Example:
   /// ```dart
@@ -64,16 +157,43 @@
   ///
   /// - It is the same object. Static and top-level functions are compile time
   ///   constants when used as values, so referring to the same function twice
-  ///   always give the same object, as does referring to a local function
+  ///   always yields the same object, as does referring to a local function
   ///   declaration twice in the same scope where it was declared.
-  /// - if they refer to the same member method extracted from the same object.
-  ///   Repeatedly extracting an instance method of an object as a function value
+  ///   ```dart
+  ///   void main() {
+  ///     assert(identical(print, print));
+  ///     int add(int x, int y) => x + y;
+  ///     assert(identical(add, add));
+  ///   }
+  ///   ```
+  /// - The functions are same member method extracted from the same object.
+  ///   Repeatedly extracting ("tearing off") the same instance method of
+  ///   the same object to a function value
   ///   gives equal, but not necessarily identical, function values.
+  ///   ```dart
+  ///   var o = Object();
+  ///   assert(o.toString == o.toString);
+  ///   ```
+  /// - Instantiations of equal generic functions with the *same* types
+  ///   yields equal results.
+  ///   ```dart
+  ///    T id<T>(T value) => value;
+  ///    assert(id<int> == id<int>);
+  ///   ```
+  ///    (If the function is a constant and the type arguments are known at
+  ///    compile-time, the results may also be identical.)
   ///
   /// Different evaluations of function literals
   /// never give rise to equal function objects.
   /// Each time a function literal is evaluated,
   /// it creates a new function value that is not equal to any other function
   /// value, not even ones created by the same expression.
+  /// ```dart
+  /// var functions = <Function>[];
+  /// for (var i = 0; i < 2; i++) {
+  ///   functions.add((x) => x);
+  /// }
+  /// assert(functions[0] != functions[1]);
+  /// ```
   bool operator ==(Object other);
 }
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 3d27f1d..81cdcab 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -169,8 +169,9 @@
   /// When [queryParameters] is used, the query is built from the
   /// provided map. Each key and value in the map is percent-encoded
   /// and joined using equal and ampersand characters.
-  /// A value in the map must be either a string, or an [Iterable] of strings,
-  /// where the latter corresponds to multiple values for the same key.
+  /// A value in the map must be either `null`, a string, or an [Iterable] of
+  /// strings. An iterable corresponds to multiple values for the same key,
+  /// and an empty iterable or `null` corresponds to no value for the key.
   ///
   /// The percent-encoding of the keys and values encodes all characters
   /// except for the unreserved characters, and replaces spaces with `+`.
@@ -209,7 +210,7 @@
       String? path,
       Iterable<String>? pathSegments,
       String? query,
-      Map<String, dynamic /*String|Iterable<String>*/ >? queryParameters,
+      Map<String, dynamic /*String?|Iterable<String>*/ >? queryParameters,
       String? fragment}) = _Uri;
 
   /// Creates a new `http` URI from authority, path and query.
@@ -243,9 +244,11 @@
   ///
   /// The `query` component is set from the optional [queryParameters]
   /// argument.
-  factory Uri.http(String authority,
-      [String unencodedPath,
-      Map<String, dynamic>? queryParameters]) = _Uri.http;
+  factory Uri.http(
+    String authority, [
+    String unencodedPath,
+    Map<String, dynamic /*String?|Iterable<String>*/ >? queryParameters,
+  ]) = _Uri.http;
 
   /// Creates a new `https` URI from authority, path and query.
   ///
@@ -765,7 +768,7 @@
       String? path,
       Iterable<String>? pathSegments,
       String? query,
-      Map<String, dynamic /*String|Iterable<String>*/ >? queryParameters,
+      Map<String, dynamic /*String?|Iterable<String>*/ >? queryParameters,
       String? fragment});
 
   /// Creates a `Uri` that differs from this only in not having a fragment.
@@ -1637,7 +1640,7 @@
       String? path,
       Iterable<String>? pathSegments,
       String? query,
-      Map<String, dynamic /*String|Iterable<String>*/ >? queryParameters,
+      Map<String, dynamic /*String?|Iterable<String>*/ >? queryParameters,
       String? fragment}) {
     if (scheme == null) {
       scheme = "";
@@ -1947,7 +1950,7 @@
       String? path,
       Iterable<String>? pathSegments,
       String? query,
-      Map<String, dynamic /*String|Iterable<String>*/ >? queryParameters,
+      Map<String, dynamic /*String?|Iterable<String>*/ >? queryParameters,
       String? fragment}) {
     // Set to true if the scheme has (potentially) changed.
     // In that case, the default port may also have changed and we need
@@ -2341,7 +2344,7 @@
   }
 
   static String? _makeQuery(String? query, int start, int end,
-      Map<String, dynamic /*String|Iterable<String>*/ >? queryParameters) {
+      Map<String, dynamic /*String?|Iterable<String>*/ >? queryParameters) {
     if (query != null) {
       if (queryParameters != null) {
         throw ArgumentError('Both query and queryParameters specified');
@@ -4553,7 +4556,7 @@
       String? path,
       Iterable<String>? pathSegments,
       String? query,
-      Map<String, dynamic /*String|Iterable<String>*/ >? queryParameters,
+      Map<String, dynamic /*String?|Iterable<String>*/ >? queryParameters,
       String? fragment}) {
     bool schemeChanged = false;
     if (scheme != null) {
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index fc4abd4..aa525fd 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -16,6 +16,18 @@
 // TODO: This typedef is not used.
 typedef Future TimelineAsyncFunction();
 
+// These values must be kept in sync with the enum "EventType" in
+// runtime/vm/timeline.h.
+const int _begin = 1;
+const int _end = 2;
+const int _instant = 4;
+const int _asyncBegin = 5;
+const int _asyncInstant = 6;
+const int _asyncEnd = 7;
+const int _flowBegin = 9;
+const int _flowStep = 10;
+const int _flowEnd = 11;
+
 /// A class to represent Flow events.
 ///
 /// [Flow] objects are used to thread flow events between timeline slices,
@@ -41,12 +53,6 @@
 /// }, flow: Flow.end(flow.id));
 /// ```
 class Flow {
-  // These values must be kept in sync with the enum "EventType" in
-  // runtime/vm/timeline.h.
-  static const int _begin = 9;
-  static const int _step = 10;
-  static const int _end = 11;
-
   final int _type;
 
   /// The flow id of the flow event.
@@ -60,7 +66,7 @@
   /// If [id] is not provided, an id that conflicts with no other Dart-generated
   /// flow id's will be generated.
   static Flow begin({int? id}) {
-    return new Flow._(_begin, id ?? _getNextTaskId());
+    return new Flow._(_flowBegin, id ?? _getNextTaskId());
   }
 
   /// A "step" Flow event.
@@ -68,14 +74,14 @@
   /// When passed to a [Timeline] method, generates a "step" Flow event.
   /// The [id] argument is required. It can come either from another [Flow]
   /// event, or some id that comes from the environment.
-  static Flow step(int id) => new Flow._(_step, id);
+  static Flow step(int id) => new Flow._(_flowStep, id);
 
   /// An "end" Flow event.
   ///
   /// When passed to a [Timeline] method, generates a "end" Flow event.
   /// The [id] argument is required. It can come either from another [Flow]
   /// event, or some id that comes from the environment.
-  static Flow end(int id) => new Flow._(_end, id);
+  static Flow end(int id) => new Flow._(_flowEnd, id);
 }
 
 /// Add to the timeline.
@@ -145,11 +151,10 @@
       // Stream is disabled.
       return;
     }
-    Map? instantArguments;
-    if (arguments != null) {
-      instantArguments = new Map.from(arguments);
-    }
-    _reportInstantEvent('Dart', name, _argumentsAsJson(instantArguments));
+    // Instant events don't have an id because they don't need to be paired with
+    // other events.
+    int taskId = 0;
+    _reportTaskEvent(taskId, _instant, name, _argumentsAsJson(arguments));
   }
 
   /// A utility method to time a synchronous [function]. Internally calls
@@ -258,7 +263,7 @@
       instantArguments[_kFilterKey] = _filterKey;
     }
     _reportTaskEvent(
-        _taskId, 'n', 'Dart', name, _argumentsAsJson(instantArguments));
+        _taskId, _asyncInstant, name, _argumentsAsJson(instantArguments));
   }
 
   /// Finish the last synchronous operation that was started.
@@ -305,9 +310,6 @@
 /// An asynchronous block of time on the timeline. This block can be kept
 /// open across isolate messages.
 class _AsyncBlock {
-  /// The category this block belongs to.
-  final String category = 'Dart';
-
   /// The name of this block.
   final String name;
 
@@ -318,21 +320,18 @@
 
   // Emit the start event.
   void _start(Map arguments) {
-    _reportTaskEvent(_taskId, 'b', category, name, _argumentsAsJson(arguments));
+    _reportTaskEvent(_taskId, _asyncBegin, name, _argumentsAsJson(arguments));
   }
 
   // Emit the finish event.
   void _finish(Map? arguments) {
-    _reportTaskEvent(_taskId, 'e', category, name, _argumentsAsJson(arguments));
+    _reportTaskEvent(_taskId, _asyncEnd, name, _argumentsAsJson(arguments));
   }
 }
 
 /// A synchronous block of time on the timeline. This block should not be
 /// kept open across isolate messages.
 class _SyncBlock {
-  /// The category this block belongs to.
-  final String category = 'Dart';
-
   /// The name of this block.
   final String name;
 
@@ -352,17 +351,17 @@
 
   /// Start this block of time.
   void _startSync() {
-    _reportTaskEvent(taskId, 'B', category, name, _jsonArguments);
+    _reportTaskEvent(taskId, _begin, name, _jsonArguments);
   }
 
   /// Finish this block of time. At this point, this block can no longer be
   /// used.
   void finish() {
     // Report event to runtime.
-    _reportTaskEvent(taskId, 'E', category, name, _jsonArguments);
+    _reportTaskEvent(taskId, _end, name, _jsonArguments);
     final Flow? tempFlow = flow;
     if (tempFlow != null) {
-      _reportFlowEvent(category, "${tempFlow.id}", tempFlow._type, tempFlow.id,
+      _reportTaskEvent(tempFlow.id, tempFlow._type, "${tempFlow.id}",
           _argumentsAsJson(null));
     }
   }
@@ -388,13 +387,5 @@
 external int _getTraceClock();
 
 /// Reports an event for a task.
-external void _reportTaskEvent(int taskId, String phase, String category,
-    String name, String argumentsAsJson);
-
-/// Reports a flow event.
-external void _reportFlowEvent(
-    String category, String name, int type, int id, String argumentsAsJson);
-
-/// Reports an instant event.
-external void _reportInstantEvent(
-    String category, String name, String argumentsAsJson);
+external void _reportTaskEvent(
+    int taskId, int type, String name, String argumentsAsJson);
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 512f152..26d027a 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -5434,19 +5434,18 @@
 
 class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase {
   final Iterable<Element> _elementIterable;
-  Iterable<CssStyleDeclaration>? _elementCssStyleDeclarationSetIterable;
+  Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable;
 
-  _CssStyleDeclarationSet(this._elementIterable) {
-    _elementCssStyleDeclarationSetIterable =
-        new List.from(_elementIterable).map((e) => e.style);
-  }
+  _CssStyleDeclarationSet(this._elementIterable)
+      : _elementCssStyleDeclarationSetIterable =
+            new List.of(_elementIterable).map((e) => e.style);
 
   String getPropertyValue(String propertyName) =>
-      _elementCssStyleDeclarationSetIterable!.first
+      _elementCssStyleDeclarationSetIterable.first
           .getPropertyValue(propertyName);
 
   void setProperty(String propertyName, String? value, [String? priority]) {
-    _elementCssStyleDeclarationSetIterable!
+    _elementCssStyleDeclarationSetIterable
         .forEach((e) => e.setProperty(propertyName, value, priority));
   }
 
@@ -34638,6 +34637,7 @@
   }
 
   // From ChildNode
+
 }
 
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
@@ -35752,6 +35752,7 @@
   }
 
   // From URLUtilsReadOnly
+
 }
 
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -35769,6 +35770,7 @@
   // From NavigatorID
 
   // From NavigatorOnLine
+
 }
 
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -37321,10 +37323,6 @@
   bool get isBroadcast => true;
 }
 
-// We would like this to just be EventListener<T> but that typdef cannot
-// use generics until dartbug/26276 is fixed.
-typedef _EventListener<T extends Event>(T event);
-
 class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
   int _pauseCount = 0;
   EventTarget? _target;
@@ -37332,19 +37330,13 @@
   EventListener? _onData;
   final bool _useCapture;
 
-  // TODO(leafp): It would be better to write this as
-  // _onData = onData == null ? null :
-  //   onData is void Function(Event)
-  //     ? _wrapZone<Event>(onData)
-  //     : _wrapZone<Event>((e) => onData(e as T))
-  // In order to support existing tests which pass the wrong type of events but
-  // use a more general listener, without causing as much slowdown for things
-  // which are typed correctly.  But this currently runs afoul of restrictions
-  // on is checks for compatibility with the VM.
   _EventStreamSubscription(
       this._target, this._eventType, void onData(T event)?, this._useCapture)
       : _onData = onData == null
             ? null
+            // If removed, we would need an `is` check on a function type which
+            // is ultimately more expensive.
+            // ignore: avoid_dynamic_calls
             : _wrapZone<Event>((e) => (onData as dynamic)(e)) {
     _tryResume();
   }
@@ -37369,6 +37361,9 @@
     _unlisten();
     _onData = handleData == null
         ? null
+        // If removed, we would need an `is` check on a function type which is
+        // ultimately more expensive.
+        // ignore: avoid_dynamic_calls
         : _wrapZone<Event>((e) => (handleData as dynamic)(e));
     _tryResume();
   }
@@ -40155,15 +40150,16 @@
   };
 }
 
-_callAttached(receiver) {
+_callAttached(Element receiver) {
   return receiver.attached();
 }
 
-_callDetached(receiver) {
+_callDetached(Element receiver) {
   return receiver.detached();
 }
 
-_callAttributeChanged(receiver, name, oldValue, newValue) {
+_callAttributeChanged(
+    Element receiver, String name, String oldValue, String newValue) {
   return receiver.attributeChanged(name, oldValue, newValue);
 }
 
@@ -40205,7 +40201,8 @@
   }
 }
 
-Function _registerCustomElement(context, document, String tag, [Map? options]) {
+Function _registerCustomElement(context, Document document, String tag,
+    [Map? options]) {
   // Function follows the same pattern as the following JavaScript code for
   // registering a custom element.
   //
@@ -40596,7 +40593,7 @@
       view = window;
     }
 
-    dynamic eventObj;
+    KeyboardEvent eventObj;
 
     // Currently this works on everything but Safari. Safari throws an
     // "Attempting to change access mechanism for an unconfigurable property"
@@ -40607,7 +40604,7 @@
     // initialize initKeyEvent.
 
     eventObj = new Event.eventType('KeyboardEvent', type,
-        canBubble: canBubble, cancelable: cancelable);
+        canBubble: canBubble, cancelable: cancelable) as KeyboardEvent;
 
     // Chromium Hack
     JS(
@@ -41130,7 +41127,11 @@
     var isAttr;
     try {
       // If getting/indexing attributes throws, count that as corrupt.
+      // Don't remove dynamic calls in sanitizing code.
+      // ignore: avoid_dynamic_calls
       attrs = element.attributes;
+      // Don't remove dynamic calls in sanitizing code.
+      // ignore: avoid_dynamic_calls
       isAttr = attrs['is'];
       var corruptedTest1 = Element._hasCorruptedAttributes(element);
 
@@ -41191,7 +41192,11 @@
     for (var i = attrs.length - 1; i >= 0; --i) {
       var name = keys[i];
       if (!validator.allowsAttribute(
-          element, name.toLowerCase(), attrs[name])) {
+          element,
+          // Don't remove dynamic calls in sanitizing code.
+          // ignore: avoid_dynamic_calls
+          name.toLowerCase(),
+          attrs[name])) {
         window.console.warn('Removing disallowed attribute '
             '<$tag $name="${attrs[name]}">');
         attrs.remove(name);
diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart
index 6a91a31..c4e2faf 100644
--- a/sdk/lib/html/html_common/conversions.dart
+++ b/sdk/lib/html/html_common/conversions.dart
@@ -245,11 +245,11 @@
       var slot = findSlot(e);
       var copy = readSlot(slot);
       if (copy != null) return copy;
-      copy = {};
+      var map = {};
 
-      writeSlot(slot, copy);
-      forEachJsField(e, (key, value) => copy[key] = walk(value));
-      return copy;
+      writeSlot(slot, map);
+      forEachJsField(e, (key, value) => map[key] = walk(value));
+      return map;
     }
 
     if (isJavaScriptArray(e)) {
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index 252d602..6150901 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.dart
@@ -15,24 +15,21 @@
 const int _osErrorResponseErrorCode = 1;
 const int _osErrorResponseMessage = 2;
 
-// Functions used to receive exceptions from native ports.
-bool _isErrorResponse(response) =>
-    response is List && response[0] != _successResponse;
-
-/// Returns an [Exception] or an [Error].
-_exceptionFromResponse(response, String message, String path) {
-  assert(_isErrorResponse(response));
-  switch (response[_errorResponseErrorType]) {
-    case _illegalArgumentResponse:
-      return new ArgumentError("$message: $path");
-    case _osErrorResponse:
-      var err = new OSError(response[_osErrorResponseMessage],
-          response[_osErrorResponseErrorCode]);
-      return new FileSystemException(message, path, err);
-    case _fileClosedResponse:
-      return new FileSystemException("File closed", path);
-    default:
-      return new Exception("Unknown error");
+/// If the [response] is an error, throws an [Exception] or an [Error].
+void _checkForErrorResponse(Object? response, String message, String path) {
+  if (response is List<Object?> && response[0] != _successResponse) {
+    switch (response[_errorResponseErrorType]) {
+      case _illegalArgumentResponse:
+        throw ArgumentError("$message: $path");
+      case _osErrorResponse:
+        var err = OSError(response[_osErrorResponseMessage] as String,
+            response[_osErrorResponseErrorCode] as int);
+        throw FileSystemException(message, path, err);
+      case _fileClosedResponse:
+        throw FileSystemException("File closed", path);
+      default:
+        throw AssertionError("Unknown error");
+    }
   }
 }
 
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index d3bc43f..ae8abf9 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -81,9 +81,7 @@
   Future<bool> exists() {
     return _File._dispatchWithNamespace(
         _IOService.directoryExists, [null, _rawPath]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionOrErrorFromResponse(response, "Exists failed");
-      }
+      _checkForErrorResponse(response, "Exists failed");
       return response == 1;
     });
   }
@@ -113,9 +111,7 @@
     } else {
       return _File._dispatchWithNamespace(
           _IOService.directoryCreate, [null, _rawPath]).then((response) {
-        if (_isErrorResponse(response)) {
-          throw _exceptionOrErrorFromResponse(response, "Creation failed");
-        }
+        _checkForErrorResponse(response, "Creation failed");
         return this;
       });
     }
@@ -153,11 +149,9 @@
     }
     return _File._dispatchWithNamespace(_IOService.directoryCreateTemp,
         [null, FileSystemEntity._toUtf8Array(fullPrefix)]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionOrErrorFromResponse(
-            response, "Creation of temporary directory failed");
-      }
-      return new Directory(response);
+      _checkForErrorResponse(
+          response, "Creation of temporary directory failed");
+      return Directory(response as String);
     });
   }
 
@@ -188,9 +182,7 @@
     return _File._dispatchWithNamespace(
             _IOService.directoryDelete, [null, _rawPath, recursive])
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionOrErrorFromResponse(response, "Deletion failed");
-      }
+      _checkForErrorResponse(response, "Deletion failed");
       return this;
     });
   }
@@ -205,9 +197,7 @@
   Future<Directory> rename(String newPath) {
     return _File._dispatchWithNamespace(
         _IOService.directoryRename, [null, _rawPath, newPath]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionOrErrorFromResponse(response, "Rename failed");
-      }
+      _checkForErrorResponse(response, "Rename failed");
       return new Directory(newPath);
     });
   }
@@ -254,20 +244,19 @@
 
   String toString() => "Directory: '$path'";
 
-  bool _isErrorResponse(response) =>
-      response is List && response[0] != _successResponse;
-
-  _exceptionOrErrorFromResponse(response, String message) {
-    assert(_isErrorResponse(response));
-    switch (response[_errorResponseErrorType]) {
-      case _illegalArgumentResponse:
-        return new ArgumentError();
-      case _osErrorResponse:
-        var err = new OSError(response[_osErrorResponseMessage],
-            response[_osErrorResponseErrorCode]);
-        return new FileSystemException(message, path, err);
-      default:
-        return new Exception("Unknown error");
+  /// If the [response] is an error, throws an [Exception] or an [Error].
+  void _checkForErrorResponse(Object? response, String message) {
+    if (response is List<Object?> && response[0] != _successResponse) {
+      switch (response[_errorResponseErrorType]) {
+        case _illegalArgumentResponse:
+          throw ArgumentError();
+        case _osErrorResponse:
+          var err = OSError(response[_osErrorResponseMessage] as String,
+              response[_osErrorResponseErrorCode] as int);
+          throw FileSystemException(message, path, err);
+        default:
+          throw AssertionError("Unknown error");
+      }
     }
   }
 
@@ -335,7 +324,7 @@
         controller.addError(response, response.stackTrace);
         close();
       } else {
-        error(response);
+        error(response as List<Object?>);
         close();
       }
     });
@@ -426,22 +415,23 @@
     }
   }
 
-  void error(message) {
-    var errorType = message[responseError][_errorResponseErrorType];
+  void error(List<Object?> message) {
+    var errorResponseInfo = message[responseError]! as List<Object?>;
+    var errorType = errorResponseInfo[_errorResponseErrorType];
     if (errorType == _illegalArgumentResponse) {
       controller.addError(new ArgumentError());
     } else if (errorType == _osErrorResponse) {
-      var responseErrorInfo = message[responseError];
-      var err = new OSError(responseErrorInfo[_osErrorResponseMessage],
-          responseErrorInfo[_osErrorResponseErrorCode]);
+      var err = new OSError(
+          errorResponseInfo[_osErrorResponseMessage] as String,
+          errorResponseInfo[_osErrorResponseErrorCode] as int);
       var errorPath = message[responsePath];
       if (errorPath == null) {
         errorPath = utf8.decode(rawPath, allowMalformed: true);
       } else if (errorPath is Uint8List) {
-        errorPath = utf8.decode(message[responsePath], allowMalformed: true);
+        errorPath = utf8.decode(errorPath, allowMalformed: true);
       }
-      controller.addError(
-          new FileSystemException("Directory listing failed", errorPath, err));
+      controller.addError(new FileSystemException(
+          "Directory listing failed", errorPath as String, err));
     } else {
       controller.addError(new FileSystemException("Internal error"));
     }
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 41ced7e..0b532a3 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -442,6 +442,12 @@
   /// In order to make sure that system resources are freed, the stream
   /// must be read to completion or the subscription on the stream must
   /// be cancelled.
+  ///
+  /// If [File] is a [named pipe](https://en.wikipedia.org/wiki/Named_pipe)
+  /// then the returned [Stream] will wait until the write side of the pipe
+  /// is closed before signaling "done". If there are no writers attached
+  /// to the pipe when it is opened, then [Stream.listen] will wait until
+  /// a writer opens the pipe.
   Stream<List<int>> openRead([int? start, int? end]);
 
   /// Creates a new independent [IOSink] for the file.
@@ -909,3 +915,61 @@
     return sb.toString();
   }
 }
+
+/// The "read" end of an [Pipe] created by [Pipe.create].
+///
+/// The read stream will continue to listen until the "write" end of the
+/// pipe (i.e. [Pipe.write]) is closed.
+///
+/// ```dart
+/// final pipe = await Pipe.create();
+/// pipe.read.transform(utf8.decoder).listen((data) {
+///   print(data);
+/// }, onDone: () => print('Done'));
+/// ```
+abstract class ReadPipe implements Stream<List<int>> {}
+
+/// The "write" end of an [Pipe] created by [Pipe.create].
+///
+/// ```dart
+/// final pipe = await Pipe.create();
+/// pipe.write.add("Hello World!".codeUnits);
+/// pipe.write.close();
+/// ```
+abstract class WritePipe implements IOSink {}
+
+/// An anonymous pipe that can be used to send data in a single direction i.e.
+/// data written to [write] can be read using [read].
+///
+/// On macOS and Linux (excluding Android), either the [read] or [write]
+/// portion of the pipe can be transmitted to another process and used for
+/// interprocess communication.
+///
+/// For example:
+/// ```dart
+/// final pipe = await Pipe.create();
+/// final socket = await RawSocket.connect(address, 0);
+/// socket.sendMessage(<SocketControlMessage>[
+/// SocketControlMessage.fromHandles(
+///     <ResourceHandle>[ResourceHandle.fromReadPipe(pipe.read)])
+/// ], 'Hello'.codeUnits);
+/// pipe.write.add('Hello over pipe!'.codeUnits);
+/// pipe.write.close();
+/// ```
+abstract class Pipe {
+  /// The read end of the [Pipe].
+  ReadPipe get read;
+
+  /// The write end of the [Pipe].
+  WritePipe get write;
+
+  // Create an anonymous pipe.
+  static Future<Pipe> create() {
+    return _Pipe.create();
+  }
+
+  /// Synchronously creates an anonymous pipe.
+  factory Pipe.createSync() {
+    return _Pipe.createSync();
+  }
+}
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index f695a16..688484e 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -13,7 +13,7 @@
 
   // Information about the underlying file.
   String? _path;
-  late RandomAccessFile _openedFile;
+  RandomAccessFile? _openedFile;
   int _position;
   int? _end;
   final Completer _closeCompleter = new Completer();
@@ -31,6 +31,10 @@
 
   _FileStream.forStdin() : _position = 0;
 
+  _FileStream.forRandomAccessFile(RandomAccessFile f)
+      : _position = 0,
+        _openedFile = f;
+
   StreamSubscription<Uint8List> listen(void onData(Uint8List event)?,
       {Function? onError, void onDone()?, bool? cancelOnError}) {
     _controller = new StreamController<Uint8List>(
@@ -56,7 +60,7 @@
       _controller.close();
     }
 
-    _openedFile.close().catchError(_controller.addError).whenComplete(done);
+    _openedFile!.close().catchError(_controller.addError).whenComplete(done);
     return _closeCompleter.future;
   }
 
@@ -82,20 +86,27 @@
         return;
       }
     }
-    _openedFile.read(readBytes).then((block) {
+    _openedFile!.read(readBytes).then((block) {
       _readInProgress = false;
       if (_unsubscribed) {
         _closeFile();
         return;
       }
       _position += block.length;
-      if (block.length < readBytes || (_end != null && _position == _end)) {
+      // read() may return less than `readBytes` if `_openFile` is a pipe or
+      // terminal or if a signal is received. Only a empty return indicates
+      // that the write side of the pipe is closed or that we are at the end
+      // of a file.
+      // See https://man7.org/linux/man-pages/man2/read.2.html
+      if (block.length == 0 || (_end != null && _position == _end)) {
         _atEnd = true;
       }
       if (!_atEnd && !_controller.isPaused) {
         _readBlock();
       }
-      _controller.add(block);
+      if (block.length > 0) {
+        _controller.add(block);
+      }
       if (_atEnd) {
         _closeFile();
       }
@@ -141,7 +152,10 @@
     }
 
     final path = _path;
-    if (path != null) {
+    final openedFile = _openedFile;
+    if (openedFile != null) {
+      onOpenFile(openedFile);
+    } else if (path != null) {
       new File(path)
           .open(mode: FileMode.read)
           .then(onOpenFile, onError: openFailed);
@@ -166,6 +180,9 @@
   _FileStreamConsumer.fromStdio(int fd)
       : _openFuture = new Future.value(_File._openStdioSync(fd));
 
+  _FileStreamConsumer.fromRandomAccessFile(RandomAccessFile f)
+      : _openFuture = Future.value(f);
+
   Future<File?> addStream(Stream<List<int>> stream) {
     Completer<File?> completer = new Completer<File?>.sync();
     _openFuture.then((openedFile) {
@@ -219,7 +236,7 @@
   // with it.
   static int _namespacePointer() => _Namespace._namespacePointer;
 
-  static Future _dispatchWithNamespace(int request, List data) {
+  static Future<Object?> _dispatchWithNamespace(int request, List data) {
     data[0] = _namespacePointer();
     return _IOService._dispatch(request, data);
   }
@@ -227,10 +244,8 @@
   Future<bool> exists() {
     return _dispatchWithNamespace(_IOService.fileExists, [null, _rawPath])
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "Cannot check existence", path);
-      }
-      return response;
+      _checkForErrorResponse(response, "Cannot check existence", path);
+      return response as bool;
     });
   }
 
@@ -251,9 +266,7 @@
         .then((_) => _dispatchWithNamespace(
             _IOService.fileCreate, [null, _rawPath, exclusive]))
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "Cannot create file", path);
-      }
+      _checkForErrorResponse(response, "Cannot create file", path);
       return this;
     });
   }
@@ -264,6 +277,8 @@
   external static _createLink(
       _Namespace namespace, Uint8List rawPath, String target);
 
+  external static List<dynamic> _createPipe(_Namespace namespace);
+
   external static _linkTarget(_Namespace namespace, Uint8List rawPath);
 
   void createSync({bool recursive = false, bool exclusive = false}) {
@@ -280,9 +295,7 @@
     }
     return _dispatchWithNamespace(_IOService.fileDelete, [null, _rawPath])
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "Cannot delete file", path);
-      }
+      _checkForErrorResponse(response, "Cannot delete file", path);
       return this;
     });
   }
@@ -302,10 +315,8 @@
   Future<File> rename(String newPath) {
     return _dispatchWithNamespace(
         _IOService.fileRename, [null, _rawPath, newPath]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(
-            response, "Cannot rename file to '$newPath'", path);
-      }
+      _checkForErrorResponse(
+          response, "Cannot rename file to '$newPath'", path);
       return new File(newPath);
     });
   }
@@ -325,10 +336,7 @@
   Future<File> copy(String newPath) {
     return _dispatchWithNamespace(
         _IOService.fileCopy, [null, _rawPath, newPath]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(
-            response, "Cannot copy file to '$newPath'", path);
-      }
+      _checkForErrorResponse(response, "Cannot copy file to '$newPath'", path);
       return new File(newPath);
     });
   }
@@ -353,21 +361,16 @@
     }
     return _dispatchWithNamespace(
         _IOService.fileOpen, [null, _rawPath, mode._mode]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "Cannot open file", path);
-      }
-      return new _RandomAccessFile(response, path);
+      _checkForErrorResponse(response, "Cannot open file", path);
+      return _RandomAccessFile(response as int, path);
     });
   }
 
   Future<int> length() {
     return _dispatchWithNamespace(
         _IOService.fileLengthFromPath, [null, _rawPath]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(
-            response, "Cannot retrieve length of file", path);
-      }
-      return response;
+      _checkForErrorResponse(response, "Cannot retrieve length of file", path);
+      return response as int;
     });
   }
 
@@ -382,11 +385,8 @@
   Future<DateTime> lastAccessed() {
     return _dispatchWithNamespace(_IOService.fileLastAccessed, [null, _rawPath])
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(
-            response, "Cannot retrieve access time", path);
-      }
-      return new DateTime.fromMillisecondsSinceEpoch(response);
+      _checkForErrorResponse(response, "Cannot retrieve access time", path);
+      return DateTime.fromMillisecondsSinceEpoch(response as int);
     });
   }
 
@@ -403,9 +403,7 @@
     return _dispatchWithNamespace(
             _IOService.fileSetLastAccessed, [null, _rawPath, millis])
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "Cannot set access time", path);
-      }
+      _checkForErrorResponse(response, "Cannot set access time", path);
       return null;
     });
   }
@@ -425,11 +423,9 @@
   Future<DateTime> lastModified() {
     return _dispatchWithNamespace(_IOService.fileLastModified, [null, _rawPath])
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(
-            response, "Cannot retrieve modification time", path);
-      }
-      return new DateTime.fromMillisecondsSinceEpoch(response);
+      _checkForErrorResponse(
+          response, "Cannot retrieve modification time", path);
+      return DateTime.fromMillisecondsSinceEpoch(response as int);
     });
   }
 
@@ -446,10 +442,7 @@
     return _dispatchWithNamespace(
             _IOService.fileSetLastModified, [null, _rawPath, millis])
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(
-            response, "Cannot set modification time", path);
-      }
+      _checkForErrorResponse(response, "Cannot set modification time", path);
       return null;
     });
   }
@@ -724,11 +717,9 @@
 
   Future<int> readByte() {
     return _dispatch(_IOService.fileReadByte, [null]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "readByte failed", path);
-      }
+      _checkForErrorResponse(response, "readByte failed", path);
       _resourceInfo.addRead(1);
-      return response;
+      return response as int;
     });
   }
 
@@ -746,11 +737,9 @@
     // TODO(40614): Remove once non-nullability is sound.
     ArgumentError.checkNotNull(bytes, "bytes");
     return _dispatch(_IOService.fileRead, [null, bytes]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "read failed", path);
-      }
-      _resourceInfo.addRead(response[1].length);
-      Uint8List result = response[1];
+      _checkForErrorResponse(response, "read failed", path);
+      var result = (response as List<Object?>)[1] as Uint8List;
+      _resourceInfo.addRead(result.length);
       return result;
     });
   }
@@ -760,8 +749,8 @@
     ArgumentError.checkNotNull(bytes, "bytes");
     _checkAvailable();
     var result = _ops.read(bytes);
-    if (result is OSError) {
-      throw new FileSystemException("readSync failed", path, result);
+    if (result is! Uint8List) {
+      throw new FileSystemException("readSync failed", path, result as OSError);
     }
     _resourceInfo.addRead(result.length);
     return result;
@@ -776,11 +765,10 @@
     }
     int length = end - start;
     return _dispatch(_IOService.fileReadInto, [null, length]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "readInto failed", path);
-      }
-      int read = response[1];
-      List<int> data = response[2];
+      _checkForErrorResponse(response, "readInto failed", path);
+      var responseList = response as List<Object?>;
+      var read = responseList[1] as int;
+      var data = responseList[2] as List<int>;
       buffer.setRange(start, start + read, data);
       _resourceInfo.addRead(read);
       return read;
@@ -807,9 +795,7 @@
     // TODO(40614): Remove once non-nullability is sound.
     ArgumentError.checkNotNull(value, "value");
     return _dispatch(_IOService.fileWriteByte, [null, value]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "writeByte failed", path);
-      }
+      _checkForErrorResponse(response, "writeByte failed", path);
       _resourceInfo.addWrite(1);
       return this;
     });
@@ -849,9 +835,7 @@
     request[2] = result.start;
     request[3] = end - (start - result.start);
     return _dispatch(_IOService.fileWriteFrom, request).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "writeFrom failed", path);
-      }
+      _checkForErrorResponse(response, "writeFrom failed", path);
       _resourceInfo.addWrite(end! - (start - result.start));
       return this;
     });
@@ -893,10 +877,8 @@
 
   Future<int> position() {
     return _dispatch(_IOService.filePosition, [null]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "position failed", path);
-      }
-      return response;
+      _checkForErrorResponse(response, "position failed", path);
+      return response as int;
     });
   }
 
@@ -912,9 +894,7 @@
   Future<RandomAccessFile> setPosition(int position) {
     return _dispatch(_IOService.fileSetPosition, [null, position])
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "setPosition failed", path);
-      }
+      _checkForErrorResponse(response, "setPosition failed", path);
       return this;
     });
   }
@@ -929,9 +909,7 @@
 
   Future<RandomAccessFile> truncate(int length) {
     return _dispatch(_IOService.fileTruncate, [null, length]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "truncate failed", path);
-      }
+      _checkForErrorResponse(response, "truncate failed", path);
       return this;
     });
   }
@@ -946,10 +924,8 @@
 
   Future<int> length() {
     return _dispatch(_IOService.fileLength, [null]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "length failed", path);
-      }
-      return response;
+      _checkForErrorResponse(response, "length failed", path);
+      return response as int;
     });
   }
 
@@ -964,9 +940,7 @@
 
   Future<RandomAccessFile> flush() {
     return _dispatch(_IOService.fileFlush, [null]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "flush failed", path);
-      }
+      _checkForErrorResponse(response, "flush failed", path);
       return this;
     });
   }
@@ -999,9 +973,7 @@
     int lock = _fileLockValue(mode);
     return _dispatch(_IOService.fileLock, [null, lock, start, end])
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, 'lock failed', path);
-      }
+      _checkForErrorResponse(response, 'lock failed', path);
       return this;
     });
   }
@@ -1015,9 +987,7 @@
     }
     return _dispatch(_IOService.fileLock, [null, lockUnlock, start, end])
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, 'unlock failed', path);
-      }
+      _checkForErrorResponse(response, 'unlock failed', path);
       return this;
     });
   }
@@ -1064,7 +1034,7 @@
   // count when it is finished with it.
   int _pointer() => _ops.getPointer();
 
-  Future _dispatch(int request, List data, {bool markClosed = false}) {
+  Future<Object?> _dispatch(int request, List data, {bool markClosed = false}) {
     if (closed) {
       return new Future.error(new FileSystemException("File closed", path));
     }
@@ -1094,3 +1064,43 @@
     }
   }
 }
+
+class _ReadPipe extends _FileStream implements ReadPipe {
+  _ReadPipe(RandomAccessFile file) : super.forRandomAccessFile(file);
+}
+
+class _WritePipe extends _IOSinkImpl implements WritePipe {
+  RandomAccessFile _file;
+  _WritePipe(file)
+      : this._file = file,
+        super(_FileStreamConsumer.fromRandomAccessFile(file), utf8);
+}
+
+class _Pipe implements Pipe {
+  final ReadPipe _readPipe;
+  final WritePipe _writePipe;
+
+  ReadPipe get read => _readPipe;
+  WritePipe get write => _writePipe;
+
+  _Pipe(this._readPipe, this._writePipe);
+
+  static Future<_Pipe> create() {
+    final completer = Completer<_Pipe>.sync();
+
+    _File._dispatchWithNamespace(_IOService.fileCreatePipe, [null])
+        .then((response) {
+      final filePointers = (response as List).cast<int>();
+      completer.complete(_Pipe(
+          _ReadPipe(_RandomAccessFile(filePointers[0], '')),
+          _WritePipe(_RandomAccessFile(filePointers[1], ''))));
+    });
+    return completer.future;
+  }
+
+  factory _Pipe.createSync() {
+    final filePointers = _File._createPipe(_Namespace._namespace);
+    return _Pipe(_ReadPipe(_RandomAccessFile(filePointers[0] as int, '')),
+        _WritePipe(_RandomAccessFile(filePointers[1] as int, '')));
+  }
+}
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index e3b9075..bf28a90 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -120,11 +120,11 @@
       path = FileSystemEntity._trimTrailingPathSeparators(path);
     }
     var data = _statSync(_Namespace._namespace, path);
-    if (data is OSError) return FileStat._notFound;
-    return new FileStat._internal(
-        new DateTime.fromMillisecondsSinceEpoch(data[_changedTime]),
-        new DateTime.fromMillisecondsSinceEpoch(data[_modifiedTime]),
-        new DateTime.fromMillisecondsSinceEpoch(data[_accessedTime]),
+    if (data is! Int64List) return FileStat._notFound;
+    return FileStat._internal(
+        DateTime.fromMillisecondsSinceEpoch(data[_changedTime]),
+        DateTime.fromMillisecondsSinceEpoch(data[_modifiedTime]),
+        DateTime.fromMillisecondsSinceEpoch(data[_accessedTime]),
         FileSystemEntityType._lookup(data[_type]),
         data[_mode],
         data[_size]);
@@ -152,18 +152,18 @@
     }
     return _File._dispatchWithNamespace(_IOService.fileStat, [null, path])
         .then((response) {
-      if (_isErrorResponse(response)) {
+      if (response is List<Object?> && response[0] != _successResponse) {
         return FileStat._notFound;
       }
       // Unwrap the real list from the "I'm not an error" wrapper.
-      List data = response[1];
-      return new FileStat._internal(
-          new DateTime.fromMillisecondsSinceEpoch(data[_changedTime]),
-          new DateTime.fromMillisecondsSinceEpoch(data[_modifiedTime]),
-          new DateTime.fromMillisecondsSinceEpoch(data[_accessedTime]),
-          FileSystemEntityType._lookup(data[_type]),
-          data[_mode],
-          data[_size]);
+      var data = (response as List)[1] as List<Object?>;
+      return FileStat._internal(
+          DateTime.fromMillisecondsSinceEpoch(data[_changedTime] as int),
+          DateTime.fromMillisecondsSinceEpoch(data[_modifiedTime] as int),
+          DateTime.fromMillisecondsSinceEpoch(data[_accessedTime] as int),
+          FileSystemEntityType._lookup(data[_type] as int),
+          data[_mode] as int,
+          data[_size] as int);
     });
   }
 
@@ -321,11 +321,8 @@
   Future<String> resolveSymbolicLinks() {
     return _File._dispatchWithNamespace(
         _IOService.fileResolveSymbolicLinks, [null, _rawPath]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(
-            response, "Cannot resolve symbolic links", path);
-      }
-      return response;
+      _checkForErrorResponse(response, "Cannot resolve symbolic links", path);
+      return response as String;
     });
   }
 
@@ -474,11 +471,9 @@
   static Future<bool> _identical(String path1, String path2) {
     return _File._dispatchWithNamespace(
         _IOService.fileIdentical, [null, path1, path2]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response,
-            "Error in FileSystemEntity.identical($path1, $path2)", "");
-      }
-      return response;
+      _checkForErrorResponse(
+          response, "Error in FileSystemEntity.identical($path1, $path2)", "");
+      return response as bool;
     });
   }
 
@@ -814,11 +809,9 @@
       Uint8List rawPath, bool followLinks) {
     return _File._dispatchWithNamespace(
         _IOService.fileType, [null, rawPath, followLinks]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "Error getting type",
-            utf8.decode(rawPath, allowMalformed: true));
-      }
-      return FileSystemEntityType._lookup(response);
+      _checkForErrorResponse(response, "Error getting type",
+          utf8.decode(rawPath, allowMalformed: true));
+      return FileSystemEntityType._lookup(response as int);
     });
   }
 
diff --git a/sdk/lib/io/io_resource_info.dart b/sdk/lib/io/io_resource_info.dart
index 3ba76c9..385e7f3 100644
--- a/sdk/lib/io/io_resource_info.dart
+++ b/sdk/lib/io/io_resource_info.dart
@@ -88,7 +88,7 @@
 class _FileResourceInfo extends _ReadWriteResourceInfo {
   static const String _type = 'OpenFile';
 
-  final file;
+  final RandomAccessFile file;
 
   static Map<int, _FileResourceInfo> openFiles = {};
 
@@ -112,7 +112,8 @@
     ));
   }
 
-  static Future<ServiceExtensionResponse> getOpenFiles(function, params) {
+  static Future<ServiceExtensionResponse> getOpenFiles(
+      String function, Map<String, String> params) {
     assert(function == 'ext.dart.io.getOpenFiles');
     final data = {
       'type': 'OpenFileList',
@@ -125,7 +126,7 @@
   Map<String, dynamic> get fileInfoMap => fullValueMap;
 
   static Future<ServiceExtensionResponse> getOpenFileInfoMapByID(
-      function, params) {
+      String function, Map<String, String> params) {
     final id = int.parse(params['id']!);
     final result = openFiles.containsKey(id) ? openFiles[id]!.fileInfoMap : {};
     final jsonValue = json.encode(result);
@@ -135,9 +136,15 @@
   String get name => file.path;
 }
 
+abstract class _Process implements Process {
+  abstract String _path;
+  abstract List<String> _arguments;
+  abstract String? _workingDirectory;
+}
+
 class _SpawnedProcessResourceInfo extends _IOResourceInfo {
   static const String _type = 'SpawnedProcess';
-  final process;
+  final _Process process;
   final int startedAt;
 
   static Map<int, _SpawnedProcessResourceInfo> startedProcesses =
diff --git a/sdk/lib/io/io_service.dart b/sdk/lib/io/io_service.dart
index 7af382c..707b9fa 100644
--- a/sdk/lib/io/io_service.dart
+++ b/sdk/lib/io/io_service.dart
@@ -37,18 +37,19 @@
   static const int fileIdentical = 28;
   static const int fileStat = 29;
   static const int fileLock = 30;
-  static const int socketLookup = 31;
-  static const int socketListInterfaces = 32;
-  static const int socketReverseLookup = 33;
-  static const int directoryCreate = 34;
-  static const int directoryDelete = 35;
-  static const int directoryExists = 36;
-  static const int directoryCreateTemp = 37;
-  static const int directoryListStart = 38;
-  static const int directoryListNext = 39;
-  static const int directoryListStop = 40;
-  static const int directoryRename = 41;
-  static const int sslProcessFilter = 42;
+  static const int fileCreatePipe = 31;
+  static const int socketLookup = 32;
+  static const int socketListInterfaces = 33;
+  static const int socketReverseLookup = 34;
+  static const int directoryCreate = 35;
+  static const int directoryDelete = 36;
+  static const int directoryExists = 37;
+  static const int directoryCreateTemp = 38;
+  static const int directoryListStart = 39;
+  static const int directoryListNext = 40;
+  static const int directoryListStop = 41;
+  static const int directoryRename = 42;
+  static const int sslProcessFilter = 43;
 
-  external static Future _dispatch(int request, List data);
+  external static Future<Object?> _dispatch(int request, List data);
 }
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index c7320ea..5f73061 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -168,10 +168,8 @@
         .then((_) => _File._dispatchWithNamespace(
             _IOService.fileCreateLink, [null, _rawPath, target]))
         .then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(
-            response, "Cannot create link to target '$target'", path);
-      }
+      _checkForErrorResponse(
+          response, "Cannot create link to target '$target'", path);
       return this;
     });
   }
@@ -209,9 +207,7 @@
     }
     return _File._dispatchWithNamespace(
         _IOService.fileDeleteLink, [null, _rawPath]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "Cannot delete link", path);
-      }
+      _checkForErrorResponse(response, "Cannot delete link", path);
       return this;
     });
   }
@@ -227,10 +223,8 @@
   Future<Link> rename(String newPath) {
     return _File._dispatchWithNamespace(
         _IOService.fileRenameLink, [null, _rawPath, newPath]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(
-            response, "Cannot rename link to '$newPath'", path);
-      }
+      _checkForErrorResponse(
+          response, "Cannot rename link to '$newPath'", path);
       return new Link(newPath);
     });
   }
@@ -244,11 +238,8 @@
   Future<String> target() {
     return _File._dispatchWithNamespace(
         _IOService.fileLinkTarget, [null, _rawPath]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(
-            response, "Cannot get target of link", path);
-      }
-      return response;
+      _checkForErrorResponse(response, "Cannot get target of link", path);
+      return response as String;
     });
   }
 
@@ -264,21 +255,19 @@
     }
   }
 
-  bool _isErrorResponse(response) {
-    return response is List && response[0] != _successResponse;
-  }
-
-  _exceptionFromResponse(response, String message, String path) {
-    assert(_isErrorResponse(response));
-    switch (response[_errorResponseErrorType]) {
-      case _illegalArgumentResponse:
-        return new ArgumentError();
-      case _osErrorResponse:
-        var err = new OSError(response[_osErrorResponseMessage],
-            response[_osErrorResponseErrorCode]);
-        return new FileSystemException(message, path, err);
-      default:
-        return new Exception("Unknown error");
+  /// If the [response] is an error, throws an [Exception] or an [Error].
+  void _checkForErrorResponse(Object? response, String message, String path) {
+    if (response is List<Object?> && response[0] != _successResponse) {
+      switch (response[_errorResponseErrorType]) {
+        case _illegalArgumentResponse:
+          throw ArgumentError();
+        case _osErrorResponse:
+          var err = OSError(response[_osErrorResponseMessage] as String,
+              response[_osErrorResponseErrorCode] as int);
+          throw FileSystemException(message, path, err);
+        default:
+          throw AssertionError("Unknown error");
+      }
     }
   }
 }
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 7dd311c..30c4f5c 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -1133,7 +1133,8 @@
     }
 
     var response =
-        await _IOService._dispatch(_IOService.sslProcessFilter, args);
+        (await _IOService._dispatch(_IOService.sslProcessFilter, args))
+            as List<Object?>;
     if (response.length == 2) {
       if (wasInHandshake) {
         // If we're in handshake, throw a handshake error.
@@ -1146,8 +1147,8 @@
             new TlsException('${response[1]} error ${response[0]}'), null);
       }
     }
-    int start(int index) => response[2 * index];
-    int end(int index) => response[2 * index + 1];
+    int start(int index) => response[2 * index] as int;
+    int end(int index) => response[2 * index + 1] as int;
 
     _FilterStatus status = new _FilterStatus();
     // Compute writeEmpty as "write plaintext buffer and write encrypted
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 4884414..7087c65 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -599,6 +599,8 @@
   /// Returns `null` if no data is available.
   ///
   /// Unsupported by [RawSecureSocket].
+  ///
+  /// Unsupported on Android, Fuchsia, Windows.
   @Since("2.15")
   SocketMessage? readMessage([int? count]);
 
@@ -638,6 +640,8 @@
   /// Throws an [OSError] if message could not be sent out.
   ///
   /// Unsupported by [RawSecureSocket].
+  ///
+  /// Unsupported on Android, Fuchsia, Windows.
   @Since("2.15")
   int sendMessage(List<SocketControlMessage> controlMessages, List<int> data,
       [int offset = 0, int? count]);
@@ -869,9 +873,20 @@
   /// Creates wrapper around current stdout.
   external factory ResourceHandle.fromStdout(Stdout stdout);
 
+  // Creates wrapper around a readable pipe.
+  external factory ResourceHandle.fromReadPipe(ReadPipe pipe);
+
+  // Creates wrapper around a writeable pipe.
+  external factory ResourceHandle.fromWritePipe(WritePipe pipe);
+
   /// Extracts opened file from resource handle.
   ///
-  /// This can also be used when receiving stdin and stdout handles.
+  /// This can also be used when receiving stdin and stdout handles and read
+  /// and write pipes.
+  ///
+  /// Since the [ResourceHandle] represents a single OS resource,
+  /// none of [toFile], [toSocket], [toRawSocket], or [toRawDatagramSocket],
+  /// [toReadPipe], [toWritePipe], can be called after a call to this method.
   ///
   /// If this resource handle is not a file or stdio handle, the behavior of the
   /// returned [RandomAccessFile] is completely unspecified.
@@ -880,6 +895,10 @@
 
   /// Extracts opened socket from resource handle.
   ///
+  /// Since the [ResourceHandle] represents a single OS resource,
+  /// none of [toFile], [toSocket], [toRawSocket], or [toRawDatagramSocket],
+  /// [toReadPipe], [toWritePipe], can be called after a call to this method.
+  //
   /// If this resource handle is not a socket handle, the behavior of the
   /// returned [Socket] is completely unspecified.
   /// Be very careful to avoid using a handle incorrectly.
@@ -887,6 +906,10 @@
 
   /// Extracts opened raw socket from resource handle.
   ///
+  /// Since the [ResourceHandle] represents a single OS resource,
+  /// none of [toFile], [toSocket], [toRawSocket], or [toRawDatagramSocket],
+  /// [toReadPipe], [toWritePipe], can be called after a call to this method.
+  ///
   /// If this resource handle is not a socket handle, the behavior of the
   /// returned [RawSocket] is completely unspecified.
   /// Be very careful to avoid using a handle incorrectly.
@@ -894,10 +917,36 @@
 
   /// Extracts opened raw datagram socket from resource handle.
   ///
+  /// Since the [ResourceHandle] represents a single OS resource,
+  /// none of [toFile], [toSocket], [toRawSocket], or [toRawDatagramSocket],
+  /// [toReadPipe], [toWritePipe], can be called after a call to this method.
+  ///
   /// If this resource handle is not a datagram socket handle, the behavior of
   /// the returned [RawDatagramSocket] is completely unspecified.
   /// Be very careful to avoid using a handle incorrectly.
   RawDatagramSocket toRawDatagramSocket();
+
+  /// Extracts a read pipe from resource handle.
+  ///
+  /// Since the [ResourceHandle] represents a single OS resource,
+  /// none of [toFile], [toSocket], [toRawSocket], or [toRawDatagramSocket],
+  /// [toReadPipe], [toWritePipe], can be called after a call to this method.
+  ///
+  /// If this resource handle is not a readable pipe, the behavior of the
+  /// returned [ReadPipe] is completely unspecified.
+  /// Be very careful to avoid using a handle incorrectly.
+  ReadPipe toReadPipe();
+
+  /// Extracts a write pipe from resource handle.
+  ///
+  /// Since the [ResourceHandle] represents a single OS resource,
+  /// none of [toFile], [toSocket], [toRawSocket], or [toRawDatagramSocket],
+  /// [toReadPipe], [toWritePipe], can be called after a call to this method.
+  ///
+  /// If this resource handle is not a writeable pipe, the behavior of the
+  /// returned [ReadPipe] is completely unspecified.
+  /// Be very careful to avoid using a handle incorrectly.
+  WritePipe toWritePipe();
 }
 
 /// Control message part of the [SocketMessage] received by a call to
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index 11cd17f..d4e0247 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -293,15 +293,11 @@
   /// The entry-point function is invoked in the new isolate with [message]
   /// as the only argument.
   ///
-  /// The function must be a top-level function or a static method
-  /// that can be called with a single argument,
-  /// that is, a compile-time constant function value
-  /// which accepts at least one positional parameter
-  /// and has at most one required positional parameter.
+  /// The [entryPoint] function must be able to be called with a single
+  /// argument,that is, a function which accepts at least one positional
+  /// parameter and has at most one required positional parameter.
   /// The function may accept any number of optional parameters,
   /// as long as it *can* be called with just a single argument.
-  /// The function must not be the value of a function expression
-  /// or an instance method tear-off.
   ///
   /// Usually the initial [message] contains a [SendPort] so
   /// that the spawner and spawnee can communicate with each other.
diff --git a/sdk/lib/js_util/js_util.dart b/sdk/lib/js_util/js_util.dart
index e47e6eb..c233e9b 100644
--- a/sdk/lib/js_util/js_util.dart
+++ b/sdk/lib/js_util/js_util.dart
@@ -159,3 +159,43 @@
 /// converts it to a Dart based object. Only JS primitives, arrays, or 'map'
 /// like JS objects are supported.
 external Object? dartify(Object? o);
+
+/// DO NOT USE - THIS IS UNIMPLEMENTED.
+///
+/// Given a `@staticInterop` type T and an instance [dartMock] of a Dart class
+/// U that implements the external extension members of T, creates a forwarding
+/// mock.
+///
+/// Optionally, you may provide a JS prototype object e.g. the JS value
+/// `Window.prototype` using [proto]. This allows instanceof and is checks with
+/// `@Native` types to pass with the returned forwarding mock.
+///
+/// When external extension members are called, they will forward to the
+/// corresponding implementing member in [dartMock]. If U does not implement all
+/// the external extension members of T, or if U does not properly override
+/// them, it will be considered a compile-time error.
+///
+/// For example:
+///
+/// ```
+/// @JS()
+/// @staticInterop
+/// class JSClass {}
+///
+/// extension JSClassExtension on JSClass {
+///   external String stringify(int param);
+/// }
+///
+/// class DartClass {
+///   String stringify(num param) => param.toString();
+/// }
+///
+/// ...
+///
+/// JSClass mock = createStaticInteropMock<JSClass, DartClass>(DartClass());
+/// ```
+///
+/// TODO(srujzs): Add more detail on how inherited extension members need to be
+/// implemented, as well as how conflicts are resolved (if they are resolvable).
+/// The semantics here tries to conform to the view type specification.
+external T createStaticInteropMock<T, U>(U dartMock, [Object? proto = null]);
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 1248afb..8fc6b5f 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -4,7 +4,7 @@
   "none": {
     "libraries": {}
   },
-  "vm": {
+  "vm_common": {
     "libraries": {
       "_builtin": {
         "uri": "_internal/vm/bin/builtin.dart"
@@ -138,12 +138,6 @@
       "nativewrappers": {
         "uri": "html/dartium/nativewrappers.dart"
       },
-      "cli": {
-        "uri": "cli/cli.dart",
-        "patches": [
-          "_internal/vm/bin/cli_patch.dart"
-        ]
-      },
       "typed_data": {
         "uri": "typed_data/typed_data.dart",
         "patches": "_internal/vm/lib/typed_data_patch.dart"
@@ -156,6 +150,21 @@
       }
     }
   },
+  "vm": {
+    "include": [
+      {
+        "target": "vm_common"
+      }
+    ],
+    "libraries": {
+      "cli": {
+        "uri": "cli/cli.dart",
+        "patches": [
+          "_internal/vm/bin/cli_patch.dart"
+        ]
+      }
+    }
+  },
   "wasm": {
     "libraries": {
       "_http": {
@@ -251,7 +260,10 @@
         "supported": false
       },
       "isolate": {
-        "uri": "isolate/isolate.dart"
+        "uri": "isolate/isolate.dart",
+        "patches": [
+          "_internal/wasm/lib/isolate_patch.dart"
+        ]
       },
       "js": {
         "uri": "js/js.dart",
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index 1941780..75ebae1 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -14,7 +14,7 @@
 none:
   libraries: {}
 
-vm:
+vm_common:
   libraries:
     _builtin:
       uri: "_internal/vm/bin/builtin.dart"
@@ -139,11 +139,6 @@
     nativewrappers:
       uri: "html/dartium/nativewrappers.dart"
 
-    cli:
-      uri: "cli/cli.dart"
-      patches:
-        - "_internal/vm/bin/cli_patch.dart"
-
     typed_data:
       uri: "typed_data/typed_data.dart"
       patches: "_internal/vm/lib/typed_data_patch.dart"
@@ -154,6 +149,15 @@
     vmservice_io:
       uri: "_internal/vm/bin/vmservice_io.dart"
 
+vm:
+  include:
+    - target: "vm_common"
+  libraries:
+    cli:
+      uri: "cli/cli.dart"
+      patches:
+        - "_internal/vm/bin/cli_patch.dart"
+
 wasm:
   libraries:
     _http:
@@ -232,6 +236,8 @@
       supported: false
     isolate:
       uri: isolate/isolate.dart
+      patches:
+        - "_internal/wasm/lib/isolate_patch.dart"
     js:
       uri: js/js.dart
       patches: _internal/wasm/lib/js_patch.dart
diff --git a/sdk/lib/wasm/wasm_types.dart b/sdk/lib/wasm/wasm_types.dart
index b95e26d..142bc07 100644
--- a/sdk/lib/wasm/wasm_types.dart
+++ b/sdk/lib/wasm/wasm_types.dart
@@ -97,8 +97,14 @@
 @pragma("wasm:entry-point")
 class WasmI32 extends _WasmInt {
   external factory WasmI32.fromInt(int value);
+  external factory WasmI32.int8FromInt(int value);
+  external factory WasmI32.uint8FromInt(int value);
+  external factory WasmI32.int16FromInt(int value);
+  external factory WasmI32.uint16FromInt(int value);
+  external factory WasmI32.fromBool(bool value);
   external int toIntSigned();
   external int toIntUnsigned();
+  external bool toBool();
 }
 
 /// The Wasm `i64` type.
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index 3254ec0..93f5c98 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -2,6 +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.
 
+[ $compiler == dart2wasm ]
+Language/Statements/Continue/async_loops_t07: Skip # https://github.com/dart-lang/sdk/issues/50026
+Language/Statements/Continue/async_loops_t08: Skip # https://github.com/dart-lang/sdk/issues/50026
+LibTest/async/Stream/Stream.fromFutures_all_t01: Skip # https://github.com/dart-lang/sdk/issues/50026
+LibTest/async/Stream/Stream.fromIterable_all_t01: Skip # https://github.com/dart-lang/sdk/issues/50026
+LibTest/async/StreamController/StreamController.broadcast_Stream_all_A01_t01: Skip # https://github.com/dart-lang/sdk/issues/50026
+LibTest/async/StreamController/stream_all_A01_t01: Skip # https://github.com/dart-lang/sdk/issues/50026
+
 [ $runtime == dart_precompiled ]
 LibTest/io/RawDatagramSocket/join_A01_t01: Skip # https://github.com/dart-lang/co19/issues/195
 LibTest/io/RawDatagramSocket/join_A01_t02: Skip # https://github.com/dart-lang/co19/issues/195
diff --git a/tests/corelib/analysis_options.yaml b/tests/corelib/analysis_options.yaml
deleted file mode 100644
index 0720d0e..0000000
--- a/tests/corelib/analysis_options.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-analyzer:
-  enable-experiment:
-  - non-nullable
\ No newline at end of file
diff --git a/tests/corelib/apply2_test.dart b/tests/corelib/apply2_test.dart
index 23805a1..b0c1e1a 100644
--- a/tests/corelib/apply2_test.dart
+++ b/tests/corelib/apply2_test.dart
@@ -20,10 +20,10 @@
   var c1 = () => 'c1';
   var c2 = (a) => 'c2 $a';
   var c3 = ([a = 1]) => 'c3 $a';
-  var c4 = ({a: 1}) => 'c4 $a';
-  var c5 = ({a: 1, b: 2}) => 'c5 $a $b';
-  var c6 = ({b: 1, a: 2}) => 'c6 $a $b';
-  var c7 = (x, {b: 1, a: 2}) => 'c7 $x $a $b';
+  var c4 = ({a = 1}) => 'c4 $a';
+  var c5 = ({a = 1, b = 2}) => 'c5 $a $b';
+  var c6 = ({b = 1, a = 2}) => 'c6 $a $b';
+  var c7 = (x, {b = 1, a = 2}) => 'c7 $x $a $b';
   var c8 = (x, y, [a = 2, b = 3]) => 'c8 $x $y $a $b';
 
   Expect.equals('c1', apply(c1, null, null));
diff --git a/tests/corelib/iterable_to_list_test.dart b/tests/corelib/iterable_to_list_test.dart
index 112d9cd..3b98b26 100644
--- a/tests/corelib/iterable_to_list_test.dart
+++ b/tests/corelib/iterable_to_list_test.dart
@@ -69,7 +69,7 @@
   }
 }
 
-test(Iterable iterable, List expected, element, {bool growable: true}) {
+test(Iterable iterable, List expected, element, {bool growable = true}) {
   var list = iterable.toList(growable: growable);
   Expect.listEquals(expected, list);
   Expect.equals(expected is List<int>, list is List<int>, "int");
diff --git a/tests/corelib/map_unmodifiable_cast_test.dart b/tests/corelib/map_unmodifiable_cast_test.dart
index 31466ef..9a1c3ad 100644
--- a/tests/corelib/map_unmodifiable_cast_test.dart
+++ b/tests/corelib/map_unmodifiable_cast_test.dart
@@ -41,7 +41,7 @@
 }
 
 void test<K, V>(map, firstKey, firstValue, String name,
-    {bool noSuchMethodMap: false}) {
+    {bool noSuchMethodMap = false}) {
   if (!noSuchMethodMap) {
     Expect.isTrue(map.containsKey(firstKey), "$name.containsKey");
     Expect.equals(1, map.length, "$name.length");
diff --git a/tests/corelib/regexp/named-captures_test.dart b/tests/corelib/regexp/named-captures_test.dart
index 0024938..12f5deb 100644
--- a/tests/corelib/regexp/named-captures_test.dart
+++ b/tests/corelib/regexp/named-captures_test.dart
@@ -37,7 +37,7 @@
   }
 
   void execString(String pattern, String input, List<String?> expectedResult,
-      {bool unicode = true, bool caseSensitive: false}) {
+      {bool unicode = true, bool caseSensitive = false}) {
     execRE(RegExp(pattern, unicode: unicode, caseSensitive: caseSensitive),
         input, expectedResult);
   }
@@ -52,7 +52,7 @@
 
   void execStringGroups(
       String pattern, String input, Map<String, String?> expectedResults,
-      {bool unicode = true, bool caseSensitive: false}) {
+      {bool unicode = true, bool caseSensitive = false}) {
     namedRE(RegExp(pattern, unicode: unicode, caseSensitive: caseSensitive),
         input, expectedResults);
   }
diff --git a/tests/corelib/uri_file_test.dart b/tests/corelib/uri_file_test.dart
index 457f9cb..f4dd61d 100644
--- a/tests/corelib/uri_file_test.dart
+++ b/tests/corelib/uri_file_test.dart
@@ -264,7 +264,7 @@
 }
 
 testAdditionalComponents() {
-  check(String s, {bool windowsOk: false}) {
+  check(String s, {bool windowsOk = false}) {
     Uri uri = Uri.parse(s);
     Expect.throwsUnsupportedError(() => uri.toFilePath(windows: false));
     if (windowsOk) {
diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status
index 361a252..413921a 100644
--- a/tests/ffi/ffi.status
+++ b/tests/ffi/ffi.status
@@ -5,9 +5,6 @@
 function_callbacks_structs_by_value_test: Pass, Slow # https://dartbug.com/47304 https://dartbug.com/45007
 function_structs_by_value_generated_test: Pass, Slow # https://dartbug.com/47303 https://dartbug.com/45007
 
-[ $builder_tag == msan ]
-vmspecific_handle_test: Skip # https://dartbug.com/42314
-
 [ $compiler == app_jitk ]
 vmspecific_leaf_call_test: Skip # https://dartbug.com/46125: Snapshot fails to generate.
 
diff --git a/tests/ffi/has_symbol_test.dart b/tests/ffi/has_symbol_test.dart
index 858de9c..08fb1a8 100644
--- a/tests/ffi/has_symbol_test.dart
+++ b/tests/ffi/has_symbol_test.dart
@@ -19,16 +19,16 @@
   Expect.isTrue(ffiTestFunctions.providesSymbol('ReturnMaxUint8'));
   Expect.isFalse(ffiTestFunctions.providesSymbol('SymbolNotInLibrary'));
 
-  if (Platform.isMacOS ||
-      Platform.isIOS ||
-      Platform.isAndroid ||
-      Platform.isLinux) {
-    DynamicLibrary p = DynamicLibrary.process();
+  final p = DynamicLibrary.process();
+  Expect.isFalse(p.providesSymbol('symbol_that_does_not_exist_in_process'));
+  if (Platform.isWindows) {
+    Expect.isTrue(p.providesSymbol('HeapAlloc'));
+    Expect.isTrue(p.providesSymbol('CoTaskMemAlloc'));
+  } else {
     Expect.isTrue(p.providesSymbol('dlopen'));
-    Expect.isFalse(p.providesSymbol('symbol_that_does_not_exist_in_process'));
   }
 
-  DynamicLibrary e = DynamicLibrary.executable();
+  final e = DynamicLibrary.executable();
   Expect.isTrue(e.providesSymbol('Dart_Invoke'));
   Expect.isFalse(e.providesSymbol('symbol_that_does_not_exist_in_executable'));
 }
diff --git a/tests/ffi/regress_49684_test.dart b/tests/ffi/regress_49684_test.dart
new file mode 100644
index 0000000..33df684
--- /dev/null
+++ b/tests/ffi/regress_49684_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, 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';
+
+void main() {
+  // Does nothing, FfiNative aren't resolved.
+}
+
+@FfiNative<Int Function(Pointer<Int>, Int)>('subtract')
+external int subtract(
+  Pointer<Int> a,
+  int b,
+);
+
+@FfiNative<Pointer<Double> Function(Pointer<Float>, Pointer<Float>)>(
+    'dividePrecision')
+external Pointer<Double> dividePrecision(
+  Pointer<Float> a,
+  Pointer<Float> b,
+);
+
+@FfiNative<Void Function(Pointer)>('free')
+external void posixFree(Pointer pointer);
+
+@FfiNative<Void Function(Pointer)>('CoTaskMemFree')
+external void winCoTaskMemFree(Pointer pv);
diff --git a/tests/ffi/variance_function_test.dart b/tests/ffi/variance_function_test.dart
index 04c812c..bea1dd0 100644
--- a/tests/ffi/variance_function_test.dart
+++ b/tests/ffi/variance_function_test.dart
@@ -189,7 +189,7 @@
   callback(fp);
 }
 
-void callbackParamImplictDowncast1() {
+void callbackParamImplicitDowncast1() {
   final callback = ffiTestFunctions.lookupFunction<CallbackNaTyPointerParamOp,
       CallbackNaTyPointerParamOpDart>(callbackParamOpName);
   final fp = Pointer.fromFunction<Int64PointerParamOp>(int64PointerParamOp);
@@ -224,7 +224,7 @@
   for (int i = 0; i < 100; ++i) {
     callbackParamInvariant1(); // Pointer<Int64> invariant
     callbackParamInvariant2(); // Pointer<NativeType> invariant
-    callbackParamImplictDowncast1(); // static and dynamically supertyped
+    callbackParamImplicitDowncast1(); // static and dynamically supertyped
     callbackParamSubtype1(); // static and dynamically subtyped
     callbackReturnInvariant1(); // Pointer<Int64> invariant
     callbackReturnInvariant2(); // Pointer<NativeType> invariant
diff --git a/tests/ffi/vmspecific_dynamic_library_test.dart b/tests/ffi/vmspecific_dynamic_library_test.dart
index c15f850..77d94dfc 100644
--- a/tests/ffi/vmspecific_dynamic_library_test.dart
+++ b/tests/ffi/vmspecific_dynamic_library_test.dart
@@ -37,22 +37,20 @@
 typedef DoubleUnOp = double Function(double);
 
 void testLookup() {
-  DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  final l = dlopenPlatformSpecific("ffi_test_dynamic_library");
   var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
   Expect.approxEquals(12.0, timesFour(3));
 
-  if (Platform.isMacOS ||
-      Platform.isIOS ||
-      Platform.isAndroid ||
-      Platform.isLinux) {
-    // Lookup a symbol from 'libc' since it's loaded with global visibility.
-    DynamicLibrary p = DynamicLibrary.process();
-    Expect.isTrue(p.lookup<Void>("strcmp") != nullptr);
+  final p = DynamicLibrary.process();
+  if (Platform.isWindows) {
+    Expect.isTrue(p.lookup<Void>("HeapAlloc") != nullptr);
+    Expect.isTrue(p.lookup<Void>("CoTaskMemAlloc") != nullptr);
   } else {
-    Expect.throws<UnsupportedError>(() => DynamicLibrary.process());
+    // Lookup a symbol from 'libc' since it's loaded with global visibility.
+    Expect.isTrue(p.lookup<Void>("strcmp") != nullptr);
   }
 
-  DynamicLibrary e = DynamicLibrary.executable();
+  final e = DynamicLibrary.executable();
   Expect.isTrue(e.lookup("Dart_Invoke") != nullptr);
 }
 
diff --git a/tests/ffi/vmspecific_variance_function_checks_test.dart b/tests/ffi/vmspecific_variance_function_checks_test.dart
index c17488c..ad1f7e5 100644
--- a/tests/ffi/vmspecific_variance_function_checks_test.dart
+++ b/tests/ffi/vmspecific_variance_function_checks_test.dart
@@ -57,10 +57,10 @@
   return Pointer.fromAddress(0x13370000);
 }
 
-final implictDowncast1 = //# 3:  compile-time error
+final implicitDowncast1 = //# 3:  compile-time error
     Pointer.fromFunction<Int64PointerParamOp>(//# 3:  continued
         naTyPointerParamOp); //# 3:  continued
-final implictDowncast2 = //# 4:  compile-time error
+final implicitDowncast2 = //# 4:  compile-time error
     Pointer.fromFunction<NaTyPointerReturnOp>(//# 4:  continued
         int64PointerReturnOp); //# 4:  continued
 
diff --git a/tests/ffi_2/ffi_2.status b/tests/ffi_2/ffi_2.status
index 361a252..413921a 100644
--- a/tests/ffi_2/ffi_2.status
+++ b/tests/ffi_2/ffi_2.status
@@ -5,9 +5,6 @@
 function_callbacks_structs_by_value_test: Pass, Slow # https://dartbug.com/47304 https://dartbug.com/45007
 function_structs_by_value_generated_test: Pass, Slow # https://dartbug.com/47303 https://dartbug.com/45007
 
-[ $builder_tag == msan ]
-vmspecific_handle_test: Skip # https://dartbug.com/42314
-
 [ $compiler == app_jitk ]
 vmspecific_leaf_call_test: Skip # https://dartbug.com/46125: Snapshot fails to generate.
 
diff --git a/tests/ffi_2/has_symbol_test.dart b/tests/ffi_2/has_symbol_test.dart
index 11c1de10e..d07f544 100644
--- a/tests/ffi_2/has_symbol_test.dart
+++ b/tests/ffi_2/has_symbol_test.dart
@@ -21,16 +21,16 @@
   Expect.isTrue(ffiTestFunctions.providesSymbol('ReturnMaxUint8'));
   Expect.isFalse(ffiTestFunctions.providesSymbol('SymbolNotInLibrary'));
 
-  if (Platform.isMacOS ||
-      Platform.isIOS ||
-      Platform.isAndroid ||
-      Platform.isLinux) {
-    DynamicLibrary p = DynamicLibrary.process();
+  final p = DynamicLibrary.process();
+  Expect.isFalse(p.providesSymbol('symbol_that_does_not_exist_in_process'));
+  if (Platform.isWindows) {
+    Expect.isTrue(p.providesSymbol('HeapAlloc'));
+    Expect.isTrue(p.providesSymbol('CoTaskMemAlloc'));
+  } else {
     Expect.isTrue(p.providesSymbol('dlopen'));
-    Expect.isFalse(p.providesSymbol('symbol_that_does_not_exist_in_process'));
   }
 
-  DynamicLibrary e = DynamicLibrary.executable();
+  final e = DynamicLibrary.executable();
   Expect.isTrue(e.providesSymbol('Dart_Invoke'));
   Expect.isFalse(e.providesSymbol('symbol_that_does_not_exist_in_executable'));
 }
diff --git a/tests/ffi_2/variance_function_test.dart b/tests/ffi_2/variance_function_test.dart
index f9981e7..295f52d 100644
--- a/tests/ffi_2/variance_function_test.dart
+++ b/tests/ffi_2/variance_function_test.dart
@@ -191,7 +191,7 @@
   callback(fp);
 }
 
-void callbackParamImplictDowncast1() {
+void callbackParamImplicitDowncast1() {
   final callback = ffiTestFunctions.lookupFunction<CallbackNaTyPointerParamOp,
       CallbackNaTyPointerParamOpDart>(callbackParamOpName);
   final fp = Pointer.fromFunction<Int64PointerParamOp>(int64PointerParamOp);
@@ -226,7 +226,7 @@
   for (int i = 0; i < 100; ++i) {
     callbackParamInvariant1(); // Pointer<Int64> invariant
     callbackParamInvariant2(); // Pointer<NativeType> invariant
-    callbackParamImplictDowncast1(); // static and dynamically supertyped
+    callbackParamImplicitDowncast1(); // static and dynamically supertyped
     callbackParamSubtype1(); // static and dynamically subtyped
     callbackReturnInvariant1(); // Pointer<Int64> invariant
     callbackReturnInvariant2(); // Pointer<NativeType> invariant
diff --git a/tests/ffi_2/vmspecific_dynamic_library_test.dart b/tests/ffi_2/vmspecific_dynamic_library_test.dart
index e7d04d3..5cdd035 100644
--- a/tests/ffi_2/vmspecific_dynamic_library_test.dart
+++ b/tests/ffi_2/vmspecific_dynamic_library_test.dart
@@ -39,22 +39,20 @@
 typedef DoubleUnOp = double Function(double);
 
 void testLookup() {
-  DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  final l = dlopenPlatformSpecific("ffi_test_dynamic_library");
   var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
   Expect.approxEquals(12.0, timesFour(3));
 
-  if (Platform.isMacOS ||
-      Platform.isIOS ||
-      Platform.isAndroid ||
-      Platform.isLinux) {
-    // Lookup a symbol from 'libc' since it's loaded with global visibility.
-    DynamicLibrary p = DynamicLibrary.process();
-    Expect.isTrue(p.lookup<Void>("strcmp") != nullptr);
+  final p = DynamicLibrary.process();
+  if (Platform.isWindows) {
+    Expect.isTrue(p.lookup<Void>("HeapAlloc") != nullptr);
+    Expect.isTrue(p.lookup<Void>("CoTaskMemAlloc") != nullptr);
   } else {
-    Expect.throws<UnsupportedError>(() => DynamicLibrary.process());
+    // Lookup a symbol from 'libc' since it's loaded with global visibility.
+    Expect.isTrue(p.lookup<Void>("strcmp") != nullptr);
   }
 
-  DynamicLibrary e = DynamicLibrary.executable();
+  final e = DynamicLibrary.executable();
   Expect.isTrue(e.lookup("Dart_Invoke") != nullptr);
 }
 
diff --git a/tests/ffi_2/vmspecific_variance_function_checks_test.dart b/tests/ffi_2/vmspecific_variance_function_checks_test.dart
index 1462acb..0241e41 100644
--- a/tests/ffi_2/vmspecific_variance_function_checks_test.dart
+++ b/tests/ffi_2/vmspecific_variance_function_checks_test.dart
@@ -59,10 +59,10 @@
   return Pointer.fromAddress(0x13370000);
 }
 
-final implictDowncast1 = //# 3:  compile-time error
+final implicitDowncast1 = //# 3:  compile-time error
     Pointer.fromFunction<Int64PointerParamOp>(//# 3:  continued
         naTyPointerParamOp); //# 3:  continued
-final implictDowncast2 = //# 4:  compile-time error
+final implicitDowncast2 = //# 4:  compile-time error
     Pointer.fromFunction<NaTyPointerReturnOp>(//# 4:  continued
         int64PointerReturnOp); //# 4:  continued
 
diff --git a/tests/language/analysis_options.yaml b/tests/language/analysis_options.yaml
deleted file mode 100644
index 0720d0e..0000000
--- a/tests/language/analysis_options.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-analyzer:
-  enable-experiment:
-  - non-nullable
\ No newline at end of file
diff --git a/tests/language/bool/condition_check_strong_test.dart b/tests/language/bool/condition_check_strong_test.dart
index 6547135..39f9b24 100644
--- a/tests/language/bool/condition_check_strong_test.dart
+++ b/tests/language/bool/condition_check_strong_test.dart
@@ -18,7 +18,7 @@
 
 class Class {
   final String field;
-  Class({bool? a: false, bool? b: true}) : this.field = check(a: a, b: b);
+  Class({bool? a = false, bool? b = true}) : this.field = check(a: a, b: b);
 }
 
 main() {
diff --git a/tests/language/bool/condition_check_weak_test.dart b/tests/language/bool/condition_check_weak_test.dart
index 761069b..ade0fd0 100644
--- a/tests/language/bool/condition_check_weak_test.dart
+++ b/tests/language/bool/condition_check_weak_test.dart
@@ -18,7 +18,7 @@
 
 class Class {
   final String field;
-  Class({bool? a: false, bool? b: true}) : this.field = check(a: a, b: b);
+  Class({bool? a = false, bool? b = true}) : this.field = check(a: a, b: b);
 }
 
 main() {
diff --git a/tests/language/call/call_test.dart b/tests/language/call/call_test.dart
index 882eeb4..9ff9943 100644
--- a/tests/language/call/call_test.dart
+++ b/tests/language/call/call_test.dart
@@ -26,7 +26,7 @@
     Expect.isTrue(opt_arg.call("b"));
   }
 
-  named_arg({x: 11, y: 22}) => "$x$y";
+  named_arg({x = 11, y = 22}) => "$x$y";
 
   for (var i = 0; i < 20; i++) {
     Expect.equals("1122", named_arg());
diff --git a/tests/language/call/closurization_test.dart b/tests/language/call/closurization_test.dart
index 102413b..bc2a28c 100644
--- a/tests/language/call/closurization_test.dart
+++ b/tests/language/call/closurization_test.dart
@@ -34,7 +34,7 @@
     Expect.isTrue(opt_arg_tearOff.call("b"));
   }
 
-  named_arg({x: 11, y: 22}) => "$x$y";
+  named_arg({x = 11, y = 22}) => "$x$y";
   var named_arg_tearOff = named_arg.call;
 
   for (var i = 0; i < 20; i++) {
diff --git a/tests/language/call/function_apply_test.dart b/tests/language/call/function_apply_test.dart
index 935cfaf..68e7e30 100644
--- a/tests/language/call/function_apply_test.dart
+++ b/tests/language/call/function_apply_test.dart
@@ -5,7 +5,7 @@
 import "package:expect/expect.dart";
 
 class A {
-  call({a: 42}) {
+  call({a = 42}) {
     return 499 + a;
   }
 }
diff --git a/tests/language/call/operator_test.dart b/tests/language/call/operator_test.dart
index 8513bcb..fc82166 100644
--- a/tests/language/call/operator_test.dart
+++ b/tests/language/call/operator_test.dart
@@ -30,7 +30,7 @@
 
 // Non-trivial method body combination of positional and named.
 class E {
-  String call(String str, {int count: 1}) {
+  String call(String str, {int count = 1}) {
     StringBuffer buffer = new StringBuffer();
     for (var i = 0; i < count; i++) {
       buffer.write(str);
diff --git a/tests/language/class/classes_static_method_clash_test.dart b/tests/language/class/classes_static_method_clash_test.dart
index 985a0c8..813809c 100644
--- a/tests/language/class/classes_static_method_clash_test.dart
+++ b/tests/language/class/classes_static_method_clash_test.dart
@@ -7,7 +7,7 @@
 // This methods needs a stub method (because it is used in Function.apply, where
 // we can't see all possible uses).
 // The stub-method(s) must not clash with other global names (like classes).
-foo({a: 499}) => a;
+foo({a = 499}) => a;
 
 bar(f) {
   return f();
diff --git a/tests/language/closure/closure7_test.dart b/tests/language/closure/closure7_test.dart
index 91b8f7b..8a94352 100644
--- a/tests/language/closure/closure7_test.dart
+++ b/tests/language/closure/closure7_test.dart
@@ -9,12 +9,12 @@
 class A {
   foo() => 499;
   fooo() => 4999; // Implicit closure class can be shared with foo.
-  bar(x, {y: 8, z: 10}) => "1 $x $y $z";
-  gee(x, {y: 9, z: 11}) => "2 $x $y $z"; // Must not be shared with "bar".
-  toto(x, {y: 8, z: 10}) => "3 $x $y $z"; // Could be shared with "bar".
+  bar(x, {y = 8, z = 10}) => "1 $x $y $z";
+  gee(x, {y = 9, z = 11}) => "2 $x $y $z"; // Must not be shared with "bar".
+  toto(x, {y = 8, z = 10}) => "3 $x $y $z"; // Could be shared with "bar".
 
-  fisk(x, {y: 8, zz: 10}) => "4 $x $y $zz";
-  titi(x, {y: 8, zz: 77}) => "5 $x $y $zz"; // Could be shared with "fisk",
+  fisk(x, {y = 8, zz = 10}) => "4 $x $y $zz";
+  titi(x, {y = 8, zz = 77}) => "5 $x $y $zz"; // Could be shared with "fisk",
   // because default-val is never used.
 }
 
@@ -23,11 +23,11 @@
   // of A.
   foo() => 4990;
   fooo() => 49990;
-  bar(x, {y: 8, z: 10}) => "1B $x $y $z";
-  gee(x, {y: 9, z: 11}) => "2B $x $y $z";
-  toto(x, {y: 8, z: 10}) => "3B $x $y $z";
-  fisk(x, {y: 8, zz: 10}) => "4B $x $y $zz";
-  titi(x, {y: 8, zz: 77}) => "5B $x $y $zz";
+  bar(x, {y = 8, z = 10}) => "1B $x $y $z";
+  gee(x, {y = 9, z = 11}) => "2B $x $y $z";
+  toto(x, {y = 8, z = 10}) => "3B $x $y $z";
+  fisk(x, {y = 8, zz = 10}) => "4B $x $y $zz";
+  titi(x, {y = 8, zz = 77}) => "5B $x $y $zz";
 }
 
 tearOffFoo(o) => o.foo;
diff --git a/tests/language/closure/partial_tearoff_instantiation_test.dart b/tests/language/closure/partial_tearoff_instantiation_test.dart
index 629b3bd..3561630 100644
--- a/tests/language/closure/partial_tearoff_instantiation_test.dart
+++ b/tests/language/closure/partial_tearoff_instantiation_test.dart
@@ -15,12 +15,12 @@
 
 class X1 {
   final F1 f;
-  const X1({this.f: defaultF});
+  const X1({this.f = defaultF});
 }
 
 class X2 {
   final F2 f;
-  const X2({this.f: defaultF});
+  const X2({this.f = defaultF});
 }
 
 class Y1 {
diff --git a/tests/language/compile_time_constant/arguments_runtime_test.dart b/tests/language/compile_time_constant/arguments_runtime_test.dart
index 9718f01..2c2677f 100644
--- a/tests/language/compile_time_constant/arguments_runtime_test.dart
+++ b/tests/language/compile_time_constant/arguments_runtime_test.dart
@@ -7,7 +7,7 @@
 
 class A {
   const A(a);
-  const A.named({a: 42});
+  const A.named({a = 42});
   const A.optional([a]);
 }
 
diff --git a/tests/language/compile_time_constant/arguments_test.dart b/tests/language/compile_time_constant/arguments_test.dart
index ca56413..5640876 100644
--- a/tests/language/compile_time_constant/arguments_test.dart
+++ b/tests/language/compile_time_constant/arguments_test.dart
@@ -4,7 +4,7 @@
 
 class A {
   const A(a);
-  const A.named({a: 42});
+  const A.named({a = 42});
   const A.optional([a]);
 }
 
diff --git a/tests/language/compile_time_constant/e_test.dart b/tests/language/compile_time_constant/e_test.dart
index f5b837f..0a08723 100644
--- a/tests/language/compile_time_constant/e_test.dart
+++ b/tests/language/compile_time_constant/e_test.dart
@@ -14,7 +14,7 @@
       : y = 499,
         t = tt,
         x = 3;
-  const A.n({this.z: 99, tt: 100})
+  const A.n({this.z = 99, tt = 100})
       : y = 499,
         t = tt,
         x = 3;
diff --git a/tests/language/const/redirecting_factory_test.dart b/tests/language/const/redirecting_factory_test.dart
index c7f8bf2..041a0e8 100644
--- a/tests/language/const/redirecting_factory_test.dart
+++ b/tests/language/const/redirecting_factory_test.dart
@@ -7,7 +7,7 @@
 class K implements L {
   final field1;
   final field2;
-  const K({this.field1: 42, this.field2: true});
+  const K({this.field1 = 42, this.field2 = true});
 }
 
 class L {
diff --git a/tests/language/const/tree_test.dart b/tests/language/const/tree_test.dart
index 7c0cd28..533e6ca 100644
--- a/tests/language/const/tree_test.dart
+++ b/tests/language/const/tree_test.dart
@@ -4,7 +4,7 @@
 
 class A {
   final List<A> children;
-  const A({this.children: const []});
+  const A({this.children = const []});
 }
 
 const a = const A();
diff --git a/tests/language/constructor/constructor5_test.dart b/tests/language/constructor/constructor5_test.dart
index 52020cf..5578cfa 100644
--- a/tests/language/constructor/constructor5_test.dart
+++ b/tests/language/constructor/constructor5_test.dart
@@ -16,7 +16,7 @@
 }
 
 class A {
-  A({arg1: 100, arg2: 200})
+  A({arg1 = 100, arg2 = 200})
       : a1 = E(arg1++),
         a2 = E(arg2++) {
     // b2 should be initialized between the above initializers and the following
diff --git a/tests/language/constructor/external_constructor_test.dart b/tests/language/constructor/external_constructor_test.dart
new file mode 100644
index 0000000..0bc07b7
--- /dev/null
+++ b/tests/language/constructor/external_constructor_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, 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 for external constructors.
+
+import "package:expect/expect.dart";
+
+class A {
+  final int field;
+
+  const A(this.field);
+  external const A.foo(dynamic arg);
+}
+
+class B extends A {
+  const B(int abc) : super(abc);
+  B.foo(dynamic arg) : super.foo(arg);
+}
+
+void main() {
+  Expect.throws(() {
+    A.foo(42);
+  }, (e) => e is NoSuchMethodError);
+  Expect.throws(() {
+    B.foo(42);
+  }, (e) => e is NoSuchMethodError);
+}
diff --git a/tests/language/constructor/forwarding_factory_constructor_default_values_test.dart b/tests/language/constructor/forwarding_factory_constructor_default_values_test.dart
index 70738fe..a25b617 100644
--- a/tests/language/constructor/forwarding_factory_constructor_default_values_test.dart
+++ b/tests/language/constructor/forwarding_factory_constructor_default_values_test.dart
@@ -13,7 +13,7 @@
 class A {
   final bool condition;
 
-  A({this.condition: true});
+  A({this.condition = true});
 
   factory A.a1({condition}) = _A1.boo;
 
@@ -25,5 +25,5 @@
 }
 
 class _A1 extends A {
-  _A1.boo({condition: true}) : super(condition: condition);
+  _A1.boo({condition = true}) : super(condition: condition);
 }
diff --git a/tests/language/constructor/implicit_super_constructor_call_test.dart b/tests/language/constructor/implicit_super_constructor_call_test.dart
index fca1a62..cb9a6c5 100644
--- a/tests/language/constructor/implicit_super_constructor_call_test.dart
+++ b/tests/language/constructor/implicit_super_constructor_call_test.dart
@@ -10,7 +10,7 @@
   final x;
 
   @pragma('dart2js:noInline')
-  A({this.x: "foo"}) {
+  A({this.x = "foo"}) {
     Expect.equals("foo", x.toString());
   }
 }
diff --git a/tests/language/constructor/named_arguments_test.dart b/tests/language/constructor/named_arguments_test.dart
index 854ae04..369d24b 100644
--- a/tests/language/constructor/named_arguments_test.dart
+++ b/tests/language/constructor/named_arguments_test.dart
@@ -20,7 +20,7 @@
 class X {
   var i;
   var j;
-  X({a: 'defa', b: 'defb'})
+  X({a = 'defa', b = 'defb'})
       : this.i = a,
         this.j = b;
   X.foo() : this(b: 1, a: 2);
diff --git a/tests/language/function/type_alias7_test.dart b/tests/language/function/type_alias7_test.dart
index 79bd6e7..ca8fef9 100644
--- a/tests/language/function/type_alias7_test.dart
+++ b/tests/language/function/type_alias7_test.dart
@@ -6,7 +6,7 @@
 
 typedef void badFuncType([int arg = 0]); //# 00: compile-time error
 
-typedef void badFuncType({int arg: 0}); //# 02: compile-time error
+typedef void badFuncType({int arg = 0}); //# 02: compile-time error
 
 class A
   extends funcType // //# 01: compile-time error
diff --git a/tests/language/function_subtype/inline2_test.dart b/tests/language/function_subtype/inline2_test.dart
index 2f63a3d..281f686 100644
--- a/tests/language/function_subtype/inline2_test.dart
+++ b/tests/language/function_subtype/inline2_test.dart
@@ -12,8 +12,8 @@
   var field;
   C.c1(int this.field()?);
   C.c2({int this.field()?});
-  C.c3({int field()?: null});
-  C.c4({int this.field()?: null});
+  C.c3({int field()? = null});
+  C.c4({int this.field()? = null});
   C.c5([int this.field()?]);
   C.c6([int field()? = null]);
   C.c7([int this.field()? = null]);
diff --git a/tests/language/function_type/function_type0_test.dart b/tests/language/function_type/function_type0_test.dart
index d2134ef..0b57f82 100644
--- a/tests/language/function_type/function_type0_test.dart
+++ b/tests/language/function_type/function_type0_test.dart
@@ -103,7 +103,7 @@
   late Function<A>(List<Function> x) Function() x22;
   late void Function<A>(core.List<core.int> x) Function() x23;
 
-  U0({this.tIsBool: false, this.tIsInt: false})
+  U0({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type10_test.dart b/tests/language/function_type/function_type10_test.dart
index fc803d6..dc1069a 100644
--- a/tests/language/function_type/function_type10_test.dart
+++ b/tests/language/function_type/function_type10_test.dart
@@ -127,7 +127,7 @@
   late Function<A>(List<T> x) Function<B extends core.int>() x22;
   late void Function<A>() Function<B extends core.int>() x23;
 
-  U10({this.tIsBool: false, this.tIsInt: false})
+  U10({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int y, {int x = -1}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type11_test.dart b/tests/language/function_type/function_type11_test.dart
index 5499988..2bfd807 100644
--- a/tests/language/function_type/function_type11_test.dart
+++ b/tests/language/function_type/function_type11_test.dart
@@ -139,7 +139,7 @@
   late Function<A>(List<T> x) Function<B extends core.int>(int x) x22;
   late void Function<A>() Function<B extends core.int>(int x) x23;
 
-  U11({this.tIsBool: false, this.tIsInt: false})
+  U11({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(Function x) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type12_test.dart b/tests/language/function_type/function_type12_test.dart
index 2bb14fc..b6e6b33 100644
--- a/tests/language/function_type/function_type12_test.dart
+++ b/tests/language/function_type/function_type12_test.dart
@@ -101,7 +101,7 @@
   late Function<A>() Function() x22;
   late void Function<A>(A x) Function() x23;
 
-  U12({this.tIsBool: false, this.tIsInt: false})
+  U12({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0([Function x = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type13_test.dart b/tests/language/function_type/function_type13_test.dart
index bdf2ac2..c08c5fc 100644
--- a/tests/language/function_type/function_type13_test.dart
+++ b/tests/language/function_type/function_type13_test.dart
@@ -103,7 +103,7 @@
   late Function<A>() Function(int x) x22;
   late void Function<A>(A x) Function(int x) x23;
 
-  U13({this.tIsBool: false, this.tIsInt: false})
+  U13({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, [Function x = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type14_test.dart b/tests/language/function_type/function_type14_test.dart
index 9b9f58c0..7920da5 100644
--- a/tests/language/function_type/function_type14_test.dart
+++ b/tests/language/function_type/function_type14_test.dart
@@ -126,7 +126,7 @@
   late Function<A>() Function<B extends core.int>() x22;
   late void Function<A>(A x) Function<B extends core.int>() x23;
 
-  U14({this.tIsBool: false, this.tIsInt: false})
+  U14({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int y, [Function x = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type15_test.dart b/tests/language/function_type/function_type15_test.dart
index 0083d12..63be8bc 100644
--- a/tests/language/function_type/function_type15_test.dart
+++ b/tests/language/function_type/function_type15_test.dart
@@ -138,7 +138,7 @@
   late Function<A>() Function<B extends core.int>(int x) x22;
   late void Function<A>(A x) Function<B extends core.int>(int x) x23;
 
-  U15({this.tIsBool: false, this.tIsInt: false})
+  U15({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(Function x0) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type16_test.dart b/tests/language/function_type/function_type16_test.dart
index 63edfae..13cc46d 100644
--- a/tests/language/function_type/function_type16_test.dart
+++ b/tests/language/function_type/function_type16_test.dart
@@ -101,7 +101,7 @@
   late Function<A>(A x) Function() x22;
   late void Function<A>(List<A> x) Function() x23;
 
-  U16({this.tIsBool: false, this.tIsInt: false})
+  U16({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0([Function x0 = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type17_test.dart b/tests/language/function_type/function_type17_test.dart
index 50b4291d..25643d8 100644
--- a/tests/language/function_type/function_type17_test.dart
+++ b/tests/language/function_type/function_type17_test.dart
@@ -102,7 +102,7 @@
   late Function<A>(A x) Function(int x) x22;
   late void Function<A>(List<A> x) Function(int x) x23;
 
-  U17({this.tIsBool: false, this.tIsInt: false})
+  U17({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type18_test.dart b/tests/language/function_type/function_type18_test.dart
index 6df5530..3bc2c6d 100644
--- a/tests/language/function_type/function_type18_test.dart
+++ b/tests/language/function_type/function_type18_test.dart
@@ -123,7 +123,7 @@
   late Function<A>(A x) Function<B extends core.int>() x22;
   late void Function<A>(List<A> x) Function<B extends core.int>() x23;
 
-  U18({this.tIsBool: false, this.tIsInt: false})
+  U18({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type19_test.dart b/tests/language/function_type/function_type19_test.dart
index 7a276f1..81a8fec0 100644
--- a/tests/language/function_type/function_type19_test.dart
+++ b/tests/language/function_type/function_type19_test.dart
@@ -139,7 +139,7 @@
   late Function<A>(A x) Function<B extends core.int>(int x) x22;
   late void Function<A>(List<A> x) Function<B extends core.int>(int x) x23;
 
-  U19({this.tIsBool: false, this.tIsInt: false})
+  U19({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0({Function x = _voidFunction}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type1_test.dart b/tests/language/function_type/function_type1_test.dart
index 4358f50..a972659 100644
--- a/tests/language/function_type/function_type1_test.dart
+++ b/tests/language/function_type/function_type1_test.dart
@@ -104,7 +104,7 @@
   late Function<A>(List<Function> x) Function(int x) x22;
   late void Function<A>(core.List<core.int> x) Function(int x) x23;
 
-  U1({this.tIsBool: false, this.tIsInt: false})
+  U1({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0([int x = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type20_test.dart b/tests/language/function_type/function_type20_test.dart
index a8df364..8bbb1bf3 100644
--- a/tests/language/function_type/function_type20_test.dart
+++ b/tests/language/function_type/function_type20_test.dart
@@ -101,7 +101,7 @@
   late Function<A>(List<A> x) Function() x22;
   late int Function(B x) Function<B extends core.int>() x23;
 
-  U20({this.tIsBool: false, this.tIsInt: false})
+  U20({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, {Function x = _voidFunction}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type21_test.dart b/tests/language/function_type/function_type21_test.dart
index ae5fdb6..b4fb488 100644
--- a/tests/language/function_type/function_type21_test.dart
+++ b/tests/language/function_type/function_type21_test.dart
@@ -103,7 +103,7 @@
   late Function<A>(List<A> x) Function(int x) x22;
   late int Function(B x) Function<B extends core.int>(int x) x23;
 
-  U21({this.tIsBool: false, this.tIsInt: false})
+  U21({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int y, {Function x = _voidFunction}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type22_test.dart b/tests/language/function_type/function_type22_test.dart
index 371ad94..8a0bf32 100644
--- a/tests/language/function_type/function_type22_test.dart
+++ b/tests/language/function_type/function_type22_test.dart
@@ -127,7 +127,7 @@
   late Function<A>(List<A> x) Function<B extends core.int>() x22;
   late Function Function(B x) Function<B extends core.int>() x23;
 
-  U22({this.tIsBool: false, this.tIsInt: false})
+  U22({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(List<Function> x) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type23_test.dart b/tests/language/function_type/function_type23_test.dart
index eb2db97..66d23ee 100644
--- a/tests/language/function_type/function_type23_test.dart
+++ b/tests/language/function_type/function_type23_test.dart
@@ -142,7 +142,7 @@
   late Function<A>(List<A> x) Function<B extends core.int>(int x) x22;
   late Function Function(B x) Function<B extends core.int>(int x) x23;
 
-  U23({this.tIsBool: false, this.tIsInt: false})
+  U23({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0([List<Function> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type24_test.dart b/tests/language/function_type/function_type24_test.dart
index 71b8e09..93650f1 100644
--- a/tests/language/function_type/function_type24_test.dart
+++ b/tests/language/function_type/function_type24_test.dart
@@ -101,7 +101,7 @@
   late A Function<A>(int x) Function() x22;
   late List<Function> Function(B x) Function<B extends core.int>() x23;
 
-  U24({this.tIsBool: false, this.tIsInt: false})
+  U24({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, [List<Function> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type25_test.dart b/tests/language/function_type/function_type25_test.dart
index e50f32c..da856c5 100644
--- a/tests/language/function_type/function_type25_test.dart
+++ b/tests/language/function_type/function_type25_test.dart
@@ -104,7 +104,7 @@
   late A Function<A>(int x) Function(int x) x22;
   late List<Function> Function(B x) Function<B extends core.int>(int x) x23;
 
-  U25({this.tIsBool: false, this.tIsInt: false})
+  U25({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int y, [List<Function> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type26_test.dart b/tests/language/function_type/function_type26_test.dart
index bb5510c..dee7192 100644
--- a/tests/language/function_type/function_type26_test.dart
+++ b/tests/language/function_type/function_type26_test.dart
@@ -136,7 +136,7 @@
   late A Function<A>(int x) Function<B extends core.int>() x22;
   late core.List<core.int> Function(B x) Function<B extends core.int>() x23;
 
-  U26({this.tIsBool: false, this.tIsInt: false})
+  U26({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(List<Function> x0) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type27_test.dart b/tests/language/function_type/function_type27_test.dart
index d96f60e..4e6bd1a 100644
--- a/tests/language/function_type/function_type27_test.dart
+++ b/tests/language/function_type/function_type27_test.dart
@@ -145,7 +145,7 @@
   late core.List<core.int> Function(B x) Function<B extends core.int>(int x)
       x23;
 
-  U27({this.tIsBool: false, this.tIsInt: false})
+  U27({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0([List<Function> x0 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type28_test.dart b/tests/language/function_type/function_type28_test.dart
index 43d24f0..e73db2d 100644
--- a/tests/language/function_type/function_type28_test.dart
+++ b/tests/language/function_type/function_type28_test.dart
@@ -101,7 +101,7 @@
   late A Function<A>(Function x) Function() x22;
   late List<T> Function(B x) Function<B extends core.int>() x23;
 
-  U28({this.tIsBool: false, this.tIsInt: false})
+  U28({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type29_test.dart b/tests/language/function_type/function_type29_test.dart
index 698cd38..0e6a8d4 100644
--- a/tests/language/function_type/function_type29_test.dart
+++ b/tests/language/function_type/function_type29_test.dart
@@ -103,7 +103,7 @@
   late A Function<A>(Function x) Function(int x) x22;
   late List<T> Function(B x) Function<B extends core.int>(int x) x23;
 
-  U29({this.tIsBool: false, this.tIsInt: false})
+  U29({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x, [List<Function> x0 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type2_test.dart b/tests/language/function_type/function_type2_test.dart
index 91eb040..a5559b7 100644
--- a/tests/language/function_type/function_type2_test.dart
+++ b/tests/language/function_type/function_type2_test.dart
@@ -134,7 +134,7 @@
   late void Function<A>(core.List<core.int> x) Function<B extends core.int>()
       x23;
 
-  U2({this.tIsBool: false, this.tIsInt: false})
+  U2({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, [int x = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type30_test.dart b/tests/language/function_type/function_type30_test.dart
index 195eaba..bb77b4d 100644
--- a/tests/language/function_type/function_type30_test.dart
+++ b/tests/language/function_type/function_type30_test.dart
@@ -130,7 +130,7 @@
   late A Function<A>(Function x) Function<B extends core.int>() x22;
   late Function(B x) Function<B extends core.int>() x23;
 
-  U30({this.tIsBool: false, this.tIsInt: false})
+  U30({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0({List<Function> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type31_test.dart b/tests/language/function_type/function_type31_test.dart
index 3426339..39859b4 100644
--- a/tests/language/function_type/function_type31_test.dart
+++ b/tests/language/function_type/function_type31_test.dart
@@ -140,7 +140,7 @@
   late A Function<A>(Function x) Function<B extends core.int>(int x) x22;
   late Function(B x) Function<B extends core.int>(int x) x23;
 
-  U31({this.tIsBool: false, this.tIsInt: false})
+  U31({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, {List<Function> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type32_test.dart b/tests/language/function_type/function_type32_test.dart
index 423bcd1..2734451 100644
--- a/tests/language/function_type/function_type32_test.dart
+++ b/tests/language/function_type/function_type32_test.dart
@@ -102,7 +102,7 @@
   late A Function<A>(List<Function> x) Function() x22;
   late B Function(B x) Function<B extends core.int>() x23;
 
-  U32({this.tIsBool: false, this.tIsInt: false})
+  U32({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int y, {List<Function> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type33_test.dart b/tests/language/function_type/function_type33_test.dart
index e7c166b..cdafcff 100644
--- a/tests/language/function_type/function_type33_test.dart
+++ b/tests/language/function_type/function_type33_test.dart
@@ -107,7 +107,7 @@
   late A Function<A>(List<Function> x) Function(int x) x22;
   late B Function(B x) Function<B extends core.int>(int x) x23;
 
-  U33({this.tIsBool: false, this.tIsInt: false})
+  U33({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(core.List<core.int> x) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type34_test.dart b/tests/language/function_type/function_type34_test.dart
index e3643a3..a67ef85 100644
--- a/tests/language/function_type/function_type34_test.dart
+++ b/tests/language/function_type/function_type34_test.dart
@@ -127,7 +127,7 @@
   late A Function<A>(List<Function> x) Function<B extends core.int>() x22;
   late List<B> Function(B x) Function<B extends core.int>() x23;
 
-  U34({this.tIsBool: false, this.tIsInt: false})
+  U34({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0([core.List<core.int> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type35_test.dart b/tests/language/function_type/function_type35_test.dart
index 313cf3d..24b1f90 100644
--- a/tests/language/function_type/function_type35_test.dart
+++ b/tests/language/function_type/function_type35_test.dart
@@ -139,7 +139,7 @@
   late A Function<A>(List<Function> x) Function<B extends core.int>(int x) x22;
   late List<B> Function(B x) Function<B extends core.int>(int x) x23;
 
-  U35({this.tIsBool: false, this.tIsInt: false})
+  U35({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type36_test.dart b/tests/language/function_type/function_type36_test.dart
index ff2124d..7acad4f 100644
--- a/tests/language/function_type/function_type36_test.dart
+++ b/tests/language/function_type/function_type36_test.dart
@@ -103,7 +103,7 @@
   late A Function<A>(core.List<core.int> x) Function() x22;
   late void Function(B x) Function<B extends core.int>() x23;
 
-  U36({this.tIsBool: false, this.tIsInt: false})
+  U36({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type37_test.dart b/tests/language/function_type/function_type37_test.dart
index 343bdca..e8f7310 100644
--- a/tests/language/function_type/function_type37_test.dart
+++ b/tests/language/function_type/function_type37_test.dart
@@ -107,7 +107,7 @@
   late A Function<A>(core.List<core.int> x) Function(int x) x22;
   late void Function(B x) Function<B extends core.int>(int x) x23;
 
-  U37({this.tIsBool: false, this.tIsInt: false})
+  U37({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(core.List<core.int> x0) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type38_test.dart b/tests/language/function_type/function_type38_test.dart
index e6a102d..6b92596 100644
--- a/tests/language/function_type/function_type38_test.dart
+++ b/tests/language/function_type/function_type38_test.dart
@@ -127,7 +127,7 @@
   late A Function<A>(core.List<core.int> x) Function<B extends core.int>() x22;
   late B Function(int x) Function<B extends core.int>() x23;
 
-  U38({this.tIsBool: false, this.tIsInt: false})
+  U38({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0([core.List<core.int> x0 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type39_test.dart b/tests/language/function_type/function_type39_test.dart
index fefb0cf..44a871b 100644
--- a/tests/language/function_type/function_type39_test.dart
+++ b/tests/language/function_type/function_type39_test.dart
@@ -147,7 +147,7 @@
       x22;
   late B Function(int x) Function<B extends core.int>(int x) x23;
 
-  U39({this.tIsBool: false, this.tIsInt: false})
+  U39({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type3_test.dart b/tests/language/function_type/function_type3_test.dart
index 23c5873..2023626 100644
--- a/tests/language/function_type/function_type3_test.dart
+++ b/tests/language/function_type/function_type3_test.dart
@@ -148,7 +148,7 @@
   late void Function<A>(core.List<core.int> x) Function<B extends core.int>(
       int x) x23;
 
-  U3({this.tIsBool: false, this.tIsInt: false})
+  U3({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int y, [int x = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type40_test.dart b/tests/language/function_type/function_type40_test.dart
index 860dbec..9ba0f8a 100644
--- a/tests/language/function_type/function_type40_test.dart
+++ b/tests/language/function_type/function_type40_test.dart
@@ -103,7 +103,7 @@
   late A Function<A>(List<T> x) Function() x22;
   late B Function(Function x) Function<B extends core.int>() x23;
 
-  U40({this.tIsBool: false, this.tIsInt: false})
+  U40({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type41_test.dart b/tests/language/function_type/function_type41_test.dart
index 48ae18b..f5b7877 100644
--- a/tests/language/function_type/function_type41_test.dart
+++ b/tests/language/function_type/function_type41_test.dart
@@ -106,7 +106,7 @@
   late A Function<A>(List<T> x) Function(int x) x22;
   late B Function(Function x) Function<B extends core.int>(int x) x23;
 
-  U41({this.tIsBool: false, this.tIsInt: false})
+  U41({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0({core.List<core.int> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type42_test.dart b/tests/language/function_type/function_type42_test.dart
index 37251c3..db0bc8e 100644
--- a/tests/language/function_type/function_type42_test.dart
+++ b/tests/language/function_type/function_type42_test.dart
@@ -129,7 +129,7 @@
   late A Function<A>(List<T> x) Function<B extends core.int>() x22;
   late B Function(List<Function> x) Function<B extends core.int>() x23;
 
-  U42({this.tIsBool: false, this.tIsInt: false})
+  U42({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type43_test.dart b/tests/language/function_type/function_type43_test.dart
index 86d8998..bc0b1fb 100644
--- a/tests/language/function_type/function_type43_test.dart
+++ b/tests/language/function_type/function_type43_test.dart
@@ -145,7 +145,7 @@
   late A Function<A>(List<T> x) Function<B extends core.int>(int x) x22;
   late B Function(List<Function> x) Function<B extends core.int>(int x) x23;
 
-  U43({this.tIsBool: false, this.tIsInt: false})
+  U43({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type44_test.dart b/tests/language/function_type/function_type44_test.dart
index a500615..36f5e88 100644
--- a/tests/language/function_type/function_type44_test.dart
+++ b/tests/language/function_type/function_type44_test.dart
@@ -102,7 +102,7 @@
   late A Function<A>() Function() x22;
   late B Function(core.List<core.int> x) Function<B extends core.int>() x23;
 
-  U44({this.tIsBool: false, this.tIsInt: false})
+  U44({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(List<T> x) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type45_test.dart b/tests/language/function_type/function_type45_test.dart
index 5cdf875..3e825cc 100644
--- a/tests/language/function_type/function_type45_test.dart
+++ b/tests/language/function_type/function_type45_test.dart
@@ -104,7 +104,7 @@
   late B Function(core.List<core.int> x) Function<B extends core.int>(int x)
       x23;
 
-  U45({this.tIsBool: false, this.tIsInt: false})
+  U45({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0([List<T> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type46_test.dart b/tests/language/function_type/function_type46_test.dart
index ebd19bf..9eb37c2 100644
--- a/tests/language/function_type/function_type46_test.dart
+++ b/tests/language/function_type/function_type46_test.dart
@@ -134,7 +134,7 @@
   late A Function<A>() Function<B extends core.int>() x22;
   late B Function(List<T> x) Function<B extends core.int>() x23;
 
-  U46({this.tIsBool: false, this.tIsInt: false})
+  U46({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, [List<T> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type47_test.dart b/tests/language/function_type/function_type47_test.dart
index cec7699..0b0de83 100644
--- a/tests/language/function_type/function_type47_test.dart
+++ b/tests/language/function_type/function_type47_test.dart
@@ -143,7 +143,7 @@
   late A Function<A>() Function<B extends core.int>(int x) x22;
   late B Function(List<T> x) Function<B extends core.int>(int x) x23;
 
-  U47({this.tIsBool: false, this.tIsInt: false})
+  U47({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int y, [List<T> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type48_test.dart b/tests/language/function_type/function_type48_test.dart
index c500094..700eaf5 100644
--- a/tests/language/function_type/function_type48_test.dart
+++ b/tests/language/function_type/function_type48_test.dart
@@ -102,7 +102,7 @@
   late A Function<A>(A x) Function() x22;
   late B Function() Function<B extends core.int>() x23;
 
-  U48({this.tIsBool: false, this.tIsInt: false})
+  U48({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(List<T> x0) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type49_test.dart b/tests/language/function_type/function_type49_test.dart
index 04c1f3e..6cec2ac 100644
--- a/tests/language/function_type/function_type49_test.dart
+++ b/tests/language/function_type/function_type49_test.dart
@@ -104,7 +104,7 @@
   late A Function<A>(A x) Function(int x) x22;
   late B Function() Function<B extends core.int>(int x) x23;
 
-  U49({this.tIsBool: false, this.tIsInt: false})
+  U49({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0([List<T> x0 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type4_test.dart b/tests/language/function_type/function_type4_test.dart
index 77b3d2b..02ecb62 100644
--- a/tests/language/function_type/function_type4_test.dart
+++ b/tests/language/function_type/function_type4_test.dart
@@ -105,7 +105,7 @@
   late Function<A>(core.List<core.int> x) Function() x22;
   late void Function<A>(List<T> x) Function() x23;
 
-  U4({this.tIsBool: false, this.tIsInt: false})
+  U4({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type50_test.dart b/tests/language/function_type/function_type50_test.dart
index cc83722..341568d 100644
--- a/tests/language/function_type/function_type50_test.dart
+++ b/tests/language/function_type/function_type50_test.dart
@@ -125,7 +125,7 @@
   late core.List<core.int> Function<A>() Function<B extends core.int>() x21;
   late A Function<A>(A x) Function<B extends core.int>() x22;
 
-  U50({this.tIsBool: false, this.tIsInt: false})
+  U50({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, [List<T> x1 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type51_test.dart b/tests/language/function_type/function_type51_test.dart
index d77cc17..34c92d8 100644
--- a/tests/language/function_type/function_type51_test.dart
+++ b/tests/language/function_type/function_type51_test.dart
@@ -141,7 +141,7 @@
       x21;
   late A Function<A>(A x) Function<B extends core.int>(int x) x22;
 
-  U51({this.tIsBool: false, this.tIsInt: false})
+  U51({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x, [List<T> x0 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type52_test.dart b/tests/language/function_type/function_type52_test.dart
index 9e3ad9f..4ebb468 100644
--- a/tests/language/function_type/function_type52_test.dart
+++ b/tests/language/function_type/function_type52_test.dart
@@ -101,7 +101,7 @@
   late core.List<core.int> Function<A>(A x) Function() x21;
   late A Function<A>(List<A> x) Function() x22;
 
-  U52({this.tIsBool: false, this.tIsInt: false})
+  U52({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0({List<T> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type53_test.dart b/tests/language/function_type/function_type53_test.dart
index 9bf4d02..3ea2e32 100644
--- a/tests/language/function_type/function_type53_test.dart
+++ b/tests/language/function_type/function_type53_test.dart
@@ -106,7 +106,7 @@
   late core.List<core.int> Function<A>(A x) Function(int x) x21;
   late A Function<A>(List<A> x) Function(int x) x22;
 
-  U53({this.tIsBool: false, this.tIsInt: false})
+  U53({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, {List<T> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type54_test.dart b/tests/language/function_type/function_type54_test.dart
index 1e3208c..855c06f 100644
--- a/tests/language/function_type/function_type54_test.dart
+++ b/tests/language/function_type/function_type54_test.dart
@@ -125,7 +125,7 @@
   late core.List<core.int> Function<A>(A x) Function<B extends core.int>() x21;
   late A Function<A>(List<A> x) Function<B extends core.int>() x22;
 
-  U54({this.tIsBool: false, this.tIsInt: false})
+  U54({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int y, {List<T> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type55_test.dart b/tests/language/function_type/function_type55_test.dart
index 5722ccb..f57c3d4 100644
--- a/tests/language/function_type/function_type55_test.dart
+++ b/tests/language/function_type/function_type55_test.dart
@@ -138,7 +138,7 @@
       x21;
   late A Function<A>(List<A> x) Function<B extends core.int>(int x) x22;
 
-  U55({this.tIsBool: false, this.tIsInt: false})
+  U55({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0() => throw 'uncalled';
diff --git a/tests/language/function_type/function_type56_test.dart b/tests/language/function_type/function_type56_test.dart
index 0ba9a93..69c92f7 100644
--- a/tests/language/function_type/function_type56_test.dart
+++ b/tests/language/function_type/function_type56_test.dart
@@ -100,7 +100,7 @@
   late core.List<core.int> Function<A>(List<A> x) Function() x21;
   late List<A> Function<A>(int x) Function() x22;
 
-  U56({this.tIsBool: false, this.tIsInt: false})
+  U56({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type57_test.dart b/tests/language/function_type/function_type57_test.dart
index 127cf18..5e48112 100644
--- a/tests/language/function_type/function_type57_test.dart
+++ b/tests/language/function_type/function_type57_test.dart
@@ -102,7 +102,7 @@
   late core.List<core.int> Function<A>(List<A> x) Function(int x) x21;
   late List<A> Function<A>(int x) Function(int x) x22;
 
-  U57({this.tIsBool: false, this.tIsInt: false})
+  U57({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0([int x = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type58_test.dart b/tests/language/function_type/function_type58_test.dart
index 55dcc02..8fd76b2 100644
--- a/tests/language/function_type/function_type58_test.dart
+++ b/tests/language/function_type/function_type58_test.dart
@@ -123,7 +123,7 @@
       x21;
   late List<A> Function<A>(int x) Function<B extends core.int>() x22;
 
-  U58({this.tIsBool: false, this.tIsInt: false})
+  U58({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, [int x = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type59_test.dart b/tests/language/function_type/function_type59_test.dart
index 8903d02..05c3fd6 100644
--- a/tests/language/function_type/function_type59_test.dart
+++ b/tests/language/function_type/function_type59_test.dart
@@ -138,7 +138,7 @@
       int x) x21;
   late List<A> Function<A>(int x) Function<B extends core.int>(int x) x22;
 
-  U59({this.tIsBool: false, this.tIsInt: false})
+  U59({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int y, [int x = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type5_test.dart b/tests/language/function_type/function_type5_test.dart
index 43c4b84..f63f5e5 100644
--- a/tests/language/function_type/function_type5_test.dart
+++ b/tests/language/function_type/function_type5_test.dart
@@ -106,7 +106,7 @@
   late Function<A>(core.List<core.int> x) Function(int x) x22;
   late void Function<A>(List<T> x) Function(int x) x23;
 
-  U5({this.tIsBool: false, this.tIsInt: false})
+  U5({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0([int x0 = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type60_test.dart b/tests/language/function_type/function_type60_test.dart
index c42ce16..1578d00 100644
--- a/tests/language/function_type/function_type60_test.dart
+++ b/tests/language/function_type/function_type60_test.dart
@@ -99,7 +99,7 @@
   late List<T> Function<A>(int x) Function() x21;
   late List<A> Function<A>(Function x) Function() x22;
 
-  U60({this.tIsBool: false, this.tIsInt: false})
+  U60({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type61_test.dart b/tests/language/function_type/function_type61_test.dart
index 1d6bb68..23f141b 100644
--- a/tests/language/function_type/function_type61_test.dart
+++ b/tests/language/function_type/function_type61_test.dart
@@ -102,7 +102,7 @@
   late List<T> Function<A>(int x) Function(int x) x21;
   late List<A> Function<A>(Function x) Function(int x) x22;
 
-  U61({this.tIsBool: false, this.tIsInt: false})
+  U61({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0([int x0 = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type62_test.dart b/tests/language/function_type/function_type62_test.dart
index 5cfc9ec..81b4ba0 100644
--- a/tests/language/function_type/function_type62_test.dart
+++ b/tests/language/function_type/function_type62_test.dart
@@ -124,7 +124,7 @@
   late List<T> Function<A>(int x) Function<B extends core.int>() x21;
   late List<A> Function<A>(Function x) Function<B extends core.int>() x22;
 
-  U62({this.tIsBool: false, this.tIsInt: false})
+  U62({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, [int x1 = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type63_test.dart b/tests/language/function_type/function_type63_test.dart
index 9950b66..8427968 100644
--- a/tests/language/function_type/function_type63_test.dart
+++ b/tests/language/function_type/function_type63_test.dart
@@ -133,7 +133,7 @@
   late List<T> Function<A>(int x) Function<B extends core.int>(int x) x21;
   late List<A> Function<A>(Function x) Function<B extends core.int>(int x) x22;
 
-  U63({this.tIsBool: false, this.tIsInt: false})
+  U63({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x, [int x0 = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type64_test.dart b/tests/language/function_type/function_type64_test.dart
index 56e5697..66fbdb2 100644
--- a/tests/language/function_type/function_type64_test.dart
+++ b/tests/language/function_type/function_type64_test.dart
@@ -100,7 +100,7 @@
   late List<T> Function<A>(Function x) Function() x21;
   late List<A> Function<A>(List<Function> x) Function() x22;
 
-  U64({this.tIsBool: false, this.tIsInt: false})
+  U64({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0({int x = -1}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type65_test.dart b/tests/language/function_type/function_type65_test.dart
index e3bef3e..cada000 100644
--- a/tests/language/function_type/function_type65_test.dart
+++ b/tests/language/function_type/function_type65_test.dart
@@ -101,7 +101,7 @@
   late List<T> Function<A>(Function x) Function(int x) x21;
   late List<A> Function<A>(List<Function> x) Function(int x) x22;
 
-  U65({this.tIsBool: false, this.tIsInt: false})
+  U65({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, {int x = -1}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type66_test.dart b/tests/language/function_type/function_type66_test.dart
index 1de0e6a..c8c8767 100644
--- a/tests/language/function_type/function_type66_test.dart
+++ b/tests/language/function_type/function_type66_test.dart
@@ -124,7 +124,7 @@
   late List<T> Function<A>(Function x) Function<B extends core.int>() x21;
   late List<A> Function<A>(List<Function> x) Function<B extends core.int>() x22;
 
-  U66({this.tIsBool: false, this.tIsInt: false})
+  U66({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int y, {int x = -1}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type67_test.dart b/tests/language/function_type/function_type67_test.dart
index 0875a3d..1b39735 100644
--- a/tests/language/function_type/function_type67_test.dart
+++ b/tests/language/function_type/function_type67_test.dart
@@ -138,7 +138,7 @@
   late List<A> Function<A>(List<Function> x) Function<B extends core.int>(int x)
       x22;
 
-  U67({this.tIsBool: false, this.tIsInt: false})
+  U67({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(Function x) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type68_test.dart b/tests/language/function_type/function_type68_test.dart
index 1f28348..d08d0e2 100644
--- a/tests/language/function_type/function_type68_test.dart
+++ b/tests/language/function_type/function_type68_test.dart
@@ -98,7 +98,7 @@
   late List<T> Function<A>(List<Function> x) Function() x21;
   late List<A> Function<A>(core.List<core.int> x) Function() x22;
 
-  U68({this.tIsBool: false, this.tIsInt: false})
+  U68({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0([Function x = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type69_test.dart b/tests/language/function_type/function_type69_test.dart
index ad7b5cb..5e8e1b3 100644
--- a/tests/language/function_type/function_type69_test.dart
+++ b/tests/language/function_type/function_type69_test.dart
@@ -102,7 +102,7 @@
   late List<T> Function<A>(List<Function> x) Function(int x) x21;
   late List<A> Function<A>(core.List<core.int> x) Function(int x) x22;
 
-  U69({this.tIsBool: false, this.tIsInt: false})
+  U69({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, [Function x = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type6_test.dart b/tests/language/function_type/function_type6_test.dart
index 7939e63..1680c99 100644
--- a/tests/language/function_type/function_type6_test.dart
+++ b/tests/language/function_type/function_type6_test.dart
@@ -131,7 +131,7 @@
   late Function<A>(core.List<core.int> x) Function<B extends core.int>() x22;
   late void Function<A>(List<T> x) Function<B extends core.int>() x23;
 
-  U6({this.tIsBool: false, this.tIsInt: false})
+  U6({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, [int x1 = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type70_test.dart b/tests/language/function_type/function_type70_test.dart
index 1c44dd1..064d5a8 100644
--- a/tests/language/function_type/function_type70_test.dart
+++ b/tests/language/function_type/function_type70_test.dart
@@ -122,7 +122,7 @@
   late List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>()
       x22;
 
-  U70({this.tIsBool: false, this.tIsInt: false})
+  U70({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int y, [Function x = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type71_test.dart b/tests/language/function_type/function_type71_test.dart
index 61df998..8df3c9b 100644
--- a/tests/language/function_type/function_type71_test.dart
+++ b/tests/language/function_type/function_type71_test.dart
@@ -140,7 +140,7 @@
   late List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>(
       int x) x22;
 
-  U71({this.tIsBool: false, this.tIsInt: false})
+  U71({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(Function x0) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type72_test.dart b/tests/language/function_type/function_type72_test.dart
index b33b49b..b1ed9a8 100644
--- a/tests/language/function_type/function_type72_test.dart
+++ b/tests/language/function_type/function_type72_test.dart
@@ -100,7 +100,7 @@
   late List<T> Function<A>(core.List<core.int> x) Function() x21;
   late List<A> Function<A>(List<T> x) Function() x22;
 
-  U72({this.tIsBool: false, this.tIsInt: false})
+  U72({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0([Function x0 = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type73_test.dart b/tests/language/function_type/function_type73_test.dart
index 605428e..9b5313a 100644
--- a/tests/language/function_type/function_type73_test.dart
+++ b/tests/language/function_type/function_type73_test.dart
@@ -104,7 +104,7 @@
   late List<T> Function<A>(core.List<core.int> x) Function(int x) x21;
   late List<A> Function<A>(List<T> x) Function(int x) x22;
 
-  U73({this.tIsBool: false, this.tIsInt: false})
+  U73({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type74_test.dart b/tests/language/function_type/function_type74_test.dart
index 110832e..77f9727 100644
--- a/tests/language/function_type/function_type74_test.dart
+++ b/tests/language/function_type/function_type74_test.dart
@@ -128,7 +128,7 @@
       x21;
   late List<A> Function<A>(List<T> x) Function<B extends core.int>() x22;
 
-  U74({this.tIsBool: false, this.tIsInt: false})
+  U74({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type75_test.dart b/tests/language/function_type/function_type75_test.dart
index 0f7938c..c1518600 100644
--- a/tests/language/function_type/function_type75_test.dart
+++ b/tests/language/function_type/function_type75_test.dart
@@ -140,7 +140,7 @@
       int x) x21;
   late List<A> Function<A>(List<T> x) Function<B extends core.int>(int x) x22;
 
-  U75({this.tIsBool: false, this.tIsInt: false})
+  U75({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0({Function x = _voidFunction}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type76_test.dart b/tests/language/function_type/function_type76_test.dart
index 0465785..2123095 100644
--- a/tests/language/function_type/function_type76_test.dart
+++ b/tests/language/function_type/function_type76_test.dart
@@ -101,7 +101,7 @@
   late List<T> Function<A>(List<T> x) Function() x21;
   late List<A> Function<A>() Function() x22;
 
-  U76({this.tIsBool: false, this.tIsInt: false})
+  U76({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, {Function x = _voidFunction}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type77_test.dart b/tests/language/function_type/function_type77_test.dart
index e310c8f..050e7b2 100644
--- a/tests/language/function_type/function_type77_test.dart
+++ b/tests/language/function_type/function_type77_test.dart
@@ -102,7 +102,7 @@
   late List<T> Function<A>(List<T> x) Function(int x) x21;
   late List<A> Function<A>() Function(int x) x22;
 
-  U77({this.tIsBool: false, this.tIsInt: false})
+  U77({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int y, {Function x = _voidFunction}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type78_test.dart b/tests/language/function_type/function_type78_test.dart
index bc3a0af..4d3819d 100644
--- a/tests/language/function_type/function_type78_test.dart
+++ b/tests/language/function_type/function_type78_test.dart
@@ -127,7 +127,7 @@
   late List<T> Function<A>(List<T> x) Function<B extends core.int>() x21;
   late List<A> Function<A>() Function<B extends core.int>() x22;
 
-  U78({this.tIsBool: false, this.tIsInt: false})
+  U78({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(List<Function> x) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type79_test.dart b/tests/language/function_type/function_type79_test.dart
index 7932960..9f3e55b 100644
--- a/tests/language/function_type/function_type79_test.dart
+++ b/tests/language/function_type/function_type79_test.dart
@@ -140,7 +140,7 @@
   late List<T> Function<A>(List<T> x) Function<B extends core.int>(int x) x21;
   late List<A> Function<A>() Function<B extends core.int>(int x) x22;
 
-  U79({this.tIsBool: false, this.tIsInt: false})
+  U79({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0([List<Function> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type7_test.dart b/tests/language/function_type/function_type7_test.dart
index eb38ae3..9c690f5 100644
--- a/tests/language/function_type/function_type7_test.dart
+++ b/tests/language/function_type/function_type7_test.dart
@@ -141,7 +141,7 @@
       x22;
   late void Function<A>(List<T> x) Function<B extends core.int>(int x) x23;
 
-  U7({this.tIsBool: false, this.tIsInt: false})
+  U7({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x, [int x0 = -1]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type80_test.dart b/tests/language/function_type/function_type80_test.dart
index 1cb0d30..52e4e27 100644
--- a/tests/language/function_type/function_type80_test.dart
+++ b/tests/language/function_type/function_type80_test.dart
@@ -102,7 +102,7 @@
   late List<T> Function<A>() Function() x21;
   late List<A> Function<A>(A x) Function() x22;
 
-  U80({this.tIsBool: false, this.tIsInt: false})
+  U80({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, [List<Function> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type81_test.dart b/tests/language/function_type/function_type81_test.dart
index 0c89ae4..39f4f23 100644
--- a/tests/language/function_type/function_type81_test.dart
+++ b/tests/language/function_type/function_type81_test.dart
@@ -105,7 +105,7 @@
   late List<T> Function<A>() Function(int x) x21;
   late List<A> Function<A>(A x) Function(int x) x22;
 
-  U81({this.tIsBool: false, this.tIsInt: false})
+  U81({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int y, [List<Function> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type82_test.dart b/tests/language/function_type/function_type82_test.dart
index ac0159d4..95615d5 100644
--- a/tests/language/function_type/function_type82_test.dart
+++ b/tests/language/function_type/function_type82_test.dart
@@ -121,7 +121,7 @@
   late List<T> Function<A>() Function<B extends core.int>() x21;
   late List<A> Function<A>(A x) Function<B extends core.int>() x22;
 
-  U82({this.tIsBool: false, this.tIsInt: false})
+  U82({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(List<Function> x0) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type83_test.dart b/tests/language/function_type/function_type83_test.dart
index 7cd2eb5..cc2a799 100644
--- a/tests/language/function_type/function_type83_test.dart
+++ b/tests/language/function_type/function_type83_test.dart
@@ -132,7 +132,7 @@
   late List<T> Function<A>() Function<B extends core.int>(int x) x21;
   late List<A> Function<A>(A x) Function<B extends core.int>(int x) x22;
 
-  U83({this.tIsBool: false, this.tIsInt: false})
+  U83({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0([List<Function> x0 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type84_test.dart b/tests/language/function_type/function_type84_test.dart
index 4c34ba2..ef112d2 100644
--- a/tests/language/function_type/function_type84_test.dart
+++ b/tests/language/function_type/function_type84_test.dart
@@ -100,7 +100,7 @@
   late List<T> Function<A>(A x) Function() x21;
   late List<A> Function<A>(List<A> x) Function() x22;
 
-  U84({this.tIsBool: false, this.tIsInt: false})
+  U84({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type85_test.dart b/tests/language/function_type/function_type85_test.dart
index a56fa37..650f0dd 100644
--- a/tests/language/function_type/function_type85_test.dart
+++ b/tests/language/function_type/function_type85_test.dart
@@ -104,7 +104,7 @@
   late List<T> Function<A>(A x) Function(int x) x21;
   late List<A> Function<A>(List<A> x) Function(int x) x22;
 
-  U85({this.tIsBool: false, this.tIsInt: false})
+  U85({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x, [List<Function> x0 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type86_test.dart b/tests/language/function_type/function_type86_test.dart
index 3961f324..9bd7541 100644
--- a/tests/language/function_type/function_type86_test.dart
+++ b/tests/language/function_type/function_type86_test.dart
@@ -119,7 +119,7 @@
   late List<T> Function<A>(A x) Function<B extends core.int>() x21;
   late List<A> Function<A>(List<A> x) Function<B extends core.int>() x22;
 
-  U86({this.tIsBool: false, this.tIsInt: false})
+  U86({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0({List<Function> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type87_test.dart b/tests/language/function_type/function_type87_test.dart
index c0da986..13139c1 100644
--- a/tests/language/function_type/function_type87_test.dart
+++ b/tests/language/function_type/function_type87_test.dart
@@ -130,7 +130,7 @@
   late List<T> Function<A>(A x) Function<B extends core.int>(int x) x21;
   late List<A> Function<A>(List<A> x) Function<B extends core.int>(int x) x22;
 
-  U87({this.tIsBool: false, this.tIsInt: false})
+  U87({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, {List<Function> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type88_test.dart b/tests/language/function_type/function_type88_test.dart
index 1544392..01cbfbb 100644
--- a/tests/language/function_type/function_type88_test.dart
+++ b/tests/language/function_type/function_type88_test.dart
@@ -99,7 +99,7 @@
   late List<T> Function<A>(List<A> x) Function() x21;
   late void Function<A>(int x) Function() x22;
 
-  U88({this.tIsBool: false, this.tIsInt: false})
+  U88({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int y, {List<Function> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type89_test.dart b/tests/language/function_type/function_type89_test.dart
index a1e892f..2f0b29d 100644
--- a/tests/language/function_type/function_type89_test.dart
+++ b/tests/language/function_type/function_type89_test.dart
@@ -101,7 +101,7 @@
   late List<T> Function<A>(List<A> x) Function(int x) x21;
   late void Function<A>(int x) Function(int x) x22;
 
-  U89({this.tIsBool: false, this.tIsInt: false})
+  U89({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(core.List<core.int> x) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type8_test.dart b/tests/language/function_type/function_type8_test.dart
index d5634fe..4c4f2eb 100644
--- a/tests/language/function_type/function_type8_test.dart
+++ b/tests/language/function_type/function_type8_test.dart
@@ -105,7 +105,7 @@
   late Function<A>(List<T> x) Function() x22;
   late void Function<A>() Function() x23;
 
-  U8({this.tIsBool: false, this.tIsInt: false})
+  U8({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0({int x = -1}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type90_test.dart b/tests/language/function_type/function_type90_test.dart
index 728530c..3b56bf8 100644
--- a/tests/language/function_type/function_type90_test.dart
+++ b/tests/language/function_type/function_type90_test.dart
@@ -119,7 +119,7 @@
   late List<T> Function<A>(List<A> x) Function<B extends core.int>() x21;
   late void Function<A>(int x) Function<B extends core.int>() x22;
 
-  U90({this.tIsBool: false, this.tIsInt: false})
+  U90({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0([core.List<core.int> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type91_test.dart b/tests/language/function_type/function_type91_test.dart
index 102e3de..a20b0ff 100644
--- a/tests/language/function_type/function_type91_test.dart
+++ b/tests/language/function_type/function_type91_test.dart
@@ -129,7 +129,7 @@
   late List<T> Function<A>(List<A> x) Function<B extends core.int>(int x) x21;
   late void Function<A>(int x) Function<B extends core.int>(int x) x22;
 
-  U91({this.tIsBool: false, this.tIsInt: false})
+  U91({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type92_test.dart b/tests/language/function_type/function_type92_test.dart
index 053e0f8..267ac18 100644
--- a/tests/language/function_type/function_type92_test.dart
+++ b/tests/language/function_type/function_type92_test.dart
@@ -101,7 +101,7 @@
   late Function<A>(int x) Function() x21;
   late void Function<A>(Function x) Function() x22;
 
-  U92({this.tIsBool: false, this.tIsInt: false})
+  U92({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type93_test.dart b/tests/language/function_type/function_type93_test.dart
index e87c2ba..209e66e 100644
--- a/tests/language/function_type/function_type93_test.dart
+++ b/tests/language/function_type/function_type93_test.dart
@@ -104,7 +104,7 @@
   late Function<A>(int x) Function(int x) x21;
   late void Function<A>(Function x) Function(int x) x22;
 
-  U93({this.tIsBool: false, this.tIsInt: false})
+  U93({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(core.List<core.int> x0) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type94_test.dart b/tests/language/function_type/function_type94_test.dart
index 011496a..cae1c14 100644
--- a/tests/language/function_type/function_type94_test.dart
+++ b/tests/language/function_type/function_type94_test.dart
@@ -120,7 +120,7 @@
   late Function<A>(int x) Function<B extends core.int>() x21;
   late void Function<A>(Function x) Function<B extends core.int>() x22;
 
-  U94({this.tIsBool: false, this.tIsInt: false})
+  U94({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0([core.List<core.int> x0 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type95_test.dart b/tests/language/function_type/function_type95_test.dart
index e5be48e..53fc1cd 100644
--- a/tests/language/function_type/function_type95_test.dart
+++ b/tests/language/function_type/function_type95_test.dart
@@ -130,7 +130,7 @@
   late Function<A>(int x) Function<B extends core.int>(int x) x21;
   late void Function<A>(Function x) Function<B extends core.int>(int x) x22;
 
-  U95({this.tIsBool: false, this.tIsInt: false})
+  U95({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type96_test.dart b/tests/language/function_type/function_type96_test.dart
index ec3c67d..fe88d8d 100644
--- a/tests/language/function_type/function_type96_test.dart
+++ b/tests/language/function_type/function_type96_test.dart
@@ -102,7 +102,7 @@
   late Function<A>(Function x) Function() x21;
   late void Function<A>(List<Function> x) Function() x22;
 
-  U96({this.tIsBool: false, this.tIsInt: false})
+  U96({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type97_test.dart b/tests/language/function_type/function_type97_test.dart
index 061794a..07d95c6 100644
--- a/tests/language/function_type/function_type97_test.dart
+++ b/tests/language/function_type/function_type97_test.dart
@@ -102,7 +102,7 @@
   late Function<A>(Function x) Function(int x) x21;
   late void Function<A>(List<Function> x) Function(int x) x22;
 
-  U97({this.tIsBool: false, this.tIsInt: false})
+  U97({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0({core.List<core.int> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type98_test.dart b/tests/language/function_type/function_type98_test.dart
index 1a7aded..af13aa9 100644
--- a/tests/language/function_type/function_type98_test.dart
+++ b/tests/language/function_type/function_type98_test.dart
@@ -122,7 +122,7 @@
   late Function<A>(Function x) Function<B extends core.int>() x21;
   late void Function<A>(List<Function> x) Function<B extends core.int>() x22;
 
-  U98({this.tIsBool: false, this.tIsInt: false})
+  U98({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type99_test.dart b/tests/language/function_type/function_type99_test.dart
index 59b8b8e..dbf9894 100644
--- a/tests/language/function_type/function_type99_test.dart
+++ b/tests/language/function_type/function_type99_test.dart
@@ -139,7 +139,7 @@
   late void Function<A>(List<Function> x) Function<B extends core.int>(int x)
       x22;
 
-  U99({this.tIsBool: false, this.tIsInt: false})
+  U99({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   Function m0(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
diff --git a/tests/language/function_type/function_type9_test.dart b/tests/language/function_type/function_type9_test.dart
index f967587..5d94411 100644
--- a/tests/language/function_type/function_type9_test.dart
+++ b/tests/language/function_type/function_type9_test.dart
@@ -108,7 +108,7 @@
   late Function<A>(List<T> x) Function(int x) x22;
   late void Function<A>() Function(int x) x23;
 
-  U9({this.tIsBool: false, this.tIsInt: false})
+  U9({this.tIsBool = false, this.tIsInt = false})
       : tIsDynamic = !tIsBool && !tIsInt;
 
   int m0(int x0, {int x = -1}) => throw 'uncalled';
diff --git a/tests/language/function_type/test_generator.dart b/tests/language/function_type/test_generator.dart
index f02d099..3a800d9 100644
--- a/tests/language/function_type/test_generator.dart
+++ b/tests/language/function_type/test_generator.dart
@@ -288,7 +288,7 @@
   }
 
   /// Writes this type as if it was a function.
-  void writeFunction(StringBuffer buffer, String name, {bool replaceT: true}) {
+  void writeFunction(StringBuffer buffer, String name, {bool replaceT = true}) {
     shouldReplaceTWithInt = replaceT;
     parameterNameCounter = 0;
 
diff --git a/tests/language/generic/functions_test.dart b/tests/language/generic/functions_test.dart
index 880fa62..ae2b3a8 100644
--- a/tests/language/generic/functions_test.dart
+++ b/tests/language/generic/functions_test.dart
@@ -17,7 +17,7 @@
   final BinaryTreeNode<K, V>? _right;
 
   BinaryTreeNode(this._key, this._value,
-      {BinaryTreeNode<K, V>? left: null, BinaryTreeNode<K, V>? right: null})
+      {BinaryTreeNode<K, V>? left = null, BinaryTreeNode<K, V>? right = null})
       : _left = left,
         _right = right;
 
diff --git a/tests/language/generic_methods/generic_methods_test.dart b/tests/language/generic_methods/generic_methods_test.dart
index 31e1d29..376b482 100644
--- a/tests/language/generic_methods/generic_methods_test.dart
+++ b/tests/language/generic_methods/generic_methods_test.dart
@@ -17,7 +17,7 @@
   final BinaryTreeNode<K, V>? _right;
 
   BinaryTreeNode(this._key, this._value,
-      {BinaryTreeNode<K, V>? left: null, BinaryTreeNode<K, V>? right: null})
+      {BinaryTreeNode<K, V>? left = null, BinaryTreeNode<K, V>? right = null})
       : _left = left,
         _right = right;
 
diff --git a/tests/language/inference_update_2/no_such_method_restriction_disabled_lib.dart b/tests/language/inference_update_2/no_such_method_restriction_disabled_lib.dart
new file mode 100644
index 0000000..887420e
--- /dev/null
+++ b/tests/language/inference_update_2/no_such_method_restriction_disabled_lib.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Library used by `no_such_method_restriction_disabled_test.dart`.
+
+// @dart=2.17
+
+class Interface {
+  static int interfaceCount = 0;
+
+  int _privateField = 100;
+
+  int get _privateGetter {
+    interfaceCount++;
+    return 101;
+  }
+
+  set _privateSetter(int value) {
+    interfaceCount++;
+  }
+
+  int _privateMethod() {
+    interfaceCount++;
+    return 102;
+  }
+
+  int publicField = 103;
+
+  int get publicGetter {
+    interfaceCount++;
+    return 104;
+  }
+
+  set publicSetter(int value) {
+    interfaceCount++;
+  }
+
+  int publicMethod() {
+    interfaceCount++;
+    return 105;
+  }
+
+  static int getPrivateField(Interface x) => x._privateField;
+
+  static void setPrivateField(Interface x) => x._privateField = 106;
+
+  static int callPrivateGetter(Interface x) => x._privateGetter;
+
+  static void callPrivateSetter(Interface x) => x._privateSetter = 107;
+
+  static int callPrivateMethod(Interface x) => x._privateMethod();
+
+  static int getPublicField(Interface x) => x.publicField;
+
+  static void setPublicField(Interface x) => x.publicField = 108;
+
+  static int callPublicGetter(Interface x) => x.publicGetter;
+
+  static void callPublicSetter(Interface x) => x.publicSetter = 109;
+
+  static int callPublicMethod(Interface x) => x.publicMethod();
+}
+
+class Dynamic {
+  static int getPrivateField(dynamic x) => x._privateField;
+
+  static void setPrivateField(dynamic x) => x._privateField = 103;
+
+  static int callPrivateGetter(dynamic x) => x._privateGetter;
+
+  static void callPrivateSetter(dynamic x) => x._privateSetter = 104;
+
+  static int callPrivateMethod(dynamic x) => x._privateMethod();
+
+  static int getPublicField(dynamic x) => x.publicField;
+
+  static void setPublicField(dynamic x) => x.publicField = 108;
+
+  static int callPublicGetter(dynamic x) => x.publicGetter;
+
+  static void callPublicSetter(dynamic x) => x.publicSetter = 109;
+
+  static int callPublicMethod(dynamic x) => x.publicMethod();
+}
+
+class Nsm {
+  int otherNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return otherNsmCount++;
+  }
+}
+
+class Stubs implements Interface {
+  int stubsNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return stubsNsmCount++;
+  }
+}
diff --git a/tests/language/inference_update_2/no_such_method_restriction_disabled_test.dart b/tests/language/inference_update_2/no_such_method_restriction_disabled_test.dart
new file mode 100644
index 0000000..fec4e7a
--- /dev/null
+++ b/tests/language/inference_update_2/no_such_method_restriction_disabled_test.dart
@@ -0,0 +1,413 @@
+// Copyright (c) 2022, 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.
+
+// Tests that the behavior of forwarding stubs to call noSuchMethod is
+// restricted to public members and members from the same library; forwarding
+// stubs for private members from other libraries always throw.
+//
+// Without this, field promotion would not be sound.  For example, in the code
+// below, each attempt to get `_i` from an instance of class `B` would result in
+// an invocation of `B.noSuchMethod`, so evaluation of `a._i` at (1) would yield
+// `0`, and evaluation of `a._i` at (2) would yield `null`.
+//
+//     main.dart:
+//       import 'other.dart';
+//       class B implements A {
+//         bool b = false;
+//         @override
+//         dynamic noSuchMethod(Invocation invocation) => (b = !b) ? 0 : null;
+//       }
+//       main() => foo(new B());
+//     other.dart:
+//       class A {
+//         final int? _i;
+//         A(this._i);
+//       }
+//       void foo(A a) {
+//         if (a._i != null) { // (1)
+//           print(a._i + 1);  // (2)
+//         }
+//       }
+//
+// Whereas with the restriction, any attempt to get `_i` from an instance of
+// class `B` would result in an exception, so the code would never reach (2).
+//
+// Since this behavior involves interactions among libraries, we have to think
+// carefully about how it is affected by language versioning.  There are two
+// issues to consider:
+//
+// 1. Should the forwarding stub throw even if the language feature
+//    "inference-update-2" is disabled in the library containing the class
+//    that's causing the forwarding stub to be generated?  We need to answer
+//    this question with a "yes", otherwise a class declaration in a library
+//    with an older language version could still ruin the soundness of field
+//    promotion in some other library.
+//
+// 2. Should the forwarding stub throw even if the language feature
+//    "inference-update-2" is disabled in the library containing the private
+//    member in question?  Our answer to this question doesn't affect soundness,
+//    because field promotion can't happen in libraries for which the language
+//    feature is disabled.  However, we still answer "yes", because otherwise an
+//    attempt to upgrade to a newer language version in one library might cause
+//    unexpected behavior changes in other libraries that import it, and we
+//    don't want that to happen.
+//
+// This file covers cases where the language feature "inference-update-2" is
+// disabled.
+
+// @dart=2.17
+
+import 'package:expect/expect.dart';
+
+import 'no_such_method_restriction_disabled_lib.dart' as lib;
+
+class Interface {
+  static int interfaceCount = 0;
+
+  int _privateField = 100;
+
+  int get _privateGetter {
+    interfaceCount++;
+    return 101;
+  }
+
+  set _privateSetter(int value) {
+    interfaceCount++;
+  }
+
+  int _privateMethod() {
+    interfaceCount++;
+    return 102;
+  }
+
+  int publicField = 103;
+
+  int get publicGetter {
+    interfaceCount++;
+    return 104;
+  }
+
+  set publicSetter(int value) {
+    interfaceCount++;
+  }
+
+  int publicMethod() {
+    interfaceCount++;
+    return 105;
+  }
+
+  static int getPrivateField(Interface x) => x._privateField;
+
+  static void setPrivateField(Interface x) => x._privateField = 106;
+
+  static int callPrivateGetter(Interface x) => x._privateGetter;
+
+  static void callPrivateSetter(Interface x) => x._privateSetter = 107;
+
+  static int callPrivateMethod(Interface x) => x._privateMethod();
+
+  static int getPublicField(Interface x) => x.publicField;
+
+  static void setPublicField(Interface x) => x.publicField = 108;
+
+  static int callPublicGetter(Interface x) => x.publicGetter;
+
+  static void callPublicSetter(Interface x) => x.publicSetter = 109;
+
+  static int callPublicMethod(Interface x) => x.publicMethod();
+}
+
+class Dynamic {
+  static int getPrivateField(dynamic x) => x._privateField;
+
+  static void setPrivateField(dynamic x) => x._privateField = 103;
+
+  static int callPrivateGetter(dynamic x) => x._privateGetter;
+
+  static void callPrivateSetter(dynamic x) => x._privateSetter = 104;
+
+  static int callPrivateMethod(dynamic x) => x._privateMethod();
+
+  static int getPublicField(dynamic x) => x.publicField;
+
+  static void setPublicField(dynamic x) => x.publicField = 108;
+
+  static int callPublicGetter(dynamic x) => x.publicGetter;
+
+  static void callPublicSetter(dynamic x) => x.publicSetter = 109;
+
+  static int callPublicMethod(dynamic x) => x.publicMethod();
+}
+
+/// The tests in this class cover the case where the members are in the same
+/// library as the forwarding stubs.  All member invocations should be
+/// dispatched to noSuchMethod.
+class Local implements Interface {
+  int _localNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return _localNsmCount++;
+  }
+
+  static void testPrivate() {
+    var x = Local();
+    Expect.equals(0, Interface.getPrivateField(x));
+    Expect.equals(1, x._localNsmCount);
+    Interface.setPrivateField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Interface.callPrivateGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Interface.callPrivateSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Interface.callPrivateMethod(x));
+    Expect.equals(5, x._localNsmCount);
+    Expect.equals(0, Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = Local();
+    Expect.equals(0, Interface.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    Interface.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Interface.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Interface.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Interface.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+    Expect.equals(0, Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = Local();
+    Expect.equals(0, Dynamic.getPrivateField(x));
+    Expect.equals(1, x._localNsmCount);
+    Dynamic.setPrivateField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Dynamic.callPrivateGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Dynamic.callPrivateSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Dynamic.callPrivateMethod(x));
+    Expect.equals(5, x._localNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = Local();
+    Expect.equals(0, Dynamic.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    Dynamic.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Dynamic.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Dynamic.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Dynamic.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+  }
+}
+
+/// The tests in this class cover the case where both noSuchMethod and the other
+/// members are in the same library as the forwarding stubs, but that library is
+/// not the same as the library containing this class.  All member invocations
+/// should be dispatched to noSuchMethod.
+class RemoteStubs extends lib.Stubs {
+  static void testPrivate() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Interface.getPrivateField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Interface.setPrivateField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Interface.callPrivateGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Interface.callPrivateSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Interface.callPrivateMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Interface.getPublicField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Interface.setPublicField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Interface.callPublicGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Interface.callPublicSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Interface.callPublicMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Dynamic.getPrivateField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Dynamic.setPrivateField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Dynamic.callPrivateGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Dynamic.callPrivateSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Dynamic.callPrivateMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Dynamic.getPublicField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Dynamic.setPublicField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Dynamic.callPublicGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Dynamic.callPublicSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Dynamic.callPublicMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+  }
+}
+
+/// The tests in this class cover the case where noSuchMember is local, but the
+/// other members are in a different library from the forwarding stubs.  All
+/// public member invocations should be dispatched to noSuchMethod; all private
+/// member invocations should throw.
+class LocalNsm implements lib.Interface {
+  int _localNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return _localNsmCount++;
+  }
+
+  static void testPrivate() {
+    var x = LocalNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Interface.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateMethod(x));
+    Expect.equals(0, x._localNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = LocalNsm();
+    Expect.equals(0, lib.Interface.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    lib.Interface.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, lib.Interface.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    lib.Interface.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, lib.Interface.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = LocalNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateMethod(x));
+    Expect.equals(0, x._localNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = LocalNsm();
+    Expect.equals(0, lib.Dynamic.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    lib.Dynamic.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, lib.Dynamic.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    lib.Dynamic.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, lib.Dynamic.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+  }
+}
+
+/// The tests in this class cover the case where both noSuchMember and the other
+/// members are in a different library from the forwarding stubs.  All public
+/// member invocations should be dispatched to noSuchMethod; all private member
+/// invocations should throw.
+class RemoteNsm extends lib.Nsm implements lib.Interface {
+  static void testPrivate() {
+    var x = RemoteNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Interface.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateMethod(x));
+    Expect.equals(0, x.otherNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = RemoteNsm();
+    Expect.equals(0, lib.Interface.getPublicField(x));
+    Expect.equals(1, x.otherNsmCount);
+    lib.Interface.setPublicField(x);
+    Expect.equals(2, x.otherNsmCount);
+    Expect.equals(2, lib.Interface.callPublicGetter(x));
+    Expect.equals(3, x.otherNsmCount);
+    lib.Interface.callPublicSetter(x);
+    Expect.equals(4, x.otherNsmCount);
+    Expect.equals(4, lib.Interface.callPublicMethod(x));
+    Expect.equals(5, x.otherNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = RemoteNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateMethod(x));
+    Expect.equals(0, x.otherNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = RemoteNsm();
+    Expect.equals(0, lib.Dynamic.getPublicField(x));
+    Expect.equals(1, x.otherNsmCount);
+    lib.Dynamic.setPublicField(x);
+    Expect.equals(2, x.otherNsmCount);
+    Expect.equals(2, lib.Dynamic.callPublicGetter(x));
+    Expect.equals(3, x.otherNsmCount);
+    lib.Dynamic.callPublicSetter(x);
+    Expect.equals(4, x.otherNsmCount);
+    Expect.equals(4, lib.Dynamic.callPublicMethod(x));
+    Expect.equals(5, x.otherNsmCount);
+  }
+}
+
+main() {
+  Local.testPrivate();
+  Local.testPublic();
+  Local.testPrivateDynamic();
+  Local.testPublicDynamic();
+  RemoteStubs.testPrivate();
+  RemoteStubs.testPublic();
+  RemoteStubs.testPrivateDynamic();
+  RemoteStubs.testPublicDynamic();
+  LocalNsm.testPrivate();
+  LocalNsm.testPublic();
+  LocalNsm.testPrivateDynamic();
+  LocalNsm.testPublicDynamic();
+  RemoteNsm.testPrivate();
+  RemoteNsm.testPublic();
+  RemoteNsm.testPrivateDynamic();
+  RemoteNsm.testPublicDynamic();
+}
diff --git a/tests/language/inference_update_2/no_such_method_restriction_enabled_lib.dart b/tests/language/inference_update_2/no_such_method_restriction_enabled_lib.dart
new file mode 100644
index 0000000..3568189
--- /dev/null
+++ b/tests/language/inference_update_2/no_such_method_restriction_enabled_lib.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Library used by `no_such_method_restriction_enabled_test.dart`.
+
+class Interface {
+  static int interfaceCount = 0;
+
+  int _privateField = 100;
+
+  int get _privateGetter {
+    interfaceCount++;
+    return 101;
+  }
+
+  set _privateSetter(int value) {
+    interfaceCount++;
+  }
+
+  int _privateMethod() {
+    interfaceCount++;
+    return 102;
+  }
+
+  int publicField = 103;
+
+  int get publicGetter {
+    interfaceCount++;
+    return 104;
+  }
+
+  set publicSetter(int value) {
+    interfaceCount++;
+  }
+
+  int publicMethod() {
+    interfaceCount++;
+    return 105;
+  }
+
+  static int getPrivateField(Interface x) => x._privateField;
+
+  static void setPrivateField(Interface x) => x._privateField = 106;
+
+  static int callPrivateGetter(Interface x) => x._privateGetter;
+
+  static void callPrivateSetter(Interface x) => x._privateSetter = 107;
+
+  static int callPrivateMethod(Interface x) => x._privateMethod();
+
+  static int getPublicField(Interface x) => x.publicField;
+
+  static void setPublicField(Interface x) => x.publicField = 108;
+
+  static int callPublicGetter(Interface x) => x.publicGetter;
+
+  static void callPublicSetter(Interface x) => x.publicSetter = 109;
+
+  static int callPublicMethod(Interface x) => x.publicMethod();
+}
+
+class Dynamic {
+  static int getPrivateField(dynamic x) => x._privateField;
+
+  static void setPrivateField(dynamic x) => x._privateField = 103;
+
+  static int callPrivateGetter(dynamic x) => x._privateGetter;
+
+  static void callPrivateSetter(dynamic x) => x._privateSetter = 104;
+
+  static int callPrivateMethod(dynamic x) => x._privateMethod();
+
+  static int getPublicField(dynamic x) => x.publicField;
+
+  static void setPublicField(dynamic x) => x.publicField = 108;
+
+  static int callPublicGetter(dynamic x) => x.publicGetter;
+
+  static void callPublicSetter(dynamic x) => x.publicSetter = 109;
+
+  static int callPublicMethod(dynamic x) => x.publicMethod();
+}
+
+class Nsm {
+  int otherNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return otherNsmCount++;
+  }
+}
+
+class Stubs implements Interface {
+  int stubsNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return stubsNsmCount++;
+  }
+}
diff --git a/tests/language/inference_update_2/no_such_method_restriction_enabled_test.dart b/tests/language/inference_update_2/no_such_method_restriction_enabled_test.dart
new file mode 100644
index 0000000..791b9c5
--- /dev/null
+++ b/tests/language/inference_update_2/no_such_method_restriction_enabled_test.dart
@@ -0,0 +1,413 @@
+// Copyright (c) 2022, 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.
+
+// Tests that the behavior of forwarding stubs to call noSuchMethod is
+// restricted to public members and members from the same library; forwarding
+// stubs for private members from other libraries always throw.
+//
+// Without this, field promotion would not be sound.  For example, in the code
+// below, each attempt to get `_i` from an instance of class `B` would result in
+// an invocation of `B.noSuchMethod`, so evaluation of `a._i` at (1) would yield
+// `0`, and evaluation of `a._i` at (2) would yield `null`.
+//
+//     main.dart:
+//       import 'other.dart';
+//       class B implements A {
+//         bool b = false;
+//         @override
+//         dynamic noSuchMethod(Invocation invocation) => (b = !b) ? 0 : null;
+//       }
+//       main() => foo(new B());
+//     other.dart:
+//       class A {
+//         final int? _i;
+//         A(this._i);
+//       }
+//       void foo(A a) {
+//         if (a._i != null) { // (1)
+//           print(a._i + 1);  // (2)
+//         }
+//       }
+//
+// Whereas with the restriction, any attempt to get `_i` from an instance of
+// class `B` would result in an exception, so the code would never reach (2).
+//
+// Since this behavior involves interactions among libraries, we have to think
+// carefully about how it is affected by language versioning.  There are two
+// issues to consider:
+//
+// 1. Should the forwarding stub throw even if the language feature
+//    "inference-update-2" is disabled in the library containing the class
+//    that's causing the forwarding stub to be generated?  We need to answer
+//    this question with a "yes", otherwise a class declaration in a library
+//    with an older language version could still ruin the soundness of field
+//    promotion in some other library.
+//
+// 2. Should the forwarding stub throw even if the language feature
+//    "inference-update-2" is disabled in the library containing the private
+//    member in question?  Our answer to this question doesn't affect soundness,
+//    because field promotion can't happen in libraries for which the language
+//    feature is disabled.  However, we still answer "yes", because otherwise an
+//    attempt to upgrade to a newer language version in one library might cause
+//    unexpected behavior changes in other libraries that import it, and we
+//    don't want that to happen.
+//
+// This file covers cases where the language feature "inference-update-2" is
+// enabled.
+
+// SharedOptions=--enable-experiment=inference-update-2
+
+import 'package:expect/expect.dart';
+
+import 'no_such_method_restriction_enabled_lib.dart' as lib;
+
+class Interface {
+  static int interfaceCount = 0;
+
+  int _privateField = 100;
+
+  int get _privateGetter {
+    interfaceCount++;
+    return 101;
+  }
+
+  set _privateSetter(int value) {
+    interfaceCount++;
+  }
+
+  int _privateMethod() {
+    interfaceCount++;
+    return 102;
+  }
+
+  int publicField = 103;
+
+  int get publicGetter {
+    interfaceCount++;
+    return 104;
+  }
+
+  set publicSetter(int value) {
+    interfaceCount++;
+  }
+
+  int publicMethod() {
+    interfaceCount++;
+    return 105;
+  }
+
+  static int getPrivateField(Interface x) => x._privateField;
+
+  static void setPrivateField(Interface x) => x._privateField = 106;
+
+  static int callPrivateGetter(Interface x) => x._privateGetter;
+
+  static void callPrivateSetter(Interface x) => x._privateSetter = 107;
+
+  static int callPrivateMethod(Interface x) => x._privateMethod();
+
+  static int getPublicField(Interface x) => x.publicField;
+
+  static void setPublicField(Interface x) => x.publicField = 108;
+
+  static int callPublicGetter(Interface x) => x.publicGetter;
+
+  static void callPublicSetter(Interface x) => x.publicSetter = 109;
+
+  static int callPublicMethod(Interface x) => x.publicMethod();
+}
+
+class Dynamic {
+  static int getPrivateField(dynamic x) => x._privateField;
+
+  static void setPrivateField(dynamic x) => x._privateField = 103;
+
+  static int callPrivateGetter(dynamic x) => x._privateGetter;
+
+  static void callPrivateSetter(dynamic x) => x._privateSetter = 104;
+
+  static int callPrivateMethod(dynamic x) => x._privateMethod();
+
+  static int getPublicField(dynamic x) => x.publicField;
+
+  static void setPublicField(dynamic x) => x.publicField = 108;
+
+  static int callPublicGetter(dynamic x) => x.publicGetter;
+
+  static void callPublicSetter(dynamic x) => x.publicSetter = 109;
+
+  static int callPublicMethod(dynamic x) => x.publicMethod();
+}
+
+/// The tests in this class cover the case where the members are in the same
+/// library as the forwarding stubs.  All member invocations should be
+/// dispatched to noSuchMethod.
+class Local implements Interface {
+  int _localNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return _localNsmCount++;
+  }
+
+  static void testPrivate() {
+    var x = Local();
+    Expect.equals(0, Interface.getPrivateField(x));
+    Expect.equals(1, x._localNsmCount);
+    Interface.setPrivateField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Interface.callPrivateGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Interface.callPrivateSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Interface.callPrivateMethod(x));
+    Expect.equals(5, x._localNsmCount);
+    Expect.equals(0, Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = Local();
+    Expect.equals(0, Interface.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    Interface.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Interface.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Interface.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Interface.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+    Expect.equals(0, Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = Local();
+    Expect.equals(0, Dynamic.getPrivateField(x));
+    Expect.equals(1, x._localNsmCount);
+    Dynamic.setPrivateField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Dynamic.callPrivateGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Dynamic.callPrivateSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Dynamic.callPrivateMethod(x));
+    Expect.equals(5, x._localNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = Local();
+    Expect.equals(0, Dynamic.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    Dynamic.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Dynamic.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Dynamic.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Dynamic.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+  }
+}
+
+/// The tests in this class cover the case where both noSuchMethod and the other
+/// members are in the same library as the forwarding stubs, but that library is
+/// not the same as the library containing this class.  All member invocations
+/// should be dispatched to noSuchMethod.
+class RemoteStubs extends lib.Stubs {
+  static void testPrivate() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Interface.getPrivateField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Interface.setPrivateField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Interface.callPrivateGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Interface.callPrivateSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Interface.callPrivateMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Interface.getPublicField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Interface.setPublicField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Interface.callPublicGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Interface.callPublicSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Interface.callPublicMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Dynamic.getPrivateField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Dynamic.setPrivateField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Dynamic.callPrivateGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Dynamic.callPrivateSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Dynamic.callPrivateMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Dynamic.getPublicField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Dynamic.setPublicField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Dynamic.callPublicGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Dynamic.callPublicSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Dynamic.callPublicMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+  }
+}
+
+/// The tests in this class cover the case where noSuchMember is local, but the
+/// other members are in a different library from the forwarding stubs.  All
+/// public member invocations should be dispatched to noSuchMethod; all private
+/// member invocations should throw.
+class LocalNsm implements lib.Interface {
+  int _localNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return _localNsmCount++;
+  }
+
+  static void testPrivate() {
+    var x = LocalNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Interface.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateMethod(x));
+    Expect.equals(0, x._localNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = LocalNsm();
+    Expect.equals(0, lib.Interface.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    lib.Interface.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, lib.Interface.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    lib.Interface.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, lib.Interface.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = LocalNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateMethod(x));
+    Expect.equals(0, x._localNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = LocalNsm();
+    Expect.equals(0, lib.Dynamic.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    lib.Dynamic.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, lib.Dynamic.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    lib.Dynamic.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, lib.Dynamic.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+  }
+}
+
+/// The tests in this class cover the case where both noSuchMember and the other
+/// members are in a different library from the forwarding stubs.  All public
+/// member invocations should be dispatched to noSuchMethod; all private member
+/// invocations should throw.
+class RemoteNsm extends lib.Nsm implements lib.Interface {
+  static void testPrivate() {
+    var x = RemoteNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Interface.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateMethod(x));
+    Expect.equals(0, x.otherNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = RemoteNsm();
+    Expect.equals(0, lib.Interface.getPublicField(x));
+    Expect.equals(1, x.otherNsmCount);
+    lib.Interface.setPublicField(x);
+    Expect.equals(2, x.otherNsmCount);
+    Expect.equals(2, lib.Interface.callPublicGetter(x));
+    Expect.equals(3, x.otherNsmCount);
+    lib.Interface.callPublicSetter(x);
+    Expect.equals(4, x.otherNsmCount);
+    Expect.equals(4, lib.Interface.callPublicMethod(x));
+    Expect.equals(5, x.otherNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = RemoteNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateMethod(x));
+    Expect.equals(0, x.otherNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = RemoteNsm();
+    Expect.equals(0, lib.Dynamic.getPublicField(x));
+    Expect.equals(1, x.otherNsmCount);
+    lib.Dynamic.setPublicField(x);
+    Expect.equals(2, x.otherNsmCount);
+    Expect.equals(2, lib.Dynamic.callPublicGetter(x));
+    Expect.equals(3, x.otherNsmCount);
+    lib.Dynamic.callPublicSetter(x);
+    Expect.equals(4, x.otherNsmCount);
+    Expect.equals(4, lib.Dynamic.callPublicMethod(x));
+    Expect.equals(5, x.otherNsmCount);
+  }
+}
+
+main() {
+  Local.testPrivate();
+  Local.testPublic();
+  Local.testPrivateDynamic();
+  Local.testPublicDynamic();
+  RemoteStubs.testPrivate();
+  RemoteStubs.testPublic();
+  RemoteStubs.testPrivateDynamic();
+  RemoteStubs.testPublicDynamic();
+  LocalNsm.testPrivate();
+  LocalNsm.testPublic();
+  LocalNsm.testPrivateDynamic();
+  LocalNsm.testPublicDynamic();
+  RemoteNsm.testPrivate();
+  RemoteNsm.testPublic();
+  RemoteNsm.testPrivateDynamic();
+  RemoteNsm.testPublicDynamic();
+}
diff --git a/tests/language/inference_update_2/no_such_method_restriction_stack_trace_lib1.dart b/tests/language/inference_update_2/no_such_method_restriction_stack_trace_lib1.dart
new file mode 100644
index 0000000..a69c6d1
--- /dev/null
+++ b/tests/language/inference_update_2/no_such_method_restriction_stack_trace_lib1.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Library used by 'no_such_method_restriction_stack_trace_test.dart'
+
+import 'no_such_method_restriction_stack_trace_lib2.dart';
+
+class Test extends Nsm implements Interface {}
diff --git a/tests/language/inference_update_2/no_such_method_restriction_stack_trace_lib2.dart b/tests/language/inference_update_2/no_such_method_restriction_stack_trace_lib2.dart
new file mode 100644
index 0000000..7f03ce4
--- /dev/null
+++ b/tests/language/inference_update_2/no_such_method_restriction_stack_trace_lib2.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Library used by 'no_such_method_restriction_stack_trace_test.dart'
+
+import 'no_such_method_restriction_stack_trace_lib2.dart';
+
+class Nsm {
+  @override
+  noSuchMethod(Invocation invocation) {}
+}
+
+class Interface {
+  void _privateMethod() {}
+}
+
+void callPrivateMethod(Interface x) {
+  x._privateMethod();
+}
diff --git a/tests/language/inference_update_2/no_such_method_restriction_stack_trace_test.dart b/tests/language/inference_update_2/no_such_method_restriction_stack_trace_test.dart
new file mode 100644
index 0000000..6642e77
--- /dev/null
+++ b/tests/language/inference_update_2/no_such_method_restriction_stack_trace_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2022, 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.
+
+// Tests that when a noSuchMethod forwarder throws an exception due to the fact
+// that the forwarding stub is for a private member of another library, the
+// resulting stack trace points to the class for which the noSuchMethod
+// forwarder was created.
+
+import 'package:expect/expect.dart';
+
+import 'no_such_method_restriction_stack_trace_lib1.dart';
+import 'no_such_method_restriction_stack_trace_lib2.dart';
+
+main() {
+  try {
+    callPrivateMethod(Test());
+  } on NoSuchMethodError catch (e, st) {
+    var stackString = st.toString();
+    if (stackString.contains('.js:') || !stackString.contains('.dart')) {
+      // Obfuscated stacktrace.  We don't expect to be able to resolve Dart
+      // files from this stack trace, so just let the test pass.
+      //
+      // Note: it's not sufficient to check for the absence of `.dart` in the
+      // stacktrace, because obfuscated Javascript stacktraces often contain
+      // `self.dartMainRunner`.
+    } else {
+      Expect.contains(
+          'no_such_method_restriction_stack_trace_lib1.dart', stackString);
+    }
+  }
+}
diff --git a/tests/language/is/is_never_does_not_promote_error_test.dart b/tests/language/is/is_never_does_not_promote_error_test.dart
new file mode 100644
index 0000000..28ec25b
--- /dev/null
+++ b/tests/language/is/is_never_does_not_promote_error_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2022, 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.
+
+// This tests changes around promotion to `Never` that were made as part of
+// https://dart-review.googlesource.com/c/sdk/+/251280
+// (https://github.com/dart-lang/sdk/issues/49635): a type test of `variable is
+// Never` no longer promotes the type of `variable` to `Never`.
+
+void f(int i) {
+  if (i is Never) {
+    i.isEven;
+    i.abs();
+    i.bogus();
+    //^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
+    // [cfe] The method 'bogus' isn't defined for the class 'int'.
+  }
+}
+
+main() {
+  f(0);
+}
diff --git a/tests/language/metadata/metadata_test.dart b/tests/language/metadata/metadata_test.dart
index e6c088f..bbd87ac 100644
--- a/tests/language/metadata/metadata_test.dart
+++ b/tests/language/metadata/metadata_test.dart
@@ -35,7 +35,7 @@
   static String staticField = "s";
 
   @Meta.Alien("ET")
-  int foo(@meta1 bool fool, {@meta1 @Tag("opt") x: 100}) {
+  int foo(@meta1 bool fool, {@meta1 @Tag("opt") x = 100}) {
     g() => 10;
     return x * g();
   }
diff --git a/tests/language/method/override3_runtime_test.dart b/tests/language/method/override3_runtime_test.dart
index e391830..5e36423 100644
--- a/tests/language/method/override3_runtime_test.dart
+++ b/tests/language/method/override3_runtime_test.dart
@@ -8,10 +8,10 @@
 import 'package:expect/expect.dart';
 
 class A {
-  foo(required1, {named1: 499}) => -(required1 + named1 * 3);
-  bar(required1, required2, {named1: 13, named2: 17}) =>
+  foo(required1, {named1 = 499}) => -(required1 + named1 * 3);
+  bar(required1, required2, {named1 = 13, named2 = 17}) =>
       -(required1 + required2 * 3 + named1 * 5 + named2 * 7);
-  gee({named1: 31}) => -named1;
+  gee({named1 = 31}) => -named1;
 }
 
 class B extends A {
@@ -19,27 +19,27 @@
       required1
 
       ,
-      {named1: 499}
+      {named1 = 499}
 
       ) {
     return required1;
   }
 
   bar(required1, required2,
-      {named1: 13
+      {named1 = 13
 
       ,
-      named2: 17
+      named2 = 17
 
       }) {
     return required1 + required2 * 3 + named1 * 5;
   }
 
   gee(
-      {named2: 11
+      {named2 = 11
 
       ,
-      named1: 31
+      named1 = 31
 
       }) {
     return named2 * 99;
diff --git a/tests/language/method/override3_test.dart b/tests/language/method/override3_test.dart
index b131ff0..be12713 100644
--- a/tests/language/method/override3_test.dart
+++ b/tests/language/method/override3_test.dart
@@ -5,10 +5,10 @@
 import 'package:expect/expect.dart';
 
 class A {
-  foo(required1, {named1: 499}) => -(required1 + named1 * 3);
-  bar(required1, required2, {named1: 13, named2: 17}) =>
+  foo(required1, {named1 = 499}) => -(required1 + named1 * 3);
+  bar(required1, required2, {named1 = 13, named2 = 17}) =>
       -(required1 + required2 * 3 + named1 * 5 + named2 * 7);
-  gee({named1: 31}) => -named1;
+  gee({named1 = 31}) => -named1;
 }
 
 class B extends A {
@@ -29,7 +29,7 @@
 //^^^
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 // [cfe] The method 'B.bar' has fewer named arguments than those of overridden method 'A.bar'.
-      {named1: 13
+      {named1 = 13
       /*
       ,
       named2: 17
@@ -42,7 +42,7 @@
 //^^^
 // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
 // [cfe] The method 'B.gee' doesn't have the named parameter 'named1' of overridden method 'A.gee'.
-      {named2: 11
+      {named2 = 11
       /*
       ,
       named1: 31
diff --git a/tests/language/mixin/super_constructor_named_test.dart b/tests/language/mixin/super_constructor_named_test.dart
index 930877a..b16c815 100644
--- a/tests/language/mixin/super_constructor_named_test.dart
+++ b/tests/language/mixin/super_constructor_named_test.dart
@@ -7,7 +7,7 @@
 class Base {
   int? i, j;
   Base.ctor(int? this.i
-            , {int? this.j: 10} //   //# 01: ok
+            , {int? this.j = 10} //   //# 01: ok
       ) {
     if (j == null) {
       j = 10;
diff --git a/tests/language/nnbd/null_assertions/parameter_checks_fields_and_setters_test.dart b/tests/language/nnbd/null_assertions/parameter_checks_fields_and_setters_test.dart
new file mode 100644
index 0000000..8ce384f
--- /dev/null
+++ b/tests/language/nnbd/null_assertions/parameter_checks_fields_and_setters_test.dart
@@ -0,0 +1,208 @@
+// Copyright (c) 2022, 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 for null assertions for parameters in NNBD weak mode.
+
+// Requirements=nnbd-weak
+// VMOptions=--enable-asserts -DcheckString=false
+// dart2jsOptions=--enable-asserts -DcheckString=false
+// SharedOptions=--null-assertions
+
+// Opt out of Null Safety:
+// @dart = 2.6
+
+import "package:expect/expect.dart";
+
+import 'parameter_checks_opted_in.dart' as null_safe;
+
+bool Function(Object) asserted(String name) {
+  if (const bool.fromEnvironment('checkString', defaultValue: true)) {
+    return (e) => e is AssertionError && e.toString().contains("$name != null");
+  } else {
+    return (e) => e is AssertionError;
+  }
+}
+
+void use(bool x) {
+  if (x != null && x) {
+    print('hey');
+  }
+}
+
+bool topLevelField = false;
+int get topLevelGetterSetterPair => 0;
+set topLevelGetterSetterPair(int i) => null;
+set topLevelSetterOnly(String s) => null;
+
+abstract class Abs {
+  int field;
+  Abs([int init]) {
+    field = init ?? 20;
+  }
+}
+
+class Impl extends Abs {
+  @override
+  final int field;
+
+  Impl([int init])
+      : field = init ?? 10,
+        super();
+}
+
+// NOTE - All class definitions should be identical to the same implementations
+// in the null safe library so the difference in behavior can be observed.
+
+/// Base class.
+class A {
+  int get getterSetterPair => 0;
+  set getterSetterPair(int i) => null;
+  set setterOnly(String s) => null;
+  int field = 0;
+  static bool staticField = false;
+  static int get staticGetterSetterPair => 0;
+  static set staticGetterSetterPair(int i) => null;
+  static set staticSetterOnly(String s) => null;
+
+  void instanceMethod(String s) => print(s);
+  static void staticMethod(String s) => print(s);
+}
+
+/// Overrides the getters but inherits the setters.
+class B extends null_safe.A {
+  @override
+  int get getterSetterPair => 999;
+  @override
+  int get field => 999;
+}
+
+/// Overrides the setters.
+class C extends null_safe.A {
+  @override
+  set getterSetterPair(int i) => null;
+  @override
+  set setterOnly(String s) => null;
+  @override
+  set field(int i) => null;
+}
+
+/// Overrides field with a field.
+class D extends null_safe.A {
+  @override
+  int field = 10;
+}
+
+main() {
+  // Top level definitions in opted out library allow null without errors.
+  topLevelField = null;
+  use(topLevelField); // Make sure topLevelField is not tree-shaken.
+  topLevelGetterSetterPair = null;
+  topLevelSetterOnly = null;
+
+  // Same definitions in a null safe library throw when set to null.
+  Expect.throws(() {
+    null_safe.topLevelField = null;
+  }, asserted('topLevelField'));
+  use(null_safe.topLevelField); // Make sure topLevelField is not tree-shaken.
+  Expect.throws(() {
+    null_safe.topLevelGetterSetterPair = null;
+  }, asserted('i'));
+  Expect.throws(() {
+    null_safe.topLevelSetterOnly = null;
+  }, asserted('s'));
+
+  // Class defined in opted out library allows null.
+  var a = A();
+  a.getterSetterPair = null;
+  a.setterOnly = null;
+  a.field = null;
+  A.staticGetterSetterPair = null;
+  A.staticSetterOnly = null;
+  A.staticField = null;
+  use(A.staticField); // Make sure A.staticField is not tree-shaken.
+
+  // Same class as above defined in a null safe library, throws on null.
+  var nullSafeA = null_safe.A();
+  Expect.throws(() {
+    nullSafeA.getterSetterPair = null;
+  }, asserted('i'));
+  Expect.throws(() {
+    nullSafeA.setterOnly = null;
+  }, asserted('s'));
+  Expect.throws(() {
+    nullSafeA.field = null;
+  }, asserted('field'));
+  Expect.throws(() {
+    null_safe.A.staticGetterSetterPair = null;
+  }, asserted('i'));
+  Expect.throws(() {
+    null_safe.A.staticSetterOnly = null;
+  }, asserted('s'));
+  Expect.throws(() {
+    null_safe.A.staticField = null;
+  }, asserted('staticField'));
+  use(null_safe.A.staticField); // Make sure A.staticField is not tree-shaken.
+
+  // Class defined in opted out library overrides getters but inherited
+  // implementations throw.
+  var b = B();
+  Expect.throws(() {
+    b.getterSetterPair = null;
+  }, asserted('i'));
+  Expect.throws(() {
+    b.setterOnly = null;
+  }, asserted('s'));
+  Expect.throws(() {
+    b.field = null;
+  }, asserted('field'));
+
+  // Same class as above defined in and inherited from null safe library throw.
+  var nullSafeB = null_safe.B();
+  Expect.throws(() {
+    nullSafeB.getterSetterPair = null;
+  }, asserted('i'));
+  Expect.throws(() {
+    nullSafeB.setterOnly = null;
+  }, asserted('s'));
+  Expect.throws(() {
+    nullSafeB.field = null;
+  }, asserted('field'));
+
+  // Class defined in opted out library, overrides all setters, doesn't throw.
+  var c = C();
+  c.getterSetterPair = null;
+  c.setterOnly = null;
+  c.field = null;
+
+  // Same class as above defined in null safe library throws.
+  var nullSafeC = null_safe.C();
+  Expect.throws(() {
+    nullSafeC.getterSetterPair = null;
+  }, asserted('i'));
+  Expect.throws(() {
+    nullSafeC.setterOnly = null;
+  }, asserted('s'));
+  Expect.throws(() {
+    nullSafeC.field = null;
+  }, asserted('i'));
+
+  // Class defined in opted out library overrides field, doesn't throw.
+  var d = D();
+  d.field = null;
+
+  // Same class as above defined in null safe library throws.
+  var nullSafeD = null_safe.D();
+  Expect.throws(() {
+    nullSafeD.field = null;
+  }, asserted('field'));
+
+  var s = Impl();
+  // Should not throw because the setter is defined in a library that has not
+  // yet migrated to null safety.
+  //
+  // The Impl class has no setter, but the field has a setterType of `Never`
+  // which is non-nullable. This acts as a regression test to ensure we don't
+  // introduce a null check because of the strange setter type.
+  s.field = null;
+}
diff --git a/tests/language/nnbd/null_assertions/parameter_checks_opted_in.dart b/tests/language/nnbd/null_assertions/parameter_checks_opted_in.dart
index a4f959f..691e7eb 100644
--- a/tests/language/nnbd/null_assertions/parameter_checks_opted_in.dart
+++ b/tests/language/nnbd/null_assertions/parameter_checks_opted_in.dart
@@ -6,6 +6,11 @@
 
 import 'dart:async' show FutureOr;
 
+bool topLevelField = false;
+int get topLevelGetterSetterPair => 0;
+set topLevelGetterSetterPair(int i) => null;
+set topLevelSetterOnly(String s) => null;
+
 foo1(int a) {}
 foo2(int a, [int b = 1, String c = '']) {}
 foo3({int a = 0, required int b}) {}
@@ -17,3 +22,42 @@
 foo6b<T extends FutureOr<S>, S extends U, U extends int>(T a) {}
 
 void Function(int) bar() => (int x) {};
+
+/// Base class.
+class A {
+  int get getterSetterPair => 0;
+  set getterSetterPair(int i) => null;
+  set setterOnly(String s) => null;
+  int field = 0;
+  static bool staticField = false;
+  static int get staticGetterSetterPair => 0;
+  static set staticGetterSetterPair(int i) => null;
+  static set staticSetterOnly(String s) => null;
+
+  void instanceMethod(String s) => print(s);
+  static void staticMethod(String s) => print(s);
+}
+
+/// Overrides the getters but inherits the setters.
+class B extends A {
+  @override
+  int get getterSetterPair => 999;
+  @override
+  int get field => 999;
+}
+
+/// Overrides the setters.
+class C extends A {
+  @override
+  set getterSetterPair(int i) => null;
+  @override
+  set setterOnly(String s) => null;
+  @override
+  set field(int i) => null;
+}
+
+/// Overrides field with a field
+class D extends A {
+  @override
+  int field = 10;
+}
diff --git a/tests/language/nnbd/static_errors/default_value_on_required_parameter_test.dart b/tests/language/nnbd/static_errors/default_value_on_required_parameter_test.dart
index f5a4532..29ab688 100644
--- a/tests/language/nnbd/static_errors/default_value_on_required_parameter_test.dart
+++ b/tests/language/nnbd/static_errors/default_value_on_required_parameter_test.dart
@@ -6,7 +6,7 @@
 // Test that it is an error if a required named parameter has a default value.
 main() {}
 
-void log1({String message: 'no message'}) {}
+void log1({String message = 'no message'}) {}
 void log2({String? message}) {}
-void log3({required String? message: 'no message'}) {} //# 01: compile-time error
+void log3({required String? message = 'no message'}) {} //# 01: compile-time error
 void log4({required String message}) {}
diff --git a/tests/language/no_such_method/no_such_method_test.dart b/tests/language/no_such_method/no_such_method_test.dart
index f38285a..0a82bad 100644
--- a/tests/language/no_such_method/no_such_method_test.dart
+++ b/tests/language/no_such_method/no_such_method_test.dart
@@ -6,7 +6,7 @@
 import "package:expect/expect.dart";
 
 class NoSuchMethodTest {
-  foo({a: 10, b: 20}) {
+  foo({a = 10, b = 20}) {
     return (10 * a) + b;
   }
 
diff --git a/tests/language/nonfunction_type_aliases/private_names/private_name_implementation_test.dart b/tests/language/nonfunction_type_aliases/private_names/private_name_implementation_test.dart
index e7a8490..41040db 100644
--- a/tests/language/nonfunction_type_aliases/private_names/private_name_implementation_test.dart
+++ b/tests/language/nonfunction_type_aliases/private_names/private_name_implementation_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.
 
-
 // Test that private names exported via public typedefs allow implementation
 
 import "package:expect/expect.dart";
diff --git a/tests/language/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart b/tests/language/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
index ab8a449..adfbf0c 100644
--- a/tests/language/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
+++ b/tests/language/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
@@ -66,8 +66,8 @@
 
   void test0(int x, int y);
   void test1({String? x});
-  void test2({String x: "w/e"});
-  void test3({String x: "w/e"});
+  void test2({String x = "w/e"});
+  void test3({String x = "w/e"});
   void test4([String? x]);
   void test5<T extends num>(T x);
   String test6();
@@ -78,7 +78,7 @@
   void test8([String? x]);
   void test9<T, S extends T>(S x1, {T? foo});
 
-  T allTogetherNow<T, S extends T>(S x1, {List<T> foo: const <Never>[]});
+  T allTogetherNow<T, S extends T>(S x1, {List<T> foo = const <Never>[]});
 }
 
 main() {
diff --git a/tests/language/parameter/bad_named_parameters_test.dart b/tests/language/parameter/bad_named_parameters_test.dart
index 9db032b..79c40c1 100644
--- a/tests/language/parameter/bad_named_parameters_test.dart
+++ b/tests/language/parameter/bad_named_parameters_test.dart
@@ -6,11 +6,11 @@
 import "package:expect/expect.dart";
 
 class BadNamedParametersTest {
-  int f42(int a, {int b: 20, int c: 30}) {
+  int f42(int a, {int b = 20, int c = 30}) {
     return 100 * (100 * a + b) + c;
   }
 
-  int f52(int a, {int b: 20, int? c, int d: 40}) {
+  int f52(int a, {int b = 20, int? c, int d = 40}) {
     return 100 * (100 * (100 * a + b) + (c == null ? 0 : c)) + d;
   }
 }
diff --git a/tests/language/parameter/bad_named_runtime_test.dart b/tests/language/parameter/bad_named_runtime_test.dart
index 8d4a861..8caf3c8 100644
--- a/tests/language/parameter/bad_named_runtime_test.dart
+++ b/tests/language/parameter/bad_named_runtime_test.dart
@@ -9,11 +9,11 @@
 import "package:expect/expect.dart";
 
 class BadNamedParametersTest {
-  int f42(int a, {int b: 20, int c: 30}) {
+  int f42(int a, {int b = 20, int c = 30}) {
     return 100 * (100 * a + b) + c;
   }
 
-  int f52(int a, {int b: 20, int? c, int d: 40}) {
+  int f52(int a, {int b = 20, int? c, int d = 40}) {
     return 100 * (100 * (100 * a + b) + (c == null ? 0 : c)) + d;
   }
 }
diff --git a/tests/language/parameter/default_test.dart b/tests/language/parameter/default_test.dart
index 3e5b990..10a40a0 100644
--- a/tests/language/parameter/default_test.dart
+++ b/tests/language/parameter/default_test.dart
@@ -4,14 +4,12 @@
 
 class C {
   foo(a
-      : 1 // //# 01: syntax error
       = 1 // //# 02: syntax error
       ) {
     print(a);
   }
 
   static bar(a
-      : 1 // //# 03: syntax error
       = 1 // //# 04: syntax error
       ) {
     print(a);
@@ -19,7 +17,6 @@
 }
 
 baz(a
-    : 1 // //# 05: syntax error
     = 1 // //# 06: syntax error
     ) {
   print(a);
@@ -27,7 +24,6 @@
 
 main() {
   foo(a
-      : 1 // //# 07: syntax error
       = 1 // //# 08: syntax error
       ) {
     print(a);
diff --git a/tests/language/parameter/initializer2_test.dart b/tests/language/parameter/initializer2_test.dart
index da775e2..aed1c3b 100644
--- a/tests/language/parameter/initializer2_test.dart
+++ b/tests/language/parameter/initializer2_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 
-// Test Parameter Intializer.
+// Test Parameter Initializer.
 
 class ParameterInitializer2Test {
   static testMain() {
diff --git a/tests/language/parameter/initializer6_test.dart b/tests/language/parameter/initializer6_test.dart
index 117a0c3..b711a86 100644
--- a/tests/language/parameter/initializer6_test.dart
+++ b/tests/language/parameter/initializer6_test.dart
@@ -8,7 +8,7 @@
 
 class Foo {
   num _y;
-  Foo.private({this._y: 77}) {}
+  Foo.private({this._y = 77}) {}
   //                ^^
   // [analyzer] COMPILE_TIME_ERROR.PRIVATE_OPTIONAL_PARAMETER
   //                ^
diff --git a/tests/language/parameter/named_aggregated_runtime_test.dart b/tests/language/parameter/named_aggregated_runtime_test.dart
index 20e3ebe..81ee702 100644
--- a/tests/language/parameter/named_aggregated_runtime_test.dart
+++ b/tests/language/parameter/named_aggregated_runtime_test.dart
@@ -15,7 +15,7 @@
 ]);
 
 class NamedParametersAggregatedTests {
-  static int F31(int a, {int b: 20, int c: 30}) {
+  static int F31(int a, {int b = 20, int c = 30}) {
     return 100 * (100 * a + b) + c;
   }
 
diff --git a/tests/language/parameter/named_aggregated_test.dart b/tests/language/parameter/named_aggregated_test.dart
index 252f67d..1ed33f2 100644
--- a/tests/language/parameter/named_aggregated_test.dart
+++ b/tests/language/parameter/named_aggregated_test.dart
@@ -13,7 +13,7 @@
 // [cfe] Can't have a default value in a function type.
 
 class NamedParametersAggregatedTests {
-  static int F31(int a, {int b: 20, int c: 30}) {
+  static int F31(int a, {int b = 20, int c = 30}) {
     return 100 * (100 * a + b) + c;
   }
 
@@ -26,7 +26,7 @@
 
   // Expect compile-time error as no default values
   // are allowed in closure type.
-  void InstallCallback(void cb({String? msg : null})?) {
+  void InstallCallback(void cb({String? msg = null})?) {
   //                                        ^
   // [analyzer] SYNTACTIC_ERROR.DEFAULT_VALUE_IN_FUNCTION_TYPE
   // [cfe] Can't have a default value in a function type.
diff --git a/tests/language/parameter/named_default_eq_runtime_test.dart b/tests/language/parameter/named_default_eq_runtime_test.dart
index dd1bb4d..746807c 100644
--- a/tests/language/parameter/named_default_eq_runtime_test.dart
+++ b/tests/language/parameter/named_default_eq_runtime_test.dart
@@ -14,15 +14,15 @@
 
 typedef functype({x, y, z});
 
-int topF({x = 3, y: 5, z}) => x * y * (z ?? 2);
+int topF({x = 3, y = 5, z}) => x * y * (z ?? 2);
 
 class A {
   int x;
   int y;
   int z;
-  A({this.x = 3, this.y: 5, z}) : z = z ?? 2;
-  A.redirect({int x = 3, int y: 5, int? z}) : this(x: x, y: y, z: z);
-  factory A.factory({int x = 3, int y: 5, int? z}) =>
+  A({this.x = 3, this.y = 5, z}) : z = z ?? 2;
+  A.redirect({int x = 3, int y = 5, int? z}) : this(x: x, y: y, z: z);
+  factory A.factory({int x = 3, int y = 5, int? z}) =>
       new A(x: x, y: y, z: z ?? 2);
   factory A.redirectFactory({int x, int y, int z}) = A;
 
@@ -32,8 +32,8 @@
 
   int get value => x * y * z;
 
-  static int staticF({x = 3, y: 5, z}) => x * y * (z ?? 2);
-  int instanceF({x = 3, y: 5, z}) => x * y * (z ?? 2);
+  static int staticF({x = 3, y = 5, z}) => x * y * (z ?? 2);
+  int instanceF({x = 3, y = 5, z}) => x * y * (z ?? 2);
 }
 
 main() {
@@ -42,8 +42,8 @@
 
   var a = new A();
 
-  int local({x = 3, y: 5, z}) => x * y * (z ?? 2);
-  var expr = ({x = 3, y: 5, z}) => x * y * (z ?? 2);
+  int local({x = 3, y = 5, z}) => x * y * (z ?? 2);
+  var expr = ({x = 3, y = 5, z}) => x * y * (z ?? 2);
   var tearOff = a.instanceF;
 
   test(function) {
diff --git a/tests/language/parameter/named_default_eq_test.dart b/tests/language/parameter/named_default_eq_test.dart
index 89ea2bb..3711a28 100644
--- a/tests/language/parameter/named_default_eq_test.dart
+++ b/tests/language/parameter/named_default_eq_test.dart
@@ -14,15 +14,15 @@
 
 typedef functype({x, y, z});
 
-int topF({x = 3, y: 5, z}) => x * y * (z ?? 2);
+int topF({x = 3, y = 5, z}) => x * y * (z ?? 2);
 
 class A {
   int x;
   int y;
   int z;
-  A({this.x = 3, this.y: 5, z}) : z = z ?? 2;
-  A.redirect({int x = 3, int y: 5, int? z}) : this(x: x, y: y, z: z);
-  factory A.factory({int x = 3, int y: 5, int? z}) =>
+  A({this.x = 3, this.y = 5, z}) : z = z ?? 2;
+  A.redirect({int x = 3, int y = 5, int? z}) : this(x: x, y: y, z: z);
+  factory A.factory({int x = 3, int y = 5, int? z}) =>
       new A(x: x, y: y, z: z ?? 2);
   factory A.redirectFactory({int x, int y, int z}) = A;
 
@@ -36,8 +36,8 @@
 
   int get value => x * y * z;
 
-  static int staticF({x = 3, y: 5, z}) => x * y * (z ?? 2);
-  int instanceF({x = 3, y: 5, z}) => x * y * (z ?? 2);
+  static int staticF({x = 3, y = 5, z}) => x * y * (z ?? 2);
+  int instanceF({x = 3, y = 5, z}) => x * y * (z ?? 2);
 }
 
 main() {
@@ -46,8 +46,8 @@
 
   var a = new A();
 
-  int local({x = 3, y: 5, z}) => x * y * (z ?? 2);
-  var expr = ({x = 3, y: 5, z}) => x * y * (z ?? 2);
+  int local({x = 3, y = 5, z}) => x * y * (z ?? 2);
+  var expr = ({x = 3, y = 5, z}) => x * y * (z ?? 2);
   var tearOff = a.instanceF;
 
   test(function) {
diff --git a/tests/language/parameter/named_passing_falsy_test.dart b/tests/language/parameter/named_passing_falsy_test.dart
index e17b75a..2e252af 100644
--- a/tests/language/parameter/named_passing_falsy_test.dart
+++ b/tests/language/parameter/named_passing_falsy_test.dart
@@ -11,14 +11,14 @@
   TestClass();
 
   method([value = 100]) => value;
-  method2({value: 100}) => value;
+  method2({value = 100}) => value;
 
   static staticMethod([value = 200]) => value;
-  static staticMethod2({value: 200}) => value;
+  static staticMethod2({value = 200}) => value;
 }
 
 globalMethod([value = 300]) => value;
-globalMethod2({value: 300}) => value;
+globalMethod2({value = 300}) => value;
 
 const testValues = const [0, 0.0, '', false, null];
 
diff --git a/tests/language/parameter/named_passing_null_test.dart b/tests/language/parameter/named_passing_null_test.dart
index a1a1fbb..1331261 100644
--- a/tests/language/parameter/named_passing_null_test.dart
+++ b/tests/language/parameter/named_passing_null_test.dart
@@ -11,14 +11,14 @@
   TestClass();
 
   num? method([value = 100]) => value;
-  num? method2({value: 100}) => value;
+  num? method2({value = 100}) => value;
 
   static num? staticMethod([value = 200]) => value;
-  static num? staticMethod2({value: 200}) => value;
+  static num? staticMethod2({value = 200}) => value;
 }
 
 num? globalMethod([value = 300]) => value;
-num? globalMethod2({value: 300}) => value;
+num? globalMethod2({value = 300}) => value;
 
 main() {
   var obj = new TestClass();
diff --git a/tests/language/parameter/named_passing_zero_test.dart b/tests/language/parameter/named_passing_zero_test.dart
index 02afcfe..a3e1d9d 100644
--- a/tests/language/parameter/named_passing_zero_test.dart
+++ b/tests/language/parameter/named_passing_zero_test.dart
@@ -11,14 +11,14 @@
   TestClass();
 
   num method([num value = 100]) => value;
-  num method2({num value: 100}) => value;
+  num method2({num value = 100}) => value;
 
   static num staticMethod([num value = 200]) => value;
-  static num staticMethod2({num value: 200}) => value;
+  static num staticMethod2({num value = 200}) => value;
 }
 
 num globalMethod([num value = 300]) => value;
-num globalMethod2({num value: 300}) => value;
+num globalMethod2({num value = 300}) => value;
 
 main() {
   var obj = new TestClass();
diff --git a/tests/language/parameter/named_regression_test.dart b/tests/language/parameter/named_regression_test.dart
index a702464..72c1055 100644
--- a/tests/language/parameter/named_regression_test.dart
+++ b/tests/language/parameter/named_regression_test.dart
@@ -5,12 +5,12 @@
 // A regression test for dart2js bug 6015.
 
 class Fisk {
-  foo({b, a: true}) {
+  foo({b, a = true}) {
     if (b == null) return;
     throw 'broken';
   }
 
-  bar({a, b: true}) {
+  bar({a, b = true}) {
     if (a == null) return;
     throw 'broken';
   }
diff --git a/tests/language/parameter/named_type_runtime_test.dart b/tests/language/parameter/named_type_runtime_test.dart
index a3a8ff1..0d0476f 100644
--- a/tests/language/parameter/named_type_runtime_test.dart
+++ b/tests/language/parameter/named_type_runtime_test.dart
@@ -15,9 +15,9 @@
   ;
   void funNumBool(num n, bool b) {}
   ;
-  void funNumOptBool(num n, {bool b: true}) {}
+  void funNumOptBool(num n, {bool b = true}) {}
   ;
-  void funNumOptBoolX(num n, {bool x: true}) {}
+  void funNumOptBoolX(num n, {bool x = true}) {}
   ;
   anyFunction = funNum;
   anyFunction = funNumBool;
diff --git a/tests/language/parameter/named_type_test.dart b/tests/language/parameter/named_type_test.dart
index 8ae1f6c..539837c 100644
--- a/tests/language/parameter/named_type_test.dart
+++ b/tests/language/parameter/named_type_test.dart
@@ -12,9 +12,9 @@
   ;
   void funNumBool(num n, bool b) {}
   ;
-  void funNumOptBool(num n, {bool b: true}) {}
+  void funNumOptBool(num n, {bool b = true}) {}
   ;
-  void funNumOptBoolX(num n, {bool x: true}) {}
+  void funNumOptBoolX(num n, {bool x = true}) {}
   ;
   anyFunction = funNum;
   anyFunction = funNumBool;
diff --git a/tests/language/parameter/named_with_conversions_test.dart b/tests/language/parameter/named_with_conversions_test.dart
index 8818036..0dffa3d 100644
--- a/tests/language/parameter/named_with_conversions_test.dart
+++ b/tests/language/parameter/named_with_conversions_test.dart
@@ -38,7 +38,7 @@
     Validate(tag, a, b);
   }
 
-  foo2(tag, {a: 10, b: 20}) {
+  foo2(tag, {a = 10, b = 20}) {
     calls += 1;
     Validate(tag, a, b);
   }
@@ -63,7 +63,7 @@
 
   makeFoo2(owner) {
     // This function is closed-over 'owner'.
-    return (tag, {a: 10, b: 20}) {
+    return (tag, {a = 10, b = 20}) {
       owner.calls += 1;
       Validate(tag, a, b);
     };
diff --git a/tests/language/parameter/optional_named_runtime_test.dart b/tests/language/parameter/optional_named_runtime_test.dart
index 3b863b9..a04ceca 100644
--- a/tests/language/parameter/optional_named_runtime_test.dart
+++ b/tests/language/parameter/optional_named_runtime_test.dart
@@ -25,35 +25,35 @@
     return a;
   }
 
-  static int F10({int b: 20}) {
+  static int F10({int b = 20}) {
     return b;
   }
 
-  int f21({int b: 20}) {
+  int f21({int b = 20}) {
     return b;
   }
 
-  static int F21(int a, {int b: 20}) {
+  static int F21(int a, {int b = 20}) {
     return 100 * a + b;
   }
 
-  int f32(int a, {int b: 20}) {
+  int f32(int a, {int b = 20}) {
     return 100 * a + b;
   }
 
-  static int F31(int a, {int b: 20, int c: 30}) {
+  static int F31(int a, {int b = 20, int c = 30}) {
     return 100 * (100 * a + b) + c;
   }
 
-  int f42(int a, {int b: 20, int c: 30}) {
+  int f42(int a, {int b = 20, int c = 30}) {
     return 100 * (100 * a + b) + c;
   }
 
-  static int F41(int a, {int b: 20, int? c, int d: 40}) {
+  static int F41(int a, {int b = 20, int? c, int d = 40}) {
     return 100 * (100 * (100 * a + b) + ((c != null) ? c : 0)) + d;
   }
 
-  int f52(int a, {int b: 20, int? c, int d: 40}) {
+  int f52(int a, {int b = 20, int? c, int d = 40}) {
     return 100 * (100 * (100 * a + b) + ((c != null) ? c : 0)) + d;
   }
 
diff --git a/tests/language/parameter/optional_named_test.dart b/tests/language/parameter/optional_named_test.dart
index 56f2adf..839228f 100644
--- a/tests/language/parameter/optional_named_test.dart
+++ b/tests/language/parameter/optional_named_test.dart
@@ -22,35 +22,35 @@
     return a;
   }
 
-  static int F10({int b: 20}) {
+  static int F10({int b = 20}) {
     return b;
   }
 
-  int f21({int b: 20}) {
+  int f21({int b = 20}) {
     return b;
   }
 
-  static int F21(int a, {int b: 20}) {
+  static int F21(int a, {int b = 20}) {
     return 100 * a + b;
   }
 
-  int f32(int a, {int b: 20}) {
+  int f32(int a, {int b = 20}) {
     return 100 * a + b;
   }
 
-  static int F31(int a, {int b: 20, int c: 30}) {
+  static int F31(int a, {int b = 20, int c = 30}) {
     return 100 * (100 * a + b) + c;
   }
 
-  int f42(int a, {int b: 20, int c: 30}) {
+  int f42(int a, {int b = 20, int c = 30}) {
     return 100 * (100 * a + b) + c;
   }
 
-  static int F41(int a, {int b: 20, int? c, int d: 40}) {
+  static int F41(int a, {int b = 20, int? c, int d = 40}) {
     return 100 * (100 * (100 * a + b) + ((c != null) ? c : 0)) + d;
   }
 
-  int f52(int a, {int b: 20, int? c, int d: 40}) {
+  int f52(int a, {int b = 20, int? c, int d = 40}) {
     return 100 * (100 * (100 * a + b) + ((c != null) ? c : 0)) + d;
   }
 
diff --git a/tests/language/record_literal_problems_test.dart b/tests/language/record_literal_problems_test.dart
new file mode 100644
index 0000000..ab279df
--- /dev/null
+++ b/tests/language/record_literal_problems_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, 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.
+
+// SharedOptions=--enable-experiment=records
+
+main() {
+  var r1 = const (42);
+  //                ^
+  // [analyzer] SYNTACTIC_ERROR.RECORD_LITERAL_ONE_POSITIONAL_NO_TRAILING_COMMA
+  // [cfe] Record literal with one field requires a trailing comma.
+
+  var r2 = const ();
+  //              ^
+  // [analyzer] SYNTACTIC_ERROR.RECORD_LITERAL_EMPTY
+  // [cfe] Record literal can't be empty.
+}
diff --git a/tests/language/record_literal_test.dart b/tests/language/record_literal_test.dart
index 15e8f39..f6ac1bf 100644
--- a/tests/language/record_literal_test.dart
+++ b/tests/language/record_literal_test.dart
@@ -21,4 +21,14 @@
   // With function inside.
   var record5 = ((foo, bar) => 42, 42);
   print(record5);
+
+  // 1 record entry with trailing comma.
+  var record6 = (42, );
+  print(record6);
+
+  // Const records.
+  var record7 = const (42, );
+  print(record7);
+  var record8 = const (42, foo: "bar");
+  print(record8);
 }
diff --git a/tests/language/record_type_empty_problems_test.dart b/tests/language/record_type_empty_problems_test.dart
new file mode 100644
index 0000000..a847433
--- /dev/null
+++ b/tests/language/record_type_empty_problems_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, 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.
+
+// SharedOptions=--enable-experiment=records
+
+main() {
+  (int, int, {/*missing*/}) r1 = (1, 2);
+  //                     ^
+  // [analyzer] SYNTACTIC_ERROR.EMPTY_RECORD_TYPE_NAMED_FIELDS_LIST
+  // [cfe] Record type named fields list can't be empty.
+
+  (int /* missing trailing comma */ ) r2 = (1, );
+  //                                ^
+  // [analyzer] SYNTACTIC_ERROR.RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA
+  // [cfe] Record type with one entry requires a trailing comma.
+}
diff --git a/tests/language/record_type_problems_test.dart b/tests/language/record_type_problems_test.dart
new file mode 100644
index 0000000..a847433
--- /dev/null
+++ b/tests/language/record_type_problems_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, 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.
+
+// SharedOptions=--enable-experiment=records
+
+main() {
+  (int, int, {/*missing*/}) r1 = (1, 2);
+  //                     ^
+  // [analyzer] SYNTACTIC_ERROR.EMPTY_RECORD_TYPE_NAMED_FIELDS_LIST
+  // [cfe] Record type named fields list can't be empty.
+
+  (int /* missing trailing comma */ ) r2 = (1, );
+  //                                ^
+  // [analyzer] SYNTACTIC_ERROR.RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA
+  // [cfe] Record type with one entry requires a trailing comma.
+}
diff --git a/tests/language/record_type_test.dart b/tests/language/record_type_test.dart
index 1be89ab..cd2ff2f 100644
--- a/tests/language/record_type_test.dart
+++ b/tests/language/record_type_test.dart
@@ -7,6 +7,7 @@
 main() {
   (int, int) record1 = (1, 2);
   print(record1);
+
   (int x, int y) record1Named = (1, 2);
   print(record1Named);
 
@@ -39,6 +40,12 @@
   List<(int, int)> listOfRecords = [];
 
   var listOfRecords2 = <(int, int)>[];
+
+  (int, ) oneElementRecord = (1, );
+  print(oneElementRecord);
+
+  ({int ok}) oneElementNamedRecord = (ok: 1);
+  print(oneElementNamedRecord);
 }
 
 (int, T) f1<T>(T t) {
diff --git a/tests/language/records/simple/constants_and_field_access_test.dart b/tests/language/records/simple/constants_and_field_access_test.dart
new file mode 100644
index 0000000..234039d
--- /dev/null
+++ b/tests/language/records/simple/constants_and_field_access_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2022, 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.
+
+// SharedOptions=--enable-experiment=records
+// VMOptions=
+// VMOptions=--test_il_serialization
+
+import "package:expect/expect.dart";
+
+void checkRecordP2(Object? e1, Object? e2, (Object?, Object?) r) {
+  Expect.equals(e1, r.$0);
+  Expect.equals(e2, r.$1);
+}
+
+void checkRecordP3(Object? e1, Object? e2, Object? e3, (Object? e1, Object? e2, Object? e3) r) {
+  Expect.equals(e1, r.$0);
+  Expect.equals(e2, r.$1);
+  Expect.equals(e3, r.$2);
+}
+
+void checkRecordN1(Object? foo, ({Object? foo}) r) {
+  Expect.equals(foo, r.foo);
+}
+
+void checkRecordN2(Object? foo, Object? bar, ({Object? foo, Object? bar}) r) {
+  Expect.equals(foo, r.foo);
+  Expect.equals(bar, r.bar);
+}
+
+void checkRecordN3(Object? foo, Object? bar, Object? baz, ({Object? foo, Object? bar, Object? baz}) r) {
+  Expect.equals(foo, r.foo);
+  Expect.equals(bar, r.bar);
+  Expect.equals(baz, r.baz);
+}
+
+void checkRecordP1N1(Object? e1, Object? foo, (Object?, {Object? foo}) r) {
+  Expect.equals(e1, r.$0);
+  Expect.equals(foo, r.foo);
+}
+
+void checkRecordP1N2(Object? e1, Object? foo, Object? bar, (Object? e1, {Object? foo, Object? bar, }) r) {
+  Expect.equals(e1, r.$0);
+  Expect.equals(foo, r.foo);
+  Expect.equals(bar, r.bar);
+}
+
+void checkRecordP3N3(Object? e1, Object? e2, Object? e3, Object? foo, Object? bar, Object? baz, (Object?, Object?, Object?, {Object? foo, Object? baz, Object? bar}) r) {
+  Expect.equals(bar, r.bar);
+  Expect.equals(foo, r.foo);
+  Expect.equals(baz, r.baz);
+  Expect.equals(e1, r.$0);
+  Expect.equals(e2, r.$1);
+  Expect.equals(e3, r.$2);
+}
+
+(Object?, {Object? foo}) getP1N1() => getP1N1Rec(42);
+
+(Object?, {Object? foo}) getP1N1Rec(int n) {
+  if (n == 0) return const (10, foo: "abc");
+  return getP1N1Rec(n - 1);
+}
+
+class A {
+  final int v;
+  const A(this.v);
+  operator==(Object other) => other is A && v == other.v;
+}
+
+const int two = 2;
+
+main() {
+  checkRecordP2(10, 20, const (10, 20));
+  checkRecordP3(3, 2, 1, const (3, two, 1));
+  checkRecordN1("FOO", const (foo: "FOO"));
+  checkRecordN1(const [1, 2, 3], const (foo: [1, 2, 3]));
+
+  checkRecordN2(const {1, 2, 3}, const A(20), const (foo: const {1, 2, 3}, bar: A(20)));
+
+  checkRecordN3(A(10), 1.0, 42, const (foo: A(10), bar: 1.0, baz: 40 + 2));
+
+  checkRecordP1N1(10, "abc", getP1N1());
+
+  checkRecordP1N2(A(1), A(2), A(3), const (foo: A(2), A(1), bar: A(3)));
+
+  checkRecordP3N3(1, 2.0, 'hey', A(10), const A(20), const ['hi'], const (2 - 1, 2.0, 'h' + 'ey', foo: A(3 + 7), baz: ['hi'], bar: A(10*2), ));
+}
diff --git a/tests/language/records/simple/equals_and_hashcode_test.dart b/tests/language/records/simple/equals_and_hashcode_test.dart
new file mode 100644
index 0000000..2f6036b
--- /dev/null
+++ b/tests/language/records/simple/equals_and_hashcode_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code as governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=records
+
+import "package:expect/expect.dart";
+
+
+class NotEqual {
+  bool operator==(Object other) => false;
+}
+
+class A {
+  final int i;
+  const A(this.i);
+
+  bool operator==(Object other) => other is A && i == other.i;
+  int get hashCode => i;
+}
+
+class B {
+  final int i;
+  bool equalsCalled = false;
+  bool hashCodeCalled = false;
+
+  B(this.i);
+
+  bool operator==(Object other) {
+    equalsCalled = true;
+    return other is B && i == other.i;
+  }
+
+  int get hashCode {
+    hashCodeCalled = true;
+    return i ^ 42;
+  }
+}
+
+checkEqualsAndHash(Object? a, Object? b) {
+  Expect.isTrue(a == b);
+  Expect.equals(a.hashCode, b.hashCode);
+}
+
+checkNotEquals(Object? a, Object? b) {
+  Expect.isFalse(a == b);
+}
+
+main() {
+  checkEqualsAndHash((1, 2), (1, 2));
+  checkEqualsAndHash((1, 2), const (1, 2));
+  checkEqualsAndHash(const (42, foo: "hello3"), (foo: "hello${int.parse("3")}", 40 + int.parse("2")));
+  checkEqualsAndHash((1, 2, 3, foo: 4, bar: 5, baz: 6), (baz: 6, 1, bar: 5, 2, foo: 4, int.parse("3")));
+  checkEqualsAndHash((foo: 1, 2), (2, foo: 1));
+  checkEqualsAndHash((foo: 3), (foo: 3));
+
+  checkNotEquals((1, 2), (1, 3));
+  checkNotEquals((1, 2), (3, 2));
+  checkNotEquals((1, 2), (2, 1));
+  checkNotEquals((1, foo: 2), (foo: 1, 2));
+  checkNotEquals((1, foo: 2), (1, bar: 2));
+
+  checkEqualsAndHash((A(1), A(2)), (A(1), A(2)));
+  checkEqualsAndHash((A(1), A(2)), (A(1), const A(2)));
+  checkEqualsAndHash((A(1), A(2)), const (A(1), A(2)));
+  checkEqualsAndHash(const (A(1), A(2)), (A(1), A(int.parse("2"))));
+
+  checkNotEquals((A(1), A(2)), (A(1), A(3)));
+
+  Object? notEqual = NotEqual();
+  checkNotEquals(notEqual, notEqual);
+  checkNotEquals((1, notEqual), (1, notEqual));
+  checkNotEquals((foo: notEqual), (foo: notEqual));
+
+  B o1 = B(1);
+  B o2 = B(2);
+  checkNotEquals((1, o1), (1, o2));
+  Expect.isTrue(o1.equalsCalled);
+  Expect.isFalse(o2.equalsCalled);
+
+  checkEqualsAndHash((2, o2), (2, B(int.parse("2"))));
+  Expect.isTrue(o2.equalsCalled);
+  Expect.isTrue(o2.hashCodeCalled);
+}
diff --git a/tests/language/records/simple/literals_and_field_access_test.dart b/tests/language/records/simple/literals_and_field_access_test.dart
new file mode 100644
index 0000000..d7c706b
--- /dev/null
+++ b/tests/language/records/simple/literals_and_field_access_test.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2022, 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.
+
+// SharedOptions=--enable-experiment=records
+
+import "package:expect/expect.dart";
+
+void checkRecordP2(Object? e1, Object? e2, (Object?, Object?) r) {
+  Expect.equals(e1, r.$0);
+  Expect.equals(e2, r.$1);
+}
+
+void checkRecordP3(Object? e1, Object? e2, Object? e3, (Object? e1, Object? e2, Object? e3) r) {
+  Expect.equals(e1, r.$0);
+  Expect.equals(e2, r.$1);
+  Expect.equals(e3, r.$2);
+}
+
+void checkRecordN1(Object? foo, ({Object? foo}) r) {
+  Expect.equals(foo, r.foo);
+}
+
+void checkRecordN2(Object? foo, Object? bar, ({Object? foo, Object? bar}) r) {
+  Expect.equals(foo, r.foo);
+  Expect.equals(bar, r.bar);
+}
+
+void checkRecordN3(Object? foo, Object? bar, Object? baz, ({Object? foo, Object? bar, Object? baz}) r) {
+  Expect.equals(foo, r.foo);
+  Expect.equals(bar, r.bar);
+  Expect.equals(baz, r.baz);
+}
+
+void checkRecordP1N1(Object? e1, Object? foo, (Object?, {Object? foo}) r) {
+  Expect.equals(e1, r.$0);
+  Expect.equals(foo, r.foo);
+}
+
+void checkRecordP1N2(Object? e1, Object? foo, Object? bar, (Object? e1, {Object? foo, Object? bar, }) r) {
+  Expect.equals(e1, r.$0);
+  Expect.equals(foo, r.foo);
+  Expect.equals(bar, r.bar);
+}
+
+void checkRecordP3N3(Object? e1, Object? e2, Object? e3, Object? foo, Object? bar, Object? baz, (Object?, Object?, Object?, {Object? foo, Object? baz, Object? bar}) r) {
+  Expect.equals(bar, r.bar);
+  Expect.equals(foo, r.foo);
+  Expect.equals(baz, r.baz);
+  Expect.equals(e1, r.$0);
+  Expect.equals(e2, r.$1);
+  Expect.equals(e3, r.$2);
+}
+
+({Object? foo}) getN1(Object foo) => (foo: foo);
+
+(Object?, {Object? foo}) getP1N1(x, y) => getP1N1Rec(42, x, y);
+
+(Object?, {Object? foo}) getP1N1Rec(int n, x, y) {
+  if (n == 0) return (foo: y, x);
+  return getP1N1Rec(n - 1, x, y);
+}
+
+(dynamic, dynamic, dynamic, {dynamic foo, dynamic bar, dynamic baz, }) getP3N3(int i, String s) {
+  (dynamic, dynamic, {dynamic foo, dynamic qq, dynamic baz}) r1 = (s.substring(i, i+1), s.substring(i, i+2), foo: s.substring(i, i+4), qq: i, baz: s.substring(i, i+6));
+  (dynamic, dynamic, dynamic, {dynamic foo, dynamic bar, dynamic baz}) r2 = (r1.$0, r1.$1, s.substring(i, i+3), foo: r1.foo, bar: s.substring(i, i+5), baz: r1.baz);
+  return r2;
+}
+
+class A {
+  final int v;
+  A(this.v);
+  operator==(Object other) => other is A && v == other.v;
+}
+
+main() {
+  checkRecordP2(10, 20, (10, 20));
+  checkRecordP3(3, 2, 1, (3, int.parse("2"), 1));
+  checkRecordN1("FOO", (foo: "FOO"));
+
+  final x = [1, 2, 3];
+  checkRecordN1(x, getN1(x));
+
+  checkRecordN2("0 1 2", "[1, 2, 3]", (foo: [for (int i = 0; i < 3; ++i) i].join(' '), bar: x.toString()));
+
+  checkRecordN3(A(10), 1.0, 42, (foo: A(9 + int.parse("1")), bar: 1.0, baz: 40 + A(2).v));
+
+  checkRecordP1N1(10, "abc", getP1N1(10, "abc"));
+
+  checkRecordP1N2(A(1), A(2), A(3), (foo: A(2), A(1), bar: A(3)));
+
+  checkRecordP3N3("h", "he", "hel", "hell", "hello", "hello,", [for (int i = 0; i < 3; ++i) getP3N3(i, "hello, world") ][0]);
+}
diff --git a/tests/language/records/simple/runtime_type_test.dart b/tests/language/records/simple/runtime_type_test.dart
new file mode 100644
index 0000000..d9aa715
--- /dev/null
+++ b/tests/language/records/simple/runtime_type_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code as governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=records
+
+import "package:expect/expect.dart";
+
+@pragma('vm:never-inline')
+Object getType1(Object obj) => obj.runtimeType;
+
+@pragma('vm:never-inline')
+Object getType2<T>() => T;
+
+@pragma('vm:never-inline')
+void testRuntimeTypeEquality(bool expected, Object a, Object b) {
+  bool result1 = getType1(a) == getType1(b);
+  Expect.equals(expected, result1);
+  // Test optimized 'a.runtimeType == b.runtimeType' pattern.
+  bool result2 = a.runtimeType == b.runtimeType;
+  Expect.equals(expected, result2);
+}
+
+main() {
+  Expect.equals(getType1(true), bool);
+  Expect.equals(getType1(false), getType2<bool>());
+  Expect.equals(getType1(1), getType2<int>());
+  Expect.equals(getType1((true, 3)), getType2<(bool, int)>());
+  Expect.equals(getType1((foo: true, bar: 2)), getType2<({int bar, bool foo})>());
+  Expect.equals(getType1((1, foo: true, false, bar: 2)), getType2<(int, bool, {int bar, bool foo})>());
+
+  testRuntimeTypeEquality(true, (1, 2), (3, 4));
+  testRuntimeTypeEquality(false, (1, 2), (1, 2, 3));
+  testRuntimeTypeEquality(false, (1, 2), (1, false));
+  testRuntimeTypeEquality(true, (1, 2, foo: true), (foo: false, 5, 4));
+  testRuntimeTypeEquality(false, (1, 2, foo: true), (bar: false, 5, 4));
+  testRuntimeTypeEquality(true, (foo: 1, bar: 2), (bar: 3, foo: 4));
+  testRuntimeTypeEquality(false, (foo: 1, bar: 2), (1, foo: 2));
+  testRuntimeTypeEquality(false, (1, 2), 3);
+  testRuntimeTypeEquality(false, (1, 2), 'hey');
+  testRuntimeTypeEquality(false, (1, 2), [1, 2]);
+}
diff --git a/tests/language/records/simple/to_string_test.dart b/tests/language/records/simple/to_string_test.dart
new file mode 100644
index 0000000..ad91b78
--- /dev/null
+++ b/tests/language/records/simple/to_string_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code as governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=records
+
+import "package:expect/expect.dart";
+
+class A {
+  final String name;
+  const A(this.name);
+
+  String toString() => name;
+}
+
+main() {
+  // Although the order of fields in toString() is unspecified,
+  // this test assumes that positional fields are printed first and
+  // named fields are sorted lexicographically.
+  // This test might need more sophisticated checks if there is
+  // an implementation which doesn't follow that order.
+
+  Expect.equals("(1, 2)", (1, 2).toString());
+  Expect.equals("(1, 2)", (const (1, 2)).toString());
+  Expect.equals("(3, 2, 1)", (3, 2, 1).toString());
+
+  Expect.equals("(1, foo: 2)", (1, foo: 2).toString());
+  Expect.equals("(1, foo: 2)", (foo: 2, 1).toString());
+
+  Expect.equals("(1, abc, bar: 3, foo: 2)", (1, foo: 2, "abc", bar: 3).toString());
+
+  Expect.equals("((A1, A2), (foo: A3), (A7, bar: A5, baz: A6, foo: A4))", ((A("A1"), A("A2")), const (foo: A("A3")), (foo: A("A4"), bar: A("A5"), baz: A("A6"), A("A7"))).toString());
+}
diff --git a/tests/language/records/simple/type_checks2_test.dart b/tests/language/records/simple/type_checks2_test.dart
new file mode 100644
index 0000000..152074b
--- /dev/null
+++ b/tests/language/records/simple/type_checks2_test.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code as governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=records
+// VMOptions=--deterministic --optimization_counter_threshold=150
+
+import "package:expect/expect.dart";
+
+class A<T> {
+}
+
+class B<T> {
+  void foo(T x) {}
+  void bar(A<T> x) {}
+}
+
+class C {
+  void baz(Object? x) {}
+}
+
+class D1 implements C {
+  void baz(covariant A<int> x) {}
+}
+
+class D2 implements C {
+  void baz(covariant A<(int, int)> x) {}
+}
+
+B<(num, num)> b1 = (int.parse('1') == 1) ? B<(int, int)>() : B<(num, num)>();
+B<({num foo})?> b2 = (int.parse('1') == 1) ? B<({int foo})>() : B<({num foo})?>();
+B<(num?, {num? foo})?> b3 = (int.parse('1') == 1) ? B<(int, {int? foo})?>() : B<(num?, {num? foo})?>();
+C d1 = (int.parse('1') == 1) ? D1() : C();
+C d2 = (int.parse('1') == 1) ? D2() : C();
+
+doTests() {
+  b1.foo((1, 2));
+  Expect.throwsTypeError(() => b1.foo((1.5, 2)));
+  Expect.throwsTypeError(() => b1.foo((1, 2.5)));
+
+  b1.bar(A<(int, int x)>());
+  b1.bar(A<Never>());
+  Expect.throwsTypeError(() => b1.bar(A<(int, double)>()));
+  Expect.throwsTypeError(() => b1.bar(A<(num, int)>()));
+
+  b2.foo((foo: 10));
+  Expect.throwsTypeError(() => b2.foo((foo: 10.5)));
+  if (hasSoundNullSafety) {
+    Expect.throwsTypeError(() => b2.foo(null));
+  }
+
+  b2.bar(A<({int foo})>());
+  b2.bar(A<Never>());
+  Expect.throwsTypeError(() => b2.bar(A<({num foo})>()));
+  if (hasSoundNullSafety) {
+    Expect.throwsTypeError(() => b2.bar(A<Null>()));
+    Expect.throwsTypeError(() => b2.bar(A<({int foo})?>()));
+  }
+
+  b3.foo((20, foo: 30));
+  b3.foo((20, foo: null));
+  b3.foo(null);
+  Expect.throwsTypeError(() => b3.foo((20.5, foo: 30)));
+  Expect.throwsTypeError(() => b3.foo((20, foo: 30.5)));
+  if (hasSoundNullSafety) {
+    Expect.throwsTypeError(() => b3.foo((null, foo: 30)));
+  }
+
+  b3.bar(A<(int, {int foo})>());
+  b3.bar(A<(int, {int? foo})>());
+  b3.bar(A<(int, {int? foo})?>());
+  b3.bar(A<Null>());
+  b3.bar(A<Never>());
+  Expect.throwsTypeError(() => b3.bar(A<(int, {double foo})>()));
+  Expect.throwsTypeError(() => b3.bar(A<(num, {int foo})>()));
+  if (hasSoundNullSafety) {
+    Expect.throwsTypeError(() => b3.bar(A<(int?, {int? foo})?>()));
+  }
+
+  d1.baz(A<int>());
+  Expect.throwsTypeError(() => d1.baz(A<(int, int)>()));
+  d2.baz(A<(int, int)>());
+  Expect.throwsTypeError(() => d2.baz(A<int>()));
+}
+
+main() {
+  for (int i = 0; i < 200; ++i) {
+    doTests();
+  }
+}
diff --git a/tests/language/records/simple/type_checks3_test.dart b/tests/language/records/simple/type_checks3_test.dart
new file mode 100644
index 0000000..84620d3
--- /dev/null
+++ b/tests/language/records/simple/type_checks3_test.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code as governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=records
+// VMOptions=--deterministic --optimization_counter_threshold=150
+
+import "package:expect/expect.dart";
+
+class A<T> {
+}
+
+class B<T> {
+  void foo(T x) {}
+  void bar(A<T> x) {}
+}
+
+B<(num, num)> b1 = (int.parse('1') == 1) ? B<(int, int)>() : B<(num, num)>();
+B<({num foo})?> b2 = (int.parse('1') == 1) ? B<({int foo})>() : B<({num foo})?>();
+B<(num?, {num? foo})?> b3 = (int.parse('1') == 1) ? B<(int, {int? foo})?>() : B<(num?, {num? foo})?>();
+
+doTests() {
+  b1 as B<(int, int)>;
+  b1 as B<(int, num)>;
+  b1 as B<(int, int?)>;
+  b1 as B<(int, int)>?;
+  b1 as B<Object>;
+  b1 as B<Record>;
+  Expect.throwsTypeError(() => b1 as B<(int, double)>);
+  Expect.throwsTypeError(() => b1 as B<(double, int)>);
+  Expect.throwsTypeError(() => b1 as B<Null>);
+  Expect.throwsTypeError(() => b1 as B<Never>);
+  Expect.throwsTypeError(() => b1 as B<Function>);
+  Expect.throwsTypeError(() => b1 as B<int>);
+  Expect.throwsTypeError(() => b1 as B<(int, {int foo})>);
+  Expect.throwsTypeError(() => b1 as B<({int foo})>);
+
+  b2 as B<({int foo})>;
+  b2 as B<({num foo})>;
+  b2 as B<({int foo})>?;
+  b2 as B<({int foo})?>;
+  b2 as B<({int? foo})>;
+  Expect.throwsTypeError(() => b2 as B<(int, int)>);
+  Expect.throwsTypeError(() => b2 as B<({int bar})>);
+  Expect.throwsTypeError(() => b2 as B<({double foo})>);
+
+  b3 as B<(int, {int? foo})?>;
+  if (hasSoundNullSafety) {
+    Expect.throwsTypeError(() => b3 as B<(int, {int? foo})>);
+    Expect.throwsTypeError(() => b3 as B<(int, {int foo})?>);
+  }
+
+  A<(int, int)>() as A<(int, num)>;
+  A<(int, int)>() as A<Object>;
+  A<(int, int)>() as A<Record>;
+  Expect.throwsTypeError(() => A<(int, int)>() as A<(double, num)>);
+  Expect.throwsTypeError(() => A<(int, int)>() as A<(num, double)>);
+  Expect.throwsTypeError(() => A<(int, int)>() as A<Function>);
+  Expect.throwsTypeError(() => A<(int, int)>() as A<int>);
+  Expect.throwsTypeError(() => A<(int, int)>() as A<String>);
+
+  A<({int foo})>() as A<({int? foo})>;
+  A<({int foo})>() as A<({int foo})?>;
+  A<({int foo})>() as A<({int foo})>?;
+  if (hasSoundNullSafety) {
+    Expect.throwsTypeError(() => A<({int? foo})>() as A<({int foo})>);
+    Expect.throwsTypeError(() => A<({int? foo})>() as A<({int foo})?>);
+    Expect.throwsTypeError(() => A<({int? foo})>() as A<({int foo})>?);
+    Expect.throwsTypeError(() => A<({int foo})?>() as A<({int? foo})>);
+    Expect.throwsTypeError(() => A<({int foo})?>() as A<({int foo})>);
+    Expect.throwsTypeError(() => A<({int foo})?>() as A<({int foo})>?);
+  }
+}
+
+main() {
+  for (int i = 0; i < 200; ++i) {
+    doTests();
+  }
+}
diff --git a/tests/language/records/simple/type_checks_test.dart b/tests/language/records/simple/type_checks_test.dart
new file mode 100644
index 0000000..4726f94
--- /dev/null
+++ b/tests/language/records/simple/type_checks_test.dart
@@ -0,0 +1,167 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code as governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=records
+// VMOptions=--deterministic --optimization_counter_threshold=150
+
+import "package:expect/expect.dart";
+
+dynamic getP2(x, y) => (x, y);
+dynamic getN2(x, y) => (foo: x, bar: y);
+dynamic getP2N2(x, y, z, w) => (x, y, foo: z, bar: w);
+
+class A<T> {
+  typeCheck(T x) {}
+  boundCheck<X extends T>() {}
+}
+
+verifyIsTests() {
+  Expect.isTrue((1, 2) is (int, int));
+  Expect.isTrue((1, 2) is (num, Object));
+  Expect.isTrue((1, 2) is (Object, int));
+  Expect.isFalse((1, 2) is (int, String));
+
+  Expect.isTrue(getP2(10, 'abc') is (int, String));
+  Expect.isTrue(getP2(10, 'abc') is (int foo, String bar));
+  Expect.isTrue(getP2(10, 'abc') is (int bar, String foo));
+  Expect.isFalse(getP2(10, 'abc') is (String bar, int foo));
+  Expect.isFalse(getP2(10, 'abc') is ({int foo, String bar}));
+  Expect.isFalse(getP2(10, 'abc') is (int foo, {String bar}));
+
+  Expect.isTrue(getN2(<int>[], 10) is ({List foo, num bar}));
+  Expect.isTrue(getN2(<int>[], 10) is ({List<int> foo, Object bar}));
+  Expect.isTrue(getN2(<int>[], 10) is ({List<num> foo, int bar}));
+  Expect.isTrue(getN2(<int>[], 10) is ({num bar, List foo}));
+  Expect.isFalse(getN2(<int>[], 10) is ({List bar, num foo}));
+  Expect.isFalse(getN2(<int>[], 10) is ({List foo}));
+  Expect.isFalse(getN2(<int>[], 10) is ({List foo, num bar, int baz}));
+  Expect.isFalse(getN2(<int>[], 10) is (List foo, {num bar}));
+
+  Expect.isTrue(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) is (List<int>, Map<int, String>, {A<num> foo, int bar}));
+  Expect.isTrue(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) is (List<int?>, Map<int?, String?>, {A<num?> foo, int? bar}));
+  Expect.isTrue(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) is (List<dynamic>, Map<dynamic, dynamic>, {A<dynamic> foo, dynamic bar}));
+  Expect.isTrue(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) is (dynamic, dynamic, {dynamic foo, dynamic bar}));
+  Expect.isFalse(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) is (dynamic, dynamic, {dynamic foo, dynamic baz}));
+  Expect.isFalse(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) is (dynamic, dynamic, dynamic, {dynamic foo, dynamic bar}));
+  Expect.isFalse(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) is (dynamic, dynamic, dynamic foo, dynamic bar));
+  Expect.isFalse(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) is (dynamic, dynamic, {dynamic foo, dynamic bar, dynamic baz}));
+}
+
+verifyAsChecks() {
+  final results = [];
+  results.add((1, 2) as (int, int));
+  results.add((1, 2) as (num, Object));
+  results.add((1, 2) as (Object, int));
+  Expect.throwsTypeError(() => (1, 2) as (int, String));
+
+  results.add(getP2(10, 'abc') as (int, String));
+  results.add(getP2(10, 'abc') as (int foo, String bar));
+  results.add(getP2(10, 'abc') as (int bar, String foo));
+  Expect.throwsTypeError(() => getP2(10, 'abc') as (String bar, int foo));
+  Expect.throwsTypeError(() => getP2(10, 'abc') as ({int foo, String bar}));
+  Expect.throwsTypeError(() => getP2(10, 'abc') as (int foo, {String bar}));
+
+  results.add(getN2(<int>[], 10) as ({List foo, num bar}));
+  results.add(getN2(<int>[], 10) as ({List<int> foo, Object bar}));
+  results.add(getN2(<int>[], 10) as ({List<num> foo, int bar}));
+  results.add(getN2(<int>[], 10) as ({num bar, List foo}));
+  Expect.throwsTypeError(() => getN2(<int>[], 10) as ({List bar, num foo}));
+  Expect.throwsTypeError(() => getN2(<int>[], 10) as ({List foo}));
+  Expect.throwsTypeError(() => getN2(<int>[], 10) as ({List foo, num bar, int baz}));
+  Expect.throwsTypeError(() => getN2(<int>[], 10) as (List foo, {num bar}));
+
+  results.add(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) as (List<int>, Map<int, String>, {A<num> foo, int bar}));
+  results.add(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) as (List<int?>, Map<int?, String?>, {A<num?> foo, int? bar}));
+  results.add(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) as (List<dynamic>, Map<dynamic, dynamic>, {A<dynamic> foo, dynamic bar}));
+  results.add(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) as (dynamic, dynamic, {dynamic foo, dynamic bar}));
+  Expect.throwsTypeError(() => getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) as (dynamic, dynamic, {dynamic foo, dynamic baz}));
+  Expect.throwsTypeError(() => getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) as (dynamic, dynamic, dynamic, {dynamic foo, dynamic bar}));
+  Expect.throwsTypeError(() => getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) as (dynamic, dynamic, dynamic foo, dynamic bar));
+  Expect.throwsTypeError(() => getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10) as (dynamic, dynamic, {dynamic foo, dynamic bar, dynamic baz}));
+
+  return results;
+}
+
+A<Object?> getA<T>() => int.parse("1") == 1 ? A<T>() : A<Never>();
+
+checkParameterType<T>(x) {
+  getA<T>().typeCheck(x);
+}
+
+verifyParameterTypeChecks() {
+  final results = [];
+  checkParameterType<(int, int)>((1, 2));
+  checkParameterType<(num, Object)>((1, 2));
+  checkParameterType<(Object, int)>((1, 2));
+  Expect.throwsTypeError(() => checkParameterType<(int, String)>((1, 2)));
+
+  checkParameterType<(int, String)>(getP2(10, 'abc'));
+  checkParameterType<(int foo, String bar)>(getP2(10, 'abc'));
+  checkParameterType<(int bar, String foo)>(getP2(10, 'abc'));
+  Expect.throwsTypeError(() => checkParameterType<(String bar, int foo)>(getP2(10, 'abc')));
+  Expect.throwsTypeError(() => checkParameterType<({int foo, String bar})>(getP2(10, 'abc')));
+  Expect.throwsTypeError(() => checkParameterType<(int foo, {String bar})>(getP2(10, 'abc')));
+
+  checkParameterType<({List foo, num bar})>(getN2(<int>[], 10));
+  checkParameterType<({List<int> foo, Object bar})>(getN2(<int>[], 10));
+  checkParameterType<({List<num> foo, int bar})>(getN2(<int>[], 10));
+  checkParameterType<({num bar, List foo})>(getN2(<int>[], 10));
+  Expect.throwsTypeError(() => checkParameterType<({List bar, num foo})>(getN2(<int>[], 10)));
+  Expect.throwsTypeError(() => checkParameterType<({List foo})>(getN2(<int>[], 10)));
+  Expect.throwsTypeError(() => checkParameterType<({List foo, num bar, int baz})>(getN2(<int>[], 10)));
+  Expect.throwsTypeError(() => checkParameterType<(List foo, {num bar})>(getN2(<int>[], 10)));
+
+  checkParameterType<(List<int>, Map<int, String>, {A<num> foo, int bar})>(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10));
+  checkParameterType<(List<int?>, Map<int?, String?>, {A<num?> foo, int? bar})>(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10));
+  checkParameterType<(List<dynamic>, Map<dynamic, dynamic>, {A<dynamic> foo, dynamic bar})>(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10));
+  checkParameterType<(dynamic, dynamic, {dynamic foo, dynamic bar})>(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10));
+  Expect.throwsTypeError(() => checkParameterType<(dynamic, dynamic, {dynamic foo, dynamic baz})>(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10)));
+  Expect.throwsTypeError(() => checkParameterType<(dynamic, dynamic, dynamic, {dynamic foo, dynamic bar})>(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10)));
+  Expect.throwsTypeError(() => checkParameterType<(dynamic, dynamic, dynamic foo, dynamic bar)>(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10)));
+  Expect.throwsTypeError(() => checkParameterType<(dynamic, dynamic, {dynamic foo, dynamic bar, dynamic baz})>(getP2N2(const <int>[42], <int, String>{1: 'hi'}, A<num>(), 10)));
+}
+
+checkTypeParameterBound<T, Bound>() {
+  getA<Bound>().boundCheck<T>();
+}
+
+void verifyTypeParameterBoundsChecks() {
+  checkTypeParameterBound<(int, int), (int, int)>();
+  checkTypeParameterBound<(int, int), (num, int)>();
+  checkTypeParameterBound<(int, int), (int, Object)>();
+  checkTypeParameterBound<(int, int), (int, int?)>();
+  checkTypeParameterBound<(int, int), (int, int)?>();
+    Expect.throwsTypeError(() => checkTypeParameterBound<(int, Object), (int, int)>());
+  if (hasSoundNullSafety) {
+    Expect.throwsTypeError(() => checkTypeParameterBound<(int, int?), (int, int)>());
+    Expect.throwsTypeError(() => checkTypeParameterBound<(int, int)?, (int, int)>());
+  }
+
+  checkTypeParameterBound<(String, {int foo}), (String, {int foo})>();
+  Expect.throwsTypeError(() => checkTypeParameterBound<(String, {int foo}), (String, {int bar})>());
+  Expect.throwsTypeError(() => checkTypeParameterBound<(String, {num foo}), (String, {int foo})>());
+  if (hasSoundNullSafety) {
+    Expect.throwsTypeError(() => checkTypeParameterBound<(String, {int? foo}), (String, {int foo})>());
+  }
+
+  checkTypeParameterBound<({int foo, Object bar}), ({Object bar, int foo})>();
+  checkTypeParameterBound<({int foo, Object bar}), ({Object foo, Object? bar})>();
+  Expect.throwsTypeError(() => checkTypeParameterBound<({int foo, Object bar}), ({Object foo, int bar})>());
+
+  checkTypeParameterBound<(int, String, double), (num, String, num)>();
+  Expect.throwsTypeError(() => checkTypeParameterBound<(int, String, Object), (num, String, num)>());
+}
+
+doTests() {
+  verifyIsTests();
+  verifyAsChecks();
+  verifyParameterTypeChecks();
+  verifyTypeParameterBoundsChecks();
+}
+
+main() {
+  for (int i = 0; i < 200; ++i) {
+    doTests();
+  }
+}
diff --git a/tests/language/redirecting/factory_default_values_test.dart b/tests/language/redirecting/factory_default_values_test.dart
index 23a0e3c..3c25607 100644
--- a/tests/language/redirecting/factory_default_values_test.dart
+++ b/tests/language/redirecting/factory_default_values_test.dart
@@ -14,12 +14,12 @@
   // [analyzer] COMPILE_TIME_ERROR.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR
   //                          ^
   // [cfe] Can't have a default value here because any default values of 'A' would be used instead.
-  factory A.h(int a, {int b: 0}) = A;
+  factory A.h(int a, {int b = 0}) = A;
   //                      ^
   // [analyzer] COMPILE_TIME_ERROR.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR
-  //                         ^
+  //                          ^
   // [cfe] Can't have a default value here because any default values of 'A' would be used instead.
-  //                               ^
+  //                                ^
   // [analyzer] COMPILE_TIME_ERROR.REDIRECT_TO_INVALID_FUNCTION_TYPE
   // [cfe] The constructor function type 'A Function(int, [int])' isn't a subtype of 'A Function(int, {int b})'.
 
diff --git a/tests/language/regress/regress12118_test.dart b/tests/language/regress/regress12118_test.dart
index fea6996..4bcd491 100644
--- a/tests/language/regress/regress12118_test.dart
+++ b/tests/language/regress/regress12118_test.dart
@@ -8,7 +8,7 @@
 
 class A {
   final x;
-  A({this.x: X});
+  A({this.x = X});
 }
 
 class B extends A {}
diff --git a/tests/language/regress/regress27659_test.dart b/tests/language/regress/regress27659_test.dart
index e40a886..3c112d1 100644
--- a/tests/language/regress/regress27659_test.dart
+++ b/tests/language/regress/regress27659_test.dart
@@ -4,11 +4,11 @@
 
 const String lineLength = '120';
 
-foo({lineLength: lineLength}) {
+foo({lineLength = lineLength}) {
   print(lineLength);
 }
 
-bar({lineLength: lineLength}) async {
+bar({lineLength = lineLength}) async {
   print(lineLength);
 }
 
diff --git a/tests/language/super/bound_closure_test.dart b/tests/language/super/bound_closure_test.dart
index 5061145..f70256c 100644
--- a/tests/language/super/bound_closure_test.dart
+++ b/tests/language/super/bound_closure_test.dart
@@ -6,29 +6,29 @@
 
 class A {
   bar([var optional = 1]) => 498 + optional;
-  bar2({namedOptional: 2}) => 40 + namedOptional;
+  bar2({namedOptional = 2}) => 40 + namedOptional;
   bar3(x, [var optional = 3]) => x + 498 + optional;
-  bar4(x, {namedOptional: 4}) => 422 + x + namedOptional;
+  bar4(x, {namedOptional = 4}) => 422 + x + namedOptional;
 
   // Gee is the same as bar, but we make sure that gee is used. Potentially
   // this yields different code if the redirecting stub exists.
   gee([var optional = 1]) => 498 + optional;
-  gee2({namedOptional: 2}) => 40 + namedOptional;
+  gee2({namedOptional = 2}) => 40 + namedOptional;
   gee3(x, [var optional = 3]) => x + 498 + optional;
-  gee4(x, {namedOptional: 4}) => 422 + x + namedOptional;
+  gee4(x, {namedOptional = 4}) => 422 + x + namedOptional;
 
   // Use identifiers that could be intercepted.
   add([var optional = 33]) => 1234 + optional;
-  trim({namedOptional: 22}) => 1313 + namedOptional;
+  trim({namedOptional = 22}) => 1313 + namedOptional;
   sublist(x, [optional = 44]) => 4321 + optional + x;
-  splitMapJoin(x, {onMatch: 55, onNonMatch: 66}) =>
+  splitMapJoin(x, {onMatch = 55, onNonMatch = 66}) =>
       111 + x + onMatch + onNonMatch;
 
   // Other interceptable identifiers, but all of them are used.
   shuffle([var optional = 121]) => 12342 + optional;
-  toList({growable: 2233}) => 13131 + growable;
+  toList({growable = 2233}) => 13131 + growable;
   lastIndexOf(x, [optional = 424]) => 14321 + optional + x;
-  lastWhere(x, {orElse: 555}) => x + 1213 + 555;
+  lastWhere(x, {orElse = 555}) => x + 1213 + 555;
 }
 
 class B extends A {
@@ -83,14 +83,14 @@
   gee4(x, {namedOptional}) => -1; //# 01: continued
 
   add([var optional = 33]) => -1;
-  trim({namedOptional: 22}) => -1;
+  trim({namedOptional = 22}) => -1;
   sublist(x, [optional = 44]) => -1;
-  splitMapJoin(x, {onMatch: 55, onNonMatch: 66}) => -1;
+  splitMapJoin(x, {onMatch = 55, onNonMatch = 66}) => -1;
 
   shuffle([var optional = 121]) => -1;
-  toList({growable: 2233}) => -1;
+  toList({growable = 2233}) => -1;
   lastIndexOf(x, [optional = 424]) => -1;
-  lastWhere(x, {orElse: 555}) => -1;
+  lastWhere(x, {orElse = 555}) => -1;
 }
 
 confuse(x) {
diff --git a/tests/language/this/as_dynamic_call_checks_test.dart b/tests/language/this/as_dynamic_call_checks_test.dart
index 829a327..6310207 100644
--- a/tests/language/this/as_dynamic_call_checks_test.dart
+++ b/tests/language/this/as_dynamic_call_checks_test.dart
@@ -16,26 +16,26 @@
   void method(T x) {}
 
   @pragma('vm:never-inline')
-  void testMethod({bool violateType: false}) {
+  void testMethod({bool violateType = false}) {
     dynamic x = this;
     x.method(violateType ? 10 : "10");
   }
 
   @pragma('vm:never-inline')
-  void testSetter({bool violateType: false}) {
+  void testSetter({bool violateType = false}) {
     dynamic x = this;
     x.property = violateType ? 10 : "10";
   }
 
   @pragma('vm:never-inline')
-  void testField({bool violateType: false}) {
+  void testField({bool violateType = false}) {
     dynamic x = this;
     x.field = violateType ? 10 : "10";
   }
 }
 
 @pragma('vm:never-inline')
-void loop(A<String> obj, {bool violateType: false}) {
+void loop(A<String> obj, {bool violateType = false}) {
   for (var i = 0; i < 100; i++) {
     obj.testMethod(violateType: violateType);
     obj.testSetter(violateType: violateType);
diff --git a/tests/language/unsorted/arg_param_trailing_comma_test.dart b/tests/language/unsorted/arg_param_trailing_comma_test.dart
index ab9c425..9119dfa 100644
--- a/tests/language/unsorted/arg_param_trailing_comma_test.dart
+++ b/tests/language/unsorted/arg_param_trailing_comma_test.dart
@@ -36,12 +36,12 @@
 
 // After specific parameter formats.
 void afterDefaultValueY([int y = 42, ]) {} //           //# none: continued
-void afterDefaultValueZ({int z : 42, }) {} //           //# none: continued
+void afterDefaultValueZ({int z = 42, }) {} //           //# none: continued
 void afterFunsigX(void f(),) {} //                      //# none: continued
 void afterFunsigY([void f()?,]) {} //                   //# none: continued
 void afterFunsigZ({void f()?,}) {} //                   //# none: continued
 void afterFunsigDefaultValueY([void f() = topy,]) {} // //# none: continued
-void afterFunsigDefaultValueZ({void f() : topz,}) {} // //# none: continued
+void afterFunsigDefaultValueZ({void f() = topz,}) {} // //# none: continued
 
 class C {
   C();
diff --git a/tests/language/unsorted/cyclic_default_values_test.dart b/tests/language/unsorted/cyclic_default_values_test.dart
index 3ac8e0b..6f85788 100644
--- a/tests/language/unsorted/cyclic_default_values_test.dart
+++ b/tests/language/unsorted/cyclic_default_values_test.dart
@@ -7,8 +7,8 @@
 bar([x = foo]) => x((_) => "bar");
 foo([y = bar]) => y((_) => "foo");
 
-foo2({f: bar2}) => f(f: ({f}) => "foo2");
-bar2({f: foo2}) => f(f: ({f}) => "bar2");
+foo2({f = bar2}) => f(f: ({f}) => "foo2");
+bar2({f = foo2}) => f(f: ({f}) => "bar2");
 
 main() {
   var f = bar;
diff --git a/tests/language/unsorted/many_named_arguments_test.dart b/tests/language/unsorted/many_named_arguments_test.dart
index 015a137..ed239a4 100644
--- a/tests/language/unsorted/many_named_arguments_test.dart
+++ b/tests/language/unsorted/many_named_arguments_test.dart
@@ -6,32 +6,32 @@
 
 class Fisk {
   method(
-      {a: 'a',
-      b: 'b',
-      c: 'c',
-      d: 'd',
-      e: 'e',
-      f: 'f',
-      g: 'g',
-      h: 'h',
-      i: 'i',
-      j: 'j',
-      k: 'k',
-      l: 'l',
-      m: 'm',
-      n: 'n',
-      o: 'o',
-      p: 'p',
-      q: 'q',
-      r: 'r',
-      s: 's',
-      t: 't',
-      u: 'u',
-      v: 'v',
-      w: 'w',
-      x: 'x',
-      y: 'y',
-      z: 'z'}) {
+      {a = 'a',
+      b = 'b',
+      c = 'c',
+      d = 'd',
+      e = 'e',
+      f = 'f',
+      g = 'g',
+      h = 'h',
+      i = 'i',
+      j = 'j',
+      k = 'k',
+      l = 'l',
+      m = 'm',
+      n = 'n',
+      o = 'o',
+      p = 'p',
+      q = 'q',
+      r = 'r',
+      s = 's',
+      t = 't',
+      u = 'u',
+      v = 'v',
+      w = 'w',
+      x = 'x',
+      y = 'y',
+      z = 'z'}) {
     return 'a: $a, '
         'b: $b, '
         'c: $c, '
diff --git a/tests/language/unsorted/shadow_parameter_and_local_test.dart b/tests/language/unsorted/shadow_parameter_and_local_test.dart
index 6082f59..12c65f0 100644
--- a/tests/language/unsorted/shadow_parameter_and_local_test.dart
+++ b/tests/language/unsorted/shadow_parameter_and_local_test.dart
@@ -55,17 +55,17 @@
     return a;
   }
 
-  mAsync({a: 0}) async {
+  mAsync({a = 0}) async {
     var a = 123;
     return a;
   }
 
-  mSyncStar({a: 0}) sync* {
+  mSyncStar({a = 0}) sync* {
     var a = 123;
     yield a;
   }
 
-  mAsyncStar({a: 0}) async* {
+  mAsyncStar({a = 0}) async* {
     var a = 123;
     yield a;
   }
diff --git a/tests/language/vm/smi_widening_test.dart b/tests/language/vm/smi_widening_test.dart
index b3fcfae..5d67699 100644
--- a/tests/language/vm/smi_widening_test.dart
+++ b/tests/language/vm/smi_widening_test.dart
@@ -57,12 +57,12 @@
 
   @pragma('vm:never-inline')
   Box(
-      {int days: 0,
-      int hours: 0,
-      int minutes: 0,
-      int seconds: 0,
-      int milliseconds: 0,
-      int microseconds: 0})
+      {int days = 0,
+      int hours = 0,
+      int minutes = 0,
+      int seconds = 0,
+      int milliseconds = 0,
+      int microseconds = 0})
       : this._microseconds(1000 * 1000 * 60 * 60 * 24 * days +
             1000 * 1000 * 60 * 60 * hours +
             1000 * 1000 * 60 * minutes +
diff --git a/tests/language_2/constructor/external_constructor_test.dart b/tests/language_2/constructor/external_constructor_test.dart
new file mode 100644
index 0000000..a4bfdba
--- /dev/null
+++ b/tests/language_2/constructor/external_constructor_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2022, 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 for external constructors.
+
+// @dart = 2.9
+
+import "package:expect/expect.dart";
+
+class A {
+  final int field;
+
+  const A(this.field);
+  external const A.foo(dynamic arg);
+}
+
+class B extends A {
+  const B(int abc) : super(abc);
+  B.foo(dynamic arg) : super.foo(arg);
+}
+
+void main() {
+  Expect.throws(() {
+    A.foo(42);
+  }, (e) => e is NoSuchMethodError);
+  Expect.throws(() {
+    B.foo(42);
+  }, (e) => e is NoSuchMethodError);
+}
diff --git a/tests/language_2/inference_update_2/no_such_method_restriction_disabled_lib.dart b/tests/language_2/inference_update_2/no_such_method_restriction_disabled_lib.dart
new file mode 100644
index 0000000..d54773d
--- /dev/null
+++ b/tests/language_2/inference_update_2/no_such_method_restriction_disabled_lib.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Library used by `no_such_method_restriction_disabled_test.dart`.
+
+// @dart=2.9
+
+class Interface {
+  static int interfaceCount = 0;
+
+  int _privateField = 100;
+
+  int get _privateGetter {
+    interfaceCount++;
+    return 101;
+  }
+
+  set _privateSetter(int value) {
+    interfaceCount++;
+  }
+
+  int _privateMethod() {
+    interfaceCount++;
+    return 102;
+  }
+
+  int publicField = 103;
+
+  int get publicGetter {
+    interfaceCount++;
+    return 104;
+  }
+
+  set publicSetter(int value) {
+    interfaceCount++;
+  }
+
+  int publicMethod() {
+    interfaceCount++;
+    return 105;
+  }
+
+  static int getPrivateField(Interface x) => x._privateField;
+
+  static void setPrivateField(Interface x) => x._privateField = 106;
+
+  static int callPrivateGetter(Interface x) => x._privateGetter;
+
+  static void callPrivateSetter(Interface x) => x._privateSetter = 107;
+
+  static int callPrivateMethod(Interface x) => x._privateMethod();
+
+  static int getPublicField(Interface x) => x.publicField;
+
+  static void setPublicField(Interface x) => x.publicField = 108;
+
+  static int callPublicGetter(Interface x) => x.publicGetter;
+
+  static void callPublicSetter(Interface x) => x.publicSetter = 109;
+
+  static int callPublicMethod(Interface x) => x.publicMethod();
+}
+
+class Dynamic {
+  static int getPrivateField(dynamic x) => x._privateField;
+
+  static void setPrivateField(dynamic x) => x._privateField = 103;
+
+  static int callPrivateGetter(dynamic x) => x._privateGetter;
+
+  static void callPrivateSetter(dynamic x) => x._privateSetter = 104;
+
+  static int callPrivateMethod(dynamic x) => x._privateMethod();
+
+  static int getPublicField(dynamic x) => x.publicField;
+
+  static void setPublicField(dynamic x) => x.publicField = 108;
+
+  static int callPublicGetter(dynamic x) => x.publicGetter;
+
+  static void callPublicSetter(dynamic x) => x.publicSetter = 109;
+
+  static int callPublicMethod(dynamic x) => x.publicMethod();
+}
+
+class Nsm {
+  int otherNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return otherNsmCount++;
+  }
+}
+
+class Stubs implements Interface {
+  int stubsNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return stubsNsmCount++;
+  }
+}
diff --git a/tests/language_2/inference_update_2/no_such_method_restriction_disabled_test.dart b/tests/language_2/inference_update_2/no_such_method_restriction_disabled_test.dart
new file mode 100644
index 0000000..fa1387f
--- /dev/null
+++ b/tests/language_2/inference_update_2/no_such_method_restriction_disabled_test.dart
@@ -0,0 +1,413 @@
+// Copyright (c) 2022, 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.
+
+// Tests that the behavior of forwarding stubs to call noSuchMethod is
+// restricted to public members and members from the same library; forwarding
+// stubs for private members from other libraries always throw.
+//
+// Without this, field promotion would not be sound.  For example, in the code
+// below, each attempt to get `_i` from an instance of class `B` would result in
+// an invocation of `B.noSuchMethod`, so evaluation of `a._i` at (1) would yield
+// `0`, and evaluation of `a._i` at (2) would yield `null`.
+//
+//     main.dart:
+//       import 'other.dart';
+//       class B implements A {
+//         bool b = false;
+//         @override
+//         dynamic noSuchMethod(Invocation invocation) => (b = !b) ? 0 : null;
+//       }
+//       main() => foo(new B());
+//     other.dart:
+//       class A {
+//         final int? _i;
+//         A(this._i);
+//       }
+//       void foo(A a) {
+//         if (a._i != null) { // (1)
+//           print(a._i + 1);  // (2)
+//         }
+//       }
+//
+// Whereas with the restriction, any attempt to get `_i` from an instance of
+// class `B` would result in an exception, so the code would never reach (2).
+//
+// Since this behavior involves interactions among libraries, we have to think
+// carefully about how it is affected by language versioning.  There are two
+// issues to consider:
+//
+// 1. Should the forwarding stub throw even if the language feature
+//    "inference-update-2" is disabled in the library containing the class
+//    that's causing the forwarding stub to be generated?  We need to answer
+//    this question with a "yes", otherwise a class declaration in a library
+//    with an older language version could still ruin the soundness of field
+//    promotion in some other library.
+//
+// 2. Should the forwarding stub throw even if the language feature
+//    "inference-update-2" is disabled in the library containing the private
+//    member in question?  Our answer to this question doesn't affect soundness,
+//    because field promotion can't happen in libraries for which the language
+//    feature is disabled.  However, we still answer "yes", because otherwise an
+//    attempt to upgrade to a newer language version in one library might cause
+//    unexpected behavior changes in other libraries that import it, and we
+//    don't want that to happen.
+//
+// This file covers cases where the language feature "inference-update-2" is
+// disabled.
+
+// @dart=2.9
+
+import 'package:expect/expect.dart';
+
+import 'no_such_method_restriction_disabled_lib.dart' as lib;
+
+class Interface {
+  static int interfaceCount = 0;
+
+  int _privateField = 100;
+
+  int get _privateGetter {
+    interfaceCount++;
+    return 101;
+  }
+
+  set _privateSetter(int value) {
+    interfaceCount++;
+  }
+
+  int _privateMethod() {
+    interfaceCount++;
+    return 102;
+  }
+
+  int publicField = 103;
+
+  int get publicGetter {
+    interfaceCount++;
+    return 104;
+  }
+
+  set publicSetter(int value) {
+    interfaceCount++;
+  }
+
+  int publicMethod() {
+    interfaceCount++;
+    return 105;
+  }
+
+  static int getPrivateField(Interface x) => x._privateField;
+
+  static void setPrivateField(Interface x) => x._privateField = 106;
+
+  static int callPrivateGetter(Interface x) => x._privateGetter;
+
+  static void callPrivateSetter(Interface x) => x._privateSetter = 107;
+
+  static int callPrivateMethod(Interface x) => x._privateMethod();
+
+  static int getPublicField(Interface x) => x.publicField;
+
+  static void setPublicField(Interface x) => x.publicField = 108;
+
+  static int callPublicGetter(Interface x) => x.publicGetter;
+
+  static void callPublicSetter(Interface x) => x.publicSetter = 109;
+
+  static int callPublicMethod(Interface x) => x.publicMethod();
+}
+
+class Dynamic {
+  static int getPrivateField(dynamic x) => x._privateField;
+
+  static void setPrivateField(dynamic x) => x._privateField = 103;
+
+  static int callPrivateGetter(dynamic x) => x._privateGetter;
+
+  static void callPrivateSetter(dynamic x) => x._privateSetter = 104;
+
+  static int callPrivateMethod(dynamic x) => x._privateMethod();
+
+  static int getPublicField(dynamic x) => x.publicField;
+
+  static void setPublicField(dynamic x) => x.publicField = 108;
+
+  static int callPublicGetter(dynamic x) => x.publicGetter;
+
+  static void callPublicSetter(dynamic x) => x.publicSetter = 109;
+
+  static int callPublicMethod(dynamic x) => x.publicMethod();
+}
+
+/// The tests in this class cover the case where the members are in the same
+/// library as the forwarding stubs.  All member invocations should be
+/// dispatched to noSuchMethod.
+class Local implements Interface {
+  int _localNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return _localNsmCount++;
+  }
+
+  static void testPrivate() {
+    var x = Local();
+    Expect.equals(0, Interface.getPrivateField(x));
+    Expect.equals(1, x._localNsmCount);
+    Interface.setPrivateField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Interface.callPrivateGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Interface.callPrivateSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Interface.callPrivateMethod(x));
+    Expect.equals(5, x._localNsmCount);
+    Expect.equals(0, Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = Local();
+    Expect.equals(0, Interface.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    Interface.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Interface.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Interface.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Interface.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+    Expect.equals(0, Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = Local();
+    Expect.equals(0, Dynamic.getPrivateField(x));
+    Expect.equals(1, x._localNsmCount);
+    Dynamic.setPrivateField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Dynamic.callPrivateGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Dynamic.callPrivateSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Dynamic.callPrivateMethod(x));
+    Expect.equals(5, x._localNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = Local();
+    Expect.equals(0, Dynamic.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    Dynamic.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, Dynamic.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    Dynamic.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, Dynamic.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+  }
+}
+
+/// The tests in this class cover the case where both noSuchMethod and the other
+/// members are in the same library as the forwarding stubs, but that library is
+/// not the same as the library containing this class.  All member invocations
+/// should be dispatched to noSuchMethod.
+class RemoteStubs extends lib.Stubs {
+  static void testPrivate() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Interface.getPrivateField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Interface.setPrivateField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Interface.callPrivateGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Interface.callPrivateSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Interface.callPrivateMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Interface.getPublicField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Interface.setPublicField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Interface.callPublicGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Interface.callPublicSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Interface.callPublicMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Dynamic.getPrivateField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Dynamic.setPrivateField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Dynamic.callPrivateGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Dynamic.callPrivateSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Dynamic.callPrivateMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = RemoteStubs();
+    Expect.equals(0, lib.Dynamic.getPublicField(x));
+    Expect.equals(1, x.stubsNsmCount);
+    lib.Dynamic.setPublicField(x);
+    Expect.equals(2, x.stubsNsmCount);
+    Expect.equals(2, lib.Dynamic.callPublicGetter(x));
+    Expect.equals(3, x.stubsNsmCount);
+    lib.Dynamic.callPublicSetter(x);
+    Expect.equals(4, x.stubsNsmCount);
+    Expect.equals(4, lib.Dynamic.callPublicMethod(x));
+    Expect.equals(5, x.stubsNsmCount);
+  }
+}
+
+/// The tests in this class cover the case where noSuchMember is local, but the
+/// other members are in a different library from the forwarding stubs.  All
+/// public member invocations should be dispatched to noSuchMethod; all private
+/// member invocations should throw.
+class LocalNsm implements lib.Interface {
+  int _localNsmCount = 0;
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    return _localNsmCount++;
+  }
+
+  static void testPrivate() {
+    var x = LocalNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Interface.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateMethod(x));
+    Expect.equals(0, x._localNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = LocalNsm();
+    Expect.equals(0, lib.Interface.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    lib.Interface.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, lib.Interface.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    lib.Interface.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, lib.Interface.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = LocalNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateMethod(x));
+    Expect.equals(0, x._localNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = LocalNsm();
+    Expect.equals(0, lib.Dynamic.getPublicField(x));
+    Expect.equals(1, x._localNsmCount);
+    lib.Dynamic.setPublicField(x);
+    Expect.equals(2, x._localNsmCount);
+    Expect.equals(2, lib.Dynamic.callPublicGetter(x));
+    Expect.equals(3, x._localNsmCount);
+    lib.Dynamic.callPublicSetter(x);
+    Expect.equals(4, x._localNsmCount);
+    Expect.equals(4, lib.Dynamic.callPublicMethod(x));
+    Expect.equals(5, x._localNsmCount);
+  }
+}
+
+/// The tests in this class cover the case where both noSuchMember and the other
+/// members are in a different library from the forwarding stubs.  All public
+/// member invocations should be dispatched to noSuchMethod; all private member
+/// invocations should throw.
+class RemoteNsm extends lib.Nsm implements lib.Interface {
+  static void testPrivate() {
+    var x = RemoteNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Interface.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Interface.callPrivateMethod(x));
+    Expect.equals(0, x.otherNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPublic() {
+    var x = RemoteNsm();
+    Expect.equals(0, lib.Interface.getPublicField(x));
+    Expect.equals(1, x.otherNsmCount);
+    lib.Interface.setPublicField(x);
+    Expect.equals(2, x.otherNsmCount);
+    Expect.equals(2, lib.Interface.callPublicGetter(x));
+    Expect.equals(3, x.otherNsmCount);
+    lib.Interface.callPublicSetter(x);
+    Expect.equals(4, x.otherNsmCount);
+    Expect.equals(4, lib.Interface.callPublicMethod(x));
+    Expect.equals(5, x.otherNsmCount);
+    Expect.equals(0, lib.Interface.interfaceCount);
+  }
+
+  static void testPrivateDynamic() {
+    var x = RemoteNsm();
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.getPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.setPrivateField(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateGetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateSetter(x));
+    Expect.throwsNoSuchMethodError(() => lib.Dynamic.callPrivateMethod(x));
+    Expect.equals(0, x.otherNsmCount);
+  }
+
+  static void testPublicDynamic() {
+    var x = RemoteNsm();
+    Expect.equals(0, lib.Dynamic.getPublicField(x));
+    Expect.equals(1, x.otherNsmCount);
+    lib.Dynamic.setPublicField(x);
+    Expect.equals(2, x.otherNsmCount);
+    Expect.equals(2, lib.Dynamic.callPublicGetter(x));
+    Expect.equals(3, x.otherNsmCount);
+    lib.Dynamic.callPublicSetter(x);
+    Expect.equals(4, x.otherNsmCount);
+    Expect.equals(4, lib.Dynamic.callPublicMethod(x));
+    Expect.equals(5, x.otherNsmCount);
+  }
+}
+
+main() {
+  Local.testPrivate();
+  Local.testPublic();
+  Local.testPrivateDynamic();
+  Local.testPublicDynamic();
+  RemoteStubs.testPrivate();
+  RemoteStubs.testPublic();
+  RemoteStubs.testPrivateDynamic();
+  RemoteStubs.testPublicDynamic();
+  LocalNsm.testPrivate();
+  LocalNsm.testPublic();
+  LocalNsm.testPrivateDynamic();
+  LocalNsm.testPublicDynamic();
+  RemoteNsm.testPrivate();
+  RemoteNsm.testPublic();
+  RemoteNsm.testPrivateDynamic();
+  RemoteNsm.testPublicDynamic();
+}
diff --git a/tests/language_2/inference_update_2/no_such_method_restriction_stack_trace_lib1.dart b/tests/language_2/inference_update_2/no_such_method_restriction_stack_trace_lib1.dart
new file mode 100644
index 0000000..1b981e4
--- /dev/null
+++ b/tests/language_2/inference_update_2/no_such_method_restriction_stack_trace_lib1.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Library used by 'no_such_method_restriction_stack_trace_test.dart'
+
+// @dart=2.9
+
+import 'no_such_method_restriction_stack_trace_lib2.dart';
+
+class Test extends Nsm implements Interface {}
diff --git a/tests/language_2/inference_update_2/no_such_method_restriction_stack_trace_lib2.dart b/tests/language_2/inference_update_2/no_such_method_restriction_stack_trace_lib2.dart
new file mode 100644
index 0000000..a6d6c41
--- /dev/null
+++ b/tests/language_2/inference_update_2/no_such_method_restriction_stack_trace_lib2.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Library used by 'no_such_method_restriction_stack_trace_test.dart'
+
+// @dart=2.9
+
+import 'no_such_method_restriction_stack_trace_lib2.dart';
+
+class Nsm {
+  @override
+  noSuchMethod(Invocation invocation) {}
+}
+
+class Interface {
+  void _privateMethod() {}
+}
+
+void callPrivateMethod(Interface x) {
+  x._privateMethod();
+}
diff --git a/tests/language_2/inference_update_2/no_such_method_restriction_stack_trace_test.dart b/tests/language_2/inference_update_2/no_such_method_restriction_stack_trace_test.dart
new file mode 100644
index 0000000..e1fb5a3
--- /dev/null
+++ b/tests/language_2/inference_update_2/no_such_method_restriction_stack_trace_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2022, 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.
+
+// Tests that when a noSuchMethod forwarder throws an exception due to the fact
+// that the forwarding stub is for a private member of another library, the
+// resulting stack trace points to the class for which the noSuchMethod
+// forwarder was created.
+
+// @dart=2.9
+
+import 'package:expect/expect.dart';
+
+import 'no_such_method_restriction_stack_trace_lib1.dart';
+import 'no_such_method_restriction_stack_trace_lib2.dart';
+
+main() {
+  try {
+    callPrivateMethod(Test());
+  } on NoSuchMethodError catch (e, st) {
+    var stackString = st.toString();
+    if (stackString.contains('.js:') || !stackString.contains('.dart')) {
+      // Obfuscated stacktrace.  We don't expect to be able to resolve Dart
+      // files from this stack trace, so just let the test pass.
+      //
+      // Note: it's not sufficient to check for the absence of `.dart` in the
+      // stacktrace, because obfuscated Javascript stacktraces often contain
+      // `self.dartMainRunner`.
+    } else {
+      Expect.contains(
+          'no_such_method_restriction_stack_trace_lib1.dart', stackString);
+    }
+  }
+}
diff --git a/tests/language_2/parameter/initializer2_test.dart b/tests/language_2/parameter/initializer2_test.dart
index 53941bf..0a41acc 100644
--- a/tests/language_2/parameter/initializer2_test.dart
+++ b/tests/language_2/parameter/initializer2_test.dart
@@ -6,7 +6,7 @@
 
 import "package:expect/expect.dart";
 
-// Test Parameter Intializer.
+// Test Parameter Initializer.
 
 class ParameterInitializer2Test {
   static testMain() {
diff --git a/tests/language_2/record_literal_problems_test.dart b/tests/language_2/record_literal_problems_test.dart
new file mode 100644
index 0000000..66da8f2
--- /dev/null
+++ b/tests/language_2/record_literal_problems_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2022, 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
+
+// SharedOptions=--enable-experiment=records
+
+main() {
+  var r1 = const (42);
+  //             ^
+  // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+  // [cfe] This requires the experimental 'records' language feature to be enabled.
+  //                ^
+  // [analyzer] SYNTACTIC_ERROR.RECORD_LITERAL_ONE_POSITIONAL_NO_TRAILING_COMMA
+  // [cfe] Record literal with one field requires a trailing comma.
+
+  var r2 = const ();
+  //             ^
+  // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+  // [cfe] This requires the experimental 'records' language feature to be enabled.
+  //              ^
+  // [analyzer] SYNTACTIC_ERROR.RECORD_LITERAL_EMPTY
+  // [cfe] Record literal can't be empty.
+}
diff --git a/tests/language_2/record_literal_test.dart b/tests/language_2/record_literal_test.dart
index 20f72b5..4441b55 100644
--- a/tests/language_2/record_literal_test.dart
+++ b/tests/language_2/record_literal_test.dart
@@ -41,4 +41,23 @@
   // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
   // [cfe] This requires the experimental 'records' language feature to be enabled.
   print(record5);
+
+  // 1 record entry with trailing comma.
+  var record6 = (42, );
+  //            ^
+  // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+  // [cfe] This requires the experimental 'records' language feature to be enabled.
+  print(record6);
+
+  // Const records.
+  var record7 = const (42, );
+  //                  ^
+  // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+  // [cfe] This requires the experimental 'records' language feature to be enabled.
+  print(record7);
+  var record8 = const (42, foo: "bar");
+  //                  ^
+  // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+  // [cfe] This requires the experimental 'records' language feature to be enabled.
+  print(record8);
 }
diff --git a/tests/language_2/record_type_problems_test.dart b/tests/language_2/record_type_problems_test.dart
new file mode 100644
index 0000000..70d081f
--- /dev/null
+++ b/tests/language_2/record_type_problems_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2022, 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
+
+// SharedOptions=--enable-experiment=records
+
+main() {
+  (int, int, {/*missing*/}) r1 = (1, 2);
+//^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the experimental 'records' language feature to be enabled.
+//                       ^
+// [analyzer] SYNTACTIC_ERROR.EMPTY_RECORD_TYPE_NAMED_FIELDS_LIST
+// [cfe] Record type named fields list can't be empty.
+//                               ^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the experimental 'records' language feature to be enabled.
+
+  (int /* missing trailing comma */ ) r2 = (1, );
+//^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the experimental 'records' language feature to be enabled.
+//                                  ^
+// [analyzer] SYNTACTIC_ERROR.RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA
+// [cfe] Record type with one entry requires a trailing comma.
+//                                         ^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the experimental 'records' language feature to be enabled.
+
+  () emptyRecord = Record.empty;
+//^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the experimental 'records' language feature to be enabled.
+  //               ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+  // [cfe] Undefined name 'Record'.
+  print(emptyRecord);
+}
diff --git a/tests/language_2/record_type_test.dart b/tests/language_2/record_type_test.dart
index b1aae07..e60f48f 100644
--- a/tests/language_2/record_type_test.dart
+++ b/tests/language_2/record_type_test.dart
@@ -116,6 +116,24 @@
   //                    ^
   // [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
   // [cfe] This requires the experimental 'records' language feature to be enabled.
+
+  (int, ) oneElementRecord = (1, );
+//^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the experimental 'records' language feature to be enabled.
+//                           ^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the experimental 'records' language feature to be enabled.
+  print(oneElementRecord);
+
+  ({int ok}) oneElementNamedRecord = (ok: 1);
+//^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the experimental 'records' language feature to be enabled.
+//                                   ^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the experimental 'records' language feature to be enabled.
+  print(oneElementNamedRecord);
 }
 
 (int, T) f1<T>(T t) {
diff --git a/tests/lib/analysis_options.yaml b/tests/lib/analysis_options.yaml
deleted file mode 100644
index 0720d0e..0000000
--- a/tests/lib/analysis_options.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-analyzer:
-  enable-experiment:
-  - non-nullable
\ No newline at end of file
diff --git a/tests/lib/async/event_helper.dart b/tests/lib/async/event_helper.dart
index 6699366..58cf057 100644
--- a/tests/lib/async/event_helper.dart
+++ b/tests/lib/async/event_helper.dart
@@ -154,7 +154,7 @@
   late StreamSubscription subscription;
   bool cancelOnError = false;
 
-  CaptureEvents(Stream stream, {bool cancelOnError: false}) {
+  CaptureEvents(Stream stream, {bool cancelOnError = false}) {
     this.cancelOnError = cancelOnError;
     subscription = stream.listen(add,
         onError: addError, onDone: close, cancelOnError: cancelOnError);
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index 8fc947b..7723e79 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -910,7 +910,7 @@
   var cleanups = new List.filled(3, false);
   asyncStart();
   asyncStart();
-  runZoned(() {
+  runZonedGuarded(() {
     Future.wait(
         new Iterable.generate(5, (i) {
           if (i != 3) return new Future.delayed(cms * (i + 1), () => i);
@@ -920,7 +920,7 @@
       cleanups[index] = true;
       if (cleanups.every((x) => x)) asyncEnd();
     });
-  }, onError: (e, s) {
+  }, (e, s) {
     asyncEnd();
   });
 }
diff --git a/tests/lib/async/run_zoned9_test.dart b/tests/lib/async/run_zoned9_test.dart
index a42b8df..bc9aec9 100644
--- a/tests/lib/async/run_zoned9_test.dart
+++ b/tests/lib/async/run_zoned9_test.dart
@@ -8,14 +8,14 @@
 
 main() {
   asyncStart();
-  // Ensure that `runZoned`'s onError handles synchronous errors but delegates
-  // to the next runZoned when the handler returns false.
+  // Ensure that `runZonedGuarded`'s onError handles synchronous errors but
+  // delegates to the next runZoned when the handler returns false.
   bool sawInnerHandler = false;
   try {
     runZonedGuarded(() {
-      runZoned(() {
+      runZonedGuarded(() {
         throw 0;
-      }, onError: (e, s) {
+      }, (e, s) {
         Expect.equals(0, e);
         sawInnerHandler = true;
         throw e;
diff --git a/tests/lib/async/stream_state_helper.dart b/tests/lib/async/stream_state_helper.dart
index 5d0471d..4421075 100644
--- a/tests/lib/async/stream_state_helper.dart
+++ b/tests/lib/async/stream_state_helper.dart
@@ -61,7 +61,7 @@
   int _subscriptionIdCounter = 0;
   Function? _onComplete;
 
-  StreamProtocolTest.broadcast({bool sync: false})
+  StreamProtocolTest.broadcast({bool sync = false})
       : isBroadcast = true,
         isAsBroadcast = false {
     _controller = new StreamController.broadcast(
@@ -72,7 +72,7 @@
     });
   }
 
-  StreamProtocolTest({bool sync: false})
+  StreamProtocolTest({bool sync = false})
       : isBroadcast = false,
         isAsBroadcast = false {
     _controller = new StreamController(
@@ -87,7 +87,7 @@
     });
   }
 
-  StreamProtocolTest.asBroadcast({bool sync: false})
+  StreamProtocolTest.asBroadcast({bool sync = false})
       : isBroadcast = false,
         isAsBroadcast = true {
     _controller = new StreamController(
@@ -116,7 +116,7 @@
     _controller.close();
   }
 
-  SubscriptionProtocolTest listen({bool cancelOnError: false}) {
+  SubscriptionProtocolTest listen({bool cancelOnError = false}) {
     int subscriptionId = _subscriptionIdCounter++;
 
     StreamSubscription subscription = _controllerStream.listen((var data) {
diff --git a/tests/lib/html/audiocontext_test.dart b/tests/lib/html/audiocontext_test.dart
index a091790..9f190dc 100644
--- a/tests/lib/html/audiocontext_test.dart
+++ b/tests/lib/html/audiocontext_test.dart
@@ -102,7 +102,7 @@
         final audioSourceUrl = "/root_dart/tests/lib/html/small.mp3";
 
         Future<void> requestAudioDecode(
-            {bool triggerDecodeError: false,
+            {bool triggerDecodeError = false,
             DecodeSuccessCallback? successCallback,
             DecodeErrorCallback? errorCallback}) async {
           HttpRequest audioRequest = HttpRequest();
diff --git a/tests/lib/isolate/unresolved_ports_test.dart b/tests/lib/isolate/unresolved_ports_test.dart
index 9ac7995..9bda019 100644
--- a/tests/lib/isolate/unresolved_ports_test.dart
+++ b/tests/lib/isolate/unresolved_ports_test.dart
@@ -53,7 +53,7 @@
   return port;
 }
 
-baseTest({bool failForNegativeTest: false}) {
+baseTest({bool failForNegativeTest = false}) {
   // Message chain with unresolved ports
   ReceivePort port = new ReceivePort();
   asyncStart();
diff --git a/tests/lib/js/static_interop_test/mock/extension_conflict_test.dart b/tests/lib/js/static_interop_test/mock/extension_conflict_test.dart
new file mode 100644
index 0000000..9008360
--- /dev/null
+++ b/tests/lib/js/static_interop_test/mock/extension_conflict_test.dart
@@ -0,0 +1,178 @@
+// Copyright (c) 2022, 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 that `createStaticInteropMock` checks for extension member conflicts.
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+class EmptyDart {}
+
+@JS()
+@staticInterop
+class Method {}
+
+extension on Method {
+  external void member();
+}
+
+@JS()
+@staticInterop
+class Getter {}
+
+extension NamedExtension on Getter {
+  external int get member;
+}
+
+@JS()
+@staticInterop
+class Field {}
+
+extension on Field {
+  external final String member;
+}
+
+@JS()
+@staticInterop
+class ExtendsImplementsConflict extends Method implements Getter {}
+
+@JS()
+@staticInterop
+class ImplementsConflict implements Method, Getter {}
+
+@JS()
+@staticInterop
+class ManyConflicts extends Method implements Getter, Field {}
+
+@JS()
+@staticInterop
+class Override implements Method {}
+
+extension on Override {
+  external int member();
+}
+
+@JS()
+@staticInterop
+class OverrideOneConflictButNotAll implements Override, Getter {}
+
+@JS()
+@staticInterop
+class ConflictThroughInheritance implements OverrideOneConflictButNotAll {}
+
+@JS()
+@staticInterop
+class ResolveThroughOverride implements ConflictThroughInheritance {}
+
+extension on ResolveThroughOverride {
+  external int member;
+}
+
+class ResolveThroughOverrideDart {
+  int member = throw '';
+}
+
+@JS()
+@staticInterop
+class Setter {}
+
+extension on Setter {
+  external set member(int val);
+}
+
+@JS()
+@staticInterop
+class NoConflictDueToSubtype implements Override, Method {}
+
+class NoConflictDueToSubtypeDart {
+  int member() => throw '';
+}
+
+@JS()
+@staticInterop
+class GetterSetterConflict implements Setter, Getter {}
+
+@JS()
+@staticInterop
+class GetterSetterSameExtension {}
+
+extension on GetterSetterSameExtension {
+  external int get member;
+  external set member(int val);
+}
+
+class GetterSetterSameExtensionDart extends ResolveThroughOverrideDart {}
+
+@JS()
+@staticInterop
+class GetterSetterMethodConflict implements GetterSetterSameExtension, Method {}
+
+@JS()
+@staticInterop
+class NonExternal {}
+
+extension on NonExternal {
+  int get member => throw '';
+}
+
+@JS()
+@staticInterop
+class ExternalNonExternal implements NonExternal, GetterSetterSameExtension {}
+
+class ExternalNonExternalDart extends ResolveThroughOverrideDart {}
+
+void main() {
+  // Test name conflicts between extended and implemented members.
+  createStaticInteropMock<ExtendsImplementsConflict, EmptyDart>(
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Method.unnamed'.
+      EmptyDart());
+  // Test name conflicts between implemented members.
+  createStaticInteropMock<ImplementsConflict, EmptyDart>(EmptyDart());
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Method.unnamed'.
+
+  // Test multiple name conflicts.
+  createStaticInteropMock<ManyConflicts, EmptyDart>(EmptyDart());
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Field.unnamed', 'Getter.NamedExtension', 'Method.unnamed'.
+
+  // Test name conflicts where one definition is overridden, but there is still
+  // a name conflict between the other two.
+  createStaticInteropMock<OverrideOneConflictButNotAll, EmptyDart>(
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Override.unnamed'.
+      EmptyDart());
+  // Test case where if we inherit a class with a conflict, the conflict still
+  // exists.
+  createStaticInteropMock<ConflictThroughInheritance, EmptyDart>(
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Override.unnamed'.
+      EmptyDart());
+  // Test case where name conflicts are resolved using derived class.
+  createStaticInteropMock<ResolveThroughOverride, ResolveThroughOverrideDart>(
+      ResolveThroughOverrideDart());
+  // Test case where you inherit two classes with the same member name but they
+  // have a subtype relation, so there is no conflict.
+  createStaticInteropMock<NoConflictDueToSubtype, NoConflictDueToSubtypeDart>(
+      NoConflictDueToSubtypeDart());
+  // Test conflict where getter and setter collide when they are in different
+  // extensions.
+  createStaticInteropMock<GetterSetterConflict, EmptyDart>(EmptyDart());
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Setter.unnamed'.
+
+  // Test no conflict where getter and setter are on the same extension.
+  createStaticInteropMock<GetterSetterSameExtension,
+      GetterSetterSameExtensionDart>(GetterSetterSameExtensionDart());
+  // Test conflict where getter and setter are in one extension, but there is
+  // a conflict with another extension.
+  createStaticInteropMock<GetterSetterMethodConflict, EmptyDart>(EmptyDart());
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'GetterSetterSameExtension.unnamed', 'Method.unnamed'.
+
+  // Test no conflict between external and non-external members.
+  createStaticInteropMock<ExternalNonExternal, ExternalNonExternalDart>(
+      ExternalNonExternalDart());
+}
diff --git a/tests/lib/js/static_interop_test/mock/functional_test.dart b/tests/lib/js/static_interop_test/mock/functional_test.dart
new file mode 100644
index 0000000..a43df9a
--- /dev/null
+++ b/tests/lib/js/static_interop_test/mock/functional_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, 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 'functional_test_lib.dart';
+
+void main() {
+  test();
+}
diff --git a/tests/lib/js/static_interop_test/mock/functional_test_lib.dart b/tests/lib/js/static_interop_test/mock/functional_test_lib.dart
new file mode 100644
index 0000000..69d5ec9
--- /dev/null
+++ b/tests/lib/js/static_interop_test/mock/functional_test_lib.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2022, 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 basic functionality of `createStaticInteropMock`. Basic methods, fields
+// (final and not), getters, and setters are tested along with potential
+// renames.
+
+import 'package:expect/minitest.dart';
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+@JS()
+@staticInterop
+class Methods {}
+
+extension on Methods {
+  external int add(int a, int b);
+  // Sanity-check that non-externals are unaffected.
+  int nonExternal() => 0;
+  @JS('_rename')
+  external int rename();
+  external int optionalAdd(int a, int b, [int c = 0, int? d]);
+}
+
+class MethodsDart {
+  int add(int a, int b) => a + b;
+  int nonExternal() => 1;
+  int rename() => 1;
+  int optionalAdd(int a, int b, [int? c, int? d]) =>
+      a + b + (c ?? 0) + (d ?? 0);
+}
+
+@JS()
+@staticInterop
+class Fields {}
+
+extension on Fields {
+  external int field;
+  external final int finalField;
+  @JS('_renamedField')
+  external int renamedField;
+  @JS('_renamedFinalField')
+  external final int renamedFinalField;
+}
+
+class FieldsDart {
+  int field = 1;
+  int finalField = 1;
+  int renamedField = 1;
+  final int renamedFinalField = 1;
+}
+
+@JS()
+@staticInterop
+class GetSet {}
+
+extension on GetSet {
+  external int get getSet;
+  external set getSet(int val);
+  @JS('_renamedGetSet')
+  external int get renamedGetSet;
+  @JS('_renamedGetSet')
+  external set renamedGetSet(int val);
+  @JS('_sameNameDifferentRenameGet')
+  external int get sameNameDifferentRename;
+  @JS('_sameNameDifferentRenameSet')
+  external set sameNameDifferentRename(int val);
+  @JS('_differentNameSameRename')
+  external int get differentNameSameRenameGet;
+  @JS('_differentNameSameRename')
+  external set differentNameSameRenameSet(int val);
+}
+
+class GetSetDart {
+  int getSet = 1;
+  int renamedGetSet = 1;
+  int sameNameDifferentRename = 1;
+  int differentNameSameRenameGet = 1;
+  int differentNameSameRenameSet = 1;
+}
+
+void test([Object? proto]) {
+  var jsMethods =
+      createStaticInteropMock<Methods, MethodsDart>(MethodsDart(), proto);
+  expect(jsMethods.add(1, 1), 2);
+  expect(jsMethods.nonExternal(), 0);
+  expect(jsMethods.rename(), 1);
+  expect(jsMethods.optionalAdd(1, 1), 2);
+  expect(jsMethods.optionalAdd(1, 1, 1), 3);
+  expect(jsMethods.optionalAdd(1, 1, 1, 1), 4);
+  var dartFields = FieldsDart();
+  var jsFields = createStaticInteropMock<Fields, FieldsDart>(dartFields, proto);
+  expect(jsFields.field, 1);
+  expect(jsFields.finalField, 1);
+  expect(jsFields.renamedField, 1);
+  expect(jsFields.renamedFinalField, 1);
+  // Modify the JS mock and check for updates in the Dart mock.
+  jsFields.field = 2;
+  jsFields.renamedField = 2;
+  expect(dartFields.field, 2);
+  expect(dartFields.renamedField, 2);
+  // Modify the Dart mock and check for updates in the JS mock.
+  dartFields.field = 3;
+  dartFields.finalField = 3;
+  dartFields.renamedField = 3;
+  expect(jsFields.field, 3);
+  expect(jsFields.finalField, 3);
+  expect(jsFields.renamedField, 3);
+  var dartGetSet = GetSetDart();
+  var jsGetSet = createStaticInteropMock<GetSet, GetSetDart>(dartGetSet, proto);
+  expect(jsGetSet.getSet, 1);
+  expect(jsGetSet.renamedGetSet, 1);
+  expect(jsGetSet.sameNameDifferentRename, 1);
+  expect(jsGetSet.differentNameSameRenameGet, 1);
+  // Modify the JS mock and check for updates in the Dart mock.
+  jsGetSet.getSet = 2;
+  jsGetSet.renamedGetSet = 2;
+  jsGetSet.sameNameDifferentRename = 2;
+  jsGetSet.differentNameSameRenameSet = 2;
+  expect(dartGetSet.getSet, 2);
+  expect(dartGetSet.renamedGetSet, 2);
+  expect(dartGetSet.sameNameDifferentRename, 2);
+  expect(dartGetSet.differentNameSameRenameGet, 1);
+  expect(dartGetSet.differentNameSameRenameSet, 2);
+  // Modify the Dart mock and check for updates in the JS mock.
+  dartGetSet.getSet = 3;
+  dartGetSet.renamedGetSet = 3;
+  dartGetSet.sameNameDifferentRename = 3;
+  // Use different values to disambiguate.
+  dartGetSet.differentNameSameRenameGet = 3;
+  dartGetSet.differentNameSameRenameSet = 4;
+  expect(jsGetSet.getSet, 3);
+  expect(jsGetSet.renamedGetSet, 3);
+  expect(jsGetSet.sameNameDifferentRename, 3);
+  expect(jsGetSet.differentNameSameRenameGet, 3);
+}
diff --git a/tests/lib/js/static_interop_test/mock/incorrect_type_arguments_test.dart b/tests/lib/js/static_interop_test/mock/incorrect_type_arguments_test.dart
new file mode 100644
index 0000000..e4729dd
--- /dev/null
+++ b/tests/lib/js/static_interop_test/mock/incorrect_type_arguments_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2022, 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 that `createStaticInteropMock` checks its type arguments.
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+@JS()
+class Js {
+  external Js();
+}
+
+@JS()
+@anonymous
+class Anonymous {
+  external factory Anonymous();
+}
+
+@JS()
+@staticInterop
+class StaticInterop {
+  external factory StaticInterop();
+}
+
+class Dart {}
+
+void main() {
+  createStaticInteropMock<StaticInterop, Dart>(Dart());
+  createStaticInteropMock<Dart, StaticInterop>(StaticInterop());
+//^
+// [web] First type argument 'Dart' is not a `@staticInterop` type.
+// [web] Second type argument 'StaticInterop' is not a Dart interface type.
+  createStaticInteropMock<Dart, Js>(Js());
+//^
+// [web] First type argument 'Dart' is not a `@staticInterop` type.
+// [web] Second type argument 'Js' is not a Dart interface type.
+  createStaticInteropMock<Dart, Anonymous>(Anonymous());
+//^
+// [web] First type argument 'Dart' is not a `@staticInterop` type.
+// [web] Second type argument 'Anonymous' is not a Dart interface type.
+  createStaticInteropMock<StaticInterop, void Function()>(() {});
+//^
+// [web] Second type argument 'void Function()' is not a Dart interface type.
+  createStaticInteropMock(Dart());
+//^
+// [web] First type argument 'dynamic' is not a `@staticInterop` type.
+}
diff --git a/tests/lib/js/static_interop_test/mock/inheritance_test.dart b/tests/lib/js/static_interop_test/mock/inheritance_test.dart
new file mode 100644
index 0000000..302d76f
--- /dev/null
+++ b/tests/lib/js/static_interop_test/mock/inheritance_test.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2022, 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.
+
+// Basic inheritance test where @staticInterop class inherits extension methods
+// which are then defined in the Dart class' inheritance chain, with some
+// overrides.
+
+import 'package:expect/minitest.dart';
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+@JS()
+@staticInterop
+class Extends {}
+
+extension on Extends {
+  external int extendsMethod(int val);
+  external int extendsField;
+  external final int extendsFinalField;
+  external int get getSet;
+  external set getSet(int val);
+}
+
+@JS()
+@staticInterop
+class Implements {}
+
+extension on Implements {
+  @JS('_implementsMethod')
+  external int implementsMethod(int val);
+  @JS('_implementsField')
+  external int implementsField;
+  @JS('_implementsFinalField')
+  external final int implementsFinalField;
+  @JS('_implementsGetter')
+  external int get implementsGetter;
+  @JS('_implementsSetter')
+  external set implementsSetter(int val);
+}
+
+@JS()
+@staticInterop
+class Inheritance extends Extends implements Implements {}
+
+extension on Inheritance {
+  external int method(int val);
+  external int field;
+  external final int finalField;
+  // Overrides
+  external int get getSet;
+  external set getSet(int val);
+}
+
+class ExtendsDart {
+  int extendsMethod(int val) => val;
+  int extendsField = 0;
+  final int extendsFinalField = 0;
+  int getSet = 0;
+}
+
+class ImplementsMixin {
+  int implementsMethod(int val) => val;
+  int implementsField = 1;
+  final int implementsFinalField = 1;
+  int _implementsGetSet = 1;
+  int get implementsGetter => _implementsGetSet;
+  set implementsSetter(int val) => _implementsGetSet = val;
+}
+
+class InheritanceDart extends ExtendsDart with ImplementsMixin {
+  int method(int val) => val;
+  int field = 2;
+  final int finalField = 2;
+  @override
+  int getSet = 2;
+}
+
+void main() {
+  var dartMock = InheritanceDart();
+  var jsMock = createStaticInteropMock<Inheritance, InheritanceDart>(dartMock);
+  expect(jsMock.extendsMethod(0), 0);
+  expect(jsMock.extendsField, 0);
+  jsMock.extendsField = 1;
+  expect(jsMock.extendsField, 1);
+  expect(jsMock.extendsFinalField, 0);
+
+  expect(jsMock.implementsMethod(1), 1);
+  expect(jsMock.implementsField, 1);
+  jsMock.implementsField = 2;
+  expect(jsMock.implementsField, 2);
+  expect(jsMock.implementsFinalField, 1);
+  expect(jsMock.implementsGetter, 1);
+  jsMock.implementsSetter = 2;
+  // Dart mock uses a field for this getter and setter, so it should change.
+  expect(jsMock.implementsGetter, 2);
+
+  expect(jsMock.method(2), 2);
+  expect(jsMock.field, 2);
+  jsMock.field = 3;
+  expect(jsMock.field, 3);
+  expect(jsMock.finalField, 2);
+  expect(jsMock.getSet, 2);
+  jsMock.getSet = 3;
+  expect(jsMock.getSet, 3);
+}
diff --git a/tests/lib/js/static_interop_test/mock/missing_overrides_test.dart b/tests/lib/js/static_interop_test/mock/missing_overrides_test.dart
new file mode 100644
index 0000000..6ff5958
--- /dev/null
+++ b/tests/lib/js/static_interop_test/mock/missing_overrides_test.dart
@@ -0,0 +1,183 @@
+// Copyright (c) 2022, 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 that `createStaticInteropMock` checks that there aren't any missing
+// overrides.
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+@JS()
+@staticInterop
+class StaticInterop {}
+
+extension on StaticInterop {
+  external int field;
+  external final int finalField;
+  external int get getSet;
+  external set getSet(int val);
+  external void method();
+
+  // We should ignore the non-external members for determining overrides.
+  int get nonExternalGetSet => throw '';
+  set nonExternalGetSet(int val) => throw '';
+  void nonExternalMethod() => throw '';
+}
+
+class CorrectDart {
+  int field = throw '';
+  final int finalField = throw '';
+  int get getSet => throw '';
+  set getSet(int val) => throw '';
+  void method() => throw '';
+}
+
+class DartStatic {
+  static int field = throw '';
+  final int finalField = throw '';
+  int get getSet => throw '';
+  set getSet(int val) => throw '';
+  void method() => throw '';
+}
+
+class DartUsingExtensions {
+  int field = throw '';
+  final int finalField = throw '';
+  int get getSet => throw '';
+  set getSet(int val) => throw '';
+}
+
+extension on DartUsingExtensions {
+  void method() => throw '';
+}
+
+class DartFactory {
+  DartFactory();
+  factory DartFactory.finalField() => DartFactory();
+  int field = throw '';
+  int get getSet => throw '';
+  set getSet(int val) => throw '';
+  void method() => throw '';
+}
+
+class DartFinal {
+  final int field = throw '';
+  final int finalField = throw '';
+  int get getSet => throw '';
+  set getSet(int val) => throw '';
+  void method() => throw '';
+}
+
+class DartNoGet {
+  int field = throw '';
+  final int finalField = throw '';
+  set getSet(int val) => throw '';
+  void method() => throw '';
+}
+
+class DartNoSet {
+  int field = throw '';
+  final int finalField = throw '';
+  int get getSet => throw '';
+  void method() => throw '';
+}
+
+class DartNoMembers {}
+
+void main() {
+  createStaticInteropMock<StaticInterop, CorrectDart>(CorrectDart());
+  // Static members do not qualify as an override.
+  createStaticInteropMock<StaticInterop, DartStatic>(
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field', but Dart class 'DartStatic' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartStatic' does not have an overriding instance member.
+      DartStatic());
+  // Extension members do not qualify as an override.
+  createStaticInteropMock<StaticInterop, DartUsingExtensions>(
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'method', but Dart class 'DartUsingExtensions' does not have an overriding instance member.
+      DartUsingExtensions());
+  // Factory members with the same name do not qualify as an override.
+  createStaticInteropMock<StaticInterop, DartFactory>(
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'finalField', but Dart class 'DartFactory' does not have an overriding instance member.
+      DartFactory());
+  // Final fields can not override a setter.
+  createStaticInteropMock<StaticInterop, DartFinal>(DartFinal());
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartFinal' does not have an overriding instance member.
+  createStaticInteropMock<StaticInterop, DartNoGet>(DartNoGet());
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet', but Dart class 'DartNoGet' does not have an overriding instance member.
+
+  // Test that getters are treated differently from setters even though they
+  // share the same name.
+  createStaticInteropMock<StaticInterop, DartNoSet>(DartNoSet());
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet=', but Dart class 'DartNoSet' does not have an overriding instance member.
+
+  // Test multiple missing members.
+  createStaticInteropMock<StaticInterop, DartNoMembers>(
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field', but Dart class 'DartNoMembers' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartNoMembers' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'finalField', but Dart class 'DartNoMembers' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet', but Dart class 'DartNoMembers' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet=', but Dart class 'DartNoMembers' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'method', but Dart class 'DartNoMembers' does not have an overriding instance member.
+      DartNoMembers());
+
+  testUsingInheritanceAndMixins();
+}
+
+// The following should classes should not contain any override errors, as they
+// have all the necessary members.
+class DartWithInheritance extends DartNoSet {
+  set getSet(int val) => throw '';
+}
+
+class DartWithMixins with CorrectDart {}
+
+mixin MixinSet {
+  set getSet(int val) => throw '';
+}
+
+class DartWithMixinsAndInheritance extends DartNoSet with MixinSet {}
+
+@JS()
+@staticInterop
+class BaseStaticInterop {}
+
+extension on BaseStaticInterop {
+  external void baseMethod();
+}
+
+@JS()
+@staticInterop
+class StaticInteropWithInheritance extends BaseStaticInterop
+    implements StaticInterop {}
+
+class DartImplementingInteropInheritance extends DartWithMixinsAndInheritance {
+  void baseMethod() => throw '';
+}
+
+void testUsingInheritanceAndMixins() {
+  // Test where Dart class implements using inherited members.
+  createStaticInteropMock<StaticInterop, DartWithInheritance>(
+      DartWithInheritance());
+  // Test where Dart class implements using mixed-in members.
+  createStaticInteropMock<StaticInterop, DartWithMixins>(DartWithMixins());
+  // Test where Dart class implements using inherited and mixed-in members.
+  createStaticInteropMock<StaticInterop, DartWithMixinsAndInheritance>(
+      DartWithMixinsAndInheritance());
+  // Missing inherited method, expect an error.
+  createStaticInteropMock<
+//^
+// [web] `@staticInterop` class 'StaticInteropWithInheritance' has external extension member 'baseMethod', but Dart class 'DartWithMixinsAndInheritance' does not have an overriding instance member.
+      StaticInteropWithInheritance,
+      DartWithMixinsAndInheritance>(DartWithMixinsAndInheritance());
+  // Added missing method, should pass.
+  createStaticInteropMock<StaticInteropWithInheritance,
+      DartImplementingInteropInheritance>(DartImplementingInteropInheritance());
+}
diff --git a/tests/lib/js/static_interop_test/mock/mockito_test.dart b/tests/lib/js/static_interop_test/mock/mockito_test.dart
new file mode 100644
index 0000000..24004e1
--- /dev/null
+++ b/tests/lib/js/static_interop_test/mock/mockito_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2022, 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 that using `createStaticInteropMock` with pkg:mockito works as expected.
+
+import 'package:expect/minitest.dart';
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+import 'package:mockito/mockito.dart';
+
+@JS()
+@staticInterop
+class StaticInterop {}
+
+extension on StaticInterop {
+  // We use nullable types here as mockito requires some additional complexity
+  // or code generation to safely mock non-nullables.
+  // https://github.com/dart-lang/mockito/blob/master/NULL_SAFETY_README.md
+  external int? method(int? val);
+  external int? field;
+  external final int? finalField;
+  external int? get getSet;
+  external set getSet(int? val);
+}
+
+class Dart {
+  int? method(int? val) => throw '';
+  int? field = throw '';
+  final int? finalField = throw '';
+  int? get getSet => throw '';
+  set getSet(int? val) => throw '';
+}
+
+// Have the mock class implement the class interface you defined to mock the
+// @staticInterop interface.
+class DartMock extends Mock implements Dart {}
+
+void main() {
+  // Write expectations on the Dart Mock object, not the JS mock object.
+  var dartMock = DartMock();
+  var jsMock = createStaticInteropMock<StaticInterop, DartMock>(dartMock);
+  when(dartMock.method(0)).thenReturn(1);
+  when(dartMock.field).thenReturn(1);
+  when(dartMock.finalField).thenReturn(1);
+  when(dartMock.getSet).thenReturn(1);
+  expect(jsMock.method(0), 1);
+  expect(jsMock.field, 1);
+  expect(jsMock.finalField, 1);
+  expect(jsMock.getSet, 1);
+  jsMock.getSet = 1;
+  verify(dartMock.getSet = 1);
+}
diff --git a/tests/lib/js/static_interop_test/mock/proto_test.dart b/tests/lib/js/static_interop_test/mock/proto_test.dart
new file mode 100644
index 0000000..647cd58
--- /dev/null
+++ b/tests/lib/js/static_interop_test/mock/proto_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2022, 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 that providing a proto object to createStaticInteropMock does not break
+// any functionality, and allows instanceof/is checks to pass.
+
+@JS()
+library proto_test;
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+import 'functional_test_lib.dart' as functional_test;
+
+@JS('Window.prototype')
+external Object get windowProto;
+
+@JS('Window')
+external Object get windowType;
+
+@JS()
+@staticInterop
+class JSWindow {}
+
+class DartWindow {}
+
+void main() {
+  // Test that everything still works the same.
+  functional_test.test(windowProto);
+  // Test instanceof/is checks.
+  var jsMock =
+      createStaticInteropMock<JSWindow, DartWindow>(DartWindow(), windowProto);
+  expect(jsMock is Window, true);
+  expect(instanceof(jsMock, windowType), true);
+}
diff --git a/tests/lib/js/static_interop_test/mock/subtype_overrides_test.dart b/tests/lib/js/static_interop_test/mock/subtype_overrides_test.dart
new file mode 100644
index 0000000..ed2b98f
--- /dev/null
+++ b/tests/lib/js/static_interop_test/mock/subtype_overrides_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2022, 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 that `createStaticInteropMock` checks that overrides are subtypes.
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+// Set up a simple type hierarchy.
+class A {
+  const A();
+}
+
+class B extends A {
+  const B();
+}
+
+class C extends B {
+  const C();
+}
+
+@JS()
+@staticInterop
+class SimpleInterop {}
+
+extension SimpleInteropExtension on SimpleInterop {
+  external B field;
+  external final B finalField;
+  external B get getSetNum;
+  external set getSetInt(B val);
+  external B method(B b);
+}
+
+// Implement using the exact same types.
+class SimpleDart {
+  B field = throw '';
+  final B finalField = throw '';
+  B get getSetNum => throw '';
+  set getSetInt(B val) => throw '';
+  B method(B b) => throw '';
+}
+
+// Implement using subtypes.
+class SubtypeSimpleDart {
+  B field = throw '';
+  final C finalField = throw '';
+  C get getSetNum => throw '';
+  set getSetInt(A val) => throw '';
+  C method(A a) => throw '';
+}
+
+// Implement using supertypes (which shouldn't work).
+class SupertypeSimpleDart {
+  A field = throw '';
+  final A finalField = throw '';
+  A get getSetNum => throw '';
+  set getSetInt(C val) => throw '';
+  A method(C c) => throw '';
+}
+
+@JS()
+@staticInterop
+class ComplexAndOptionalInteropMethods {}
+
+extension ComplexAndOptionalInteropMethodsExtension
+    on ComplexAndOptionalInteropMethods {
+  external B Function(B _) nestedTypes(List<B> arg1, Map<Set<B>, B> arg2);
+  external B optional(B b, [B? b2]);
+  external B optionalSubtype(B b, [B b2 = const B()]);
+}
+
+class ComplexAndOptionalDart {
+  C Function(A _) nestedTypes(List<B> arg1, Map<Set<B>, B> arg2) => throw '';
+  B optional(B b, [B? b2]) => throw '';
+  C optionalSubtype(A a, [A? a2]) => throw '';
+}
+
+class IncorrectComplexAndOptionalDart {
+  // List type is wrong.
+  B Function(B _) nestedTypes(List<List<B>> arg1, Map<Set<B>, B> arg2) =>
+      throw '';
+  // Second argument is not optional, this is invalid.
+  B optional(B b, B? b2) => throw '';
+  // Third argument is supposed to be a supertype, not a subtype.
+  B optionalSubtype(B b, [C c = const C()]) => throw '';
+}
+
+void main() {
+  createStaticInteropMock<SimpleInterop, SimpleDart>(SimpleDart());
+  createStaticInteropMock<SimpleInterop, SubtypeSimpleDart>(
+      SubtypeSimpleDart());
+  createStaticInteropMock<SimpleInterop, SupertypeSimpleDart>(
+//^
+// [web] Dart class member 'SupertypeSimpleDart.field' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.field' with type 'B Function()'.
+// [web] Dart class member 'SupertypeSimpleDart.finalField' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.finalField' with type 'B Function()'.
+// [web] Dart class member 'SupertypeSimpleDart.getSetInt=' with type 'void Function(C)' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.getSetInt=' with type 'void Function(B)'.
+// [web] Dart class member 'SupertypeSimpleDart.getSetNum' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.getSetNum' with type 'B Function()'.
+// [web] Dart class member 'SupertypeSimpleDart.method' with type 'A Function(C)' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.method' with type 'B Function(B)'.
+      SupertypeSimpleDart());
+  createStaticInteropMock<ComplexAndOptionalInteropMethods,
+      ComplexAndOptionalDart>(ComplexAndOptionalDart());
+  createStaticInteropMock<
+//^
+// [web] Dart class member 'IncorrectComplexAndOptionalDart.nestedTypes' with type 'B Function(B) Function(List<List<B>>, Map<Set<B>, B>)' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.nestedTypes' with type 'B Function(B) Function(List<B>, Map<Set<B>, B>)'.
+// [web] Dart class member 'IncorrectComplexAndOptionalDart.optional' with type 'B Function(B, B?)' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.optional' with type 'B Function(B, [B?])'.
+// [web] Dart class member 'IncorrectComplexAndOptionalDart.optionalSubtype' with type 'B Function(B, [C])' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.optionalSubtype' with type 'B Function(B, [B])'.
+      ComplexAndOptionalInteropMethods,
+      IncorrectComplexAndOptionalDart>(IncorrectComplexAndOptionalDart());
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index c68cbad..921086b 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -15,6 +15,7 @@
 js/js_util/javascriptobject_extensions_test: SkipByDesign # Uses dart:html.
 js/static_interop_test/constants_test: SkipByDesign # Uses dart:html.
 js/static_interop_test/futurevaluetype_test: SkipByDesign # Uses dart:html.
+js/static_interop_test/mock/proto_test: SkipByDesign # Uses dart:html.
 js/static_interop_test/supertype_transform_test: SkipByDesign # Uses dart:html.
 
 [ $runtime == dart_precompiled ]
diff --git a/tests/lib/mirrors/deferred_constraints_constants_test.dart b/tests/lib/mirrors/deferred_constraints_constants_test.dart
index 053bb81..35a5f7b 100644
--- a/tests/lib/mirrors/deferred_constraints_constants_test.dart
+++ b/tests/lib/mirrors/deferred_constraints_constants_test.dart
@@ -20,7 +20,7 @@
   */ //                 //# reference2: continued
 
 void f1(
-    {a:
+    {a =
   const lib.Const() //# default_argument1: compile-time error
   /* //                  //# default_argument1: continued
         499
@@ -28,7 +28,7 @@
     }) {}
 
 void f2(
-    {a:
+    {a =
   lib.constantInstance //# default_argument2: compile-time error
   /* //                        //# default_argument2: continued
         499
diff --git a/tests/lib/mirrors/delegate_class_test.dart b/tests/lib/mirrors/delegate_class_test.dart
index 83ee8f0..97140ae 100644
--- a/tests/lib/mirrors/delegate_class_test.dart
+++ b/tests/lib/mirrors/delegate_class_test.dart
@@ -10,7 +10,7 @@
 
 class C {
   static method(a, b, c) => "$a-$b-$c";
-  static methodWithNamed(a, {b: 'B', c}) => "$a-$b-$c";
+  static methodWithNamed(a, {b = 'B', c}) => "$a-$b-$c";
   static methodWithOpt(a, [b, c = 'C']) => "$a-$b-$c";
   static get getter => 'g';
   static set setter(x) {
diff --git a/tests/lib/mirrors/delegate_library_test.dart b/tests/lib/mirrors/delegate_library_test.dart
index a4cf432..a44c67c 100644
--- a/tests/lib/mirrors/delegate_library_test.dart
+++ b/tests/lib/mirrors/delegate_library_test.dart
@@ -9,7 +9,7 @@
 import 'package:expect/expect.dart';
 
 method(a, b, c) => "$a-$b-$c";
-methodWithNamed(a, {b: 'B', c}) => "$a-$b-$c";
+methodWithNamed(a, {b = 'B', c}) => "$a-$b-$c";
 methodWithOpt(a, [b, c = 'C']) => "$a-$b-$c";
 get getter => 'g';
 set setter(x) {
diff --git a/tests/lib/mirrors/delegate_test.dart b/tests/lib/mirrors/delegate_test.dart
index 4c63f28..0cd8ffa 100644
--- a/tests/lib/mirrors/delegate_test.dart
+++ b/tests/lib/mirrors/delegate_test.dart
@@ -10,7 +10,7 @@
 
 class C {
   method(a, b, c) => "$a-$b-$c";
-  methodWithNamed(a, {b: 'B', c}) => "$a-$b-$c";
+  methodWithNamed(a, {b = 'B', c}) => "$a-$b-$c";
   methodWithOpt(a, [b, c = 'C']) => "$a-$b-$c";
   get getter => 'g';
   set setter(x) {
diff --git a/tests/lib/mirrors/function_apply_mirrors_test.dart b/tests/lib/mirrors/function_apply_mirrors_test.dart
index 81d3b9e..c07c9f2 100644
--- a/tests/lib/mirrors/function_apply_mirrors_test.dart
+++ b/tests/lib/mirrors/function_apply_mirrors_test.dart
@@ -13,7 +13,7 @@
 
 import "package:expect/expect.dart";
 
-int foo({x: 499, y: 42}) => x + y;
+int foo({x = 499, y = 42}) => x + y;
 
 main() {
   Expect.equals(709, Function.apply(foo, [], {#y: 210}));
diff --git a/tests/lib/mirrors/invoke_closurization2_test.dart b/tests/lib/mirrors/invoke_closurization2_test.dart
index efbc7da..dec7357 100644
--- a/tests/lib/mirrors/invoke_closurization2_test.dart
+++ b/tests/lib/mirrors/invoke_closurization2_test.dart
@@ -34,7 +34,7 @@
   // matchAsPrefix matches signature from String.
   matchAsPrefix(x, [y = 0]) => "matchAsPrefix-$x,$y";
   // Matches signature from List
-  toList({growable: true}) => "toList-$growable";
+  toList({growable = true}) => "toList-$growable";
   // Same name as intercepted, but with named argument.
   toSet({named}) => "toSet-$named";
 }
diff --git a/tests/lib/mirrors/invoke_named_test.dart b/tests/lib/mirrors/invoke_named_test.dart
index 04d547b..3dfe4f9 100644
--- a/tests/lib/mirrors/invoke_named_test.dart
+++ b/tests/lib/mirrors/invoke_named_test.dart
@@ -15,16 +15,16 @@
 bool isDart2js = false;
 
 class C {
-  a(a, {b: 'B', c}) => "$a-$b-$c";
-  b({a: 'A', b, c}) => "$a-$b-$c";
+  a(a, {b = 'B', c}) => "$a-$b-$c";
+  b({a = 'A', b, c}) => "$a-$b-$c";
   c(a, [b, c = 'C']) => "$a-$b-$c";
   d([a, b = 'B', c = 'C']) => "$a-$b-$c";
   e(a, b, c) => "$a-$b-$c";
 }
 
 class D {
-  static a(a, {b: 'B', c}) => "$a-$b-$c";
-  static b({a: 'A', b, c}) => "$a-$b-$c";
+  static a(a, {b = 'B', c}) => "$a-$b-$c";
+  static b({a = 'A', b, c}) => "$a-$b-$c";
   static c(a, [b, c = 'C']) => "$a-$b-$c";
   static d([a, b = 'B', c = 'C']) => "$a-$b-$c";
   static e(a, b, c) => "$a-$b-$c";
@@ -32,15 +32,15 @@
 
 class E {
   var field;
-  E(a, {b: 'B', c}) : this.field = "$a-$b-$c";
-  E.b({a: 'A', b, c}) : this.field = "$a-$b-$c";
+  E(a, {b = 'B', c}) : this.field = "$a-$b-$c";
+  E.b({a = 'A', b, c}) : this.field = "$a-$b-$c";
   E.c(a, [b, c = 'C']) : this.field = "$a-$b-$c";
   E.d([a, b = 'B', c = 'C']) : this.field = "$a-$b-$c";
   E.e(a, b, c) : this.field = "$a-$b-$c";
 }
 
-a(a, {b: 'B', c}) => "$a-$b-$c";
-b({a: 'A', b, c}) => "$a-$b-$c";
+a(a, {b = 'B', c}) => "$a-$b-$c";
+b({a = 'A', b, c}) => "$a-$b-$c";
 c(a, [b, c = 'C']) => "$a-$b-$c";
 d([a, b = 'B', c = 'C']) => "$a-$b-$c";
 e(a, b, c) => "$a-$b-$c";
diff --git a/tests/lib/mirrors/mirrors_reader.dart b/tests/lib/mirrors/mirrors_reader.dart
index d3a0bde..158bbda 100644
--- a/tests/lib/mirrors/mirrors_reader.dart
+++ b/tests/lib/mirrors/mirrors_reader.dart
@@ -29,7 +29,7 @@
   List<ReadError> errors = <ReadError>[];
   List<Mirror> queue = <Mirror>[];
 
-  MirrorsReader({this.verbose: false, this.includeStackTrace: false});
+  MirrorsReader({this.verbose = false, this.includeStackTrace = false});
 
   void checkMirrorSystem(MirrorSystem mirrorSystem) {
     visitMirrorSystem(mirrorSystem);
diff --git a/tests/lib/mirrors/mirrors_reader_test.dart b/tests/lib/mirrors/mirrors_reader_test.dart
index 659c4e0..5835e0c 100644
--- a/tests/lib/mirrors/mirrors_reader_test.dart
+++ b/tests/lib/mirrors/mirrors_reader_test.dart
@@ -15,7 +15,7 @@
   final String mirrorSystemType;
 
   RuntimeMirrorsReader(MirrorSystem mirrorSystem,
-      {bool verbose: false, bool includeStackTrace: false})
+      {bool verbose = false, bool includeStackTrace = false})
       : this.mirrorSystem = mirrorSystem,
         this.mirrorSystemType = '${mirrorSystem.runtimeType}',
         super(verbose: verbose, includeStackTrace: includeStackTrace);
diff --git a/tests/lib/mirrors/parameter_abstract_test.dart b/tests/lib/mirrors/parameter_abstract_test.dart
index cf2bd25..30a9e4a 100644
--- a/tests/lib/mirrors/parameter_abstract_test.dart
+++ b/tests/lib/mirrors/parameter_abstract_test.dart
@@ -12,7 +12,7 @@
 const Z = 'Z';
 
 abstract class C {
-  foo1({@X int x: 1, @Y int y: 2, @Z int z: 3});
+  foo1({@X int x = 1, @Y int y = 2, @Z int z = 3});
 }
 
 main() {
diff --git a/tests/lib/mirrors/parameter_metadata_test.dart b/tests/lib/mirrors/parameter_metadata_test.dart
index 78e814f..2ac83a8 100644
--- a/tests/lib/mirrors/parameter_metadata_test.dart
+++ b/tests/lib/mirrors/parameter_metadata_test.dart
@@ -24,8 +24,8 @@
 
   baz(@m1 final int x, @m2 int y, @m3 final int z) {}
   qux(int x, [@m3 @m2 @m1 int y = 3 + 1]) {}
-  quux(int x, {String str: "foo"}) {}
-  corge({@m1 int x: 3 * 17, @m2 String str: "bar"}) {}
+  quux(int x, {String str = "foo"}) {}
+  corge({@m1 int x = 3 * 17, @m2 String str = "bar"}) {}
 
   set x(@m2 final value) {}
 }
diff --git a/tests/lib/mirrors/parameter_optional_order_test.dart b/tests/lib/mirrors/parameter_optional_order_test.dart
index a2fa3d4..ea2b490 100644
--- a/tests/lib/mirrors/parameter_optional_order_test.dart
+++ b/tests/lib/mirrors/parameter_optional_order_test.dart
@@ -16,9 +16,9 @@
   positional2(u, v, w, [@Y int y = 1, @Z int z = 2, @X int x = 3]) {}
   positional3(u, v, w, [@Z int z = 1, @X int x = 2, @Y int y = 3]) {}
 
-  named1(u, v, w, {@X int x: 1, @Y int y: 2, @Z int z: 3}) {}
-  named2(u, v, w, {@Y int y: 1, @Z int z: 2, @X int x: 3}) {}
-  named3(u, v, w, {@Z int z: 1, @X int x: 2, @Y int y: 3}) {}
+  named1(u, v, w, {@X int x = 1, @Y int y = 2, @Z int z = 3}) {}
+  named2(u, v, w, {@Y int y = 1, @Z int z = 2, @X int x = 3}) {}
+  named3(u, v, w, {@Z int z = 1, @X int x = 2, @Y int y = 3}) {}
 }
 
 testPositional() {
diff --git a/tests/lib/mirrors/parameter_test.dart b/tests/lib/mirrors/parameter_test.dart
index 2d9418f..c828515 100644
--- a/tests/lib/mirrors/parameter_test.dart
+++ b/tests/lib/mirrors/parameter_test.dart
@@ -24,8 +24,8 @@
   // TODO(6490): Currently only supported by the VM.
   B.baz(final int x, int y, final int z);
   B.qux(int x, [int y = 3 + 1]);
-  B.quux(int x, {String str: "foo"});
-  B.corge({int x: 3 * 17, String str: "bar"});
+  B.quux(int x, {String str = "foo"});
+  B.corge({int x = 3 * 17, String str = "bar"});
 
   var _x;
   get x => _x;
diff --git a/tests/lib/mirrors/redirecting_factory_test.dart b/tests/lib/mirrors/redirecting_factory_test.dart
index 2f5e47a..628ecba 100644
--- a/tests/lib/mirrors/redirecting_factory_test.dart
+++ b/tests/lib/mirrors/redirecting_factory_test.dart
@@ -17,14 +17,14 @@
   factory Class.redirectingFactoryUnnamedOptional(a, [b]) =
       Class.factoryUnnamedOptional;
 
-  factory Class.factoryNamedOptional(a, {b: 42}) {
+  factory Class.factoryNamedOptional(a, {b = 42}) {
     return new Class<T1, T2>(a - b);
   }
 
   factory Class.redirectingFactoryNamedOptional(a, {b}) =
       Class.factoryNamedOptional;
 
-  factory Class.factoryMoreNamedOptional(a, {b: 0, c: 2}) {
+  factory Class.factoryMoreNamedOptional(a, {b = 0, c = 2}) {
     return new Class<T1, T2>(a - b - c);
   }
 
diff --git a/tests/lib/typed_data/polymorphic_unmodifiable_typed_data_test.dart b/tests/lib/typed_data/polymorphic_unmodifiable_typed_data_test.dart
index 95629dc..5ed1d81 100644
--- a/tests/lib/typed_data/polymorphic_unmodifiable_typed_data_test.dart
+++ b/tests/lib/typed_data/polymorphic_unmodifiable_typed_data_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.
 
+// VMOptions=--inline_alloc
+// VMOptions=--no_inline_alloc
+
 import "dart:typed_data";
 import "package:expect/expect.dart";
 
diff --git a/tests/lib/typed_data/unmodifiable_typed_data_test.dart b/tests/lib/typed_data/unmodifiable_typed_data_test.dart
index 32d3d6a..ed20bc4 100644
--- a/tests/lib/typed_data/unmodifiable_typed_data_test.dart
+++ b/tests/lib/typed_data/unmodifiable_typed_data_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.
 
+// VMOptions=--inline_alloc
+// VMOptions=--no_inline_alloc
+
 import 'dart:typed_data';
 import 'package:expect/expect.dart';
 
diff --git a/tests/lib/wasm/basic_test.dart b/tests/lib/wasm/basic_test.dart
deleted file mode 100644
index 309f943..0000000
--- a/tests/lib/wasm/basic_test.dart
+++ /dev/null
@@ -1,30 +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.
-
-// Test that we can load a wasm module, find a function, and call it.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // int64_t square(int64_t n) { return n * n; }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
-    0x01, 0x7e, 0x01, 0x7e, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70,
-    0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f,
-    0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65,
-    0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72,
-    0x65, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00,
-    0x7e, 0x0b,
-  ]);
-
-  var inst = WasmModule(data).instantiate().build();
-  var fn = inst.lookupFunction("square");
-  int n = fn(1234);
-
-  Expect.equals(1234 * 1234, n);
-
-  Expect.isNull(inst.lookupFunction("not_a_function"));
-}
diff --git a/tests/lib/wasm/corrupted_error_test.dart b/tests/lib/wasm/corrupted_error_test.dart
deleted file mode 100644
index 2b8d3fa..0000000
--- a/tests/lib/wasm/corrupted_error_test.dart
+++ /dev/null
@@ -1,20 +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.
-
-// Test error thrown when the wasm module is corrupted.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  var data = Uint8List.fromList([
-    0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60, 0x01, 0x7e, 0x01, 0x7e,
-    0x07, 0x13, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
-    0x06, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x00, 0x00, 0x00, 0x20, 0x00,
-    0x7e, 0x0b,
-  ]);
-
-  Expect.throws(() => WasmModule(data));
-}
diff --git a/tests/lib/wasm/fn_call_error_test.dart b/tests/lib/wasm/fn_call_error_test.dart
deleted file mode 100644
index 641f915..0000000
--- a/tests/lib/wasm/fn_call_error_test.dart
+++ /dev/null
@@ -1,29 +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.
-
-// Test error thrown when a function is called with the wrong args.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // int64_t square(int64_t n) { return n * n; }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
-    0x01, 0x7e, 0x01, 0x7e, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70,
-    0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f,
-    0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65,
-    0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72,
-    0x65, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00,
-    0x7e, 0x0b,
-  ]);
-
-  var inst = WasmModule(data).instantiate().build();
-  var fn = inst.lookupFunction("square");
-
-  Expect.throwsArgumentError(() => fn());
-  Expect.throwsArgumentError(() => fn(1, 2, 3));
-  Expect.throwsArgumentError(() => fn(1.23));
-}
diff --git a/tests/lib/wasm/fn_import_error_test.dart b/tests/lib/wasm/fn_import_error_test.dart
deleted file mode 100644
index 8e4aa00..0000000
--- a/tests/lib/wasm/fn_import_error_test.dart
+++ /dev/null
@@ -1,68 +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.
-
-// Test errors thrown by function imports.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // This module expects a function import like:
-  // int64_t someFn(int32_t a, int64_t b, float c, double d);
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x02, 0x60,
-    0x04, 0x7f, 0x7e, 0x7d, 0x7c, 0x01, 0x7e, 0x60, 0x00, 0x00, 0x02, 0x0e,
-    0x01, 0x03, 0x65, 0x6e, 0x76, 0x06, 0x73, 0x6f, 0x6d, 0x65, 0x46, 0x6e,
-    0x00, 0x00, 0x03, 0x02, 0x01, 0x01, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01,
-    0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41,
-    0x80, 0x88, 0x04, 0x0b, 0x07, 0x11, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f,
-    0x72, 0x79, 0x02, 0x00, 0x04, 0x62, 0x6c, 0x61, 0x68, 0x00, 0x01, 0x0a,
-    0x1d, 0x01, 0x1b, 0x00, 0x41, 0x01, 0x42, 0x02, 0x43, 0x00, 0x00, 0x40,
-    0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x10, 0x80,
-    0x80, 0x80, 0x80, 0x00, 0x1a, 0x0b,
-  ]);
-
-  var mod = WasmModule(data);
-
-  // Valid instantiation.
-  var inst = mod
-      .instantiate()
-      .addFunction("env", "someFn", (int a, int b, num c, double d) => 123)
-      .build();
-
-  // Missing imports.
-  Expect.throws(() => mod.instantiate().build(),
-      (Exception e) => "$e".contains("Missing import"));
-
-  // Wrong kind of import.
-  Expect.throws(
-      () => mod.instantiate().addMemory(false, "env", "someFn", mod.createMemory(10)),
-      (Exception e) => "$e".contains("Import is not a memory"));
-
-  // Wrong namespace.
-  Expect.throws(
-      () => mod
-          .instantiate()
-          .addFunction("foo", "someFn", (int a, int b, num c, double d) => 123)
-          .build(),
-      (Exception e) => "$e".contains("Import not found"));
-
-  // Wrong name.
-  Expect.throws(
-      () => mod
-          .instantiate()
-          .addFunction("env", "otherFn", (int a, int b, num c, double d) => 123)
-          .build(),
-      (Exception e) => "$e".contains("Import not found"));
-
-  // Already filled.
-  Expect.throws(
-      () => mod
-          .instantiate()
-          .addFunction("env", "someFn", (int a, int b, num c, double d) => 123)
-          .addFunction("env", "someFn", (int a, int b, num c, double d) => 456)
-          .build(),
-      (Exception e) => "$e".contains("Import already filled"));
-}
diff --git a/tests/lib/wasm/fn_import_exception_test.dart b/tests/lib/wasm/fn_import_exception_test.dart
deleted file mode 100644
index c97a68a..0000000
--- a/tests/lib/wasm/fn_import_exception_test.dart
+++ /dev/null
@@ -1,48 +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.
-
-// Test throwing exceptions from an imported function.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // void fn() {
-  //   a();
-  //   b();
-  // }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x60,
-    0x00, 0x00, 0x02, 0x11, 0x02, 0x03, 0x65, 0x6e, 0x76, 0x01, 0x61, 0x00,
-    0x00, 0x03, 0x65, 0x6e, 0x76, 0x01, 0x62, 0x00, 0x00, 0x03, 0x02, 0x01,
-    0x00, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00,
-    0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07,
-    0x0f, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02,
-    0x66, 0x6e, 0x00, 0x02, 0x0a, 0x10, 0x01, 0x0e, 0x00, 0x10, 0x80, 0x80,
-    0x80, 0x80, 0x00, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x0b,
-  ]);
-
-  bool called_b = false;
-  var thrownException = Exception("Hello exception!");
-  var inst = WasmModule(data).instantiate().addFunction("env", "a", () {
-    throw thrownException;
-  }).addFunction("env", "b", () {
-    called_b = true;
-  }).build();
-  var fn = inst.lookupFunction("fn");
-  Expect.throws(() => fn(), (Exception e) => e == thrownException);
-  Expect.isFalse(called_b);
-
-  bool called_a = false;
-  inst = WasmModule(data).instantiate().addFunction("env", "a", () {
-    called_a = true;
-  }).addFunction("env", "b", () {
-    called_b = true;
-  }).build();
-  fn = inst.lookupFunction("fn");
-  fn();
-  Expect.isTrue(called_a);
-  Expect.isTrue(called_b);
-}
diff --git a/tests/lib/wasm/fn_import_test.dart b/tests/lib/wasm/fn_import_test.dart
deleted file mode 100644
index 3558c17..0000000
--- a/tests/lib/wasm/fn_import_test.dart
+++ /dev/null
@@ -1,37 +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.
-
-// Test that we can load a wasm module, find a function, and call it.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // void reportStuff() { report(123, 456); }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x09, 0x02, 0x60,
-    0x02, 0x7e, 0x7e, 0x00, 0x60, 0x00, 0x00, 0x02, 0x0e, 0x01, 0x03, 0x65,
-    0x6e, 0x76, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x03,
-    0x02, 0x01, 0x01, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01, 0x01, 0x05, 0x03,
-    0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41, 0x80, 0x88, 0x04,
-    0x0b, 0x07, 0x18, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02,
-    0x00, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x75, 0x66,
-    0x66, 0x00, 0x01, 0x0a, 0x10, 0x01, 0x0e, 0x00, 0x42, 0xfb, 0x00, 0x42,
-    0xc8, 0x03, 0x10, 0x80, 0x80, 0x80, 0x80, 0x00, 0x0b,
-  ]);
-
-  int report_x = -1;
-  int report_y = -1;
-
-  var inst = WasmModule(data).instantiate()
-    .addFunction("env", "report", (int x, int y) {
-      report_x = x;
-      report_y = y;
-    }).build();
-  var fn = inst.lookupFunction("reportStuff");
-  fn();
-  Expect.equals(report_x, 123);
-  Expect.equals(report_y, 456);
-}
diff --git a/tests/lib/wasm/hello_wasi_test.dart b/tests/lib/wasm/hello_wasi_test.dart
deleted file mode 100644
index d862b89..0000000
--- a/tests/lib/wasm/hello_wasi_test.dart
+++ /dev/null
@@ -1,184 +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.
-
-// Variant of hello_world_test that uses the default WASI imports.
-
-import "package:async_helper/async_helper.dart";
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:convert";
-import "dart:typed_data";
-
-void main() async {
-  asyncStart();
-
-  // Hello world module generated by emscripten+WASI. Exports a function like
-  // `void _start()`, and prints using `int fd_write(int, int, int, int)`.
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
-    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
-    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
-    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
-    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
-    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
-    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
-    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
-    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
-    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
-    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
-    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
-    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
-    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
-    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
-    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
-    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
-    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
-    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
-    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
-    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
-    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
-    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
-    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
-    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
-    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
-    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
-    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
-    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
-    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
-    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
-    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
-    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
-    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
-    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
-    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
-    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
-    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
-    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
-    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
-    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
-    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
-    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
-    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
-    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
-    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
-    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
-    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
-    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
-    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
-    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
-    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
-    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
-    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
-    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
-    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
-    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
-    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
-    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
-    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
-    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
-    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
-    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
-    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
-    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
-    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
-    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
-    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
-    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
-    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
-    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
-    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
-    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
-    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
-    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
-    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
-    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
-    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
-    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
-    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
-    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
-    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
-    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
-    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
-    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
-    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
-    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
-    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
-    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
-    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
-    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
-    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
-    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
-    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
-    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
-    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
-    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
-    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
-    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
-    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
-    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
-    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
-    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
-    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
-    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
-    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
-    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
-    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
-    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
-    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
-    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
-    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
-    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
-    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
-    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
-    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
-    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
-    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
-    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
-    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
-    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
-    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
-    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
-    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
-    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
-  ]);
-
-  var inst =
-      WasmModule(data).instantiate().enableWasi(captureStdout: true).build();
-
-  var fn = inst.lookupFunction("_start");
-  fn();
-  var out = utf8.decode(await inst.stdout.first);
-  Expect.equals("hello, world!\n", out);
-  asyncEnd();
-}
diff --git a/tests/lib/wasm/hello_world_test.dart b/tests/lib/wasm/hello_world_test.dart
deleted file mode 100644
index 1dc49e9..0000000
--- a/tests/lib/wasm/hello_world_test.dart
+++ /dev/null
@@ -1,205 +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.
-
-// Test for hello world built using emscripten with WASI.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // Hello world module generated by emscripten+WASI. Exports a function like
-  // `void _start()`, and prints using `int fd_write(int, int, int, int)`.
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
-    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
-    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
-    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
-    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
-    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
-    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
-    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
-    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
-    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
-    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
-    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
-    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
-    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
-    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
-    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
-    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
-    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
-    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
-    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
-    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
-    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
-    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
-    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
-    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
-    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
-    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
-    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
-    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
-    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
-    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
-    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
-    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
-    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
-    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
-    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
-    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
-    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
-    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
-    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
-    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
-    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
-    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
-    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
-    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
-    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
-    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
-    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
-    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
-    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
-    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
-    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
-    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
-    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
-    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
-    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
-    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
-    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
-    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
-    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
-    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
-    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
-    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
-    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
-    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
-    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
-    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
-    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
-    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
-    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
-    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
-    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
-    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
-    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
-    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
-    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
-    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
-    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
-    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
-    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
-    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
-    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
-    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
-    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
-    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
-    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
-    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
-    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
-    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
-    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
-    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
-    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
-    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
-    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
-    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
-    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
-    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
-    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
-    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
-    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
-    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
-    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
-    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
-    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
-    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
-    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
-    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
-    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
-    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
-    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
-    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
-    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
-    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
-    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
-    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
-    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
-    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
-    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
-    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
-    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
-    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
-    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
-    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
-    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
-    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
-  ]);
-
-  late WasmMemory mem;
-  String out = "";
-  var getI32 = (int p) {
-    // Read a little-endian I32.
-    int n = 0;
-    for (var i = p + 3; i >= p; --i) {
-      n *= 256;
-      n += mem[i];
-    }
-    return n;
-  };
-  var inst = WasmModule(data)
-      .instantiate()
-      .addFunction("wasi_unstable", "fd_write",
-          (int fd, int iovs, int iovs_len, int unused) {
-    // iovs points to an array of length iovs_len. Each element is two I32s,
-    // a char* and a length.
-    String o = "";
-    for (var i = 0; i < iovs_len; ++i) {
-      var str = getI32(iovs + 8 * i);
-      var len = getI32(iovs + 4 + 8 * i);
-      for (var j = 0; j < len; ++j) {
-        o += String.fromCharCode(mem[str + j]);
-      }
-    }
-    out += o;
-    return o.length;
-  }).build();
-  mem = inst.memory;
-
-  var fn = inst.lookupFunction("_start");
-  fn();
-  Expect.equals("hello, world!\n", out);
-}
diff --git a/tests/lib/wasm/import_error_test.dart b/tests/lib/wasm/import_error_test.dart
deleted file mode 100644
index a06a3a9..0000000
--- a/tests/lib/wasm/import_error_test.dart
+++ /dev/null
@@ -1,18 +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.
-
-// Test errors thrown by WasmImports.
-
-import "package:expect/expect.dart";
-import "dart:wasm";
-import "dart:typed_data";
-
-void main() {
-  var imp = WasmImports();
-  imp.addGlobal<Int64>("env", "x", 123, false);
-  imp.addGlobal<Double>("env", "y", 4.56, true);
-  Expect.throwsArgumentError(() => imp.addGlobal<int>("env", "a", 1, true));
-  Expect.throwsArgumentError(() => imp.addGlobal<double>("env", "b", 2, true));
-  Expect.throwsArgumentError(() => imp.addGlobal<dynamic>("env", "c", 3, true));
-}
diff --git a/tests/lib/wasm/memory_error_test.dart b/tests/lib/wasm/memory_error_test.dart
deleted file mode 100644
index f02dc6c..0000000
--- a/tests/lib/wasm/memory_error_test.dart
+++ /dev/null
@@ -1,22 +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.
-
-// Test errors thrown by WasmMemory.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // Empty wasm module.
-  var data = Uint8List.fromList(
-      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
-  var module = WasmModule(data);
-
-  Expect.throws(() => module.createMemory(1000000000));
-  var mem = module.createMemory(100);
-  Expect.throws(() => mem.grow(1000000000));
-  mem = module.createMemory(100, 200);
-  Expect.throws(() => mem.grow(300));
-}
diff --git a/tests/lib/wasm/memory_test.dart b/tests/lib/wasm/memory_test.dart
deleted file mode 100644
index 544c6a1..0000000
--- a/tests/lib/wasm/memory_test.dart
+++ /dev/null
@@ -1,28 +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.
-
-// Test that we can create a WasmMemory, edit it, and grow it.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // Empty wasm module.
-  var data = Uint8List.fromList(
-      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
-  var module = WasmModule(data);
-
-  var mem = module.createMemory(100);
-  Expect.equals(100, mem.lengthInPages);
-  Expect.equals(100 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
-
-  mem[123] = 45;
-  Expect.equals(45, mem[123]);
-
-  mem.grow(10);
-  Expect.equals(110, mem.lengthInPages);
-  Expect.equals(110 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
-  Expect.equals(45, mem[123]);
-}
diff --git a/tests/lib/wasm/numerics_test.dart b/tests/lib/wasm/numerics_test.dart
deleted file mode 100644
index eba9aaa..0000000
--- a/tests/lib/wasm/numerics_test.dart
+++ /dev/null
@@ -1,49 +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.
-
-// Test numeric types.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // int64_t addI64(int64_t x, int64_t y) { return x + y; }
-  // int32_t addI32(int32_t x, int32_t y) { return x + y; }
-  // double addF64(double x, double y) { return x + y; }
-  // float addF32(float x, float y) { return x + y; }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x19, 0x04, 0x60,
-    0x02, 0x7e, 0x7e, 0x01, 0x7e, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
-    0x02, 0x7c, 0x7c, 0x01, 0x7c, 0x60, 0x02, 0x7d, 0x7d, 0x01, 0x7d, 0x03,
-    0x05, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01,
-    0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41,
-    0x80, 0x88, 0x04, 0x0b, 0x07, 0x2e, 0x05, 0x06, 0x6d, 0x65, 0x6d, 0x6f,
-    0x72, 0x79, 0x02, 0x00, 0x06, 0x61, 0x64, 0x64, 0x49, 0x36, 0x34, 0x00,
-    0x00, 0x06, 0x61, 0x64, 0x64, 0x49, 0x33, 0x32, 0x00, 0x01, 0x06, 0x61,
-    0x64, 0x64, 0x46, 0x36, 0x34, 0x00, 0x02, 0x06, 0x61, 0x64, 0x64, 0x46,
-    0x33, 0x32, 0x00, 0x03, 0x0a, 0x21, 0x04, 0x07, 0x00, 0x20, 0x01, 0x20,
-    0x00, 0x7c, 0x0b, 0x07, 0x00, 0x20, 0x01, 0x20, 0x00, 0x6a, 0x0b, 0x07,
-    0x00, 0x20, 0x00, 0x20, 0x01, 0xa0, 0x0b, 0x07, 0x00, 0x20, 0x00, 0x20,
-    0x01, 0x92, 0x0b,
-  ]);
-
-  var inst = WasmModule(data).instantiate().build();
-  var addI64 = inst.lookupFunction("addI64");
-  var addI32 = inst.lookupFunction("addI32");
-  var addF64 = inst.lookupFunction("addF64");
-  var addF32 = inst.lookupFunction("addF32");
-
-  int i64 = addI64(0x123456789ABCDEF, 0xFEDCBA987654321);
-  Expect.equals(0x1111111111111110, i64);
-
-  int i32 = addI32(0xABCDEF, 0xFEDCBA);
-  Expect.equals(0x1aaaaa9, i32);
-
-  double f64 = addF64(1234.5678, 8765.4321);
-  Expect.approxEquals(9999.9999, f64, 1e-6);
-
-  double f32 = addF32(1234.5678, 8765.4321);
-  Expect.approxEquals(9999.9999, f32, 1e-3);
-}
diff --git a/tests/lib/wasm/void_test.dart b/tests/lib/wasm/void_test.dart
deleted file mode 100644
index aba9c65..0000000
--- a/tests/lib/wasm/void_test.dart
+++ /dev/null
@@ -1,34 +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.
-
-// Test functions with void return type, and functions that take no args.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // int64_t x = 0;
-  // void set(int64_t a, int64_t b) { x = a + b; }
-  // int64_t get() { return x; }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x02, 0x60,
-    0x02, 0x7e, 0x7e, 0x00, 0x60, 0x00, 0x01, 0x7e, 0x03, 0x03, 0x02, 0x00,
-    0x01, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00,
-    0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41, 0x90, 0x88, 0x04, 0x0b, 0x07,
-    0x16, 0x03, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x03,
-    0x73, 0x65, 0x74, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, 0x01, 0x0a,
-    0x1e, 0x02, 0x10, 0x00, 0x41, 0x00, 0x20, 0x01, 0x20, 0x00, 0x7c, 0x37,
-    0x03, 0x80, 0x88, 0x80, 0x80, 0x00, 0x0b, 0x0b, 0x00, 0x41, 0x00, 0x29,
-    0x03, 0x80, 0x88, 0x80, 0x80, 0x00, 0x0b, 0x0b, 0x0f, 0x01, 0x00, 0x41,
-    0x80, 0x08, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  ]);
-
-  var inst = WasmModule(data).instantiate().build();
-  var setFn = inst.lookupFunction("set");
-  var getFn = inst.lookupFunction("get");
-  Expect.isNull(setFn(123, 456));
-  int n = getFn();
-  Expect.equals(123 + 456, n);
-}
diff --git a/tests/lib/wasm/wasi_error_test.dart b/tests/lib/wasm/wasi_error_test.dart
deleted file mode 100644
index 8418dad..0000000
--- a/tests/lib/wasm/wasi_error_test.dart
+++ /dev/null
@@ -1,204 +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.
-
-// Test the errors that can be thrown by WASI.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // Empty wasm module.
-  var emptyModuleData = Uint8List.fromList(
-      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
-
-  // Failed to fill WASI imports (the empty module was not built with WASI).
-  Expect.throws(() => WasmModule(emptyModuleData).instantiate().enableWasi(),
-      (Exception e) => "$e".contains("Failed to fill WASI imports"));
-
-  // Hello world module generated by emscripten+WASI. Exports a function like
-  // `void _start()`, and prints using `int fd_write(int, int, int, int)`.
-  var helloWorldData = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
-    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
-    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
-    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
-    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
-    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
-    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
-    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
-    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
-    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
-    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
-    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
-    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
-    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
-    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
-    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
-    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
-    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
-    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
-    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
-    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
-    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
-    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
-    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
-    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
-    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
-    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
-    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
-    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
-    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
-    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
-    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
-    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
-    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
-    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
-    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
-    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
-    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
-    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
-    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
-    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
-    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
-    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
-    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
-    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
-    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
-    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
-    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
-    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
-    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
-    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
-    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
-    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
-    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
-    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
-    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
-    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
-    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
-    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
-    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
-    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
-    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
-    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
-    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
-    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
-    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
-    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
-    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
-    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
-    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
-    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
-    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
-    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
-    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
-    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
-    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
-    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
-    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
-    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
-    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
-    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
-    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
-    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
-    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
-    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
-    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
-    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
-    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
-    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
-    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
-    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
-    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
-    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
-    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
-    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
-    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
-    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
-    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
-    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
-    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
-    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
-    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
-    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
-    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
-    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
-    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
-    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
-    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
-    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
-    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
-    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
-    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
-    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
-    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
-    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
-    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
-    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
-    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
-    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
-    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
-    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
-    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
-    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
-    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
-    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
-  ]);
-
-  // Trying to import WASI twice.
-  Expect.throws(
-      () => WasmModule(helloWorldData).instantiate().enableWasi().enableWasi(),
-      (Exception e) => "$e".contains("WASI is already enabled"));
-
-  // Missing imports due to not enabling WASI.
-  Expect.throws(() => WasmModule(helloWorldData).instantiate().build(),
-      (Exception e) => "$e".contains("Missing import"));
-
-  // Trying to get stdout/stderr without WASI enabled (WASI function import has
-  // been manually filled).
-  var inst = WasmModule(helloWorldData)
-      .instantiate()
-      .addFunction("wasi_unstable", "fd_write",
-          (int fd, int iovs, int iovs_len, int unused) => 0)
-      .build();
-  Expect.throws(
-      () => inst.stdout,
-      (Exception e) =>
-          "$e".contains("Can't capture stdout without WASI enabled"));
-  Expect.throws(
-      () => inst.stderr,
-      (Exception e) =>
-          "$e".contains("Can't capture stderr without WASI enabled"));
-}
diff --git a/tests/lib_2/js/static_interop_test/mock/extension_conflict_test.dart b/tests/lib_2/js/static_interop_test/mock/extension_conflict_test.dart
new file mode 100644
index 0000000..9008360
--- /dev/null
+++ b/tests/lib_2/js/static_interop_test/mock/extension_conflict_test.dart
@@ -0,0 +1,178 @@
+// Copyright (c) 2022, 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 that `createStaticInteropMock` checks for extension member conflicts.
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+class EmptyDart {}
+
+@JS()
+@staticInterop
+class Method {}
+
+extension on Method {
+  external void member();
+}
+
+@JS()
+@staticInterop
+class Getter {}
+
+extension NamedExtension on Getter {
+  external int get member;
+}
+
+@JS()
+@staticInterop
+class Field {}
+
+extension on Field {
+  external final String member;
+}
+
+@JS()
+@staticInterop
+class ExtendsImplementsConflict extends Method implements Getter {}
+
+@JS()
+@staticInterop
+class ImplementsConflict implements Method, Getter {}
+
+@JS()
+@staticInterop
+class ManyConflicts extends Method implements Getter, Field {}
+
+@JS()
+@staticInterop
+class Override implements Method {}
+
+extension on Override {
+  external int member();
+}
+
+@JS()
+@staticInterop
+class OverrideOneConflictButNotAll implements Override, Getter {}
+
+@JS()
+@staticInterop
+class ConflictThroughInheritance implements OverrideOneConflictButNotAll {}
+
+@JS()
+@staticInterop
+class ResolveThroughOverride implements ConflictThroughInheritance {}
+
+extension on ResolveThroughOverride {
+  external int member;
+}
+
+class ResolveThroughOverrideDart {
+  int member = throw '';
+}
+
+@JS()
+@staticInterop
+class Setter {}
+
+extension on Setter {
+  external set member(int val);
+}
+
+@JS()
+@staticInterop
+class NoConflictDueToSubtype implements Override, Method {}
+
+class NoConflictDueToSubtypeDart {
+  int member() => throw '';
+}
+
+@JS()
+@staticInterop
+class GetterSetterConflict implements Setter, Getter {}
+
+@JS()
+@staticInterop
+class GetterSetterSameExtension {}
+
+extension on GetterSetterSameExtension {
+  external int get member;
+  external set member(int val);
+}
+
+class GetterSetterSameExtensionDart extends ResolveThroughOverrideDart {}
+
+@JS()
+@staticInterop
+class GetterSetterMethodConflict implements GetterSetterSameExtension, Method {}
+
+@JS()
+@staticInterop
+class NonExternal {}
+
+extension on NonExternal {
+  int get member => throw '';
+}
+
+@JS()
+@staticInterop
+class ExternalNonExternal implements NonExternal, GetterSetterSameExtension {}
+
+class ExternalNonExternalDart extends ResolveThroughOverrideDart {}
+
+void main() {
+  // Test name conflicts between extended and implemented members.
+  createStaticInteropMock<ExtendsImplementsConflict, EmptyDart>(
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Method.unnamed'.
+      EmptyDart());
+  // Test name conflicts between implemented members.
+  createStaticInteropMock<ImplementsConflict, EmptyDart>(EmptyDart());
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Method.unnamed'.
+
+  // Test multiple name conflicts.
+  createStaticInteropMock<ManyConflicts, EmptyDart>(EmptyDart());
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Field.unnamed', 'Getter.NamedExtension', 'Method.unnamed'.
+
+  // Test name conflicts where one definition is overridden, but there is still
+  // a name conflict between the other two.
+  createStaticInteropMock<OverrideOneConflictButNotAll, EmptyDart>(
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Override.unnamed'.
+      EmptyDart());
+  // Test case where if we inherit a class with a conflict, the conflict still
+  // exists.
+  createStaticInteropMock<ConflictThroughInheritance, EmptyDart>(
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Override.unnamed'.
+      EmptyDart());
+  // Test case where name conflicts are resolved using derived class.
+  createStaticInteropMock<ResolveThroughOverride, ResolveThroughOverrideDart>(
+      ResolveThroughOverrideDart());
+  // Test case where you inherit two classes with the same member name but they
+  // have a subtype relation, so there is no conflict.
+  createStaticInteropMock<NoConflictDueToSubtype, NoConflictDueToSubtypeDart>(
+      NoConflictDueToSubtypeDart());
+  // Test conflict where getter and setter collide when they are in different
+  // extensions.
+  createStaticInteropMock<GetterSetterConflict, EmptyDart>(EmptyDart());
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Setter.unnamed'.
+
+  // Test no conflict where getter and setter are on the same extension.
+  createStaticInteropMock<GetterSetterSameExtension,
+      GetterSetterSameExtensionDart>(GetterSetterSameExtensionDart());
+  // Test conflict where getter and setter are in one extension, but there is
+  // a conflict with another extension.
+  createStaticInteropMock<GetterSetterMethodConflict, EmptyDart>(EmptyDart());
+//^
+// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'GetterSetterSameExtension.unnamed', 'Method.unnamed'.
+
+  // Test no conflict between external and non-external members.
+  createStaticInteropMock<ExternalNonExternal, ExternalNonExternalDart>(
+      ExternalNonExternalDart());
+}
diff --git a/tests/lib_2/js/static_interop_test/mock/functional_test.dart b/tests/lib_2/js/static_interop_test/mock/functional_test.dart
new file mode 100644
index 0000000..a43df9a
--- /dev/null
+++ b/tests/lib_2/js/static_interop_test/mock/functional_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, 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 'functional_test_lib.dart';
+
+void main() {
+  test();
+}
diff --git a/tests/lib_2/js/static_interop_test/mock/functional_test_lib.dart b/tests/lib_2/js/static_interop_test/mock/functional_test_lib.dart
new file mode 100644
index 0000000..69d5ec9
--- /dev/null
+++ b/tests/lib_2/js/static_interop_test/mock/functional_test_lib.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2022, 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 basic functionality of `createStaticInteropMock`. Basic methods, fields
+// (final and not), getters, and setters are tested along with potential
+// renames.
+
+import 'package:expect/minitest.dart';
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+@JS()
+@staticInterop
+class Methods {}
+
+extension on Methods {
+  external int add(int a, int b);
+  // Sanity-check that non-externals are unaffected.
+  int nonExternal() => 0;
+  @JS('_rename')
+  external int rename();
+  external int optionalAdd(int a, int b, [int c = 0, int? d]);
+}
+
+class MethodsDart {
+  int add(int a, int b) => a + b;
+  int nonExternal() => 1;
+  int rename() => 1;
+  int optionalAdd(int a, int b, [int? c, int? d]) =>
+      a + b + (c ?? 0) + (d ?? 0);
+}
+
+@JS()
+@staticInterop
+class Fields {}
+
+extension on Fields {
+  external int field;
+  external final int finalField;
+  @JS('_renamedField')
+  external int renamedField;
+  @JS('_renamedFinalField')
+  external final int renamedFinalField;
+}
+
+class FieldsDart {
+  int field = 1;
+  int finalField = 1;
+  int renamedField = 1;
+  final int renamedFinalField = 1;
+}
+
+@JS()
+@staticInterop
+class GetSet {}
+
+extension on GetSet {
+  external int get getSet;
+  external set getSet(int val);
+  @JS('_renamedGetSet')
+  external int get renamedGetSet;
+  @JS('_renamedGetSet')
+  external set renamedGetSet(int val);
+  @JS('_sameNameDifferentRenameGet')
+  external int get sameNameDifferentRename;
+  @JS('_sameNameDifferentRenameSet')
+  external set sameNameDifferentRename(int val);
+  @JS('_differentNameSameRename')
+  external int get differentNameSameRenameGet;
+  @JS('_differentNameSameRename')
+  external set differentNameSameRenameSet(int val);
+}
+
+class GetSetDart {
+  int getSet = 1;
+  int renamedGetSet = 1;
+  int sameNameDifferentRename = 1;
+  int differentNameSameRenameGet = 1;
+  int differentNameSameRenameSet = 1;
+}
+
+void test([Object? proto]) {
+  var jsMethods =
+      createStaticInteropMock<Methods, MethodsDart>(MethodsDart(), proto);
+  expect(jsMethods.add(1, 1), 2);
+  expect(jsMethods.nonExternal(), 0);
+  expect(jsMethods.rename(), 1);
+  expect(jsMethods.optionalAdd(1, 1), 2);
+  expect(jsMethods.optionalAdd(1, 1, 1), 3);
+  expect(jsMethods.optionalAdd(1, 1, 1, 1), 4);
+  var dartFields = FieldsDart();
+  var jsFields = createStaticInteropMock<Fields, FieldsDart>(dartFields, proto);
+  expect(jsFields.field, 1);
+  expect(jsFields.finalField, 1);
+  expect(jsFields.renamedField, 1);
+  expect(jsFields.renamedFinalField, 1);
+  // Modify the JS mock and check for updates in the Dart mock.
+  jsFields.field = 2;
+  jsFields.renamedField = 2;
+  expect(dartFields.field, 2);
+  expect(dartFields.renamedField, 2);
+  // Modify the Dart mock and check for updates in the JS mock.
+  dartFields.field = 3;
+  dartFields.finalField = 3;
+  dartFields.renamedField = 3;
+  expect(jsFields.field, 3);
+  expect(jsFields.finalField, 3);
+  expect(jsFields.renamedField, 3);
+  var dartGetSet = GetSetDart();
+  var jsGetSet = createStaticInteropMock<GetSet, GetSetDart>(dartGetSet, proto);
+  expect(jsGetSet.getSet, 1);
+  expect(jsGetSet.renamedGetSet, 1);
+  expect(jsGetSet.sameNameDifferentRename, 1);
+  expect(jsGetSet.differentNameSameRenameGet, 1);
+  // Modify the JS mock and check for updates in the Dart mock.
+  jsGetSet.getSet = 2;
+  jsGetSet.renamedGetSet = 2;
+  jsGetSet.sameNameDifferentRename = 2;
+  jsGetSet.differentNameSameRenameSet = 2;
+  expect(dartGetSet.getSet, 2);
+  expect(dartGetSet.renamedGetSet, 2);
+  expect(dartGetSet.sameNameDifferentRename, 2);
+  expect(dartGetSet.differentNameSameRenameGet, 1);
+  expect(dartGetSet.differentNameSameRenameSet, 2);
+  // Modify the Dart mock and check for updates in the JS mock.
+  dartGetSet.getSet = 3;
+  dartGetSet.renamedGetSet = 3;
+  dartGetSet.sameNameDifferentRename = 3;
+  // Use different values to disambiguate.
+  dartGetSet.differentNameSameRenameGet = 3;
+  dartGetSet.differentNameSameRenameSet = 4;
+  expect(jsGetSet.getSet, 3);
+  expect(jsGetSet.renamedGetSet, 3);
+  expect(jsGetSet.sameNameDifferentRename, 3);
+  expect(jsGetSet.differentNameSameRenameGet, 3);
+}
diff --git a/tests/lib_2/js/static_interop_test/mock/incorrect_type_arguments_test.dart b/tests/lib_2/js/static_interop_test/mock/incorrect_type_arguments_test.dart
new file mode 100644
index 0000000..e4729dd
--- /dev/null
+++ b/tests/lib_2/js/static_interop_test/mock/incorrect_type_arguments_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2022, 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 that `createStaticInteropMock` checks its type arguments.
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+@JS()
+class Js {
+  external Js();
+}
+
+@JS()
+@anonymous
+class Anonymous {
+  external factory Anonymous();
+}
+
+@JS()
+@staticInterop
+class StaticInterop {
+  external factory StaticInterop();
+}
+
+class Dart {}
+
+void main() {
+  createStaticInteropMock<StaticInterop, Dart>(Dart());
+  createStaticInteropMock<Dart, StaticInterop>(StaticInterop());
+//^
+// [web] First type argument 'Dart' is not a `@staticInterop` type.
+// [web] Second type argument 'StaticInterop' is not a Dart interface type.
+  createStaticInteropMock<Dart, Js>(Js());
+//^
+// [web] First type argument 'Dart' is not a `@staticInterop` type.
+// [web] Second type argument 'Js' is not a Dart interface type.
+  createStaticInteropMock<Dart, Anonymous>(Anonymous());
+//^
+// [web] First type argument 'Dart' is not a `@staticInterop` type.
+// [web] Second type argument 'Anonymous' is not a Dart interface type.
+  createStaticInteropMock<StaticInterop, void Function()>(() {});
+//^
+// [web] Second type argument 'void Function()' is not a Dart interface type.
+  createStaticInteropMock(Dart());
+//^
+// [web] First type argument 'dynamic' is not a `@staticInterop` type.
+}
diff --git a/tests/lib_2/js/static_interop_test/mock/inheritance_test.dart b/tests/lib_2/js/static_interop_test/mock/inheritance_test.dart
new file mode 100644
index 0000000..302d76f
--- /dev/null
+++ b/tests/lib_2/js/static_interop_test/mock/inheritance_test.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2022, 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.
+
+// Basic inheritance test where @staticInterop class inherits extension methods
+// which are then defined in the Dart class' inheritance chain, with some
+// overrides.
+
+import 'package:expect/minitest.dart';
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+@JS()
+@staticInterop
+class Extends {}
+
+extension on Extends {
+  external int extendsMethod(int val);
+  external int extendsField;
+  external final int extendsFinalField;
+  external int get getSet;
+  external set getSet(int val);
+}
+
+@JS()
+@staticInterop
+class Implements {}
+
+extension on Implements {
+  @JS('_implementsMethod')
+  external int implementsMethod(int val);
+  @JS('_implementsField')
+  external int implementsField;
+  @JS('_implementsFinalField')
+  external final int implementsFinalField;
+  @JS('_implementsGetter')
+  external int get implementsGetter;
+  @JS('_implementsSetter')
+  external set implementsSetter(int val);
+}
+
+@JS()
+@staticInterop
+class Inheritance extends Extends implements Implements {}
+
+extension on Inheritance {
+  external int method(int val);
+  external int field;
+  external final int finalField;
+  // Overrides
+  external int get getSet;
+  external set getSet(int val);
+}
+
+class ExtendsDart {
+  int extendsMethod(int val) => val;
+  int extendsField = 0;
+  final int extendsFinalField = 0;
+  int getSet = 0;
+}
+
+class ImplementsMixin {
+  int implementsMethod(int val) => val;
+  int implementsField = 1;
+  final int implementsFinalField = 1;
+  int _implementsGetSet = 1;
+  int get implementsGetter => _implementsGetSet;
+  set implementsSetter(int val) => _implementsGetSet = val;
+}
+
+class InheritanceDart extends ExtendsDart with ImplementsMixin {
+  int method(int val) => val;
+  int field = 2;
+  final int finalField = 2;
+  @override
+  int getSet = 2;
+}
+
+void main() {
+  var dartMock = InheritanceDart();
+  var jsMock = createStaticInteropMock<Inheritance, InheritanceDart>(dartMock);
+  expect(jsMock.extendsMethod(0), 0);
+  expect(jsMock.extendsField, 0);
+  jsMock.extendsField = 1;
+  expect(jsMock.extendsField, 1);
+  expect(jsMock.extendsFinalField, 0);
+
+  expect(jsMock.implementsMethod(1), 1);
+  expect(jsMock.implementsField, 1);
+  jsMock.implementsField = 2;
+  expect(jsMock.implementsField, 2);
+  expect(jsMock.implementsFinalField, 1);
+  expect(jsMock.implementsGetter, 1);
+  jsMock.implementsSetter = 2;
+  // Dart mock uses a field for this getter and setter, so it should change.
+  expect(jsMock.implementsGetter, 2);
+
+  expect(jsMock.method(2), 2);
+  expect(jsMock.field, 2);
+  jsMock.field = 3;
+  expect(jsMock.field, 3);
+  expect(jsMock.finalField, 2);
+  expect(jsMock.getSet, 2);
+  jsMock.getSet = 3;
+  expect(jsMock.getSet, 3);
+}
diff --git a/tests/lib_2/js/static_interop_test/mock/missing_overrides_test.dart b/tests/lib_2/js/static_interop_test/mock/missing_overrides_test.dart
new file mode 100644
index 0000000..6ff5958
--- /dev/null
+++ b/tests/lib_2/js/static_interop_test/mock/missing_overrides_test.dart
@@ -0,0 +1,183 @@
+// Copyright (c) 2022, 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 that `createStaticInteropMock` checks that there aren't any missing
+// overrides.
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+@JS()
+@staticInterop
+class StaticInterop {}
+
+extension on StaticInterop {
+  external int field;
+  external final int finalField;
+  external int get getSet;
+  external set getSet(int val);
+  external void method();
+
+  // We should ignore the non-external members for determining overrides.
+  int get nonExternalGetSet => throw '';
+  set nonExternalGetSet(int val) => throw '';
+  void nonExternalMethod() => throw '';
+}
+
+class CorrectDart {
+  int field = throw '';
+  final int finalField = throw '';
+  int get getSet => throw '';
+  set getSet(int val) => throw '';
+  void method() => throw '';
+}
+
+class DartStatic {
+  static int field = throw '';
+  final int finalField = throw '';
+  int get getSet => throw '';
+  set getSet(int val) => throw '';
+  void method() => throw '';
+}
+
+class DartUsingExtensions {
+  int field = throw '';
+  final int finalField = throw '';
+  int get getSet => throw '';
+  set getSet(int val) => throw '';
+}
+
+extension on DartUsingExtensions {
+  void method() => throw '';
+}
+
+class DartFactory {
+  DartFactory();
+  factory DartFactory.finalField() => DartFactory();
+  int field = throw '';
+  int get getSet => throw '';
+  set getSet(int val) => throw '';
+  void method() => throw '';
+}
+
+class DartFinal {
+  final int field = throw '';
+  final int finalField = throw '';
+  int get getSet => throw '';
+  set getSet(int val) => throw '';
+  void method() => throw '';
+}
+
+class DartNoGet {
+  int field = throw '';
+  final int finalField = throw '';
+  set getSet(int val) => throw '';
+  void method() => throw '';
+}
+
+class DartNoSet {
+  int field = throw '';
+  final int finalField = throw '';
+  int get getSet => throw '';
+  void method() => throw '';
+}
+
+class DartNoMembers {}
+
+void main() {
+  createStaticInteropMock<StaticInterop, CorrectDart>(CorrectDart());
+  // Static members do not qualify as an override.
+  createStaticInteropMock<StaticInterop, DartStatic>(
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field', but Dart class 'DartStatic' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartStatic' does not have an overriding instance member.
+      DartStatic());
+  // Extension members do not qualify as an override.
+  createStaticInteropMock<StaticInterop, DartUsingExtensions>(
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'method', but Dart class 'DartUsingExtensions' does not have an overriding instance member.
+      DartUsingExtensions());
+  // Factory members with the same name do not qualify as an override.
+  createStaticInteropMock<StaticInterop, DartFactory>(
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'finalField', but Dart class 'DartFactory' does not have an overriding instance member.
+      DartFactory());
+  // Final fields can not override a setter.
+  createStaticInteropMock<StaticInterop, DartFinal>(DartFinal());
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartFinal' does not have an overriding instance member.
+  createStaticInteropMock<StaticInterop, DartNoGet>(DartNoGet());
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet', but Dart class 'DartNoGet' does not have an overriding instance member.
+
+  // Test that getters are treated differently from setters even though they
+  // share the same name.
+  createStaticInteropMock<StaticInterop, DartNoSet>(DartNoSet());
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet=', but Dart class 'DartNoSet' does not have an overriding instance member.
+
+  // Test multiple missing members.
+  createStaticInteropMock<StaticInterop, DartNoMembers>(
+//^
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field', but Dart class 'DartNoMembers' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartNoMembers' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'finalField', but Dart class 'DartNoMembers' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet', but Dart class 'DartNoMembers' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet=', but Dart class 'DartNoMembers' does not have an overriding instance member.
+// [web] `@staticInterop` class 'StaticInterop' has external extension member 'method', but Dart class 'DartNoMembers' does not have an overriding instance member.
+      DartNoMembers());
+
+  testUsingInheritanceAndMixins();
+}
+
+// The following should classes should not contain any override errors, as they
+// have all the necessary members.
+class DartWithInheritance extends DartNoSet {
+  set getSet(int val) => throw '';
+}
+
+class DartWithMixins with CorrectDart {}
+
+mixin MixinSet {
+  set getSet(int val) => throw '';
+}
+
+class DartWithMixinsAndInheritance extends DartNoSet with MixinSet {}
+
+@JS()
+@staticInterop
+class BaseStaticInterop {}
+
+extension on BaseStaticInterop {
+  external void baseMethod();
+}
+
+@JS()
+@staticInterop
+class StaticInteropWithInheritance extends BaseStaticInterop
+    implements StaticInterop {}
+
+class DartImplementingInteropInheritance extends DartWithMixinsAndInheritance {
+  void baseMethod() => throw '';
+}
+
+void testUsingInheritanceAndMixins() {
+  // Test where Dart class implements using inherited members.
+  createStaticInteropMock<StaticInterop, DartWithInheritance>(
+      DartWithInheritance());
+  // Test where Dart class implements using mixed-in members.
+  createStaticInteropMock<StaticInterop, DartWithMixins>(DartWithMixins());
+  // Test where Dart class implements using inherited and mixed-in members.
+  createStaticInteropMock<StaticInterop, DartWithMixinsAndInheritance>(
+      DartWithMixinsAndInheritance());
+  // Missing inherited method, expect an error.
+  createStaticInteropMock<
+//^
+// [web] `@staticInterop` class 'StaticInteropWithInheritance' has external extension member 'baseMethod', but Dart class 'DartWithMixinsAndInheritance' does not have an overriding instance member.
+      StaticInteropWithInheritance,
+      DartWithMixinsAndInheritance>(DartWithMixinsAndInheritance());
+  // Added missing method, should pass.
+  createStaticInteropMock<StaticInteropWithInheritance,
+      DartImplementingInteropInheritance>(DartImplementingInteropInheritance());
+}
diff --git a/tests/lib_2/js/static_interop_test/mock/mockito_test.dart b/tests/lib_2/js/static_interop_test/mock/mockito_test.dart
new file mode 100644
index 0000000..24004e1
--- /dev/null
+++ b/tests/lib_2/js/static_interop_test/mock/mockito_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2022, 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 that using `createStaticInteropMock` with pkg:mockito works as expected.
+
+import 'package:expect/minitest.dart';
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+import 'package:mockito/mockito.dart';
+
+@JS()
+@staticInterop
+class StaticInterop {}
+
+extension on StaticInterop {
+  // We use nullable types here as mockito requires some additional complexity
+  // or code generation to safely mock non-nullables.
+  // https://github.com/dart-lang/mockito/blob/master/NULL_SAFETY_README.md
+  external int? method(int? val);
+  external int? field;
+  external final int? finalField;
+  external int? get getSet;
+  external set getSet(int? val);
+}
+
+class Dart {
+  int? method(int? val) => throw '';
+  int? field = throw '';
+  final int? finalField = throw '';
+  int? get getSet => throw '';
+  set getSet(int? val) => throw '';
+}
+
+// Have the mock class implement the class interface you defined to mock the
+// @staticInterop interface.
+class DartMock extends Mock implements Dart {}
+
+void main() {
+  // Write expectations on the Dart Mock object, not the JS mock object.
+  var dartMock = DartMock();
+  var jsMock = createStaticInteropMock<StaticInterop, DartMock>(dartMock);
+  when(dartMock.method(0)).thenReturn(1);
+  when(dartMock.field).thenReturn(1);
+  when(dartMock.finalField).thenReturn(1);
+  when(dartMock.getSet).thenReturn(1);
+  expect(jsMock.method(0), 1);
+  expect(jsMock.field, 1);
+  expect(jsMock.finalField, 1);
+  expect(jsMock.getSet, 1);
+  jsMock.getSet = 1;
+  verify(dartMock.getSet = 1);
+}
diff --git a/tests/lib_2/js/static_interop_test/mock/proto_test.dart b/tests/lib_2/js/static_interop_test/mock/proto_test.dart
new file mode 100644
index 0000000..647cd58
--- /dev/null
+++ b/tests/lib_2/js/static_interop_test/mock/proto_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2022, 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 that providing a proto object to createStaticInteropMock does not break
+// any functionality, and allows instanceof/is checks to pass.
+
+@JS()
+library proto_test;
+
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+import 'functional_test_lib.dart' as functional_test;
+
+@JS('Window.prototype')
+external Object get windowProto;
+
+@JS('Window')
+external Object get windowType;
+
+@JS()
+@staticInterop
+class JSWindow {}
+
+class DartWindow {}
+
+void main() {
+  // Test that everything still works the same.
+  functional_test.test(windowProto);
+  // Test instanceof/is checks.
+  var jsMock =
+      createStaticInteropMock<JSWindow, DartWindow>(DartWindow(), windowProto);
+  expect(jsMock is Window, true);
+  expect(instanceof(jsMock, windowType), true);
+}
diff --git a/tests/lib_2/js/static_interop_test/mock/subtype_overrides_test.dart b/tests/lib_2/js/static_interop_test/mock/subtype_overrides_test.dart
new file mode 100644
index 0000000..ed2b98f
--- /dev/null
+++ b/tests/lib_2/js/static_interop_test/mock/subtype_overrides_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2022, 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 that `createStaticInteropMock` checks that overrides are subtypes.
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart';
+
+// Set up a simple type hierarchy.
+class A {
+  const A();
+}
+
+class B extends A {
+  const B();
+}
+
+class C extends B {
+  const C();
+}
+
+@JS()
+@staticInterop
+class SimpleInterop {}
+
+extension SimpleInteropExtension on SimpleInterop {
+  external B field;
+  external final B finalField;
+  external B get getSetNum;
+  external set getSetInt(B val);
+  external B method(B b);
+}
+
+// Implement using the exact same types.
+class SimpleDart {
+  B field = throw '';
+  final B finalField = throw '';
+  B get getSetNum => throw '';
+  set getSetInt(B val) => throw '';
+  B method(B b) => throw '';
+}
+
+// Implement using subtypes.
+class SubtypeSimpleDart {
+  B field = throw '';
+  final C finalField = throw '';
+  C get getSetNum => throw '';
+  set getSetInt(A val) => throw '';
+  C method(A a) => throw '';
+}
+
+// Implement using supertypes (which shouldn't work).
+class SupertypeSimpleDart {
+  A field = throw '';
+  final A finalField = throw '';
+  A get getSetNum => throw '';
+  set getSetInt(C val) => throw '';
+  A method(C c) => throw '';
+}
+
+@JS()
+@staticInterop
+class ComplexAndOptionalInteropMethods {}
+
+extension ComplexAndOptionalInteropMethodsExtension
+    on ComplexAndOptionalInteropMethods {
+  external B Function(B _) nestedTypes(List<B> arg1, Map<Set<B>, B> arg2);
+  external B optional(B b, [B? b2]);
+  external B optionalSubtype(B b, [B b2 = const B()]);
+}
+
+class ComplexAndOptionalDart {
+  C Function(A _) nestedTypes(List<B> arg1, Map<Set<B>, B> arg2) => throw '';
+  B optional(B b, [B? b2]) => throw '';
+  C optionalSubtype(A a, [A? a2]) => throw '';
+}
+
+class IncorrectComplexAndOptionalDart {
+  // List type is wrong.
+  B Function(B _) nestedTypes(List<List<B>> arg1, Map<Set<B>, B> arg2) =>
+      throw '';
+  // Second argument is not optional, this is invalid.
+  B optional(B b, B? b2) => throw '';
+  // Third argument is supposed to be a supertype, not a subtype.
+  B optionalSubtype(B b, [C c = const C()]) => throw '';
+}
+
+void main() {
+  createStaticInteropMock<SimpleInterop, SimpleDart>(SimpleDart());
+  createStaticInteropMock<SimpleInterop, SubtypeSimpleDart>(
+      SubtypeSimpleDart());
+  createStaticInteropMock<SimpleInterop, SupertypeSimpleDart>(
+//^
+// [web] Dart class member 'SupertypeSimpleDart.field' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.field' with type 'B Function()'.
+// [web] Dart class member 'SupertypeSimpleDart.finalField' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.finalField' with type 'B Function()'.
+// [web] Dart class member 'SupertypeSimpleDart.getSetInt=' with type 'void Function(C)' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.getSetInt=' with type 'void Function(B)'.
+// [web] Dart class member 'SupertypeSimpleDart.getSetNum' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.getSetNum' with type 'B Function()'.
+// [web] Dart class member 'SupertypeSimpleDart.method' with type 'A Function(C)' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.method' with type 'B Function(B)'.
+      SupertypeSimpleDart());
+  createStaticInteropMock<ComplexAndOptionalInteropMethods,
+      ComplexAndOptionalDart>(ComplexAndOptionalDart());
+  createStaticInteropMock<
+//^
+// [web] Dart class member 'IncorrectComplexAndOptionalDart.nestedTypes' with type 'B Function(B) Function(List<List<B>>, Map<Set<B>, B>)' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.nestedTypes' with type 'B Function(B) Function(List<B>, Map<Set<B>, B>)'.
+// [web] Dart class member 'IncorrectComplexAndOptionalDart.optional' with type 'B Function(B, B?)' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.optional' with type 'B Function(B, [B?])'.
+// [web] Dart class member 'IncorrectComplexAndOptionalDart.optionalSubtype' with type 'B Function(B, [C])' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.optionalSubtype' with type 'B Function(B, [B])'.
+      ComplexAndOptionalInteropMethods,
+      IncorrectComplexAndOptionalDart>(IncorrectComplexAndOptionalDart());
+}
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 1688cf9..15d4e48 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -15,6 +15,7 @@
 js/js_util/javascriptobject_extensions_test: SkipByDesign # Uses dart:html.
 js/static_interop_test/constants_test: SkipByDesign # Uses dart:html.
 js/static_interop_test/futurevaluetype_test: SkipByDesign # Uses dart:html.
+js/static_interop_test/mock/proto_test: SkipByDesign # Uses dart:html.
 js/static_interop_test/supertype_transform_test: SkipByDesign # Uses dart:html.
 
 [ $runtime == dart_precompiled ]
diff --git a/tests/lib_2/typed_data/polymorphic_unmodifiable_typed_data_test.dart b/tests/lib_2/typed_data/polymorphic_unmodifiable_typed_data_test.dart
index f18de07..a0cf893 100644
--- a/tests/lib_2/typed_data/polymorphic_unmodifiable_typed_data_test.dart
+++ b/tests/lib_2/typed_data/polymorphic_unmodifiable_typed_data_test.dart
@@ -4,6 +4,9 @@
 
 // @dart = 2.9
 
+// VMOptions=--inline_alloc
+// VMOptions=--no_inline_alloc
+
 import "dart:typed_data";
 import "package:expect/expect.dart";
 
diff --git a/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart b/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
index 8609125..fbbaa9d 100644
--- a/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
+++ b/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
@@ -4,6 +4,9 @@
 
 // @dart = 2.9
 
+// VMOptions=--inline_alloc
+// VMOptions=--no_inline_alloc
+
 import 'dart:typed_data';
 import 'package:expect/expect.dart';
 
diff --git a/tests/lib_2/wasm/basic_test.dart b/tests/lib_2/wasm/basic_test.dart
deleted file mode 100644
index 858657e..0000000
--- a/tests/lib_2/wasm/basic_test.dart
+++ /dev/null
@@ -1,32 +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.
-
-// @dart = 2.9
-
-// Test that we can load a wasm module, find a function, and call it.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // int64_t square(int64_t n) { return n * n; }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
-    0x01, 0x7e, 0x01, 0x7e, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70,
-    0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f,
-    0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65,
-    0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72,
-    0x65, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00,
-    0x7e, 0x0b,
-  ]);
-
-  var inst = WasmModule(data).instantiate().build();
-  var fn = inst.lookupFunction("square");
-  int n = fn(1234);
-
-  Expect.equals(1234 * 1234, n);
-
-  Expect.isNull(inst.lookupFunction("not_a_function"));
-}
diff --git a/tests/lib_2/wasm/corrupted_error_test.dart b/tests/lib_2/wasm/corrupted_error_test.dart
deleted file mode 100644
index ed2cc66..0000000
--- a/tests/lib_2/wasm/corrupted_error_test.dart
+++ /dev/null
@@ -1,22 +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.
-
-// @dart = 2.9
-
-// Test error thrown when the wasm module is corrupted.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  var data = Uint8List.fromList([
-    0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60, 0x01, 0x7e, 0x01, 0x7e,
-    0x07, 0x13, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
-    0x06, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x00, 0x00, 0x00, 0x20, 0x00,
-    0x7e, 0x0b,
-  ]);
-
-  Expect.throws(() => WasmModule(data));
-}
diff --git a/tests/lib_2/wasm/fn_call_error_test.dart b/tests/lib_2/wasm/fn_call_error_test.dart
deleted file mode 100644
index 2364605..0000000
--- a/tests/lib_2/wasm/fn_call_error_test.dart
+++ /dev/null
@@ -1,31 +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.
-
-// @dart = 2.9
-
-// Test error thrown when a function is called with the wrong args.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // int64_t square(int64_t n) { return n * n; }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
-    0x01, 0x7e, 0x01, 0x7e, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70,
-    0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f,
-    0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65,
-    0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72,
-    0x65, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00,
-    0x7e, 0x0b,
-  ]);
-
-  var inst = WasmModule(data).instantiate().build();
-  var fn = inst.lookupFunction("square");
-
-  Expect.throwsArgumentError(() => fn());
-  Expect.throwsArgumentError(() => fn(1, 2, 3));
-  Expect.throwsArgumentError(() => fn(1.23));
-}
diff --git a/tests/lib_2/wasm/fn_import_error_test.dart b/tests/lib_2/wasm/fn_import_error_test.dart
deleted file mode 100644
index c99054c..0000000
--- a/tests/lib_2/wasm/fn_import_error_test.dart
+++ /dev/null
@@ -1,70 +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.
-
-// @dart = 2.9
-
-// Test errors thrown by function imports.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // This module expects a function import like:
-  // int64_t someFn(int32_t a, int64_t b, float c, double d);
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x02, 0x60,
-    0x04, 0x7f, 0x7e, 0x7d, 0x7c, 0x01, 0x7e, 0x60, 0x00, 0x00, 0x02, 0x0e,
-    0x01, 0x03, 0x65, 0x6e, 0x76, 0x06, 0x73, 0x6f, 0x6d, 0x65, 0x46, 0x6e,
-    0x00, 0x00, 0x03, 0x02, 0x01, 0x01, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01,
-    0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41,
-    0x80, 0x88, 0x04, 0x0b, 0x07, 0x11, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f,
-    0x72, 0x79, 0x02, 0x00, 0x04, 0x62, 0x6c, 0x61, 0x68, 0x00, 0x01, 0x0a,
-    0x1d, 0x01, 0x1b, 0x00, 0x41, 0x01, 0x42, 0x02, 0x43, 0x00, 0x00, 0x40,
-    0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x10, 0x80,
-    0x80, 0x80, 0x80, 0x00, 0x1a, 0x0b,
-  ]);
-
-  var mod = WasmModule(data);
-
-  // Valid instantiation.
-  var inst = mod
-      .instantiate()
-      .addFunction("env", "someFn", (int a, int b, num c, double d) => 123)
-      .build();
-
-  // Missing imports.
-  Expect.throws(() => mod.instantiate().build(),
-      (Exception e) => "$e".contains("Missing import"));
-
-  // Wrong kind of import.
-  Expect.throws(
-      () => mod.instantiate().addMemory(false, "env", "someFn", mod.createMemory(10)),
-      (Exception e) => "$e".contains("Import is not a memory"));
-
-  // Wrong namespace.
-  Expect.throws(
-      () => mod
-          .instantiate()
-          .addFunction("foo", "someFn", (int a, int b, num c, double d) => 123)
-          .build(),
-      (Exception e) => "$e".contains("Import not found"));
-
-  // Wrong name.
-  Expect.throws(
-      () => mod
-          .instantiate()
-          .addFunction("env", "otherFn", (int a, int b, num c, double d) => 123)
-          .build(),
-      (Exception e) => "$e".contains("Import not found"));
-
-  // Already filled.
-  Expect.throws(
-      () => mod
-          .instantiate()
-          .addFunction("env", "someFn", (int a, int b, num c, double d) => 123)
-          .addFunction("env", "someFn", (int a, int b, num c, double d) => 456)
-          .build(),
-      (Exception e) => "$e".contains("Import already filled"));
-}
diff --git a/tests/lib_2/wasm/fn_import_exception_test.dart b/tests/lib_2/wasm/fn_import_exception_test.dart
deleted file mode 100644
index 8199023..0000000
--- a/tests/lib_2/wasm/fn_import_exception_test.dart
+++ /dev/null
@@ -1,50 +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.
-
-// @dart = 2.9
-
-// Test throwing exceptions from an imported function.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // void fn() {
-  //   a();
-  //   b();
-  // }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x60,
-    0x00, 0x00, 0x02, 0x11, 0x02, 0x03, 0x65, 0x6e, 0x76, 0x01, 0x61, 0x00,
-    0x00, 0x03, 0x65, 0x6e, 0x76, 0x01, 0x62, 0x00, 0x00, 0x03, 0x02, 0x01,
-    0x00, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00,
-    0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07,
-    0x0f, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02,
-    0x66, 0x6e, 0x00, 0x02, 0x0a, 0x10, 0x01, 0x0e, 0x00, 0x10, 0x80, 0x80,
-    0x80, 0x80, 0x00, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x0b,
-  ]);
-
-  bool called_b = false;
-  var thrownException = Exception("Hello exception!");
-  var inst = WasmModule(data).instantiate().addFunction("env", "a", () {
-    throw thrownException;
-  }).addFunction("env", "b", () {
-    called_b = true;
-  }).build();
-  var fn = inst.lookupFunction("fn");
-  Expect.throws(() => fn(), (Exception e) => e == thrownException);
-  Expect.isFalse(called_b);
-
-  bool called_a = false;
-  inst = WasmModule(data).instantiate().addFunction("env", "a", () {
-    called_a = true;
-  }).addFunction("env", "b", () {
-    called_b = true;
-  }).build();
-  fn = inst.lookupFunction("fn");
-  fn();
-  Expect.isTrue(called_a);
-  Expect.isTrue(called_b);
-}
diff --git a/tests/lib_2/wasm/fn_import_test.dart b/tests/lib_2/wasm/fn_import_test.dart
deleted file mode 100644
index eac6ac0..0000000
--- a/tests/lib_2/wasm/fn_import_test.dart
+++ /dev/null
@@ -1,39 +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.
-
-// @dart = 2.9
-
-// Test that we can load a wasm module, find a function, and call it.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // void reportStuff() { report(123, 456); }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x09, 0x02, 0x60,
-    0x02, 0x7e, 0x7e, 0x00, 0x60, 0x00, 0x00, 0x02, 0x0e, 0x01, 0x03, 0x65,
-    0x6e, 0x76, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x03,
-    0x02, 0x01, 0x01, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01, 0x01, 0x05, 0x03,
-    0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41, 0x80, 0x88, 0x04,
-    0x0b, 0x07, 0x18, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02,
-    0x00, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x75, 0x66,
-    0x66, 0x00, 0x01, 0x0a, 0x10, 0x01, 0x0e, 0x00, 0x42, 0xfb, 0x00, 0x42,
-    0xc8, 0x03, 0x10, 0x80, 0x80, 0x80, 0x80, 0x00, 0x0b,
-  ]);
-
-  int report_x = -1;
-  int report_y = -1;
-
-  var inst = WasmModule(data).instantiate()
-    .addFunction("env", "report", (int x, int y) {
-      report_x = x;
-      report_y = y;
-    }).build();
-  var fn = inst.lookupFunction("reportStuff");
-  fn();
-  Expect.equals(report_x, 123);
-  Expect.equals(report_y, 456);
-}
diff --git a/tests/lib_2/wasm/hello_wasi_test.dart b/tests/lib_2/wasm/hello_wasi_test.dart
deleted file mode 100644
index 3dd5d43..0000000
--- a/tests/lib_2/wasm/hello_wasi_test.dart
+++ /dev/null
@@ -1,186 +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.
-
-// @dart = 2.9
-
-// Variant of hello_world_test that uses the default WASI imports.
-
-import "package:async_helper/async_helper.dart";
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:convert";
-import "dart:typed_data";
-
-void main() async {
-  asyncStart();
-
-  // Hello world module generated by emscripten+WASI. Exports a function like
-  // `void _start()`, and prints using `int fd_write(int, int, int, int)`.
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
-    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
-    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
-    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
-    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
-    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
-    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
-    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
-    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
-    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
-    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
-    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
-    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
-    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
-    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
-    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
-    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
-    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
-    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
-    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
-    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
-    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
-    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
-    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
-    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
-    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
-    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
-    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
-    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
-    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
-    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
-    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
-    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
-    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
-    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
-    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
-    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
-    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
-    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
-    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
-    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
-    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
-    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
-    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
-    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
-    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
-    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
-    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
-    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
-    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
-    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
-    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
-    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
-    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
-    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
-    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
-    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
-    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
-    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
-    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
-    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
-    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
-    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
-    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
-    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
-    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
-    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
-    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
-    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
-    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
-    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
-    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
-    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
-    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
-    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
-    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
-    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
-    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
-    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
-    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
-    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
-    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
-    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
-    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
-    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
-    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
-    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
-    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
-    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
-    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
-    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
-    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
-    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
-    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
-    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
-    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
-    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
-    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
-    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
-    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
-    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
-    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
-    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
-    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
-    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
-    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
-    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
-    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
-    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
-    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
-    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
-    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
-    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
-    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
-    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
-    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
-    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
-    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
-    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
-    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
-    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
-    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
-    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
-    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
-    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
-  ]);
-
-  var inst =
-      WasmModule(data).instantiate().enableWasi(captureStdout: true).build();
-
-  var fn = inst.lookupFunction("_start");
-  fn();
-  var out = utf8.decode(await inst.stdout.first);
-  Expect.equals("hello, world!\n", out);
-  asyncEnd();
-}
diff --git a/tests/lib_2/wasm/hello_world_test.dart b/tests/lib_2/wasm/hello_world_test.dart
deleted file mode 100644
index 3c09a5e..0000000
--- a/tests/lib_2/wasm/hello_world_test.dart
+++ /dev/null
@@ -1,207 +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.
-
-// @dart = 2.9
-
-// Test for hello world built using emscripten with WASI.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // Hello world module generated by emscripten+WASI. Exports a function like
-  // `void _start()`, and prints using `int fd_write(int, int, int, int)`.
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
-    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
-    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
-    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
-    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
-    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
-    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
-    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
-    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
-    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
-    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
-    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
-    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
-    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
-    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
-    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
-    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
-    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
-    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
-    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
-    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
-    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
-    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
-    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
-    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
-    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
-    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
-    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
-    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
-    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
-    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
-    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
-    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
-    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
-    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
-    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
-    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
-    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
-    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
-    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
-    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
-    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
-    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
-    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
-    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
-    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
-    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
-    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
-    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
-    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
-    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
-    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
-    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
-    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
-    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
-    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
-    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
-    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
-    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
-    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
-    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
-    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
-    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
-    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
-    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
-    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
-    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
-    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
-    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
-    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
-    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
-    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
-    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
-    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
-    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
-    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
-    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
-    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
-    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
-    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
-    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
-    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
-    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
-    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
-    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
-    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
-    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
-    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
-    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
-    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
-    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
-    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
-    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
-    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
-    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
-    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
-    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
-    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
-    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
-    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
-    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
-    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
-    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
-    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
-    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
-    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
-    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
-    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
-    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
-    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
-    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
-    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
-    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
-    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
-    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
-    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
-    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
-    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
-    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
-    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
-    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
-    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
-    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
-    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
-    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
-  ]);
-
-  WasmMemory mem = null;
-  String out = "";
-  var getI32 = (int p) {
-    // Read a little-endian I32.
-    int n = 0;
-    for (var i = p + 3; i >= p; --i) {
-      n *= 256;
-      n += mem[i];
-    }
-    return n;
-  };
-  var inst = WasmModule(data)
-      .instantiate()
-      .addFunction("wasi_unstable", "fd_write",
-          (int fd, int iovs, int iovs_len, int unused) {
-    // iovs points to an array of length iovs_len. Each element is two I32s,
-    // a char* and a length.
-    String o = "";
-    for (var i = 0; i < iovs_len; ++i) {
-      var str = getI32(iovs + 8 * i);
-      var len = getI32(iovs + 4 + 8 * i);
-      for (var j = 0; j < len; ++j) {
-        o += String.fromCharCode(mem[str + j]);
-      }
-    }
-    out += o;
-    return o.length;
-  }).build();
-  mem = inst.memory;
-
-  var fn = inst.lookupFunction("_start");
-  fn();
-  Expect.equals("hello, world!\n", out);
-}
diff --git a/tests/lib_2/wasm/import_error_test.dart b/tests/lib_2/wasm/import_error_test.dart
deleted file mode 100644
index a1b6536..0000000
--- a/tests/lib_2/wasm/import_error_test.dart
+++ /dev/null
@@ -1,20 +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.
-
-// @dart = 2.9
-
-// Test errors thrown by WasmImports.
-
-import "package:expect/expect.dart";
-import "dart:wasm";
-import "dart:typed_data";
-
-void main() {
-  var imp = WasmImports();
-  imp.addGlobal<Int64>("env", "x", 123, false);
-  imp.addGlobal<Double>("env", "y", 4.56, true);
-  Expect.throwsArgumentError(() => imp.addGlobal<int>("env", "a", 1, true));
-  Expect.throwsArgumentError(() => imp.addGlobal<double>("env", "b", 2, true));
-  Expect.throwsArgumentError(() => imp.addGlobal<dynamic>("env", "c", 3, true));
-}
diff --git a/tests/lib_2/wasm/memory_error_test.dart b/tests/lib_2/wasm/memory_error_test.dart
deleted file mode 100644
index 34825e7..0000000
--- a/tests/lib_2/wasm/memory_error_test.dart
+++ /dev/null
@@ -1,24 +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.
-
-// @dart = 2.9
-
-// Test errors thrown by WasmMemory.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // Empty wasm module.
-  var data = Uint8List.fromList(
-      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
-  var module = WasmModule(data);
-
-  Expect.throws(() => module.createMemory(1000000000));
-  var mem = module.createMemory(100);
-  Expect.throws(() => mem.grow(1000000000));
-  mem = module.createMemory(100, 200);
-  Expect.throws(() => mem.grow(300));
-}
diff --git a/tests/lib_2/wasm/memory_test.dart b/tests/lib_2/wasm/memory_test.dart
deleted file mode 100644
index 7b58af4..0000000
--- a/tests/lib_2/wasm/memory_test.dart
+++ /dev/null
@@ -1,30 +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.
-
-// @dart = 2.9
-
-// Test that we can create a WasmMemory, edit it, and grow it.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // Empty wasm module.
-  var data = Uint8List.fromList(
-      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
-  var module = WasmModule(data);
-
-  var mem = module.createMemory(100);
-  Expect.equals(100, mem.lengthInPages);
-  Expect.equals(100 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
-
-  mem[123] = 45;
-  Expect.equals(45, mem[123]);
-
-  mem.grow(10);
-  Expect.equals(110, mem.lengthInPages);
-  Expect.equals(110 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
-  Expect.equals(45, mem[123]);
-}
diff --git a/tests/lib_2/wasm/numerics_test.dart b/tests/lib_2/wasm/numerics_test.dart
deleted file mode 100644
index 2cf73bb..0000000
--- a/tests/lib_2/wasm/numerics_test.dart
+++ /dev/null
@@ -1,51 +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.
-
-// @dart = 2.9
-
-// Test numeric types.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // int64_t addI64(int64_t x, int64_t y) { return x + y; }
-  // int32_t addI32(int32_t x, int32_t y) { return x + y; }
-  // double addF64(double x, double y) { return x + y; }
-  // float addF32(float x, float y) { return x + y; }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x19, 0x04, 0x60,
-    0x02, 0x7e, 0x7e, 0x01, 0x7e, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
-    0x02, 0x7c, 0x7c, 0x01, 0x7c, 0x60, 0x02, 0x7d, 0x7d, 0x01, 0x7d, 0x03,
-    0x05, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01,
-    0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41,
-    0x80, 0x88, 0x04, 0x0b, 0x07, 0x2e, 0x05, 0x06, 0x6d, 0x65, 0x6d, 0x6f,
-    0x72, 0x79, 0x02, 0x00, 0x06, 0x61, 0x64, 0x64, 0x49, 0x36, 0x34, 0x00,
-    0x00, 0x06, 0x61, 0x64, 0x64, 0x49, 0x33, 0x32, 0x00, 0x01, 0x06, 0x61,
-    0x64, 0x64, 0x46, 0x36, 0x34, 0x00, 0x02, 0x06, 0x61, 0x64, 0x64, 0x46,
-    0x33, 0x32, 0x00, 0x03, 0x0a, 0x21, 0x04, 0x07, 0x00, 0x20, 0x01, 0x20,
-    0x00, 0x7c, 0x0b, 0x07, 0x00, 0x20, 0x01, 0x20, 0x00, 0x6a, 0x0b, 0x07,
-    0x00, 0x20, 0x00, 0x20, 0x01, 0xa0, 0x0b, 0x07, 0x00, 0x20, 0x00, 0x20,
-    0x01, 0x92, 0x0b,
-  ]);
-
-  var inst = WasmModule(data).instantiate().build();
-  var addI64 = inst.lookupFunction("addI64");
-  var addI32 = inst.lookupFunction("addI32");
-  var addF64 = inst.lookupFunction("addF64");
-  var addF32 = inst.lookupFunction("addF32");
-
-  int i64 = addI64(0x123456789ABCDEF, 0xFEDCBA987654321);
-  Expect.equals(0x1111111111111110, i64);
-
-  int i32 = addI32(0xABCDEF, 0xFEDCBA);
-  Expect.equals(0x1aaaaa9, i32);
-
-  double f64 = addF64(1234.5678, 8765.4321);
-  Expect.approxEquals(9999.9999, f64, 1e-6);
-
-  double f32 = addF32(1234.5678, 8765.4321);
-  Expect.approxEquals(9999.9999, f32, 1e-3);
-}
diff --git a/tests/lib_2/wasm/void_test.dart b/tests/lib_2/wasm/void_test.dart
deleted file mode 100644
index 2281603..0000000
--- a/tests/lib_2/wasm/void_test.dart
+++ /dev/null
@@ -1,36 +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.
-
-// @dart = 2.9
-
-// Test functions with void return type, and functions that take no args.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // int64_t x = 0;
-  // void set(int64_t a, int64_t b) { x = a + b; }
-  // int64_t get() { return x; }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x02, 0x60,
-    0x02, 0x7e, 0x7e, 0x00, 0x60, 0x00, 0x01, 0x7e, 0x03, 0x03, 0x02, 0x00,
-    0x01, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00,
-    0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41, 0x90, 0x88, 0x04, 0x0b, 0x07,
-    0x16, 0x03, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x03,
-    0x73, 0x65, 0x74, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, 0x01, 0x0a,
-    0x1e, 0x02, 0x10, 0x00, 0x41, 0x00, 0x20, 0x01, 0x20, 0x00, 0x7c, 0x37,
-    0x03, 0x80, 0x88, 0x80, 0x80, 0x00, 0x0b, 0x0b, 0x00, 0x41, 0x00, 0x29,
-    0x03, 0x80, 0x88, 0x80, 0x80, 0x00, 0x0b, 0x0b, 0x0f, 0x01, 0x00, 0x41,
-    0x80, 0x08, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  ]);
-
-  var inst = WasmModule(data).instantiate().build();
-  var setFn = inst.lookupFunction("set");
-  var getFn = inst.lookupFunction("get");
-  Expect.isNull(setFn(123, 456));
-  int n = getFn();
-  Expect.equals(123 + 456, n);
-}
diff --git a/tests/lib_2/wasm/wasi_error_test.dart b/tests/lib_2/wasm/wasi_error_test.dart
deleted file mode 100644
index d121681..0000000
--- a/tests/lib_2/wasm/wasi_error_test.dart
+++ /dev/null
@@ -1,206 +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.
-
-// @dart = 2.9
-
-// Test the errors that can be thrown by WASI.
-
-import "package:expect/expect.dart";
-import "package:wasm/wasm.dart";
-import "dart:typed_data";
-
-void main() {
-  // Empty wasm module.
-  var emptyModuleData = Uint8List.fromList(
-      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
-
-  // Failed to fill WASI imports (the empty module was not built with WASI).
-  Expect.throws(() => WasmModule(emptyModuleData).instantiate().enableWasi(),
-      (Exception e) => "$e".contains("Failed to fill WASI imports"));
-
-  // Hello world module generated by emscripten+WASI. Exports a function like
-  // `void _start()`, and prints using `int fd_write(int, int, int, int)`.
-  var helloWorldData = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
-    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
-    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
-    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
-    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
-    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
-    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
-    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
-    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
-    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
-    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
-    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
-    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
-    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
-    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
-    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
-    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
-    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
-    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
-    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
-    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
-    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
-    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
-    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
-    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
-    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
-    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
-    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
-    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
-    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
-    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
-    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
-    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
-    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
-    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
-    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
-    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
-    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
-    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
-    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
-    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
-    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
-    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
-    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
-    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
-    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
-    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
-    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
-    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
-    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
-    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
-    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
-    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
-    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
-    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
-    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
-    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
-    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
-    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
-    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
-    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
-    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
-    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
-    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
-    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
-    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
-    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
-    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
-    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
-    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
-    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
-    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
-    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
-    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
-    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
-    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
-    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
-    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
-    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
-    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
-    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
-    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
-    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
-    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
-    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
-    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
-    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
-    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
-    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
-    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
-    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
-    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
-    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
-    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
-    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
-    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
-    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
-    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
-    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
-    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
-    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
-    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
-    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
-    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
-    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
-    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
-    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
-    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
-    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
-    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
-    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
-    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
-    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
-    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
-    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
-    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
-    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
-    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
-    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
-    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
-    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
-    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
-    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
-    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
-    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
-    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
-    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
-    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
-    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
-    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
-    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
-    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
-    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
-    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
-    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
-    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
-    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
-    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
-  ]);
-
-  // Trying to import WASI twice.
-  Expect.throws(
-      () => WasmModule(helloWorldData).instantiate().enableWasi().enableWasi(),
-      (Exception e) => "$e".contains("WASI is already enabled"));
-
-  // Missing imports due to not enabling WASI.
-  Expect.throws(() => WasmModule(helloWorldData).instantiate().build(),
-      (Exception e) => "$e".contains("Missing import"));
-
-  // Trying to get stdout/stderr without WASI enabled (WASI function import has
-  // been manually filled).
-  var inst = WasmModule(helloWorldData)
-      .instantiate()
-      .addFunction("wasi_unstable", "fd_write",
-          (int fd, int iovs, int iovs_len, int unused) => 0)
-      .build();
-  Expect.throws(
-      () => inst.stdout,
-      (Exception e) =>
-          "$e".contains("Can't capture stdout without WASI enabled"));
-  Expect.throws(
-      () => inst.stderr,
-      (Exception e) =>
-          "$e".contains("Can't capture stderr without WASI enabled"));
-}
diff --git a/tests/standalone/io/file_pipe_test.dart b/tests/standalone/io/file_pipe_test.dart
new file mode 100644
index 0000000..e36f91f
--- /dev/null
+++ b/tests/standalone/io/file_pipe_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2013, 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 test program for testing the dart:io `Pipe` class
+
+import 'dart:io';
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+testReadFromClosedPipe() async {
+  final pipe = await Pipe.create();
+  pipe.write.close();
+  Expect.isTrue(await pipe.read.isEmpty);
+}
+
+testCreateSync() async {
+  final pipe = Pipe.createSync();
+  pipe.write.close();
+  Expect.isTrue(await pipe.read.isEmpty);
+}
+
+testMultipleWritesAndReads() async {
+  final pipe = await Pipe.create();
+  int count = 0;
+  pipe.write.add([count]);
+  await pipe.read.listen((event) {
+    Expect.listEquals([count], event);
+    ++count;
+    if (count < 10) {
+      pipe.write.add([count]);
+    } else {
+      pipe.write.close();
+    }
+  }, onDone: () => Expect.equals(10, count));
+}
+
+main() async {
+  asyncStart();
+  try {
+    await testReadFromClosedPipe();
+    await testCreateSync();
+    await testMultipleWritesAndReads();
+  } finally {
+    asyncEnd();
+  }
+}
diff --git a/tests/standalone/io/file_stream_test.dart b/tests/standalone/io/file_stream_test.dart
index 2d3577e..5d9ddcb 100644
--- a/tests/standalone/io/file_stream_test.dart
+++ b/tests/standalone/io/file_stream_test.dart
@@ -58,7 +58,27 @@
   });
 }
 
-void main() {
+Future<void> testStreamAppendedToAfterOpen() async {
+  asyncStart();
+
+  final pipe = Pipe.createSync();
+  pipe.write.add("Hello World".codeUnits);
+  int i = 0;
+  await pipe.read.listen((event) {
+    Expect.listEquals("Hello World".codeUnits, event);
+    if (i < 10) {
+      pipe.write.add("Hello World".codeUnits);
+      ++i;
+    } else {
+      pipe.write.close();
+    }
+  }).asFuture();
+
+  asyncEnd();
+}
+
+void main() async {
   testPauseResumeCancelStream();
   testStreamIsEmpty();
+  await testStreamAppendedToAfterOpen();
 }
diff --git a/tests/standalone/io/http_auth_digest_test.dart b/tests/standalone/io/http_auth_digest_test.dart
index 5a533a2..0c7195f 100644
--- a/tests/standalone/io/http_auth_digest_test.dart
+++ b/tests/standalone/io/http_auth_digest_test.dart
@@ -17,7 +17,7 @@
   var ha1;
 
   static Future<Server> start(String? algorithm, String? qop,
-      {int? nonceStaleAfter, bool useNextNonce: false}) {
+      {int? nonceStaleAfter, bool useNextNonce = false}) {
     return new Server()._start(algorithm, qop, nonceStaleAfter, useNextNonce);
   }
 
@@ -37,7 +37,7 @@
     HttpServer.bind("127.0.0.1", 0).then((s) {
       server = s;
       server.listen((HttpRequest request) {
-        sendUnauthorizedResponse(HttpResponse response, {stale: false}) {
+        sendUnauthorizedResponse(HttpResponse response, {stale = false}) {
           response.statusCode = HttpStatus.unauthorized;
           StringBuffer authHeader = new StringBuffer();
           authHeader.write('Digest');
diff --git a/tests/standalone/io/http_compression_test.dart b/tests/standalone/io/http_compression_test.dart
index 594d5d7..1682ae8 100644
--- a/tests/standalone/io/http_compression_test.dart
+++ b/tests/standalone/io/http_compression_test.dart
@@ -11,7 +11,7 @@
 import 'dart:io';
 import 'dart:typed_data';
 
-Future<void> testServerCompress({bool clientAutoUncompress: true}) async {
+Future<void> testServerCompress({bool clientAutoUncompress = true}) async {
   Future<void> test(List<int> data) async {
     final server = await HttpServer.bind("127.0.0.1", 0);
     server.autoCompress = true;
diff --git a/tests/standalone/io/http_cookie_date_test.dart b/tests/standalone/io/http_cookie_date_test.dart
index dc1787d..fa79bf3 100644
--- a/tests/standalone/io/http_cookie_date_test.dart
+++ b/tests/standalone/io/http_cookie_date_test.dart
@@ -16,7 +16,11 @@
 import "package:expect/expect.dart";
 
 import "../../../sdk/lib/internal/internal.dart"
-    show Since, valueOfNonNullableParamWithDefault, HttpStatus;
+    show
+        checkNotNullable,
+        Since,
+        valueOfNonNullableParamWithDefault,
+        HttpStatus;
 
 part "../../../sdk/lib/_http/crypto.dart";
 part "../../../sdk/lib/_http/embedder_config.dart";
diff --git a/tests/standalone/io/http_force_staggered_ipv6_lookup_test.dart b/tests/standalone/io/http_force_staggered_ipv6_lookup_test.dart
index c644488..c191cc4 100644
--- a/tests/standalone/io/http_force_staggered_ipv6_lookup_test.dart
+++ b/tests/standalone/io/http_force_staggered_ipv6_lookup_test.dart
@@ -22,7 +22,7 @@
   }, test: (error) => error is! String);
 }
 
-void testConnect(InternetAddress loopback, {int expectedElapsedMs: 0}) async {
+void testConnect(InternetAddress loopback, {int expectedElapsedMs = 0}) async {
   asyncStart();
   final max = 10;
   final servers = <ServerSocket>[];
diff --git a/tests/standalone/io/http_headers_test.dart b/tests/standalone/io/http_headers_test.dart
index 99884f6..d1b2450 100644
--- a/tests/standalone/io/http_headers_test.dart
+++ b/tests/standalone/io/http_headers_test.dart
@@ -16,7 +16,11 @@
 import "package:expect/expect.dart";
 
 import "../../../sdk/lib/internal/internal.dart"
-    show Since, valueOfNonNullableParamWithDefault, HttpStatus;
+    show
+        checkNotNullable,
+        Since,
+        valueOfNonNullableParamWithDefault,
+        HttpStatus;
 
 part "../../../sdk/lib/_http/crypto.dart";
 part "../../../sdk/lib/_http/embedder_config.dart";
@@ -659,7 +663,7 @@
 }
 
 void testInvalidFieldValue() {
-  void test(value, {bool remove: true}) {
+  void test(value, {bool remove = true}) {
     _HttpHeaders headers = new _HttpHeaders("1.1");
     Expect.throwsFormatException(() => headers.add("field", value));
     Expect.throwsFormatException(() => headers.set("field", value));
diff --git a/tests/standalone/io/http_open_method_validate_test.dart b/tests/standalone/io/http_open_method_validate_test.dart
new file mode 100644
index 0000000..484a4ab
--- /dev/null
+++ b/tests/standalone/io/http_open_method_validate_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, 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.
+//
+// Verify that HttpClient open, openUrl method argument is validated.
+
+import "dart:io";
+import "package:expect/expect.dart";
+
+void testInvalidArgumentException(String method) {
+  Expect.throws(() => HttpClient()..open(method, "127.0.0.1", 8080, "/"),
+      (e) => e is ArgumentError);
+  Expect.throws(
+      () => HttpClient()..openUrl(method, Uri.parse("http://127.0.0.1/")),
+      (e) => e is ArgumentError);
+}
+
+main() {
+  const String separators = "\t\n\r()<>@,;:\\/[]?={}";
+  for (int i = 0; i < separators.length; i++) {
+    String separator = separators.substring(i, i + 1);
+    testInvalidArgumentException(separator);
+    testInvalidArgumentException(separator + "CONNECT");
+    testInvalidArgumentException("CONN" + separator + "ECT");
+    testInvalidArgumentException("CONN" + separator + separator + "ECT");
+    testInvalidArgumentException("CONNECT" + separator);
+  }
+}
diff --git a/tests/standalone/io/http_override_test.dart b/tests/standalone/io/http_override_test.dart
index fccbbe4..258a055 100644
--- a/tests/standalone/io/http_override_test.dart
+++ b/tests/standalone/io/http_override_test.dart
@@ -53,7 +53,7 @@
   set badCertificateCallback(
       bool callback(X509Certificate cert, String host, int port)?) {}
   void set keyLog(Function(String line)? callback) {}
-  void close({bool force: false}) {}
+  void close({bool force = false}) {}
 }
 
 class MyHttpClient2 implements HttpClient {
@@ -102,7 +102,7 @@
   set badCertificateCallback(
       bool callback(X509Certificate cert, String host, int port)?) {}
   void set keyLog(Function(String line)? callback) {}
-  void close({bool force: false}) {}
+  void close({bool force = false}) {}
 }
 
 class MyHttpOverrides extends HttpOverrides {
diff --git a/tests/standalone/io/http_parser_test.dart b/tests/standalone/io/http_parser_test.dart
index 300ed63..c3b98d5f 100644
--- a/tests/standalone/io/http_parser_test.dart
+++ b/tests/standalone/io/http_parser_test.dart
@@ -16,7 +16,11 @@
 import "package:expect/expect.dart";
 
 import "../../../sdk/lib/internal/internal.dart"
-    show Since, valueOfNonNullableParamWithDefault, HttpStatus;
+    show
+        checkNotNullable,
+        Since,
+        valueOfNonNullableParamWithDefault,
+        HttpStatus;
 
 part "../../../sdk/lib/_http/crypto.dart";
 part "../../../sdk/lib/_http/embedder_config.dart";
@@ -47,14 +51,14 @@
 
   void _testParseRequest(
       String request, String expectedMethod, String expectedUri,
-      {int expectedTransferLength: 0,
-      int expectedBytesReceived: 0,
-      Map<String, String>? expectedHeaders: null,
-      bool chunked: false,
-      bool upgrade: false,
-      int unparsedLength: 0,
-      bool connectionClose: false,
-      String expectedVersion: "1.1"}) {
+      {int expectedTransferLength = 0,
+      int expectedBytesReceived = 0,
+      Map<String, String>? expectedHeaders = null,
+      bool chunked = false,
+      bool upgrade = false,
+      int unparsedLength = 0,
+      bool connectionClose = false,
+      String expectedVersion = "1.1"}) {
     late StreamController<Uint8List> controller;
     void reset() {
       _HttpParser httpParser = new _HttpParser.requestParser();
@@ -139,14 +143,14 @@
 
   void _testParseRequestLean(
       String request, String expectedMethod, String expectedUri,
-      {int expectedTransferLength: 0,
-      int expectedBytesReceived: 0,
-      Map<String, String>? expectedHeaders: null,
-      bool chunked: false,
-      bool upgrade: false,
-      int unparsedLength: 0,
-      bool connectionClose: false,
-      String expectedVersion: "1.1"}) {
+      {int expectedTransferLength = 0,
+      int expectedBytesReceived = 0,
+      Map<String, String>? expectedHeaders = null,
+      bool chunked = false,
+      bool upgrade = false,
+      int unparsedLength = 0,
+      bool connectionClose = false,
+      String expectedVersion = "1.1"}) {
     _testParseRequest(request, expectedMethod, expectedUri,
         expectedTransferLength: expectedTransferLength,
         expectedBytesReceived: expectedBytesReceived,
@@ -214,16 +218,16 @@
 
   void _testParseResponse(
       String response, int expectedStatusCode, String expectedReasonPhrase,
-      {int expectedTransferLength: 0,
-      int expectedBytesReceived: 0,
-      Map<String, String>? expectedHeaders: null,
-      bool chunked: false,
-      bool close: false,
-      String? responseToMethod: null,
-      bool connectionClose: false,
-      bool upgrade: false,
-      int unparsedLength: 0,
-      String expectedVersion: "1.1"}) {
+      {int expectedTransferLength = 0,
+      int expectedBytesReceived = 0,
+      Map<String, String>? expectedHeaders = null,
+      bool chunked = false,
+      bool close = false,
+      String? responseToMethod = null,
+      bool connectionClose = false,
+      bool upgrade = false,
+      int unparsedLength = 0,
+      String expectedVersion = "1.1"}) {
     late StreamController<Uint8List> controller;
     bool upgraded;
 
diff --git a/tests/standalone/io/http_proxy_advanced_test.dart b/tests/standalone/io/http_proxy_advanced_test.dart
index d29a42d..2b9c58f 100644
--- a/tests/standalone/io/http_proxy_advanced_test.dart
+++ b/tests/standalone/io/http_proxy_advanced_test.dart
@@ -82,7 +82,7 @@
 }
 
 Future<Server> setupServer(int proxyHops,
-    {List<String> directRequestPaths: const <String>[], secure: false}) {
+    {List<String> directRequestPaths = const <String>[], secure = false}) {
   Server server = new Server(proxyHops, directRequestPaths, secure);
   return server.start();
 }
@@ -104,7 +104,7 @@
 
   var nonce = "12345678"; // No need for random nonce in test.
 
-  ProxyServer({this.ipV6: false});
+  ProxyServer({this.ipV6 = false});
 
   void useBasicAuthentication(String username, String password) {
     this.username = username;
@@ -132,7 +132,7 @@
     });
   }
 
-  digestAuthenticationRequired(request, {stale: false}) {
+  digestAuthenticationRequired(request, {stale = false}) {
     request.fold(null, (x, y) {}).then((_) {
       var response = request.response;
       response.statusCode = HttpStatus.proxyAuthenticationRequired;
@@ -277,7 +277,7 @@
   int get port => server.port;
 }
 
-Future<ProxyServer> setupProxyServer({ipV6: false}) {
+Future<ProxyServer> setupProxyServer({ipV6 = false}) {
   ProxyServer proxyServer = new ProxyServer(ipV6: ipV6);
   return proxyServer.start();
 }
@@ -332,8 +332,8 @@
   });
 }
 
-int testProxyFromEnviromentDoneCount = 0;
-void testProxyFromEnviroment() {
+int testProxyFromEnvironmentDoneCount = 0;
+void testProxyFromEnvironment() {
   setupProxyServer().then((proxyServer) {
     setupServer(1).then((server) {
       setupServer(1, secure: true).then((secureServer) {
@@ -361,8 +361,8 @@
               return clientRequest.close();
             }).then((HttpClientResponse response) {
               response.listen((_) {}, onDone: () {
-                testProxyFromEnviromentDoneCount++;
-                if (testProxyFromEnviromentDoneCount == loopCount * 2) {
+                testProxyFromEnvironmentDoneCount++;
+                if (testProxyFromEnvironmentDoneCount == loopCount * 2) {
                   Expect.equals(loopCount, server.requestCount);
                   Expect.equals(loopCount, secureServer.requestCount);
                   proxyServer.shutdown();
@@ -612,7 +612,7 @@
 
 main() {
   testProxyIPV6();
-  testProxyFromEnviroment();
+  testProxyFromEnvironment();
   // The two invocations use the same global variable for state -
   // run one after the other.
   testProxyAuthenticate(false).then((_) => testProxyAuthenticate(true));
diff --git a/tests/standalone/io/http_proxy_test.dart b/tests/standalone/io/http_proxy_test.dart
index d13d0ba..93d07b4 100644
--- a/tests/standalone/io/http_proxy_test.dart
+++ b/tests/standalone/io/http_proxy_test.dart
@@ -82,7 +82,7 @@
 }
 
 Future<Server> setupServer(int proxyHops,
-    {List<String> directRequestPaths: const <String>[], secure: false}) {
+    {List<String> directRequestPaths = const <String>[], secure = false}) {
   Server server = new Server(proxyHops, directRequestPaths, secure);
   return server.start();
 }
@@ -104,7 +104,7 @@
 
   var nonce = "12345678"; // No need for random nonce in test.
 
-  ProxyServer({this.ipV6: false});
+  ProxyServer({this.ipV6 = false});
 
   void useBasicAuthentication(String username, String password) {
     this.username = username;
@@ -122,7 +122,7 @@
     });
   }
 
-  digestAuthenticationRequired(request, {stale: false}) {
+  digestAuthenticationRequired(request, {stale = false}) {
     request.fold(null, (x, y) {}).then((_) {
       var response = request.response;
       response.statusCode = HttpStatus.proxyAuthenticationRequired;
@@ -266,7 +266,7 @@
   int get port => server.port;
 }
 
-Future<ProxyServer> setupProxyServer({ipV6: false}) {
+Future<ProxyServer> setupProxyServer({ipV6 = false}) {
   ProxyServer proxyServer = new ProxyServer(ipV6: ipV6);
   return proxyServer.start();
 }
diff --git a/tests/standalone/io/io_override_test.dart b/tests/standalone/io/io_override_test.dart
index 5b3234a..aefaf01 100644
--- a/tests/standalone/io/io_override_test.dart
+++ b/tests/standalone/io/io_override_test.dart
@@ -21,8 +21,8 @@
   static DirectoryMock getSystemTemp() => new DirectoryMock("");
 
   Uri get uri => throw "";
-  Future<Directory> create({bool recursive: false}) => throw "";
-  void createSync({bool recursive: false}) {}
+  Future<Directory> create({bool recursive = false}) => throw "";
+  void createSync({bool recursive = false}) {}
   Future<Directory> createTemp([String? prefix]) => throw "";
   Directory createTempSync([String? prefix]) => throw "";
   Future<bool> exists() => throw "";
@@ -33,10 +33,10 @@
   Directory renameSync(String newPath) => throw "";
   Directory get absolute => throw "";
   Stream<FileSystemEntity> list(
-          {bool recursive: false, bool followLinks: true}) =>
+          {bool recursive = false, bool followLinks = true}) =>
       throw "";
   List<FileSystemEntity> listSync(
-          {bool recursive: false, bool followLinks: true}) =>
+          {bool recursive = false, bool followLinks = true}) =>
       throw "";
 }
 
@@ -47,9 +47,9 @@
 
   static FileMock createFile(String path) => new FileMock(path);
 
-  Future<File> create({bool recursive: false, bool exclusive: false}) =>
+  Future<File> create({bool recursive = false, bool exclusive = false}) =>
       throw "";
-  void createSync({bool recursive: false, bool exclusive: false}) {}
+  void createSync({bool recursive = false, bool exclusive = false}) {}
   Future<File> rename(String newPath) => throw "";
   File renameSync(String newPath) => throw "";
   Future<File> copy(String newPath) => throw "";
@@ -67,31 +67,32 @@
   DateTime lastModifiedSync() => throw "";
   Future setLastModified(DateTime time) => throw "";
   void setLastModifiedSync(DateTime time) {}
-  Future<RandomAccessFile> open({FileMode mode: FileMode.read}) => throw "";
-  RandomAccessFile openSync({FileMode mode: FileMode.read}) => throw "";
+  Future<RandomAccessFile> open({FileMode mode = FileMode.read}) => throw "";
+  RandomAccessFile openSync({FileMode mode = FileMode.read}) => throw "";
   Stream<List<int>> openRead([int? start, int? end]) => throw "";
-  IOSink openWrite({FileMode mode: FileMode.write, Encoding encoding: utf8}) =>
+  IOSink openWrite(
+          {FileMode mode = FileMode.write, Encoding encoding = utf8}) =>
       throw "";
   Future<Uint8List> readAsBytes() => throw "";
   Uint8List readAsBytesSync() => throw "";
-  Future<String> readAsString({Encoding encoding: utf8}) => throw "";
-  String readAsStringSync({Encoding encoding: utf8}) => throw "";
-  Future<List<String>> readAsLines({Encoding encoding: utf8}) => throw "";
-  List<String> readAsLinesSync({Encoding encoding: utf8}) => throw "";
+  Future<String> readAsString({Encoding encoding = utf8}) => throw "";
+  String readAsStringSync({Encoding encoding = utf8}) => throw "";
+  Future<List<String>> readAsLines({Encoding encoding = utf8}) => throw "";
+  List<String> readAsLinesSync({Encoding encoding = utf8}) => throw "";
   Future<File> writeAsBytes(List<int> bytes,
-          {FileMode mode: FileMode.write, bool flush: false}) =>
+          {FileMode mode = FileMode.write, bool flush = false}) =>
       throw "";
   void writeAsBytesSync(List<int> bytes,
-      {FileMode mode: FileMode.write, bool flush: false}) {}
+      {FileMode mode = FileMode.write, bool flush = false}) {}
   Future<File> writeAsString(String contents,
-          {FileMode mode: FileMode.write,
-          Encoding encoding: utf8,
-          bool flush: false}) =>
+          {FileMode mode = FileMode.write,
+          Encoding encoding = utf8,
+          bool flush = false}) =>
       throw "";
   void writeAsStringSync(String contents,
-      {FileMode mode: FileMode.write,
-      Encoding encoding: utf8,
-      bool flush: false}) {}
+      {FileMode mode = FileMode.write,
+      Encoding encoding = utf8,
+      bool flush = false}) {}
 }
 
 class FileStatMock implements FileStat {
@@ -146,8 +147,8 @@
 
   static Link createLink(String path) => new LinkMock(path);
 
-  Future<Link> create(String target, {bool recursive: false}) => throw "";
-  void createSync(String target, {bool recursive: false}) {}
+  Future<Link> create(String target, {bool recursive = false}) => throw "";
+  void createSync(String target, {bool recursive = false}) {}
   void updateSync(String target) {}
   Future<Link> update(String target) => throw "";
   Future<bool> exists() => throw "";
@@ -172,7 +173,7 @@
 }
 
 Future<ServerSocket> serverSocketBind(dynamic address, int port,
-    {int backlog: 0, bool v6Only: false, bool shared: false}) async {
+    {int backlog = 0, bool v6Only = false, bool shared = false}) async {
   throw "";
 }
 
diff --git a/tests/standalone/io/io_sink_test.dart b/tests/standalone/io/io_sink_test.dart
index daeb997..d34d56c 100644
--- a/tests/standalone/io/io_sink_test.dart
+++ b/tests/standalone/io/io_sink_test.dart
@@ -16,7 +16,7 @@
   bool expectClose;
 
   TestConsumer(this.expected,
-      {this.expectClose: true, this.expcetedAddStreamCount: -1}) {
+      {this.expectClose = true, this.expcetedAddStreamCount = -1}) {
     if (expectClose) asyncStart();
   }
 
diff --git a/tests/standalone/io/resource_handle_test.dart b/tests/standalone/io/resource_handle_test.dart
new file mode 100644
index 0000000..2ad922c
--- /dev/null
+++ b/tests/standalone/io/resource_handle_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2022, 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.
+
+// Most tests for [ResourceHandle] are in unix_socket_test.dart.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+
+import 'test_utils.dart' show throws, withTempDir;
+
+Future testToCallsAfterFromFile(String tempDirPath) async {
+  final file = File('$tempDirPath/sock1');
+
+  await file.create();
+  final openFile = await file.open();
+
+  final handle = ResourceHandle.fromFile(openFile);
+
+  handle.toFile().close();
+
+  throws(handle.toFile, (e) => e is StateError);
+  throws(handle.toRawDatagramSocket, (e) => e is StateError);
+  throws(handle.toRawSocket, (e) => e is StateError);
+  throws(handle.toSocket, (e) => e is StateError);
+  throws(handle.toReadPipe, (e) => e is StateError);
+  throws(handle.toWritePipe, (e) => e is StateError);
+}
+
+void main(List<String> args) async {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
+    return;
+  }
+
+  await withTempDir('resource_handle_test', (Directory dir) async {
+    await testToCallsAfterFromFile('${dir.path}');
+  });
+}
diff --git a/tests/standalone/io/stdio_implicit_close_test.dart b/tests/standalone/io/stdio_implicit_close_test.dart
index 11a615c..81eb540 100644
--- a/tests/standalone/io/stdio_implicit_close_test.dart
+++ b/tests/standalone/io/stdio_implicit_close_test.dart
@@ -6,7 +6,6 @@
 
 import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
-import "dart:convert";
 import "dart:io";
 
 void test({required bool closeStdout, required bool closeStderr}) {
@@ -20,9 +19,7 @@
   if (closeStderr) arguments.add("stderr");
 
   asyncStart();
-  Process.run(Platform.executable, arguments,
-          stdoutEncoding: ascii, stderrEncoding: ascii)
-      .then((result) {
+  Process.run(Platform.executable, arguments).then((result) {
     print(result.stdout);
     print(result.stderr);
     Expect.equals(0, result.exitCode);
diff --git a/tests/standalone/io/stream_pipe_test.dart b/tests/standalone/io/stream_pipe_test.dart
index 7955725..9661a87 100644
--- a/tests/standalone/io/stream_pipe_test.dart
+++ b/tests/standalone/io/stream_pipe_test.dart
@@ -20,7 +20,7 @@
     Platform.script.resolve(path).toFilePath();
 
 bool compareFileContent(String fileName1, String fileName2,
-    {int file1Offset: 0, int file2Offset: 0, int? count}) {
+    {int file1Offset = 0, int file2Offset = 0, int? count}) {
   var file1 = new File(fileName1).openSync();
   var file2 = new File(fileName2).openSync();
   var length1 = file1.lengthSync();
diff --git a/tests/standalone/io/test_utils.dart b/tests/standalone/io/test_utils.dart
index 9160c18..2e8acfc 100644
--- a/tests/standalone/io/test_utils.dart
+++ b/tests/standalone/io/test_utils.dart
@@ -9,7 +9,7 @@
 
 int lastRetryId = 0;
 
-Future retry(Future fun(), {int maxCount: 10}) async {
+Future retry(Future fun(), {int maxCount = 10}) async {
   final int id = lastRetryId++;
   for (int i = 0; i < maxCount; i++) {
     try {
diff --git a/tests/standalone/io/unix_socket_test.dart b/tests/standalone/io/unix_socket_test.dart
index e0b80b6..f9764d8 100644
--- a/tests/standalone/io/unix_socket_test.dart
+++ b/tests/standalone/io/unix_socket_test.dart
@@ -438,10 +438,11 @@
 }
 
 Future testFileMessage(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
 
+  final firstMessageReceived = Completer<void>();
   final completer = Completer<bool>();
 
   final address =
@@ -475,6 +476,7 @@
         receivedFile.writeStringSync('Hello, server!\n');
         print("server has written to the $receivedFile file");
         socket.write('abc'.codeUnits);
+        firstMessageReceived.complete();
       } else if (e == RawSocketEvent.readClosed) {
         print('server socket got readClosed');
         socket.close();
@@ -487,13 +489,14 @@
   final randomAccessFile = file.openSync(mode: FileMode.write);
   // Send a message with sample file.
   final socket = await RawSocket.connect(address, 0);
-  socket.listen((e) {
+  socket.listen((e) async {
     if (e == RawSocketEvent.write) {
       randomAccessFile.writeStringSync('Hello, client!\n');
       socket.sendMessage(<SocketControlMessage>[
         SocketControlMessage.fromHandles(
             <ResourceHandle>[ResourceHandle.fromFile(randomAccessFile)])
       ], 'Hello'.codeUnits);
+      await firstMessageReceived.future;
       print('client sent a message');
       socket.sendMessage(<SocketControlMessage>[], 'EmptyMessage'.codeUnits);
       print('client sent a message without control data');
@@ -514,7 +517,7 @@
 }
 
 Future testTooLargeControlMessage(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
   final completer = Completer<bool>();
@@ -562,7 +565,7 @@
 }
 
 Future testFileMessageWithShortRead(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
 
@@ -673,10 +676,9 @@
 }
 
 Future testSocketMessage(String uniqueName) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
-
   final address =
       InternetAddress('$uniqueName/sock', type: InternetAddressType.unix);
   final server = await RawServerSocket.bind(address, 0, shared: false);
@@ -739,13 +741,16 @@
   });
 }
 
-Future testStdioMessage(String tempDirPath, {bool caller: false}) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+Future testStdioMessage(String tempDirPath, {bool caller = false}) async {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
   if (caller) {
-    final process = await Process.start(Platform.resolvedExecutable,
-        <String>[Platform.script.toFilePath(), '--start-stdio-message-test']);
+    final process = await Process.start(Platform.resolvedExecutable, <String>[
+      ...Platform.executableArguments,
+      Platform.script.toFilePath(),
+      '--start-stdio-message-test'
+    ]);
     String processStdout = "";
     String processStderr = "";
     process.stdout.transform(utf8.decoder).listen((line) {
@@ -823,8 +828,142 @@
   });
 }
 
+Future testReadPipeMessage(String uniqueName) async {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
+    return;
+  }
+  final address =
+      InternetAddress('$uniqueName/sock', type: InternetAddressType.unix);
+  final server = await RawServerSocket.bind(address, 0, shared: false);
+
+  server.listen((RawSocket socket) async {
+    socket.listen((e) async {
+      switch (e) {
+        case RawSocketEvent.read:
+          final SocketMessage? message = socket.readMessage();
+          if (message == null) {
+            return;
+          }
+          Expect.equals('Hello', String.fromCharCodes(message.data));
+          Expect.equals(1, message.controlMessages.length);
+          final SocketControlMessage controlMessage =
+              message.controlMessages[0];
+          final handles = controlMessage.extractHandles();
+          Expect.isNotNull(handles);
+          Expect.equals(1, handles.length);
+          final receivedPipe = handles[0].toReadPipe();
+          Expect.equals('Hello over pipe!',
+              await receivedPipe.transform(utf8.decoder).join());
+          socket.write('server replied'.codeUnits);
+          break;
+        case RawSocketEvent.readClosed:
+          socket.close();
+          server.close();
+          break;
+      }
+    });
+  });
+
+  final RawServerSocket testServer = await createTestServer();
+  final testPipe = await Pipe.create();
+
+  // Send a message containing an open pipe.
+  final socket = await RawSocket.connect(address, 0);
+  socket.listen((e) {
+    switch (e) {
+      case RawSocketEvent.write:
+        socket.sendMessage(<SocketControlMessage>[
+          SocketControlMessage.fromHandles(
+              <ResourceHandle>[ResourceHandle.fromReadPipe(testPipe.read)])
+        ], 'Hello'.codeUnits);
+        testPipe.write.add('Hello over pipe!'.codeUnits);
+        testPipe.write.close();
+        break;
+      case RawSocketEvent.read:
+        final data = socket.read();
+        if (data == null) {
+          return;
+        }
+
+        final dataString = String.fromCharCodes(data);
+        Expect.equals('server replied', dataString);
+        socket.close();
+        testPipe.write.close();
+        testServer.close();
+    }
+  });
+}
+
+Future testWritePipeMessage(String uniqueName) async {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
+    return;
+  }
+  final address =
+      InternetAddress('$uniqueName/sock', type: InternetAddressType.unix);
+  final server = await RawServerSocket.bind(address, 0, shared: false);
+
+  server.listen((RawSocket socket) async {
+    socket.listen((e) async {
+      switch (e) {
+        case RawSocketEvent.read:
+          final SocketMessage? message = socket.readMessage();
+          if (message == null) {
+            return;
+          }
+          Expect.equals('Hello', String.fromCharCodes(message.data));
+          Expect.equals(1, message.controlMessages.length);
+          final SocketControlMessage controlMessage =
+              message.controlMessages[0];
+          final handles = controlMessage.extractHandles();
+          Expect.isNotNull(handles);
+          Expect.equals(1, handles.length);
+          final receivedPipe = handles[0].toWritePipe();
+
+          receivedPipe.add('Hello over pipe!'.codeUnits);
+          receivedPipe.close();
+          socket.write('server replied'.codeUnits);
+          break;
+        case RawSocketEvent.readClosed:
+          socket.close();
+          server.close();
+          break;
+      }
+    });
+  });
+
+  final RawServerSocket testServer = await createTestServer();
+  final testPipe = await Pipe.create();
+
+  // Send a message containing an open pipe.
+  final socket = await RawSocket.connect(address, 0);
+  socket.listen((e) async {
+    switch (e) {
+      case RawSocketEvent.write:
+        socket.sendMessage(<SocketControlMessage>[
+          SocketControlMessage.fromHandles(
+              <ResourceHandle>[ResourceHandle.fromWritePipe(testPipe.write)])
+        ], 'Hello'.codeUnits);
+
+        Expect.equals('Hello over pipe!',
+            await testPipe.read.transform(utf8.decoder).join());
+        break;
+      case RawSocketEvent.read:
+        final data = socket.read();
+        if (data == null) {
+          return;
+        }
+
+        final dataString = String.fromCharCodes(data);
+        Expect.equals('server replied', dataString);
+        socket.close();
+        testPipe.write.close();
+        testServer.close();
+    }
+  });
+}
+
 Future testDeleteFile(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
   final name = '$tempDirPath/sock';
@@ -848,7 +987,7 @@
 }
 
 Future testFileStat(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
   final name = '$tempDirPath/sock';
@@ -878,7 +1017,7 @@
 }
 
 Future testFileCopy(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
   final name1 = '$tempDirPath/sock1';
@@ -950,6 +1089,12 @@
       await testStdioMessage('${dir.path}', caller: true);
     });
     await withTempDir('unix_socket_test', (Directory dir) async {
+      await testReadPipeMessage('${dir.path}');
+    });
+    await withTempDir('unix_socket_test', (Directory dir) async {
+      await testWritePipeMessage('${dir.path}');
+    });
+    await withTempDir('unix_socket_test', (Directory dir) async {
       await testDeleteFile('${dir.path}');
     });
     await withTempDir('unix_socket_test', (Directory dir) async {
@@ -963,7 +1108,7 @@
     });
   }, (e, st) {
     if (Platform.isMacOS || Platform.isLinux || Platform.isAndroid) {
-      Expect.fail("Unexpected exception $e is thrown");
+      Expect.fail("Unexpected exception $e is thrown:\n$st");
     } else {
       Expect.isTrue(e is SocketException);
       Expect.isTrue(e.toString().contains('not available'));
diff --git a/tests/standalone/io/web_socket_compression_test.dart b/tests/standalone/io/web_socket_compression_test.dart
index 01e7269..4a26049 100644
--- a/tests/standalone/io/web_socket_compression_test.dart
+++ b/tests/standalone/io/web_socket_compression_test.dart
@@ -33,7 +33,7 @@
 
   SecurityConfiguration(this.secure);
 
-  Future<HttpServer> createServer({int backlog: 0}) => secure
+  Future<HttpServer> createServer({int backlog = 0}) => secure
       ? HttpServer.bindSecure(HOST_NAME, 0, serverContext, backlog: backlog)
       : HttpServer.bind(HOST_NAME, 0, backlog: backlog);
 
@@ -82,7 +82,7 @@
   }
 
   void testCompressionSupport(
-      {server: false, client: false, contextTakeover: false}) {
+      {server = false, client = false, contextTakeover = false}) {
     asyncStart();
 
     var clientOptions = new CompressionOptions(
@@ -124,8 +124,8 @@
   }
 
   void testContextSupport(
-      {CompressionOptions serverOpts: CompressionOptions.compressionDefault,
-      CompressionOptions clientOpts: CompressionOptions.compressionDefault,
+      {CompressionOptions serverOpts = CompressionOptions.compressionDefault,
+      CompressionOptions clientOpts = CompressionOptions.compressionDefault,
       int? messages}) {
     asyncStart();
 
@@ -206,7 +206,7 @@
   }
 
   void testReturnHeaders(String headerValue, String expected,
-      {CompressionOptions serverCompression:
+      {CompressionOptions serverCompression =
           CompressionOptions.compressionDefault}) {
     asyncStart();
     createServer().then((server) {
diff --git a/tests/standalone/io/web_socket_error_test.dart b/tests/standalone/io/web_socket_error_test.dart
index a37afdb..155c8bb 100644
--- a/tests/standalone/io/web_socket_error_test.dart
+++ b/tests/standalone/io/web_socket_error_test.dart
@@ -44,7 +44,7 @@
 
   SecurityConfiguration({required bool this.secure});
 
-  Future<HttpServer> createServer({int backlog: 0}) => secure
+  Future<HttpServer> createServer({int backlog = 0}) => secure
       ? HttpServer.bindSecure(HOST_NAME, 0, serverContext, backlog: backlog)
       : HttpServer.bind(HOST_NAME, 0, backlog: backlog);
 
diff --git a/tests/standalone/io/web_socket_protocol_processor_test.dart b/tests/standalone/io/web_socket_protocol_processor_test.dart
index 344a0b9..a3a57a5 100644
--- a/tests/standalone/io/web_socket_protocol_processor_test.dart
+++ b/tests/standalone/io/web_socket_protocol_processor_test.dart
@@ -17,7 +17,11 @@
 import "package:expect/expect.dart";
 
 import "../../../sdk/lib/internal/internal.dart"
-    show Since, valueOfNonNullableParamWithDefault, HttpStatus;
+    show
+        checkNotNullable,
+        Since,
+        valueOfNonNullableParamWithDefault,
+        HttpStatus;
 
 part "../../../sdk/lib/_http/crypto.dart";
 part "../../../sdk/lib/_http/embedder_config.dart";
diff --git a/tests/standalone/io/web_socket_test.dart b/tests/standalone/io/web_socket_test.dart
index 8f40c32..99a4287 100644
--- a/tests/standalone/io/web_socket_test.dart
+++ b/tests/standalone/io/web_socket_test.dart
@@ -42,7 +42,7 @@
 
   SecurityConfiguration({required this.secure});
 
-  Future<HttpServer> createServer({int backlog: 0}) => secure
+  Future<HttpServer> createServer({int backlog = 0}) => secure
       ? HttpServer.bindSecure(HOST_NAME, 0, serverContext, backlog: backlog)
       : HttpServer.bind(HOST_NAME, 0, backlog: backlog);
 
diff --git a/tests/standalone/io/web_socket_typed_data_test.dart b/tests/standalone/io/web_socket_typed_data_test.dart
index c05cdb7..d093471 100644
--- a/tests/standalone/io/web_socket_typed_data_test.dart
+++ b/tests/standalone/io/web_socket_typed_data_test.dart
@@ -47,7 +47,7 @@
   });
 }
 
-testUintLists({bool compression: false}) {
+testUintLists({bool compression = false}) {
   var fillData = new List.generate(256, (index) => index);
   var testData = [
     new Uint8List(256),
@@ -60,7 +60,7 @@
   test(fillData, testData, compression);
 }
 
-testIntLists({bool compression: false}) {
+testIntLists({bool compression = false}) {
   var fillData = new List.generate(128, (index) => index);
   var testData = [
     new Int8List(128),
@@ -72,7 +72,7 @@
   test(fillData, testData, compression);
 }
 
-void testOutOfRangeClient({bool compression: false}) {
+void testOutOfRangeClient({bool compression = false}) {
   createServer().then((server) {
     var messageCount = 0;
     var transformer = compression
@@ -134,7 +134,7 @@
   });
 }
 
-void testOutOfRangeServer({bool compression: false}) {
+void testOutOfRangeServer({bool compression = false}) {
   var futures = <Future>[];
   var testData = [];
   var data;
diff --git a/tests/standalone/priority_queue_stress_test.dart b/tests/standalone/priority_queue_stress_test.dart
index aab8bfa..f03db7e 100644
--- a/tests/standalone/priority_queue_stress_test.dart
+++ b/tests/standalone/priority_queue_stress_test.dart
@@ -219,7 +219,7 @@
    * If the queue is not empty, but no node exists that adheres to the
    * restrictions we return null.
    */
-  N? removeFirst({List<N> restrictions: const []}) {
+  N? removeFirst({List<N> restrictions = const []}) {
     if (isEmpty) throw "Trying to remove node from empty queue";
     var candidate = getRestricted(restrictions);
 
diff --git a/tests/standalone_2/io/file_pipe_test.dart b/tests/standalone_2/io/file_pipe_test.dart
new file mode 100644
index 0000000..7a97d62
--- /dev/null
+++ b/tests/standalone_2/io/file_pipe_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2013, 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 test program for testing the dart:io `Pipe` class
+
+// @dart = 2.9
+
+import 'dart:io';
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+testReadFromClosedPipe() async {
+  final pipe = await Pipe.create();
+  pipe.write.close();
+  Expect.isTrue(await pipe.read.isEmpty);
+}
+
+testCreateSync() async {
+  final pipe = Pipe.createSync();
+  pipe.write.close();
+  Expect.isTrue(await pipe.read.isEmpty);
+}
+
+testMultipleWritesAndReads() async {
+  final pipe = await Pipe.create();
+  int count = 0;
+  pipe.write.add([count]);
+  await pipe.read.listen((event) {
+    Expect.listEquals([count], event);
+    ++count;
+    if (count < 10) {
+      pipe.write.add([count]);
+    } else {
+      pipe.write.close();
+    }
+  }, onDone: () => Expect.equals(10, count));
+}
+
+main() async {
+  asyncStart();
+  try {
+    await testReadFromClosedPipe();
+    await testCreateSync();
+    await testMultipleWritesAndReads();
+  } finally {
+    asyncEnd();
+  }
+}
diff --git a/tests/standalone_2/io/file_stream_test.dart b/tests/standalone_2/io/file_stream_test.dart
index 64c9d41..373d6e2 100644
--- a/tests/standalone_2/io/file_stream_test.dart
+++ b/tests/standalone_2/io/file_stream_test.dart
@@ -60,7 +60,27 @@
   });
 }
 
-void main() {
+Future<void> testStreamAppendedToAfterOpen() async {
+  asyncStart();
+
+  final pipe = Pipe.createSync();
+  pipe.write.add("Hello World".codeUnits);
+  int i = 0;
+  await pipe.read.listen((event) {
+    Expect.listEquals("Hello World".codeUnits, event);
+    if (i < 10) {
+      pipe.write.add("Hello World".codeUnits);
+      ++i;
+    } else {
+      pipe.write.close();
+    }
+  }).asFuture();
+
+  asyncEnd();
+}
+
+void main() async {
   testPauseResumeCancelStream();
   testStreamIsEmpty();
+  await testStreamAppendedToAfterOpen();
 }
diff --git a/tests/standalone_2/io/http_open_method_validate_test.dart b/tests/standalone_2/io/http_open_method_validate_test.dart
new file mode 100644
index 0000000..668f570
--- /dev/null
+++ b/tests/standalone_2/io/http_open_method_validate_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2022, 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.
+//
+// Verify that HttpClient open, openUrl method argument is validated.
+
+// @dart = 2.9
+
+import "dart:io";
+import "package:expect/expect.dart";
+
+void testInvalidArgumentException(String method) {
+  Expect.throws(() => HttpClient()..open(method, "127.0.0.1", 8080, "/"),
+      (e) => e is ArgumentError);
+  Expect.throws(
+      () => HttpClient()..openUrl(method, Uri.parse("http://127.0.0.1/")),
+      (e) => e is ArgumentError);
+}
+
+main() {
+  const String separators = "\t\n\r()<>@,;:\\/[]?={}";
+  for (int i = 0; i < separators.length; i++) {
+    String separator = separators.substring(i, i + 1);
+    testInvalidArgumentException(separator);
+    testInvalidArgumentException(separator + "CONNECT");
+    testInvalidArgumentException("CONN" + separator + "ECT");
+    testInvalidArgumentException("CONN" + separator + separator + "ECT");
+    testInvalidArgumentException("CONNECT" + separator);
+  }
+}
diff --git a/tests/standalone_2/io/http_proxy_advanced_test.dart b/tests/standalone_2/io/http_proxy_advanced_test.dart
index 38dd62b..f2d9b93 100644
--- a/tests/standalone_2/io/http_proxy_advanced_test.dart
+++ b/tests/standalone_2/io/http_proxy_advanced_test.dart
@@ -334,8 +334,8 @@
   });
 }
 
-int testProxyFromEnviromentDoneCount = 0;
-void testProxyFromEnviroment() {
+int testProxyFromEnvironmentDoneCount = 0;
+void testProxyFromEnvironment() {
   setupProxyServer().then((proxyServer) {
     setupServer(1).then((server) {
       setupServer(1, secure: true).then((secureServer) {
@@ -363,8 +363,8 @@
               return clientRequest.close();
             }).then((HttpClientResponse response) {
               response.listen((_) {}, onDone: () {
-                testProxyFromEnviromentDoneCount++;
-                if (testProxyFromEnviromentDoneCount == loopCount * 2) {
+                testProxyFromEnvironmentDoneCount++;
+                if (testProxyFromEnvironmentDoneCount == loopCount * 2) {
                   Expect.equals(loopCount, server.requestCount);
                   Expect.equals(loopCount, secureServer.requestCount);
                   proxyServer.shutdown();
@@ -614,7 +614,7 @@
 
 main() {
   testProxyIPV6();
-  testProxyFromEnviroment();
+  testProxyFromEnvironment();
   // The two invocations use the same global variable for state -
   // run one after the other.
   testProxyAuthenticate(false).then((_) => testProxyAuthenticate(true));
diff --git a/tests/standalone_2/io/resource_handle_test.dart b/tests/standalone_2/io/resource_handle_test.dart
new file mode 100644
index 0000000..11a25c8
--- /dev/null
+++ b/tests/standalone_2/io/resource_handle_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2022, 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
+
+// Most tests for [ResourceHandle] are in unix_socket_test.dart.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+
+import 'test_utils.dart' show throws, withTempDir;
+
+Future testToCallsAfterFromFile(String tempDirPath) async {
+  final file = File('$tempDirPath/sock1');
+
+  await file.create();
+  final openFile = await file.open();
+
+  final handle = ResourceHandle.fromFile(openFile);
+
+  handle.toFile().close();
+
+  throws(handle.toFile, (e) => e is StateError);
+  throws(handle.toRawDatagramSocket, (e) => e is StateError);
+  throws(handle.toRawSocket, (e) => e is StateError);
+  throws(handle.toSocket, (e) => e is StateError);
+  throws(handle.toReadPipe, (e) => e is StateError);
+  throws(handle.toWritePipe, (e) => e is StateError);
+}
+
+void main(List<String> args) async {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
+    return;
+  }
+
+  await withTempDir('resource_handle_test', (Directory dir) async {
+    await testToCallsAfterFromFile('${dir.path}');
+  });
+}
diff --git a/tests/standalone_2/io/stdio_implicit_close_test.dart b/tests/standalone_2/io/stdio_implicit_close_test.dart
index 787ee73..995691d 100644
--- a/tests/standalone_2/io/stdio_implicit_close_test.dart
+++ b/tests/standalone_2/io/stdio_implicit_close_test.dart
@@ -8,7 +8,6 @@
 
 import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
-import "dart:convert";
 import "dart:io";
 
 void test({bool closeStdout, bool closeStderr}) {
@@ -22,9 +21,7 @@
   if (closeStderr) arguments.add("stderr");
 
   asyncStart();
-  Process.run(Platform.executable, arguments,
-          stdoutEncoding: ascii, stderrEncoding: ascii)
-      .then((result) {
+  Process.run(Platform.executable, arguments).then((result) {
     print(result.stdout);
     print(result.stderr);
     Expect.equals(0, result.exitCode);
diff --git a/tests/standalone_2/io/unix_socket_test.dart b/tests/standalone_2/io/unix_socket_test.dart
index 7d8e7a5..c51d612 100644
--- a/tests/standalone_2/io/unix_socket_test.dart
+++ b/tests/standalone_2/io/unix_socket_test.dart
@@ -440,10 +440,11 @@
 }
 
 Future testFileMessage(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
 
+  final firstMessageReceived = Completer<void>();
   final completer = Completer<bool>();
 
   final address =
@@ -477,6 +478,7 @@
         receivedFile.writeStringSync('Hello, server!\n');
         print("server has written to the $receivedFile file");
         socket.write('abc'.codeUnits);
+        firstMessageReceived.complete();
       } else if (e == RawSocketEvent.readClosed) {
         print('server socket got readClosed');
         socket.close();
@@ -489,13 +491,14 @@
   final randomAccessFile = file.openSync(mode: FileMode.write);
   // Send a message with sample file.
   final socket = await RawSocket.connect(address, 0);
-  socket.listen((e) {
+  socket.listen((e) async {
     if (e == RawSocketEvent.write) {
       randomAccessFile.writeStringSync('Hello, client!\n');
       socket.sendMessage(<SocketControlMessage>[
         SocketControlMessage.fromHandles(
             <ResourceHandle>[ResourceHandle.fromFile(randomAccessFile)])
       ], 'Hello'.codeUnits);
+      await firstMessageReceived.future;
       print('client sent a message');
       socket.sendMessage(<SocketControlMessage>[], 'EmptyMessage'.codeUnits);
       print('client sent a message without control data');
@@ -513,7 +516,7 @@
 }
 
 Future testTooLargeControlMessage(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
   final completer = Completer<bool>();
@@ -561,7 +564,7 @@
 }
 
 Future testFileMessageWithShortRead(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
 
@@ -669,7 +672,7 @@
 }
 
 Future testSocketMessage(String uniqueName) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
 
@@ -735,16 +738,19 @@
   });
 }
 
-Future testStdioMessage(String tempDirPath, {bool caller: false}) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+Future testStdioMessage(String tempDirPath, {bool caller = false}) async {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
 
   final completer = Completer<bool>();
 
   if (caller) {
-    final process = await Process.start(Platform.resolvedExecutable,
-        <String>[Platform.script.toFilePath(), '--start-stdio-message-test']);
+    final process = await Process.start(Platform.resolvedExecutable, <String>[
+      ...Platform.executableArguments,
+      Platform.script.toFilePath(),
+      '--start-stdio-message-test'
+    ]);
     String processStdout = "";
     String processStderr = "";
     process.stdout.transform(utf8.decoder).listen((line) {
@@ -825,8 +831,142 @@
   return completer.future;
 }
 
+Future testReadPipeMessage(String uniqueName) async {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
+    return;
+  }
+  final address =
+      InternetAddress('$uniqueName/sock', type: InternetAddressType.unix);
+  final server = await RawServerSocket.bind(address, 0, shared: false);
+
+  server.listen((RawSocket socket) async {
+    socket.listen((e) async {
+      switch (e) {
+        case RawSocketEvent.read:
+          final SocketMessage message = socket.readMessage();
+          if (message == null) {
+            return;
+          }
+          Expect.equals('Hello', String.fromCharCodes(message.data));
+          Expect.equals(1, message.controlMessages.length);
+          final SocketControlMessage controlMessage =
+              message.controlMessages[0];
+          final handles = controlMessage.extractHandles();
+          Expect.isNotNull(handles);
+          Expect.equals(1, handles.length);
+          final receivedPipe = handles[0].toReadPipe();
+          Expect.equals('Hello over pipe!',
+              await receivedPipe.transform(utf8.decoder).join());
+          socket.write('server replied'.codeUnits);
+          break;
+        case RawSocketEvent.readClosed:
+          socket.close();
+          server.close();
+          break;
+      }
+    });
+  });
+
+  final RawServerSocket testServer = await createTestServer();
+  final testPipe = await Pipe.create();
+
+  // Send a message containing an open pipe.
+  final socket = await RawSocket.connect(address, 0);
+  socket.listen((e) {
+    switch (e) {
+      case RawSocketEvent.write:
+        socket.sendMessage(<SocketControlMessage>[
+          SocketControlMessage.fromHandles(
+              <ResourceHandle>[ResourceHandle.fromReadPipe(testPipe.read)])
+        ], 'Hello'.codeUnits);
+        testPipe.write.add('Hello over pipe!'.codeUnits);
+        testPipe.write.close();
+        break;
+      case RawSocketEvent.read:
+        final data = socket.read();
+        if (data == null) {
+          return;
+        }
+
+        final dataString = String.fromCharCodes(data);
+        Expect.equals('server replied', dataString);
+        socket.close();
+        testPipe.write.close();
+        testServer.close();
+    }
+  });
+}
+
+Future testWritePipeMessage(String uniqueName) async {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
+    return;
+  }
+  final address =
+      InternetAddress('$uniqueName/sock', type: InternetAddressType.unix);
+  final server = await RawServerSocket.bind(address, 0, shared: false);
+
+  server.listen((RawSocket socket) async {
+    socket.listen((e) async {
+      switch (e) {
+        case RawSocketEvent.read:
+          final SocketMessage message = socket.readMessage();
+          if (message == null) {
+            return;
+          }
+          Expect.equals('Hello', String.fromCharCodes(message.data));
+          Expect.equals(1, message.controlMessages.length);
+          final SocketControlMessage controlMessage =
+              message.controlMessages[0];
+          final handles = controlMessage.extractHandles();
+          Expect.isNotNull(handles);
+          Expect.equals(1, handles.length);
+          final receivedPipe = handles[0].toWritePipe();
+
+          receivedPipe.add('Hello over pipe!'.codeUnits);
+          receivedPipe.close();
+          socket.write('server replied'.codeUnits);
+          break;
+        case RawSocketEvent.readClosed:
+          socket.close();
+          server.close();
+          break;
+      }
+    });
+  });
+
+  final RawServerSocket testServer = await createTestServer();
+  final testPipe = await Pipe.create();
+
+  // Send a message containing an open pipe.
+  final socket = await RawSocket.connect(address, 0);
+  socket.listen((e) async {
+    switch (e) {
+      case RawSocketEvent.write:
+        socket.sendMessage(<SocketControlMessage>[
+          SocketControlMessage.fromHandles(
+              <ResourceHandle>[ResourceHandle.fromWritePipe(testPipe.write)])
+        ], 'Hello'.codeUnits);
+
+        Expect.equals('Hello over pipe!',
+            await testPipe.read.transform(utf8.decoder).join());
+        break;
+      case RawSocketEvent.read:
+        final data = socket.read();
+        if (data == null) {
+          return;
+        }
+
+        final dataString = String.fromCharCodes(data);
+        Expect.equals('server replied', dataString);
+        socket.close();
+        testPipe.write.close();
+        testServer.close();
+    }
+  });
+}
+
 Future testDeleteFile(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
   final address =
@@ -850,7 +990,7 @@
 }
 
 Future testFileStat(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
   final name = '$tempDirPath/sock';
@@ -862,7 +1002,7 @@
 }
 
 Future testFileRename(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
   final name1 = '$tempDirPath/sock1';
@@ -880,7 +1020,7 @@
 }
 
 Future testFileCopy(String tempDirPath) async {
-  if (!Platform.isLinux && !Platform.isAndroid) {
+  if (!Platform.isMacOS && !Platform.isLinux && !Platform.isAndroid) {
     return;
   }
   final name1 = '$tempDirPath/sock1';
@@ -950,6 +1090,12 @@
       await testSocketMessage('${dir.path}');
     });
     await withTempDir('unix_socket_test', (Directory dir) async {
+      await testReadPipeMessage('${dir.path}');
+    });
+    await withTempDir('unix_socket_test', (Directory dir) async {
+      await testWritePipeMessage('${dir.path}');
+    });
+    await withTempDir('unix_socket_test', (Directory dir) async {
       await testStdioMessage('${dir.path}', caller: true);
     });
     await withTempDir('unix_socket_test', (Directory dir) async {
@@ -966,7 +1112,7 @@
     });
   }, (e, st) {
     if (Platform.isMacOS || Platform.isLinux || Platform.isAndroid) {
-      Expect.fail("Unexpected exception $e is thrown");
+      Expect.fail("Unexpected exception $e is thrown:\n$st");
     } else {
       Expect.isTrue(e is SocketException);
       Expect.isTrue(e.toString().contains('not available'));
diff --git a/tests/web/closure3_test.dart b/tests/web/closure3_test.dart
index daea300..0e8feb7 100644
--- a/tests/web/closure3_test.dart
+++ b/tests/web/closure3_test.dart
@@ -5,7 +5,7 @@
 import "package:expect/expect.dart";
 
 main() {
-  var f = ({a: 3, b: 8}) {
+  var f = ({a = 3, b = 8}) {
     return a + b;
   };
   Expect.equals(11, f());
diff --git a/tests/web/closure5_test.dart b/tests/web/closure5_test.dart
index f135346..b3b315a 100644
--- a/tests/web/closure5_test.dart
+++ b/tests/web/closure5_test.dart
@@ -6,7 +6,7 @@
 
 class A {
   foo() => 499;
-  bar({a: 1, b: 7, c: 99}) => a + b + c;
+  bar({a = 1, b = 7, c = 99}) => a + b + c;
   toto() => bar;
   gee(f) => f(toto);
 }
diff --git a/tests/web/closure6_test.dart b/tests/web/closure6_test.dart
index a49b187..efb406e 100644
--- a/tests/web/closure6_test.dart
+++ b/tests/web/closure6_test.dart
@@ -20,13 +20,13 @@
   Expect.equals(499, a.foo());
   a.foo = (x, y) => x + y;
   Expect.equals(102, a.bar());
-  a.foo = ({fun: null}) => fun(41);
+  a.foo = ({fun = null}) => fun(41);
   Expect.equals(42, a.gee((x) => x + 1));
 
   a.foo = () => 499;
   Expect.equals(499, a.foo2());
   a.foo = (x, y) => x + y;
   Expect.equals(102, a.bar2());
-  a.foo = ({fun: null}) => fun(41);
+  a.foo = ({fun = null}) => fun(41);
   Expect.equals(42, a.gee2((x) => x + 1));
 }
diff --git a/tests/web/closure7_test.dart b/tests/web/closure7_test.dart
index bae471e..63a7ac3 100644
--- a/tests/web/closure7_test.dart
+++ b/tests/web/closure7_test.dart
@@ -17,14 +17,14 @@
   Expect.equals(499, foo());
   foo = (x, y) => x + y;
   Expect.equals(102, bar());
-  foo = ({fun: null}) => fun(41);
+  foo = ({fun = null}) => fun(41);
   Expect.equals(42, gee((x) => x + 1));
 
   foo = () => 499;
   Expect.equals(499, foo2());
   foo = (x, y) => x + y;
   Expect.equals(102, bar2());
-  foo = ({fun: null}) => fun(41);
+  foo = ({fun = null}) => fun(41);
   Expect.equals(42, gee2((x) => x + 1));
 }
 
@@ -43,14 +43,14 @@
   Expect.equals(499, A.foo());
   A.foo = (x, y) => x + y;
   Expect.equals(102, A.bar());
-  A.foo = ({fun: null}) => fun(41);
+  A.foo = ({fun = null}) => fun(41);
   Expect.equals(42, A.gee((x) => x + 1));
 
   A.foo = () => 499;
   Expect.equals(499, A.foo2());
   A.foo = (x, y) => x + y;
   Expect.equals(102, A.bar2());
-  A.foo = ({fun: null}) => fun(41);
+  A.foo = ({fun = null}) => fun(41);
   Expect.equals(42, A.gee2((x) => x + 1));
 }
 
diff --git a/tests/web/constant_javascript_semantics_test5.dart b/tests/web/constant_javascript_semantics_test5.dart
index e2275ea..82bdca7 100644
--- a/tests/web/constant_javascript_semantics_test5.dart
+++ b/tests/web/constant_javascript_semantics_test5.dart
@@ -24,7 +24,7 @@
 }
 
 class EnumHaver {
-  const EnumHaver({this.myEnum: Enum.a}) : assert(myEnum != null);
+  const EnumHaver({this.myEnum = Enum.a}) : assert(myEnum != null);
   final Enum myEnum;
 }
 
diff --git a/tests/web/deferred/deferred_class_library2.dart b/tests/web/deferred/deferred_class_library2.dart
index fecca53..4683670 100644
--- a/tests/web/deferred/deferred_class_library2.dart
+++ b/tests/web/deferred/deferred_class_library2.dart
@@ -35,8 +35,8 @@
 
   Gee([this.c = const Constant(111)]);
   const Gee.n321([this.c = const Constant(321)]);
-  Gee.n135({arg: const Constant(135)}) : this.c = arg;
-  const Gee.n246({arg: const Constant(246)}) : this.c = arg;
+  Gee.n135({arg = const Constant(135)}) : this.c = arg;
+  const Gee.n246({arg = const Constant(246)}) : this.c = arg;
   const Gee.n888() : this.c = const Constant(888);
   const Gee.constant(this.c);
 }
diff --git a/tests/web/deferred/multiple_default_arg_lib1.dart b/tests/web/deferred/multiple_default_arg_lib1.dart
index 32ed7e6..e81a900 100644
--- a/tests/web/deferred/multiple_default_arg_lib1.dart
+++ b/tests/web/deferred/multiple_default_arg_lib1.dart
@@ -4,5 +4,5 @@
 
 defaultArg1() => 1;
 defaultArg2() => 2;
-myFunction1({argumentName1: defaultArg1, argumentName2: defaultArg2}) =>
+myFunction1({argumentName1 = defaultArg1, argumentName2 = defaultArg2}) =>
     "${argumentName1()} - ${argumentName2()}";
diff --git a/tests/web/deferred/multiple_default_arg_lib2.dart b/tests/web/deferred/multiple_default_arg_lib2.dart
index eff81f4..b6b15b3 100644
--- a/tests/web/deferred/multiple_default_arg_lib2.dart
+++ b/tests/web/deferred/multiple_default_arg_lib2.dart
@@ -4,5 +4,5 @@
 
 defaultArg3() => 3;
 defaultArg4() => 4;
-myFunction2({argumentName3: defaultArg3, argumentName4: defaultArg4}) =>
+myFunction2({argumentName3 = defaultArg3, argumentName4 = defaultArg4}) =>
     "${argumentName3()} - ${argumentName4()}";
diff --git a/tests/web/deferred/multiple_default_arg_lib3.dart b/tests/web/deferred/multiple_default_arg_lib3.dart
index dab89a4..a793460 100644
--- a/tests/web/deferred/multiple_default_arg_lib3.dart
+++ b/tests/web/deferred/multiple_default_arg_lib3.dart
@@ -5,11 +5,11 @@
 defaultArg3() => "3b";
 defaultArg4() => "4b";
 myFunction3(positional1, positional2,
-        {argumentName3: defaultArg3, argumentName4: defaultArg4}) =>
+        {argumentName3 = defaultArg3, argumentName4 = defaultArg4}) =>
     "$positional1 $positional2 ${argumentName3()} - ${argumentName4()}";
 
 myFunction4(positional1, positional2,
-        {argumentName5: const X(5), argumentName6}) =>
+        {argumentName5 = const X(5), argumentName6}) =>
     argumentName5.value;
 
 class X {
diff --git a/tests/web/generator_elided_parameter_test.dart b/tests/web/generator_elided_parameter_test.dart
index 60bf18b..d3f5922 100644
--- a/tests/web/generator_elided_parameter_test.dart
+++ b/tests/web/generator_elided_parameter_test.dart
@@ -11,7 +11,7 @@
 // The type parameter forces us to create a generator body. The call from the
 // method to the body needs to correctly handle elided parameters.
 Future<T> foo<T>(T Function(int, int, int) toT,
-    {int p1: 0, int p2: 1, int p3: 2}) async {
+    {int p1 = 0, int p2 = 1, int p3 = 2}) async {
   await null;
   return toT(p1, p2, p3);
 }
diff --git a/tests/web/many_constants_test.dart b/tests/web/many_constants_test.dart
index f28e2ff..d841b73 100644
--- a/tests/web/many_constants_test.dart
+++ b/tests/web/many_constants_test.dart
@@ -12,7 +12,8 @@
 
 class Z {
   final a, b, c, d, e, f;
-  const Z({this.a: 1, this.b: 1, this.c: 1, this.d: 1, this.e: 1, this.f: 1});
+  const Z(
+      {this.a = 1, this.b = 1, this.c = 1, this.d = 1, this.e = 1, this.f = 1});
 }
 
 const c1 = const {};
diff --git a/tests/web/no_such_method_strong12_test.dart b/tests/web/no_such_method_strong12_test.dart
index b097966..637f358 100644
--- a/tests/web/no_such_method_strong12_test.dart
+++ b/tests/web/no_such_method_strong12_test.dart
@@ -7,7 +7,7 @@
 import 'package:expect/expect.dart';
 
 abstract class A {
-  m({a: 1, c: 3, b: 2});
+  m({a = 1, c = 3, b = 2});
 }
 
 class B implements A {
diff --git a/tests/web/regress/issue/32997a_lib.dart b/tests/web/regress/issue/32997a_lib.dart
index 54e4f54..fb6f30b 100644
--- a/tests/web/regress/issue/32997a_lib.dart
+++ b/tests/web/regress/issue/32997a_lib.dart
@@ -6,6 +6,6 @@
 
 typedef dynamic G<T>(T v);
 
-m(int x, {G<int> f: getFoo}) {
+m(int x, {G<int> f = getFoo}) {
   print(f(x));
 }
diff --git a/tests/web/regress/issue/32997b_lib.dart b/tests/web/regress/issue/32997b_lib.dart
index 62eee11..7e467e9 100644
--- a/tests/web/regress/issue/32997b_lib.dart
+++ b/tests/web/regress/issue/32997b_lib.dart
@@ -6,6 +6,6 @@
 
 typedef dynamic G<T>(T v);
 
-m<T>(T x, {G<T> f: getFoo}) {
+m<T>(T x, {G<T> f = getFoo}) {
   print(f);
 }
diff --git a/tests/web/wasm/callback_test.dart b/tests/web/wasm/callback_test.dart
index 2530977..34cc031 100644
--- a/tests/web/wasm/callback_test.dart
+++ b/tests/web/wasm/callback_test.dart
@@ -11,51 +11,172 @@
 @JS()
 external void eval(String code);
 
-typedef SumStringCallback = String Function(String a, String b);
+typedef SumTwoPositionalFun = String Function(String a, String b);
+typedef SumOnePositionalAndOneOptionalFun = String Function(String a,
+    [String? b]);
+typedef SumTwoOptionalFun = String Function([String? a, String? b]);
+typedef SumOnePositionalAndOneOptionalNonNullFun = String Function(String a,
+    [String b]);
+typedef SumTwoOptionalNonNullFun = String Function([String a, String b]);
 
 @JS()
 @staticInterop
 class DartFromJSCallbackHelper {
-  external factory DartFromJSCallbackHelper.factory(SumStringCallback summer);
+  external factory DartFromJSCallbackHelper.factory(
+      SumTwoPositionalFun sumTwoPositional,
+      SumOnePositionalAndOneOptionalFun sumOnePositionalOneOptional,
+      SumTwoOptionalFun sumTwoOptional,
+      SumOnePositionalAndOneOptionalNonNullFun
+          sumOnePositionalAndOneOptionalNonNull,
+      SumTwoOptionalNonNullFun sumTwoOptionalNonNull);
 }
 
 extension DartFromJSCallbackHelperMethods on DartFromJSCallbackHelper {
   external String doSum1();
   external String doSum2(String a, String b);
   external String doSum3(Object summer);
+
+  external String doSumOnePositionalAndOneOptionalA(String a);
+  external String doSumOnePositionalAndOneOptionalB(String a, String b);
+  external String doSumTwoOptionalA();
+  external String doSumTwoOptionalB(String a);
+  external String doSumTwoOptionalC(String a, String b);
+
+  external String doSumOnePositionalAndOneOptionalANonNull(String a);
+  external String doSumOnePositionalAndOneOptionalBNonNull(String a, String b);
+  external String doSumTwoOptionalANonNull();
+  external String doSumTwoOptionalBNonNull(String a);
+  external String doSumTwoOptionalCNonNull(String a, String b);
 }
 
-String sumString(String a, String b) {
+String sumTwoPositional(String a, String b) {
+  return a + b;
+}
+
+String sumOnePositionalAndOneOptional(String a, [String? b]) {
+  return a + (b ?? 'bar');
+}
+
+String sumTwoOptional([String? a, String? b]) {
+  return (a ?? 'foo') + (b ?? 'bar');
+}
+
+String sumOnePositionalAndOneOptionalNonNull(String a, [String b = 'bar']) {
+  return a + b;
+}
+
+String sumTwoOptionalNonNull([String a = 'foo', String b = 'bar']) {
   return a + b;
 }
 
 void staticInteropCallbackTest() {
   eval(r'''
-    globalThis.DartFromJSCallbackHelper = function(summer) {
+    globalThis.DartFromJSCallbackHelper = function(
+        sumTwoPositional, sumOnePositionalOneOptional, sumTwoOptional,
+        sumOnePositionalAndOneOptionalNonNull, sumTwoOptionalNonNull) {
       this.a = 'hello ';
       this.b = 'world!';
       this.sum = null;
-      this.summer = summer;
+      this.sumTwoPositional = sumTwoPositional;
+      this.sumOnePositionalOneOptional = sumOnePositionalOneOptional;
+      this.sumTwoOptional = sumTwoOptional;
+      this.sumOnePositionalAndOneOptionalNonNull = sumOnePositionalAndOneOptionalNonNull;
+      this.sumTwoOptionalNonNull = sumTwoOptionalNonNull;
       this.doSum1 = () => {
-        return this.summer(this.a, this.b);
+        return this.sumTwoPositional(this.a, this.b);
       }
       this.doSum2 = (a, b) => {
-        return this.summer(a, b);
+        return this.sumTwoPositional(a, b);
       }
       this.doSum3 = (summer) => {
         return summer(this.a, this.b);
       }
+      this.doSumOnePositionalAndOneOptionalA = (a) => {
+        return sumOnePositionalOneOptional(a);
+      }
+      this.doSumOnePositionalAndOneOptionalB = (a, b) => {
+        return sumOnePositionalOneOptional(a, b);
+      }
+      this.doSumTwoOptionalA = () => {
+        return sumTwoOptional();
+      }
+      this.doSumTwoOptionalB = (a) => {
+        return sumTwoOptional(a);
+      }
+      this.doSumTwoOptionalC = (a, b) => {
+        return sumTwoOptional(a, b);
+      }
+      this.doSumOnePositionalAndOneOptionalANonNull = (a) => {
+        return sumOnePositionalAndOneOptionalNonNull(a);
+      }
+      this.doSumOnePositionalAndOneOptionalBNonNull = (a, b) => {
+        return sumOnePositionalAndOneOptionalNonNull(a, b);
+      }
+      this.doSumTwoOptionalANonNull = () => {
+        return sumTwoOptionalNonNull();
+      }
+      this.doSumTwoOptionalBNonNull = (a) => {
+        return sumTwoOptionalNonNull(a);
+      }
+      this.doSumTwoOptionalCNonNull = (a, b) => {
+        return sumTwoOptionalNonNull(a, b);
+      }
+
     }
   ''');
 
-  final dartFromJSCallbackHelper = DartFromJSCallbackHelper.factory(
-      allowInterop<SumStringCallback>(sumString));
-  Expect.equals('hello world!', dartFromJSCallbackHelper.doSum1());
-  Expect.equals('foobar', dartFromJSCallbackHelper.doSum2('foo', 'bar'));
+  final helper = DartFromJSCallbackHelper.factory(
+      allowInterop<SumTwoPositionalFun>(sumTwoPositional),
+      allowInterop<SumOnePositionalAndOneOptionalFun>(
+          sumOnePositionalAndOneOptional),
+      allowInterop<SumTwoOptionalFun>(sumTwoOptional),
+      allowInterop<SumOnePositionalAndOneOptionalNonNullFun>(
+          sumOnePositionalAndOneOptionalNonNull),
+      allowInterop<SumTwoOptionalNonNullFun>(sumTwoOptionalNonNull));
+
+  Expect.equals('hello world!', helper.doSum1());
+  Expect.equals('foobar', helper.doSum2('foo', 'bar'));
+  Expect.equals('hello world!',
+      helper.doSum3(allowInterop<SumTwoPositionalFun>((a, b) => a + b)));
+
+  Expect.equals('foobar', helper.doSumOnePositionalAndOneOptionalA('foo'));
   Expect.equals(
-      'hello world!',
-      dartFromJSCallbackHelper
-          .doSum3(allowInterop<SumStringCallback>((a, b) => a + b)));
+      'foobar', helper.doSumOnePositionalAndOneOptionalB('foo', 'bar'));
+  Expect.equals('foobar', helper.doSumTwoOptionalA());
+  Expect.equals('foobar', helper.doSumTwoOptionalB('foo'));
+  Expect.equals('foobar', helper.doSumTwoOptionalC('foo', 'bar'));
+
+  Expect.equals(
+      'foobar', helper.doSumOnePositionalAndOneOptionalANonNull('foo'));
+  Expect.equals(
+      'foobar', helper.doSumOnePositionalAndOneOptionalBNonNull('foo', 'bar'));
+  Expect.equals('foobar', helper.doSumTwoOptionalANonNull());
+  Expect.equals('foobar', helper.doSumTwoOptionalBNonNull('foo'));
+  Expect.equals('foobar', helper.doSumTwoOptionalCNonNull('foo', 'bar'));
+}
+
+typedef NoArgsFun = String Function();
+typedef OneArgFun = String Function(String arg);
+typedef OnePositionalAndOneOptionalArgsFun = String Function(String arg,
+    [String arg2]);
+typedef TwoPositionalArgsFun = String Function([String arg, String arg2]);
+
+class TornOffClass {
+  String noArgs() {
+    return 'foo';
+  }
+
+  String oneArg(String arg) {
+    return arg;
+  }
+
+  String onePositionalAndOneOptionalArgs(String arg, [String arg2 = 'bar']) {
+    return arg + arg2;
+  }
+
+  String twoPositionalArgs([String arg = 'foo', String? arg2]) {
+    return arg + (arg2 ?? '');
+  }
 }
 
 void allowInteropCallbackTest() {
@@ -66,17 +187,186 @@
     globalThis.doSum2 = function(a, b) {
       return globalThis.summer(a, b);
     }
+    globalThis.doSumOnePositionalAndOneOptionalA = function(a) {
+      return summer(a);
+    }
+    globalThis.doSumOnePositionalAndOneOptionalB = function(a, b) {
+      return summer(a, b);
+    }
+    globalThis.doSumTwoOptionalA = function() {
+      return summer();
+    }
+    globalThis.doSumTwoOptionalB = function(a) {
+      return summer(a);
+    }
+    globalThis.doSumTwoOptionalC = function(a, b) {
+      return summer(a, b);
+    }
+    globalThis.doSumOnePositionalAndOneOptionalANonNull = function(a) {
+      return summer(a);
+    }
+    globalThis.doSumOnePositionalAndOneOptionalBNonNull = function(a, b) {
+      return summer(a, b);
+    }
+    globalThis.doSumTwoOptionalANonNull = function() {
+      return summer();
+    }
+    globalThis.doSumTwoOptionalBNonNull = function(a) {
+      return summer(a);
+    }
+    globalThis.doSumTwoOptionalCNonNull = function(a, b) {
+      return summer(a, b);
+    }
+
+    // tear off cases
+    globalThis.tearOffNoArgs = function (f) {
+      return f();
+    }
+    globalThis.tearOffOneArg = function (f) {
+      return f('foo');
+    }
+    globalThis.tearOffOnePositionalAndOneOptionalArgsA = function (f) {
+      return f('foo');
+    }
+    globalThis.tearOffOnePositionalAndOneOptionalArgsB = function (f) {
+      return f('foo', 'baz');
+    }
+    globalThis.tearOffTwoPositionalArgsA = function (f) {
+      return f('foo');
+    }
+    globalThis.tearOffTwoPositionalArgsB = function (f) {
+      return f('foo', 'baz');
+    }
   ''');
 
-  final interopCallback = allowInterop<SumStringCallback>((a, b) => a + b);
-  Expect.equals(
-      'foobar', callMethod(globalThis, 'doSum1', [interopCallback]).toString());
-  setProperty(globalThis, 'summer', interopCallback);
-  Expect.equals(
-      'foobar', callMethod(globalThis, 'doSum2', ['foo', 'bar']).toString());
-  final roundTripCallback = getProperty(globalThis, 'summer');
-  Expect.equals('foobar',
-      (dartify(roundTripCallback) as SumStringCallback)('foo', 'bar'));
+  // General
+  {
+    final interopCallback = allowInterop<SumTwoPositionalFun>((a, b) => a + b);
+    Expect.equals('foobar',
+        callMethod(globalThis, 'doSum1', [interopCallback]).toString());
+    setProperty(globalThis, 'summer', interopCallback);
+    Expect.equals(
+        'foobar', callMethod(globalThis, 'doSum2', ['foo', 'bar']).toString());
+    final roundTripCallback = getProperty(globalThis, 'summer');
+    Expect.equals('foobar',
+        (dartify(roundTripCallback) as SumTwoPositionalFun)('foo', 'bar'));
+  }
+
+  // 1 nullable optional argument
+  {
+    final interopCallback = allowInterop<SumOnePositionalAndOneOptionalFun>(
+        (a, [b]) => a + (b ?? 'bar'));
+    setProperty(globalThis, 'summer', interopCallback);
+    Expect.equals(
+        'foobar',
+        callMethod(globalThis, 'doSumOnePositionalAndOneOptionalA', ['foo'])
+            .toString());
+    Expect.equals(
+        'foobar',
+        callMethod(
+                globalThis, 'doSumOnePositionalAndOneOptionalB', ['foo', 'bar'])
+            .toString());
+  }
+
+  // All nullable optional arguments
+  {
+    final interopCallback = allowInterop<SumTwoOptionalFun>(
+        ([a, b]) => (a ?? 'foo') + (b ?? 'bar'));
+    setProperty(globalThis, 'summer', interopCallback);
+    Expect.equals(
+        'foobar', callMethod(globalThis, 'doSumTwoOptionalA', []).toString());
+    Expect.equals('foobar',
+        callMethod(globalThis, 'doSumTwoOptionalB', ['foo']).toString());
+    Expect.equals('foobar',
+        callMethod(globalThis, 'doSumTwoOptionalC', ['foo', 'bar']).toString());
+  }
+
+  // 1 non-nullable optional argument
+  {
+    final interopCallback =
+        allowInterop<SumOnePositionalAndOneOptionalNonNullFun>(
+            (a, [b = 'bar']) => a + b);
+    setProperty(globalThis, 'summer', interopCallback);
+    Expect.equals(
+        'foobar',
+        callMethod(globalThis, 'doSumOnePositionalAndOneOptionalA', ['foo'])
+            .toString());
+    Expect.equals(
+        'foobar',
+        callMethod(
+                globalThis, 'doSumOnePositionalAndOneOptionalB', ['foo', 'bar'])
+            .toString());
+  }
+
+  // All non-nullable optional arguments
+  {
+    final interopCallback = allowInterop<SumTwoOptionalNonNullFun>(
+        ([a = 'foo', b = 'bar']) => a + b);
+    setProperty(globalThis, 'summer', interopCallback);
+    Expect.equals(
+        'foobar', callMethod(globalThis, 'doSumTwoOptionalA', []).toString());
+    Expect.equals('foobar',
+        callMethod(globalThis, 'doSumTwoOptionalB', ['foo']).toString());
+    Expect.equals('foobar',
+        callMethod(globalThis, 'doSumTwoOptionalC', ['foo', 'bar']).toString());
+  }
+
+  // Tear off cases
+  // No args.
+  {
+    final t = TornOffClass();
+    final interopCallback = allowInterop<NoArgsFun>(t.noArgs);
+    Expect.equals(
+        'foo', callMethod(globalThis, 'tearOffNoArgs', [interopCallback]));
+  }
+
+  // One arg.
+  {
+    final t = TornOffClass();
+    final interopCallback = allowInterop<OneArgFun>(t.oneArg);
+    Expect.equals(
+        'foo', callMethod(globalThis, 'tearOffOneArg', [interopCallback]));
+  }
+
+  // One positional and one optional case A.
+  {
+    final t = TornOffClass();
+    final interopCallback = allowInterop<OnePositionalAndOneOptionalArgsFun>(
+        t.onePositionalAndOneOptionalArgs);
+    Expect.equals(
+        'foobar',
+        callMethod(globalThis, 'tearOffOnePositionalAndOneOptionalArgsA',
+            [interopCallback]));
+  }
+
+  // One positional and one optional case B.
+  {
+    final t = TornOffClass();
+    final interopCallback = allowInterop<OnePositionalAndOneOptionalArgsFun>(
+        t.onePositionalAndOneOptionalArgs);
+    Expect.equals(
+        'foobaz',
+        callMethod(globalThis, 'tearOffOnePositionalAndOneOptionalArgsB',
+            [interopCallback]));
+  }
+
+  // Two positional case A.
+  {
+    final t = TornOffClass();
+    final interopCallback =
+        allowInterop<TwoPositionalArgsFun>(t.twoPositionalArgs);
+    Expect.equals('foo',
+        callMethod(globalThis, 'tearOffTwoPositionalArgsA', [interopCallback]));
+  }
+
+  // Two positional case B.
+  {
+    final t = TornOffClass();
+    final interopCallback =
+        allowInterop<TwoPositionalArgsFun>(t.twoPositionalArgs);
+    Expect.equals('foobaz',
+        callMethod(globalThis, 'tearOffTwoPositionalArgsB', [interopCallback]));
+  }
 }
 
 void main() {
diff --git a/tests/web/wasm/ffi_native_test.dart b/tests/web/wasm/ffi_native_test.dart
new file mode 100644
index 0000000..88c013d
--- /dev/null
+++ b/tests/web/wasm/ffi_native_test.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2022, 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.
+
+// SharedObjects=ffi_native_test_module
+
+import 'dart:ffi';
+import 'dart:nativewrappers';
+
+import 'package:expect/expect.dart';
+
+@FfiNative<Void Function()>("ffi.empty")
+external void empty();
+
+@FfiNative<Int8 Function(Int8, Int8)>("ffi.addInt8")
+external int addInt8(int a, int b);
+
+@FfiNative<Int8 Function(Uint8, Uint8)>("ffi.addUint8")
+external int addUint8(int a, int b);
+
+@FfiNative<Int16 Function(Int16, Int16)>("ffi.addInt16")
+external int addInt16(int a, int b);
+
+@FfiNative<Uint16 Function(Uint16, Uint16)>("ffi.addUint16")
+external int addUint16(int a, int b);
+
+@FfiNative<Int32 Function(Int32, Int32)>("ffi.addInt32")
+external int addInt32(int a, int b);
+
+@FfiNative<Uint32 Function(Uint32, Uint32)>("ffi.addUint32")
+external int addUint32(int a, int b);
+
+@FfiNative<Int64 Function(Int64, Int64)>("ffi.addInt64")
+external int addInt64(int a, int b);
+
+@FfiNative<Uint64 Function(Uint64, Uint64)>("ffi.addUint64")
+external int addUint64(int a, int b);
+
+@FfiNative<Bool Function(Bool)>("ffi.negateBool")
+external bool negateBool(bool b);
+
+@FfiNative<Bool Function(Int32)>("ffi.boolReturn")
+external bool boolReturn(int b);
+
+@FfiNative<Void Function()>("ffi.toggleBool")
+external void toggleBool();
+
+@FfiNative<Double Function(Double)>("ffi.sqrt")
+external double sqrt(double d);
+
+class MyStruct extends Struct implements NativeFieldWrapperClass1 {
+  @Double()
+  external double x;
+
+  @Int16()
+  external int y;
+}
+
+@FfiNative<Pointer<MyStruct> Function()>("ffi.getStruct")
+external Pointer<MyStruct> getStruct();
+
+@FfiNative<Void Function(Pointer<MyStruct>)>("ffi.clearStruct")
+external void clearStruct(Pointer<MyStruct> struct);
+
+void main() {
+  empty();
+
+  Expect.equals(addInt8(1, 2), 3);
+  Expect.equals(addInt8(127, 10), -119);
+
+  Expect.equals(addUint8(1, 2), 3);
+  Expect.equals(addUint8(255, 10), 9);
+
+  Expect.equals(addInt16(1, 2), 3);
+  Expect.equals(addInt16(32767, 10), -32759);
+
+  Expect.equals(addUint16(1, 2), 3);
+  Expect.equals(addUint16(65535, 10), 9);
+
+  Expect.equals(addInt32(1, 2), 3);
+  Expect.equals(addInt32(2147483647, 10), -2147483639);
+
+  Expect.equals(addUint32(1, 2), 3);
+  Expect.equals(addUint32(4294967295, 10), 9);
+
+  Expect.equals(addInt64(1, 2), 3);
+  Expect.equals(addInt64(9223372036854775807, 10), -9223372036854775799);
+
+  Expect.equals(addUint64(1, 2), 3);
+  Expect.equals(addUint64(9223372036854775807, 10), -9223372036854775799);
+
+  Expect.equals(negateBool(true), false);
+  Expect.equals(negateBool(false), true);
+
+  Expect.equals(boolReturn(123), true);
+  Expect.equals(boolReturn(456), false);
+  Expect.equals(boolReturn(789), true);
+  toggleBool();
+  Expect.equals(boolReturn(789), false);
+
+  final struct_ = getStruct();
+  Expect.equals(struct_.ref.x, 1.0);
+  Expect.equals(struct_.ref.y, 2);
+  clearStruct(struct_);
+  Expect.equals(struct_.ref.x, 0.0);
+  Expect.equals(struct_.ref.y, 0);
+}
diff --git a/tests/web/wasm/ffi_native_test_module.c b/tests/web/wasm/ffi_native_test_module.c
new file mode 100644
index 0000000..e6964a0
--- /dev/null
+++ b/tests/web/wasm/ffi_native_test_module.c
@@ -0,0 +1,90 @@
+// Copyright (c) 2022, 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 <emscripten.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+struct MyStruct {
+    double x;
+    int16_t y;
+} s = { 1.0, 2 }, a[10];
+
+EMSCRIPTEN_KEEPALIVE
+struct MyStruct* getStruct() {
+    return &s;
+}
+
+EMSCRIPTEN_KEEPALIVE
+void clearStruct(struct MyStruct* s) {
+    s->x = 0.0;
+    s->y = 0;
+}
+
+EMSCRIPTEN_KEEPALIVE
+void empty() {}
+
+EMSCRIPTEN_KEEPALIVE
+int8_t addInt8(int8_t a, int8_t b) {
+    return a + b;
+}
+
+EMSCRIPTEN_KEEPALIVE
+uint8_t addUint8(uint8_t a, uint8_t b) {
+    return a + b;
+}
+
+EMSCRIPTEN_KEEPALIVE
+int16_t addInt16(int16_t a, int16_t b) {
+    return a + b;
+}
+
+EMSCRIPTEN_KEEPALIVE
+uint16_t addUint16(uint16_t a, uint16_t b) {
+    return a + b;
+}
+
+EMSCRIPTEN_KEEPALIVE
+int32_t addInt32(int32_t a, int32_t b) {
+    return a + b;
+}
+
+EMSCRIPTEN_KEEPALIVE
+uint32_t addUint32(uint32_t a, uint32_t b) {
+    return a + b;
+}
+
+EMSCRIPTEN_KEEPALIVE
+int64_t addInt64(int64_t a, int64_t b) {
+    return a + b;
+}
+
+EMSCRIPTEN_KEEPALIVE
+uint64_t addUint64(uint64_t a, uint64_t b) {
+    return a + b;
+}
+
+EMSCRIPTEN_KEEPALIVE
+bool negateBool(bool a) {
+    return !a;
+}
+
+static bool b = true;
+
+EMSCRIPTEN_KEEPALIVE
+void toggleBool() {
+    b = !b;
+}
+
+EMSCRIPTEN_KEEPALIVE
+bool boolReturn(int a) {
+    if (a == 123) {
+        return true;
+    } else if (a == 456) {
+        return false;
+    } else {
+        return b;
+    }
+}
diff --git a/tests/web/wasm/js_util_test.dart b/tests/web/wasm/js_util_test.dart
index c62d2c7..f017d92 100644
--- a/tests/web/wasm/js_util_test.dart
+++ b/tests/web/wasm/js_util_test.dart
@@ -5,6 +5,7 @@
 import 'dart:js_util';
 import 'dart:typed_data';
 
+import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 import 'package:js/js.dart';
 
@@ -19,6 +20,61 @@
   Expect.equals('bar', getProperty(o, 'foo'));
 }
 
+void equalTest() {
+  // Different objects aren't equal.
+  {
+    Object o1 = newObject();
+    Object o2 = newObject();
+    Expect.notEquals(o1, o2);
+  }
+
+  {
+    eval(r'''
+      function JSClass() {}
+
+      globalThis.boolData = true;
+      globalThis.boolData2 = true;
+      globalThis.numData = 4;
+      globalThis.numData2 = 4;
+      globalThis.arrData = [1, 2, 3];
+      globalThis.strData = 'foo';
+      globalThis.strData2 = 'foo';
+      globalThis.funcData = function JSClass() {}
+      globalThis.JSClass = new globalThis.funcData();
+    ''');
+    Object gt = globalThis;
+    void test(String propertyName, bool testCanonicalization) {
+      Expect.equals(
+          getProperty(gt, propertyName), getProperty(gt, propertyName));
+      if (testCanonicalization) {
+        Expect.equals(
+            getProperty(gt, propertyName), getProperty(gt, propertyName + "2"));
+      }
+    }
+
+    test("boolData", true);
+    test("numData", true);
+    // TODO(joshualitt): Start returning arrays by reference.
+    //test("arrData", false);
+    test("strData", true);
+    test("funcData", false);
+    test("JSClass", false);
+  }
+}
+
+void instanceofTest() {
+  eval(r'''
+      globalThis.JSClass1 = function() {}
+      globalThis.JSClass2 = function() {}
+
+      globalThis.obj = new JSClass1();
+    ''');
+  Expect.isTrue(instanceof(
+      getProperty(globalThis, 'obj'), getProperty(globalThis, 'JSClass1')));
+  Expect.isFalse(instanceof(
+      getProperty(globalThis, 'obj'), getProperty(globalThis, 'JSClass2')));
+}
+
 void _expectIterableEquals(Iterable<Object?> l, Iterable<Object?> r) {
   final lIt = l.iterator;
   final rIt = r.iterator;
@@ -210,9 +266,66 @@
       callMethod(gt, 'invoke', <Object?>[dartify(getProperty(gt, 'f'))]));
 }
 
-void main() {
+Future<void> promiseToFutureTest() async {
+  Object gt = globalThis;
+  eval(r'''
+    globalThis.rejectedPromise = new Promise((resolve, reject) => reject('rejected'));
+    globalThis.resolvedPromise = new Promise(resolve => resolve('resolved'));
+    globalThis.getResolvedPromise = function() {
+      return resolvedPromise;
+    }
+    //globalThis.nullRejectedPromise = Promise.reject(null);
+  ''');
+
+  // Test resolved
+  {
+    Future f = promiseToFuture(getProperty(gt, 'resolvedPromise'));
+    Expect.equals('resolved', await f);
+  }
+
+  // Test rejected
+  {
+    String result = await asyncExpectThrows<String>(
+        promiseToFuture(getProperty(gt, 'rejectedPromise')));
+    Expect.equals('rejected', result);
+  }
+
+  // Test return resolved
+  {
+    Future f = promiseToFuture(callMethod(gt, 'getResolvedPromise', []));
+    Expect.equals('resolved', await f);
+  }
+
+  // Test promise chaining
+  {
+    bool didThen = false;
+    Future f = promiseToFuture(callMethod(gt, 'getResolvedPromise', []));
+    f.then((resolved) {
+      Expect.equals(resolved, 'resolved');
+      didThen = true;
+    });
+    await f;
+    Expect.isTrue(didThen);
+  }
+
+  // Test rejecting promise with null should trigger an exception.
+  // TODO(joshualitt): Fails with an illegal cast.
+  // {
+  //   Future f = promiseToFuture(getProperty(gt, 'nullRejectedPromise'));
+  //   f.then((_) { Expect.fail("Expect promise to reject"); }).catchError((e) {
+  //     print('A');
+  //     Expect.isTrue(e is NullRejectionException);
+  //   });
+  //   await f;
+  // }
+}
+
+void main() async {
   createObjectTest();
+  equalTest();
+  instanceofTest();
   evalAndConstructTest();
   dartObjectRoundTripTest();
   deepConversionsTest();
+  await promiseToFutureTest();
 }
diff --git a/tests/web/wasm/static_interop_test.dart b/tests/web/wasm/static_interop_test.dart
index 1aeed4c..c642334 100644
--- a/tests/web/wasm/static_interop_test.dart
+++ b/tests/web/wasm/static_interop_test.dart
@@ -17,23 +17,106 @@
 extension StaticJSClassMethods on StaticJSClass {
   external String foo;
   external String sum(String a, String? b, String c);
+  external void doublifyNumbers();
+  external set nonNullableInt(int d);
+  external int get nonNullableInt;
+  external set nullableInt(int? d);
+  external int? get nullableInt;
+  external int nonNullableIntReturnMethod();
+  external int? nullableIntReturnMethod(bool returnNull);
+  external String doSum1Or2(String a, [String? b]);
+  external String doSumUpTo2([String? a, String? b]);
+  external String doSum1Or2NonNull(String a, [String b = 'bar']);
+  external String doSumUpTo2NonNull([String a = 'foo', String b = 'bar']);
 }
 
 void createClassTest() {
   eval(r'''
     globalThis.JSClass = function(foo) {
       this.foo = foo;
+      this.nonNullableInt = 6;
+      this.nonNullableIntReturnMethod = function() {
+        return 7;
+      }
+      this.nullableIntReturnMethod = function(returnNull) {
+        if (returnNull) {
+          return null;
+        } else {
+          return 8;
+        }
+      }
       this.sum = function(a, b, c) {
         if (b == null) b = ' ';
         return a + b + c;
       }
+      this.doublifyNumbers = function() {
+        this.nonNullableInt = 60.5;
+        this.nullableInt = 100.5;
+      }
+      this.doSum1Or2 = function(a, b) {
+        return a + (b ?? 'bar');
+      }
+      this.doSumUpTo2 = function(a, b) {
+        return (a ?? 'foo') + (b ?? 'bar');
+      }
+      this.doSum1Or2NonNull = function(a, b) {
+        return a + b;
+      }
+      this.doSumUpTo2NonNull = function(a, b) {
+        return a + b;
+      }
     }
   ''');
   final foo = StaticJSClass.factory('foo');
-  Expect.equals(foo.foo, 'foo');
+  Expect.equals('foo', foo.foo);
   foo.foo = 'bar';
-  Expect.equals(foo.foo, 'bar');
+  Expect.equals('bar', foo.foo);
   Expect.equals('hello world!!', foo.sum('hello', null, 'world!!'));
+  Expect.equals(null, foo.nullableInt);
+  foo.nullableInt = 5;
+  Expect.equals(5, foo.nullableInt);
+  Expect.equals(6, foo.nonNullableInt);
+  foo.nonNullableInt = 16;
+  Expect.equals(16, foo.nonNullableInt);
+  Expect.equals(7, foo.nonNullableIntReturnMethod());
+  Expect.equals(8, foo.nullableIntReturnMethod(false));
+  Expect.equals(null, foo.nullableIntReturnMethod(true));
+  foo.doublifyNumbers();
+  Expect.equals(100, foo.nullableInt);
+  Expect.equals(60, foo.nonNullableInt);
+
+  Expect.equals('foobar', foo.doSum1Or2('foo'));
+  Expect.equals('foobar', foo.doSum1Or2('foo', 'bar'));
+  Expect.equals('foobar', foo.doSumUpTo2());
+  Expect.equals('foobar', foo.doSumUpTo2('foo'));
+  Expect.equals('foobar', foo.doSumUpTo2('foo', 'bar'));
+
+  Expect.equals('foobar', foo.doSum1Or2NonNull('foo'));
+  Expect.equals('foobar', foo.doSum1Or2NonNull('foo', 'bar'));
+  Expect.equals('foobar', foo.doSumUpTo2NonNull());
+  Expect.equals('foobar', foo.doSumUpTo2NonNull('foo'));
+  Expect.equals('foobar', foo.doSumUpTo2NonNull('foo', 'bar'));
+}
+
+@JS('JSClass.NestedJSClass')
+@staticInterop
+class NestedJSClass {
+  external factory NestedJSClass.factory(String foo);
+}
+
+extension NestedJSClassMethods on NestedJSClass {
+  external String foo;
+}
+
+void createClassWithNestedJSNameTest() {
+  eval(r'''
+    globalThis.JSClass = {};
+    globalThis.JSClass.NestedJSClass = function(foo) {
+      this.foo = foo;
+    };
+  ''');
+  final foo = NestedJSClass.factory('foo');
+  Expect.equals(foo.foo, 'foo');
 }
 
 @JS('JSParent')
@@ -162,6 +245,7 @@
 
 void main() {
   createClassTest();
+  createClassWithNestedJSNameTest();
   setInteropPropertyTest();
   setDartObjectPropertyTest();
   topLevelMethodsTest();
diff --git a/tests/web/wasm/wasm_types_test.dart b/tests/web/wasm/wasm_types_test.dart
index 0ce54a3..1f1da18 100644
--- a/tests/web/wasm/wasm_types_test.dart
+++ b/tests/web/wasm/wasm_types_test.dart
@@ -7,14 +7,14 @@
 import 'package:expect/expect.dart';
 
 @pragma("wasm:import", "Object.create")
-external WasmAnyRef createObject(WasmAnyRef? prototype);
+external WasmExternRef? createObject(WasmExternRef? prototype);
 
 @pragma("wasm:import", "Array.of")
-external WasmAnyRef singularArray(WasmAnyRef element);
+external WasmExternRef? singularArray(WasmExternRef? element);
 
 @pragma("wasm:import", "Reflect.apply")
-external WasmAnyRef apply(
-    WasmFuncRef target, WasmAnyRef thisArgument, WasmAnyRef argumentsList);
+external WasmExternRef? apply(WasmFuncRef? target, WasmExternRef? thisArgument,
+    WasmExternRef? argumentsList);
 
 WasmAnyRef? anyRef;
 WasmEqRef? eqRef;
@@ -32,7 +32,7 @@
   Object dartObject1 = "1";
   Object dartObject2 = true;
   Object dartObject3 = Object();
-  WasmAnyRef jsObject1 = createObject(null);
+  WasmAnyRef jsObject1 = createObject(null)!.internalize();
 
   // A JS object is not a Dart object.
   Expect.isFalse(jsObject1.isObject);
@@ -77,7 +77,7 @@
   var dartObjectRef = WasmEqRef.fromObject("Dart object");
   var ff = WasmFunction.fromFunction(fun);
   ff.call(dartObjectRef);
-  apply(ff, createObject(null), singularArray(dartObjectRef));
+  apply(ff, createObject(null), singularArray(dartObjectRef.externalize()));
 
   // Cast a typed function reference to a `funcref` and back.
   WasmFuncRef funcref = WasmFuncRef.fromWasmFunction(ff);
@@ -86,7 +86,7 @@
 
   // Create a typed function reference from an import and call it.
   var createObjectFun = WasmFunction.fromFunction(createObject);
-  WasmAnyRef jsObject3 = createObjectFun.call(null);
+  WasmAnyRef jsObject3 = createObjectFun.call(null).internalize()!;
   Expect.isFalse(jsObject3.isObject);
 
   Expect.equals(3, funCount);
diff --git a/tools/OWNERS_ECOSYSTEM b/tools/OWNERS_ECOSYSTEM
index 1b71776..d338068 100644
--- a/tools/OWNERS_ECOSYSTEM
+++ b/tools/OWNERS_ECOSYSTEM
@@ -1,5 +1,6 @@
 devoncarew@google.com
 kevmoo@google.com
 mit@google.com
+mosum@google.com
 nbosch@google.com
 omersa@google.com
diff --git a/tools/VERSION b/tools/VERSION
index 937d6ab..9047c02 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 19
 PATCH 0
-PRERELEASE 146
-PRERELEASE_PATCH 2
+PRERELEASE 255
+PRERELEASE_PATCH 1
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index f1d1cdf..411f2c17 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -181,6 +181,7 @@
       "out/ReleaseX64/dart2wasm_asserts.snapshot",
       "out/ReleaseX64/dart2wasm_outline.dill",
       "out/ReleaseX64/dart2wasm_platform.dill",
+      "out/ReleaseX64/wasm/",
       "pkg/",
       "runtime/tests/",
       "samples-dev/",
@@ -206,8 +207,7 @@
       "third_party/d8/",
       "third_party/pkg/",
       "third_party/requirejs/",
-      "tools/",
-      "xcodebuild/ReleaseX64/dart"
+      "tools/"
     ],
     "front-end": [
       ".dart_tool/package_config.json",
@@ -1377,6 +1377,7 @@
     },
     {
       "builders": [
+        "vm-kernel-precomp-nnbd-linux-debug-simriscv64",
         "vm-kernel-precomp-nnbd-linux-debug-x64",
         "vm-kernel-precomp-nnbd-linux-release-simarm64",
         "vm-kernel-precomp-nnbd-linux-release-simarm64c",
@@ -1946,6 +1947,7 @@
     {
       "builders": [
         "vm-kernel-nnbd-linux-debug-ia32",
+        "vm-kernel-nnbd-linux-debug-simriscv64",
         "vm-kernel-nnbd-linux-debug-x64",
         "vm-kernel-nnbd-linux-debug-x64c",
         "vm-kernel-nnbd-linux-release-ia32",
@@ -1962,9 +1964,9 @@
         "vm-kernel-nnbd-mac-release-arm64",
         "vm-kernel-nnbd-mac-release-x64",
         "vm-kernel-nnbd-mac-release-x64c",
-        "vm-kernel-nnbd-win-release-ia32",
         "vm-kernel-nnbd-win-debug-x64",
         "vm-kernel-nnbd-win-debug-x64c",
+        "vm-kernel-nnbd-win-release-ia32",
         "vm-kernel-nnbd-win-release-x64",
         "vm-kernel-nnbd-win-release-x64c"
       ],
@@ -3148,9 +3150,10 @@
             "language",
             "corelib",
             "web/wasm",
-            "lib/js/static_interop_test"
+            "lib/lib/(async|collection|convert|js/static_interop_test|math|typed_data)/",
+            "co19/co19/(src/)?(Language|LanguageFeatures|LibTest/(async|collection|convert|core|math|typed_data))/"
           ],
-          "shards": 3,
+          "shards": 10,
           "fileset": "dart2wasm_hostasserts"
         }
       ]
@@ -3202,64 +3205,6 @@
     },
     {
       "builders": [
-        "dart-sdk-mac",
-        "dart-sdk-mac-arm64"
-      ],
-      "meta": {
-        "description": "This configuration is used by the sdk-builders for MacOS."
-      },
-      "steps": [
-        {
-          "name": "build dart",
-          "script": "tools/build.py",
-          "arguments": [
-            "--mode=release",
-            "--check-clean",
-            "create_sdk"
-          ],
-          "environment": {
-            "DART_GN_ARGS": "mac_use_goma_rbe=true"
-          }
-        },
-        {
-          "name": "upload sdk",
-          "script": "tools/bots/dart_sdk.py",
-          "arguments": [
-            "--arch=${arch}"
-          ]
-        }
-      ]
-    },
-    {
-      "builders": [
-        "dart-sdk-win"
-      ],
-      "meta": {
-        "description": "This configuration is used by the sdk-builders for Windows. It also adds CQ coverage for building on Windows."
-      },
-      "steps": [
-        {
-          "name": "build dart",
-          "script": "tools/build.py",
-          "arguments": [
-            "--arch=ia32,x64,arm64",
-            "--mode=release",
-            "--check-clean",
-            "create_sdk",
-            "runtime"
-          ]
-        },
-        {
-          "name": "upload sdk",
-          "script": "tools/bots/dart_sdk.py",
-          "arguments": [
-            "--arch=ia32,x64,arm64"
-          ]
-        }
-      ]
-    },
-    {
-      "builders": [
         "debianpackage-linux"
       ],
       "meta": {
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index 20258a0..b7892de 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -150,7 +150,7 @@
       out/ReleaseIA32/kernel-service.dart.snapshot \
       out/ReleaseIA32/run_vm_tests \
       sdk \
-      samples-dev/swarm \
+      pkg/compiler/test/codesize/swarm \
       third_party/pkg \
       .dart_tool/package_config.json \
       pkg \
@@ -297,7 +297,7 @@
       out/ReleaseX64/gen/utils/dartdevc/sound/ \
       out/ReleaseX64/ddc_outline_sound.dill \
       sdk \
-      samples-dev/swarm \
+      pkg/compiler/test/codesize/swarm \
       third_party/pkg \
       .dart_tool/package_config.json \
       pkg \
diff --git a/tools/build.py b/tools/build.py
index aa0f625..296fe61 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -167,7 +167,7 @@
     build_config = utils.GetBuildConf(mode, arch, target_os, sanitizer)
     out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os, sanitizer)
     using_goma = False
-    command = ['ninja', '-C', out_dir]
+    command = ['buildtools/ninja/ninja', '-C', out_dir]
     if options.verbose:
         command += ['-v']
     if UseGoma(out_dir):
diff --git a/tools/dom/scripts/css_code_generator.py b/tools/dom/scripts/css_code_generator.py
index 3510edd..16cf73b 100644
--- a/tools/dom/scripts/css_code_generator.py
+++ b/tools/dom/scripts/css_code_generator.py
@@ -232,20 +232,19 @@
 
 class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase {
   final Iterable<Element> _elementIterable;
-  Iterable<CssStyleDeclaration>$NULLABLE _elementCssStyleDeclarationSetIterable;
+  Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable;
 
-  _CssStyleDeclarationSet(this._elementIterable) {
-    _elementCssStyleDeclarationSetIterable = new List.from(
-        _elementIterable).map((e) => e.style);
-  }
+  _CssStyleDeclarationSet(this._elementIterable)
+    : _elementCssStyleDeclarationSetIterable = 
+            new List.of(_elementIterable).map((e) => e.style);
 
   String getPropertyValue(String propertyName) =>
-      _elementCssStyleDeclarationSetIterable$NULLASSERT.first.getPropertyValue(
+      _elementCssStyleDeclarationSetIterable.first.getPropertyValue(
           propertyName);
 
   void setProperty(String propertyName, String$NULLABLE value,
       [String$NULLABLE priority]) {
-    _elementCssStyleDeclarationSetIterable$NULLASSERT.forEach((e) =>
+    _elementCssStyleDeclarationSetIterable.forEach((e) =>
         e.setProperty(propertyName, value, priority));
   }
 
diff --git a/tools/dom/scripts/dartdomgenerator.py b/tools/dom/scripts/dartdomgenerator.py
index dd31046..132f6c2 100755
--- a/tools/dom/scripts/dartdomgenerator.py
+++ b/tools/dom/scripts/dartdomgenerator.py
@@ -56,6 +56,7 @@
 from generate_blink_file import Generate_Blink
 from htmleventgenerator import HtmlEventGenerator
 from htmlrenamer import HtmlRenamer
+from prototype_htmleventgenerator import Prototype_HtmlEventGenerator
 from systemhtml import DartLibraryEmitter, Dart2JSBackend,\
                        HtmlDartInterfaceGenerator, DartLibrary, DartLibraries,\
                        HTML_LIBRARY_NAMES
@@ -95,7 +96,8 @@
                          update_dom_metadata=False,
                          logging_level=logging.WARNING,
                          dart_js_interop=False,
-                         generate_static_extensions=False):
+                         generate_static_extensions=False,
+                         generate_prototype_events=False):
     print('\n ----- Accessing DOM using %s -----\n' %
           ('dart:js' if dart_js_interop else 'C++'))
 
@@ -142,17 +144,22 @@
                                                   dart_libraries)
         event_generator = HtmlEventGenerator(webkit_database, renamer, metadata,
                                              template_loader)
+        prototype_event_generator = Prototype_HtmlEventGenerator(
+            webkit_database, renamer, metadata, event_generator)
 
         def generate_interface(interface, gl_constants=None):
             backend = backend_factory(interface)
             interface_generator = HtmlDartInterfaceGenerator(
-                options, dart_library_emitter, event_generator, interface,
-                backend)
+                options, dart_library_emitter, event_generator,
+                prototype_event_generator, interface, backend)
             interface_generator.Generate()
             if len(backend._gl_constants) > 0 and not (gl_constants is None):
                 gl_constants.extend(backend._gl_constants)
 
         generator.Generate(webkit_database, common_database, generate_interface)
+        if generate_prototype_events:
+            dart_bin = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dart')
+            prototype_event_generator.WriteFile(dart_bin)
 
         dart_library_emitter.EmitLibraries(auxiliary_dir, dart_js_interop)
 
@@ -313,6 +320,12 @@
         action='store_true',
         default=False,
         help='Generate static extension members for dart:html classes')
+    parser.add_option(
+        '--generate-prototype-events',
+        dest='generate_prototype_events',
+        action='store_true',
+        default=False,
+        help='Generate event stream library for dart:html prototype')
 
     (options, args) = parser.parse_args()
 
@@ -345,7 +358,8 @@
     GenerateFromDatabase(database, dart2js_output_dir,
                          options.update_dom_metadata, logging_level,
                          options.dart_js_interop,
-                         options.generate_static_extensions)
+                         options.generate_static_extensions,
+                         options.generate_prototype_events)
 
     file_generation_start_time = time.time()
 
diff --git a/tools/dom/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
index 0e47653..4efff34 100644
--- a/tools/dom/scripts/htmleventgenerator.py
+++ b/tools/dom/scripts/htmleventgenerator.py
@@ -287,7 +287,7 @@
     def EmitStreamProviders(self, interface, custom_events, members_emitter,
                             library_name):
 
-        events = self._GetEvents(interface, custom_events)
+        events = self.GetEvents(interface, custom_events)
         if not events:
             return
 
@@ -321,7 +321,7 @@
                           stream_getter_signatures_emitter=None,
                           element_stream_getters_emitter=None):
 
-        events = self._GetEvents(interface, custom_events)
+        events = self.GetEvents(interface, custom_events)
         if not events:
             return
 
@@ -386,7 +386,7 @@
                 ]))
         return events
 
-    def _GetEvents(self, interface, custom_events):
+    def GetEvents(self, interface, custom_events):
         """ Gets a list of all of the events for the specified interface.
     """
         html_interface_name = interface.doc_js_name
@@ -422,7 +422,7 @@
         return events
 
     def _HasEvent(self, events, event_name, event_type):
-        """ Checks if the event is declared in the list of events (from _GetEvents),
+        """ Checks if the event is declared in the list of events (from GetEvents),
     with the same event type.
     """
         for (dom_name, html_name, found_type) in events:
@@ -442,7 +442,7 @@
                 interface.doc_js_name == 'GlobalEventHandlers'):
             media_interface = self._database.GetInterface('HTMLMediaElement')
             if not self._media_events:
-                self._media_events = self._GetEvents(media_interface, [])
+                self._media_events = self.GetEvents(media_interface, [])
             if self._HasEvent(self._media_events, event_name, event_type):
                 return True
 
@@ -452,7 +452,7 @@
     """
         if interface.doc_js_name == 'Window' or interface.doc_js_name == 'Document':
             element_interface = self._database.GetInterface('Element')
-            element_events = self._GetEvents(element_interface, [])
+            element_events = self.GetEvents(element_interface, [])
             if self._HasEvent(element_events, event_name, event_type):
                 return 'Element'
         return None
diff --git a/tools/dom/scripts/prototype_css_generator.py b/tools/dom/scripts/prototype_css_generator.py
index 7cf54af..3c4af43 100644
--- a/tools/dom/scripts/prototype_css_generator.py
+++ b/tools/dom/scripts/prototype_css_generator.py
@@ -90,9 +90,21 @@
     output_file = open(OUTPUT_FILE, 'w')
     output_file.write("""
 /// Exposing all the extra CSS property getters and setters.
-part of 'dart:html_extensions';
+@JS()
+library dart.css_properties;
 
-extension CssStyleDeclarationPropertiesExtension on html.CssStyleDeclaration {
+import 'dart:_js_annotations';
+import 'dart:_js_bindings' as js_bindings;
+import 'dart:html_common';
+
+@JS()
+@staticInterop
+class CssStyleDeclaration implements js_bindings.CSSStyleDeclaration {}
+
+extension CssStyleDeclarationView on CssStyleDeclaration {
+  // dart:html requires a `String?` type for `value`.
+  external Object setProperty(String property, String? value,
+      [String? priority = '']);
 
   // ##### Universal property getters and setters #####
   """)
diff --git a/tools/dom/scripts/prototype_htmleventgenerator.py b/tools/dom/scripts/prototype_htmleventgenerator.py
new file mode 100644
index 0000000..1418ed2
--- /dev/null
+++ b/tools/dom/scripts/prototype_htmleventgenerator.py
@@ -0,0 +1,182 @@
+#!/usr/bin/env python3
+# Copyright (c) 2022, 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.
+"""Generates the dart:html event providers and getters for the prototype."""
+
+import monitored
+import subprocess
+
+OUTPUT_FILE = 'prototype_events.dart'
+
+_custom_events = set(['mouseWheel', 'transitionEnd', 'visibilityChange'])
+
+_type_specific_events = set(['doubleClick', 'error'])
+
+_deprecated_event_interfaces = set([
+    'AccessibleNode', 'AccessibleNodeList', 'ApplicationCache', 'FileWriter',
+    'VRSession'
+])
+_deprecated_event_types = set(['ForeignFetchEvent', 'MediaStreamEvent'])
+
+_non_html_types = monitored.Dict(
+    'prototype_htmleventgenerator._non_html_events', {
+        'ContextEvent': 'web_gl',
+        'Database': 'indexed_db',
+        'OpenDBRequest': 'indexed_db',
+        'Request': 'indexed_db',
+        'SvgElement': 'svg',
+        'Transaction': 'indexed_db',
+        'VersionChangeEvent': 'indexed_db'
+    })
+
+
+class Prototype_HtmlEventGenerator(object):
+
+    def __init__(self, database, renamer, metadata, htmleventgenerator):
+        self._database = database
+        self._renamer = renamer
+        self._metadata = metadata
+        self._html_event_generator = htmleventgenerator
+        self._all_event_providers = {}
+        self._all_event_getters = {}
+
+    # Gather all EventStreamProviders for the given interface type.
+    def CollectStreamProviders(self, interface, custom_events, library_name):
+
+        events = self._html_event_generator.GetEvents(interface, custom_events)
+        if not events:
+            return
+
+        for event_info in events:
+            (dom_name, html_name, event_type) = event_info
+            # Skip custom events that are added to glue code separately
+            if html_name in _custom_events:
+                continue
+            annotation_name = dom_name + 'Event'
+
+            annotations = self._metadata.FormatMetadata(
+                self._metadata.GetMetadata(library_name, interface,
+                                           annotation_name, 'on' + dom_name),
+                '  ')
+
+            # Strip comment from annotations
+            if '/**' in annotations:
+                annotations = annotations[annotations.index('*/') + 2:]
+            event_type = self._formatEventType(event_type)
+            html_name = (html_name if html_name not in _type_specific_events
+                         else html_name + interface.doc_js_name)
+
+            self._all_event_providers.update(
+                {html_name: [annotations, dom_name, event_type]})
+
+    # Gather all getters `onFooEvent` for the given interface type.
+    def CollectStreamGetters(self, interface, custom_events, library_name):
+        events = self._html_event_generator.GetEvents(interface, custom_events)
+        if not events:
+            return
+        interface_events = {}
+        for event_info in events:
+            (dom_name, html_name, event_type) = event_info
+            # Skip custom events that are added to glue code separately
+            if html_name in _custom_events:
+                continue
+            getter_name = 'on%s%s' % (html_name[:1].upper(), html_name[1:])
+            annotation_name = 'on' + dom_name
+
+            annotations = self._metadata.GetFormattedMetadata(
+                library_name, interface, annotation_name, '  ')
+
+            # Strip comment from annotations
+            if '///' in annotations:
+                annotations = annotations[annotations.index('\n') + 1:]
+
+            event_type = self._formatEventType(event_type)
+            html_name = (html_name if html_name not in _type_specific_events
+                         else html_name + interface.doc_js_name)
+            provider = html_name + 'Event'
+
+            interface_events.update(
+                {getter_name: [annotations, event_type, provider]})
+        self._all_event_getters.update({interface: interface_events})
+
+    # Returns whether the given interface has `Element` as a supertype.
+    def _isElement(self, interface):
+        for parent in self._database.Hierarchy(interface):
+            if parent.id == 'Element':
+                return True
+        return False
+
+    # Formats event_type by stripping other namespace prefixing.
+    def _formatEventType(self, event_type):
+        if '.' in event_type:
+            event_type = event_type[event_type.index('.') + 1:]
+        return event_type
+
+    # Output Providers and Event Getters to the output file.
+    def WriteFile(self, dart_bin):
+        output_file = open(OUTPUT_FILE, 'w')
+        output_file.write("""
+/// Exposing the Streams of events for legacy dart:html.
+library dart.html_events;
+
+import 'dart:html' as html;
+import 'dart:html_common';
+import 'dart:indexed_db' as indexed_db;
+import 'dart:event_stream' show ElementStream, EventStreamProvider;
+import 'dart:svg' as svg;
+import 'dart:web_gl' as web_gl;
+
+""")
+        self._writeProviders(output_file)
+        self._writeEventGetters(output_file)
+        output_file.close()
+        formatCommand = ' '.join([dart_bin, 'format', OUTPUT_FILE])
+        subprocess.call([formatCommand], shell=True)
+
+    # Output all EventstreamProviders.
+    def _writeProviders(self, output_file):
+        output_file.write("""
+/// Statically accessible `EventStreamProvider`s for all event types.
+class EventStreamProviders {
+""")
+        for html_name, info in sorted(self._all_event_providers.items()):
+            (annotations, dom_name, event_type) = info
+            if event_type in _deprecated_event_types:
+                continue
+            event_prefix = ('html' if event_type not in _non_html_types else
+                            _non_html_types[event_type])
+            output_file.write("""
+  %sstatic const EventStreamProvider<%s.%s> %sEvent = 
+  const EventStreamProvider<%s.%s>('%s');
+""" % (annotations, event_prefix, event_type, html_name, event_prefix,
+            event_type, dom_name))
+        output_file.write("""\n}\n""")
+
+    # Output all onFooEvent getters in extensions.
+    def _writeEventGetters(self, output_file):
+        for interface, events in self._all_event_getters.items():
+            isElement = self._isElement(interface)
+            interface_name = interface.doc_js_name
+            if interface_name in _deprecated_event_interfaces:
+                continue
+            interface_name = self._renamer.RenameInterface(interface)
+            interface_prefix = ('html' if interface_name not in _non_html_types
+                                else _non_html_types[interface_name])
+            output_file.write("""
+
+/// Additional Event getters for [%s].
+extension %sEventGetters on %s.%s {
+""" % (interface_name, interface_name, interface_prefix, interface_name))
+            for getter_name, info in sorted(events.items()):
+                (annotations, event_type, provider) = info
+                if event_type in _deprecated_event_types:
+                    continue
+                event_prefix = ('html' if event_type not in _non_html_types else
+                                _non_html_types[event_type])
+                output_file.write("""
+%s
+%sStream<%s.%s> get %s => EventStreamProviders.%s.%s(this);
+""" % (annotations, 'Element' if isElement else '', event_prefix, event_type,
+                getter_name, provider, 'forElement' if isElement else 'forTarget'))
+            output_file.write("""\n}\n""")
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 63d913e..c20bbb6 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -596,8 +596,8 @@
 class HtmlDartInterfaceGenerator(object):
     """Generates dart interface and implementation for the DOM IDL interface."""
 
-    def __init__(self, options, library_emitter, event_generator, interface,
-                 backend):
+    def __init__(self, options, library_emitter, event_generator,
+                 prototype_event_generator, interface, backend):
         self._renamer = options.renamer
         self._database = options.database
         self._template_loader = options.templates
@@ -605,6 +605,7 @@
         self._options = options
         self._library_emitter = library_emitter
         self._event_generator = event_generator
+        self._prototype_event_generator = prototype_event_generator
         self._interface = interface
         self._backend = backend
         self._interface_type_info = self._type_registry.TypeInfo(
@@ -850,6 +851,9 @@
         self._event_generator.EmitStreamProviders(
             self._interface, self._backend.CustomJSMembers(),
             implementation_members_emitter, self._library_name)
+        self._prototype_event_generator.CollectStreamProviders(
+            self._interface, self._backend.CustomJSMembers(),
+            self._library_name)
         self._backend.AddConstructors(constructors, factory_provider,
                                       factory_constructor_name,
                                       class_members_emitter)
@@ -891,6 +895,8 @@
             self._interface, [], implementation_members_emitter,
             self._library_name, stream_getter_signatures_emitter,
             element_stream_getters_emitter)
+        self._prototype_event_generator.CollectStreamGetters(
+            self._interface, [], self._library_name)
         self._backend.FinishInterface()
 
     def _ImplementationEmitter(self):
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index 19e25fc..d58b3aa 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -219,10 +219,6 @@
   bool get isBroadcast => true;
 }
 
-// We would like this to just be EventListener<T> but that typdef cannot
-// use generics until dartbug/26276 is fixed.
-typedef _EventListener<T extends Event>(T event);
-
 class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
   int _pauseCount = 0;
   EventTarget? _target;
@@ -230,19 +226,13 @@
   EventListener? _onData;
   final bool _useCapture;
 
-  // TODO(leafp): It would be better to write this as
-  // _onData = onData == null ? null :
-  //   onData is void Function(Event)
-  //     ? _wrapZone<Event>(onData)
-  //     : _wrapZone<Event>((e) => onData(e as T))
-  // In order to support existing tests which pass the wrong type of events but
-  // use a more general listener, without causing as much slowdown for things
-  // which are typed correctly.  But this currently runs afoul of restrictions
-  // on is checks for compatibility with the VM.
   _EventStreamSubscription(
       this._target, this._eventType, void onData(T event)?, this._useCapture)
       : _onData = onData == null
             ? null
+            // If removed, we would need an `is` check on a function type which
+            // is ultimately more expensive.
+            // ignore: avoid_dynamic_calls
             : _wrapZone<Event>((e) => (onData as dynamic)(e)) {
     _tryResume();
   }
@@ -267,6 +257,9 @@
     _unlisten();
     _onData = handleData == null
         ? null
+        // If removed, we would need an `is` check on a function type which is
+        // ultimately more expensive.
+        // ignore: avoid_dynamic_calls
         : _wrapZone<Event>((e) => (handleData as dynamic)(e));
     _tryResume();
   }
diff --git a/tools/dom/src/Validators.dart b/tools/dom/src/Validators.dart
index 1fbafbd..efbf73b 100644
--- a/tools/dom/src/Validators.dart
+++ b/tools/dom/src/Validators.dart
@@ -229,7 +229,11 @@
     var isAttr;
     try {
       // If getting/indexing attributes throws, count that as corrupt.
+      // Don't remove dynamic calls in sanitizing code.
+      // ignore: avoid_dynamic_calls
       attrs = element.attributes;
+      // Don't remove dynamic calls in sanitizing code.
+      // ignore: avoid_dynamic_calls
       isAttr = attrs['is'];
       var corruptedTest1 = Element._hasCorruptedAttributes(element);
 
@@ -290,7 +294,11 @@
     for (var i = attrs.length - 1; i >= 0; --i) {
       var name = keys[i];
       if (!validator.allowsAttribute(
-          element, name.toLowerCase(), attrs[name])) {
+          element,
+          // Don't remove dynamic calls in sanitizing code.
+          // ignore: avoid_dynamic_calls
+          name.toLowerCase(),
+          attrs[name])) {
         window.console.warn('Removing disallowed attribute '
             '<$tag $name="${attrs[name]}">');
         attrs.remove(name);
diff --git a/tools/dom/src/dart2js_CustomElementSupport.dart b/tools/dom/src/dart2js_CustomElementSupport.dart
index aea853a..c4c49bd 100644
--- a/tools/dom/src/dart2js_CustomElementSupport.dart
+++ b/tools/dom/src/dart2js_CustomElementSupport.dart
@@ -16,15 +16,16 @@
   };
 }
 
-_callAttached(receiver) {
+_callAttached(Element receiver) {
   return receiver.attached();
 }
 
-_callDetached(receiver) {
+_callDetached(Element receiver) {
   return receiver.detached();
 }
 
-_callAttributeChanged(receiver, name, oldValue, newValue) {
+_callAttributeChanged(
+    Element receiver, String name, String oldValue, String newValue) {
   return receiver.attributeChanged(name, oldValue, newValue);
 }
 
@@ -66,7 +67,8 @@
   }
 }
 
-Function _registerCustomElement(context, document, String tag, [Map? options]) {
+Function _registerCustomElement(context, Document document, String tag,
+    [Map? options]) {
   // Function follows the same pattern as the following JavaScript code for
   // registering a custom element.
   //
diff --git a/tools/dom/src/dart2js_KeyEvent.dart b/tools/dom/src/dart2js_KeyEvent.dart
index d573437..e6e964f 100644
--- a/tools/dom/src/dart2js_KeyEvent.dart
+++ b/tools/dom/src/dart2js_KeyEvent.dart
@@ -108,7 +108,7 @@
       view = window;
     }
 
-    dynamic eventObj;
+    KeyboardEvent eventObj;
 
     // Currently this works on everything but Safari. Safari throws an
     // "Attempting to change access mechanism for an unconfigurable property"
@@ -119,7 +119,7 @@
     // initialize initKeyEvent.
 
     eventObj = new Event.eventType('KeyboardEvent', type,
-        canBubble: canBubble, cancelable: cancelable);
+        canBubble: canBubble, cancelable: cancelable) as KeyboardEvent;
 
     // Chromium Hack
     JS(
diff --git a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
index 7aade98..10ea0fc 100644
--- a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
@@ -1373,20 +1373,19 @@
 
 class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase {
   final Iterable<Element> _elementIterable;
-  Iterable<CssStyleDeclaration>$NULLABLE _elementCssStyleDeclarationSetIterable;
+  Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable;
 
-  _CssStyleDeclarationSet(this._elementIterable) {
-    _elementCssStyleDeclarationSetIterable = new List.from(
-        _elementIterable).map((e) => e.style);
-  }
+  _CssStyleDeclarationSet(this._elementIterable)
+    : _elementCssStyleDeclarationSetIterable = 
+            new List.of(_elementIterable).map((e) => e.style);
 
   String getPropertyValue(String propertyName) =>
-      _elementCssStyleDeclarationSetIterable$NULLASSERT.first.getPropertyValue(
+      _elementCssStyleDeclarationSetIterable.first.getPropertyValue(
           propertyName);
 
   void setProperty(String propertyName, String$NULLABLE value,
       [String$NULLABLE priority]) {
-    _elementCssStyleDeclarationSetIterable$NULLASSERT.forEach((e) =>
+    _elementCssStyleDeclarationSetIterable.forEach((e) =>
         e.setProperty(propertyName, value, priority));
   }
 
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index ec7842a..d27ee9e 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -17,8 +17,8 @@
 #   dart pkg/analyzer/tool/experiments/generate.dart
 #
 # Also, pkg/analyzer/lib/src/dart/analysis/driver.dart will need a bump in
-# DATA_VERSION if making changes that changes previous flags' "index", e.g.
-# if adding a new flag that doesn't happen to be lexicographically last.
+# DATA_VERSION if making changes that change the "index" of any previous flags,
+# e.g. if adding a new flag that doesn't happen to be lexicographically last.
 #
 # kernel:
 #   pkg/front_end/tool/fasta generate-experimental-flags
@@ -100,7 +100,7 @@
 # files that specify an earlier version.
 #
 # Furthermore, most of the above was designed with language features
-# (spanning both CFE and Analyzer) in mind, but didn't take into account
+# (spanning both CFE anqgit d Analyzer) in mind, but didn't take into account
 # features in individual products (e.g. in CFE that has no influence on
 # Analyzer). As a stepping-stone to allow for this usage as well, a "category"
 # is also available. If no "category" is specified it's assumed to be the
@@ -131,6 +131,12 @@
   records:
     help: "Records"
 
+  patterns:
+    help: "Patterns"
+
+  unnamed-libraries:
+    help: "Unnamed libraries"
+
 # Experiment flag only used for testing.
   test-experiment:
     help: >-
@@ -247,7 +253,7 @@
     help: "Named Arguments Anywhere"
     enabledIn: '2.17.0'
     validation: |
-      void test(String msg, {bool enabled : false}) {
+      void test(String msg, {bool enabled = false}) {
         if (enabled) {
           print(msg);
         }
diff --git a/tools/generate_idefiles.py b/tools/generate_idefiles.py
index ac75696..6b68ef4 100755
--- a/tools/generate_idefiles.py
+++ b/tools/generate_idefiles.py
@@ -12,6 +12,7 @@
 import argparse
 import json
 import os
+import re
 import subprocess
 import sys
 
@@ -57,8 +58,10 @@
         return 1
 
     command_set = json.loads(
-        subprocess.check_output(
-            ["ninja", "-C", out_folder, "-t", "compdb", "cxx", "cc", "h"]))
+        subprocess.check_output([
+            "buildtools/ninja/ninja", "-C", out_folder, "-t", "compdb", "-x",
+            "cxx", "cc", "h"
+        ]))
 
     commands = []
     for obj in command_set:
@@ -71,6 +74,31 @@
         # Remove warnings
         command = command.replace("-Werror", "")
 
+        # Remove ninja prepend on Windows.
+        # This is not fully correct, as now it fails to find a sysroot for
+        # Windows. However, clangd completely fails with the `-t` flag.
+        command = re.sub(r"([^\s]*)ninja -t msvc -e environment.x64 --", "",
+                         command)
+
+        # Add sysroot from out\DebugX64\environment.x64 on Windows.
+        # TODO(dacoharkes): Fetch the paths from that file.
+        windowsSysroots = [
+            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\1023ce2e82\\Windows Kits\\10\\Include\\10.0.20348.0\\um',
+            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\1023ce2e82\\Windows Kits\\10\\Include\\10.0.20348.0\\shared',
+            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\1023ce2e82\\Windows Kits\\10\\Include\\10.0.20348.0\\winrt',
+            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\1023ce2e82\\Windows Kits\\10\\Include\\10.0.20348.0\\ucrt',
+            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\1023ce2e82\\VC\\Tools\\MSVC\\14.29.30133\\include',
+            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\1023ce2e82\\VC\\Tools\\MSVC\\14.29.30133\\atlmfc\\include',
+        ]
+        for windowsSysroot in windowsSysroots:
+            command = command.replace(
+                "-DDART_TARGET_OS_WINDOWS",
+                "-DDART_TARGET_OS_WINDOWS \"-I%s\"" % windowsSysroot)
+
+        # Prevent packing errors from causing fatal_too_many_errors on Windows.
+        command = command.replace("-DDART_TARGET_OS_WINDOWS",
+                                  "-DDART_TARGET_OS_WINDOWS -ferror-limit=0")
+
         obj["command"] = command
         commands += [obj]
 
diff --git a/tools/linux_dist_support/run_debian_build.sh b/tools/linux_dist_support/run_debian_build.sh
index 4f09663..b36eefe 100755
--- a/tools/linux_dist_support/run_debian_build.sh
+++ b/tools/linux_dist_support/run_debian_build.sh
@@ -4,8 +4,8 @@
 # BSD-style license that can be found in the LICENSE file.
 set -x
 
-ninja=$(which ninja)
-depot_tools=$(dirname $ninja)
+fetch=$(which fetch)
+depot_tools=$(dirname $fetch)
 image="debian-package:0.1"
 dockerfile=tools/linux_dist_support/Debian.dockerfile
 docker build --build-arg depot_tools=$depot_tools -t $image - < $dockerfile
diff --git a/tools/spec_parser/Dart.g b/tools/spec_parser/Dart.g
index e992711..9aa4692 100644
--- a/tools/spec_parser/Dart.g
+++ b/tools/spec_parser/Dart.g
@@ -4,6 +4,9 @@
 
 // CHANGES:
 //
+// v0.19 Add support for super parameters, named arguments everywhere, and
+// records.
+//
 // v0.18 Add support for enhanced `enum` declarations.
 //
 // v0.17 (58d917e7573c359580ade43845004dbbc62220d5) Correct `uri` to allow
@@ -293,6 +296,7 @@
     :    functionFormalParameter
     |    fieldFormalParameter
     |    simpleFormalParameter
+    |    superFormalParameter
     ;
 
 // NB: It is an anomaly that a functionFormalParameter cannot be FINAL.
@@ -310,6 +314,10 @@
     :    finalConstVarOrType? THIS '.' identifier (formalParameterPart '?'?)?
     ;
 
+superFormalParameter
+    :    type? SUPER '.' identifier (formalParameterPart '?'?)?
+    ;
+
 defaultFormalParameter
     :    normalFormalParameter ('=' expression)?
     ;
@@ -561,6 +569,7 @@
     |    symbolLiteral
     |    setOrMapLiteral
     |    listLiteral
+    |    recordLiteral
     ;
 
 nullLiteral
@@ -587,11 +596,25 @@
     ;
 
 setOrMapLiteral
-    : CONST? typeArguments? LBRACE elements? RBRACE
+    :    CONST? typeArguments? LBRACE elements? RBRACE
     ;
 
 listLiteral
-    : CONST? typeArguments? '[' elements? ']'
+    :    CONST? typeArguments? '[' elements? ']'
+    ;
+
+recordLiteral
+    :    CONST? recordLiteralNoConst
+    ;
+
+recordLiteralNoConst
+    :    '(' expression ',' ')'
+    |    '(' label expression ','? ')'
+    |    '(' recordField ',' recordField (',' recordField)* ','? ')'
+    ;
+
+recordField
+    :    label? expression
     ;
 
 elements
@@ -693,12 +716,11 @@
     ;
 
 argumentList
-    :    namedArgument (',' namedArgument)*
-    |    expressionList (',' namedArgument)*
+    :    argument (',' argument)*
     ;
 
-namedArgument
-    :    label expression
+argument
+    :    label? expression
     ;
 
 cascade
@@ -1185,11 +1207,13 @@
 
 typeNotVoid
     :    functionType '?'?
+    |    recordType '?'?
     |    typeNotVoidNotFunction
     ;
 
 typeNotFunction
     :    typeNotVoidNotFunction
+    |    recordType '?'?
     |    VOID
     ;
 
@@ -1210,6 +1234,28 @@
     :    type (',' type)*
     ;
 
+recordType
+    :    '(' recordTypeFields ',' recordTypeNamedFields ')'
+    |    '(' recordTypeFields ','? ')'
+    |    '(' recordTypeNamedFields? ')'
+    ;
+
+recordTypeFields
+    :    recordTypeField (',' recordTypeField)*
+    ;
+
+recordTypeField
+    :    metadata type identifier?
+    ;
+
+recordTypeNamedFields
+    :    LBRACE recordTypeNamedField (',' recordTypeNamedField)* ','? RBRACE
+    ;
+
+recordTypeNamedField
+    :    metadata typedIdentifier
+    ;
+
 typeNotVoidNotFunctionList
     :    typeNotVoidNotFunction (',' typeNotVoidNotFunction)*
     ;
diff --git a/utils/dart2wasm/BUILD.gn b/utils/dart2wasm/BUILD.gn
index 428922f..591b026 100644
--- a/utils/dart2wasm/BUILD.gn
+++ b/utils/dart2wasm/BUILD.gn
@@ -7,6 +7,22 @@
 
 sdk_root = "../../sdk"
 
+template("wasm_module") {
+  action(target_name) {
+    script = rebase_path("//build/gn_run_binary.py")
+    args = [
+      "compiled_action",
+      rebase_path("//third_party/emsdk/upstream/emscripten/emcc"),
+      "--no-entry",
+      rebase_path("//tests/web/wasm/${invoker.module_name}.c"),
+      "-o",
+      rebase_path("$root_out_dir/wasm/${invoker.module_name}.wasm"),
+      "-O",
+    ]
+    outputs = [ "$root_out_dir/wasm/${invoker.module_name}.wasm" ]
+  }
+}
+
 aot_snapshot("dart2wasm_snapshot") {
   main_dart = "../../pkg/dart2wasm/bin/dart2wasm.dart"
   name = "dart2wasm"
@@ -36,3 +52,11 @@
     "--nnbd-strong",
   ]
 }
+
+wasm_module("ffi_native_test_wasm_module") {
+  module_name = "ffi_native_test_module"
+}
+
+group("test_wasm_modules") {
+  deps = [ ":ffi_native_test_wasm_module" ]
+}